Skip to content

Commit

Permalink
Support generating ESM output
Browse files Browse the repository at this point in the history
Setting `emitESM=true` in the generator's configuration will switch from
using `require` to `import` calls in the generated code.

I haven't been successful in actually using the ESM output. Bi-directional
relationships between models lead to circular dependencies in
`*WhereInput` and `*ListRelationFilter` and cause the following error at
start-up:

> ReferenceError: Cannot access 'FooWhereInput' before initialization
>     at file:///app/node_modules/@generated/type-graphql/resolvers/inputs/FooListRelationFilter.js:10:31

Regardless of ESM setting, create a package.json if generating into
node_modules. This makes sure that the generated code doesn't inherit a
parent package's `type`.
  • Loading branch information
nigelzor committed May 18, 2023
1 parent 6784f3f commit ef99728
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 51 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/cli/prisma-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export async function generate(options: GeneratorOptions) {
"formatGeneratedCode",
["prettier", "tsc"] as const,
),
emitESM: parseStringBoolean(generatorConfig.emitESM),
};
const internalConfig: InternalGeneratorOptions = {
outputDirPath: outputDir,
Expand Down
2 changes: 2 additions & 0 deletions src/generator/args-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default function generateArgsTypeClassFromArgs(
generateGraphQLScalarsImport(sourceFile);
generateInputsImports(
sourceFile,
dmmfDocument.options,
fields
.map(arg => arg.selectedInputType)
.filter(argInputType => argInputType.location === "inputObjectTypes")
Expand All @@ -42,6 +43,7 @@ export default function generateArgsTypeClassFromArgs(
);
generateEnumsImports(
sourceFile,
dmmfDocument.options,
fields
.map(field => field.selectedInputType)
.filter(argType => argType.location === "enumTypes")
Expand Down
48 changes: 45 additions & 3 deletions src/generator/generate-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ export default async function generateCode(
const project = new Project({
compilerOptions: {
...baseCompilerOptions,
...(options.emitESM && {
module: ModuleKind.ES2020,
}),
...(emitTranspiledCode && {
declaration: true,
importHelpers: true,
Expand Down Expand Up @@ -122,7 +125,11 @@ export default async function generateCode(
undefined,
{ overwrite: true },
);
generateEnumsBarrelFile(enumsBarrelExportSourceFile, emittedEnumNames);
generateEnumsBarrelFile(
enumsBarrelExportSourceFile,
dmmfDocument.options,
emittedEnumNames,
);
}

if (dmmfDocument.shouldGenerateBlock("models")) {
Expand All @@ -146,6 +153,7 @@ export default async function generateCode(
);
generateModelsBarrelFile(
modelsBarrelExportSourceFile,
dmmfDocument.options,
dmmfDocument.datamodel.models.map(it => it.typeName),
);
}
Expand Down Expand Up @@ -186,6 +194,7 @@ export default async function generateCode(
);
generateOutputsBarrelFile(
outputsBarrelExportSourceFile,
dmmfDocument.options,
outputTypesToGenerate.map(it => it.typeName),
outputTypesFieldsArgsToGenerate.length > 0,
);
Expand Down Expand Up @@ -215,6 +224,7 @@ export default async function generateCode(
);
generateArgsBarrelFile(
outputsArgsBarrelExportSourceFile,
dmmfDocument.options,
outputTypesFieldsArgsToGenerate.map(it => it.argsTypeName!),
);
}
Expand All @@ -237,6 +247,7 @@ export default async function generateCode(
);
generateInputsBarrelFile(
inputsBarrelExportSourceFile,
dmmfDocument.options,
dmmfDocument.schema.inputTypes.map(it => it.typeName),
);
}
Expand Down Expand Up @@ -267,6 +278,7 @@ export default async function generateCode(
);
generateResolversBarrelFile(
relationResolversBarrelExportSourceFile,
dmmfDocument.options,
dmmfDocument.relationModels.map<GenerateMappingData>(relationModel => ({
resolverName: relationModel.resolverName,
modelName: relationModel.model.typeName,
Expand Down Expand Up @@ -302,7 +314,11 @@ export default async function generateCode(
undefined,
{ overwrite: true },
);
generateArgsBarrelFile(barrelExportSourceFile, argTypeNames);
generateArgsBarrelFile(
barrelExportSourceFile,
dmmfDocument.options,
argTypeNames,
);
}
});

Expand All @@ -325,6 +341,7 @@ export default async function generateCode(
);
generateArgsIndexFile(
relationResolversArgsIndexSourceFile,
dmmfDocument.options,
relationModelsWithArgs.map(
relationModelData => relationModelData.model.typeName,
),
Expand All @@ -342,6 +359,7 @@ export default async function generateCode(
);
generateResolversIndexFile(
relationResolversIndexSourceFile,
dmmfDocument.options,
"relations",
relationModelsWithArgs.length > 0,
);
Expand Down Expand Up @@ -399,6 +417,7 @@ export default async function generateCode(
);
generateResolversBarrelFile(
crudResolversBarrelExportSourceFile,
dmmfDocument.options,
generateMappingData,
);
const crudResolversActionsBarrelExportSourceFile = project.createSourceFile(
Expand All @@ -413,6 +432,7 @@ export default async function generateCode(
);
generateResolversActionsBarrelFile(
crudResolversActionsBarrelExportSourceFile,
dmmfDocument.options,
generateMappingData,
);
const crudResolversIndexSourceFile = project.createSourceFile(
Expand All @@ -425,7 +445,12 @@ export default async function generateCode(
undefined,
{ overwrite: true },
);
generateResolversIndexFile(crudResolversIndexSourceFile, "crud", true);
generateResolversIndexFile(
crudResolversIndexSourceFile,
dmmfDocument.options,
"crud",
true,
);

log("Generating crud resolvers args...");
dmmfDocument.modelMappings.forEach(async mapping => {
Expand Down Expand Up @@ -459,6 +484,7 @@ export default async function generateCode(
);
generateArgsBarrelFile(
barrelExportSourceFile,
dmmfDocument.options,
actionsWithArgs.map(it => it.argsTypeName!),
);
}
Expand All @@ -475,6 +501,7 @@ export default async function generateCode(
);
generateArgsIndexFile(
crudResolversArgsIndexSourceFile,
dmmfDocument.options,
dmmfDocument.modelMappings
.filter(mapping =>
mapping.actions.some(it => it.argsTypeName !== undefined),
Expand Down Expand Up @@ -523,11 +550,26 @@ export default async function generateCode(
);
generateIndexFile(
indexSourceFile,
dmmfDocument.options,
dmmfDocument.relationModels.length > 0,
dmmfDocument.options.blocksToEmit,
);

log("Emitting generated code files");
if (options.outputDirPath.includes("node_modules")) {
await project.getFileSystem().writeFile(
baseDirPath + "/package.json",
JSON.stringify(
{
type: dmmfDocument.options.emitESM ? "module" : "commonjs",
main: "./index.js",
types: "./index.d.ts",
},
null,
2,
),
);
}
if (emitTranspiledCode) {
await project.emit();
} else {
Expand Down
28 changes: 21 additions & 7 deletions src/generator/generate-enhance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ export function generateEnhanceMap(

if (dmmfDocument.shouldGenerateBlock("crudResolvers")) {
sourceFile.addImportDeclaration({
moduleSpecifier: `./${resolversFolderName}/${crudResolversFolderName}/resolvers-crud.index`,
moduleSpecifier: `./${resolversFolderName}/${crudResolversFolderName}/resolvers-crud.index${
dmmfDocument.options.emitESM ? ".js" : ""
}`,
namespaceImport: "crudResolvers",
});
sourceFile.addImportDeclaration({
moduleSpecifier: `./${resolversFolderName}/${crudResolversFolderName}/args.index`,
moduleSpecifier: `./${resolversFolderName}/${crudResolversFolderName}/args.index${
dmmfDocument.options.emitESM ? ".js" : ""
}`,
namespaceImport: "argsTypes",
});
sourceFile.addVariableStatement({
Expand All @@ -67,7 +71,9 @@ export function generateEnhanceMap(
trailingTrivia: "\r\n",
});
sourceFile.addImportDeclaration({
moduleSpecifier: `./${resolversFolderName}/${crudResolversFolderName}/resolvers-actions.index`,
moduleSpecifier: `./${resolversFolderName}/${crudResolversFolderName}/resolvers-actions.index${
dmmfDocument.options.emitESM ? ".js" : ""
}`,
namespaceImport: "actionResolvers",
});
sourceFile.addVariableStatement({
Expand Down Expand Up @@ -237,7 +243,9 @@ export function generateEnhanceMap(

if (hasRelations && dmmfDocument.shouldGenerateBlock("relationResolvers")) {
sourceFile.addImportDeclaration({
moduleSpecifier: `./${resolversFolderName}/${relationsResolversFolderName}/resolvers.index`,
moduleSpecifier: `./${resolversFolderName}/${relationsResolversFolderName}/resolvers.index${
dmmfDocument.options.emitESM ? ".js" : ""
}`,
namespaceImport: "relationResolvers",
});
sourceFile.addVariableStatement({
Expand Down Expand Up @@ -367,7 +375,9 @@ export function generateEnhanceMap(

if (dmmfDocument.shouldGenerateBlock("models")) {
sourceFile.addImportDeclaration({
moduleSpecifier: `./${modelsFolderName}`,
moduleSpecifier: `./${modelsFolderName}${
dmmfDocument.options.emitESM ? "/index.js" : ""
}`,
namespaceImport: "models",
});
sourceFile.addVariableStatement({
Expand Down Expand Up @@ -435,7 +445,9 @@ export function generateEnhanceMap(

if (dmmfDocument.shouldGenerateBlock("outputs")) {
sourceFile.addImportDeclaration({
moduleSpecifier: `./${resolversFolderName}/${outputsFolderName}`,
moduleSpecifier: `./${resolversFolderName}/${outputsFolderName}${
dmmfDocument.options.emitESM ? "/index.js" : ""
}`,
namespaceImport: "outputTypes",
});
sourceFile.addVariableStatement({
Expand Down Expand Up @@ -497,7 +509,9 @@ export function generateEnhanceMap(

if (dmmfDocument.shouldGenerateBlock("inputs")) {
sourceFile.addImportDeclaration({
moduleSpecifier: `./${resolversFolderName}/${inputsFolderName}`,
moduleSpecifier: `./${resolversFolderName}/${inputsFolderName}${
dmmfDocument.options.emitESM ? "/index.js" : ""
}`,
namespaceImport: "inputTypes",
});
sourceFile.addVariableStatement({
Expand Down
Loading

0 comments on commit ef99728

Please sign in to comment.