|
1 | 1 | /* eslint-disable @typescript-eslint/ban-ts-comment */
|
| 2 | +import { DELEGATE_AUX_RELATION_PREFIX } from '@zenstackhq/runtime'; |
2 | 3 | import {
|
3 | 4 | getForeignKeyFields,
|
| 5 | + getRelationBackLink, |
4 | 6 | hasAttribute,
|
5 | 7 | indentString,
|
| 8 | + isDelegateModel, |
6 | 9 | isDiscriminatorField,
|
7 | 10 | type PluginOptions,
|
8 | 11 | } from '@zenstackhq/sdk';
|
@@ -67,7 +70,11 @@ export default class Transformer {
|
67 | 70 | const filePath = path.join(Transformer.outputPath, `enums/${name}.schema.ts`);
|
68 | 71 | const content = `${this.generateImportZodStatement()}\n${this.generateExportSchemaStatement(
|
69 | 72 | `${name}`,
|
70 |
| - `z.enum(${JSON.stringify(enumType.values)})` |
| 73 | + `z.enum(${JSON.stringify( |
| 74 | + enumType.values |
| 75 | + // exclude fields generated for delegate models |
| 76 | + .filter((v) => !v.startsWith(DELEGATE_AUX_RELATION_PREFIX)) |
| 77 | + )})` |
71 | 78 | )}`;
|
72 | 79 | this.sourceFiles.push(this.project.createSourceFile(filePath, content, { overwrite: true }));
|
73 | 80 | generated.push(enumType.name);
|
@@ -243,12 +250,19 @@ export default class Transformer {
|
243 | 250 | !isFieldRef &&
|
244 | 251 | (inputType.namespace === 'prisma' || isEnum)
|
245 | 252 | ) {
|
246 |
| - if (inputType.type !== this.originalName && typeof inputType.type === 'string') { |
247 |
| - this.addSchemaImport(inputType.type); |
| 253 | + // reduce concrete input types to their delegate base types |
| 254 | + // e.g.: "UserCreateNestedOneWithoutDelegate_aux_PostInput" => "UserCreateWithoutAssetInput" |
| 255 | + let mappedInputType = inputType; |
| 256 | + if (contextDataModel) { |
| 257 | + mappedInputType = this.mapDelegateInputType(inputType, contextDataModel, field.name); |
| 258 | + } |
| 259 | + |
| 260 | + if (mappedInputType.type !== this.originalName && typeof mappedInputType.type === 'string') { |
| 261 | + this.addSchemaImport(mappedInputType.type); |
248 | 262 | }
|
249 | 263 |
|
250 | 264 | const contextField = contextDataModel?.fields.find((f) => f.name === field.name);
|
251 |
| - result.push(this.generatePrismaStringLine(field, inputType, lines.length, contextField)); |
| 265 | + result.push(this.generatePrismaStringLine(field, mappedInputType, lines.length, contextField)); |
252 | 266 | }
|
253 | 267 | }
|
254 | 268 |
|
@@ -289,6 +303,46 @@ export default class Transformer {
|
289 | 303 | return [[` ${fieldName} ${resString} `, field, true]];
|
290 | 304 | }
|
291 | 305 |
|
| 306 | + private mapDelegateInputType( |
| 307 | + inputType: PrismaDMMF.InputTypeRef, |
| 308 | + contextDataModel: DataModel, |
| 309 | + contextFieldName: string |
| 310 | + ) { |
| 311 | + // input type mapping is only relevant for relation inherited from delegate models |
| 312 | + const contextField = contextDataModel.fields.find((f) => f.name === contextFieldName); |
| 313 | + if (!contextField || !isDataModel(contextField.type.reference?.ref)) { |
| 314 | + return inputType; |
| 315 | + } |
| 316 | + |
| 317 | + if (!contextField.$inheritedFrom || !isDelegateModel(contextField.$inheritedFrom)) { |
| 318 | + return inputType; |
| 319 | + } |
| 320 | + |
| 321 | + let processedInputType = inputType; |
| 322 | + |
| 323 | + // captures: model name and operation, "Without" part that references a concrete model, |
| 324 | + // and the "Input" or "NestedInput" suffix |
| 325 | + const match = inputType.type.match(/^(\S+?)((NestedOne)?WithoutDelegate_aux\S+?)((Nested)?Input)$/); |
| 326 | + if (match) { |
| 327 | + let mappedInputTypeName = match[1]; |
| 328 | + |
| 329 | + if (contextDataModel) { |
| 330 | + // get the opposite side of the relation field, which should be of the proper |
| 331 | + // delegate base type |
| 332 | + const oppositeRelationField = getRelationBackLink(contextField); |
| 333 | + if (oppositeRelationField) { |
| 334 | + mappedInputTypeName += `Without${upperCaseFirst(oppositeRelationField.name)}`; |
| 335 | + } |
| 336 | + } |
| 337 | + |
| 338 | + // "Input" or "NestedInput" suffix |
| 339 | + mappedInputTypeName += match[4]; |
| 340 | + |
| 341 | + processedInputType = { ...inputType, type: mappedInputTypeName }; |
| 342 | + } |
| 343 | + return processedInputType; |
| 344 | + } |
| 345 | + |
292 | 346 | wrapWithZodValidators(
|
293 | 347 | mainValidators: string | string[],
|
294 | 348 | field: PrismaDMMF.SchemaArg,
|
|
0 commit comments