zenstack
Version:
FullStack enhancement for Prisma ORM: seamless integration from database to UI
684 lines (682 loc) • 42.9 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/ban-ts-comment */
const runtime_1 = require("@zenstackhq/runtime");
const sdk_1 = require("@zenstackhq/sdk");
const ast_1 = require("@zenstackhq/sdk/ast");
const dmmf_helpers_1 = require("@zenstackhq/sdk/dmmf-helpers");
const prisma_1 = require("@zenstackhq/sdk/prisma");
const path_1 = __importDefault(require("path"));
const upper_case_first_1 = require("upper-case-first");
const generator_1 = require("./generator");
class Transformer {
constructor(params) {
var _a, _b, _c, _d, _e, _f;
this.schemaImports = new Set();
this.hasJson = false;
this.hasDecimal = false;
this.sourceFiles = [];
this.createUpdateInputRegex = /(\S+?)(Unchecked)?(Create|Update|CreateMany|UpdateMany).*Input/;
this.originalName = (_a = params.name) !== null && _a !== void 0 ? _a : '';
this.name = params.name ? (0, upper_case_first_1.upperCaseFirst)(params.name) : '';
this.fields = (_b = params.fields) !== null && _b !== void 0 ? _b : [];
this.models = (_c = params.models) !== null && _c !== void 0 ? _c : [];
this.modelOperations = (_d = params.modelOperations) !== null && _d !== void 0 ? _d : [];
this.aggregateOperationSupport = (_e = params.aggregateOperationSupport) !== null && _e !== void 0 ? _e : {};
this.enumTypes = (_f = params.enumTypes) !== null && _f !== void 0 ? _f : [];
this.project = params.project;
this.inputObjectTypes = params.inputObjectTypes;
this.zmodel = params.zmodel;
this.mode = params.mode;
}
static setOutputPath(outPath) {
this.outputPath = outPath;
}
static getOutputPath() {
return this.outputPath;
}
generateEnumSchemas() {
return __awaiter(this, void 0, void 0, function* () {
const generated = [];
// generate for enums in DMMF
for (const enumType of this.enumTypes) {
const name = (0, upper_case_first_1.upperCaseFirst)(enumType.name);
const filePath = path_1.default.join(Transformer.outputPath, `enums/${name}.schema.ts`);
const content = `${this.generateImportZodStatement()}\n${this.generateExportSchemaStatement(`${name}`, `z.enum(${JSON.stringify(enumType.values
// exclude fields generated for delegate models
.filter((v) => !v.startsWith(runtime_1.DELEGATE_AUX_RELATION_PREFIX)))})`)}`;
this.sourceFiles.push(this.project.createSourceFile(filePath, content, { overwrite: true }));
generated.push(enumType.name);
}
// enums not referenced by data models are not in DMMF, deal with them separately
const extraEnums = this.zmodel.declarations.filter((d) => (0, ast_1.isEnum)(d) && !generated.includes(d.name));
for (const enumDecl of extraEnums) {
const name = (0, upper_case_first_1.upperCaseFirst)(enumDecl.name);
const filePath = path_1.default.join(Transformer.outputPath, `enums/${name}.schema.ts`);
const content = `${this.generateImportZodStatement()}\n${this.generateExportSchemaStatement(`${name}`, `z.enum(${JSON.stringify(enumDecl.fields.map((f) => f.name))})`)}`;
this.sourceFiles.push(this.project.createSourceFile(filePath, content, { overwrite: true }));
generated.push(enumDecl.name);
}
this.sourceFiles.push(this.project.createSourceFile(path_1.default.join(Transformer.outputPath, `enums/index.ts`), generated.map((name) => `export * from './${(0, upper_case_first_1.upperCaseFirst)(name)}.schema';`).join('\n'), { overwrite: true }));
});
}
generateImportZodStatement() {
let r = "import { z } from 'zod';\n";
if (this.mode === 'strip') {
// import the additional `smartUnion` helper
r += `import { smartUnion } from '@zenstackhq/runtime/zod-utils';\n`;
}
return r;
}
generateExportSchemaStatement(name, schema) {
return `export const ${name}Schema = ${schema}`;
}
generateObjectSchema(generateUnchecked, options) {
const { schemaFields, extraImports } = this.generateObjectSchemaFields(generateUnchecked);
const objectSchema = this.prepareObjectSchema(schemaFields, options);
const filePath = path_1.default.join(Transformer.outputPath, `objects/${this.name}.schema.ts`);
const content = extraImports.join('\n\n') + objectSchema;
this.sourceFiles.push(this.project.createSourceFile(filePath, content, { overwrite: true }));
return `${this.name}.schema`;
}
generateObjectSchemaFields(generateUnchecked) {
let fields = this.fields;
let contextDataModel;
const extraImports = [];
// exclude discriminator fields from create/update input schemas
const createUpdateMatch = this.createUpdateInputRegex.exec(this.name);
if (createUpdateMatch) {
const modelName = createUpdateMatch[1];
contextDataModel = this.zmodel.declarations.find((d) => (0, ast_1.isDataModel)(d) && d.name === modelName);
if (contextDataModel) {
// exclude discriminator fields from create/update input schemas
const discriminatorFields = contextDataModel.fields.filter(sdk_1.isDiscriminatorField);
if (discriminatorFields.length > 0) {
fields = fields.filter((field) => {
return !discriminatorFields.some((discriminatorField) => discriminatorField.name === field.name);
});
}
// import type-def's schemas
const typeDefFields = contextDataModel.fields.filter((f) => { var _a; return (0, ast_1.isTypeDef)((_a = f.type.reference) === null || _a === void 0 ? void 0 : _a.ref); });
typeDefFields.forEach((field) => {
const typeName = (0, upper_case_first_1.upperCaseFirst)(field.type.reference.$refText);
const importLine = `import { ${typeName}Schema } from '../models/${typeName}.schema';`;
if (!extraImports.includes(importLine)) {
extraImports.push(importLine);
}
});
}
}
const zodObjectSchemaFields = fields
.map((field) => this.generateObjectSchemaField(field, contextDataModel, generateUnchecked, !!createUpdateMatch))
.flatMap((item) => item)
.map((item) => {
const [zodStringWithMainType, field, skipValidators] = item;
const value = skipValidators
? zodStringWithMainType
: this.generateFieldValidators(zodStringWithMainType, field);
return value.trim();
});
return { schemaFields: zodObjectSchemaFields, extraImports };
}
generateObjectSchemaField(field, contextDataModel, generateUnchecked, replaceJsonWithTypeDef = false) {
var _a;
const lines = field.inputTypes;
if (lines.length === 0) {
return [];
}
let alternatives = undefined;
if (replaceJsonWithTypeDef) {
const dmField = contextDataModel === null || contextDataModel === void 0 ? void 0 : contextDataModel.fields.find((f) => f.name === field.name);
if ((0, ast_1.isTypeDef)((_a = dmField === null || dmField === void 0 ? void 0 : dmField.type.reference) === null || _a === void 0 ? void 0 : _a.ref)) {
const isList = dmField.type.array;
const lazyStr = `z.lazy(() => ${(0, upper_case_first_1.upperCaseFirst)(dmField.type.reference.$refText)}Schema)`;
alternatives = [isList ? `${lazyStr}.array()` : lazyStr];
}
}
if (!alternatives) {
alternatives = lines.reduce((result, inputType) => {
if (!generateUnchecked && typeof inputType.type === 'string' && inputType.type.includes('Unchecked')) {
return result;
}
if (inputType.type.includes('CreateMany') && !(0, prisma_1.supportCreateMany)(this.zmodel)) {
return result;
}
// TODO: unify the following with `schema-gen.ts`
if (inputType.type === 'String') {
result.push(this.wrapWithZodValidators('z.string()', field, inputType));
}
else if (inputType.type === 'Int' || inputType.type === 'Float') {
result.push(this.wrapWithZodValidators('z.number()', field, inputType));
}
else if (inputType.type === 'Decimal') {
this.hasDecimal = true;
result.push(this.wrapWithZodValidators('DecimalSchema', field, inputType));
}
else if (inputType.type === 'BigInt') {
result.push(this.wrapWithZodValidators('z.bigint()', field, inputType));
}
else if (inputType.type === 'Boolean') {
result.push(this.wrapWithZodValidators('z.boolean()', field, inputType));
}
else if (inputType.type === 'DateTime') {
result.push(this.wrapWithZodValidators(['z.date()', 'z.string().datetime()'], field, inputType));
}
else if (inputType.type === 'Bytes') {
result.push(this.wrapWithZodValidators(`z.custom<Buffer | Uint8Array>(data => data instanceof Uint8Array)`, field, inputType));
}
else if (inputType.type === 'Json') {
this.hasJson = true;
result.push(this.wrapWithZodValidators('jsonSchema', field, inputType));
}
else if (inputType.type === 'True') {
result.push(this.wrapWithZodValidators('z.literal(true)', field, inputType));
}
else if (inputType.type === 'Null') {
result.push(this.wrapWithZodValidators('z.null()', field, inputType));
}
else {
const isEnum = inputType.location === 'enumTypes';
const isFieldRef = inputType.location === 'fieldRefTypes';
if (
// fieldRefTypes refer to other fields in the model and don't need to be generated as part of schema
!isFieldRef &&
(inputType.namespace === 'prisma' || isEnum)) {
// reduce concrete input types to their delegate base types
// e.g.: "UserCreateNestedOneWithoutDelegate_aux_PostInput" => "UserCreateWithoutAssetInput"
let mappedInputType = inputType;
if (contextDataModel) {
mappedInputType = this.mapDelegateInputType(inputType, contextDataModel, field.name);
}
if (mappedInputType.type !== this.originalName && typeof mappedInputType.type === 'string') {
this.addSchemaImport(mappedInputType.type);
}
const contextField = contextDataModel === null || contextDataModel === void 0 ? void 0 : contextDataModel.fields.find((f) => f.name === field.name);
result.push(this.generatePrismaStringLine(field, mappedInputType, lines.length, contextField));
}
}
return result;
}, []);
}
if (alternatives.length === 0) {
return [];
}
if (alternatives.length > 1) {
alternatives = alternatives.map((alter) => alter.replace('.optional()', ''));
}
const fieldName = alternatives.some((alt) => alt.includes(':')) ? '' : ` ${field.name}:`;
let resString;
if (alternatives.length === 1) {
resString = alternatives[0];
}
else {
if (alternatives.some((alt) => alt.includes('Unchecked'))) {
// if the union is for combining checked and unchecked input types, use `smartUnion`
// to parse with the best candidate at runtime
resString = this.wrapWithSmartUnion(...alternatives);
}
else {
resString = `z.union([${alternatives.join(',\r\n')}])`;
}
}
if (!field.isRequired) {
resString += '.optional()';
}
if (field.isNullable) {
resString += '.nullable()';
}
return [[` ${fieldName} ${resString} `, field, true]];
}
mapDelegateInputType(inputType, contextDataModel, contextFieldName) {
var _a;
// input type mapping is only relevant for relation inherited from delegate models
const contextField = contextDataModel.fields.find((f) => f.name === contextFieldName);
if (!contextField || !(0, ast_1.isDataModel)((_a = contextField.type.reference) === null || _a === void 0 ? void 0 : _a.ref)) {
return inputType;
}
if (!contextField.$inheritedFrom || !(0, sdk_1.isDelegateModel)(contextField.$inheritedFrom)) {
return inputType;
}
let processedInputType = inputType;
// captures: model name and operation, "Without" part that references a concrete model,
// and the "Input" or "NestedInput" suffix
const match = inputType.type.match(/^(\S+?)((NestedOne)?WithoutDelegate_aux\S+?)((Nested)?Input)$/);
if (match) {
let mappedInputTypeName = match[1];
if (contextDataModel) {
// get the opposite side of the relation field, which should be of the proper
// delegate base type
const oppositeRelationField = (0, sdk_1.getRelationBackLink)(contextField);
if (oppositeRelationField) {
mappedInputTypeName += `Without${(0, upper_case_first_1.upperCaseFirst)(oppositeRelationField.name)}`;
}
}
// "Input" or "NestedInput" suffix
mappedInputTypeName += match[4];
processedInputType = Object.assign(Object.assign({}, inputType), { type: mappedInputTypeName });
}
return processedInputType;
}
wrapWithZodValidators(mainValidators, field, inputType) {
let line = '';
const base = Array.isArray(mainValidators) ? mainValidators : [mainValidators];
line += base
.map((validator) => {
let r = validator;
if (inputType.isList) {
r += '.array()';
}
if (!field.isRequired) {
r += '.optional()';
}
return r;
})
.join(', ');
if (base.length > 1) {
line = `z.union([${line}])`;
}
return line;
}
addSchemaImport(name) {
this.schemaImports.add((0, upper_case_first_1.upperCaseFirst)(name));
}
generatePrismaStringLine(field, inputType, inputsLength, contextField) {
const isEnum = inputType.location === 'enumTypes';
const { isModelQueryType, modelName, queryName } = this.checkIsModelQueryType(inputType.type);
const objectSchemaLine = isModelQueryType
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.resolveModelQuerySchemaName(modelName, queryName)
: `${(0, upper_case_first_1.upperCaseFirst)(inputType.type.toString())}ObjectSchema`;
const enumSchemaLine = `${(0, upper_case_first_1.upperCaseFirst)(inputType.type.toString())}Schema`;
const schema = inputType.type === this.name ? objectSchemaLine : isEnum ? enumSchemaLine : objectSchemaLine;
const arr = inputType.isList ? '.array()' : '';
const optional = !field.isRequired ||
// also check if the zmodel field infers the field as optional
(contextField && this.isFieldOptional(contextField));
return inputsLength === 1
? ` ${field.name}: z.lazy(() => ${schema})${arr}${optional ? '.optional()' : ''}`
: `z.lazy(() => ${schema})${arr}${optional ? '.optional()' : ''}`;
}
isFieldOptional(dmField) {
var _a;
if ((0, sdk_1.hasAttribute)(dmField, '@default')) {
// it's possible that ZModel field has a default but it's transformed away
// when generating Prisma schema, e.g.: `@default(auth().id)`
return true;
}
if ((0, ast_1.isDataModel)((_a = dmField.type.reference) === null || _a === void 0 ? void 0 : _a.ref)) {
// if field is a relation, we need to check if the corresponding fk field has a default
// {
// authorId Int @default(auth().id)
// author User @relation(...) // <- author should be optional
// }
const fkFields = (0, sdk_1.getForeignKeyFields)(dmField);
if (fkFields.every((fkField) => (0, sdk_1.hasAttribute)(fkField, '@default'))) {
return true;
}
}
return false;
}
generateFieldValidators(zodStringWithMainType, field) {
const { isRequired, isNullable } = field;
if (!isRequired) {
zodStringWithMainType += '.optional()';
}
if (isNullable) {
zodStringWithMainType += '.nullable()';
}
return zodStringWithMainType;
}
prepareObjectSchema(zodObjectSchemaFields, options) {
const objectSchema = `${this.generateExportObjectSchemaStatement(this.wrapWithZodObject(zodObjectSchemaFields, options.mode))}\n`;
const prismaImportStatement = this.generateImportPrismaStatement(options);
const json = this.generateJsonSchemaImplementation();
return `${this.generateObjectSchemaImportStatements()}${prismaImportStatement}${json}${objectSchema}`;
}
generateExportObjectSchemaStatement(schema) {
let name = this.name;
let origName = this.originalName;
if ((0, dmmf_helpers_1.isAggregateInputType)(name)) {
name = `${name}Type`;
origName = `${origName}Type`;
}
const outType = `z.ZodType<Prisma.${origName}>`;
return `type SchemaType = ${outType};
export const ${this.name}ObjectSchema: SchemaType = ${schema} as SchemaType;`;
}
generateImportPrismaStatement(options) {
const prismaClientImportPath = (0, generator_1.computePrismaClientImport)(path_1.default.resolve(Transformer.outputPath, './objects'), options);
return `import type { Prisma } from '${prismaClientImportPath}';\n\n`;
}
generateJsonSchemaImplementation() {
let jsonSchemaImplementation = '';
if (this.hasJson) {
jsonSchemaImplementation += `\n`;
jsonSchemaImplementation += `const literalSchema = z.union([z.string(), z.number(), z.boolean()]);\n`;
jsonSchemaImplementation += `const jsonSchema: z.ZodType<Prisma.InputJsonValue> = z.lazy(() =>\n`;
jsonSchemaImplementation += ` z.union([literalSchema, z.array(jsonSchema.nullable()), z.record(jsonSchema.nullable())])\n`;
jsonSchemaImplementation += `);\n\n`;
}
return jsonSchemaImplementation;
}
generateObjectSchemaImportStatements() {
let generatedImports = this.generateImportZodStatement();
generatedImports += this.generateSchemaImports();
generatedImports += this.generateCommonImport();
generatedImports += '\n\n';
return generatedImports;
}
generateSchemaImports() {
return [...this.schemaImports]
.map((name) => {
const { isModelQueryType, modelName } = this.checkIsModelQueryType(name);
if (isModelQueryType) {
return `import { ${modelName}InputSchema } from '../input/${modelName}Input.schema';`;
}
else if (Transformer.enumNames.includes(name)) {
return `import { ${name}Schema } from '../enums/${name}.schema';`;
}
else {
return `import { ${name}ObjectSchema } from './${name}.schema';`;
}
})
.join('\n');
}
generateCommonImport() {
let r = '';
if (this.hasDecimal) {
r += `import { DecimalSchema } from '../common';\n`;
}
if (r) {
r += '\n';
}
return r;
}
checkIsModelQueryType(type) {
const modelQueryTypeSuffixToQueryName = {
FindManyArgs: 'findMany',
};
for (const modelQueryType of ['FindManyArgs']) {
if (type.includes(modelQueryType)) {
const modelQueryTypeSuffixIndex = type.indexOf(modelQueryType);
return {
isModelQueryType: true,
modelName: (0, upper_case_first_1.upperCaseFirst)(type.substring(0, modelQueryTypeSuffixIndex)),
queryName: modelQueryTypeSuffixToQueryName[modelQueryType],
};
}
}
return { isModelQueryType: false };
}
resolveModelQuerySchemaName(modelName, queryName) {
return `${modelName}InputSchema.${queryName}`;
}
wrapWithZodObject(zodStringFields, mode = 'strict') {
let wrapped = '';
wrapped += 'z.object({';
wrapped += '\n';
wrapped += ' ' + zodStringFields;
wrapped += '\n';
wrapped += '})';
switch (mode) {
case 'strip':
// zod strips by default
break;
case 'passthrough':
wrapped += '.passthrough()';
break;
default:
wrapped += '.strict()';
break;
}
return wrapped;
}
wrapWithSmartUnion(...schemas) {
if (this.mode === 'strip') {
return `smartUnion(z, [${schemas.join(', ')}])`;
}
else {
return `z.union([${schemas.join(', ')}])`;
}
}
generateInputSchemas(options, zmodel) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f;
const globalExports = [];
// whether Prisma's Unchecked* series of input types should be generated
const generateUnchecked = options.noUncheckedInput !== true;
for (const modelOperation of this.modelOperations) {
const { model: origModelName, findUnique, findFirst, findMany,
// @ts-expect-error
createOne, createMany,
// @ts-expect-error
deleteOne,
// @ts-expect-error
updateOne, deleteMany, updateMany,
// @ts-expect-error
upsertOne, aggregate, groupBy,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} = modelOperation;
const modelName = (0, upper_case_first_1.upperCaseFirst)(origModelName);
globalExports.push(`export * from './${modelName}Input.schema'`);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const model = (0, dmmf_helpers_1.findModelByName)(this.models, origModelName);
const { selectImport, includeImport, selectZodSchemaLineLazy, includeZodSchemaLineLazy } = this.resolveSelectIncludeImportAndZodSchemaLine(model);
let imports = [
this.generateImportZodStatement(),
this.generateImportPrismaStatement(options),
selectImport,
includeImport,
];
let codeBody = '';
const operations = [];
const mode = (_a = options.mode) !== null && _a !== void 0 ? _a : 'strict';
// OrderByWithRelationInput's name is different when "fullTextSearch" is enabled
const orderByWithRelationInput = this.inputObjectTypes
.map((o) => (0, upper_case_first_1.upperCaseFirst)(o.name))
.includes(`${modelName}OrderByWithRelationInput`)
? `${modelName}OrderByWithRelationInput`
: `${modelName}OrderByWithRelationAndSearchRelevanceInput`;
if (findUnique) {
imports.push(`import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`);
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereUniqueInputObjectSchema`;
codeBody += `findUnique: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['findUnique', origModelName]);
}
if (findFirst) {
imports.push(`import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`, `import { ${orderByWithRelationInput}ObjectSchema } from '../objects/${orderByWithRelationInput}.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`, `import { ${modelName}ScalarFieldEnumSchema } from '../enums/${modelName}ScalarFieldEnum.schema'`);
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${orderByWithRelationInput}ObjectSchema, ${orderByWithRelationInput}ObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${modelName}ScalarFieldEnumSchema).optional()`;
codeBody += `findFirst: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['findFirst', origModelName]);
}
if (findMany) {
imports.push(`import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`, `import { ${orderByWithRelationInput}ObjectSchema } from '../objects/${orderByWithRelationInput}.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`, `import { ${modelName}ScalarFieldEnumSchema } from '../enums/${modelName}ScalarFieldEnum.schema'`);
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${orderByWithRelationInput}ObjectSchema, ${orderByWithRelationInput}ObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${modelName}ScalarFieldEnumSchema).optional()`;
codeBody += `findMany: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['findMany', origModelName]);
}
if (createOne) {
imports.push(`import { ${modelName}CreateInputObjectSchema } from '../objects/${modelName}CreateInput.schema'`);
if (generateUnchecked) {
imports.push(`import { ${modelName}UncheckedCreateInputObjectSchema } from '../objects/${modelName}UncheckedCreateInput.schema'`);
}
const dataSchema = generateUnchecked
? this.wrapWithSmartUnion(`${modelName}CreateInputObjectSchema`, `${modelName}UncheckedCreateInputObjectSchema`)
: `${modelName}CreateInputObjectSchema`;
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} data: ${dataSchema}`;
codeBody += `create: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['create', origModelName]);
}
if (createMany && (0, prisma_1.supportCreateMany)(zmodel)) {
imports.push(`import { ${modelName}CreateManyInputObjectSchema } from '../objects/${modelName}CreateManyInput.schema'`);
const fields = `data: z.union([${modelName}CreateManyInputObjectSchema, z.array(${modelName}CreateManyInputObjectSchema)]), skipDuplicates: z.boolean().optional()`;
codeBody += `createMany: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['createMany', origModelName]);
}
if (deleteOne) {
imports.push(`import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`);
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereUniqueInputObjectSchema`;
codeBody += `'delete': ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['delete', origModelName]);
}
if (deleteMany) {
imports.push(`import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`);
const fields = `where: ${modelName}WhereInputObjectSchema.optional()`;
codeBody += `deleteMany: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['deleteMany', origModelName]);
}
if (updateOne) {
imports.push(`import { ${modelName}UpdateInputObjectSchema } from '../objects/${modelName}UpdateInput.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`);
if (generateUnchecked) {
imports.push(`import { ${modelName}UncheckedUpdateInputObjectSchema } from '../objects/${modelName}UncheckedUpdateInput.schema'`);
}
const dataSchema = generateUnchecked
? this.wrapWithSmartUnion(`${modelName}UpdateInputObjectSchema`, `${modelName}UncheckedUpdateInputObjectSchema`)
: `${modelName}UpdateInputObjectSchema`;
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} data: ${dataSchema}, where: ${modelName}WhereUniqueInputObjectSchema`;
codeBody += `update: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['update', origModelName]);
}
if (updateMany) {
imports.push(`import { ${modelName}UpdateManyMutationInputObjectSchema } from '../objects/${modelName}UpdateManyMutationInput.schema'`, `import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`);
if (generateUnchecked) {
imports.push(`import { ${modelName}UncheckedUpdateManyInputObjectSchema } from '../objects/${modelName}UncheckedUpdateManyInput.schema'`);
}
const dataSchema = generateUnchecked
? this.wrapWithSmartUnion(`${modelName}UpdateManyMutationInputObjectSchema`, `${modelName}UncheckedUpdateManyInputObjectSchema`)
: `${modelName}UpdateManyMutationInputObjectSchema`;
const fields = `data: ${dataSchema}, where: ${modelName}WhereInputObjectSchema.optional()`;
codeBody += `updateMany: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['updateMany', origModelName]);
}
if (upsertOne) {
imports.push(`import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`, `import { ${modelName}CreateInputObjectSchema } from '../objects/${modelName}CreateInput.schema'`, `import { ${modelName}UpdateInputObjectSchema } from '../objects/${modelName}UpdateInput.schema'`);
if (generateUnchecked) {
imports.push(`import { ${modelName}UncheckedCreateInputObjectSchema } from '../objects/${modelName}UncheckedCreateInput.schema'`, `import { ${modelName}UncheckedUpdateInputObjectSchema } from '../objects/${modelName}UncheckedUpdateInput.schema'`);
}
const createSchema = generateUnchecked
? this.wrapWithSmartUnion(`${modelName}CreateInputObjectSchema`, `${modelName}UncheckedCreateInputObjectSchema`)
: `${modelName}CreateInputObjectSchema`;
const updateSchema = generateUnchecked
? this.wrapWithSmartUnion(`${modelName}UpdateInputObjectSchema`, `${modelName}UncheckedUpdateInputObjectSchema`)
: `${modelName}UpdateInputObjectSchema`;
const fields = `${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereUniqueInputObjectSchema, create: ${createSchema}, update: ${updateSchema}`;
codeBody += `upsert: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['upsert', origModelName]);
}
const aggregateOperations = [];
if ((_b = this.aggregateOperationSupport[modelName]) === null || _b === void 0 ? void 0 : _b.count) {
imports.push(`import { ${modelName}CountAggregateInputObjectSchema } from '../objects/${modelName}CountAggregateInput.schema'`);
aggregateOperations.push(`_count: z.union([ z.literal(true), ${modelName}CountAggregateInputObjectSchema ]).optional()`);
}
if ((_c = this.aggregateOperationSupport[modelName]) === null || _c === void 0 ? void 0 : _c.min) {
imports.push(`import { ${modelName}MinAggregateInputObjectSchema } from '../objects/${modelName}MinAggregateInput.schema'`);
aggregateOperations.push(`_min: ${modelName}MinAggregateInputObjectSchema.optional()`);
}
if ((_d = this.aggregateOperationSupport[modelName]) === null || _d === void 0 ? void 0 : _d.max) {
imports.push(`import { ${modelName}MaxAggregateInputObjectSchema } from '../objects/${modelName}MaxAggregateInput.schema'`);
aggregateOperations.push(`_max: ${modelName}MaxAggregateInputObjectSchema.optional()`);
}
if ((_e = this.aggregateOperationSupport[modelName]) === null || _e === void 0 ? void 0 : _e.avg) {
imports.push(`import { ${modelName}AvgAggregateInputObjectSchema } from '../objects/${modelName}AvgAggregateInput.schema'`);
aggregateOperations.push(`_avg: ${modelName}AvgAggregateInputObjectSchema.optional()`);
}
if ((_f = this.aggregateOperationSupport[modelName]) === null || _f === void 0 ? void 0 : _f.sum) {
imports.push(`import { ${modelName}SumAggregateInputObjectSchema } from '../objects/${modelName}SumAggregateInput.schema'`);
aggregateOperations.push(`_sum: ${modelName}SumAggregateInputObjectSchema.optional()`);
}
if (aggregate) {
imports.push(`import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`, `import { ${orderByWithRelationInput}ObjectSchema } from '../objects/${orderByWithRelationInput}.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`);
const fields = `where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${orderByWithRelationInput}ObjectSchema, ${orderByWithRelationInput}ObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), ${aggregateOperations.join(', ')}`;
codeBody += `aggregate: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['aggregate', modelName]);
}
if (groupBy) {
imports.push(`import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithAggregationInputObjectSchema } from '../objects/${modelName}OrderByWithAggregationInput.schema'`, `import { ${modelName}ScalarWhereWithAggregatesInputObjectSchema } from '../objects/${modelName}ScalarWhereWithAggregatesInput.schema'`, `import { ${modelName}ScalarFieldEnumSchema } from '../enums/${modelName}ScalarFieldEnum.schema'`);
const fields = `where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithAggregationInputObjectSchema, ${modelName}OrderByWithAggregationInputObjectSchema.array()]).optional(), having: ${modelName}ScalarWhereWithAggregatesInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), by: z.array(${modelName}ScalarFieldEnumSchema), ${aggregateOperations.join(', ')}`;
codeBody += `groupBy: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['groupBy', origModelName]);
}
// count
{
imports.push(`import { ${modelName}WhereInputObjectSchema } from '../objects/${modelName}WhereInput.schema'`, `import { ${orderByWithRelationInput}ObjectSchema } from '../objects/${orderByWithRelationInput}.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from '../objects/${modelName}WhereUniqueInput.schema'`, `import { ${modelName}ScalarFieldEnumSchema } from '../enums/${modelName}ScalarFieldEnum.schema'`, `import { ${modelName}CountAggregateInputObjectSchema } from '../objects/${modelName}CountAggregateInput.schema'`);
const fields = `where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${orderByWithRelationInput}ObjectSchema, ${orderByWithRelationInput}ObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${modelName}ScalarFieldEnumSchema).optional(), select: z.union([ z.literal(true), ${modelName}CountAggregateInputObjectSchema ]).optional()`;
codeBody += `count: ${this.wrapWithZodObject(fields, mode)},`;
operations.push(['count', origModelName]);
}
imports = [...new Set(imports)];
const filePath = path_1.default.join(Transformer.outputPath, `input/${modelName}Input.schema.ts`);
const content = `
${imports.join(';\n')}
type ${modelName}InputSchemaType = {
${operations
.map(([operation, typeName]) => (0, sdk_1.indentString)(`${operation}: z.ZodType<Prisma.${typeName}${(0, upper_case_first_1.upperCaseFirst)(operation)}Args>`, 4))
.join(',\n')}
}
export const ${modelName}InputSchema = {
${(0, sdk_1.indentString)(codeBody, 4)}
} as ${modelName}InputSchemaType;
`;
this.sourceFiles.push(this.project.createSourceFile(filePath, content, { overwrite: true }));
}
const indexFilePath = path_1.default.join(Transformer.outputPath, 'input/index.ts');
const indexContent = `
${globalExports.join(';\n')}
`;
this.sourceFiles.push(this.project.createSourceFile(indexFilePath, indexContent, { overwrite: true }));
});
}
generateImportStatements(imports) {
var _a;
let generatedImports = this.generateImportZodStatement();
generatedImports += (_a = imports === null || imports === void 0 ? void 0 : imports.filter((importItem) => !!importItem).join(';\r\n')) !== null && _a !== void 0 ? _a : '';
generatedImports += '\n\n';
return generatedImports;
}
resolveSelectIncludeImportAndZodSchemaLine(model) {
const { name } = model;
const modelName = (0, upper_case_first_1.upperCaseFirst)(name);
const hasRelationToAnotherModel = (0, dmmf_helpers_1.checkModelHasModelRelation)(model);
const selectImport = `import { ${modelName}SelectObjectSchema } from '../objects/${modelName}Select.schema'`;
const includeImport = hasRelationToAnotherModel
? `import { ${modelName}IncludeObjectSchema } from '../objects/${modelName}Include.schema'`
: '';
let selectZodSchemaLine = '';
let includeZodSchemaLine = '';
let selectZodSchemaLineLazy = '';
let includeZodSchemaLineLazy = '';
const zodSelectObjectSchema = `${modelName}SelectObjectSchema.optional()`;
selectZodSchemaLine = `select: ${zodSelectObjectSchema},`;
selectZodSchemaLineLazy = `select: z.lazy(() => ${zodSelectObjectSchema}),`;
if (hasRelationToAnotherModel) {
const zodIncludeObjectSchema = `${modelName}IncludeObjectSchema.optional()`;
includeZodSchemaLine = `include: ${zodIncludeObjectSchema},`;
includeZodSchemaLineLazy = `include: z.lazy(() => ${zodIncludeObjectSchema}),`;
}
return {
selectImport,
includeImport,
selectZodSchemaLine,
includeZodSchemaLine,
selectZodSchemaLineLazy,
includeZodSchemaLineLazy,
};
}
}
Transformer.enumNames = [];
Transformer.rawOpsMap = {};
Transformer.outputPath = './generated';
exports.default = Transformer;
//# sourceMappingURL=transformer.js.map
;