Skip to content

Commit 002860d

Browse files
Disallow use of union types in args and return types
1 parent 84338eb commit 002860d

File tree

7 files changed

+84
-54
lines changed

7 files changed

+84
-54
lines changed

ndc-lambda-sdk/src/inference.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ function deriveSchemaTypeForTsType(tsType: ts.Type, typePath: TypePathSegment[],
306306
return new Err([`Class types are not supported, but one was encountered in ${typePathToString(typePath)} (type: ${context.typeChecker.typeToString(tsType)})`]);
307307
}
308308

309+
if (tsType.isUnion()) {
310+
return new Err([`Union types are not supported, but one was encountered in ${typePathToString(typePath)} (type: ${context.typeChecker.typeToString(tsType)})`]);
311+
}
312+
309313
// We don't know how to deal with this type, so just make it an opaque scalar
310314
const typeName = generateTypeNameFromTypePath(typePath);
311315
context.scalarTypeDefinitions[typeName] = {};

ndc-lambda-sdk/test/inference/basic-inference/basic-inference.test.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,7 @@ describe("basic inference", function() {
499499

500500
assert.deepStrictEqual(schema, {
501501
compilerDiagnostics: [],
502-
functionIssues: {
503-
"test": [
504-
"Unable to derive an NDC type for function 'test' parameter 'unionWithNull' (type: string | number | null). Assuming that it is a scalar type."
505-
]
506-
},
502+
functionIssues: {},
507503
functionsSchema: {
508504
functions: {
509505
"test": {
@@ -556,15 +552,6 @@ describe("basic inference", function() {
556552
},
557553
},
558554
},
559-
{
560-
argumentName: "unionWithNull",
561-
description: null,
562-
type: {
563-
kind: "scalar",
564-
name: "test_arguments_unionWithNull",
565-
type: "named",
566-
},
567-
},
568555
{
569556
argumentName: "optionalParam",
570557
description: null,
@@ -656,7 +643,6 @@ describe("basic inference", function() {
656643
},
657644
scalarTypes: {
658645
String: {},
659-
test_arguments_unionWithNull: {},
660646
},
661647
}
662648
})

ndc-lambda-sdk/test/inference/basic-inference/nullable-types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export function test(
1111
nullableParam: string | null,
1212
undefinedParam: string | undefined,
1313
nullOrUndefinedParam: string | undefined | null,
14-
unionWithNull: string | number | null,
1514
optionalParam?: string
1615
): string | null {
1716
return "test"

ndc-lambda-sdk/test/inference/external-dependencies/external-dependencies.test.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,7 @@ describe("external dependencies", function() {
4646

4747
assert.deepStrictEqual(schema, {
4848
compilerDiagnostics: [],
49-
functionIssues: {
50-
"delete_todos": [
51-
"Unable to derive an NDC type for function 'delete_todos' return value (type: string | { error: string; }). Assuming that it is a scalar type."
52-
],
53-
"insert_todos": [
54-
"Unable to derive an NDC type for function 'insert_todos' return value (type: {} | { id: string; user_id: string; todo: string; created_at: string; } | { message: string; } | { error: string; }). Assuming that it is a scalar type."
55-
],
56-
"insert_user": [
57-
"Unable to derive an NDC type for function 'insert_user' return value (type: {} | { id: string; name: string; created_at: string; } | { message: string; } | { error: string; }). Assuming that it is a scalar type."
58-
],
59-
},
49+
functionIssues: {},
6050
functionsSchema: {
6151
functions: {
6252
"insert_user": {
@@ -76,7 +66,7 @@ describe("external dependencies", function() {
7666
resultType: {
7767
type: "named",
7868
kind: "scalar",
79-
name: "insert_user_output"
69+
name: "JSON"
8070
}
8171
},
8272
"insert_todos": {
@@ -105,7 +95,7 @@ describe("external dependencies", function() {
10595
resultType: {
10696
type: "named",
10797
kind: "scalar",
108-
name: "insert_todos_output"
98+
name: "JSON"
10999
}
110100
},
111101
"delete_todos": {
@@ -124,18 +114,45 @@ describe("external dependencies", function() {
124114
],
125115
resultType: {
126116
type: "named",
127-
kind: "scalar",
117+
kind: "object",
128118
name: "delete_todos_output"
129119
}
130120
},
131121
},
132122
scalarTypes: {
133123
String: {},
134-
insert_todos_output: {},
135-
insert_user_output: {},
136-
delete_todos_output: {},
124+
JSON: {}
125+
},
126+
objectTypes: {
127+
"delete_todos_output": {
128+
properties: [
129+
{
130+
propertyName: "error",
131+
type: {
132+
nullOrUndefinability: NullOrUndefinability.AcceptsUndefinedOnly,
133+
type: "nullable",
134+
underlyingType: {
135+
kind: "scalar",
136+
name: "String",
137+
type: "named",
138+
}
139+
}
140+
},
141+
{
142+
propertyName: "result",
143+
type: {
144+
nullOrUndefinability: NullOrUndefinability.AcceptsUndefinedOnly,
145+
type: "nullable",
146+
underlyingType: {
147+
kind: "scalar",
148+
name: "String",
149+
type: "named",
150+
}
151+
}
152+
}
153+
]
154+
}
137155
},
138-
objectTypes: {},
139156
}
140157
})
141158
});

ndc-lambda-sdk/test/inference/external-dependencies/use-postgres-package.ts

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Client } from "node-postgres";
2+
import * as sdk from "../../../src/schema";
23

34
const dbConfig = {
45
user: "aaysha",
@@ -12,11 +13,7 @@ const dbConfig = {
1213

1314
export async function insert_user(
1415
user_name: string,
15-
): Promise<
16-
{ id: string; name: string; created_at: string } | { message: string } | {
17-
error: string;
18-
} | {}
19-
> {
16+
): Promise<sdk.JSONValue> {
2017
const client = new Client(dbConfig);
2118

2219
try {
@@ -29,14 +26,14 @@ export async function insert_user(
2926
if (result && result.rows.length > 0 && result.rows[0]) {
3027
return result.rows[0];
3128
} else {
32-
return { message: "Insert Failed" };
29+
return new sdk.JSONValue({ message: "Insert Failed" });
3330
}
3431
} catch (error) {
3532
console.error("Error:", error);
3633
if (error != null && typeof error === "object" && "message" in error) {
37-
return { error: "Error: " + error.message };
34+
return new sdk.JSONValue({ error: "Error: " + error.message });
3835
} else {
39-
return { error: "Unknown error" };
36+
return new sdk.JSONValue({ error: "Unknown error" });
4037
}
4138
} finally {
4239
await client.end();
@@ -46,11 +43,7 @@ export async function insert_user(
4643
export async function insert_todos(
4744
user_id: string,
4845
todo: string
49-
): Promise<
50-
{ id: string; user_id: string; todo: string; created_at: string } | { message: string } | {
51-
error: string;
52-
} | {}
53-
> {
46+
): Promise<sdk.JSONValue> {
5447
const client = new Client(dbConfig);
5548

5649
try {
@@ -62,7 +55,7 @@ export async function insert_todos(
6255
})
6356

6457
if (userExistsQuery.rows.length === 0) {
65-
return { message: "User not found. Insert Failed" };
58+
return new sdk.JSONValue({ message: "User not found. Insert Failed" });
6659
}
6760
const result = await client.query({
6861
text: `INSERT INTO todos(user_id,todo) VALUES ('${user_id}','${todo}') RETURNING *`,
@@ -71,14 +64,14 @@ export async function insert_todos(
7164
if (result && result.rows.length > 0 && result.rows[0]) {
7265
return result.rows[0];
7366
} else {
74-
return { message: "Insert Failed" };
67+
return new sdk.JSONValue({ message: "Insert Failed" });
7568
}
7669
} catch (error) {
7770
console.error("Error:", error);
7871
if (error != null && typeof error === "object" && "message" in error) {
79-
return { error: "Error: " + error.message };
72+
return new sdk.JSONValue({ error: "Error: " + error.message });
8073
} else {
81-
return { error: "Unknown error" };
74+
return new sdk.JSONValue({ error: "Unknown error" });
8275
}
8376
} finally {
8477
await client.end();
@@ -88,16 +81,16 @@ export async function insert_todos(
8881

8982
export async function delete_todos(
9083
todo_id: string
91-
){
84+
): Promise<{ error?: string, result?: string }> {
9285
const client = new Client(dbConfig);
9386
try {
9487
await client.connect();
9588

9689
const result = await client.query({ text: `DELETE FROM todos WHERE id =${todo_id}`})
9790
if (result.rowCount === 1) {
98-
return `Deleted todo with id= ${todo_id} successfully`
91+
return { result: `Deleted todo with id= ${todo_id} successfully` }
9992
} else {
100-
return "Deletion unsuccessful"
93+
return { result: "Deletion unsuccessful" }
10194
}
10295
} catch (error) {
10396
if (error != null && typeof error === "object" && "message" in error) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type AliasedUnion = string | boolean;
2+
3+
export function unionTypes(
4+
numberOrString: number | string,
5+
aliasedUnion: AliasedUnion,
6+
unionedObjects: { prop1: string } | { prop2: string }
7+
): string {
8+
return ""
9+
}

ndc-lambda-sdk/test/inference/unsupported-types/unsupported-types.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,26 @@ describe("unsupported types", function() {
217217
}
218218
})
219219
});
220+
221+
it("union types", function() {
222+
const schema = deriveSchema(require.resolve("./union-types.ts"));
223+
224+
assert.deepStrictEqual(schema, {
225+
compilerDiagnostics: [],
226+
functionIssues: {
227+
"unionTypes": [
228+
"Union types are not supported, but one was encountered in function 'unionTypes' parameter 'numberOrString' (type: string | number)",
229+
"Union types are not supported, but one was encountered in function 'unionTypes' parameter 'aliasedUnion' (type: AliasedUnion)",
230+
"Union types are not supported, but one was encountered in function 'unionTypes' parameter 'unionedObjects' (type: { prop1: string; } | { prop2: string; })"
231+
],
232+
},
233+
functionsSchema: {
234+
scalarTypes: {
235+
String: {}
236+
},
237+
objectTypes: {},
238+
functions: {}
239+
}
240+
})
241+
});
220242
});

0 commit comments

Comments
 (0)