Skip to content

Commit

Permalink
feat: add support for output types
Browse files Browse the repository at this point in the history
  • Loading branch information
rfermann committed Apr 19, 2021
1 parent c67398d commit 7f6f203
Show file tree
Hide file tree
Showing 13 changed files with 642 additions and 47 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ generator nestjs {
- Enums
- Models
- Input Types
- Output Types

## Usage

All supported objects can be used as the regular NestJS GraphQL object equivalents.

## Upcoming features

- Output Types
- Resolvers
- [Prisma Select](https://paljs.com/plugins/select/) integration

Expand Down
9 changes: 8 additions & 1 deletion src/Generator/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe("Generator", () => {
expect([...folderList]).toStrictEqual(["enums", "Session", "shared", "User"]);
});
it("should log the correct actions", async () => {
expect.assertions(23);
expect.assertions(29);

const generator = new Generator({
datamodel: "",
Expand Down Expand Up @@ -137,5 +137,12 @@ describe("Generator", () => {
expect(findCompletedMessage(values, Generator.messages.inputTypes.parse)).toHaveLength(1);
expect(findStartedMessage(values, Generator.messages.inputTypes.generate)).toHaveLength(1);
expect(findCompletedMessage(values, Generator.messages.inputTypes.generate)).toHaveLength(1);

expect(findStartedMessage(values, Generator.messages.outputTypes.title)).toHaveLength(1);
expect(findCompletedMessage(values, Generator.messages.outputTypes.title)).toHaveLength(1);
expect(findStartedMessage(values, Generator.messages.outputTypes.parse)).toHaveLength(1);
expect(findCompletedMessage(values, Generator.messages.outputTypes.parse)).toHaveLength(1);
expect(findStartedMessage(values, Generator.messages.outputTypes.generate)).toHaveLength(1);
expect(findCompletedMessage(values, Generator.messages.outputTypes.generate)).toHaveLength(1);
});
});
26 changes: 26 additions & 0 deletions src/Generator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GeneratorConfig } from "../GeneratorConfig";
import { EnumHandler } from "../Handlers/EnumHandler";
import { InputTypeHandler } from "../Handlers/InputTypeHandler";
import { ModelHandler } from "../Handlers/ModelHandler";
import { OutputTypeHandler } from "../Handlers/OutputTypeHandler";
import { importDmmf } from "../helpers";

export class Generator {
Expand All @@ -29,6 +30,11 @@ export class Generator {
title: "Parsing and generating Models",
},
objects: "Processing Models, Object Types and Resolvers",
outputTypes: {
generate: "Generating Output Types",
parse: "Parsing Output Types",
title: "Parsing and generating Output Types",
},
title: "Generating NestJS integration",
};

Expand All @@ -40,6 +46,8 @@ export class Generator {

private _inputTypeHandler!: InputTypeHandler;

private _outputTypeHandler!: OutputTypeHandler;

private _modelHandler!: ModelHandler;

constructor({ generator, otherGenerators }: GeneratorOptions) {
Expand Down Expand Up @@ -77,6 +85,7 @@ export class Generator {
title: Generator.messages.enums.title,
},
{
// eslint-disable-next-line max-lines-per-function
task: async () =>
new Listr(
[
Expand Down Expand Up @@ -112,6 +121,22 @@ export class Generator {
]),
title: Generator.messages.inputTypes.title,
},
{
task: async () =>
new Listr([
{
task: () => this._outputTypeHandler.parse(this._enumHandler.getEnums()),
title: Generator.messages.outputTypes.parse,
},
{
task: async () => {
await this._outputTypeHandler.createFiles();
},
title: Generator.messages.outputTypes.generate,
},
]),
title: Generator.messages.outputTypes.title,
},
],
{ concurrent: true }
),
Expand Down Expand Up @@ -139,6 +164,7 @@ export class Generator {
this._enumHandler = new EnumHandler({ config: this._config, dmmf: this._dmmf });
this._modelHandler = new ModelHandler({ config: this._config, dmmf: this._dmmf });
this._inputTypeHandler = new InputTypeHandler({ config: this._config, dmmf: this._dmmf });
this._outputTypeHandler = new OutputTypeHandler({ config: this._config, dmmf: this._dmmf });

await this._initOutputFolder();
}
Expand Down
2 changes: 2 additions & 0 deletions src/GeneratorConfig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ interface Paths {
enums: string;
inputTypes: string;
model: string;
outputTypes: string;
shared: string;
}

Expand Down Expand Up @@ -35,6 +36,7 @@ export class GeneratorConfig {
enums: "enums",
inputTypes: "inputTypes",
model: "model",
outputTypes: "outputTypes",
shared: "shared",
};
this.prismaClientImportPath = prismaClientPath.output.value;
Expand Down
66 changes: 29 additions & 37 deletions src/Handlers/BaseHandler/BaseFileGenerator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class BaseFileGenerator {
addEnumImports({ enums, sourceFile, type }: { enums: string[]; sourceFile: SourceFile; type: TypeEnum }): void {
let moduleSpecifier = "";

if (type === TypeEnum.InputType) {
if (type === TypeEnum.InputType || type === TypeEnum.OutputType) {
moduleSpecifier = `../../${this._config.paths.enums}`;
}

Expand All @@ -59,42 +59,6 @@ export class BaseFileGenerator {
});
}

addInputTypeImports({
inputTypes,
model,
sourceFile,
}: {
inputTypes: string[];
model?: string;
sourceFile: SourceFile;
}): void {
inputTypes.sort(comparePrimitiveValues).forEach((inputType) => {
let moduleSpecifier = "";
const currentModel = this._baseParser.getModelName(inputType);

if (model && model === currentModel) {
moduleSpecifier = `.`;
}

if (model && currentModel && model !== currentModel) {
moduleSpecifier = `../../${currentModel}/${this._config.paths.inputTypes}`;
}

if (!model && !currentModel) {
moduleSpecifier = `.`;
}

if (model && !currentModel) {
moduleSpecifier = `../../${this._config.paths.shared}/${this._config.paths.inputTypes}`;
}

sourceFile.addImportDeclaration({
moduleSpecifier: `${moduleSpecifier}/${inputType}`,
namedImports: [inputType],
});
});
}

// eslint-disable-next-line class-methods-use-this
addJsonImports({ sourceFile }: { sourceFile: SourceFile }): void {
sourceFile.addImportDeclaration({
Expand Down Expand Up @@ -143,6 +107,34 @@ export class BaseFileGenerator {
nestJSImportDeclaration.addNamedImports(Array.from(new Set(imports)).sort(comparePrimitiveValues));
}

addTypeImports({ sourceFile, types, model }: { model?: string; sourceFile: SourceFile; types: string[] }): void {
types.sort(comparePrimitiveValues).forEach((type) => {
let moduleSpecifier = "";
const currentModel = this._baseParser.getModelName(type);

if (model && model === currentModel) {
moduleSpecifier = `.`;
}

if (model && currentModel && model !== currentModel) {
moduleSpecifier = `../../${currentModel}/${this._config.paths.inputTypes}`;
}

if (!model && !currentModel) {
moduleSpecifier = `.`;
}

if (model && !currentModel) {
moduleSpecifier = `../../${this._config.paths.shared}/${this._config.paths.inputTypes}`;
}

sourceFile.addImportDeclaration({
moduleSpecifier: `${moduleSpecifier}/${type}`,
namedImports: [type],
});
});
}

createSourceFile(name: string): SourceFile {
return this._project.createSourceFile(`${this._config.basePath}/${name}.ts`, undefined, {
overwrite: true,
Expand Down
13 changes: 9 additions & 4 deletions src/Handlers/BaseHandler/BaseParser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class BaseParser {
NestJSTypes.Int as string,
]);

readonly outputTypeList: Set<string> = new Set();

readonly prismaImport = "Prisma";

constructor(dmmf: DMMF.Document) {
Expand All @@ -53,6 +55,9 @@ export class BaseParser {
this.inputTypeList.add(name);
});
this.modelsList = this.dmmf.datamodel.models.map(({ name }) => name);
this.dmmf.schema.outputObjectTypes.prisma.forEach(({ name }) => {
this.outputTypeList.add(name);
});
}

getEnumImports({
Expand All @@ -62,7 +67,7 @@ export class BaseParser {
enumImports: Set<string>;
field: {
location: DMMF.FieldLocation;
type: DMMF.ArgType;
type: DMMF.ArgType | DMMF.SchemaField["outputType"]["type"];
};
}): Set<string> {
if (location === "enumTypes") {
Expand All @@ -73,7 +78,7 @@ export class BaseParser {
}

// eslint-disable-next-line class-methods-use-this
getEnumName(type: DMMF.ArgType): string {
getEnumName(type: DMMF.ArgType | DMMF.SchemaField["outputType"]["type"]): string {
if (typeof type === "string") {
return `${type.replace("Enum", "")}Enum`;
}
Expand Down Expand Up @@ -135,7 +140,7 @@ export class BaseParser {
}: {
field: {
location: DMMF.FieldLocation;
type: DMMF.ArgType;
type: DMMF.ArgType | DMMF.SchemaField["outputType"]["type"];
};
jsonImports: Set<string>;
tsType: string;
Expand Down Expand Up @@ -164,7 +169,7 @@ export class BaseParser {
let modelName: ReturnType<BaseParser["getModelName"]>;

this.modelsList.forEach((model) => {
if (input.startsWith(model)) {
if (input.startsWith(model) || input.endsWith(model)) {
modelName = model;
}
});
Expand Down
2 changes: 2 additions & 0 deletions src/Handlers/InputTypeHandler/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe("InputTypeHandler", () => {
enums: "enums",
inputTypes: "inputTypes",
model: "model",
outputTypes: "outputTypes",
shared: "shared",
},
prismaClientImportPath: `${process.cwd()}/node_modules/@prisma/client`,
Expand Down Expand Up @@ -73,6 +74,7 @@ describe("InputTypeHandler", () => {
enums: "enums",
inputTypes: "inputTypes",
model: "model",
outputTypes: "outputTypes",
shared: "shared",
},
prismaClientImportPath: `${process.cwd()}/node_modules/@prisma/client`,
Expand Down
4 changes: 2 additions & 2 deletions src/Handlers/InputTypeHandler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export class InputTypeHandler extends BaseHandler {
}

if (inputTypeImports && inputTypeImports.length > 0) {
this.baseFileGenerator.addInputTypeImports({
inputTypes: inputTypeImports,
this.baseFileGenerator.addTypeImports({
model,
sourceFile,
types: inputTypeImports,
});
}

Expand Down
1 change: 1 addition & 0 deletions src/Handlers/ModelHandler/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe("ModelHandler", () => {
enums: "enums",
inputTypes: "",
model: "model",
outputTypes: "outputTypes",
shared: "",
},
prismaClientImportPath: `${process.cwd()}/node_modules/@prisma/client`,
Expand Down

0 comments on commit 7f6f203

Please sign in to comment.