Skip to content

Commit

Permalink
Avoid interfaces naming collisions from default module (#888)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaclarke committed Mar 5, 2024
1 parent cd1d76f commit 6c7de1a
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
8 changes: 8 additions & 0 deletions integration-tests/lts/dbschema/default.esdl
Expand Up @@ -197,6 +197,12 @@ module default {
type PgVectorTest {
test_embedding: embedding;
}

module nested {
type Test {
property prop: str;
}
}
};

module `💯💯💯` {
Expand All @@ -212,4 +218,6 @@ module extra {

module User {
scalar type Status extending enum<"Active", "Disabled">;

type User extending default::User;
}
9 changes: 9 additions & 0 deletions integration-tests/lts/dbschema/migrations/00024.edgeql
@@ -0,0 +1,9 @@
CREATE MIGRATION m13x34vijy2dlwl3x5jewnjcxb6tysyo7pr2zbbljadjdi2y5w3cja
ONTO m1tdrrz5jv7b4z7wo532wow2bdkq2oij5lkatt4vkqxfneise7j32q
{
CREATE MODULE default::nested IF NOT EXISTS;
CREATE TYPE User::User EXTENDING default::User;
CREATE TYPE default::nested::Test {
CREATE PROPERTY prop: std::str;
};
};
28 changes: 27 additions & 1 deletion integration-tests/lts/interfaces.test.ts
@@ -1,6 +1,15 @@
import * as tc from "conditional-type-checks";

import type { Movie, W, X, Y, Z } from "./dbschema/interfaces";
import type {
Movie,
W,
X,
Y,
Z,
User,
nested,
$default,
} from "./dbschema/interfaces";

export type Genre =
| "Horror"
Expand Down Expand Up @@ -34,10 +43,27 @@ export interface test_Profile extends BaseObject {
interface test_Z extends BaseObject {
xy?: W | X | Y | null;
}
interface test_User extends BaseObject {
username: string;
favourite_movies: Movie[];
}

describe("interfaces", () => {
test("check generated interfaces", () => {
tc.assert<tc.IsExact<Movie, test_Movie>>(true);
tc.assert<tc.IsExact<Z, test_Z>>(true);

// default module export
tc.assert<tc.IsExact<$default.Movie, Movie>>(true);

// test overlapping namespaces
// default::User type
tc.assert<tc.IsExact<User, test_User>>(true);
// user module
tc.assert<tc.IsExact<User.Status, "Active" | "Disabled">>(true);
tc.assert<tc.IsExact<User.User, User>>(true);

// module nested in default module
tc.assert<tc.IsExact<nested.Test["prop"], string | null | undefined>>(true);
});
});
54 changes: 32 additions & 22 deletions packages/generate/src/edgeql-js/generateInterfaces.ts
@@ -1,4 +1,4 @@
import { CodeBuffer, js, t } from "../builders";
import { CodeBuffer, t } from "../builders";
import type { GeneratorParams } from "../genutil";
import { $ } from "../genutil";
import { makePlainIdent, quote, splitName, toTSScalarType } from "../genutil";
Expand Down Expand Up @@ -32,8 +32,7 @@ export const generateInterfaces = (params: GenerateInterfacesParams) => {
const modName = modParts[modParts.length - 1];
const parentModName = modParts.slice(0, -1).join("::");
const parent = parentModName ? getModule(parentModName) : null;
const internalName =
modName === "default" && !parentModName ? "" : makePlainIdent(modName);
const internalName = makePlainIdent(modName);

module = {
name: modName,
Expand Down Expand Up @@ -73,9 +72,8 @@ export const generateInterfaces = (params: GenerateInterfacesParams) => {
(typeName: string, withModule: boolean = false): string => {
const { tMod, tName, module } = getPlainTypeModule(typeName);
return (
((mod !== tMod || withModule) && tMod !== "default"
? `${module.fullInternalName}.`
: "") + `${makePlainIdent(tName)}`
(mod !== tMod || withModule ? `${module.fullInternalName}.` : "") +
`${makePlainIdent(tName)}`
);
};

Expand All @@ -100,7 +98,7 @@ export const generateInterfaces = (params: GenerateInterfacesParams) => {
const isUnionType = Boolean(type.union_of?.length);
const isIntersectionType = Boolean(type.intersection_of?.length);

if (isIntersectionType) {
if (isIntersectionType || isUnionType) {
continue;
}

Expand Down Expand Up @@ -140,12 +138,10 @@ export const generateInterfaces = (params: GenerateInterfacesParams) => {
const { module: plainTypeModule } = getPlainTypeModule(type.name);
const pointers = type.pointers.filter((ptr) => ptr.name !== "__type__");

if (!isUnionType) {
plainTypeModule.types.set(name, getTypeName(type.name, true));
}
plainTypeModule.types.set(name, getTypeName(type.name, true));

plainTypeModule.buf.writeln([
t`${isUnionType ? "" : "export "}interface ${getTypeName(type.name)}${
t`export interface ${getTypeName(type.name)}${
type.bases.length
? ` extends ${type.bases
.map(({ id }) => {
Expand Down Expand Up @@ -178,12 +174,8 @@ export const generateInterfaces = (params: GenerateInterfacesParams) => {
const plainTypesExportBuf = new CodeBuffer();

const writeModuleExports = (module: ModuleData) => {
const wrapInNamespace = !(module.isRoot && module.name === "default");
if (wrapInNamespace) {
plainTypesCode.writeln([t`export namespace ${module.internalName} {`]);
plainTypesCode.writeln([js`const ${module.internalName} = {`]);
plainTypesCode.increaseIndent();
}
plainTypesCode.writeln([t`export namespace ${module.internalName} {`]);
plainTypesCode.increaseIndent();

plainTypesCode.writeBuf(module.buf);

Expand All @@ -200,11 +192,29 @@ export const generateInterfaces = (params: GenerateInterfacesParams) => {
plainTypesExportBuf.decreaseIndent();
plainTypesExportBuf.writeln([t`};`]);

if (wrapInNamespace) {
plainTypesCode.decreaseIndent();
plainTypesCode.writeln([t`}`]);
plainTypesCode.writeln([js`}`]);
plainTypesCode.addExport(module.internalName, { modes: ["js"] });
plainTypesCode.decreaseIndent();
plainTypesCode.writeln([t`}`]);
plainTypesCode.addExport(module.internalName, { modes: ["js"] });

if (module.isRoot && module.name === "default") {
const typeRefs = [
...module.types.values(),
...[...module.nestedModules.values()].map(
(nestedMod) => nestedMod.fullInternalName
),
];
for (const typeRef of typeRefs) {
plainTypesCode.writeln([
`import ${typeRef.slice(
module.internalName.length + 1
)} = ${typeRef};`,
]);
}
plainTypesCode.writeln([
`export {${typeRefs
.map((typeRef) => typeRef.slice(module.internalName.length + 1))
.join(", ")}};`,
]);
}
};

Expand Down

0 comments on commit 6c7de1a

Please sign in to comment.