Skip to content

fix: canonicalize plugin's output folder detection; don't generate aux field unnecessarily #423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions packages/plugins/openapi/src/generator-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { DMMF } from '@prisma/generator-helper';
import { PluginError, PluginOptions, getDataModels, hasAttribute } from '@zenstackhq/sdk';
import { Model } from '@zenstackhq/sdk/ast';
import type { OpenAPIV3_1 as OAPI } from 'openapi-types';
import { SecuritySchemesSchema } from './schema';
import { fromZodError } from 'zod-validation-error';
import { SecuritySchemesSchema } from './schema';

export abstract class OpenAPIGeneratorBase {
constructor(protected model: Model, protected options: PluginOptions, protected dmmf: DMMF.Document) {}
Expand Down Expand Up @@ -51,7 +51,10 @@ export abstract class OpenAPIGeneratorBase {
if (securitySchemes) {
const parsed = SecuritySchemesSchema.safeParse(securitySchemes);
if (!parsed.success) {
throw new PluginError(`"securitySchemes" option is invalid: ${fromZodError(parsed.error)}`);
throw new PluginError(
this.options.name,
`"securitySchemes" option is invalid: ${fromZodError(parsed.error)}`
);
}
return parsed.data;
}
Expand Down
9 changes: 4 additions & 5 deletions packages/plugins/openapi/src/rest-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import { DMMF } from '@prisma/generator-helper';
import {
AUXILIARY_FIELDS,
PluginError,
analyzePolicies,
getDataModels,
isForeignKeyField,
isIdField,
isRelationshipField,
requireOption,
resolvePath,
} from '@zenstackhq/sdk';
import { DataModel, DataModelField, DataModelFieldType, Enum, isDataModel, isEnum } from '@zenstackhq/sdk/ast';
import * as fs from 'fs';
Expand All @@ -30,10 +31,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
private warnings: string[] = [];

generate() {
const output = this.getOption('output', '');
if (!output) {
throw new PluginError('"output" option is required');
}
let output = requireOption<string>(this.options, 'output');
output = resolvePath(output, this.options);

const components = this.generateComponents();
const paths = this.generatePaths();
Expand Down
10 changes: 4 additions & 6 deletions packages/plugins/openapi/src/rpc-generator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Inspired by: https://github.com/omar-dulaimi/prisma-trpc-generator

import { DMMF } from '@prisma/generator-helper';
import { analyzePolicies, AUXILIARY_FIELDS, PluginError } from '@zenstackhq/sdk';
import { analyzePolicies, AUXILIARY_FIELDS, PluginError, requireOption, resolvePath } from '@zenstackhq/sdk';
import { DataModel, isDataModel } from '@zenstackhq/sdk/ast';
import {
addMissingInputObjectTypesForAggregate,
Expand Down Expand Up @@ -31,10 +31,8 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
private warnings: string[] = [];

generate() {
const output = this.getOption('output', '');
if (!output) {
throw new PluginError('"output" option is required');
}
let output = requireOption<string>(this.options, 'output');
output = resolvePath(output, this.options);

// input types
this.inputObjectTypes.push(...this.dmmf.schema.inputObjectTypes.prisma);
Expand Down Expand Up @@ -663,7 +661,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
return this.wrapArray(this.ref(def.type, false), def.isList);

default:
throw new PluginError(`Unsupported field kind: ${def.kind}`);
throw new PluginError(this.options.name, `Unsupported field kind: ${def.kind}`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/react/src/generator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
case 'react-query':
return reactQueryGenerate(model, options, dmmf);
default:
throw new PluginError(`Unknown "fetcher" option: ${fetcher}, use "swr" or "react-query"`);
throw new PluginError(options.name, `Unknown "fetcher" option: ${fetcher}, use "swr" or "react-query"`);
}
}
14 changes: 4 additions & 10 deletions packages/plugins/react/src/generator/react-query.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { DMMF } from '@prisma/generator-helper';
import { PluginError, PluginOptions, createProject, getDataModels, saveProject } from '@zenstackhq/sdk';
import { PluginOptions, createProject, getDataModels, saveProject } from '@zenstackhq/sdk';
import { DataModel, Model } from '@zenstackhq/sdk/ast';
import { requireOption, resolvePath } from '@zenstackhq/sdk/utils';
import { paramCase } from 'change-case';
import { lowerCaseFirst } from 'lower-case-first';
import * as path from 'path';
import { Project, SourceFile, VariableDeclarationKind } from 'ts-morph';
import { upperCaseFirst } from 'upper-case-first';

export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
let outDir = options.output as string;
if (!outDir) {
throw new PluginError('"output" option is required');
}

if (!path.isAbsolute(outDir)) {
// output dir is resolved relative to the schema file path
outDir = path.join(path.dirname(options.schemaPath), outDir);
}
let outDir = requireOption<string>(options, 'output');
outDir = resolvePath(outDir, options);

const project = createProject();
const warnings: string[] = [];
Expand Down
14 changes: 4 additions & 10 deletions packages/plugins/react/src/generator/swr.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { DMMF } from '@prisma/generator-helper';
import {
CrudFailureReason,
PluginError,
PluginOptions,
createProject,
getDataModels,
requireOption,
resolvePath,
saveProject,
} from '@zenstackhq/sdk';
import { DataModel, Model } from '@zenstackhq/sdk/ast';
Expand All @@ -14,15 +15,8 @@ import * as path from 'path';
import { Project } from 'ts-morph';

export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
let outDir = options.output as string;
if (!outDir) {
throw new PluginError('"output" option is required');
}

if (!path.isAbsolute(outDir)) {
// output dir is resolved relative to the schema file path
outDir = path.join(path.dirname(options.schemaPath), outDir);
}
let outDir = requireOption<string>(options, 'output');
outDir = resolvePath(outDir, options);

const project = createProject();
const warnings: string[] = [];
Expand Down
14 changes: 4 additions & 10 deletions packages/plugins/swr/src/generator.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { DMMF } from '@prisma/generator-helper';
import {
CrudFailureReason,
PluginError,
PluginOptions,
createProject,
getDataModels,
requireOption,
resolvePath,
saveProject,
} from '@zenstackhq/sdk';
import { DataModel, Model } from '@zenstackhq/sdk/ast';
Expand All @@ -15,15 +16,8 @@ import path from 'path';
import { Project } from 'ts-morph';

export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
let outDir = options.output as string;
if (!outDir) {
throw new PluginError('"output" option is required');
}

if (!path.isAbsolute(outDir)) {
// output dir is resolved relative to the schema file path
outDir = path.join(path.dirname(options.schemaPath), outDir);
}
let outDir = requireOption<string>(options, 'output');
outDir = resolvePath(outDir, options);

const project = createProject();
const warnings: string[] = [];
Expand Down
44 changes: 23 additions & 21 deletions packages/plugins/tanstack-query/src/generator.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { DMMF } from '@prisma/generator-helper';
import { PluginError, PluginOptions, createProject, getDataModels, saveProject } from '@zenstackhq/sdk';
import {
PluginError,
PluginOptions,
createProject,
getDataModels,
requireOption,
resolvePath,
saveProject,
} from '@zenstackhq/sdk';
import { DataModel, Model } from '@zenstackhq/sdk/ast';
import { paramCase } from 'change-case';
import fs from 'fs';
import { lowerCaseFirst } from 'lower-case-first';
import path from 'path';
import { Project, SourceFile, VariableDeclarationKind } from 'ts-morph';
import { upperCaseFirst } from 'upper-case-first';
import { name } from '.';

const supportedTargets = ['react', 'svelte'];
type TargetFramework = (typeof supportedTargets)[number];

export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
let outDir = options.output as string;
if (!outDir) {
throw new PluginError('"output" option is required');
}

if (!path.isAbsolute(outDir)) {
// output dir is resolved relative to the schema file path
outDir = path.join(path.dirname(options.schemaPath), outDir);
}
let outDir = requireOption<string>(options, 'output');
outDir = resolvePath(outDir, options);

const project = createProject();
const warnings: string[] = [];
const models = getDataModels(model);

const target = options.target as string;
if (!target) {
throw new PluginError(`"target" option is required, supported values: ${supportedTargets.join(', ')}`);
}
const target = requireOption<string>(options, 'target');
if (!supportedTargets.includes(target)) {
throw new PluginError(`Unsupported target "${target}", supported values: ${supportedTargets.join(', ')}`);
throw new PluginError(
options.name,
`Unsupported target "${target}", supported values: ${supportedTargets.join(', ')}`
);
}

generateIndex(project, outDir, models);
Expand Down Expand Up @@ -198,7 +200,7 @@ function generateMutationHook(
break;

default:
throw new PluginError(`Unsupported target "${target}"`);
throw new PluginError(name, `Unsupported target "${target}"`);
}

func.addStatements('return mutation;');
Expand Down Expand Up @@ -395,7 +397,7 @@ function generateHelper(target: TargetFramework, project: Project, outDir: strin
srcFile = path.join(__dirname, './res/svelte/helper.ts');
break;
default:
throw new PluginError(`Unsupported target: ${target}`);
throw new PluginError(name, `Unsupported target: ${target}`);
}

// merge content of `shared.ts`, `helper.ts` and `marshal-?.ts`
Expand All @@ -418,7 +420,7 @@ function makeGetContext(target: TargetFramework) {
case 'svelte':
return `const { endpoint } = getContext<RequestHandlerContext>(SvelteQueryContextKey);`;
default:
throw new PluginError(`Unsupported target "${target}"`);
throw new PluginError(name, `Unsupported target "${target}"`);
}
}

Expand All @@ -441,7 +443,7 @@ function makeBaseImports(target: TargetFramework) {
...shared,
];
default:
throw new PluginError(`Unsupported target: ${target}`);
throw new PluginError(name, `Unsupported target: ${target}`);
}
}

Expand All @@ -452,7 +454,7 @@ function makeQueryOptions(target: string, returnType: string) {
case 'svelte':
return `QueryOptions<${returnType}>`;
default:
throw new PluginError(`Unsupported target: ${target}`);
throw new PluginError(name, `Unsupported target: ${target}`);
}
}

