Skip to content

Commit

Permalink
Support formatting generated code by Prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalLytek committed Apr 12, 2023
1 parent 7776d4c commit 8cb09b5
Show file tree
Hide file tree
Showing 12 changed files with 586 additions and 11 deletions.
15 changes: 15 additions & 0 deletions .cli.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
tsconfig*.json

build
lib
package

coverage
tests/artifacts

.docusaurus

**/prisma/generated/**/*
**/prisma/migrations/**/*
prisma-client-mock.js
prisma-client-mock.d.ts
12 changes: 9 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
tsconfig*.json
lib/**/*
package/**/*
tests/artifacts

build
lib
package

coverage
# tests/artifacts

.docusaurus

**/prisma/generated/**/*
**/prisma/migrations/**/*
prisma-client-mock.js
Expand Down
36 changes: 36 additions & 0 deletions docs/basics/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,39 @@ generator typegraphql {
emitTranspiledCode = true
}
```

## Formatting generated code

By default, the generated code is formatted by TypeScript compiler while emitting.

However, if you prefer some other code style, you can provide `formatGeneratedCode` generator option to format the codebase with [Prettier](https://prettier.io/):

```prisma {4}
generator typegraphql {
provider = "typegraphql-prisma"
output = "../prisma/generated/type-graphql"
formatGeneratedCode = "prettier"
}
```

Prettier will look for the configuration file in your project tree and use it to format the generated code. If no config file detected, default settings will be applied.

:::caution
Be aware that formatting code by Prettier has a quite huge impact on the generation time, so use it with caution.
:::

If you git-ignore the generated files or you don't want to read the generated source code, you can ignore the generated code style and disable the formatting at all - by providing `false` value to `formatGeneratedCode` generator option:

```prisma {4}
generator typegraphql {
provider = "typegraphql-prisma"
output = "../prisma/generated/type-graphql"
formatGeneratedCode = false
}
```

This way you can save even up to 33% of the generation process time.

:::info
When the generator is configured to emit transpiled code, the generated JS code is always formatted by TypeScript compiler and you can't change it to Prettier or disable the formatting by the `formatGeneratedCode` option.
:::
1 change: 1 addition & 0 deletions experiments/postgres/prisma/generated/client/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ generator typegraphql {
contextPrismaKey = "prismaClient"
useSimpleInputs = true
emitRedundantTypesInfo = true
formatGeneratedCode = "tsc"
}

// Role enum comment
Expand Down
1 change: 1 addition & 0 deletions experiments/postgres/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ generator typegraphql {
contextPrismaKey = "prismaClient"
useSimpleInputs = true
emitRedundantTypesInfo = true
formatGeneratedCode = "tsc"
}

// Role enum comment
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
"check:type": "tsc --noEmit",
"check:experiments:postgres": "cd ./experiments/postgres && tsc --noEmit",
"check:experiments:mongodb": "cd ./experiments/mongodb && tsc --noEmit",
"check:format": "prettier --check ./**/*.{js,json,ts,tsx}",
"check:format": "prettier --ignore-path ./.cli.prettierignore --check ./**/*.{js,json,ts,tsx}",
"test": "ts-node ./tests/helpers/setup-tests.ts && jest --watch --verbose",
"test:integration": "ts-node ./tests/helpers/setup-tests.ts && env-cmd jest --watch --verbose --config ./jest.config.integration.ts",
"test:ci": "ts-node ./tests/helpers/setup-tests.ts && jest --coverage --verbose --runInBand && jest --coverage --verbose --runInBand --config ./jest.config.integration.ts",
"format": "prettier --write ./**/*.{js,json,ts,tsx}"
"format": "prettier --ignore-path ./.cli.prettierignore --write ./**/*.{js,json,ts,tsx}"
},
"bin": {
"typegraphql-prisma": "lib/generator.js"
Expand All @@ -39,7 +39,7 @@
"devDependencies": {
"@jest/types": "^29.5.0",
"@prisma/client": "~4.12.0",
"@prisma/fetch-engine": "4.12.0",
"@prisma/fetch-engine": "~4.12.0",
"@types/graphql-fields": "^1.3.5",
"@types/jest": "^29.5.0",
"@types/node": "^18.15.11",
Expand Down
24 changes: 22 additions & 2 deletions src/cli/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
export function parseStringBoolean(stringBoolean: string | undefined) {
return stringBoolean ? stringBoolean === "true" : undefined;
return stringBoolean === "true"
? true
: stringBoolean === "false"
? false
: undefined;
}

export function parseStringArray<TAllowedValue extends string>(
stringArray: string | undefined,
optionPropertyName: string,
allowedValues?: TAllowedValue[],
allowedValues?: readonly TAllowedValue[],
): TAllowedValue[] | undefined {
if (!stringArray) {
return undefined;
Expand All @@ -22,3 +26,19 @@ export function parseStringArray<TAllowedValue extends string>(
}
return parsedArray as TAllowedValue[];
}

export function parseStringEnum<TAllowedValue extends string>(
stringEnum: string | undefined,
optionPropertyName: string,
allowedValues: readonly TAllowedValue[],
): TAllowedValue | undefined {
if (!stringEnum) {
return undefined;
}
if (!allowedValues.includes(stringEnum as any)) {
throw new Error(
`Invalid "${optionPropertyName}" option value "${stringEnum}" provided for TypeGraphQL generator.`,
);
}
return stringEnum as TAllowedValue;
}
13 changes: 12 additions & 1 deletion src/cli/prisma-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import {
InternalGeneratorOptions,
} from "../generator/options";
import { ALL_EMIT_BLOCK_KINDS } from "../generator/emit-block";
import { parseStringBoolean, parseStringArray } from "./helpers";
import {
parseStringBoolean,
parseStringArray,
parseStringEnum,
} from "./helpers";

export async function generate(options: GeneratorOptions) {
const outputDir = parseEnvValue(options.generator.output!);
Expand Down Expand Up @@ -56,6 +60,13 @@ export async function generate(options: GeneratorOptions) {
generatorConfig.omitOutputFieldsByDefault,
"omitOutputFieldsByDefault",
),
formatGeneratedCode:
parseStringBoolean(generatorConfig.formatGeneratedCode) ??
parseStringEnum(
generatorConfig.formatGeneratedCode,
"formatGeneratedCode",
["prettier", "tsc"] as const,
),
};
const internalConfig: InternalGeneratorOptions = {
outputDirPath: outputDir,
Expand Down
13 changes: 11 additions & 2 deletions src/generator/generate-code.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { DMMF as PrismaDMMF } from "@prisma/client/runtime";
import { Project, ScriptTarget, ModuleKind, CompilerOptions } from "ts-morph";
import path from "path";
import { exec } from "node:child_process";
import { promisify } from "node:util";
const execa = promisify(exec);

import { noop, toUnixPath } from "./helpers";
import generateEnumFromDef from "./enum";
Expand Down Expand Up @@ -76,6 +79,7 @@ export default async function generateCode(
baseOptions.prismaClientPath.includes("node_modules")
? "@prisma/client"
: undefined,
formatGeneratedCode: baseOptions.formatGeneratedCode ?? "tsc", // default for backward compatibility
};

const baseDirPath = options.outputDirPath;
Expand Down Expand Up @@ -527,9 +531,14 @@ export default async function generateCode(
if (emitTranspiledCode) {
await project.emit();
} else {
for (const file of project.getSourceFiles()) {
file.formatText({ indentSize: 2 });
if (options.formatGeneratedCode === "tsc") {
for (const file of project.getSourceFiles()) {
file.formatText({ indentSize: 2 });
}
}
await project.save();
if (options.formatGeneratedCode === "prettier") {
await execa(`npx prettier --write ${baseDirPath}`);
}
}
}
1 change: 1 addition & 0 deletions src/generator/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface ExternalGeneratorOptions {
useSimpleInputs?: boolean;
omitInputFieldsByDefault?: string[];
omitOutputFieldsByDefault?: string[];
formatGeneratedCode?: boolean | "prettier" | "tsc";
}

export interface InternalGeneratorOptions {
Expand Down
Loading

0 comments on commit 8cb09b5

Please sign in to comment.