From afe8a0ceac28e94da958b80713717d24afdc38dc Mon Sep 17 00:00:00 2001 From: Scott Trinh Date: Tue, 11 Jul 2023 15:08:59 -0400 Subject: [PATCH] Handle >2 union members in links (#669) --- .github/workflows/tests.yml | 2 - integration-tests/lts/dbschema/default.esdl | 6 +- .../lts/dbschema/migrations/00021.edgeql | 17 ++ integration-tests/lts/interfaces.test.ts | 4 +- integration-tests/lts/objectTypes.test.ts | 5 +- integration-tests/lts/params.test.ts | 2 +- .../src/edgeql-js/generateObjectTypes.ts | 186 +----------------- 7 files changed, 31 insertions(+), 191 deletions(-) create mode 100644 integration-tests/lts/dbschema/migrations/00021.edgeql diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 611a3c439..fcb6a1776 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,8 +6,6 @@ on: - master - ci pull_request: - branches: - - master jobs: test: diff --git a/integration-tests/lts/dbschema/default.esdl b/integration-tests/lts/dbschema/default.esdl index 0407ba660..96ce2bc4c 100644 --- a/integration-tests/lts/dbschema/default.esdl +++ b/integration-tests/lts/dbschema/default.esdl @@ -128,6 +128,10 @@ module default { type Simple extending HasName, HasAge {} + type W { + property a -> str; + property d -> float64; + } type X { property a -> str; property b -> int32; @@ -137,7 +141,7 @@ module default { property c -> bool; } type Z { - link xy -> X | Y; + link xy -> W | X | Y; } # Unicode handling diff --git a/integration-tests/lts/dbschema/migrations/00021.edgeql b/integration-tests/lts/dbschema/migrations/00021.edgeql new file mode 100644 index 000000000..9acfda49d --- /dev/null +++ b/integration-tests/lts/dbschema/migrations/00021.edgeql @@ -0,0 +1,17 @@ +CREATE MIGRATION m1bffqrfcj7ols7s3v27kgbxhtsetpvwvqpxrogvhsq2crwwlnbbya + ONTO m1sxhoqfjqn7vtpmatzanmwydtxndf3jlf33npkblmya42fx3bcdoa +{ + CREATE TYPE default::W { + CREATE PROPERTY a -> std::str; + CREATE PROPERTY d -> std::float64; + }; + ALTER TYPE default::Z { + ALTER LINK xy { + SET TYPE ((default::Y | default::X) | default::W) USING (SELECT + default::X + LIMIT + 1 + ); + }; + }; +}; diff --git a/integration-tests/lts/interfaces.test.ts b/integration-tests/lts/interfaces.test.ts index db21f44c4..6aa818476 100644 --- a/integration-tests/lts/interfaces.test.ts +++ b/integration-tests/lts/interfaces.test.ts @@ -1,6 +1,6 @@ import * as tc from "conditional-type-checks"; -import type { Movie, X, Y, Z } from "./dbschema/interfaces"; +import type { Movie, W, X, Y, Z } from "./dbschema/interfaces"; export type Genre = | "Horror" @@ -32,7 +32,7 @@ export interface test_Profile extends BaseObject { c?: string | null; } interface test_Z extends BaseObject { - xy?: X | Y | null; + xy?: W | X | Y | null; } describe("interfaces", () => { diff --git a/integration-tests/lts/objectTypes.test.ts b/integration-tests/lts/objectTypes.test.ts index 047a93906..29ec15b64 100644 --- a/integration-tests/lts/objectTypes.test.ts +++ b/integration-tests/lts/objectTypes.test.ts @@ -58,7 +58,10 @@ describe("object types", () => { $Z.__pointers__.xy.target.__pointers__.a.target.__name__, "std::str" ); - assert.equal($Z.__pointers__.xy.target.__name__, "default::X | default::Y"); + assert.equal( + $Z.__pointers__.xy.target.__name__, + "default::X | default::Y | default::W" + ); }); const link = $AnnotationSubject.__pointers__.annotations; diff --git a/integration-tests/lts/params.test.ts b/integration-tests/lts/params.test.ts index a938863ca..0367b11b7 100644 --- a/integration-tests/lts/params.test.ts +++ b/integration-tests/lts/params.test.ts @@ -274,7 +274,7 @@ SELECT (SELECT __param__test)` tuple: args, }); - assert.deepEqual(Object.values(complexResult.tuple), Object.values(args)); + assert.deepEqual(complexResult.tuple, args); }); test("v2 param types", async () => { diff --git a/packages/generate/src/edgeql-js/generateObjectTypes.ts b/packages/generate/src/edgeql-js/generateObjectTypes.ts index 5ec96b0ec..0a1b16a5c 100644 --- a/packages/generate/src/edgeql-js/generateObjectTypes.ts +++ b/packages/generate/src/edgeql-js/generateObjectTypes.ts @@ -1,4 +1,4 @@ -import { CodeFragment, dts, r, t, ts } from "../builders"; +import { type CodeFragment, dts, r, t, ts } from "../builders"; import type { GeneratorParams } from "../genutil"; import type { $ } from "../genutil"; import { @@ -158,93 +158,15 @@ export const getStringRepresentation: ( export const generateObjectTypes = (params: GeneratorParams) => { const { dir, types } = params; - // const plainTypesCode = dir.getPath("types"); - // plainTypesCode.addImportStar("edgedb", "edgedb", { - // typeOnly: true - // }); - // const plainTypeModules = new Map< - // string, - // {internalName: string; buf: CodeBuffer; types: Map} - // >(); - - // const getPlainTypeModule = ( - // typeName: string - // ): { - // tMod: string; - // tName: string; - // module: { - // internalName: string; - // buf: CodeBuffer; - // types: Map; - // }; - // } => { - // const {mod: tMod, name: tName} = splitName(typeName); - // if (!plainTypeModules.has(tMod)) { - // plainTypeModules.set(tMod, { - // internalName: makePlainIdent(tMod), - // buf: new CodeBuffer(), - // types: new Map() - // }); - // } - // return {tMod, tName, module: plainTypeModules.get(tMod)!}; - // }; - - // const _getTypeName = - // (mod: string) => - // (typeName: string, withModule: boolean = false): string => { - // const {tMod, tName, module} = getPlainTypeModule(typeName); - // return ( - // ((mod !== tMod || withModule) && tMod !== "default" - // ? `${module.internalName}.` - // : "") + `${makePlainIdent(tName)}` - // ); - // }; - for (const type of types.values()) { if (type.kind !== "object") { - // if (type.kind === "scalar" && type.enum_values?.length) { - // // generate plain enum type - // const {mod: enumMod, name: enumName} = splitName(type.name); - // const getEnumTypeName = _getTypeName(enumMod); - - // const {module} = getPlainTypeModule(type.name); - // module.types.set(enumName, getEnumTypeName(type.name, true)); - // module.buf.writeln( - // [t`export enum ${getEnumTypeName(type.name)} {`], - // ...type.enum_values.map(val => [ - // t` ${makePlainIdent(val)} = ${quote(val)},` - // ]), - // [t`}`] - // ); - - // if (enumMod === "default") { - // module.buf.writeln( - // [js`const ${getEnumTypeName(type.name)} = {`], - // ...type.enum_values.map(val => [ - // js` ${makePlainIdent(val)}: ${quote(val)},` - // ]), - // [js`}`] - // ); - // plainTypesCode.addExport(getEnumTypeName(type.name), { - // modes: ["js"] - // }); - // } else { - // module.buf.writeln( - // [js`"${getEnumTypeName(type.name)}": {`], - // ...type.enum_values.map(val => [ - // js` ${makePlainIdent(val)}: ${quote(val)},` - // ]), - // [js`},`] - // ); - // } - // } continue; } const isUnionType = Boolean(type.union_of?.length); const isIntersectionType = Boolean(type.intersection_of?.length); - if (isIntersectionType) { + if (isIntersectionType || isUnionType) { continue; } @@ -256,65 +178,6 @@ export const generateObjectTypes = (params: GeneratorParams) => { const ref = getRef(type.name); - ///////// - // generate plain type - ///////// - - // const getTypeName = _getTypeName(mod); - - // const getTSType = (pointer: $.introspect.Pointer): string => { - // const targetType = types.get(pointer.target_id); - // if (pointer.kind === "link") { - // return getTypeName(targetType.name); - // } else { - // return toTSScalarType( - // targetType as $.introspect.PrimitiveType, - // types, - // { - // getEnumRef: enumType => getTypeName(enumType.name), - // edgedbDatatypePrefix: "" - // } - // ).join(""); - // } - // }; - - // const {module: plainTypeModule} = getPlainTypeModule(type.name); - - // if (!isUnionType) { - // plainTypeModule.types.set(name, getTypeName(type.name, true)); - // } - // plainTypeModule.buf.writeln([ - // t`${ - // !isUnionType ? "export " : "" - // }interface ${getTypeName(type.name)}${ - // type.bases.length - // ? ` extends ${type.bases - // .map(({id}) => { - // const baseType = types.get(id); - // return getTypeName(baseType.name); - // }) - // .join(", ")}` - // : "" - // } ${ - // type.pointers.length - // ? `{\n${type.pointers - // .map(pointer => { - // const isOptional = - // pointer.real_cardinality === Cardinality.AtMostOne; - // return ` ${quote(pointer.name)}${ - // isOptional ? "?" : "" - // }: ${getTSType(pointer)}${ - // pointer.card === Cardinality.Many || - // pointer.card === Cardinality.AtLeastOne - // ? "[]" - // : "" - // }${isOptional ? " | null" : ""};`; - // }) - // .join("\n")}\n}` - // : "{}" - // }\n`, - // ]); - ///////// // generate interface ///////// @@ -357,19 +220,6 @@ export const generateObjectTypes = (params: GeneratorParams) => { }; }; - // unique - // const BaseObject = params.typesByName["std::BaseObject"]; - // const uniqueStubs = [...new Set(type.backlinks.map((bl) => bl.stub))]; - // const stubLines = uniqueStubs.map((stub): $.introspect.Pointer => { - // return { - // card: Cardinality.Many, - // kind: "link", - // name: `<${stub}`, - // target_id: BaseObject.id, - // is_exclusive: false, - // pointers: null, - // }; - // }); const lines = [ ...type.pointers, ...type.backlinks, @@ -456,7 +306,6 @@ export const generateObjectTypes = (params: GeneratorParams) => { } }); - // const ref = getRef(type.name); for (const ex of type.exclusives) { body.writeln([ t` {`, @@ -468,7 +317,6 @@ export const generateObjectTypes = (params: GeneratorParams) => { }), t`},`, ]); - // body.writeln([t`\n {${lines.join(", ")}}`]); } body.writeln([t`]>;`]); @@ -480,11 +328,6 @@ export const generateObjectTypes = (params: GeneratorParams) => { ///////// // generate runtime type ///////// - if (isUnionType) { - // union types don't need runtime type - continue; - } - const literal = getRef(type.name, { prefix: "" }); body.writeln([ @@ -496,7 +339,6 @@ export const generateObjectTypes = (params: GeneratorParams) => { r`(_.spec, ${quote(type.id)}, _.syntax.literal);`, ]); body.addExport(ref); - // body.addExport(ref, `$${name}`); // dollar const typeCard = singletonObjectTypes.has(type.name) ? "One" : "Many"; @@ -513,28 +355,4 @@ export const generateObjectTypes = (params: GeneratorParams) => { body.addExport(literal); body.addToDefaultExport(literal, name); } - - // plain types export - // const plainTypesExportBuf = new CodeBuffer(); - // for (const [moduleName, module] of plainTypeModules) { - // if (moduleName === "default") { - // plainTypesCode.writeBuf(module.buf); - // } else { - // plainTypesCode.writeln([t`export namespace ${module.internalName} {`]); - // plainTypesCode.writeln([js`const ${module.internalName} = {`]); - // plainTypesCode.indented(() => plainTypesCode.writeBuf(module.buf)); - // plainTypesCode.writeln([t`}`]); - // plainTypesCode.writeln([js`}`]); - // plainTypesCode.addExport(module.internalName, {modes: ["js"]}); - // } - - // plainTypesExportBuf.writeln([ - // t` ${quote(moduleName)}: {\n${[...module.types.entries()] - // .map(([name, typeName]) => ` ${quote(name)}: ${typeName};`) - // .join("\n")}\n };` - // ]); - // } - // plainTypesCode.writeln([t`export interface types {`]); - // plainTypesCode.writeBuf(plainTypesExportBuf); - // plainTypesCode.writeln([t`}`]); };