Expand All @@ -463,6 +465,6 @@ function makeMutationOptions(target: string, returnType: string, argsType: strin
case 'svelte':
return `MutationOptions<${returnType}, unknown, ${argsType}>`;
default:
throw new PluginError(`Unsupported target: ${target}`);
throw new PluginError(name, `Unsupported target: ${target}`);
}
}
22 changes: 11 additions & 11 deletions packages/plugins/trpc/src/generator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { DMMF } from '@prisma/generator-helper';
import { CrudFailureReason, PluginError, PluginOptions, RUNTIME_PACKAGE, saveProject } from '@zenstackhq/sdk';
import {
CrudFailureReason,
PluginOptions,
RUNTIME_PACKAGE,
requireOption,
resolvePath,
saveProject,
} from '@zenstackhq/sdk';
import { Model } from '@zenstackhq/sdk/ast';
import { lowerCaseFirst } from 'lower-case-first';
import { promises as fs } from 'fs';
import { lowerCaseFirst } from 'lower-case-first';
import path from 'path';
import { Project } from 'ts-morph';
import {
Expand All @@ -17,15 +24,8 @@ import removeDir from './utils/removeDir';
import { generate as PrismaZodGenerator } from './zod/generator';

export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
let outDir = options.output as string;
if (!outDir) {
throw new PluginError('"output" option is required');
}

if (!path.isAbsolute(outDir)) {
// output dir is resolved relative to the schema file path
outDir = path.join(path.dirname(options.schemaPath), outDir);
}
let outDir = requireOption<string>(options, 'output');
outDir = resolvePath(outDir, options);

await fs.mkdir(outDir, { recursive: true });
await removeDir(outDir, true);
Expand Down
6 changes: 4 additions & 2 deletions packages/plugins/trpc/src/zod/generator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ConnectorType, DMMF } from '@prisma/generator-helper';
import { Dictionary } from '@prisma/internals';
import { PluginOptions, getLiteral } from '@zenstackhq/sdk';
import { PluginOptions, getLiteral, resolvePath } from '@zenstackhq/sdk';
import { DataSource, Model, isDataSource } from '@zenstackhq/sdk/ast';
import {
AggregateOperationSupport,
Expand All @@ -14,7 +14,9 @@ import removeDir from './utils/removeDir';
import { writeFileSafely } from './utils/writeFileSafely';

export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
const output = (options.output as string) ?? './generated';
let output = (options.output as string) ?? './generated';
output = resolvePath(output, options);

await handleGeneratorOutputValue(output);

const prismaClientDmmf = dmmf;
Expand Down
Loading