diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..bdb54dd --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +src/test/functional/**/expected/** +src/test/functional/**/actual/** diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index 8b13789..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1 +0,0 @@ - diff --git a/dist/zod-prisma.cjs.development.js b/dist/zod-prisma.cjs.development.js deleted file mode 100644 index 43244e2..0000000 --- a/dist/zod-prisma.cjs.development.js +++ /dev/null @@ -1,345 +0,0 @@ -'use strict'; - -var generatorHelper = require('@prisma/generator-helper'); -var typescript = require('typescript'); -var zod = require('zod'); -var path = require('path'); -var tsMorph = require('ts-morph'); -var parenthesis = require('parenthesis'); - -function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } - -var path__default = /*#__PURE__*/_interopDefaultLegacy(path); - -var version = "0.5.6"; - -const configBoolean = /*#__PURE__*/zod.z.enum(['true', 'false']).transform(arg => JSON.parse(arg)); -const configSchema = /*#__PURE__*/zod.z.object({ - relationModel: /*#__PURE__*/configBoolean.default('true').or( /*#__PURE__*/zod.z.literal('default')), - modelSuffix: /*#__PURE__*/zod.z.string().default('Model'), - modelCase: /*#__PURE__*/zod.z.enum(['PascalCase', 'camelCase']).default('PascalCase'), - useDecimalJs: /*#__PURE__*/configBoolean.default('false'), - imports: /*#__PURE__*/zod.z.string().optional(), - prismaJsonNullability: /*#__PURE__*/configBoolean.default('true') -}); - -const writeArray = (writer, array, newLine = true) => array.forEach(line => writer.write(line).conditionalNewLine(newLine)); -const useModelNames = ({ - modelCase, - modelSuffix, - relationModel -}) => { - const formatModelName = (name, prefix = '') => { - if (modelCase === 'camelCase') { - name = name.slice(0, 1).toLowerCase() + name.slice(1); - } - - return `${prefix}${name}${modelSuffix}`; - }; - - return { - modelName: name => formatModelName(name, relationModel === 'default' ? '_' : ''), - relatedModelName: name => formatModelName(relationModel === 'default' ? name.toString() : `Related${name.toString()}`) - }; -}; -const needsRelatedModel = (model, config) => model.fields.some(field => field.kind === 'object') && config.relationModel !== false; -const chunk = (input, size) => { - return input.reduce((arr, item, idx) => { - return idx % size === 0 ? [...arr, [item]] : [...arr.slice(0, -1), [...arr.slice(-1)[0], item]]; - }, []); -}; -const dotSlash = input => { - const converted = input.replace(/^\\\\\?\\/, '').replace(/\\/g, '/').replace(/\/\/+/g, '/'); - if (converted.includes(`/node_modules/`)) return converted.split(`/node_modules/`).slice(-1)[0]; - if (converted.startsWith(`../`)) return converted; - return './' + converted; -}; - -const getJSDocs = docString => { - const lines = []; - - if (docString) { - const docLines = docString.split('\n').filter(dL => !dL.trimStart().startsWith('@zod')); - - if (docLines.length) { - lines.push('/**'); - docLines.forEach(dL => lines.push(` * ${dL}`)); - lines.push(' */'); - } - } - - return lines; -}; -const getZodDocElements = docString => docString.split('\n').filter(line => line.trimStart().startsWith('@zod')).map(line => line.trimStart().slice(4)).flatMap(line => // Array.from(line.matchAll(/\.([^().]+\(.*?\))/g), (m) => m.slice(1)).flat() -chunk(parenthesis.parse(line), 2).slice(0, -1).map(([each, contents]) => each.replace(/\)?\./, '') + `${parenthesis.stringify(contents)})`)); -const computeCustomSchema = docString => { - var _getZodDocElements$fi; - - return (_getZodDocElements$fi = getZodDocElements(docString).find(modifier => modifier.startsWith('custom('))) == null ? void 0 : _getZodDocElements$fi.slice(7).slice(0, -1); -}; -const computeModifiers = docString => { - return getZodDocElements(docString).filter(each => !each.startsWith('custom(')); -}; - -const getZodConstructor = (field, getRelatedModelName = name => name.toString()) => { - let zodType = 'z.unknown()'; - let extraModifiers = ['']; - - if (field.kind === 'scalar') { - switch (field.type) { - case 'String': - zodType = 'z.string()'; - break; - - case 'Int': - zodType = 'z.number()'; - extraModifiers.push('int()'); - break; - - case 'BigInt': - zodType = 'z.bigint()'; - break; - - case 'DateTime': - zodType = 'z.date()'; - break; - - case 'Float': - zodType = 'z.number()'; - break; - - case 'Decimal': - zodType = 'z.number()'; - break; - - case 'Json': - zodType = 'jsonSchema'; - break; - - case 'Boolean': - zodType = 'z.boolean()'; - break; - // TODO: Proper type for bytes fields - - case 'Bytes': - zodType = 'z.unknown()'; - break; - } - } else if (field.kind === 'enum') { - zodType = `z.nativeEnum(${field.type})`; - } else if (field.kind === 'object') { - zodType = getRelatedModelName(field.type); - } - - if (field.isList) extraModifiers.push('array()'); - - if (field.documentation) { - var _computeCustomSchema; - - zodType = (_computeCustomSchema = computeCustomSchema(field.documentation)) != null ? _computeCustomSchema : zodType; - extraModifiers.push(...computeModifiers(field.documentation)); - } - - if (!field.isRequired && field.type !== 'Json') extraModifiers.push('nullish()'); // if (field.hasDefaultValue) extraModifiers.push('optional()') - - return `${zodType}${extraModifiers.join('.')}`; -}; - -const writeImportsForModel = (model, sourceFile, config, { - schemaPath, - outputPath, - clientPath -}) => { - const { - relatedModelName - } = useModelNames(config); - const importList = [{ - kind: tsMorph.StructureKind.ImportDeclaration, - namespaceImport: 'z', - moduleSpecifier: 'zod' - }]; - - if (config.imports) { - importList.push({ - kind: tsMorph.StructureKind.ImportDeclaration, - namespaceImport: 'imports', - moduleSpecifier: dotSlash(path__default["default"].relative(outputPath, path__default["default"].resolve(path__default["default"].dirname(schemaPath), config.imports))) - }); - } - - if (config.useDecimalJs && model.fields.some(f => f.type === 'Decimal')) { - importList.push({ - kind: tsMorph.StructureKind.ImportDeclaration, - namedImports: ['Decimal'], - moduleSpecifier: 'decimal.js' - }); - } - - const enumFields = model.fields.filter(f => f.kind === 'enum'); - const relationFields = model.fields.filter(f => f.kind === 'object'); - const relativePath = path__default["default"].relative(outputPath, clientPath); - - if (enumFields.length > 0) { - importList.push({ - kind: tsMorph.StructureKind.ImportDeclaration, - isTypeOnly: enumFields.length === 0, - moduleSpecifier: dotSlash(relativePath), - namedImports: Array.from(new Set(enumFields.map(f => f.type))) - }); - } - - if (config.relationModel !== false && relationFields.length > 0) { - const filteredFields = relationFields.filter(f => f.type !== model.name); - - if (filteredFields.length > 0) { - importList.push({ - kind: tsMorph.StructureKind.ImportDeclaration, - moduleSpecifier: './index', - namedImports: Array.from(new Set(filteredFields.flatMap(f => [`Complete${f.type}`, relatedModelName(f.type)]))) - }); - } - } - - sourceFile.addImportDeclarations(importList); -}; -const writeTypeSpecificSchemas = (model, sourceFile, config, _prismaOptions) => { - if (model.fields.some(f => f.type === 'Json')) { - sourceFile.addStatements(writer => { - writer.newLine(); - writeArray(writer, ['// Helper schema for JSON fields', `type Literal = boolean | number | string${config.prismaJsonNullability ? '' : '| null'}`, 'type Json = Literal | { [key: string]: Json } | Json[]', `const literalSchema = z.union([z.string(), z.number(), z.boolean()${config.prismaJsonNullability ? '' : ', z.null()'}])`, 'const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))']); - }); - } - - if (config.useDecimalJs && model.fields.some(f => f.type === 'Decimal')) { - sourceFile.addStatements(writer => { - writer.newLine(); - writeArray(writer, ['// Helper schema for Decimal fields', 'z', '.instanceof(Decimal)', '.or(z.string())', '.or(z.number())', '.refine((value) => {', ' try {', ' return new Decimal(value);', ' } catch (error) {', ' return false;', ' }', '})', '.transform((value) => new Decimal(value));']); - }); - } -}; -const generateSchemaForModel = (model, sourceFile, config, _prismaOptions) => { - const { - modelName - } = useModelNames(config); - sourceFile.addVariableStatement({ - declarationKind: tsMorph.VariableDeclarationKind.Const, - isExported: true, - leadingTrivia: writer => writer.blankLineIfLastNot(), - declarations: [{ - name: modelName(model.name), - - initializer(writer) { - writer.write('z.object(').inlineBlock(() => { - model.fields.filter(f => f.kind !== 'object').filter(f => { - var _f$documentation; - - return !getZodDocElements((_f$documentation = f.documentation) != null ? _f$documentation : '').includes('omit()'); - }).forEach(field => { - writeArray(writer, getJSDocs(field.documentation)); - writer.write(`${field.name}: ${getZodConstructor(field)}`).write(',').newLine(); - }); - }).write(')'); - } - - }] - }); -}; -const generateRelatedSchemaForModel = (model, sourceFile, config, _prismaOptions) => { - const { - modelName, - relatedModelName - } = useModelNames(config); - const relationFields = model.fields.filter(f => f.kind === 'object'); - sourceFile.addInterface({ - name: `Complete${model.name}`, - isExported: true, - extends: [`z.infer`], - properties: relationFields.map(f => ({ - hasQuestionToken: !f.isRequired, - name: f.name, - type: `Complete${f.type}${f.isList ? '[]' : ''}${!f.isRequired ? ' | null' : ''}` - })) - }); - sourceFile.addStatements(writer => writeArray(writer, ['', '/**', ` * ${relatedModelName(model.name)} contains all relations on your model in addition to the scalars`, ' *', ' * NOTE: Lazy required in case of potential circular dependencies within schema', ' */'])); - sourceFile.addVariableStatement({ - declarationKind: tsMorph.VariableDeclarationKind.Const, - isExported: true, - declarations: [{ - name: relatedModelName(model.name), - type: `z.ZodSchema`, - - initializer(writer) { - writer.write(`z.lazy(() => ${modelName(model.name)}.extend(`).inlineBlock(() => { - relationFields.forEach(field => { - writeArray(writer, getJSDocs(field.documentation)); - writer.write(`${field.name}: ${getZodConstructor(field, relatedModelName)}`).write(',').newLine(); - }); - }).write('))'); - } - - }] - }); -}; -const populateModelFile = (model, sourceFile, config, prismaOptions) => { - writeImportsForModel(model, sourceFile, config, prismaOptions); - writeTypeSpecificSchemas(model, sourceFile, config); - generateSchemaForModel(model, sourceFile, config); - if (needsRelatedModel(model, config)) generateRelatedSchemaForModel(model, sourceFile, config); -}; -const generateBarrelFile = (models, indexFile) => { - models.forEach(model => indexFile.addExportDeclaration({ - moduleSpecifier: `./${model.name.toLowerCase()}` - })); -}; - -// @ts-ignore Importing package.json for automated synchronization of version numbers -generatorHelper.generatorHandler({ - onManifest() { - return { - version, - prettyName: 'Zod Schemas', - defaultOutput: 'zod' - }; - }, - - onGenerate(options) { - const project = new tsMorph.Project(); - const models = options.dmmf.datamodel.models; - const { - schemaPath - } = options; - const outputPath = options.generator.output.value; - const clientPath = options.otherGenerators.find(each => each.provider.value === 'prisma-client-js').output.value; - const results = configSchema.safeParse(options.generator.config); - if (!results.success) throw new Error('Incorrect config provided. Please check the values you provided and try again.'); - const config = results.data; - const prismaOptions = { - clientPath, - outputPath, - schemaPath - }; - const indexFile = project.createSourceFile(`${outputPath}/index.ts`, {}, { - overwrite: true - }); - generateBarrelFile(models, indexFile); - indexFile.formatText({ - indentSize: 2, - convertTabsToSpaces: true, - semicolons: typescript.SemicolonPreference.Remove - }); - models.forEach(model => { - const sourceFile = project.createSourceFile(`${outputPath}/${model.name.toLowerCase()}.ts`, {}, { - overwrite: true - }); - populateModelFile(model, sourceFile, config, prismaOptions); - sourceFile.formatText({ - indentSize: 2, - convertTabsToSpaces: true, - semicolons: typescript.SemicolonPreference.Remove - }); - }); - return project.save(); - } - -}); -//# sourceMappingURL=zod-prisma.cjs.development.js.map diff --git a/dist/zod-prisma.cjs.development.js.map b/dist/zod-prisma.cjs.development.js.map deleted file mode 100644 index f4d7055..0000000 --- a/dist/zod-prisma.cjs.development.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"zod-prisma.cjs.development.js","sources":["../src/config.ts","../src/util.ts","../src/docs.ts","../src/types.ts","../src/generator.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod'\n\nconst configBoolean = z.enum(['true', 'false']).transform((arg) => JSON.parse(arg))\n\nexport const configSchema = z.object({\n\trelationModel: configBoolean.default('true').or(z.literal('default')),\n\tmodelSuffix: z.string().default('Model'),\n\tmodelCase: z.enum(['PascalCase', 'camelCase']).default('PascalCase'),\n\tuseDecimalJs: configBoolean.default('false'),\n\timports: z.string().optional(),\n\tprismaJsonNullability: configBoolean.default('true'),\n})\n\nexport type Config = z.infer\n\nexport type PrismaOptions = {\n\tschemaPath: string\n\toutputPath: string\n\tclientPath: string\n}\n\nexport type Names = {\n\tmodel: string\n\trelated: string\n}\n","import { DMMF } from '@prisma/generator-helper'\nimport type { CodeBlockWriter } from 'ts-morph'\nimport { Config } from './config'\n\nexport const writeArray = (writer: CodeBlockWriter, array: string[], newLine = true) =>\n\tarray.forEach((line) => writer.write(line).conditionalNewLine(newLine))\n\nexport const useModelNames = ({ modelCase, modelSuffix, relationModel }: Config) => {\n\tconst formatModelName = (name: string, prefix = '') => {\n\t\tif (modelCase === 'camelCase') {\n\t\t\tname = name.slice(0, 1).toLowerCase() + name.slice(1)\n\t\t}\n\t\treturn `${prefix}${name}${modelSuffix}`\n\t}\n\n\treturn {\n\t\tmodelName: (name: string) => formatModelName(name, relationModel === 'default' ? '_' : ''),\n\t\trelatedModelName: (name: string | DMMF.SchemaEnum | DMMF.OutputType | DMMF.SchemaArg) =>\n\t\t\tformatModelName(\n\t\t\t\trelationModel === 'default' ? name.toString() : `Related${name.toString()}`\n\t\t\t),\n\t}\n}\n\nexport const needsRelatedModel = (model: DMMF.Model, config: Config) =>\n\tmodel.fields.some((field) => field.kind === 'object') && config.relationModel !== false\n\nexport const chunk = (input: T, size: number): T[] => {\n\treturn input.reduce((arr, item, idx) => {\n\t\treturn idx % size === 0\n\t\t\t? [...arr, [item]]\n\t\t\t: [...arr.slice(0, -1), [...arr.slice(-1)[0], item]]\n\t}, [])\n}\n\nexport const dotSlash = (input: string) => {\n\tconst converted = input\n\t\t.replace(/^\\\\\\\\\\?\\\\/, '')\n\t\t.replace(/\\\\/g, '/')\n\t\t.replace(/\\/\\/+/g, '/')\n\n\tif (converted.includes(`/node_modules/`)) return converted.split(`/node_modules/`).slice(-1)[0]\n\n\tif (converted.startsWith(`../`)) return converted\n\n\treturn './' + converted\n}\n","import { ArrayTree, parse, stringify } from 'parenthesis'\nimport { chunk } from './util'\n\nexport const getJSDocs = (docString?: string) => {\n\tconst lines: string[] = []\n\n\tif (docString) {\n\t\tconst docLines = docString.split('\\n').filter((dL) => !dL.trimStart().startsWith('@zod'))\n\n\t\tif (docLines.length) {\n\t\t\tlines.push('/**')\n\t\t\tdocLines.forEach((dL) => lines.push(` * ${dL}`))\n\t\t\tlines.push(' */')\n\t\t}\n\t}\n\n\treturn lines\n}\n\nexport const getZodDocElements = (docString: string) =>\n\tdocString\n\t\t.split('\\n')\n\t\t.filter((line) => line.trimStart().startsWith('@zod'))\n\t\t.map((line) => line.trimStart().slice(4))\n\t\t.flatMap((line) =>\n\t\t\t// Array.from(line.matchAll(/\\.([^().]+\\(.*?\\))/g), (m) => m.slice(1)).flat()\n\t\t\tchunk(parse(line), 2)\n\t\t\t\t.slice(0, -1)\n\t\t\t\t.map(\n\t\t\t\t\t([each, contents]) =>\n\t\t\t\t\t\t(each as string).replace(/\\)?\\./, '') +\n\t\t\t\t\t\t`${stringify(contents as ArrayTree)})`\n\t\t\t\t)\n\t\t)\n\nexport const computeCustomSchema = (docString: string) => {\n\treturn getZodDocElements(docString)\n\t\t.find((modifier) => modifier.startsWith('custom('))\n\t\t?.slice(7)\n\t\t.slice(0, -1)\n}\n\nexport const computeModifiers = (docString: string) => {\n\treturn getZodDocElements(docString).filter((each) => !each.startsWith('custom('))\n}\n","import type { DMMF } from '@prisma/generator-helper'\nimport { computeCustomSchema, computeModifiers } from './docs'\n\nexport const getZodConstructor = (\n\tfield: DMMF.Field,\n\tgetRelatedModelName = (name: string | DMMF.SchemaEnum | DMMF.OutputType | DMMF.SchemaArg) =>\n\t\tname.toString()\n) => {\n\tlet zodType = 'z.unknown()'\n\tlet extraModifiers: string[] = ['']\n\tif (field.kind === 'scalar') {\n\t\tswitch (field.type) {\n\t\t\tcase 'String':\n\t\t\t\tzodType = 'z.string()'\n\t\t\t\tbreak\n\t\t\tcase 'Int':\n\t\t\t\tzodType = 'z.number()'\n\t\t\t\textraModifiers.push('int()')\n\t\t\t\tbreak\n\t\t\tcase 'BigInt':\n\t\t\t\tzodType = 'z.bigint()'\n\t\t\t\tbreak\n\t\t\tcase 'DateTime':\n\t\t\t\tzodType = 'z.date()'\n\t\t\t\tbreak\n\t\t\tcase 'Float':\n\t\t\t\tzodType = 'z.number()'\n\t\t\t\tbreak\n\t\t\tcase 'Decimal':\n\t\t\t\tzodType = 'z.number()'\n\t\t\t\tbreak\n\t\t\tcase 'Json':\n\t\t\t\tzodType = 'jsonSchema'\n\t\t\t\tbreak\n\t\t\tcase 'Boolean':\n\t\t\t\tzodType = 'z.boolean()'\n\t\t\t\tbreak\n\t\t\t// TODO: Proper type for bytes fields\n\t\t\tcase 'Bytes':\n\t\t\t\tzodType = 'z.unknown()'\n\t\t\t\tbreak\n\t\t}\n\t} else if (field.kind === 'enum') {\n\t\tzodType = `z.nativeEnum(${field.type})`\n\t} else if (field.kind === 'object') {\n\t\tzodType = getRelatedModelName(field.type)\n\t}\n\n\tif (field.isList) extraModifiers.push('array()')\n\tif (field.documentation) {\n\t\tzodType = computeCustomSchema(field.documentation) ?? zodType\n\t\textraModifiers.push(...computeModifiers(field.documentation))\n\t}\n\tif (!field.isRequired && field.type !== 'Json') extraModifiers.push('nullish()')\n\t// if (field.hasDefaultValue) extraModifiers.push('optional()')\n\n\treturn `${zodType}${extraModifiers.join('.')}`\n}\n","import path from 'path'\nimport { DMMF } from '@prisma/generator-helper'\nimport {\n\tImportDeclarationStructure,\n\tSourceFile,\n\tStructureKind,\n\tVariableDeclarationKind,\n} from 'ts-morph'\nimport { Config, PrismaOptions } from './config'\nimport { dotSlash, needsRelatedModel, useModelNames, writeArray } from './util'\nimport { getJSDocs, getZodDocElements } from './docs'\nimport { getZodConstructor } from './types'\n\nexport const writeImportsForModel = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t{ schemaPath, outputPath, clientPath }: PrismaOptions\n) => {\n\tconst { relatedModelName } = useModelNames(config)\n\tconst importList: ImportDeclarationStructure[] = [\n\t\t{\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tnamespaceImport: 'z',\n\t\t\tmoduleSpecifier: 'zod',\n\t\t},\n\t]\n\n\tif (config.imports) {\n\t\timportList.push({\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tnamespaceImport: 'imports',\n\t\t\tmoduleSpecifier: dotSlash(\n\t\t\t\tpath.relative(outputPath, path.resolve(path.dirname(schemaPath), config.imports))\n\t\t\t),\n\t\t})\n\t}\n\n\tif (config.useDecimalJs && model.fields.some((f) => f.type === 'Decimal')) {\n\t\timportList.push({\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tnamedImports: ['Decimal'],\n\t\t\tmoduleSpecifier: 'decimal.js',\n\t\t})\n\t}\n\n\tconst enumFields = model.fields.filter((f) => f.kind === 'enum')\n\tconst relationFields = model.fields.filter((f) => f.kind === 'object')\n\tconst relativePath = path.relative(outputPath, clientPath)\n\n\tif (enumFields.length > 0) {\n\t\timportList.push({\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tisTypeOnly: enumFields.length === 0,\n\t\t\tmoduleSpecifier: dotSlash(relativePath),\n\t\t\tnamedImports: Array.from(new Set(enumFields.map((f) => f.type))),\n\t\t})\n\t}\n\n\tif (config.relationModel !== false && relationFields.length > 0) {\n\t\tconst filteredFields = relationFields.filter((f) => f.type !== model.name)\n\n\t\tif (filteredFields.length > 0) {\n\t\t\timportList.push({\n\t\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\t\tmoduleSpecifier: './index',\n\t\t\t\tnamedImports: Array.from(\n\t\t\t\t\tnew Set(\n\t\t\t\t\t\tfilteredFields.flatMap((f) => [\n\t\t\t\t\t\t\t`Complete${f.type}`,\n\t\t\t\t\t\t\trelatedModelName(f.type),\n\t\t\t\t\t\t])\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t})\n\t\t}\n\t}\n\n\tsourceFile.addImportDeclarations(importList)\n}\n\nexport const writeTypeSpecificSchemas = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t_prismaOptions: PrismaOptions\n) => {\n\tif (model.fields.some((f) => f.type === 'Json')) {\n\t\tsourceFile.addStatements((writer) => {\n\t\t\twriter.newLine()\n\t\t\twriteArray(writer, [\n\t\t\t\t'// Helper schema for JSON fields',\n\t\t\t\t`type Literal = boolean | number | string${\n\t\t\t\t\tconfig.prismaJsonNullability ? '' : '| null'\n\t\t\t\t}`,\n\t\t\t\t'type Json = Literal | { [key: string]: Json } | Json[]',\n\t\t\t\t`const literalSchema = z.union([z.string(), z.number(), z.boolean()${\n\t\t\t\t\tconfig.prismaJsonNullability ? '' : ', z.null()'\n\t\t\t\t}])`,\n\t\t\t\t'const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))',\n\t\t\t])\n\t\t})\n\t}\n\n\tif (config.useDecimalJs && model.fields.some((f) => f.type === 'Decimal')) {\n\t\tsourceFile.addStatements((writer) => {\n\t\t\twriter.newLine()\n\t\t\twriteArray(writer, [\n\t\t\t\t'// Helper schema for Decimal fields',\n\t\t\t\t'z',\n\t\t\t\t'.instanceof(Decimal)',\n\t\t\t\t'.or(z.string())',\n\t\t\t\t'.or(z.number())',\n\t\t\t\t'.refine((value) => {',\n\t\t\t\t' try {',\n\t\t\t\t' return new Decimal(value);',\n\t\t\t\t' } catch (error) {',\n\t\t\t\t' return false;',\n\t\t\t\t' }',\n\t\t\t\t'})',\n\t\t\t\t'.transform((value) => new Decimal(value));',\n\t\t\t])\n\t\t})\n\t}\n}\n\nexport const generateSchemaForModel = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t_prismaOptions: PrismaOptions\n) => {\n\tconst { modelName } = useModelNames(config)\n\n\tsourceFile.addVariableStatement({\n\t\tdeclarationKind: VariableDeclarationKind.Const,\n\t\tisExported: true,\n\t\tleadingTrivia: (writer) => writer.blankLineIfLastNot(),\n\t\tdeclarations: [\n\t\t\t{\n\t\t\t\tname: modelName(model.name),\n\t\t\t\tinitializer(writer) {\n\t\t\t\t\twriter\n\t\t\t\t\t\t.write('z.object(')\n\t\t\t\t\t\t.inlineBlock(() => {\n\t\t\t\t\t\t\tmodel.fields\n\t\t\t\t\t\t\t\t.filter((f) => f.kind !== 'object')\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(f) =>\n\t\t\t\t\t\t\t\t\t\t!getZodDocElements(f.documentation ?? '').includes('omit()')\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.forEach((field) => {\n\t\t\t\t\t\t\t\t\twriteArray(writer, getJSDocs(field.documentation))\n\t\t\t\t\t\t\t\t\twriter\n\t\t\t\t\t\t\t\t\t\t.write(`${field.name}: ${getZodConstructor(field)}`)\n\t\t\t\t\t\t\t\t\t\t.write(',')\n\t\t\t\t\t\t\t\t\t\t.newLine()\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.write(')')\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t})\n}\n\nexport const generateRelatedSchemaForModel = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t_prismaOptions: PrismaOptions\n) => {\n\tconst { modelName, relatedModelName } = useModelNames(config)\n\n\tconst relationFields = model.fields.filter((f) => f.kind === 'object')\n\n\tsourceFile.addInterface({\n\t\tname: `Complete${model.name}`,\n\t\tisExported: true,\n\t\textends: [`z.infer`],\n\t\tproperties: relationFields.map((f) => ({\n\t\t\thasQuestionToken: !f.isRequired,\n\t\t\tname: f.name,\n\t\t\ttype: `Complete${f.type}${f.isList ? '[]' : ''}${!f.isRequired ? ' | null' : ''}`,\n\t\t})),\n\t})\n\n\tsourceFile.addStatements((writer) =>\n\t\twriteArray(writer, [\n\t\t\t'',\n\t\t\t'/**',\n\t\t\t` * ${relatedModelName(\n\t\t\t\tmodel.name\n\t\t\t)} contains all relations on your model in addition to the scalars`,\n\t\t\t' *',\n\t\t\t' * NOTE: Lazy required in case of potential circular dependencies within schema',\n\t\t\t' */',\n\t\t])\n\t)\n\n\tsourceFile.addVariableStatement({\n\t\tdeclarationKind: VariableDeclarationKind.Const,\n\t\tisExported: true,\n\t\tdeclarations: [\n\t\t\t{\n\t\t\t\tname: relatedModelName(model.name),\n\t\t\t\ttype: `z.ZodSchema`,\n\t\t\t\tinitializer(writer) {\n\t\t\t\t\twriter\n\t\t\t\t\t\t.write(`z.lazy(() => ${modelName(model.name)}.extend(`)\n\t\t\t\t\t\t.inlineBlock(() => {\n\t\t\t\t\t\t\trelationFields.forEach((field) => {\n\t\t\t\t\t\t\t\twriteArray(writer, getJSDocs(field.documentation))\n\n\t\t\t\t\t\t\t\twriter\n\t\t\t\t\t\t\t\t\t.write(\n\t\t\t\t\t\t\t\t\t\t`${field.name}: ${getZodConstructor(\n\t\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\t\trelatedModelName\n\t\t\t\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.write(',')\n\t\t\t\t\t\t\t\t\t.newLine()\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.write('))')\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t})\n}\n\nexport const populateModelFile = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\tprismaOptions: PrismaOptions\n) => {\n\twriteImportsForModel(model, sourceFile, config, prismaOptions)\n\twriteTypeSpecificSchemas(model, sourceFile, config, prismaOptions)\n\tgenerateSchemaForModel(model, sourceFile, config, prismaOptions)\n\tif (needsRelatedModel(model, config))\n\t\tgenerateRelatedSchemaForModel(model, sourceFile, config, prismaOptions)\n}\n\nexport const generateBarrelFile = (models: DMMF.Model[], indexFile: SourceFile) => {\n\tmodels.forEach((model) =>\n\t\tindexFile.addExportDeclaration({\n\t\t\tmoduleSpecifier: `./${model.name.toLowerCase()}`,\n\t\t})\n\t)\n}\n","// @ts-ignore Importing package.json for automated synchronization of version numbers\nimport { version } from '../package.json'\n\nimport { generatorHandler } from '@prisma/generator-helper'\nimport { SemicolonPreference } from 'typescript'\nimport { configSchema, PrismaOptions } from './config'\nimport { populateModelFile, generateBarrelFile } from './generator'\nimport { Project } from 'ts-morph'\n\ngeneratorHandler({\n\tonManifest() {\n\t\treturn {\n\t\t\tversion,\n\t\t\tprettyName: 'Zod Schemas',\n\t\t\tdefaultOutput: 'zod',\n\t\t}\n\t},\n\tonGenerate(options) {\n\t\tconst project = new Project()\n\n\t\tconst models = options.dmmf.datamodel.models\n\n\t\tconst { schemaPath } = options\n\t\tconst outputPath = options.generator.output!.value\n\t\tconst clientPath = options.otherGenerators.find(\n\t\t\t(each) => each.provider.value === 'prisma-client-js'\n\t\t)!.output!.value!\n\n\t\tconst results = configSchema.safeParse(options.generator.config)\n\t\tif (!results.success)\n\t\t\tthrow new Error(\n\t\t\t\t'Incorrect config provided. Please check the values you provided and try again.'\n\t\t\t)\n\n\t\tconst config = results.data\n\t\tconst prismaOptions: PrismaOptions = {\n\t\t\tclientPath,\n\t\t\toutputPath,\n\t\t\tschemaPath,\n\t\t}\n\n\t\tconst indexFile = project.createSourceFile(\n\t\t\t`${outputPath}/index.ts`,\n\t\t\t{},\n\t\t\t{ overwrite: true }\n\t\t)\n\n\t\tgenerateBarrelFile(models, indexFile)\n\n\t\tindexFile.formatText({\n\t\t\tindentSize: 2,\n\t\t\tconvertTabsToSpaces: true,\n\t\t\tsemicolons: SemicolonPreference.Remove,\n\t\t})\n\n\t\tmodels.forEach((model) => {\n\t\t\tconst sourceFile = project.createSourceFile(\n\t\t\t\t`${outputPath}/${model.name.toLowerCase()}.ts`,\n\t\t\t\t{},\n\t\t\t\t{ overwrite: true }\n\t\t\t)\n\n\t\t\tpopulateModelFile(model, sourceFile, config, prismaOptions)\n\n\t\t\tsourceFile.formatText({\n\t\t\t\tindentSize: 2,\n\t\t\t\tconvertTabsToSpaces: true,\n\t\t\t\tsemicolons: SemicolonPreference.Remove,\n\t\t\t})\n\t\t})\n\n\t\treturn project.save()\n\t},\n})\n"],"names":["configBoolean","z","enum","transform","arg","JSON","parse","configSchema","object","relationModel","default","or","literal","modelSuffix","string","modelCase","useDecimalJs","imports","optional","prismaJsonNullability","writeArray","writer","array","newLine","forEach","line","write","conditionalNewLine","useModelNames","formatModelName","name","prefix","slice","toLowerCase","modelName","relatedModelName","toString","needsRelatedModel","model","config","fields","some","field","kind","chunk","input","size","reduce","arr","item","idx","dotSlash","converted","replace","includes","split","startsWith","getJSDocs","docString","lines","docLines","filter","dL","trimStart","length","push","getZodDocElements","map","flatMap","each","contents","stringify","computeCustomSchema","find","modifier","computeModifiers","getZodConstructor","getRelatedModelName","zodType","extraModifiers","type","isList","documentation","isRequired","join","writeImportsForModel","sourceFile","schemaPath","outputPath","clientPath","importList","StructureKind","ImportDeclaration","namespaceImport","moduleSpecifier","path","relative","resolve","dirname","f","namedImports","enumFields","relationFields","relativePath","isTypeOnly","Array","from","Set","filteredFields","addImportDeclarations","writeTypeSpecificSchemas","_prismaOptions","addStatements","generateSchemaForModel","addVariableStatement","declarationKind","VariableDeclarationKind","Const","isExported","leadingTrivia","blankLineIfLastNot","declarations","initializer","inlineBlock","generateRelatedSchemaForModel","addInterface","extends","properties","hasQuestionToken","populateModelFile","prismaOptions","generateBarrelFile","models","indexFile","addExportDeclaration","generatorHandler","onManifest","version","prettyName","defaultOutput","onGenerate","options","project","Project","dmmf","datamodel","generator","output","value","otherGenerators","provider","results","safeParse","success","Error","data","createSourceFile","overwrite","formatText","indentSize","convertTabsToSpaces","semicolons","SemicolonPreference","Remove","save"],"mappings":"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"} \ No newline at end of file diff --git a/dist/zod-prisma.cjs.production.min.js b/dist/zod-prisma.cjs.production.min.js deleted file mode 100644 index 6f00abe..0000000 --- a/dist/zod-prisma.cjs.production.min.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict";var e=require("@prisma/generator-helper"),t=require("typescript"),a=require("zod"),r=require("path"),i=require("ts-morph"),n=require("parenthesis");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var l=o(r);const s=a.z.enum(["true","false"]).transform((e=>JSON.parse(e))),c=a.z.object({relationModel:s.default("true").or(a.z.literal("default")),modelSuffix:a.z.string().default("Model"),modelCase:a.z.enum(["PascalCase","camelCase"]).default("PascalCase"),useDecimalJs:s.default("false"),imports:a.z.string().optional(),prismaJsonNullability:s.default("true")}),d=(e,t,a=!0)=>t.forEach((t=>e.write(t).conditionalNewLine(a))),m=({modelCase:e,modelSuffix:t,relationModel:a})=>{const r=(a,r="")=>("camelCase"===e&&(a=a.slice(0,1).toLowerCase()+a.slice(1)),`${r}${a}${t}`);return{modelName:e=>r(e,"default"===a?"_":""),relatedModelName:e=>r("default"===a?e.toString():`Related${e.toString()}`)}},u=e=>{const t=e.replace(/^\\\\\?\\/,"").replace(/\\/g,"/").replace(/\/\/+/g,"/");return t.includes("/node_modules/")?t.split("/node_modules/").slice(-1)[0]:t.startsWith("../")?t:"./"+t},p=e=>{const t=[];if(e){const a=e.split("\n").filter((e=>!e.trimStart().startsWith("@zod")));a.length&&(t.push("/**"),a.forEach((e=>t.push(` * ${e}`))),t.push(" */"))}return t},f=e=>e.split("\n").filter((e=>e.trimStart().startsWith("@zod"))).map((e=>e.trimStart().slice(4))).flatMap((e=>{return(t=n.parse(e),t.reduce(((e,t,a)=>a%2==0?[...e,[t]]:[...e.slice(0,-1),[...e.slice(-1)[0],t]]),[])).slice(0,-1).map((([e,t])=>e.replace(/\)?\./,"")+`${n.stringify(t)})`));var t})),h=(e,t=(e=>e.toString()))=>{let a="z.unknown()",r=[""];if("scalar"===e.kind)switch(e.type){case"String":a="z.string()";break;case"Int":a="z.number()",r.push("int()");break;case"BigInt":a="z.bigint()";break;case"DateTime":a="z.date()";break;case"Float":case"Decimal":a="z.number()";break;case"Json":a="jsonSchema";break;case"Boolean":a="z.boolean()";break;case"Bytes":a="z.unknown()"}else"enum"===e.kind?a=`z.nativeEnum(${e.type})`:"object"===e.kind&&(a=t(e.type));var i,n,o;return e.isList&&r.push("array()"),e.documentation&&(a=null!=(i=null==(n=f(e.documentation).find((e=>e.startsWith("custom("))))?void 0:n.slice(7).slice(0,-1))?i:a,r.push(...(o=e.documentation,f(o).filter((e=>!e.startsWith("custom(")))))),e.isRequired||"Json"===e.type||r.push("nullish()"),`${a}${r.join(".")}`};e.generatorHandler({onManifest:()=>({version:"0.5.6",prettyName:"Zod Schemas",defaultOutput:"zod"}),onGenerate(e){const a=new i.Project,r=e.dmmf.datamodel.models,{schemaPath:n}=e,o=e.generator.output.value,s=e.otherGenerators.find((e=>"prisma-client-js"===e.provider.value)).output.value,S=c.safeParse(e.generator.config);if(!S.success)throw new Error("Incorrect config provided. Please check the values you provided and try again.");const z=S.data,y={clientPath:s,outputPath:o,schemaPath:n},b=a.createSourceFile(`${o}/index.ts`,{},{overwrite:!0});return((e,t)=>{e.forEach((e=>t.addExportDeclaration({moduleSpecifier:`./${e.name.toLowerCase()}`})))})(r,b),b.formatText({indentSize:2,convertTabsToSpaces:!0,semicolons:t.SemicolonPreference.Remove}),r.forEach((e=>{const r=a.createSourceFile(`${o}/${e.name.toLowerCase()}.ts`,{},{overwrite:!0});((e,t,a,r)=>{((e,t,a,{schemaPath:r,outputPath:n,clientPath:o})=>{const{relatedModelName:s}=m(a),c=[{kind:i.StructureKind.ImportDeclaration,namespaceImport:"z",moduleSpecifier:"zod"}];a.imports&&c.push({kind:i.StructureKind.ImportDeclaration,namespaceImport:"imports",moduleSpecifier:u(l.default.relative(n,l.default.resolve(l.default.dirname(r),a.imports)))}),a.useDecimalJs&&e.fields.some((e=>"Decimal"===e.type))&&c.push({kind:i.StructureKind.ImportDeclaration,namedImports:["Decimal"],moduleSpecifier:"decimal.js"});const d=e.fields.filter((e=>"enum"===e.kind)),p=e.fields.filter((e=>"object"===e.kind)),f=l.default.relative(n,o);if(d.length>0&&c.push({kind:i.StructureKind.ImportDeclaration,isTypeOnly:0===d.length,moduleSpecifier:u(f),namedImports:Array.from(new Set(d.map((e=>e.type))))}),!1!==a.relationModel&&p.length>0){const t=p.filter((t=>t.type!==e.name));t.length>0&&c.push({kind:i.StructureKind.ImportDeclaration,moduleSpecifier:"./index",namedImports:Array.from(new Set(t.flatMap((e=>[`Complete${e.type}`,s(e.type)]))))})}t.addImportDeclarations(c)})(e,t,a,r),((e,t,a,r)=>{e.fields.some((e=>"Json"===e.type))&&t.addStatements((e=>{e.newLine(),d(e,["// Helper schema for JSON fields","type Literal = boolean | number | string"+(a.prismaJsonNullability?"":"| null"),"type Json = Literal | { [key: string]: Json } | Json[]",`const literalSchema = z.union([z.string(), z.number(), z.boolean()${a.prismaJsonNullability?"":", z.null()"}])`,"const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))"])})),a.useDecimalJs&&e.fields.some((e=>"Decimal"===e.type))&&t.addStatements((e=>{e.newLine(),d(e,["// Helper schema for Decimal fields","z",".instanceof(Decimal)",".or(z.string())",".or(z.number())",".refine((value) => {"," try {"," return new Decimal(value);"," } catch (error) {"," return false;"," }","})",".transform((value) => new Decimal(value));"])}))})(e,t,a),((e,t,a,r)=>{const{modelName:n}=m(a);t.addVariableStatement({declarationKind:i.VariableDeclarationKind.Const,isExported:!0,leadingTrivia:e=>e.blankLineIfLastNot(),declarations:[{name:n(e.name),initializer(t){t.write("z.object(").inlineBlock((()=>{e.fields.filter((e=>"object"!==e.kind)).filter((e=>{var t;return!f(null!=(t=e.documentation)?t:"").includes("omit()")})).forEach((e=>{d(t,p(e.documentation)),t.write(`${e.name}: ${h(e)}`).write(",").newLine()}))})).write(")")}}]})})(e,t,a),((e,t)=>e.fields.some((e=>"object"===e.kind))&&!1!==t.relationModel)(e,a)&&((e,t,a,r)=>{const{modelName:n,relatedModelName:o}=m(a),l=e.fields.filter((e=>"object"===e.kind));t.addInterface({name:`Complete${e.name}`,isExported:!0,extends:[`z.infer`],properties:l.map((e=>({hasQuestionToken:!e.isRequired,name:e.name,type:`Complete${e.type}${e.isList?"[]":""}${e.isRequired?"":" | null"}`})))}),t.addStatements((t=>d(t,["","/**",` * ${o(e.name)} contains all relations on your model in addition to the scalars`," *"," * NOTE: Lazy required in case of potential circular dependencies within schema"," */"]))),t.addVariableStatement({declarationKind:i.VariableDeclarationKind.Const,isExported:!0,declarations:[{name:o(e.name),type:`z.ZodSchema`,initializer(t){t.write(`z.lazy(() => ${n(e.name)}.extend(`).inlineBlock((()=>{l.forEach((e=>{d(t,p(e.documentation)),t.write(`${e.name}: ${h(e,o)}`).write(",").newLine()}))})).write("))")}}]})})(e,t,a)})(e,r,z,y),r.formatText({indentSize:2,convertTabsToSpaces:!0,semicolons:t.SemicolonPreference.Remove})})),a.save()}}); -//# sourceMappingURL=zod-prisma.cjs.production.min.js.map diff --git a/dist/zod-prisma.cjs.production.min.js.map b/dist/zod-prisma.cjs.production.min.js.map deleted file mode 100644 index 729d7da..0000000 --- a/dist/zod-prisma.cjs.production.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"zod-prisma.cjs.production.min.js","sources":["../src/config.ts","../src/util.ts","../src/docs.ts","../src/types.ts","../src/index.ts","../src/generator.ts"],"sourcesContent":["import { z } from 'zod'\n\nconst configBoolean = z.enum(['true', 'false']).transform((arg) => JSON.parse(arg))\n\nexport const configSchema = z.object({\n\trelationModel: configBoolean.default('true').or(z.literal('default')),\n\tmodelSuffix: z.string().default('Model'),\n\tmodelCase: z.enum(['PascalCase', 'camelCase']).default('PascalCase'),\n\tuseDecimalJs: configBoolean.default('false'),\n\timports: z.string().optional(),\n\tprismaJsonNullability: configBoolean.default('true'),\n})\n\nexport type Config = z.infer\n\nexport type PrismaOptions = {\n\tschemaPath: string\n\toutputPath: string\n\tclientPath: string\n}\n\nexport type Names = {\n\tmodel: string\n\trelated: string\n}\n","import { DMMF } from '@prisma/generator-helper'\nimport type { CodeBlockWriter } from 'ts-morph'\nimport { Config } from './config'\n\nexport const writeArray = (writer: CodeBlockWriter, array: string[], newLine = true) =>\n\tarray.forEach((line) => writer.write(line).conditionalNewLine(newLine))\n\nexport const useModelNames = ({ modelCase, modelSuffix, relationModel }: Config) => {\n\tconst formatModelName = (name: string, prefix = '') => {\n\t\tif (modelCase === 'camelCase') {\n\t\t\tname = name.slice(0, 1).toLowerCase() + name.slice(1)\n\t\t}\n\t\treturn `${prefix}${name}${modelSuffix}`\n\t}\n\n\treturn {\n\t\tmodelName: (name: string) => formatModelName(name, relationModel === 'default' ? '_' : ''),\n\t\trelatedModelName: (name: string | DMMF.SchemaEnum | DMMF.OutputType | DMMF.SchemaArg) =>\n\t\t\tformatModelName(\n\t\t\t\trelationModel === 'default' ? name.toString() : `Related${name.toString()}`\n\t\t\t),\n\t}\n}\n\nexport const needsRelatedModel = (model: DMMF.Model, config: Config) =>\n\tmodel.fields.some((field) => field.kind === 'object') && config.relationModel !== false\n\nexport const chunk = (input: T, size: number): T[] => {\n\treturn input.reduce((arr, item, idx) => {\n\t\treturn idx % size === 0\n\t\t\t? [...arr, [item]]\n\t\t\t: [...arr.slice(0, -1), [...arr.slice(-1)[0], item]]\n\t}, [])\n}\n\nexport const dotSlash = (input: string) => {\n\tconst converted = input\n\t\t.replace(/^\\\\\\\\\\?\\\\/, '')\n\t\t.replace(/\\\\/g, '/')\n\t\t.replace(/\\/\\/+/g, '/')\n\n\tif (converted.includes(`/node_modules/`)) return converted.split(`/node_modules/`).slice(-1)[0]\n\n\tif (converted.startsWith(`../`)) return converted\n\n\treturn './' + converted\n}\n","import { ArrayTree, parse, stringify } from 'parenthesis'\nimport { chunk } from './util'\n\nexport const getJSDocs = (docString?: string) => {\n\tconst lines: string[] = []\n\n\tif (docString) {\n\t\tconst docLines = docString.split('\\n').filter((dL) => !dL.trimStart().startsWith('@zod'))\n\n\t\tif (docLines.length) {\n\t\t\tlines.push('/**')\n\t\t\tdocLines.forEach((dL) => lines.push(` * ${dL}`))\n\t\t\tlines.push(' */')\n\t\t}\n\t}\n\n\treturn lines\n}\n\nexport const getZodDocElements = (docString: string) =>\n\tdocString\n\t\t.split('\\n')\n\t\t.filter((line) => line.trimStart().startsWith('@zod'))\n\t\t.map((line) => line.trimStart().slice(4))\n\t\t.flatMap((line) =>\n\t\t\t// Array.from(line.matchAll(/\\.([^().]+\\(.*?\\))/g), (m) => m.slice(1)).flat()\n\t\t\tchunk(parse(line), 2)\n\t\t\t\t.slice(0, -1)\n\t\t\t\t.map(\n\t\t\t\t\t([each, contents]) =>\n\t\t\t\t\t\t(each as string).replace(/\\)?\\./, '') +\n\t\t\t\t\t\t`${stringify(contents as ArrayTree)})`\n\t\t\t\t)\n\t\t)\n\nexport const computeCustomSchema = (docString: string) => {\n\treturn getZodDocElements(docString)\n\t\t.find((modifier) => modifier.startsWith('custom('))\n\t\t?.slice(7)\n\t\t.slice(0, -1)\n}\n\nexport const computeModifiers = (docString: string) => {\n\treturn getZodDocElements(docString).filter((each) => !each.startsWith('custom('))\n}\n","import type { DMMF } from '@prisma/generator-helper'\nimport { computeCustomSchema, computeModifiers } from './docs'\n\nexport const getZodConstructor = (\n\tfield: DMMF.Field,\n\tgetRelatedModelName = (name: string | DMMF.SchemaEnum | DMMF.OutputType | DMMF.SchemaArg) =>\n\t\tname.toString()\n) => {\n\tlet zodType = 'z.unknown()'\n\tlet extraModifiers: string[] = ['']\n\tif (field.kind === 'scalar') {\n\t\tswitch (field.type) {\n\t\t\tcase 'String':\n\t\t\t\tzodType = 'z.string()'\n\t\t\t\tbreak\n\t\t\tcase 'Int':\n\t\t\t\tzodType = 'z.number()'\n\t\t\t\textraModifiers.push('int()')\n\t\t\t\tbreak\n\t\t\tcase 'BigInt':\n\t\t\t\tzodType = 'z.bigint()'\n\t\t\t\tbreak\n\t\t\tcase 'DateTime':\n\t\t\t\tzodType = 'z.date()'\n\t\t\t\tbreak\n\t\t\tcase 'Float':\n\t\t\t\tzodType = 'z.number()'\n\t\t\t\tbreak\n\t\t\tcase 'Decimal':\n\t\t\t\tzodType = 'z.number()'\n\t\t\t\tbreak\n\t\t\tcase 'Json':\n\t\t\t\tzodType = 'jsonSchema'\n\t\t\t\tbreak\n\t\t\tcase 'Boolean':\n\t\t\t\tzodType = 'z.boolean()'\n\t\t\t\tbreak\n\t\t\t// TODO: Proper type for bytes fields\n\t\t\tcase 'Bytes':\n\t\t\t\tzodType = 'z.unknown()'\n\t\t\t\tbreak\n\t\t}\n\t} else if (field.kind === 'enum') {\n\t\tzodType = `z.nativeEnum(${field.type})`\n\t} else if (field.kind === 'object') {\n\t\tzodType = getRelatedModelName(field.type)\n\t}\n\n\tif (field.isList) extraModifiers.push('array()')\n\tif (field.documentation) {\n\t\tzodType = computeCustomSchema(field.documentation) ?? zodType\n\t\textraModifiers.push(...computeModifiers(field.documentation))\n\t}\n\tif (!field.isRequired && field.type !== 'Json') extraModifiers.push('nullish()')\n\t// if (field.hasDefaultValue) extraModifiers.push('optional()')\n\n\treturn `${zodType}${extraModifiers.join('.')}`\n}\n","// @ts-ignore Importing package.json for automated synchronization of version numbers\nimport { version } from '../package.json'\n\nimport { generatorHandler } from '@prisma/generator-helper'\nimport { SemicolonPreference } from 'typescript'\nimport { configSchema, PrismaOptions } from './config'\nimport { populateModelFile, generateBarrelFile } from './generator'\nimport { Project } from 'ts-morph'\n\ngeneratorHandler({\n\tonManifest() {\n\t\treturn {\n\t\t\tversion,\n\t\t\tprettyName: 'Zod Schemas',\n\t\t\tdefaultOutput: 'zod',\n\t\t}\n\t},\n\tonGenerate(options) {\n\t\tconst project = new Project()\n\n\t\tconst models = options.dmmf.datamodel.models\n\n\t\tconst { schemaPath } = options\n\t\tconst outputPath = options.generator.output!.value\n\t\tconst clientPath = options.otherGenerators.find(\n\t\t\t(each) => each.provider.value === 'prisma-client-js'\n\t\t)!.output!.value!\n\n\t\tconst results = configSchema.safeParse(options.generator.config)\n\t\tif (!results.success)\n\t\t\tthrow new Error(\n\t\t\t\t'Incorrect config provided. Please check the values you provided and try again.'\n\t\t\t)\n\n\t\tconst config = results.data\n\t\tconst prismaOptions: PrismaOptions = {\n\t\t\tclientPath,\n\t\t\toutputPath,\n\t\t\tschemaPath,\n\t\t}\n\n\t\tconst indexFile = project.createSourceFile(\n\t\t\t`${outputPath}/index.ts`,\n\t\t\t{},\n\t\t\t{ overwrite: true }\n\t\t)\n\n\t\tgenerateBarrelFile(models, indexFile)\n\n\t\tindexFile.formatText({\n\t\t\tindentSize: 2,\n\t\t\tconvertTabsToSpaces: true,\n\t\t\tsemicolons: SemicolonPreference.Remove,\n\t\t})\n\n\t\tmodels.forEach((model) => {\n\t\t\tconst sourceFile = project.createSourceFile(\n\t\t\t\t`${outputPath}/${model.name.toLowerCase()}.ts`,\n\t\t\t\t{},\n\t\t\t\t{ overwrite: true }\n\t\t\t)\n\n\t\t\tpopulateModelFile(model, sourceFile, config, prismaOptions)\n\n\t\t\tsourceFile.formatText({\n\t\t\t\tindentSize: 2,\n\t\t\t\tconvertTabsToSpaces: true,\n\t\t\t\tsemicolons: SemicolonPreference.Remove,\n\t\t\t})\n\t\t})\n\n\t\treturn project.save()\n\t},\n})\n","import path from 'path'\nimport { DMMF } from '@prisma/generator-helper'\nimport {\n\tImportDeclarationStructure,\n\tSourceFile,\n\tStructureKind,\n\tVariableDeclarationKind,\n} from 'ts-morph'\nimport { Config, PrismaOptions } from './config'\nimport { dotSlash, needsRelatedModel, useModelNames, writeArray } from './util'\nimport { getJSDocs, getZodDocElements } from './docs'\nimport { getZodConstructor } from './types'\n\nexport const writeImportsForModel = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t{ schemaPath, outputPath, clientPath }: PrismaOptions\n) => {\n\tconst { relatedModelName } = useModelNames(config)\n\tconst importList: ImportDeclarationStructure[] = [\n\t\t{\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tnamespaceImport: 'z',\n\t\t\tmoduleSpecifier: 'zod',\n\t\t},\n\t]\n\n\tif (config.imports) {\n\t\timportList.push({\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tnamespaceImport: 'imports',\n\t\t\tmoduleSpecifier: dotSlash(\n\t\t\t\tpath.relative(outputPath, path.resolve(path.dirname(schemaPath), config.imports))\n\t\t\t),\n\t\t})\n\t}\n\n\tif (config.useDecimalJs && model.fields.some((f) => f.type === 'Decimal')) {\n\t\timportList.push({\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tnamedImports: ['Decimal'],\n\t\t\tmoduleSpecifier: 'decimal.js',\n\t\t})\n\t}\n\n\tconst enumFields = model.fields.filter((f) => f.kind === 'enum')\n\tconst relationFields = model.fields.filter((f) => f.kind === 'object')\n\tconst relativePath = path.relative(outputPath, clientPath)\n\n\tif (enumFields.length > 0) {\n\t\timportList.push({\n\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\tisTypeOnly: enumFields.length === 0,\n\t\t\tmoduleSpecifier: dotSlash(relativePath),\n\t\t\tnamedImports: Array.from(new Set(enumFields.map((f) => f.type))),\n\t\t})\n\t}\n\n\tif (config.relationModel !== false && relationFields.length > 0) {\n\t\tconst filteredFields = relationFields.filter((f) => f.type !== model.name)\n\n\t\tif (filteredFields.length > 0) {\n\t\t\timportList.push({\n\t\t\t\tkind: StructureKind.ImportDeclaration,\n\t\t\t\tmoduleSpecifier: './index',\n\t\t\t\tnamedImports: Array.from(\n\t\t\t\t\tnew Set(\n\t\t\t\t\t\tfilteredFields.flatMap((f) => [\n\t\t\t\t\t\t\t`Complete${f.type}`,\n\t\t\t\t\t\t\trelatedModelName(f.type),\n\t\t\t\t\t\t])\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t})\n\t\t}\n\t}\n\n\tsourceFile.addImportDeclarations(importList)\n}\n\nexport const writeTypeSpecificSchemas = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t_prismaOptions: PrismaOptions\n) => {\n\tif (model.fields.some((f) => f.type === 'Json')) {\n\t\tsourceFile.addStatements((writer) => {\n\t\t\twriter.newLine()\n\t\t\twriteArray(writer, [\n\t\t\t\t'// Helper schema for JSON fields',\n\t\t\t\t`type Literal = boolean | number | string${\n\t\t\t\t\tconfig.prismaJsonNullability ? '' : '| null'\n\t\t\t\t}`,\n\t\t\t\t'type Json = Literal | { [key: string]: Json } | Json[]',\n\t\t\t\t`const literalSchema = z.union([z.string(), z.number(), z.boolean()${\n\t\t\t\t\tconfig.prismaJsonNullability ? '' : ', z.null()'\n\t\t\t\t}])`,\n\t\t\t\t'const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))',\n\t\t\t])\n\t\t})\n\t}\n\n\tif (config.useDecimalJs && model.fields.some((f) => f.type === 'Decimal')) {\n\t\tsourceFile.addStatements((writer) => {\n\t\t\twriter.newLine()\n\t\t\twriteArray(writer, [\n\t\t\t\t'// Helper schema for Decimal fields',\n\t\t\t\t'z',\n\t\t\t\t'.instanceof(Decimal)',\n\t\t\t\t'.or(z.string())',\n\t\t\t\t'.or(z.number())',\n\t\t\t\t'.refine((value) => {',\n\t\t\t\t' try {',\n\t\t\t\t' return new Decimal(value);',\n\t\t\t\t' } catch (error) {',\n\t\t\t\t' return false;',\n\t\t\t\t' }',\n\t\t\t\t'})',\n\t\t\t\t'.transform((value) => new Decimal(value));',\n\t\t\t])\n\t\t})\n\t}\n}\n\nexport const generateSchemaForModel = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t_prismaOptions: PrismaOptions\n) => {\n\tconst { modelName } = useModelNames(config)\n\n\tsourceFile.addVariableStatement({\n\t\tdeclarationKind: VariableDeclarationKind.Const,\n\t\tisExported: true,\n\t\tleadingTrivia: (writer) => writer.blankLineIfLastNot(),\n\t\tdeclarations: [\n\t\t\t{\n\t\t\t\tname: modelName(model.name),\n\t\t\t\tinitializer(writer) {\n\t\t\t\t\twriter\n\t\t\t\t\t\t.write('z.object(')\n\t\t\t\t\t\t.inlineBlock(() => {\n\t\t\t\t\t\t\tmodel.fields\n\t\t\t\t\t\t\t\t.filter((f) => f.kind !== 'object')\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(f) =>\n\t\t\t\t\t\t\t\t\t\t!getZodDocElements(f.documentation ?? '').includes('omit()')\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.forEach((field) => {\n\t\t\t\t\t\t\t\t\twriteArray(writer, getJSDocs(field.documentation))\n\t\t\t\t\t\t\t\t\twriter\n\t\t\t\t\t\t\t\t\t\t.write(`${field.name}: ${getZodConstructor(field)}`)\n\t\t\t\t\t\t\t\t\t\t.write(',')\n\t\t\t\t\t\t\t\t\t\t.newLine()\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.write(')')\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t})\n}\n\nexport const generateRelatedSchemaForModel = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\t_prismaOptions: PrismaOptions\n) => {\n\tconst { modelName, relatedModelName } = useModelNames(config)\n\n\tconst relationFields = model.fields.filter((f) => f.kind === 'object')\n\n\tsourceFile.addInterface({\n\t\tname: `Complete${model.name}`,\n\t\tisExported: true,\n\t\textends: [`z.infer`],\n\t\tproperties: relationFields.map((f) => ({\n\t\t\thasQuestionToken: !f.isRequired,\n\t\t\tname: f.name,\n\t\t\ttype: `Complete${f.type}${f.isList ? '[]' : ''}${!f.isRequired ? ' | null' : ''}`,\n\t\t})),\n\t})\n\n\tsourceFile.addStatements((writer) =>\n\t\twriteArray(writer, [\n\t\t\t'',\n\t\t\t'/**',\n\t\t\t` * ${relatedModelName(\n\t\t\t\tmodel.name\n\t\t\t)} contains all relations on your model in addition to the scalars`,\n\t\t\t' *',\n\t\t\t' * NOTE: Lazy required in case of potential circular dependencies within schema',\n\t\t\t' */',\n\t\t])\n\t)\n\n\tsourceFile.addVariableStatement({\n\t\tdeclarationKind: VariableDeclarationKind.Const,\n\t\tisExported: true,\n\t\tdeclarations: [\n\t\t\t{\n\t\t\t\tname: relatedModelName(model.name),\n\t\t\t\ttype: `z.ZodSchema`,\n\t\t\t\tinitializer(writer) {\n\t\t\t\t\twriter\n\t\t\t\t\t\t.write(`z.lazy(() => ${modelName(model.name)}.extend(`)\n\t\t\t\t\t\t.inlineBlock(() => {\n\t\t\t\t\t\t\trelationFields.forEach((field) => {\n\t\t\t\t\t\t\t\twriteArray(writer, getJSDocs(field.documentation))\n\n\t\t\t\t\t\t\t\twriter\n\t\t\t\t\t\t\t\t\t.write(\n\t\t\t\t\t\t\t\t\t\t`${field.name}: ${getZodConstructor(\n\t\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\t\trelatedModelName\n\t\t\t\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.write(',')\n\t\t\t\t\t\t\t\t\t.newLine()\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.write('))')\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t})\n}\n\nexport const populateModelFile = (\n\tmodel: DMMF.Model,\n\tsourceFile: SourceFile,\n\tconfig: Config,\n\tprismaOptions: PrismaOptions\n) => {\n\twriteImportsForModel(model, sourceFile, config, prismaOptions)\n\twriteTypeSpecificSchemas(model, sourceFile, config, prismaOptions)\n\tgenerateSchemaForModel(model, sourceFile, config, prismaOptions)\n\tif (needsRelatedModel(model, config))\n\t\tgenerateRelatedSchemaForModel(model, sourceFile, config, prismaOptions)\n}\n\nexport const generateBarrelFile = (models: DMMF.Model[], indexFile: SourceFile) => {\n\tmodels.forEach((model) =>\n\t\tindexFile.addExportDeclaration({\n\t\t\tmoduleSpecifier: `./${model.name.toLowerCase()}`,\n\t\t})\n\t)\n}\n"],"names":["configBoolean","z","enum","transform","arg","JSON","parse","configSchema","object","relationModel","default","or","literal","modelSuffix","string","modelCase","useDecimalJs","imports","optional","prismaJsonNullability","writeArray","writer","array","newLine","forEach","line","write","conditionalNewLine","useModelNames","formatModelName","name","prefix","slice","toLowerCase","modelName","relatedModelName","toString","dotSlash","input","converted","replace","includes","split","startsWith","getJSDocs","docString","lines","docLines","filter","dL","trimStart","length","push","getZodDocElements","map","flatMap","chunk","reduce","arr","item","idx","each","contents","stringify","getZodConstructor","field","getRelatedModelName","zodType","extraModifiers","kind","type","isList","documentation","find","modifier","_getZodDocElements$fi","isRequired","join","generatorHandler","onManifest","version","prettyName","defaultOutput","onGenerate","options","project","Project","models","dmmf","datamodel","schemaPath","outputPath","generator","output","value","clientPath","otherGenerators","provider","results","safeParse","config","success","Error","data","prismaOptions","indexFile","createSourceFile","overwrite","model","addExportDeclaration","moduleSpecifier","generateBarrelFile","formatText","indentSize","convertTabsToSpaces","semicolons","SemicolonPreference","Remove","sourceFile","importList","StructureKind","ImportDeclaration","namespaceImport","path","relative","resolve","dirname","fields","some","f","namedImports","enumFields","relationFields","relativePath","isTypeOnly","Array","from","Set","filteredFields","addImportDeclarations","writeImportsForModel","_prismaOptions","addStatements","writeTypeSpecificSchemas","addVariableStatement","declarationKind","VariableDeclarationKind","Const","isExported","leadingTrivia","blankLineIfLastNot","declarations","initializer","inlineBlock","generateSchemaForModel","needsRelatedModel","addInterface","extends","properties","hasQuestionToken","generateRelatedSchemaForModel","populateModelFile","save"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 9cdfe45..64fd8fc 100644 --- a/package.json +++ b/package.json @@ -65,17 +65,17 @@ "execa": "^5.1.0", "fast-glob": "^3.2.5", "fs-extra": "^10.0.0", - "husky": "^7.0.4", + "husky": "^9.1.7", "jest-mock-extended": "^2.0.4", "prisma": "^3.4.2", "tslib": "^2.3.1", - "typescript": "^4.5.4", - "zod": "^3.11.6" + "typescript": "^5.6.3", + "zod": "^4.1.11" }, "peerDependencies": { "decimal.js": "^10.0.0", "prisma": "^4.0.0", - "zod": "^3.0.0" + "zod": "^4.0.0" }, "peerDependenciesMeta": { "decimal.js": { @@ -84,5 +84,6 @@ }, "engines": { "node": ">=14" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/src/config.ts b/src/config.ts index 55dd5a8..c99efbf 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,14 +1,17 @@ import { z } from 'zod' -const configBoolean = z.enum(['true', 'false']).transform((arg) => JSON.parse(arg)) +const stringBoolean = z.union([z.literal('true'), z.literal('false')]) +const configBoolean = stringBoolean + .default('true') + .transform((arg: 'true' | 'false') => arg === 'true') export const configSchema = z.object({ - relationModel: configBoolean.default('true').or(z.literal('default')), + relationModel: z.union([z.literal('default'), configBoolean]), modelSuffix: z.string().default('Model'), - modelCase: z.enum(['PascalCase', 'camelCase']).default('PascalCase'), - useDecimalJs: configBoolean.default('false'), + modelCase: z.union([z.literal('PascalCase'), z.literal('camelCase')]).default('PascalCase'), + useDecimalJs: configBoolean, imports: z.string().optional(), - prismaJsonNullability: configBoolean.default('true'), + prismaJsonNullability: configBoolean, }) export type Config = z.infer diff --git a/src/generator.ts b/src/generator.ts index 6149cc0..aa8fc87 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -9,6 +9,7 @@ import { import { Config, PrismaOptions } from './config' import { dotSlash, needsRelatedModel, useModelNames, writeArray } from './util' import { getJSDocs, getZodDocElements } from './docs' +import { computeCustomSchema } from './docs' import { getZodConstructor } from './types' export const writeImportsForModel = ( @@ -36,7 +37,10 @@ export const writeImportsForModel = ( }) } - if (config.useDecimalJs && model.fields.some((f) => f.type === 'Decimal')) { + const hasNonCustomDecimalFieldForImports = model.fields.some( + (f) => f.type === 'Decimal' && (!f.documentation || !computeCustomSchema(f.documentation)) + ) + if (config.useDecimalJs && hasNonCustomDecimalFieldForImports) { importList.push({ kind: StructureKind.ImportDeclaration, namedImports: ['Decimal'], @@ -97,12 +101,15 @@ export const writeTypeSpecificSchemas = ( `const literalSchema = z.union([z.string(), z.number(), z.boolean()${ config.prismaJsonNullability ? '' : ', z.null()' }])`, - 'const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))', + 'const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)]))', ]) }) } - if (config.useDecimalJs && model.fields.some((f) => f.type === 'Decimal')) { + const hasNonCustomDecimalField = model.fields.some( + (f) => f.type === 'Decimal' && (!f.documentation || !computeCustomSchema(f.documentation)) + ) + if (config.useDecimalJs && hasNonCustomDecimalField) { sourceFile.addStatements((writer) => { writer.newLine() writeArray(writer, [ diff --git a/src/test/functional/basic/expected/spreadsheet.ts b/src/test/functional/basic/expected/spreadsheet.ts index 5daf7b7..c64b9f9 100644 --- a/src/test/functional/basic/expected/spreadsheet.ts +++ b/src/test/functional/basic/expected/spreadsheet.ts @@ -4,7 +4,7 @@ import * as z from "zod" type Literal = boolean | number | string type Json = Literal | { [key: string]: Json } | Json[] const literalSchema = z.union([z.string(), z.number(), z.boolean()]) -const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])) +const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])) export const SpreadsheetModel = z.object({ id: z.string(), diff --git a/src/test/functional/driver.test.ts b/src/test/functional/driver.test.ts index ff82c4c..b62d06d 100644 --- a/src/test/functional/driver.test.ts +++ b/src/test/functional/driver.test.ts @@ -116,7 +116,13 @@ describe('Functional Tests', () => { test.concurrent('Type Check Everything', async () => { const typeCheckResults = await execa( path.resolve(__dirname, '../../../node_modules/.bin/tsc'), - ['--strict', '--noEmit', ...(await glob(`${__dirname}/*/expected/*.ts`))] + [ + '--strict', + '--noEmit', + '--esModuleInterop', + '--skipLibCheck', + ...(await glob(`${__dirname}/*/expected/*.ts`)), + ] ) expect(typeCheckResults.exitCode).toBe(0) diff --git a/src/test/functional/imports/expected/spreadsheet.ts b/src/test/functional/imports/expected/spreadsheet.ts index d17b9b2..8b4f72b 100644 --- a/src/test/functional/imports/expected/spreadsheet.ts +++ b/src/test/functional/imports/expected/spreadsheet.ts @@ -5,7 +5,7 @@ import { CompletePresentation, RelatedPresentationModel } from "./index" type Literal = boolean | number | string type Json = Literal | { [key: string]: Json } | Json[] const literalSchema = z.union([z.string(), z.number(), z.boolean()]) -const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])) +const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])) export const SpreadsheetModel = z.object({ id: z.string(), diff --git a/src/test/functional/json/expected/user.ts b/src/test/functional/json/expected/user.ts index 911d077..feb2418 100644 --- a/src/test/functional/json/expected/user.ts +++ b/src/test/functional/json/expected/user.ts @@ -5,7 +5,7 @@ import { CompletePost, RelatedPostModel } from "./index" type Literal = boolean | number | string type Json = Literal | { [key: string]: Json } | Json[] const literalSchema = z.union([z.string(), z.number(), z.boolean()]) -const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])) +const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])) export const UserModel = z.object({ id: z.number().int(), diff --git a/src/test/functional/optional/expected/user.ts b/src/test/functional/optional/expected/user.ts index abfad2a..3fe8f03 100644 --- a/src/test/functional/optional/expected/user.ts +++ b/src/test/functional/optional/expected/user.ts @@ -5,7 +5,7 @@ import { CompletePost, RelatedPostModel } from "./index" type Literal = boolean | number | string type Json = Literal | { [key: string]: Json } | Json[] const literalSchema = z.union([z.string(), z.number(), z.boolean()]) -const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])) +const jsonSchema: z.ZodSchema = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(z.string(), jsonSchema)])) export const UserModel = z.object({ id: z.number().int(), diff --git a/yarn.lock b/yarn.lock index 0114b51..e9765c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3557,10 +3557,10 @@ humanize-duration@^3.15.3: resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-3.27.1.tgz#2cd4ea4b03bd92184aee6d90d77a8f3d7628df69" integrity sha512-jCVkMl+EaM80rrMrAPl96SGG4NRac53UyI1o/yAzebDntEY6K6/Fj2HOjdPg8omTqIe5Y0wPBai2q5xXrIbarA== -husky@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" - integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== +husky@^9.1.7: + version "9.1.7" + resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.7.tgz#d46a38035d101b46a70456a850ff4201344c0b2d" + integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA== iconv-lite@0.4.24: version "0.4.24" @@ -6120,6 +6120,11 @@ typescript@^4.5.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== +typescript@^5.6.3: + version "5.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" + integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== + unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -6417,7 +6422,7 @@ zip-stream@^3.0.1: compress-commons "^3.0.0" readable-stream "^3.6.0" -zod@^3.11.6: - version "3.11.6" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.11.6.tgz#e43a5e0c213ae2e02aefe7cb2b1a6fa3d7f1f483" - integrity sha512-daZ80A81I3/9lIydI44motWe6n59kRBfNzTuS2bfzVh1nAXi667TOTWWtatxyG+fwgNUiagSj/CWZwRRbevJIg== +zod@^4.1.11: + version "4.1.11" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.11.tgz#4aab62f76cfd45e6c6166519ba31b2ea019f75f5" + integrity sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==