Skip to content

Commit

Permalink
Disallow use of union types in args and return types
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-chambers committed Jan 17, 2024
1 parent 84338eb commit 002860d
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 54 deletions.
4 changes: 4 additions & 0 deletions ndc-lambda-sdk/src/inference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ function deriveSchemaTypeForTsType(tsType: ts.Type, typePath: TypePathSegment[],
return new Err([`Class types are not supported, but one was encountered in ${typePathToString(typePath)} (type: ${context.typeChecker.typeToString(tsType)})`]);
}

if (tsType.isUnion()) {
return new Err([`Union types are not supported, but one was encountered in ${typePathToString(typePath)} (type: ${context.typeChecker.typeToString(tsType)})`]);
}

// We don't know how to deal with this type, so just make it an opaque scalar
const typeName = generateTypeNameFromTypePath(typePath);
context.scalarTypeDefinitions[typeName] = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,11 +499,7 @@ describe("basic inference", function() {

assert.deepStrictEqual(schema, {
compilerDiagnostics: [],
functionIssues: {
"test": [
"Unable to derive an NDC type for function 'test' parameter 'unionWithNull' (type: string | number | null). Assuming that it is a scalar type."
]
},
functionIssues: {},
functionsSchema: {
functions: {
"test": {
Expand Down Expand Up @@ -556,15 +552,6 @@ describe("basic inference", function() {
},
},
},
{
argumentName: "unionWithNull",
description: null,
type: {
kind: "scalar",
name: "test_arguments_unionWithNull",
type: "named",
},
},
{
argumentName: "optionalParam",
description: null,
Expand Down Expand Up @@ -656,7 +643,6 @@ describe("basic inference", function() {
},
scalarTypes: {
String: {},
test_arguments_unionWithNull: {},
},
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export function test(
nullableParam: string | null,
undefinedParam: string | undefined,
nullOrUndefinedParam: string | undefined | null,
unionWithNull: string | number | null,
optionalParam?: string
): string | null {
return "test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,7 @@ describe("external dependencies", function() {

assert.deepStrictEqual(schema, {
compilerDiagnostics: [],
functionIssues: {
"delete_todos": [
"Unable to derive an NDC type for function 'delete_todos' return value (type: string | { error: string; }). Assuming that it is a scalar type."
],
"insert_todos": [
"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."
],
"insert_user": [
"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."
],
},
functionIssues: {},
functionsSchema: {
functions: {
"insert_user": {
Expand All @@ -76,7 +66,7 @@ describe("external dependencies", function() {
resultType: {
type: "named",
kind: "scalar",
name: "insert_user_output"
name: "JSON"
}
},
"insert_todos": {
Expand Down Expand Up @@ -105,7 +95,7 @@ describe("external dependencies", function() {
resultType: {
type: "named",
kind: "scalar",
name: "insert_todos_output"
name: "JSON"
}
},
"delete_todos": {
Expand All @@ -124,18 +114,45 @@ describe("external dependencies", function() {
],
resultType: {
type: "named",
kind: "scalar",
kind: "object",
name: "delete_todos_output"
}
},
},
scalarTypes: {
String: {},
insert_todos_output: {},
insert_user_output: {},
delete_todos_output: {},
JSON: {}
},
objectTypes: {
"delete_todos_output": {
properties: [
{
propertyName: "error",
type: {
nullOrUndefinability: NullOrUndefinability.AcceptsUndefinedOnly,
type: "nullable",
underlyingType: {
kind: "scalar",
name: "String",
type: "named",
}
}
},
{
propertyName: "result",
type: {
nullOrUndefinability: NullOrUndefinability.AcceptsUndefinedOnly,
type: "nullable",
underlyingType: {
kind: "scalar",
name: "String",
type: "named",
}
}
}
]
}
},
objectTypes: {},
}
})
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Client } from "node-postgres";
import * as sdk from "../../../src/schema";

const dbConfig = {
user: "aaysha",
Expand All @@ -12,11 +13,7 @@ const dbConfig = {

export async function insert_user(
user_name: string,
): Promise<
{ id: string; name: string; created_at: string } | { message: string } | {
error: string;
} | {}
> {
): Promise<sdk.JSONValue> {
const client = new Client(dbConfig);

try {
Expand All @@ -29,14 +26,14 @@ export async function insert_user(
if (result && result.rows.length > 0 && result.rows[0]) {
return result.rows[0];
} else {
return { message: "Insert Failed" };
return new sdk.JSONValue({ message: "Insert Failed" });
}
} catch (error) {
console.error("Error:", error);
if (error != null && typeof error === "object" && "message" in error) {
return { error: "Error: " + error.message };
return new sdk.JSONValue({ error: "Error: " + error.message });
} else {
return { error: "Unknown error" };
return new sdk.JSONValue({ error: "Unknown error" });
}
} finally {
await client.end();
Expand All @@ -46,11 +43,7 @@ export async function insert_user(
export async function insert_todos(
user_id: string,
todo: string
): Promise<
{ id: string; user_id: string; todo: string; created_at: string } | { message: string } | {
error: string;
} | {}
> {
): Promise<sdk.JSONValue> {
const client = new Client(dbConfig);

try {
Expand All @@ -62,7 +55,7 @@ export async function insert_todos(
})

if (userExistsQuery.rows.length === 0) {
return { message: "User not found. Insert Failed" };
return new sdk.JSONValue({ message: "User not found. Insert Failed" });
}
const result = await client.query({
text: `INSERT INTO todos(user_id,todo) VALUES ('${user_id}','${todo}') RETURNING *`,
Expand All @@ -71,14 +64,14 @@ export async function insert_todos(
if (result && result.rows.length > 0 && result.rows[0]) {
return result.rows[0];
} else {
return { message: "Insert Failed" };
return new sdk.JSONValue({ message: "Insert Failed" });
}
} catch (error) {
console.error("Error:", error);
if (error != null && typeof error === "object" && "message" in error) {
return { error: "Error: " + error.message };
return new sdk.JSONValue({ error: "Error: " + error.message });
} else {
return { error: "Unknown error" };
return new sdk.JSONValue({ error: "Unknown error" });
}
} finally {
await client.end();
Expand All @@ -88,16 +81,16 @@ export async function insert_todos(

export async function delete_todos(
todo_id: string
){
): Promise<{ error?: string, result?: string }> {
const client = new Client(dbConfig);
try {
await client.connect();

const result = await client.query({ text: `DELETE FROM todos WHERE id =${todo_id}`})
if (result.rowCount === 1) {
return `Deleted todo with id= ${todo_id} successfully`
return { result: `Deleted todo with id= ${todo_id} successfully` }
} else {
return "Deletion unsuccessful"
return { result: "Deletion unsuccessful" }
}
} catch (error) {
if (error != null && typeof error === "object" && "message" in error) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type AliasedUnion = string | boolean;

export function unionTypes(
numberOrString: number | string,
aliasedUnion: AliasedUnion,
unionedObjects: { prop1: string } | { prop2: string }
): string {
return ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,26 @@ describe("unsupported types", function() {
}
})
});

it("union types", function() {
const schema = deriveSchema(require.resolve("./union-types.ts"));

assert.deepStrictEqual(schema, {
compilerDiagnostics: [],
functionIssues: {
"unionTypes": [
"Union types are not supported, but one was encountered in function 'unionTypes' parameter 'numberOrString' (type: string | number)",
"Union types are not supported, but one was encountered in function 'unionTypes' parameter 'aliasedUnion' (type: AliasedUnion)",
"Union types are not supported, but one was encountered in function 'unionTypes' parameter 'unionedObjects' (type: { prop1: string; } | { prop2: string; })"
],
},
functionsSchema: {
scalarTypes: {
String: {}
},
objectTypes: {},
functions: {}
}
})
});
});

0 comments on commit 002860d

Please sign in to comment.