From 5d4ee2be8b8bbb703560f2282720a7388116f35c Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 11 Mar 2024 19:08:16 -0500 Subject: [PATCH] Fix collision in QB with nested object & module names (#900) --- integration-tests/lts/dbschema/default.esdl | 13 ++++++ .../lts/dbschema/migrations/00025.edgeql | 14 ++++++ packages/generate/src/builders.ts | 45 ++++++++++++++++--- 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 integration-tests/lts/dbschema/migrations/00025.edgeql diff --git a/integration-tests/lts/dbschema/default.esdl b/integration-tests/lts/dbschema/default.esdl index 6db426ae4..0c3f1595a 100644 --- a/integration-tests/lts/dbschema/default.esdl +++ b/integration-tests/lts/dbschema/default.esdl @@ -220,4 +220,17 @@ module User { scalar type Status extending enum<"Active", "Disabled">; type User extending default::User; + + type Profile { + link address -> User::Profile::MailingAddress; + } + + module Profile { + type MailingAddress { + property street -> str; + property city -> str; + property state -> str; + property zip -> str; + } + } } diff --git a/integration-tests/lts/dbschema/migrations/00025.edgeql b/integration-tests/lts/dbschema/migrations/00025.edgeql new file mode 100644 index 000000000..269b2008b --- /dev/null +++ b/integration-tests/lts/dbschema/migrations/00025.edgeql @@ -0,0 +1,14 @@ +CREATE MIGRATION m1rjlewu5fimvn4lf4xguullcbvlttuxmtxyl4yz4dmsbyw5shva7a + ONTO m13x34vijy2dlwl3x5jewnjcxb6tysyo7pr2zbbljadjdi2y5w3cja +{ + CREATE MODULE User::Profile IF NOT EXISTS; + CREATE TYPE User::Profile::MailingAddress { + CREATE PROPERTY city: std::str; + CREATE PROPERTY state: std::str; + CREATE PROPERTY street: std::str; + CREATE PROPERTY zip: std::str; + }; + CREATE TYPE User::Profile { + CREATE LINK address: User::Profile::MailingAddress; + }; +}; diff --git a/packages/generate/src/builders.ts b/packages/generate/src/builders.ts index 37ec62567..419bcc225 100644 --- a/packages/generate/src/builders.ts +++ b/packages/generate/src/builders.ts @@ -488,12 +488,22 @@ class BuilderImportsExports { exports.push(`export type { ${exportTypes.join(", ")} };\n`); } if (refsDefault.length || forceDefaultExport) { + const refsByExportAs = [...groupToMapBy(refsDefault, (x) => x.as)].map( + ([as, group]) => ({ + as, + refs: group.map(({ ref }) => ref).reverse(), + }) + ); if (mode === "ts" || mode === "dts") { exports.push( `${ mode === "dts" ? "declare " : "" - }type __defaultExports = {\n${refsDefault - .map(({ ref, as }) => ` ${genutil.quote(as)}: typeof ${ref}`) + }type __defaultExports = {\n${refsByExportAs + .map(({ refs, as }) => { + const key = genutil.quote(as); + const value = refs.map((ref) => `typeof ${ref}`).join(" & "); + return ` ${key}: ${value}`; + }) .join(";\n")}\n};` ); } @@ -501,8 +511,17 @@ class BuilderImportsExports { exports.push( `const __defaultExports${ mode === "ts" ? ": __defaultExports" : "" - } = {\n${refsDefault - .map(({ ref, as }) => ` ${genutil.quote(as)}: ${ref}`) + } = {\n${refsByExportAs + .map(({ refs, as }) => { + const key = genutil.quote(as); + const value = + refs.length === 1 + ? refs + : `Object.freeze({ ${refs + .map((ref) => `...${ref}`) + .join(", ")} })`; + return ` ${key}: ${value}`; + }) .join(",\n")}\n};` ); } @@ -603,15 +622,16 @@ export class CodeBuilder { let prefix = ""; if (ref.dir !== this.dir) { - const mod = path.posix.basename(ref.dir, path.posix.extname(ref.dir)); - prefix = `_${mod}`; + const namespaceParts = identRef.name.split("::").slice(0, -1); + prefix = `_${namespaceParts.join("")}`; + const moduleFileName = namespaceParts.at(-1)!; let importPath = path.posix.join( path.posix.relative( path.posix.dirname(this.dir), path.posix.dirname(ref.dir) ), - mod + moduleFileName ); if (!importPath.startsWith("../")) { @@ -846,3 +866,14 @@ export class DirBuilder { } } } + +const groupToMapBy = ( + items: Iterable, + by: (item: V) => K +): ReadonlyMap => + [...items].reduce((map, item) => { + const groupKey = by(item); + const prev = map.get(groupKey) ?? []; + map.set(groupKey, [...prev, item]); + return map; + }, new Map());