prisma-nestjs-graphql 21.2.0 → 22.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/generate.cjs DELETED
@@ -1,2152 +0,0 @@
1
- 'use strict';
2
-
3
- var require$$0 = require('await-event-emitter');
4
- var assert = require('assert');
5
- var lodash = require('lodash');
6
- var tsMorph = require('ts-morph');
7
- var JSON5 = require('json5');
8
- var pupa = require('pupa');
9
- var getRelativePath = require('get-relative-path');
10
- var outmatch = require('outmatch');
11
- var gracefulFs = require('graceful-fs');
12
- var filenamify = require('filenamify');
13
- var flat = require('flat');
14
- var pluralize = require('pluralize');
15
-
16
- function isManyAndReturnOutputType(name) {
17
- const lowerName = name.toLowerCase();
18
- if ((lowerName.startsWith("createmany") || lowerName.startsWith("updatemany")) && (lowerName.endsWith("andreturnoutputtype") || lowerName.endsWith("andreturn"))) {
19
- return true;
20
- }
21
- return false;
22
- }
23
-
24
- function pascalCase(string) {
25
- return lodash.startCase(lodash.camelCase(string)).replaceAll(" ", "");
26
- }
27
-
28
- function argsType(field, args) {
29
- if (["queryRaw", "executeRaw"].includes(field.name)) {
30
- return;
31
- }
32
- if (isManyAndReturnOutputType(field.name)) return;
33
- const { eventEmitter, typeNames, getModelName } = args;
34
- let className = pascalCase(`${field.name}Args`);
35
- const modelName = getModelName(className) || "";
36
- switch (className) {
37
- case `Aggregate${modelName}Args`: {
38
- className = `${modelName}AggregateArgs`;
39
- break;
40
- }
41
- case `GroupBy${modelName}Args`: {
42
- className = `${modelName}GroupByArgs`;
43
- break;
44
- }
45
- }
46
- const inputType = {
47
- // eslint-disable-next-line unicorn/no-null
48
- constraints: { maxNumFields: null, minNumFields: null },
49
- name: className,
50
- fields: [...field.args]
51
- };
52
- if (!field.args.some((x) => x.name === "_count") && [`${modelName}AggregateArgs`, `${modelName}GroupByArgs`].includes(className)) {
53
- const names = ["Count", "Avg", "Sum", "Min", "Max"];
54
- if (`${modelName}GroupByArgs` === inputType.name) {
55
- const byField = inputType.fields.find((f) => f.name === "by");
56
- if (byField?.inputTypes) {
57
- byField.inputTypes = byField.inputTypes.filter((inputType2) => inputType2.isList);
58
- }
59
- }
60
- for (const name of names) {
61
- if (!typeNames.has(`${modelName}${name}AggregateInput`)) {
62
- continue;
63
- }
64
- inputType.fields.push({
65
- name: `_${name.toLowerCase()}`,
66
- isRequired: false,
67
- isNullable: true,
68
- inputTypes: [
69
- {
70
- location: "inputObjectTypes",
71
- type: `${modelName}${name}AggregateInput`,
72
- isList: false
73
- }
74
- ]
75
- });
76
- }
77
- }
78
- eventEmitter.emitSync("InputType", {
79
- ...args,
80
- inputType,
81
- fileType: "args",
82
- classDecoratorName: "ArgsType"
83
- });
84
- }
85
-
86
- const BeforeGenerateField = "BeforeGenerateField";
87
-
88
- function combineScalarFilters(eventEmitter) {
89
- eventEmitter.on("BeforeInputType", beforeInputType$2);
90
- eventEmitter.on(BeforeGenerateField, beforeGenerateField);
91
- eventEmitter.on("PostBegin", postBegin);
92
- }
93
- function beforeInputType$2(args) {
94
- const { inputType, removeTypes } = args;
95
- if (isContainBogus(inputType.name) && isScalarFilter(inputType)) {
96
- removeTypes.add(inputType.name);
97
- inputType.name = replaceBogus(inputType.name);
98
- }
99
- }
100
- function beforeGenerateField(field) {
101
- for (const fieldInput of field.inputTypes) {
102
- if (fieldInput.location !== "inputObjectTypes") {
103
- continue;
104
- }
105
- const fieldInputType = String(fieldInput.type);
106
- if (isContainBogus(fieldInputType)) {
107
- fieldInput.type = replaceBogus(fieldInputType);
108
- }
109
- }
110
- }
111
- function replaceBogus(name) {
112
- return name.replaceAll(/Nullable|Nested/g, "");
113
- }
114
- function isContainBogus(name) {
115
- return name.startsWith("Nested") || name.includes("Nullable") && name.endsWith("Filter") || name.endsWith("NullableFilter");
116
- }
117
- function isScalarFilter(inputType) {
118
- if (!inputType.name.endsWith("Filter")) {
119
- return false;
120
- }
121
- let result = false;
122
- const equals = inputType.fields.find((f) => f.name === "equals");
123
- if (equals) {
124
- result = equals.inputTypes.every((x) => {
125
- return ["enumTypes", "scalar"].includes(x.location);
126
- });
127
- }
128
- return result;
129
- }
130
- function postBegin(args) {
131
- const { modelNames, schema } = args;
132
- const inputTypes = schema.inputObjectTypes.prisma;
133
- const enumTypes = schema.enumTypes.model || [];
134
- const types = [
135
- "Bool",
136
- "Int",
137
- "String",
138
- "DateTime",
139
- "Decimal",
140
- "Float",
141
- "Json",
142
- "Bytes",
143
- "BigInt"
144
- ];
145
- for (const enumType of enumTypes) {
146
- const { name } = enumType;
147
- types.push(`Enum${name}`);
148
- }
149
- const inputTypeByName = lodash.keyBy(inputTypes, (inputType) => inputType.name);
150
- const replaceBogusFilters = (filterName, filterNameCandidates) => {
151
- for (const filterNameCandidate of filterNameCandidates) {
152
- const candidate = inputTypeByName[filterNameCandidate];
153
- if (candidate) {
154
- const inputType = lodash.cloneDeep({ ...candidate, name: filterName });
155
- inputTypes.push(inputType);
156
- inputTypeByName[filterName] = inputType;
157
- break;
158
- }
159
- }
160
- };
161
- for (const type of types) {
162
- replaceBogusFilters(`${type}Filter`, [
163
- `${type}NullableFilter`,
164
- `Nested${type}NullableFilter`
165
- ]);
166
- replaceBogusFilters(`${type}WithAggregatesFilter`, [
167
- `${type}NullableWithAggregatesFilter`,
168
- `Nested${type}NullableWithAggregatesFilter`
169
- ]);
170
- replaceBogusFilters(`${type}ListFilter`, [
171
- `${type}NullableListFilter`,
172
- `Nested${type}NullableListFilter`
173
- ]);
174
- }
175
- for (const modelName of modelNames) {
176
- replaceBogusFilters(`${modelName}RelationFilter`, [
177
- `${modelName}NullableRelationFilter`
178
- ]);
179
- }
180
- for (const modelName of modelNames) {
181
- replaceBogusFilters(`${modelName}ScalarRelationFilter`, [
182
- `${modelName}NullableScalarRelationFilter`
183
- ]);
184
- }
185
- lodash.remove(inputTypes, (inputType) => {
186
- return isContainBogus(inputType.name);
187
- });
188
- }
189
-
190
- function createAggregateInput(args) {
191
- const { eventEmitter, outputType } = args;
192
- const className = `${outputType.name}Input`;
193
- const inputType = {
194
- // eslint-disable-next-line unicorn/no-null
195
- constraints: { maxNumFields: null, minNumFields: null },
196
- name: className,
197
- fields: outputType.fields.map((x) => ({
198
- name: x.name,
199
- isNullable: x.isNullable ?? true,
200
- isRequired: false,
201
- inputTypes: [
202
- {
203
- isList: false,
204
- type: "true",
205
- location: "scalar"
206
- }
207
- ]
208
- }))
209
- };
210
- eventEmitter.emitSync("InputType", {
211
- ...args,
212
- inputType,
213
- fileType: "input",
214
- classDecoratorName: "InputType"
215
- });
216
- }
217
-
218
- function emitSingle(emitter) {
219
- emitter.on("ClassProperty", classProperty);
220
- }
221
- function classProperty(property, eventArguments) {
222
- const { location, isList, propertyType } = eventArguments;
223
- if (["inputObjectTypes", "outputObjectTypes"].includes(location) && !isList) {
224
- const [safeTypes, instanceofTypes] = lodash.partition(
225
- propertyType,
226
- (t) => t === "null" || t.startsWith("Prisma.")
227
- );
228
- const mappedInstanceofTypes = instanceofTypes.map((t) => `InstanceType<typeof ${t}>`);
229
- property.type = [...mappedInstanceofTypes, ...safeTypes].join(" | ");
230
- }
231
- }
232
-
233
- class ImportDeclarationMap extends Map {
234
- add(name, value) {
235
- if (!this.has(name)) {
236
- const structure = typeof value === "string" ? { moduleSpecifier: value, namedImports: [{ name }] } : value;
237
- this.set(name, structure);
238
- }
239
- }
240
- create(args) {
241
- const { from, defaultImport, namespaceImport, namedImport } = args;
242
- let name = args.name;
243
- const value = {
244
- moduleSpecifier: from,
245
- namedImports: [],
246
- defaultImport: void 0,
247
- namespaceImport: void 0
248
- };
249
- if (namedImport === true && namespaceImport) {
250
- value.namedImports = [{ name: namespaceImport }];
251
- name = namespaceImport;
252
- } else if (defaultImport) {
253
- value.defaultImport = defaultImport === true ? name : defaultImport;
254
- name = value.defaultImport;
255
- } else if (namespaceImport) {
256
- value.namespaceImport = namespaceImport;
257
- name = namespaceImport;
258
- } else {
259
- value.namedImports = [{ name }];
260
- }
261
- this.add(name, value);
262
- }
263
- *toStatements() {
264
- const iterator = this.values();
265
- let result = iterator.next();
266
- while (result.value) {
267
- yield {
268
- ...result.value,
269
- kind: tsMorph.StructureKind.ImportDeclaration
270
- };
271
- result = iterator.next();
272
- }
273
- }
274
- }
275
-
276
- async function generateFiles(args) {
277
- const { config, eventEmitter, output, project } = args;
278
- if (config.emitSingle) {
279
- const rootDirectory = project.getDirectory(output) || project.createDirectory(output);
280
- const sourceFile = rootDirectory.getSourceFile("index.ts") || rootDirectory.createSourceFile("index.ts", void 0, { overwrite: true });
281
- const statements = project.getSourceFiles().flatMap((s) => {
282
- if (s === sourceFile) {
283
- return [];
284
- }
285
- const classDeclaration = s.getClass(() => true);
286
- const statements2 = s.getStructure().statements;
287
- if (Array.isArray(statements2)) {
288
- for (const statement of statements2) {
289
- if (!(typeof statement === "object" && statement.kind === tsMorph.StructureKind.Class)) {
290
- continue;
291
- }
292
- for (const property of statement.properties || []) {
293
- for (const decorator of property.decorators || []) {
294
- const fullName = classDeclaration?.getProperty(property.name)?.getDecorator(decorator.name)?.getFullName();
295
- assert.ok(
296
- fullName,
297
- `Cannot get full name of decorator of class ${statement.name}`
298
- );
299
- decorator.name = fullName;
300
- }
301
- }
302
- }
303
- }
304
- project.removeSourceFile(s);
305
- return statements2;
306
- });
307
- const imports = new ImportDeclarationMap();
308
- const enums = [];
309
- const classes = [];
310
- for (const statement of statements) {
311
- if (typeof statement === "string") {
312
- if (statement.startsWith("registerEnumType")) {
313
- enums.push(statement);
314
- }
315
- continue;
316
- }
317
- switch (statement.kind) {
318
- case tsMorph.StructureKind.ImportDeclaration: {
319
- if (statement.moduleSpecifier.startsWith("./") || statement.moduleSpecifier.startsWith("..")) {
320
- continue;
321
- }
322
- for (const namedImport of statement.namedImports) {
323
- const name = namedImport.alias || namedImport.name;
324
- imports.add(name, statement.moduleSpecifier);
325
- }
326
- if (statement.defaultImport) {
327
- imports.create({
328
- defaultImport: statement.defaultImport,
329
- from: statement.moduleSpecifier,
330
- name: statement.defaultImport
331
- });
332
- }
333
- if (statement.namespaceImport) {
334
- imports.create({
335
- from: statement.moduleSpecifier,
336
- name: statement.namespaceImport,
337
- namespaceImport: statement.namespaceImport
338
- });
339
- }
340
- break;
341
- }
342
- case tsMorph.StructureKind.Enum: {
343
- enums.unshift(statement);
344
- break;
345
- }
346
- case tsMorph.StructureKind.Class: {
347
- classes.push(statement);
348
- break;
349
- }
350
- }
351
- }
352
- for (const customImport of config.customImport) {
353
- imports.create(customImport);
354
- }
355
- sourceFile.set({
356
- kind: tsMorph.StructureKind.SourceFile,
357
- statements: [...imports.toStatements(), ...enums, ...classes]
358
- });
359
- }
360
- if (config.emitCompiled) {
361
- project.compilerOptions.set({
362
- declaration: true,
363
- declarationDir: output,
364
- emitDecoratorMetadata: false,
365
- outDir: output,
366
- rootDir: output,
367
- skipLibCheck: true
368
- });
369
- const emitResult = await project.emit();
370
- const errors = emitResult.getDiagnostics().map((d) => String(d.getMessageText()));
371
- if (errors.length > 0) {
372
- eventEmitter.emitSync("Warning", errors);
373
- }
374
- } else {
375
- await project.save();
376
- }
377
- }
378
-
379
- function fileTypeByLocation(fieldLocation) {
380
- switch (fieldLocation) {
381
- case "inputObjectTypes": {
382
- return "input";
383
- }
384
- case "outputObjectTypes": {
385
- return "output";
386
- }
387
- case "enumTypes": {
388
- return "enum";
389
- }
390
- }
391
- return "object";
392
- }
393
-
394
- function relativePath(from, to) {
395
- if (!from.startsWith("/")) {
396
- from = `/${from}`;
397
- }
398
- if (!to.startsWith("/")) {
399
- to = `/${to}`;
400
- }
401
- let result = getRelativePath(from, to);
402
- if (!result.startsWith(".")) {
403
- result = `./${result}`;
404
- }
405
- if (result.endsWith(".ts")) {
406
- result = result.slice(0, -3);
407
- }
408
- return result;
409
- }
410
-
411
- function getGraphqlImport(args) {
412
- const {
413
- config,
414
- fileType,
415
- getSourceFile,
416
- isId,
417
- location,
418
- noTypeId,
419
- sourceFile,
420
- typeName
421
- } = args;
422
- if (location === "scalar") {
423
- if (isId && !noTypeId) {
424
- return { name: "ID", specifier: "@nestjs/graphql" };
425
- }
426
- const graphqlType = config.graphqlScalars[typeName];
427
- if (graphqlType) {
428
- return { name: graphqlType.name, specifier: graphqlType.specifier };
429
- }
430
- switch (typeName) {
431
- case "Float":
432
- case "Int": {
433
- return { name: typeName, specifier: "@nestjs/graphql" };
434
- }
435
- case "DateTime": {
436
- return { name: "Date", specifier: void 0 };
437
- }
438
- case "true":
439
- case "Boolean": {
440
- return { name: "Boolean", specifier: void 0 };
441
- }
442
- case "Decimal": {
443
- return {
444
- name: "GraphQLDecimal",
445
- specifier: "prisma-graphql-type-decimal"
446
- };
447
- }
448
- case "Json": {
449
- return { name: "GraphQLJSON", specifier: "graphql-type-json" };
450
- }
451
- }
452
- return { name: "String", specifier: void 0 };
453
- }
454
- let sourceFileType = fileTypeByLocation(location);
455
- if (sourceFileType === "output" && fileType === "model") {
456
- sourceFileType = "model";
457
- }
458
- const specifier = relativePath(
459
- sourceFile.getFilePath(),
460
- getSourceFile({
461
- name: typeName,
462
- type: sourceFileType
463
- }).getFilePath()
464
- );
465
- return { name: typeName, specifier };
466
- }
467
-
468
- function getGraphqlInputType(inputTypes, pattern) {
469
- let result;
470
- inputTypes = inputTypes.filter((t) => !["null", "Null"].includes(String(t.type)));
471
- inputTypes = lodash.uniqWith(inputTypes, lodash.isEqual);
472
- if (inputTypes.length === 1) {
473
- return inputTypes[0];
474
- }
475
- const countTypes = lodash.countBy(inputTypes, (x) => x.location);
476
- const isOneType = Object.keys(countTypes).length === 1;
477
- if (isOneType) {
478
- result = inputTypes.find((x) => x.isList);
479
- if (result) {
480
- return result;
481
- }
482
- }
483
- if (pattern) {
484
- if (pattern.startsWith("matcher:") || pattern.startsWith("match:")) {
485
- const { 1: patternValue } = pattern.split(":", 2);
486
- const isMatch = outmatch(patternValue, { separator: false });
487
- result = inputTypes.find((x) => isMatch(String(x.type)));
488
- if (result) {
489
- return result;
490
- }
491
- }
492
- result = inputTypes.find((x) => String(x.type).includes(pattern));
493
- if (result) {
494
- return result;
495
- }
496
- }
497
- result = inputTypes.find((x) => x.location === "inputObjectTypes");
498
- if (result) {
499
- return result;
500
- }
501
- if (countTypes.enumTypes && countTypes.scalar && inputTypes.some((x) => x.type === "Json" && x.location === "scalar")) {
502
- result = inputTypes.find((x) => x.type === "Json" && x.location === "scalar");
503
- if (result) {
504
- return result;
505
- }
506
- }
507
- if ((countTypes.scalar >= 1 || countTypes.enumTypes >= 1) && countTypes.fieldRefTypes === 1) {
508
- result = inputTypes.find(
509
- (x) => (x.location === "scalar" || x.location === "enumTypes") && x.isList
510
- );
511
- if (result) {
512
- return result;
513
- }
514
- result = inputTypes.find(
515
- (x) => x.location === "scalar" || x.location === "enumTypes"
516
- );
517
- if (result) {
518
- return result;
519
- }
520
- }
521
- throw new TypeError(
522
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
523
- `Cannot get matching input type from ${inputTypes.map((x) => x.type).join(", ") || "zero length inputTypes"}`
524
- );
525
- }
526
-
527
- function getPropertyType(args) {
528
- const { location, type } = args;
529
- switch (type) {
530
- case "Float":
531
- case "Int": {
532
- return ["number"];
533
- }
534
- case "String": {
535
- return ["string"];
536
- }
537
- case "Boolean": {
538
- return ["boolean"];
539
- }
540
- case "DateTime": {
541
- return ["Date", "string"];
542
- }
543
- case "Decimal": {
544
- return ["Decimal"];
545
- }
546
- case "Json": {
547
- return ["any"];
548
- }
549
- case "Null": {
550
- return ["null"];
551
- }
552
- case "Bytes": {
553
- return ["Uint8Array"];
554
- }
555
- case "BigInt": {
556
- return ["bigint", "number"];
557
- }
558
- }
559
- if (["inputObjectTypes", "outputObjectTypes"].includes(location)) {
560
- return [type];
561
- }
562
- if (location === "enumTypes") {
563
- const enumType = "`${" + type + "}`";
564
- return [enumType];
565
- }
566
- if (location === "scalar") {
567
- return [type];
568
- }
569
- return ["unknown"];
570
- }
571
-
572
- function getWhereUniqueAtLeastKeys(model) {
573
- const names = model.fields.filter((field) => field.isUnique || field.isId).map((field) => field.name);
574
- if (model.primaryKey) {
575
- names.push(createFieldName(model.primaryKey));
576
- }
577
- for (const uniqueIndex of model.uniqueIndexes) {
578
- names.push(createFieldName(uniqueIndex));
579
- }
580
- return names;
581
- }
582
- function createFieldName(args) {
583
- const { name, fields } = args;
584
- return name || fields.join("_");
585
- }
586
-
587
- function isWhereUniqueInputType(name) {
588
- return name.endsWith("WhereUniqueInput");
589
- }
590
-
591
- function propertyStructure(args) {
592
- const {
593
- isNullable,
594
- propertyType,
595
- name,
596
- isList,
597
- hasQuestionToken,
598
- hasExclamationToken
599
- } = args;
600
- const type = propertyType.map((type2) => isList ? `Array<${type2}>` : type2).join(" | ");
601
- return {
602
- kind: tsMorph.StructureKind.Property,
603
- name,
604
- type,
605
- hasQuestionToken: hasQuestionToken ?? isNullable,
606
- hasExclamationToken: hasExclamationToken ?? !isNullable,
607
- decorators: [],
608
- leadingTrivia: "\n"
609
- };
610
- }
611
-
612
- function inputType(args) {
613
- const {
614
- classDecoratorName,
615
- classTransformerTypeModels,
616
- config,
617
- eventEmitter,
618
- fieldSettings,
619
- fileType,
620
- getModelName,
621
- getSourceFile,
622
- inputType: inputType2,
623
- models,
624
- removeTypes,
625
- typeNames
626
- } = args;
627
- typeNames.add(inputType2.name);
628
- const importDeclarations = new ImportDeclarationMap();
629
- const sourceFile = getSourceFile({
630
- name: inputType2.name,
631
- type: fileType
632
- });
633
- const classStructure = {
634
- kind: tsMorph.StructureKind.Class,
635
- isExported: true,
636
- name: inputType2.name,
637
- decorators: [
638
- {
639
- name: classDecoratorName,
640
- arguments: []
641
- }
642
- ],
643
- properties: []
644
- };
645
- const modelName = getModelName(inputType2.name) || "";
646
- const model = models.get(modelName);
647
- const modelFieldSettings = model && fieldSettings.get(model.name);
648
- const moduleSpecifier = "@nestjs/graphql";
649
- importDeclarations.set("Field", {
650
- namedImports: [{ name: "Field" }],
651
- moduleSpecifier
652
- }).set(classDecoratorName, {
653
- namedImports: [{ name: classDecoratorName }],
654
- moduleSpecifier
655
- });
656
- const useInputType = config.useInputType.find(
657
- (x) => inputType2.name.includes(x.typeName)
658
- );
659
- const isWhereUnique = isWhereUniqueInputType(inputType2.name);
660
- for (const field of inputType2.fields) {
661
- field.inputTypes = field.inputTypes.filter((t) => !removeTypes.has(String(t.type)));
662
- eventEmitter.emitSync(BeforeGenerateField, field, args);
663
- const { inputTypes, isRequired, name } = field;
664
- if (inputTypes.length === 0) {
665
- continue;
666
- }
667
- const usePattern = useInputType?.ALL || useInputType?.[name];
668
- const graphqlInputType = getGraphqlInputType(inputTypes, usePattern);
669
- const { isList, location, type } = graphqlInputType;
670
- const typeName = String(type);
671
- const settings = modelFieldSettings?.get(name);
672
- const propertySettings = settings?.getPropertyType({
673
- name: inputType2.name,
674
- input: true
675
- });
676
- const modelField = model?.fields.find((f) => f.name === name);
677
- const isCustomsApplicable = typeName === modelField?.type;
678
- const atLeastKeys = model && getWhereUniqueAtLeastKeys(model);
679
- const whereUniqueInputType = isWhereUniqueInputType(typeName) && atLeastKeys && `Prisma.AtLeast<${typeName}, ${atLeastKeys.map((name2) => `'${name2}'`).join(" | ")}>`;
680
- const propertyType = lodash.castArray(
681
- propertySettings?.name || whereUniqueInputType || getPropertyType({
682
- location,
683
- type: typeName
684
- })
685
- );
686
- const hasExclamationToken = Boolean(
687
- isWhereUnique && config.unsafeCompatibleWhereUniqueInput && atLeastKeys?.includes(name)
688
- );
689
- const property = propertyStructure({
690
- name,
691
- isNullable: !isRequired,
692
- hasExclamationToken: hasExclamationToken || void 0,
693
- hasQuestionToken: hasExclamationToken ? false : void 0,
694
- propertyType,
695
- isList
696
- });
697
- classStructure.properties.push(property);
698
- if (propertySettings) {
699
- importDeclarations.create({ ...propertySettings });
700
- } else if (propertyType.includes("Decimal")) {
701
- importDeclarations.add("Decimal", `${config.prismaClientImport}/runtime/library`);
702
- } else if (propertyType.some((p) => p.startsWith("Prisma."))) {
703
- importDeclarations.add("Prisma", config.prismaClientImport);
704
- }
705
- let graphqlType;
706
- const shouldHideField = settings?.shouldHideField({
707
- name: inputType2.name,
708
- input: true
709
- }) || config.decorate.some(
710
- (d) => d.name === "HideField" && d.from === moduleSpecifier && d.isMatchField(name) && d.isMatchType(inputType2.name)
711
- );
712
- const fieldType = settings?.getFieldType({
713
- name: inputType2.name,
714
- input: true
715
- });
716
- if (fieldType && isCustomsApplicable && !shouldHideField) {
717
- graphqlType = fieldType.name;
718
- importDeclarations.create({ ...fieldType });
719
- } else {
720
- const graphqlImport = getGraphqlImport({
721
- config,
722
- sourceFile,
723
- location,
724
- typeName,
725
- getSourceFile
726
- });
727
- graphqlType = graphqlImport.name;
728
- let referenceName = propertyType[0];
729
- if (location === "enumTypes") {
730
- referenceName = lodash.last(referenceName.split(" "));
731
- }
732
- if (graphqlImport.specifier && !importDeclarations.has(graphqlImport.name) && graphqlImport.name !== inputType2.name) {
733
- importDeclarations.set(graphqlImport.name, {
734
- namedImports: [{ name: graphqlImport.name }],
735
- moduleSpecifier: graphqlImport.specifier
736
- });
737
- }
738
- }
739
- assert.ok(property.decorators, "property.decorators is undefined");
740
- if (shouldHideField) {
741
- importDeclarations.add("HideField", moduleSpecifier);
742
- property.decorators.push({ name: "HideField", arguments: [] });
743
- } else {
744
- property.decorators.push({
745
- name: "Field",
746
- arguments: [
747
- isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`,
748
- JSON5.stringify({
749
- ...settings?.fieldArguments(),
750
- nullable: !isRequired
751
- })
752
- ]
753
- });
754
- if (graphqlType === "GraphQLDecimal") {
755
- importDeclarations.add("transformToDecimal", "prisma-graphql-type-decimal");
756
- importDeclarations.add("Transform", "class-transformer");
757
- importDeclarations.add("Type", "class-transformer");
758
- property.decorators.push(
759
- {
760
- name: "Type",
761
- arguments: ["() => Object"]
762
- },
763
- {
764
- name: "Transform",
765
- arguments: ["transformToDecimal"]
766
- }
767
- );
768
- } else if (location === "inputObjectTypes" && (modelField?.type === "Decimal" || [
769
- "connect",
770
- "connectOrCreate",
771
- "create",
772
- "createMany",
773
- "data",
774
- "delete",
775
- "deleteMany",
776
- "disconnect",
777
- "set",
778
- "update",
779
- "updateMany",
780
- "upsert",
781
- "where"
782
- ].includes(name) || classTransformerTypeModels.has(getModelName(graphqlType) || "") || modelField?.kind === "object" && models.get(modelField.type) && models.get(modelField.type)?.fields.some(
783
- (field2) => field2.kind === "object" && classTransformerTypeModels.has(field2.type)
784
- ))) {
785
- importDeclarations.add("Type", "class-transformer");
786
- property.decorators.push({ name: "Type", arguments: [`() => ${graphqlType}`] });
787
- }
788
- if (isCustomsApplicable) {
789
- for (const options of settings || []) {
790
- if ((options.kind === "Decorator" && options.input && options.match?.(name)) ?? true) {
791
- property.decorators.push({
792
- name: options.name,
793
- arguments: options.arguments
794
- });
795
- assert.ok(options.from, "Missed 'from' part in configuration or field setting");
796
- importDeclarations.create(options);
797
- }
798
- }
799
- }
800
- for (const decorate of config.decorate) {
801
- if (decorate.isMatchField(name) && decorate.isMatchType(inputType2.name)) {
802
- property.decorators.push({
803
- name: decorate.name,
804
- arguments: decorate.arguments?.map((x) => pupa(x, { propertyType }))
805
- });
806
- importDeclarations.create(decorate);
807
- }
808
- }
809
- }
810
- eventEmitter.emitSync("ClassProperty", property, {
811
- location,
812
- isList,
813
- propertyType
814
- });
815
- }
816
- sourceFile.set({
817
- statements: [...importDeclarations.toStatements(), classStructure]
818
- });
819
- }
820
-
821
- class ObjectSettings extends Array {
822
- shouldHideField({
823
- name,
824
- input = false,
825
- output = false
826
- }) {
827
- const hideField = this.find((s) => s.name === "HideField");
828
- return Boolean(
829
- hideField?.input && input || hideField?.output && output || hideField?.match?.(name)
830
- );
831
- }
832
- getFieldType({
833
- name,
834
- input,
835
- output
836
- }) {
837
- const fieldType = this.find((s) => s.kind === "FieldType");
838
- if (!fieldType) {
839
- return void 0;
840
- }
841
- if (fieldType.match) {
842
- return fieldType.match(name) ? fieldType : void 0;
843
- }
844
- if (input && !fieldType.input) {
845
- return void 0;
846
- }
847
- if (output && !fieldType.output) {
848
- return void 0;
849
- }
850
- return fieldType;
851
- }
852
- getPropertyType({
853
- name,
854
- input,
855
- output
856
- }) {
857
- const propertyType = this.find((s) => s.kind === "PropertyType");
858
- if (!propertyType) {
859
- return void 0;
860
- }
861
- if (propertyType.match) {
862
- return propertyType.match(name) ? propertyType : void 0;
863
- }
864
- if (input && !propertyType.input) {
865
- return void 0;
866
- }
867
- if (output && !propertyType.output) {
868
- return void 0;
869
- }
870
- return propertyType;
871
- }
872
- getObjectTypeArguments(options) {
873
- const objectTypeOptions = lodash.merge({}, options);
874
- const resultArguments = [objectTypeOptions];
875
- const objectType = this.find((s) => s.kind === "ObjectType");
876
- if (objectType && lodash.isObject(objectType.arguments)) {
877
- const name = objectType.arguments.name;
878
- lodash.merge(objectTypeOptions, lodash.omit(objectType.arguments, "name"));
879
- if (name) {
880
- resultArguments.unshift(name);
881
- }
882
- }
883
- return resultArguments.map((x) => JSON5.stringify(x));
884
- }
885
- fieldArguments() {
886
- const item = this.find((item2) => item2.kind === "Field");
887
- if (item) {
888
- return item.arguments;
889
- }
890
- }
891
- }
892
- function createObjectSettings(args) {
893
- const { config, text } = args;
894
- const result = new ObjectSettings();
895
- const textLines = text.split("\n");
896
- const documentationLines = [];
897
- let fieldElement = result.find((item) => item.kind === "Field");
898
- if (!fieldElement) {
899
- fieldElement = {
900
- name: "",
901
- kind: "Field",
902
- arguments: {}
903
- };
904
- }
905
- for (const line of textLines) {
906
- const match = /^@(?<name>\w+(\.(\w+))?)\((?<args>.*)\)/.exec(line);
907
- const { element, documentLine } = createSettingElement({
908
- line,
909
- config,
910
- fieldElement,
911
- match
912
- });
913
- if (element) {
914
- result.push(element);
915
- }
916
- if (documentLine) {
917
- documentationLines.push(line);
918
- }
919
- }
920
- return {
921
- settings: result,
922
- documentation: documentationLines.filter(Boolean).join("\n") || void 0
923
- };
924
- }
925
- function createSettingElement({
926
- line,
927
- config,
928
- fieldElement,
929
- match
930
- }) {
931
- const result = {
932
- documentLine: "",
933
- element: void 0
934
- };
935
- if (line.startsWith("@deprecated")) {
936
- fieldElement.arguments["deprecationReason"] = lodash.trim(line.slice(11));
937
- result.element = fieldElement;
938
- return result;
939
- }
940
- if (line.startsWith("@complexity")) {
941
- let n = Number.parseInt(lodash.trim(line.slice(11)));
942
- if (n !== n || n < 1) n = 1;
943
- fieldElement.arguments["complexity"] = n;
944
- result.element = fieldElement;
945
- return result;
946
- }
947
- const name = match?.groups?.name;
948
- if (!(match && name)) {
949
- result.documentLine = line;
950
- return result;
951
- }
952
- const element = {
953
- kind: "Decorator",
954
- name: "",
955
- arguments: [],
956
- input: false,
957
- output: false,
958
- model: false,
959
- from: ""
960
- };
961
- result.element = element;
962
- if (name === "TypeGraphQL.omit" || name === "HideField") {
963
- Object.assign(element, hideFieldDecorator(match));
964
- return result;
965
- }
966
- if (["FieldType", "PropertyType"].includes(name) && match.groups?.args) {
967
- const options2 = customType(match.groups.args);
968
- lodash.merge(element, options2.namespace && config.fields[options2.namespace], options2, {
969
- kind: name
970
- });
971
- return result;
972
- }
973
- if (name === "ObjectType" && match.groups?.args) {
974
- element.kind = "ObjectType";
975
- const options2 = customType(match.groups.args);
976
- if (typeof options2[0] === "string" && options2[0]) {
977
- options2.name = options2[0];
978
- }
979
- if (lodash.isObject(options2[1])) {
980
- lodash.merge(options2, options2[1]);
981
- }
982
- element.arguments = {
983
- name: options2.name,
984
- isAbstract: options2.isAbstract
985
- };
986
- return result;
987
- }
988
- if (name === "Directive" && match.groups?.args) {
989
- const options2 = customType(match.groups.args);
990
- lodash.merge(element, { model: true, from: "@nestjs/graphql" }, options2, {
991
- name,
992
- namespace: false,
993
- kind: "Decorator",
994
- arguments: Array.isArray(options2.arguments) ? options2.arguments.map((s) => JSON5.stringify(s)) : options2.arguments
995
- });
996
- return result;
997
- }
998
- const namespace = getNamespace(name);
999
- element.namespaceImport = namespace;
1000
- const options = {
1001
- name,
1002
- arguments: (match.groups?.args || "").split(",").map((s) => lodash.trim(s)).filter(Boolean)
1003
- };
1004
- lodash.merge(element, namespace && config.fields[namespace], options);
1005
- return result;
1006
- }
1007
- function customType(args) {
1008
- const result = {};
1009
- let options = parseArgs(args);
1010
- if (typeof options === "string") {
1011
- options = { name: options };
1012
- }
1013
- Object.assign(result, options);
1014
- const namespace = getNamespace(options.name);
1015
- result.namespace = namespace;
1016
- if (options.name?.includes(".")) {
1017
- result.namespaceImport = namespace;
1018
- }
1019
- if (typeof options.match === "string" || Array.isArray(options.match)) {
1020
- result.match = outmatch(options.match, { separator: false });
1021
- }
1022
- return result;
1023
- }
1024
- function hideFieldDecorator(match) {
1025
- const result = {
1026
- name: "HideField",
1027
- arguments: [],
1028
- from: "@nestjs/graphql",
1029
- defaultImport: void 0,
1030
- namespaceImport: void 0,
1031
- match: void 0
1032
- };
1033
- if (!match.groups?.args) {
1034
- result.output = true;
1035
- return result;
1036
- }
1037
- if (match.groups.args.includes("{") && match.groups.args.includes("}")) {
1038
- const options = parseArgs(match.groups.args);
1039
- result.output = Boolean(options.output);
1040
- result.input = Boolean(options.input);
1041
- if (typeof options.match === "string" || Array.isArray(options.match)) {
1042
- result.match = outmatch(options.match, { separator: false });
1043
- }
1044
- } else {
1045
- if (/output:\s*true/.test(match.groups.args)) {
1046
- result.output = true;
1047
- }
1048
- if (/input:\s*true/.test(match.groups.args)) {
1049
- result.input = true;
1050
- }
1051
- }
1052
- return result;
1053
- }
1054
- function parseArgs(string) {
1055
- try {
1056
- return JSON5.parse(string);
1057
- } catch {
1058
- try {
1059
- return JSON5.parse(`[${string}]`);
1060
- } catch {
1061
- throw new Error(`Failed to parse: ${string}`);
1062
- }
1063
- }
1064
- }
1065
- function getNamespace(name) {
1066
- if (name === void 0) {
1067
- return void 0;
1068
- }
1069
- let result = String(name);
1070
- if (result.includes(".")) {
1071
- [result] = result.split(".");
1072
- }
1073
- return result;
1074
- }
1075
-
1076
- function modelData(model, args) {
1077
- const {
1078
- config,
1079
- modelNames,
1080
- models,
1081
- modelFields,
1082
- fieldSettings,
1083
- classTransformerTypeModels
1084
- } = args;
1085
- modelNames.push(model.name);
1086
- models.set(model.name, model);
1087
- const modelFieldsValue = /* @__PURE__ */ new Map();
1088
- modelFields.set(model.name, modelFieldsValue);
1089
- const fieldSettingsValue = /* @__PURE__ */ new Map();
1090
- fieldSettings.set(model.name, fieldSettingsValue);
1091
- for (const field of model.fields) {
1092
- if (field.documentation) {
1093
- const { documentation, settings } = createObjectSettings({
1094
- text: field.documentation,
1095
- config
1096
- });
1097
- field.documentation = documentation;
1098
- fieldSettingsValue.set(field.name, settings);
1099
- }
1100
- modelFieldsValue.set(field.name, field);
1101
- }
1102
- if (model.fields.some((field) => field.type === "Decimal")) {
1103
- classTransformerTypeModels.add(model.name);
1104
- }
1105
- }
1106
-
1107
- function createComment(documentation, settings) {
1108
- const documentationLines = documentation.split("\n");
1109
- const commentLines = ["/**"];
1110
- for (const line of documentationLines) {
1111
- commentLines.push(` * ${line}`);
1112
- }
1113
- const deprecationReason = settings?.fieldArguments()?.deprecationReason;
1114
- if (deprecationReason) {
1115
- commentLines.push(` * @deprecated ${deprecationReason}`);
1116
- }
1117
- commentLines.push(" */\n");
1118
- return commentLines.join("\n");
1119
- }
1120
-
1121
- function getOutputTypeName(name) {
1122
- return name.replace(/(?:OutputType|Output)$/, "");
1123
- }
1124
-
1125
- const nestjsGraphql$1 = "@nestjs/graphql";
1126
- function modelOutputType(outputType, args) {
1127
- const { config, eventEmitter, fieldSettings, getSourceFile, modelFields, models } = args;
1128
- if (isManyAndReturnOutputType(outputType.name)) return;
1129
- const model = models.get(outputType.name);
1130
- assert.ok(model, `Cannot find model by name ${outputType.name}`);
1131
- const sourceFile = getSourceFile({
1132
- name: outputType.name,
1133
- type: "model"
1134
- });
1135
- const sourceFileStructure = sourceFile.getStructure();
1136
- const exportDeclaration = getExportDeclaration$1(
1137
- model.name,
1138
- sourceFileStructure.statements
1139
- );
1140
- const importDeclarations = new ImportDeclarationMap();
1141
- const classStructure = {
1142
- decorators: [
1143
- {
1144
- arguments: [],
1145
- name: "ObjectType"
1146
- }
1147
- ],
1148
- isExported: true,
1149
- kind: tsMorph.StructureKind.Class,
1150
- name: outputType.name,
1151
- properties: []
1152
- };
1153
- sourceFileStructure.statements.push(classStructure);
1154
- assert.ok(classStructure.decorators, "classStructure.decorators is undefined");
1155
- const decorator = classStructure.decorators.find((d) => d.name === "ObjectType");
1156
- assert.ok(decorator, "ObjectType decorator not found");
1157
- let modelSettings;
1158
- if (model.documentation) {
1159
- const objectTypeOptions = {};
1160
- const { documentation, settings } = createObjectSettings({
1161
- config,
1162
- text: model.documentation
1163
- });
1164
- if (documentation) {
1165
- if (!classStructure.leadingTrivia) {
1166
- classStructure.leadingTrivia = createComment(documentation);
1167
- }
1168
- objectTypeOptions.description = documentation;
1169
- }
1170
- decorator.arguments = settings.getObjectTypeArguments(objectTypeOptions);
1171
- modelSettings = settings;
1172
- }
1173
- importDeclarations.add("Field", nestjsGraphql$1);
1174
- importDeclarations.add("ObjectType", nestjsGraphql$1);
1175
- for (const field of outputType.fields) {
1176
- if (config.omitModelsCount && field.name === "_count") continue;
1177
- let fileType = "model";
1178
- const { isList, location, namespace, type } = field.outputType;
1179
- let outputTypeName = String(type);
1180
- if (namespace !== "model") {
1181
- fileType = "output";
1182
- outputTypeName = getOutputTypeName(outputTypeName);
1183
- }
1184
- const modelField = modelFields.get(model.name)?.get(field.name);
1185
- const settings = fieldSettings.get(model.name)?.get(field.name);
1186
- const fieldType = settings?.getFieldType({
1187
- name: outputType.name,
1188
- output: true
1189
- });
1190
- const propertySettings = settings?.getPropertyType({
1191
- name: outputType.name,
1192
- output: true
1193
- });
1194
- const propertyType = lodash.castArray(
1195
- propertySettings?.name || getPropertyType({
1196
- location,
1197
- type: outputTypeName
1198
- })
1199
- );
1200
- propertyType.splice(1, propertyType.length);
1201
- if (field.isNullable && !isList) {
1202
- propertyType.push("null");
1203
- }
1204
- let graphqlType;
1205
- if (fieldType) {
1206
- graphqlType = fieldType.name;
1207
- importDeclarations.create({ ...fieldType });
1208
- } else {
1209
- const graphqlImport = getGraphqlImport({
1210
- config,
1211
- fileType,
1212
- getSourceFile,
1213
- isId: modelField?.isId,
1214
- location,
1215
- noTypeId: config.noTypeId,
1216
- sourceFile,
1217
- typeName: outputTypeName
1218
- });
1219
- graphqlType = graphqlImport.name;
1220
- if (graphqlImport.name !== outputType.name && graphqlImport.specifier) {
1221
- importDeclarations.add(graphqlImport.name, graphqlImport.specifier);
1222
- }
1223
- }
1224
- const property = propertyStructure({
1225
- hasExclamationToken: true,
1226
- hasQuestionToken: location === "outputObjectTypes",
1227
- isList,
1228
- isNullable: field.isNullable,
1229
- name: field.name,
1230
- propertyType
1231
- });
1232
- if (typeof property.leadingTrivia === "string" && modelField?.documentation) {
1233
- property.leadingTrivia += createComment(modelField.documentation, settings);
1234
- }
1235
- classStructure.properties?.push(property);
1236
- if (propertySettings) {
1237
- importDeclarations.create({ ...propertySettings });
1238
- } else if (propertyType.includes("Decimal")) {
1239
- importDeclarations.add("Decimal", `${config.prismaClientImport}/runtime/library`);
1240
- }
1241
- assert.ok(property.decorators, "property.decorators is undefined");
1242
- const shouldHideField = settings?.shouldHideField({ name: outputType.name, output: true }) || config.decorate.some(
1243
- (d) => d.name === "HideField" && d.from === "@nestjs/graphql" && d.isMatchField(field.name) && d.isMatchType(outputTypeName)
1244
- );
1245
- if (shouldHideField) {
1246
- importDeclarations.add("HideField", nestjsGraphql$1);
1247
- property.decorators.push({ arguments: [], name: "HideField" });
1248
- } else {
1249
- property.decorators.push({
1250
- arguments: [
1251
- isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`,
1252
- JSON5.stringify({
1253
- ...settings?.fieldArguments(),
1254
- defaultValue: ["number", "string", "boolean"].includes(
1255
- typeof modelField?.default
1256
- ) ? modelField?.default : void 0,
1257
- description: modelField?.documentation,
1258
- nullable: Boolean(field.isNullable)
1259
- })
1260
- ],
1261
- name: "Field"
1262
- });
1263
- for (const setting of settings || []) {
1264
- if (shouldBeDecorated(setting) && (setting.match?.(field.name) ?? true)) {
1265
- property.decorators.push({
1266
- arguments: setting.arguments,
1267
- name: setting.name
1268
- });
1269
- assert.ok(setting.from, "Missed 'from' part in configuration or field setting");
1270
- importDeclarations.create(setting);
1271
- }
1272
- }
1273
- for (const decorate of config.decorate) {
1274
- if (decorate.isMatchField(field.name) && decorate.isMatchType(outputTypeName)) {
1275
- property.decorators.push({
1276
- arguments: decorate.arguments?.map((x) => pupa(x, { propertyType })),
1277
- name: decorate.name
1278
- });
1279
- importDeclarations.create(decorate);
1280
- }
1281
- }
1282
- }
1283
- eventEmitter.emitSync("ClassProperty", property, {
1284
- isList,
1285
- location,
1286
- propertyType
1287
- });
1288
- }
1289
- for (const setting of modelSettings || []) {
1290
- if (shouldBeDecorated(setting)) {
1291
- classStructure.decorators.push({
1292
- arguments: setting.arguments,
1293
- name: setting.name
1294
- });
1295
- importDeclarations.create(setting);
1296
- }
1297
- }
1298
- if (exportDeclaration) {
1299
- sourceFile.set({
1300
- statements: [exportDeclaration, "\n", classStructure]
1301
- });
1302
- const classDeclaration = sourceFile.getClassOrThrow(model.name);
1303
- const commentedText = classDeclaration.getText().split("\n").map((x) => `// ${x}`);
1304
- classDeclaration.remove();
1305
- sourceFile.addStatements(["\n", ...commentedText]);
1306
- } else {
1307
- sourceFile.set({
1308
- statements: [...importDeclarations.toStatements(), classStructure]
1309
- });
1310
- }
1311
- }
1312
- function shouldBeDecorated(setting) {
1313
- return setting.kind === "Decorator" && (setting.output || setting.model) && !(setting.output && setting.model);
1314
- }
1315
- function getExportDeclaration$1(name, statements) {
1316
- return statements.find((structure) => {
1317
- return structure.kind === tsMorph.StructureKind.ExportDeclaration && structure.namedExports.some(
1318
- (o) => (o.alias || o.name) === name
1319
- );
1320
- });
1321
- }
1322
-
1323
- function noAtomicOperations(eventEmitter) {
1324
- eventEmitter.on("BeforeInputType", beforeInputType$1);
1325
- eventEmitter.on("BeforeGenerateFiles", beforeGenerateFiles$1);
1326
- }
1327
- function beforeInputType$1(args) {
1328
- const { inputType, getModelName } = args;
1329
- for (const field of inputType.fields) {
1330
- const fieldName = field.name;
1331
- field.inputTypes = field.inputTypes.filter((inputType2) => {
1332
- const inputTypeName = String(inputType2.type);
1333
- const modelName = getModelName(inputTypeName);
1334
- if (isAtomicOperation(inputTypeName) || modelName && isListInput(inputTypeName, modelName, fieldName)) {
1335
- return false;
1336
- }
1337
- return true;
1338
- });
1339
- }
1340
- }
1341
- function beforeGenerateFiles$1(args) {
1342
- const { project } = args;
1343
- for (const sourceFile of project.getSourceFiles()) {
1344
- const className = sourceFile.getClass(() => true)?.getName();
1345
- if (className && isAtomicOperation(className)) {
1346
- project.removeSourceFile(sourceFile);
1347
- }
1348
- }
1349
- }
1350
- function isAtomicOperation(typeName) {
1351
- if (typeName.endsWith("FieldUpdateOperationsInput")) {
1352
- return true;
1353
- }
1354
- return false;
1355
- }
1356
- function isListInput(typeName, model, field) {
1357
- return typeName === `${model}Create${field}Input` || typeName === `${model}Update${field}Input`;
1358
- }
1359
-
1360
- function getEnumName(referenceName) {
1361
- return referenceName.slice(3, -2);
1362
- }
1363
-
1364
- const nestjsGraphql = "@nestjs/graphql";
1365
- function outputType(outputType2, args) {
1366
- const { config, eventEmitter, fieldSettings, getModelName, getSourceFile, models } = args;
1367
- const importDeclarations = new ImportDeclarationMap();
1368
- const fileType = "output";
1369
- const modelName = getModelName(outputType2.name) || "";
1370
- const model = models.get(modelName);
1371
- const isAggregateOutput = model && /(?:Count|Avg|Sum|Min|Max)AggregateOutputType$/.test(outputType2.name) && String(outputType2.name).startsWith(model.name);
1372
- const isCountOutput = model?.name && outputType2.name === `${model.name}CountOutputType`;
1373
- if (!config.emitBlocks.outputs && !isCountOutput) return;
1374
- outputType2.name = getOutputTypeName(outputType2.name);
1375
- if (isAggregateOutput) {
1376
- eventEmitter.emitSync("AggregateOutput", { ...args, outputType: outputType2 });
1377
- }
1378
- const sourceFile = getSourceFile({
1379
- name: outputType2.name,
1380
- type: fileType
1381
- });
1382
- const classStructure = {
1383
- decorators: [
1384
- {
1385
- arguments: [],
1386
- name: "ObjectType"
1387
- }
1388
- ],
1389
- isExported: true,
1390
- kind: tsMorph.StructureKind.Class,
1391
- name: outputType2.name,
1392
- properties: []
1393
- };
1394
- importDeclarations.add("Field", nestjsGraphql);
1395
- importDeclarations.add("ObjectType", nestjsGraphql);
1396
- for (const field of outputType2.fields) {
1397
- const { isList, location, type } = field.outputType;
1398
- const outputTypeName = getOutputTypeName(String(type));
1399
- const settings = isCountOutput ? void 0 : model && fieldSettings.get(model.name)?.get(field.name);
1400
- const propertySettings = settings?.getPropertyType({
1401
- name: outputType2.name,
1402
- output: true
1403
- });
1404
- const isCustomsApplicable = outputTypeName === model?.fields.find((f) => f.name === field.name)?.type;
1405
- field.outputType.type = outputTypeName;
1406
- const propertyType = lodash.castArray(
1407
- propertySettings?.name || getPropertyType({
1408
- location,
1409
- type: outputTypeName
1410
- })
1411
- );
1412
- const property = propertyStructure({
1413
- hasQuestionToken: isCountOutput ? true : void 0,
1414
- isList,
1415
- isNullable: field.isNullable,
1416
- name: field.name,
1417
- propertyType
1418
- });
1419
- classStructure.properties?.push(property);
1420
- if (propertySettings) {
1421
- importDeclarations.create({ ...propertySettings });
1422
- } else if (propertyType.includes("Decimal")) {
1423
- importDeclarations.add("Decimal", `${config.prismaClientImport}/runtime/library`);
1424
- }
1425
- let graphqlType;
1426
- const shouldHideField = settings?.shouldHideField({
1427
- name: outputType2.name,
1428
- output: true
1429
- }) || config.decorate.some(
1430
- (d) => d.name === "HideField" && d.from === "@nestjs/graphql" && d.isMatchField(field.name) && d.isMatchType(outputTypeName)
1431
- );
1432
- const fieldType = settings?.getFieldType({
1433
- name: outputType2.name,
1434
- output: true
1435
- });
1436
- if (fieldType && isCustomsApplicable && !shouldHideField) {
1437
- graphqlType = fieldType.name;
1438
- importDeclarations.create({ ...fieldType });
1439
- } else {
1440
- const graphqlImport = getGraphqlImport({
1441
- config,
1442
- fileType,
1443
- getSourceFile,
1444
- isId: false,
1445
- location,
1446
- sourceFile,
1447
- typeName: outputTypeName
1448
- });
1449
- const referenceName = location === "enumTypes" ? getEnumName(propertyType[0]) : propertyType[0];
1450
- graphqlType = graphqlImport.name;
1451
- if (graphqlImport.specifier && !importDeclarations.has(graphqlImport.name) && (graphqlImport.name !== outputType2.name && !shouldHideField || shouldHideField && referenceName === graphqlImport.name)) {
1452
- importDeclarations.set(graphqlImport.name, {
1453
- moduleSpecifier: graphqlImport.specifier,
1454
- namedImports: [{ name: graphqlImport.name }]
1455
- });
1456
- }
1457
- }
1458
- assert.ok(property.decorators, "property.decorators is undefined");
1459
- if (shouldHideField) {
1460
- importDeclarations.add("HideField", nestjsGraphql);
1461
- property.decorators.push({ arguments: [], name: "HideField" });
1462
- } else {
1463
- property.decorators.push({
1464
- arguments: [
1465
- isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`,
1466
- JSON5.stringify({
1467
- ...settings?.fieldArguments(),
1468
- nullable: Boolean(field.isNullable)
1469
- })
1470
- ],
1471
- name: "Field"
1472
- });
1473
- if (isCustomsApplicable) {
1474
- for (const options of settings || []) {
1475
- if ((options.kind === "Decorator" && options.output && options.match?.(field.name)) ?? true) {
1476
- property.decorators.push({
1477
- arguments: options.arguments,
1478
- name: options.name
1479
- });
1480
- assert.ok(options.from, "Missed 'from' part in configuration or field setting");
1481
- importDeclarations.create(options);
1482
- }
1483
- }
1484
- }
1485
- }
1486
- eventEmitter.emitSync("ClassProperty", property, {
1487
- isList,
1488
- location,
1489
- propertyType
1490
- });
1491
- }
1492
- sourceFile.set({
1493
- statements: [...importDeclarations.toStatements(), classStructure]
1494
- });
1495
- }
1496
-
1497
- function purgeOutput(emitter) {
1498
- emitter.on("Begin", begin);
1499
- emitter.on("End", end);
1500
- }
1501
- function begin({ project, output }) {
1502
- const sourceFiles = project.getDirectory(output)?.getDescendantSourceFiles();
1503
- if (sourceFiles) {
1504
- for (const sourceFile of sourceFiles) {
1505
- sourceFile.delete();
1506
- }
1507
- }
1508
- }
1509
- function end({ project, output }) {
1510
- const directories = project.getDirectory(output)?.getDescendantDirectories().filter((directory) => directory.getSourceFiles().length === 0).map((directory) => directory.getPath());
1511
- for (const directory of directories || []) {
1512
- try {
1513
- gracefulFs.rmdirSync(directory);
1514
- } catch {
1515
- }
1516
- }
1517
- }
1518
-
1519
- var ReExport = /* @__PURE__ */ ((ReExport2) => {
1520
- ReExport2["None"] = "None";
1521
- ReExport2["Directories"] = "Directories";
1522
- ReExport2["Single"] = "Single";
1523
- ReExport2["All"] = "All";
1524
- return ReExport2;
1525
- })(ReExport || {});
1526
- function reExport(emitter) {
1527
- emitter.on("BeforeGenerateFiles", beforeGenerateFiles);
1528
- }
1529
- function beforeGenerateFiles(args) {
1530
- const { project, output, config } = args;
1531
- const rootDirectory = project.getDirectoryOrThrow(output);
1532
- if (["Directories" /* Directories */, "All" /* All */].includes(config.reExport)) {
1533
- for (const directory of rootDirectory.getDescendantDirectories()) {
1534
- let indexSourceFile;
1535
- const exportDeclarations = directory.getSourceFiles().filter((sourceFile) => {
1536
- return sourceFile.getBaseName() !== "index.ts";
1537
- }).map((sourcesFile) => getExportDeclaration(directory, sourcesFile));
1538
- if (exportDeclarations.length > 0) {
1539
- indexSourceFile = directory.createSourceFile(
1540
- "index.ts",
1541
- {
1542
- statements: exportDeclarations
1543
- },
1544
- {
1545
- overwrite: true
1546
- }
1547
- );
1548
- }
1549
- if (indexSourceFile) {
1550
- continue;
1551
- }
1552
- const namespaceExportDeclarations = directory.getDirectories().map(
1553
- (sourceDirectory) => getNamespaceExportDeclaration(directory, sourceDirectory)
1554
- );
1555
- project.createSourceFile(
1556
- `${directory.getPath()}/index.ts`,
1557
- {
1558
- statements: namespaceExportDeclarations
1559
- },
1560
- {
1561
- overwrite: true
1562
- }
1563
- );
1564
- }
1565
- }
1566
- if (config.reExport === "Single" /* Single */) {
1567
- const exportDeclarations = project.getSourceFiles().filter((sourceFile) => {
1568
- return sourceFile.getBaseName() !== "index.ts";
1569
- }).map((sourceFile) => getExportDeclaration(rootDirectory, sourceFile));
1570
- rootDirectory.createSourceFile(
1571
- "index.ts",
1572
- {
1573
- statements: exportDeclarations
1574
- },
1575
- {
1576
- overwrite: true
1577
- }
1578
- );
1579
- }
1580
- if (config.reExport === "All" /* All */) {
1581
- const exportDeclarations = [];
1582
- for (const directory of rootDirectory.getDirectories()) {
1583
- if (directory.getBaseName() === "node_modules") continue;
1584
- const sourceFile = directory.getSourceFileOrThrow("index.ts");
1585
- exportDeclarations.push(getExportDeclaration(rootDirectory, sourceFile));
1586
- }
1587
- rootDirectory.createSourceFile(
1588
- "index.ts",
1589
- {
1590
- statements: exportDeclarations
1591
- },
1592
- {
1593
- overwrite: true
1594
- }
1595
- );
1596
- }
1597
- }
1598
- function getExportDeclaration(directory, sourceFile) {
1599
- return {
1600
- kind: tsMorph.StructureKind.ExportDeclaration,
1601
- namedExports: sourceFile.getExportSymbols().map((s) => ({ name: s.getName() })),
1602
- moduleSpecifier: directory.getRelativePathAsModuleSpecifierTo(sourceFile)
1603
- };
1604
- }
1605
- function getNamespaceExportDeclaration(directory, sourceDirectory) {
1606
- return {
1607
- kind: tsMorph.StructureKind.ExportDeclaration,
1608
- moduleSpecifier: directory.getRelativePathAsModuleSpecifierTo(sourceDirectory)
1609
- };
1610
- }
1611
-
1612
- function extractEnumValueDocs(values) {
1613
- return Object.fromEntries(
1614
- values.map((value) => {
1615
- const { name } = value;
1616
- const documentation = value.documentation;
1617
- if (typeof documentation !== "string") return null;
1618
- if (documentation.startsWith("@deprecated")) {
1619
- return [name, { deprecationReason: documentation.slice(11).trim() }];
1620
- }
1621
- return [name, { description: documentation }];
1622
- }).filter((entry) => entry !== null)
1623
- );
1624
- }
1625
-
1626
- function registerEnum(enumType, args) {
1627
- const { config, enums, getSourceFile } = args;
1628
- if (!config.emitBlocks.prismaEnums && !enums[enumType.name]) return;
1629
- const dataModelEnum = enums[enumType.name];
1630
- const enumTypesData = dataModelEnum?.values || [];
1631
- const sourceFile = getSourceFile({
1632
- name: enumType.name,
1633
- type: "enum"
1634
- });
1635
- const importDeclarations = new ImportDeclarationMap();
1636
- importDeclarations.set("registerEnumType", {
1637
- moduleSpecifier: "@nestjs/graphql",
1638
- namedImports: [{ name: "registerEnumType" }]
1639
- });
1640
- const valuesMap = extractEnumValueDocs(enumTypesData);
1641
- const filteredValuesMap = Object.fromEntries(
1642
- Object.entries(valuesMap).filter(([_, v]) => Object.keys(v).length > 0)
1643
- );
1644
- const hasValuesMap = Object.keys(filteredValuesMap).length > 0;
1645
- const formattedValuesMap = hasValuesMap ? JSON.stringify(filteredValuesMap, null, 2).replace(/"([^"]+)":/g, "$1:") : "";
1646
- const valuesMapEntry = hasValuesMap ? `, valuesMap: ${formattedValuesMap}` : "";
1647
- const enumStructure = {
1648
- kind: tsMorph.StructureKind.Enum,
1649
- isExported: true,
1650
- name: enumType.name,
1651
- members: enumType.values.map((v) => ({
1652
- name: v,
1653
- initializer: JSON.stringify(v)
1654
- }))
1655
- };
1656
- sourceFile.set({
1657
- statements: [
1658
- ...importDeclarations.toStatements(),
1659
- enumStructure,
1660
- "\n",
1661
- `registerEnumType(${enumType.name}, { name: '${enumType.name}', description: ${JSON.stringify(
1662
- dataModelEnum?.documentation
1663
- )}${valuesMapEntry} })`
1664
- ]
1665
- });
1666
- }
1667
-
1668
- function requireSingleFieldsInWhereUniqueInput(eventEmitter) {
1669
- eventEmitter.on("BeforeInputType", beforeInputType);
1670
- }
1671
- function beforeInputType(args) {
1672
- const { inputType } = args;
1673
- if (!isWhereUniqueInputType(inputType.name) || inputType.fields.length !== 1) {
1674
- return;
1675
- }
1676
- for (const field of inputType.fields) {
1677
- field.isRequired = true;
1678
- field.isNullable = false;
1679
- }
1680
- }
1681
-
1682
- function warning(message) {
1683
- if (Array.isArray(message)) {
1684
- console.log("prisma-nestjs-graphql:");
1685
- console.log(message.join("\n"));
1686
- } else {
1687
- console.log("prisma-nestjs-graphql:", message);
1688
- }
1689
- }
1690
-
1691
- const allEmmittedBlocks = [
1692
- "prismaEnums",
1693
- "schemaEnums",
1694
- "models",
1695
- "inputs",
1696
- "args",
1697
- "outputs"
1698
- ];
1699
- const blocksDependencyMap = {
1700
- enums: ["schemaEnums", "prismaEnums"],
1701
- models: ["models", "schemaEnums"],
1702
- inputs: ["inputs", "prismaEnums"],
1703
- outputs: ["outputs"],
1704
- args: ["args", "inputs", "prismaEnums"]
1705
- };
1706
- function createEmitBlocks(data) {
1707
- if (!data) {
1708
- return Object.fromEntries(allEmmittedBlocks.map((block) => [block, true]));
1709
- }
1710
- let blocksToEmit = {};
1711
- for (const block of data) {
1712
- if (!Object.keys(blocksDependencyMap).includes(block)) continue;
1713
- blocksToEmit = {
1714
- ...blocksToEmit,
1715
- ...Object.fromEntries(
1716
- blocksDependencyMap[block].map((block2) => [block2, true])
1717
- )
1718
- };
1719
- }
1720
- return blocksToEmit;
1721
- }
1722
-
1723
- function createConfig(data) {
1724
- const config = lodash.merge({}, flat.unflatten(data, { delimiter: "_" }));
1725
- const $warnings = [];
1726
- const configOutputFilePattern = String(
1727
- config.outputFilePattern || `{model}/{name}.{type}.ts`
1728
- );
1729
- let outputFilePattern = filenamify(configOutputFilePattern, {
1730
- replacement: "/"
1731
- }).replaceAll("..", "/").replaceAll(/\/+/g, "/");
1732
- outputFilePattern = lodash.trim(outputFilePattern, "/");
1733
- if (outputFilePattern !== configOutputFilePattern) {
1734
- $warnings.push(
1735
- `Due to invalid filepath 'outputFilePattern' changed to '${outputFilePattern}'`
1736
- );
1737
- }
1738
- if (config.reExportAll) {
1739
- $warnings.push(`Option 'reExportAll' is deprecated, use 'reExport' instead`);
1740
- if (toBoolean(config.reExportAll)) {
1741
- config.reExport = "All";
1742
- }
1743
- }
1744
- const fields = Object.fromEntries(
1745
- Object.entries(
1746
- config.fields ?? {}
1747
- ).filter(({ 1: value }) => typeof value === "object").map(([name, value]) => {
1748
- const fieldSetting = {
1749
- arguments: [],
1750
- output: toBoolean(value.output),
1751
- input: toBoolean(value.input),
1752
- model: toBoolean(value.model),
1753
- from: value.from,
1754
- defaultImport: toBoolean(value.defaultImport) ? true : value.defaultImport,
1755
- namespaceImport: value.namespaceImport
1756
- };
1757
- return [name, fieldSetting];
1758
- })
1759
- );
1760
- const decorate = [];
1761
- const configDecorate = Object.values(
1762
- config.decorate || {}
1763
- );
1764
- for (const element of configDecorate) {
1765
- if (!element) continue;
1766
- assert.ok(
1767
- element.from && element.name,
1768
- `Missed 'from' or 'name' part in configuration for decorate`
1769
- );
1770
- decorate.push({
1771
- isMatchField: outmatch(element.field, { separator: false }),
1772
- isMatchType: outmatch(element.type, { separator: false }),
1773
- from: element.from,
1774
- name: element.name,
1775
- namedImport: toBoolean(element.namedImport),
1776
- defaultImport: toBoolean(element.defaultImport) ? true : element.defaultImport,
1777
- namespaceImport: element.namespaceImport,
1778
- arguments: element.arguments ? JSON5.parse(element.arguments) : void 0
1779
- });
1780
- }
1781
- const customImport = [];
1782
- const configCustomImport = Object.values(
1783
- config.customImport || {}
1784
- );
1785
- for (const element of configCustomImport) {
1786
- if (!element) continue;
1787
- assert.ok(
1788
- element.from && element.name,
1789
- `Missed 'from' or 'name' part in configuration for customImport`
1790
- );
1791
- customImport.push({
1792
- from: element.from,
1793
- name: element.name,
1794
- namedImport: toBoolean(element.namedImport),
1795
- defaultImport: toBoolean(element.defaultImport) ? true : element.defaultImport,
1796
- namespaceImport: element.namespaceImport
1797
- });
1798
- }
1799
- return {
1800
- outputFilePattern,
1801
- tsConfigFilePath: createTsConfigFilePathValue(config.tsConfigFilePath),
1802
- prismaClientImport: createPrismaImport(config.prismaClientImport),
1803
- combineScalarFilters: toBoolean(config.combineScalarFilters),
1804
- noAtomicOperations: toBoolean(config.noAtomicOperations),
1805
- reExport: ReExport[String(config.reExport)] || ReExport.None,
1806
- emitSingle: toBoolean(config.emitSingle),
1807
- emitCompiled: toBoolean(config.emitCompiled),
1808
- emitBlocks: createEmitBlocks(config.emitBlocks),
1809
- omitModelsCount: toBoolean(config.omitModelsCount),
1810
- $warnings,
1811
- fields,
1812
- purgeOutput: toBoolean(config.purgeOutput),
1813
- useInputType: createUseInputType(config.useInputType),
1814
- noTypeId: toBoolean(config.noTypeId),
1815
- requireSingleFieldsInWhereUniqueInput: toBoolean(
1816
- config.requireSingleFieldsInWhereUniqueInput
1817
- ),
1818
- unsafeCompatibleWhereUniqueInput: toBoolean(
1819
- config.unsafeCompatibleWhereUniqueInput
1820
- ),
1821
- graphqlScalars: config.graphqlScalars || {},
1822
- decorate,
1823
- customImport
1824
- };
1825
- }
1826
- const tsConfigFileExists = lodash.memoize((filePath) => {
1827
- return gracefulFs.existsSync(filePath);
1828
- });
1829
- function createTsConfigFilePathValue(value) {
1830
- if (typeof value === "string") return value;
1831
- if (tsConfigFileExists("tsconfig.json")) return "tsconfig.json";
1832
- }
1833
- function createPrismaImport(value) {
1834
- if (typeof value === "string") return value;
1835
- return "@prisma/client";
1836
- }
1837
- function createUseInputType(data) {
1838
- if (!data) {
1839
- return [];
1840
- }
1841
- const result = [];
1842
- for (const [typeName, useInputs] of Object.entries(data)) {
1843
- const entry = {
1844
- typeName,
1845
- ALL: void 0
1846
- };
1847
- if (useInputs.ALL) {
1848
- entry.ALL = useInputs.ALL;
1849
- delete useInputs.ALL;
1850
- }
1851
- for (const [propertyName, pattern] of Object.entries(useInputs)) {
1852
- entry[propertyName] = pattern;
1853
- }
1854
- result.push(entry);
1855
- }
1856
- return result;
1857
- }
1858
- function toBoolean(value) {
1859
- return ["true", "1", "on"].includes(String(value));
1860
- }
1861
-
1862
- function generateFileName(args) {
1863
- const { getModelName, name, template, type } = args;
1864
- return pupa(template, {
1865
- get model() {
1866
- const result = getModelName(name) || "prisma";
1867
- return lodash.kebabCase(result);
1868
- },
1869
- get name() {
1870
- let result = lodash.kebabCase(name);
1871
- for (const suffix of ["input", "args", "enum"]) {
1872
- const ending = `-${suffix}`;
1873
- if (type === suffix && result.endsWith(ending)) {
1874
- result = result.slice(0, -ending.length);
1875
- }
1876
- }
1877
- return result;
1878
- },
1879
- plural: {
1880
- get type() {
1881
- return pluralize(type);
1882
- }
1883
- },
1884
- type
1885
- });
1886
- }
1887
-
1888
- function factoryGetSourceFile(args) {
1889
- const { outputFilePattern, output, getModelName, project } = args;
1890
- return function getSourceFile(args2) {
1891
- const { name, type } = args2;
1892
- let filePath = generateFileName({
1893
- getModelName,
1894
- name,
1895
- type,
1896
- template: outputFilePattern
1897
- });
1898
- filePath = `${output}/${filePath}`;
1899
- return project.getSourceFile(filePath) || project.createSourceFile(filePath, void 0, { overwrite: true });
1900
- };
1901
- }
1902
-
1903
- function createGetModelName(modelNames) {
1904
- return lodash.memoize(tryGetName);
1905
- function tryGetName(name) {
1906
- return getModelName({ modelNames, name });
1907
- }
1908
- }
1909
- function getModelName(args) {
1910
- const { modelNames, name } = args;
1911
- for (const keyword of splitKeywords) {
1912
- const [test] = name.split(keyword, 1);
1913
- if (modelNames.includes(test)) {
1914
- return test;
1915
- }
1916
- }
1917
- for (const keyword of endsWithKeywords) {
1918
- const [test] = name.split(keyword).slice(-1);
1919
- if (modelNames.includes(test)) {
1920
- return test;
1921
- }
1922
- }
1923
- for (const [start, end] of middleKeywords) {
1924
- let test = name.slice(start.length).slice(0, -end.length);
1925
- if (modelNames.includes(test) && name.startsWith(start) && name.endsWith(end)) {
1926
- return test;
1927
- }
1928
- test = name.slice(0, -(start + end).length);
1929
- if (modelNames.includes(test) && name.endsWith(start + end)) {
1930
- return test;
1931
- }
1932
- }
1933
- if (name.slice(-19) === "CompoundUniqueInput") {
1934
- const test = name.slice(0, -19);
1935
- const models = modelNames.filter((x) => test.startsWith(x)).sort((a, b) => b.length - a.length);
1936
- return lodash.first(models);
1937
- }
1938
- if (name.slice(-5) === "Count") {
1939
- const test = name.slice(0, -5);
1940
- if (modelNames.includes(test)) {
1941
- return test;
1942
- }
1943
- }
1944
- }
1945
- const splitKeywords = [
1946
- "CreateInput",
1947
- "CreateMany",
1948
- "CreateNested",
1949
- "CreateOneWithout",
1950
- "CreateOrConnect",
1951
- "CreateWithout",
1952
- "DistinctField",
1953
- "Filter",
1954
- "ManyWithout",
1955
- "OrderByInput",
1956
- "RelationFilter",
1957
- "NullableRelationFilter",
1958
- "ListRelationFilter",
1959
- "ScalarWhereInput",
1960
- "UpdateInput",
1961
- "UpdateMany",
1962
- "UpdateOneRequiredWithout",
1963
- "UpdateOneWithout",
1964
- "UpdateWith",
1965
- "UpsertWith",
1966
- "UpsertWithout",
1967
- "WhereInput",
1968
- "WhereUniqueInput",
1969
- "AvgAggregate",
1970
- "SumAggregate",
1971
- "MinAggregate",
1972
- "MaxAggregate",
1973
- "CountAggregate",
1974
- "ScalarField",
1975
- "GroupBy",
1976
- "OrderBy",
1977
- "UncheckedUpdate",
1978
- "UncheckedCreate",
1979
- "ScalarWhere",
1980
- "CountOutputType",
1981
- "CountOrderBy",
1982
- "SumOrderBy",
1983
- "MinOrderBy",
1984
- "MaxOrderBy",
1985
- "AvgOrderBy",
1986
- "Create",
1987
- "Update",
1988
- "ScalarRelationFilter",
1989
- "NullableScalarRelationFilter"
1990
- ].sort((a, b) => b.length - a.length);
1991
- const endsWithKeywords = [
1992
- "Aggregate",
1993
- "GroupBy",
1994
- "CreateOne",
1995
- "CreateMany",
1996
- "DeleteMany",
1997
- "DeleteOne",
1998
- "FindMany",
1999
- "FindOne",
2000
- "FindUnique",
2001
- "UpdateMany",
2002
- "UpdateOne",
2003
- "UpsertOne"
2004
- ];
2005
- const middleKeywords = [
2006
- ["FindFirst", "OrThrowArgs"],
2007
- ["FindUnique", "OrThrowArgs"],
2008
- ["Aggregate", "Args"],
2009
- ["CreateOne", "Args"],
2010
- ["CreateMany", "Args"],
2011
- ["DeleteMany", "Args"],
2012
- ["DeleteOne", "Args"],
2013
- ["FindMany", "Args"],
2014
- ["FindFirst", "Args"],
2015
- ["FindOne", "Args"],
2016
- ["FindUnique", "Args"],
2017
- ["UpdateMany", "Args"],
2018
- ["UpdateMany", "AndReturnOutputType"],
2019
- ["UpdateOne", "Args"],
2020
- ["UpsertOne", "Args"],
2021
- ["GroupBy", "Args"],
2022
- ["OrderBy", "Args"]
2023
- ];
2024
-
2025
- const AwaitEventEmitter = require$$0.default;
2026
- async function generate(args) {
2027
- const { connectCallback, dmmf, generator, skipAddOutputSourceFiles } = args;
2028
- const generatorOutputValue = generator.output?.value;
2029
- assert.ok(generatorOutputValue, "Missing generator configuration: output");
2030
- const config = createConfig(generator.config);
2031
- const eventEmitter = new AwaitEventEmitter();
2032
- eventEmitter.on("Warning", warning);
2033
- config.emitBlocks.models && eventEmitter.on("Model", modelData);
2034
- if (config.emitBlocks.prismaEnums || config.emitBlocks.schemaEnums) {
2035
- eventEmitter.on("EnumType", registerEnum);
2036
- }
2037
- if (config.emitBlocks.outputs || config.emitBlocks.models && !config.omitModelsCount) {
2038
- eventEmitter.on("OutputType", outputType);
2039
- }
2040
- config.emitBlocks.models && eventEmitter.on("ModelOutputType", modelOutputType);
2041
- config.emitBlocks.outputs && eventEmitter.on("AggregateOutput", createAggregateInput);
2042
- config.emitBlocks.inputs && eventEmitter.on("InputType", inputType);
2043
- config.emitBlocks.args && eventEmitter.on("ArgsType", argsType);
2044
- eventEmitter.on("GenerateFiles", generateFiles);
2045
- for (const message of config.$warnings) {
2046
- eventEmitter.emitSync("Warning", message);
2047
- }
2048
- const project = new tsMorph.Project({
2049
- manipulationSettings: {
2050
- quoteKind: tsMorph.QuoteKind.Single
2051
- },
2052
- skipAddingFilesFromTsConfig: true,
2053
- skipLoadingLibFiles: !config.emitCompiled,
2054
- tsConfigFilePath: config.tsConfigFilePath
2055
- });
2056
- if (!skipAddOutputSourceFiles) {
2057
- project.addSourceFilesAtPaths([
2058
- `${generatorOutputValue}/**/*.ts`,
2059
- `!${generatorOutputValue}/**/*.d.ts`
2060
- ]);
2061
- }
2062
- config.combineScalarFilters && combineScalarFilters(eventEmitter);
2063
- config.noAtomicOperations && noAtomicOperations(eventEmitter);
2064
- config.reExport !== ReExport.None && reExport(eventEmitter);
2065
- config.emitSingle && emitSingle(eventEmitter);
2066
- config.purgeOutput && purgeOutput(eventEmitter);
2067
- config.requireSingleFieldsInWhereUniqueInput && requireSingleFieldsInWhereUniqueInput(eventEmitter);
2068
- const models = /* @__PURE__ */ new Map();
2069
- const modelNames = [];
2070
- const modelFields = /* @__PURE__ */ new Map();
2071
- const fieldSettings = /* @__PURE__ */ new Map();
2072
- const getModelName = createGetModelName(modelNames);
2073
- const getSourceFile = factoryGetSourceFile({
2074
- getModelName,
2075
- output: generatorOutputValue,
2076
- outputFilePattern: config.outputFilePattern,
2077
- project
2078
- });
2079
- const { datamodel, schema } = JSON.parse(JSON.stringify(dmmf));
2080
- const removeTypes = /* @__PURE__ */ new Set();
2081
- const eventArguments = {
2082
- classTransformerTypeModels: /* @__PURE__ */ new Set(),
2083
- config,
2084
- enums: lodash.mapKeys(datamodel.enums, (x) => x.name),
2085
- eventEmitter,
2086
- fieldSettings,
2087
- getModelName,
2088
- getSourceFile,
2089
- modelFields,
2090
- modelNames,
2091
- models,
2092
- output: generatorOutputValue,
2093
- project,
2094
- removeTypes,
2095
- schema,
2096
- typeNames: /* @__PURE__ */ new Set()
2097
- };
2098
- if (connectCallback) {
2099
- await connectCallback(eventEmitter, eventArguments);
2100
- }
2101
- await eventEmitter.emit("Begin", eventArguments);
2102
- for (const model of datamodel.models) {
2103
- await eventEmitter.emit("Model", model, eventArguments);
2104
- }
2105
- for (const model of datamodel.types || []) {
2106
- await eventEmitter.emit("Model", model, eventArguments);
2107
- }
2108
- const { enumTypes, inputObjectTypes, outputObjectTypes } = schema;
2109
- await eventEmitter.emit("PostBegin", eventArguments);
2110
- for (const enumType of enumTypes.prisma.concat(enumTypes.model || [])) {
2111
- await eventEmitter.emit("EnumType", enumType, eventArguments);
2112
- }
2113
- for (const outputType2 of outputObjectTypes.model) {
2114
- await eventEmitter.emit("ModelOutputType", outputType2, eventArguments);
2115
- }
2116
- const queryOutputTypes = [];
2117
- for (const outputType2 of outputObjectTypes.prisma) {
2118
- if (["Query", "Mutation"].includes(outputType2.name)) {
2119
- queryOutputTypes.push(outputType2);
2120
- continue;
2121
- }
2122
- await eventEmitter.emit("OutputType", outputType2, eventArguments);
2123
- }
2124
- const inputTypes = inputObjectTypes.prisma.concat(inputObjectTypes.model || []);
2125
- for (const inputType2 of inputTypes) {
2126
- const event = {
2127
- ...eventArguments,
2128
- classDecoratorName: "InputType",
2129
- fileType: "input",
2130
- inputType: inputType2
2131
- };
2132
- if (inputType2.fields.length === 0) {
2133
- removeTypes.add(inputType2.name);
2134
- continue;
2135
- }
2136
- await eventEmitter.emit("BeforeInputType", event);
2137
- await eventEmitter.emit("InputType", event);
2138
- }
2139
- for (const outputType2 of queryOutputTypes) {
2140
- for (const field of outputType2.fields) {
2141
- await eventEmitter.emit("ArgsType", field, eventArguments);
2142
- }
2143
- }
2144
- await eventEmitter.emit("BeforeGenerateFiles", eventArguments);
2145
- await eventEmitter.emit("GenerateFiles", eventArguments);
2146
- await eventEmitter.emit("End", eventArguments);
2147
- for (const name of Object.keys(eventEmitter._events)) {
2148
- eventEmitter.off(name);
2149
- }
2150
- }
2151
-
2152
- exports.generate = generate;