@pegasusheavy/nestjs-prisma-graphql 1.4.2 → 1.6.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/README.md +18 -7
- package/dist/benchmark/analysis.d.ts +7 -0
- package/dist/benchmark/analysis.d.ts.map +1 -0
- package/dist/benchmark/analysis.js +265 -0
- package/dist/benchmark/analysis.js.map +1 -0
- package/dist/benchmark/index.d.ts +7 -0
- package/dist/benchmark/index.d.ts.map +1 -0
- package/dist/benchmark/index.js +272 -0
- package/dist/benchmark/index.js.map +1 -0
- package/dist/event-names.d.ts +2 -0
- package/dist/event-names.d.ts.map +1 -0
- package/dist/event-names.js +2 -0
- package/dist/event-names.js.map +1 -0
- package/dist/generate.d.ts +4 -140
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +199 -2811
- package/dist/generate.js.map +1 -1
- package/dist/handlers/args-type.d.ts +7 -0
- package/dist/handlers/args-type.d.ts.map +1 -0
- package/dist/handlers/args-type.js +68 -0
- package/dist/handlers/args-type.js.map +1 -0
- package/dist/handlers/combine-scalar-filters.d.ts +6 -0
- package/dist/handlers/combine-scalar-filters.d.ts.map +1 -0
- package/dist/handlers/combine-scalar-filters.js +110 -0
- package/dist/handlers/combine-scalar-filters.js.map +1 -0
- package/dist/handlers/create-aggregate-input.d.ts +10 -0
- package/dist/handlers/create-aggregate-input.d.ts.map +1 -0
- package/dist/handlers/create-aggregate-input.js +33 -0
- package/dist/handlers/create-aggregate-input.js.map +1 -0
- package/dist/handlers/decimal-helpers.d.ts +10 -0
- package/dist/handlers/decimal-helpers.d.ts.map +1 -0
- package/dist/handlers/decimal-helpers.js +73 -0
- package/dist/handlers/decimal-helpers.js.map +1 -0
- package/dist/handlers/emit-single.d.ts +3 -0
- package/dist/handlers/emit-single.d.ts.map +1 -0
- package/dist/handlers/emit-single.js +14 -0
- package/dist/handlers/emit-single.js.map +1 -0
- package/dist/handlers/generate-barrel-exports.d.ts +13 -0
- package/dist/handlers/generate-barrel-exports.d.ts.map +1 -0
- package/dist/handlers/generate-barrel-exports.js +69 -0
- package/dist/handlers/generate-barrel-exports.js.map +1 -0
- package/dist/handlers/generate-files.d.ts +3 -0
- package/dist/handlers/generate-files.d.ts.map +1 -0
- package/dist/handlers/generate-files.js +133 -0
- package/dist/handlers/generate-files.js.map +1 -0
- package/dist/handlers/input-type.d.ts +7 -0
- package/dist/handlers/input-type.d.ts.map +1 -0
- package/dist/handlers/input-type.js +297 -0
- package/dist/handlers/input-type.js.map +1 -0
- package/dist/handlers/model-data.d.ts +3 -0
- package/dist/handlers/model-data.d.ts.map +1 -0
- package/dist/handlers/model-data.js +27 -0
- package/dist/handlers/model-data.js.map +1 -0
- package/dist/handlers/model-output-type.d.ts +3 -0
- package/dist/handlers/model-output-type.d.ts.map +1 -0
- package/dist/handlers/model-output-type.js +283 -0
- package/dist/handlers/model-output-type.js.map +1 -0
- package/dist/handlers/no-atomic-operations.d.ts +3 -0
- package/dist/handlers/no-atomic-operations.d.ts.map +1 -0
- package/dist/handlers/no-atomic-operations.js +41 -0
- package/dist/handlers/no-atomic-operations.js.map +1 -0
- package/dist/handlers/output-type.d.ts +3 -0
- package/dist/handlers/output-type.d.ts.map +1 -0
- package/dist/handlers/output-type.js +179 -0
- package/dist/handlers/output-type.js.map +1 -0
- package/dist/handlers/patch-type-registry.d.ts +16 -0
- package/dist/handlers/patch-type-registry.d.ts.map +1 -0
- package/dist/handlers/patch-type-registry.js +47 -0
- package/dist/handlers/patch-type-registry.js.map +1 -0
- package/dist/handlers/post-process-imports.d.ts +11 -0
- package/dist/handlers/post-process-imports.d.ts.map +1 -0
- package/dist/handlers/post-process-imports.js +44 -0
- package/dist/handlers/post-process-imports.js.map +1 -0
- package/dist/handlers/prisma-enum-doc.d.ts +11 -0
- package/dist/handlers/prisma-enum-doc.d.ts.map +1 -0
- package/dist/handlers/prisma-enum-doc.js +16 -0
- package/dist/handlers/prisma-enum-doc.js.map +1 -0
- package/dist/handlers/purge-output.d.ts +3 -0
- package/dist/handlers/purge-output.d.ts.map +1 -0
- package/dist/handlers/purge-output.js +34 -0
- package/dist/handlers/purge-output.js.map +1 -0
- package/dist/handlers/re-export.d.ts +9 -0
- package/dist/handlers/re-export.d.ts.map +1 -0
- package/dist/handlers/re-export.js +101 -0
- package/dist/handlers/re-export.js.map +1 -0
- package/dist/handlers/register-all-types.d.ts +13 -0
- package/dist/handlers/register-all-types.d.ts.map +1 -0
- package/dist/handlers/register-all-types.js +99 -0
- package/dist/handlers/register-all-types.js.map +1 -0
- package/dist/handlers/register-enum.d.ts +3 -0
- package/dist/handlers/register-enum.d.ts.map +1 -0
- package/dist/handlers/register-enum.js +65 -0
- package/dist/handlers/register-enum.js.map +1 -0
- package/dist/handlers/require-single-fields-in-whereunique-input.d.ts +3 -0
- package/dist/handlers/require-single-fields-in-whereunique-input.d.ts.map +1 -0
- package/dist/handlers/require-single-fields-in-whereunique-input.js +15 -0
- package/dist/handlers/require-single-fields-in-whereunique-input.js.map +1 -0
- package/dist/handlers/type-registry.d.ts +14 -0
- package/dist/handlers/type-registry.d.ts.map +1 -0
- package/dist/handlers/type-registry.js +151 -0
- package/dist/handlers/type-registry.js.map +1 -0
- package/dist/handlers/warning.d.ts +2 -0
- package/dist/handlers/warning.d.ts.map +1 -0
- package/dist/handlers/warning.js +14 -0
- package/dist/handlers/warning.js.map +1 -0
- package/dist/helpers/create-comment.d.ts +3 -0
- package/dist/helpers/create-comment.d.ts.map +1 -0
- package/dist/helpers/create-comment.js +23 -0
- package/dist/helpers/create-comment.js.map +1 -0
- package/dist/helpers/create-config.d.ts +51 -0
- package/dist/helpers/create-config.d.ts.map +1 -0
- package/dist/helpers/create-config.js +165 -0
- package/dist/helpers/create-config.js.map +1 -0
- package/dist/helpers/create-emit-blocks.d.ts +5 -0
- package/dist/helpers/create-emit-blocks.d.ts.map +1 -0
- package/dist/helpers/create-emit-blocks.js +37 -0
- package/dist/helpers/create-emit-blocks.js.map +1 -0
- package/dist/helpers/detect-circular-deps.d.ts +28 -0
- package/dist/helpers/detect-circular-deps.d.ts.map +1 -0
- package/dist/helpers/detect-circular-deps.js +92 -0
- package/dist/helpers/detect-circular-deps.js.map +1 -0
- package/dist/helpers/factory-get-source-file.d.ts +13 -0
- package/dist/helpers/factory-get-source-file.d.ts.map +1 -0
- package/dist/helpers/factory-get-source-file.js +17 -0
- package/dist/helpers/factory-get-source-file.js.map +1 -0
- package/dist/helpers/file-type-by-location.d.ts +3 -0
- package/dist/helpers/file-type-by-location.d.ts.map +1 -0
- package/dist/helpers/file-type-by-location.js +19 -0
- package/dist/helpers/file-type-by-location.js.map +1 -0
- package/dist/helpers/generate-file-name.d.ts +7 -0
- package/dist/helpers/generate-file-name.d.ts.map +1 -0
- package/dist/helpers/generate-file-name.js +35 -0
- package/dist/helpers/generate-file-name.js.map +1 -0
- package/dist/helpers/get-enum-name.d.ts +2 -0
- package/dist/helpers/get-enum-name.d.ts.map +1 -0
- package/dist/helpers/get-enum-name.js +5 -0
- package/dist/helpers/get-enum-name.js.map +1 -0
- package/dist/helpers/get-graphql-import.d.ts +19 -0
- package/dist/helpers/get-graphql-import.d.ts.map +1 -0
- package/dist/helpers/get-graphql-import.js +52 -0
- package/dist/helpers/get-graphql-import.js.map +1 -0
- package/dist/helpers/get-graphql-input-type.d.ts +6 -0
- package/dist/helpers/get-graphql-input-type.d.ts.map +1 -0
- package/dist/helpers/get-graphql-input-type.js +64 -0
- package/dist/helpers/get-graphql-input-type.js.map +1 -0
- package/dist/helpers/get-model-name.d.ts +2 -0
- package/dist/helpers/get-model-name.d.ts.map +1 -0
- package/dist/helpers/get-model-name.js +130 -0
- package/dist/helpers/get-model-name.js.map +1 -0
- package/dist/helpers/get-output-type-name.d.ts +2 -0
- package/dist/helpers/get-output-type-name.d.ts.map +1 -0
- package/dist/helpers/get-output-type-name.js +4 -0
- package/dist/helpers/get-output-type-name.js.map +1 -0
- package/dist/helpers/get-property-type.d.ts +9 -0
- package/dist/helpers/get-property-type.d.ts.map +1 -0
- package/dist/helpers/get-property-type.js +48 -0
- package/dist/helpers/get-property-type.js.map +1 -0
- package/dist/helpers/get-where-unique-at-least-keys.d.ts +3 -0
- package/dist/helpers/get-where-unique-at-least-keys.d.ts.map +1 -0
- package/dist/helpers/get-where-unique-at-least-keys.js +17 -0
- package/dist/helpers/get-where-unique-at-least-keys.js.map +1 -0
- package/dist/helpers/import-declaration-map.d.ts +19 -0
- package/dist/helpers/import-declaration-map.d.ts.map +1 -0
- package/dist/helpers/import-declaration-map.js +69 -0
- package/dist/helpers/import-declaration-map.js.map +1 -0
- package/dist/helpers/is-many-and-return.d.ts +2 -0
- package/dist/helpers/is-many-and-return.d.ts.map +1 -0
- package/dist/helpers/is-many-and-return.js +9 -0
- package/dist/helpers/is-many-and-return.js.map +1 -0
- package/dist/helpers/is-where-unique-input-type.d.ts +2 -0
- package/dist/helpers/is-where-unique-input-type.d.ts.map +1 -0
- package/dist/helpers/is-where-unique-input-type.js +4 -0
- package/dist/helpers/is-where-unique-input-type.js.map +1 -0
- package/dist/helpers/object-settings.d.ts +39 -0
- package/dist/helpers/object-settings.d.ts.map +1 -0
- package/dist/helpers/object-settings.js +297 -0
- package/dist/helpers/object-settings.js.map +1 -0
- package/dist/helpers/pascal-case.d.ts +2 -0
- package/dist/helpers/pascal-case.d.ts.map +1 -0
- package/dist/helpers/pascal-case.js +5 -0
- package/dist/helpers/pascal-case.js.map +1 -0
- package/dist/helpers/property-structure.d.ts +13 -0
- package/dist/helpers/property-structure.d.ts.map +1 -0
- package/dist/helpers/property-structure.js +20 -0
- package/dist/helpers/property-structure.js.map +1 -0
- package/dist/helpers/relative-path.d.ts +2 -0
- package/dist/helpers/relative-path.d.ts.map +1 -0
- package/dist/helpers/relative-path.js +20 -0
- package/dist/helpers/relative-path.js.map +1 -0
- package/dist/helpers/type-safe-assert.d.ts +7 -0
- package/dist/helpers/type-safe-assert.d.ts.map +1 -0
- package/dist/helpers/type-safe-assert.js +10 -0
- package/dist/helpers/type-safe-assert.js.map +1 -0
- package/dist/helpers/update-object-property.d.ts +7 -0
- package/dist/helpers/update-object-property.d.ts.map +1 -0
- package/dist/helpers/update-object-property.js +21 -0
- package/dist/helpers/update-object-property.js.map +1 -0
- package/dist/index.d.ts +4 -6
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -2941
- package/dist/index.js.map +1 -1
- package/dist/test/test-utils.d.ts +4 -0
- package/dist/test/test-utils.d.ts.map +1 -0
- package/dist/test/test-utils.js +14 -0
- package/dist/test/test-utils.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,2960 +1,154 @@
|
|
|
1
|
-
import { existsSync, readdirSync
|
|
2
|
-
import { createRequire } from 'module';
|
|
3
|
-
import { arch, platform } from 'os';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// src/helpers/is-many-and-return.ts
|
|
25
|
-
function isManyAndReturnOutputType(name) {
|
|
26
|
-
const lowerName = name.toLowerCase();
|
|
27
|
-
if ((lowerName.startsWith("createmany") || lowerName.startsWith("updatemany")) && (lowerName.endsWith("andreturnoutputtype") || lowerName.endsWith("andreturn"))) {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
function pascalCase(string) {
|
|
33
|
-
return startCase(camelCase(string)).replaceAll(" ", "");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// src/handlers/args-type.ts
|
|
37
|
-
function argsType(field, args) {
|
|
38
|
-
if (["queryRaw", "executeRaw"].includes(field.name)) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (isManyAndReturnOutputType(field.name)) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const { eventEmitter, getModelName: getModelName2, typeNames } = args;
|
|
45
|
-
let className = pascalCase(`${field.name}Args`);
|
|
46
|
-
const modelName = getModelName2(className) ?? "";
|
|
47
|
-
switch (className) {
|
|
48
|
-
case `Aggregate${modelName}Args`: {
|
|
49
|
-
className = `${modelName}AggregateArgs`;
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
case `GroupBy${modelName}Args`: {
|
|
53
|
-
className = `${modelName}GroupByArgs`;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const inputType2 = {
|
|
58
|
-
constraints: { maxNumFields: null, minNumFields: null },
|
|
59
|
-
fields: [...field.args],
|
|
60
|
-
name: className
|
|
61
|
-
};
|
|
62
|
-
if (!field.args.some((x) => x.name === "_count") && [`${modelName}AggregateArgs`, `${modelName}GroupByArgs`].includes(className)) {
|
|
63
|
-
const names = ["Count", "Avg", "Sum", "Min", "Max"];
|
|
64
|
-
if (`${modelName}GroupByArgs` === inputType2.name) {
|
|
65
|
-
const byField = inputType2.fields.find((f) => f.name === "by");
|
|
66
|
-
if (byField?.inputTypes) {
|
|
67
|
-
byField.inputTypes = byField.inputTypes.filter((it) => it.isList);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
for (const name of names) {
|
|
71
|
-
if (!typeNames.has(`${modelName}${name}AggregateInput`)) {
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
inputType2.fields.push({
|
|
75
|
-
inputTypes: [
|
|
76
|
-
{
|
|
77
|
-
isList: false,
|
|
78
|
-
location: "inputObjectTypes",
|
|
79
|
-
type: `${modelName}${name}AggregateInput`
|
|
80
|
-
}
|
|
81
|
-
],
|
|
82
|
-
isNullable: true,
|
|
83
|
-
isRequired: false,
|
|
84
|
-
name: `_${name.toLowerCase()}`
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
eventEmitter.emitSync("InputType", {
|
|
89
|
-
...args,
|
|
90
|
-
classDecoratorName: "ArgsType",
|
|
91
|
-
fileType: "args",
|
|
92
|
-
inputType: inputType2
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// src/event-names.ts
|
|
97
|
-
var BeforeGenerateField = "BeforeGenerateField";
|
|
98
|
-
|
|
99
|
-
// src/handlers/combine-scalar-filters.ts
|
|
100
|
-
function combineScalarFilters(eventEmitter) {
|
|
101
|
-
eventEmitter.on("BeforeInputType", beforeInputType);
|
|
102
|
-
eventEmitter.on(BeforeGenerateField, beforeGenerateField);
|
|
103
|
-
eventEmitter.on("PostBegin", postBegin);
|
|
104
|
-
}
|
|
105
|
-
function beforeInputType(args) {
|
|
106
|
-
const { inputType: inputType2, removeTypes } = args;
|
|
107
|
-
if (isContainBogus(inputType2.name) && isScalarFilter(inputType2)) {
|
|
108
|
-
removeTypes.add(inputType2.name);
|
|
109
|
-
inputType2.name = replaceBogus(inputType2.name);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function beforeGenerateField(field) {
|
|
113
|
-
for (const fieldInput of field.inputTypes) {
|
|
114
|
-
if (fieldInput.location !== "inputObjectTypes") {
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
const fieldInputType = fieldInput.type;
|
|
118
|
-
if (isContainBogus(fieldInputType)) {
|
|
119
|
-
fieldInput.type = replaceBogus(fieldInputType);
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { arch, platform } from 'node:os';
|
|
4
|
+
const createRequireTyped = createRequire;
|
|
5
|
+
// ESLint doesn't understand import.meta.url type - cast to string explicitly
|
|
6
|
+
const requireCjs = createRequireTyped(String(import.meta.url));
|
|
7
|
+
const gracefulFsRaw = requireCjs('graceful-fs');
|
|
8
|
+
const gracefulFs = gracefulFsRaw;
|
|
9
|
+
const nodeFsRaw = requireCjs('fs');
|
|
10
|
+
const nodeFs = nodeFsRaw;
|
|
11
|
+
gracefulFs.gracefulify(nodeFs);
|
|
12
|
+
const globalConsole = globalThis.console;
|
|
13
|
+
const logError = (msg) => {
|
|
14
|
+
globalConsole.log(msg);
|
|
15
|
+
};
|
|
16
|
+
const processTyped = process;
|
|
17
|
+
processTyped.on('unhandledRejection', (reason) => {
|
|
18
|
+
logError(`nestjs-prisma-graphql: unhandled rejection: ${String(reason)}`);
|
|
19
|
+
if (reason instanceof Error && typeof reason.stack === 'string') {
|
|
20
|
+
logError(reason.stack);
|
|
120
21
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return name.startsWith("Nested") || name.includes("Nullable") && name.endsWith("Filter") || name.endsWith("NullableFilter");
|
|
128
|
-
}
|
|
129
|
-
function isScalarFilter(inputType2) {
|
|
130
|
-
if (!inputType2.name.endsWith("Filter")) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
let result = false;
|
|
134
|
-
const equals = inputType2.fields.find((f) => f.name === "equals");
|
|
135
|
-
if (equals) {
|
|
136
|
-
result = equals.inputTypes.every((x) => {
|
|
137
|
-
return ["enumTypes", "scalar"].includes(x.location);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
function postBegin(args) {
|
|
143
|
-
const { modelNames, schema } = args;
|
|
144
|
-
const inputTypes = schema.inputObjectTypes.prisma ?? [];
|
|
145
|
-
const enumTypes = schema.enumTypes.model ?? [];
|
|
146
|
-
const types = [
|
|
147
|
-
"Bool",
|
|
148
|
-
"Int",
|
|
149
|
-
"String",
|
|
150
|
-
"DateTime",
|
|
151
|
-
"Decimal",
|
|
152
|
-
"Float",
|
|
153
|
-
"Json",
|
|
154
|
-
"Bytes",
|
|
155
|
-
"BigInt"
|
|
156
|
-
];
|
|
157
|
-
for (const enumType of enumTypes) {
|
|
158
|
-
const { name } = enumType;
|
|
159
|
-
types.push(`Enum${name}`);
|
|
160
|
-
}
|
|
161
|
-
const inputTypeByName = keyBy(inputTypes, (it) => it.name);
|
|
162
|
-
const replaceBogusFilters = (filterName, filterNameCandidates) => {
|
|
163
|
-
for (const filterNameCandidate of filterNameCandidates) {
|
|
164
|
-
const candidate = inputTypeByName[filterNameCandidate];
|
|
165
|
-
if (candidate) {
|
|
166
|
-
const it = cloneDeep({ ...candidate, name: filterName });
|
|
167
|
-
inputTypes.push(it);
|
|
168
|
-
inputTypeByName[filterName] = it;
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
22
|
+
});
|
|
23
|
+
processTyped.on('uncaughtException', (error) => {
|
|
24
|
+
const err = error;
|
|
25
|
+
logError(`nestjs-prisma-graphql: uncaught exception: ${err.message}`);
|
|
26
|
+
if (typeof err.stack === 'string') {
|
|
27
|
+
logError(err.stack);
|
|
171
28
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
`Nested${type}NullableFilter`
|
|
177
|
-
]);
|
|
178
|
-
replaceBogusFilters(`${type}WithAggregatesFilter`, [
|
|
179
|
-
`${type}NullableWithAggregatesFilter`,
|
|
180
|
-
`Nested${type}NullableWithAggregatesFilter`
|
|
181
|
-
]);
|
|
182
|
-
replaceBogusFilters(`${type}ListFilter`, [
|
|
183
|
-
`${type}NullableListFilter`,
|
|
184
|
-
`Nested${type}NullableListFilter`
|
|
185
|
-
]);
|
|
186
|
-
}
|
|
187
|
-
for (const modelName of modelNames) {
|
|
188
|
-
replaceBogusFilters(`${modelName}RelationFilter`, [
|
|
189
|
-
`${modelName}NullableRelationFilter`
|
|
190
|
-
]);
|
|
191
|
-
}
|
|
192
|
-
for (const modelName of modelNames) {
|
|
193
|
-
replaceBogusFilters(`${modelName}ScalarRelationFilter`, [
|
|
194
|
-
`${modelName}NullableScalarRelationFilter`
|
|
195
|
-
]);
|
|
196
|
-
}
|
|
197
|
-
remove(inputTypes, (it) => {
|
|
198
|
-
return isContainBogus(it.name);
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// src/handlers/create-aggregate-input.ts
|
|
203
|
-
function createAggregateInput(args) {
|
|
204
|
-
const { eventEmitter, outputType: outputType2 } = args;
|
|
205
|
-
const className = `${outputType2.name}Input`;
|
|
206
|
-
const inputType2 = {
|
|
207
|
-
constraints: { maxNumFields: null, minNumFields: null },
|
|
208
|
-
fields: outputType2.fields.map((x) => ({
|
|
209
|
-
inputTypes: [
|
|
210
|
-
{
|
|
211
|
-
isList: false,
|
|
212
|
-
location: "scalar",
|
|
213
|
-
type: "true"
|
|
214
|
-
}
|
|
215
|
-
],
|
|
216
|
-
isNullable: x.isNullable ?? true,
|
|
217
|
-
isRequired: false,
|
|
218
|
-
name: x.name
|
|
219
|
-
})),
|
|
220
|
-
name: className
|
|
221
|
-
};
|
|
222
|
-
eventEmitter.emitSync("InputType", {
|
|
223
|
-
...args,
|
|
224
|
-
classDecoratorName: "InputType",
|
|
225
|
-
fileType: "input",
|
|
226
|
-
inputType: inputType2
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// src/handlers/decimal-helpers.ts
|
|
231
|
-
function generateDecimalHelpers(args) {
|
|
232
|
-
const { output, project } = args;
|
|
233
|
-
const rootDirectory = project.getDirectory(output) ?? project.createDirectory(output);
|
|
234
|
-
const sourceFile = rootDirectory.createSourceFile("decimal-helpers.ts", void 0, {
|
|
235
|
-
overwrite: true
|
|
236
|
-
});
|
|
237
|
-
const helpersCode = `/**
|
|
238
|
-
* Decimal Helpers for Prisma GraphQL
|
|
239
|
-
*
|
|
240
|
-
* This module provides utilities for transforming Decimal values
|
|
241
|
-
* between GraphQL and Prisma, compatible with Prisma 7+.
|
|
242
|
-
*
|
|
243
|
-
* These functions replace the prisma-graphql-type-decimal package
|
|
244
|
-
* which is incompatible with Prisma 7's new client structure.
|
|
245
|
-
*/
|
|
246
|
-
|
|
247
|
-
import Decimal from 'decimal.js';
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Reconstruct a Decimal from a serialized object.
|
|
251
|
-
* Prisma serializes Decimals as objects with d, e, s properties.
|
|
252
|
-
*/
|
|
253
|
-
function createDecimalFromObject(object: { d: number[]; e: number; s: number }): Decimal {
|
|
254
|
-
return Object.create(Decimal.prototype, {
|
|
255
|
-
d: { value: object.d },
|
|
256
|
-
e: { value: object.e },
|
|
257
|
-
s: { value: object.s },
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
29
|
+
});
|
|
30
|
+
import generatorHelper from '@prisma/generator-helper';
|
|
31
|
+
const { generatorHandler } = generatorHelper;
|
|
32
|
+
import { generate } from './generate.js';
|
|
261
33
|
/**
|
|
262
|
-
*
|
|
263
|
-
*
|
|
34
|
+
* Environment variables that can disable the generator:
|
|
35
|
+
* - DISABLE_NESTJS_PRISMA_GRAPHQL=true - Disable this specific generator
|
|
36
|
+
* - PRISMA_GENERATOR_SKIP=true - Skip all Prisma generators (common convention)
|
|
37
|
+
* - SKIP_PRISMA_GENERATE=true - Alternative skip flag
|
|
38
|
+
* - CI_SKIP_PRISMA_GRAPHQL=true - CI-specific skip flag
|
|
264
39
|
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (v instanceof Decimal) return v;
|
|
274
|
-
if (typeof v === 'object' && v !== null && 'd' in v && 'e' in v && 's' in v) {
|
|
275
|
-
return createDecimalFromObject(v as { d: number[]; e: number; s: number });
|
|
276
|
-
}
|
|
277
|
-
return new Decimal(v as string | number);
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if (value instanceof Decimal) return value;
|
|
282
|
-
if (typeof value === 'object' && value !== null && 'd' in value && 'e' in value && 's' in value) {
|
|
283
|
-
return createDecimalFromObject(value as { d: number[]; e: number; s: number });
|
|
284
|
-
}
|
|
285
|
-
return new Decimal(value as string | number);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Re-export Decimal class for convenience
|
|
40
|
+
* Config options (in schema.prisma):
|
|
41
|
+
* - disabled = true - Disable generation
|
|
42
|
+
* - disabled = "true" - Disable generation (string)
|
|
43
|
+
* - disabled = 1 - Disable generation (number as string)
|
|
44
|
+
*
|
|
45
|
+
* @param options - Generator options or minimal config object
|
|
46
|
+
* @param env - Environment variables (defaults to process.env)
|
|
47
|
+
* @returns true if the generator should be disabled
|
|
290
48
|
*/
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
function classProperty(property, eventArguments) {
|
|
299
|
-
const { isList, location, propertyType } = eventArguments;
|
|
300
|
-
if (["inputObjectTypes", "outputObjectTypes"].includes(location) && !isList) {
|
|
301
|
-
const [safeTypes, instanceofTypes] = partition(
|
|
302
|
-
propertyType,
|
|
303
|
-
(t) => t === "null" || t.startsWith("Prisma.")
|
|
304
|
-
);
|
|
305
|
-
const mappedInstanceofTypes = instanceofTypes.map((t) => `InstanceType<typeof ${t}>`);
|
|
306
|
-
property.type = [...mappedInstanceofTypes, ...safeTypes].join(" | ");
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
var ImportDeclarationMap = class extends Map {
|
|
310
|
-
add(name, value, isTypeOnly) {
|
|
311
|
-
if (!this.has(name)) {
|
|
312
|
-
const structure = typeof value === "string" ? { isTypeOnly, moduleSpecifier: value, namedImports: [{ name }] } : value;
|
|
313
|
-
this.set(name, structure);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Add a type-only import for ESM circular dependency resolution
|
|
318
|
-
*/
|
|
319
|
-
addType(name, moduleSpecifier) {
|
|
320
|
-
const typeOnlyKey = `type:${name}`;
|
|
321
|
-
if (!this.has(typeOnlyKey) && !this.has(name)) {
|
|
322
|
-
this.set(typeOnlyKey, {
|
|
323
|
-
isTypeOnly: true,
|
|
324
|
-
moduleSpecifier,
|
|
325
|
-
namedImports: [{ name }]
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
create(args) {
|
|
330
|
-
const { defaultImport, from, isTypeOnly, namedImport, namespaceImport } = args;
|
|
331
|
-
let { name } = args;
|
|
332
|
-
const value = {
|
|
333
|
-
defaultImport: void 0,
|
|
334
|
-
isTypeOnly,
|
|
335
|
-
moduleSpecifier: from,
|
|
336
|
-
namedImports: [],
|
|
337
|
-
namespaceImport: void 0
|
|
338
|
-
};
|
|
339
|
-
if (namedImport === true && namespaceImport !== void 0) {
|
|
340
|
-
value.namedImports = [{ name: namespaceImport }];
|
|
341
|
-
name = namespaceImport;
|
|
342
|
-
} else if (defaultImport === void 0) {
|
|
343
|
-
if (namespaceImport === void 0) {
|
|
344
|
-
value.namedImports = [{ name }];
|
|
345
|
-
} else {
|
|
346
|
-
value.namespaceImport = namespaceImport;
|
|
347
|
-
name = namespaceImport;
|
|
348
|
-
}
|
|
349
|
-
} else {
|
|
350
|
-
value.defaultImport = defaultImport === true ? name : defaultImport;
|
|
351
|
-
name = value.defaultImport;
|
|
352
|
-
}
|
|
353
|
-
const key = isTypeOnly === true ? `type:${name}` : name;
|
|
354
|
-
if (this.has(key)) {
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
this.set(key, value);
|
|
358
|
-
}
|
|
359
|
-
*toStatements() {
|
|
360
|
-
const iterator = this.values();
|
|
361
|
-
let result = iterator.next();
|
|
362
|
-
while (result.value !== void 0) {
|
|
363
|
-
yield {
|
|
364
|
-
...result.value,
|
|
365
|
-
kind: StructureKind.ImportDeclaration
|
|
366
|
-
};
|
|
367
|
-
result = iterator.next();
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
// src/handlers/generate-files.ts
|
|
373
|
-
async function generateFiles(args) {
|
|
374
|
-
const { config, eventEmitter, output, project } = args;
|
|
375
|
-
if (config.emitSingle) {
|
|
376
|
-
const rootDirectory = project.getDirectory(output) ?? project.createDirectory(output);
|
|
377
|
-
const sourceFile = rootDirectory.getSourceFile("index.ts") ?? rootDirectory.createSourceFile("index.ts", void 0, { overwrite: true });
|
|
378
|
-
const statements = project.getSourceFiles().flatMap((s) => {
|
|
379
|
-
if (s === sourceFile) {
|
|
380
|
-
return [];
|
|
381
|
-
}
|
|
382
|
-
const classDeclaration = s.getClass(() => true);
|
|
383
|
-
const stmts = s.getStructure().statements;
|
|
384
|
-
if (Array.isArray(stmts)) {
|
|
385
|
-
for (const statement of stmts) {
|
|
386
|
-
if (!(typeof statement === "object" && statement.kind === StructureKind.Class)) {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
for (const property of statement.properties ?? []) {
|
|
390
|
-
for (const decorator of property.decorators ?? []) {
|
|
391
|
-
const fullName = classDeclaration?.getProperty(property.name)?.getDecorator(decorator.name)?.getFullName();
|
|
392
|
-
ok(
|
|
393
|
-
fullName !== void 0,
|
|
394
|
-
`Cannot get full name of decorator of class ${String(statement.name)}`
|
|
395
|
-
);
|
|
396
|
-
decorator.name = fullName;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
project.removeSourceFile(s);
|
|
402
|
-
return stmts;
|
|
403
|
-
});
|
|
404
|
-
const imports = new ImportDeclarationMap();
|
|
405
|
-
const enums = [];
|
|
406
|
-
const classes = [];
|
|
407
|
-
for (const statement of statements) {
|
|
408
|
-
if (typeof statement === "string") {
|
|
409
|
-
if (statement.startsWith("registerEnumType")) {
|
|
410
|
-
enums.push(statement);
|
|
411
|
-
}
|
|
412
|
-
continue;
|
|
413
|
-
}
|
|
414
|
-
switch (statement.kind) {
|
|
415
|
-
case StructureKind.ImportDeclaration: {
|
|
416
|
-
if (statement.moduleSpecifier.startsWith("./") || statement.moduleSpecifier.startsWith("..")) {
|
|
417
|
-
continue;
|
|
418
|
-
}
|
|
419
|
-
for (const namedImport of statement.namedImports) {
|
|
420
|
-
const name = namedImport.alias ?? namedImport.name;
|
|
421
|
-
imports.add(name, statement.moduleSpecifier);
|
|
422
|
-
}
|
|
423
|
-
if (statement.defaultImport) {
|
|
424
|
-
imports.create({
|
|
425
|
-
defaultImport: statement.defaultImport,
|
|
426
|
-
from: statement.moduleSpecifier,
|
|
427
|
-
name: statement.defaultImport
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
if (statement.namespaceImport) {
|
|
431
|
-
imports.create({
|
|
432
|
-
from: statement.moduleSpecifier,
|
|
433
|
-
name: statement.namespaceImport,
|
|
434
|
-
namespaceImport: statement.namespaceImport
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
break;
|
|
438
|
-
}
|
|
439
|
-
case StructureKind.Enum: {
|
|
440
|
-
enums.unshift(statement);
|
|
441
|
-
break;
|
|
442
|
-
}
|
|
443
|
-
case StructureKind.Class: {
|
|
444
|
-
classes.push(statement);
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
for (const customImport of config.customImport) {
|
|
450
|
-
imports.create(customImport);
|
|
451
|
-
}
|
|
452
|
-
sourceFile.set({
|
|
453
|
-
kind: StructureKind.SourceFile,
|
|
454
|
-
statements: [...imports.toStatements(), ...enums, ...classes]
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
const sourceFiles = project.getSourceFiles();
|
|
458
|
-
const sourceFileCount = sourceFiles.length;
|
|
459
|
-
const globalConsole3 = globalThis.console;
|
|
460
|
-
const logMessage = (msg) => {
|
|
461
|
-
globalConsole3.log(msg);
|
|
462
|
-
};
|
|
463
|
-
logMessage(
|
|
464
|
-
`nestjs-prisma-graphql: saving ${String(sourceFileCount)} source files to ${output}`
|
|
465
|
-
);
|
|
466
|
-
if (sourceFileCount === 0) {
|
|
467
|
-
throw new Error(
|
|
468
|
-
"nestjs-prisma-graphql: project has 0 source files \u2014 nothing to write"
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
if (config.emitCompiled) {
|
|
472
|
-
project.compilerOptions.set({
|
|
473
|
-
declaration: true,
|
|
474
|
-
declarationDir: output,
|
|
475
|
-
emitDecoratorMetadata: false,
|
|
476
|
-
outDir: output,
|
|
477
|
-
rootDir: output,
|
|
478
|
-
skipLibCheck: true
|
|
479
|
-
});
|
|
480
|
-
const emitResult = await project.emit();
|
|
481
|
-
const errors = emitResult.getDiagnostics().map((d) => String(d.getMessageText()));
|
|
482
|
-
if (errors.length > 0) {
|
|
483
|
-
eventEmitter.emitSync("Warning", errors);
|
|
484
|
-
}
|
|
485
|
-
} else {
|
|
486
|
-
const BATCH_SIZE = 100;
|
|
487
|
-
if (sourceFileCount > BATCH_SIZE) {
|
|
488
|
-
logMessage(
|
|
489
|
-
`nestjs-prisma-graphql: using batched save for large schema (${String(sourceFileCount)} files)`
|
|
490
|
-
);
|
|
491
|
-
for (let i = 0; i < sourceFileCount; i += BATCH_SIZE) {
|
|
492
|
-
const batch = sourceFiles.slice(i, i + BATCH_SIZE);
|
|
493
|
-
logMessage(
|
|
494
|
-
`nestjs-prisma-graphql: saving batch ${String(Math.floor(i / BATCH_SIZE) + 1)}/${String(Math.ceil(sourceFileCount / BATCH_SIZE))} (${String(batch.length)} files)`
|
|
495
|
-
);
|
|
496
|
-
await Promise.all(batch.map(async (sf) => await sf.save()));
|
|
497
|
-
}
|
|
498
|
-
} else {
|
|
499
|
-
await project.save();
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// src/helpers/file-type-by-location.ts
|
|
505
|
-
function fileTypeByLocation(fieldLocation) {
|
|
506
|
-
switch (fieldLocation) {
|
|
507
|
-
case "inputObjectTypes": {
|
|
508
|
-
return "input";
|
|
509
|
-
}
|
|
510
|
-
case "outputObjectTypes": {
|
|
511
|
-
return "output";
|
|
512
|
-
}
|
|
513
|
-
case "enumTypes": {
|
|
514
|
-
return "enum";
|
|
515
|
-
}
|
|
516
|
-
case "fieldRefTypes":
|
|
517
|
-
case "scalar":
|
|
518
|
-
default: {
|
|
519
|
-
return "object";
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
function relativePath(from, to) {
|
|
524
|
-
let fromPath = from;
|
|
525
|
-
let toPath = to;
|
|
526
|
-
if (!fromPath.startsWith("/")) {
|
|
527
|
-
fromPath = `/${fromPath}`;
|
|
528
|
-
}
|
|
529
|
-
if (!toPath.startsWith("/")) {
|
|
530
|
-
toPath = `/${toPath}`;
|
|
531
|
-
}
|
|
532
|
-
let result = getRelativePath(fromPath, toPath);
|
|
533
|
-
if (!result.startsWith(".")) {
|
|
534
|
-
result = `./${result}`;
|
|
535
|
-
}
|
|
536
|
-
if (result.endsWith(".ts")) {
|
|
537
|
-
result = result.slice(0, -3);
|
|
538
|
-
}
|
|
539
|
-
return result;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// src/helpers/get-graphql-import.ts
|
|
543
|
-
function getGraphqlImport(args) {
|
|
544
|
-
const {
|
|
545
|
-
config,
|
|
546
|
-
fileType,
|
|
547
|
-
getSourceFile,
|
|
548
|
-
isId,
|
|
549
|
-
location,
|
|
550
|
-
noTypeId,
|
|
551
|
-
sourceFile,
|
|
552
|
-
typeName
|
|
553
|
-
} = args;
|
|
554
|
-
if (location === "scalar") {
|
|
555
|
-
if (isId && !noTypeId) {
|
|
556
|
-
return { name: "ID", specifier: "@nestjs/graphql" };
|
|
557
|
-
}
|
|
558
|
-
const graphqlType = config.graphqlScalars[typeName];
|
|
559
|
-
if (graphqlType) {
|
|
560
|
-
return { name: graphqlType.name, specifier: graphqlType.specifier };
|
|
561
|
-
}
|
|
562
|
-
switch (typeName) {
|
|
563
|
-
case "Float":
|
|
564
|
-
case "Int": {
|
|
565
|
-
return { name: typeName, specifier: "@nestjs/graphql" };
|
|
566
|
-
}
|
|
567
|
-
case "DateTime": {
|
|
568
|
-
return { name: "Date", specifier: void 0 };
|
|
569
|
-
}
|
|
570
|
-
case "true":
|
|
571
|
-
case "Boolean": {
|
|
572
|
-
return { name: "Boolean", specifier: void 0 };
|
|
573
|
-
}
|
|
574
|
-
case "Decimal": {
|
|
575
|
-
return {
|
|
576
|
-
name: "GraphQLDecimal",
|
|
577
|
-
specifier: "graphql-scalars"
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
case "Json": {
|
|
581
|
-
return { name: "GraphQLJSON", specifier: "graphql-type-json" };
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
return { name: "String", specifier: void 0 };
|
|
585
|
-
}
|
|
586
|
-
let sourceFileType = fileTypeByLocation(location);
|
|
587
|
-
if (sourceFileType === "output" && fileType === "model") {
|
|
588
|
-
sourceFileType = "model";
|
|
589
|
-
}
|
|
590
|
-
const specifier = relativePath(
|
|
591
|
-
sourceFile.getFilePath(),
|
|
592
|
-
getSourceFile({
|
|
593
|
-
name: typeName,
|
|
594
|
-
type: sourceFileType
|
|
595
|
-
}).getFilePath()
|
|
596
|
-
);
|
|
597
|
-
return { name: typeName, specifier };
|
|
598
|
-
}
|
|
599
|
-
function getGraphqlInputType(inputTypes, pattern) {
|
|
600
|
-
let result;
|
|
601
|
-
inputTypes = inputTypes.filter((t) => !["null", "Null"].includes(t.type));
|
|
602
|
-
inputTypes = uniqWith(inputTypes, isEqual);
|
|
603
|
-
if (inputTypes.length === 1) {
|
|
604
|
-
return inputTypes[0];
|
|
605
|
-
}
|
|
606
|
-
const countTypes = countBy(inputTypes, (x) => x.location);
|
|
607
|
-
const isOneType = Object.keys(countTypes).length === 1;
|
|
608
|
-
if (isOneType) {
|
|
609
|
-
result = inputTypes.find((x) => x.isList);
|
|
610
|
-
if (result) {
|
|
611
|
-
return result;
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
if (pattern !== null && pattern !== void 0 && pattern.length > 0) {
|
|
615
|
-
if (pattern.startsWith("matcher:") || pattern.startsWith("match:")) {
|
|
616
|
-
const { 1: patternValue } = pattern.split(":", 2);
|
|
617
|
-
const isMatch = outmatch2(patternValue, { separator: false });
|
|
618
|
-
result = inputTypes.find((x) => isMatch(x.type));
|
|
619
|
-
if (result !== void 0) {
|
|
620
|
-
return result;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
result = inputTypes.find((x) => x.type.includes(pattern));
|
|
624
|
-
if (result !== void 0) {
|
|
625
|
-
return result;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
result = inputTypes.find((x) => x.location === "inputObjectTypes");
|
|
629
|
-
if (result !== void 0) {
|
|
630
|
-
return result;
|
|
631
|
-
}
|
|
632
|
-
if ((countTypes.enumTypes ?? 0) > 0 && (countTypes.scalar ?? 0) > 0 && inputTypes.some((x) => x.type === "Json" && x.location === "scalar")) {
|
|
633
|
-
result = inputTypes.find((x) => x.type === "Json" && x.location === "scalar");
|
|
634
|
-
if (result !== void 0) {
|
|
635
|
-
return result;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
if (((countTypes.scalar ?? 0) >= 1 || (countTypes.enumTypes ?? 0) >= 1) && countTypes.fieldRefTypes === 1) {
|
|
639
|
-
result = inputTypes.find(
|
|
640
|
-
(x) => (x.location === "scalar" || x.location === "enumTypes") && x.isList
|
|
641
|
-
);
|
|
642
|
-
if (result !== void 0) {
|
|
643
|
-
return result;
|
|
644
|
-
}
|
|
645
|
-
result = inputTypes.find((x) => x.location === "scalar" || x.location === "enumTypes");
|
|
646
|
-
if (result !== void 0) {
|
|
647
|
-
return result;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
throw new TypeError(
|
|
651
|
-
`Cannot get matching input type from ${inputTypes.length > 0 ? inputTypes.map((x) => x.type).join(", ") : "zero length inputTypes"}`
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
// src/helpers/get-property-type.ts
|
|
656
|
-
function getPropertyType(args) {
|
|
657
|
-
const { location, type } = args;
|
|
658
|
-
switch (type) {
|
|
659
|
-
case "Float":
|
|
660
|
-
case "Int": {
|
|
661
|
-
return ["number"];
|
|
662
|
-
}
|
|
663
|
-
case "String": {
|
|
664
|
-
return ["string"];
|
|
665
|
-
}
|
|
666
|
-
case "Boolean": {
|
|
667
|
-
return ["boolean"];
|
|
668
|
-
}
|
|
669
|
-
case "DateTime": {
|
|
670
|
-
return ["Date", "string"];
|
|
671
|
-
}
|
|
672
|
-
case "Decimal": {
|
|
673
|
-
return ["Prisma.Decimal"];
|
|
674
|
-
}
|
|
675
|
-
case "Json": {
|
|
676
|
-
return ["any"];
|
|
677
|
-
}
|
|
678
|
-
case "Null": {
|
|
679
|
-
return ["null"];
|
|
680
|
-
}
|
|
681
|
-
case "Bytes": {
|
|
682
|
-
return ["Uint8Array"];
|
|
683
|
-
}
|
|
684
|
-
case "BigInt": {
|
|
685
|
-
return ["bigint", "number"];
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
if (["inputObjectTypes", "outputObjectTypes"].includes(location)) {
|
|
689
|
-
return [type];
|
|
690
|
-
}
|
|
691
|
-
if (location === "enumTypes") {
|
|
692
|
-
const enumType = `\`\${${type}}\``;
|
|
693
|
-
return [enumType];
|
|
694
|
-
}
|
|
695
|
-
if (location === "scalar") {
|
|
696
|
-
return [type];
|
|
697
|
-
}
|
|
698
|
-
return ["unknown"];
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
// src/helpers/get-where-unique-at-least-keys.ts
|
|
702
|
-
function getWhereUniqueAtLeastKeys(model) {
|
|
703
|
-
const names = model.fields.filter((field) => field.isUnique || field.isId).map((field) => field.name);
|
|
704
|
-
if (model.primaryKey) {
|
|
705
|
-
names.push(createFieldName(model.primaryKey));
|
|
706
|
-
}
|
|
707
|
-
for (const uniqueIndex of model.uniqueIndexes) {
|
|
708
|
-
names.push(createFieldName(uniqueIndex));
|
|
709
|
-
}
|
|
710
|
-
return names;
|
|
711
|
-
}
|
|
712
|
-
function createFieldName(args) {
|
|
713
|
-
const { fields, name } = args;
|
|
714
|
-
return name !== null && name !== void 0 && name.length > 0 ? name : fields.join("_");
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
// src/helpers/is-where-unique-input-type.ts
|
|
718
|
-
function isWhereUniqueInputType(name) {
|
|
719
|
-
return name.endsWith("WhereUniqueInput");
|
|
720
|
-
}
|
|
721
|
-
function propertyStructure(args) {
|
|
722
|
-
const {
|
|
723
|
-
hasExclamationToken,
|
|
724
|
-
hasQuestionToken,
|
|
725
|
-
isList,
|
|
726
|
-
isNullable,
|
|
727
|
-
name,
|
|
728
|
-
propertyType
|
|
729
|
-
} = args;
|
|
730
|
-
const typeString = propertyType.map((typeItem) => isList ? `Array<${typeItem}>` : typeItem).join(" | ");
|
|
731
|
-
return {
|
|
732
|
-
decorators: [],
|
|
733
|
-
hasExclamationToken: hasExclamationToken ?? !isNullable,
|
|
734
|
-
hasQuestionToken: hasQuestionToken ?? isNullable,
|
|
735
|
-
kind: StructureKind.Property,
|
|
736
|
-
leadingTrivia: "\n",
|
|
737
|
-
name,
|
|
738
|
-
type: typeString
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
// src/handlers/input-type.ts
|
|
743
|
-
function inputType(args) {
|
|
744
|
-
const {
|
|
745
|
-
classDecoratorName,
|
|
746
|
-
classTransformerTypeModels,
|
|
747
|
-
config,
|
|
748
|
-
eventEmitter,
|
|
749
|
-
fieldSettings,
|
|
750
|
-
fileType,
|
|
751
|
-
getModelName: getModelName2,
|
|
752
|
-
getSourceFile,
|
|
753
|
-
inputType: inputTypeArg,
|
|
754
|
-
models,
|
|
755
|
-
output,
|
|
756
|
-
removeTypes,
|
|
757
|
-
typeNames
|
|
758
|
-
} = args;
|
|
759
|
-
typeNames.add(inputTypeArg.name);
|
|
760
|
-
const importDeclarations = new ImportDeclarationMap();
|
|
761
|
-
const sourceFile = getSourceFile({
|
|
762
|
-
name: inputTypeArg.name,
|
|
763
|
-
type: fileType
|
|
764
|
-
});
|
|
765
|
-
const classStructure = {
|
|
766
|
-
decorators: [
|
|
767
|
-
{
|
|
768
|
-
arguments: [],
|
|
769
|
-
name: classDecoratorName
|
|
770
|
-
}
|
|
771
|
-
],
|
|
772
|
-
isExported: true,
|
|
773
|
-
kind: StructureKind.Class,
|
|
774
|
-
name: inputTypeArg.name,
|
|
775
|
-
properties: []
|
|
776
|
-
};
|
|
777
|
-
const modelName = getModelName2(inputTypeArg.name) ?? "";
|
|
778
|
-
const model = models.get(modelName);
|
|
779
|
-
const modelFieldSettings = model && fieldSettings.get(model.name);
|
|
780
|
-
const moduleSpecifier = "@nestjs/graphql";
|
|
781
|
-
const lazyTypes = /* @__PURE__ */ new Set();
|
|
782
|
-
importDeclarations.set("Field", {
|
|
783
|
-
moduleSpecifier,
|
|
784
|
-
namedImports: [{ name: "Field" }]
|
|
785
|
-
}).set(classDecoratorName, {
|
|
786
|
-
moduleSpecifier,
|
|
787
|
-
namedImports: [{ name: classDecoratorName }]
|
|
788
|
-
});
|
|
789
|
-
if (config.esmCompatible) {
|
|
790
|
-
const typeRegistryPath = relativePath(
|
|
791
|
-
sourceFile.getFilePath(),
|
|
792
|
-
`${output}/type-registry.ts`
|
|
793
|
-
);
|
|
794
|
-
importDeclarations.add("registerType", typeRegistryPath);
|
|
795
|
-
importDeclarations.add("getType", typeRegistryPath);
|
|
796
|
-
}
|
|
797
|
-
const useInputType = config.useInputType.find(
|
|
798
|
-
(x) => inputTypeArg.name.includes(x.typeName)
|
|
799
|
-
);
|
|
800
|
-
const isWhereUnique = isWhereUniqueInputType(inputTypeArg.name);
|
|
801
|
-
for (const field of inputTypeArg.fields) {
|
|
802
|
-
field.inputTypes = field.inputTypes.filter((t) => !removeTypes.has(t.type));
|
|
803
|
-
eventEmitter.emitSync(BeforeGenerateField, field, args);
|
|
804
|
-
const { inputTypes, isRequired, name } = field;
|
|
805
|
-
if (inputTypes.length === 0) {
|
|
806
|
-
continue;
|
|
807
|
-
}
|
|
808
|
-
const usePattern = useInputType?.ALL ?? useInputType?.[name];
|
|
809
|
-
const graphqlInputType = getGraphqlInputType(inputTypes, usePattern);
|
|
810
|
-
const { isList, location, type } = graphqlInputType;
|
|
811
|
-
const typeName = type;
|
|
812
|
-
const settings = modelFieldSettings?.get(name);
|
|
813
|
-
const propertySettings = settings?.getPropertyType({
|
|
814
|
-
input: true,
|
|
815
|
-
name: inputTypeArg.name
|
|
816
|
-
});
|
|
817
|
-
const modelField = model?.fields.find((f) => f.name === name);
|
|
818
|
-
const isCustomsApplicable = typeName === modelField?.type;
|
|
819
|
-
const atLeastKeys = model && getWhereUniqueAtLeastKeys(model);
|
|
820
|
-
const whereUniqueInputTypeValue = isWhereUniqueInputType(typeName) && atLeastKeys && `Prisma.AtLeast<${typeName}, ${atLeastKeys.map((n) => `'${n}'`).join(" | ")}>`;
|
|
821
|
-
const propertyType = castArray(
|
|
822
|
-
propertySettings?.name ?? whereUniqueInputTypeValue ?? getPropertyType({
|
|
823
|
-
location,
|
|
824
|
-
type: typeName
|
|
825
|
-
})
|
|
826
|
-
);
|
|
827
|
-
const hasExclamationToken = Boolean(
|
|
828
|
-
isWhereUnique && config.unsafeCompatibleWhereUniqueInput && atLeastKeys?.includes(name)
|
|
829
|
-
);
|
|
830
|
-
const property = propertyStructure({
|
|
831
|
-
hasExclamationToken: hasExclamationToken || void 0,
|
|
832
|
-
hasQuestionToken: hasExclamationToken ? false : void 0,
|
|
833
|
-
isList,
|
|
834
|
-
isNullable: !isRequired,
|
|
835
|
-
name,
|
|
836
|
-
propertyType
|
|
837
|
-
});
|
|
838
|
-
if (classStructure.properties) {
|
|
839
|
-
classStructure.properties.push(property);
|
|
840
|
-
}
|
|
841
|
-
if (propertySettings) {
|
|
842
|
-
importDeclarations.create({ ...propertySettings });
|
|
843
|
-
} else if (propertyType.some(
|
|
844
|
-
(p) => typeof p === "string" && p.includes("Prisma.Decimal")
|
|
845
|
-
)) {
|
|
846
|
-
importDeclarations.add("Prisma", config.prismaClientImport);
|
|
847
|
-
} else if (propertyType.some((p) => typeof p === "string" && p.startsWith("Prisma."))) {
|
|
848
|
-
importDeclarations.add("Prisma", config.prismaClientImport);
|
|
849
|
-
}
|
|
850
|
-
let graphqlType;
|
|
851
|
-
let useGetType = false;
|
|
852
|
-
const shouldHideField = settings?.shouldHideField({
|
|
853
|
-
input: true,
|
|
854
|
-
name: inputTypeArg.name
|
|
855
|
-
}) ?? config.decorate.some(
|
|
856
|
-
(d) => d.name === "HideField" && d.from === moduleSpecifier && d.isMatchField(name) && d.isMatchType(inputTypeArg.name)
|
|
857
|
-
);
|
|
858
|
-
const fieldType = settings?.getFieldType({
|
|
859
|
-
input: true,
|
|
860
|
-
name: inputTypeArg.name
|
|
861
|
-
});
|
|
862
|
-
if (fieldType && isCustomsApplicable && !shouldHideField) {
|
|
863
|
-
graphqlType = fieldType.name;
|
|
864
|
-
importDeclarations.create({ ...fieldType });
|
|
865
|
-
} else {
|
|
866
|
-
const graphqlImport = getGraphqlImport({
|
|
867
|
-
config,
|
|
868
|
-
getSourceFile,
|
|
869
|
-
location,
|
|
870
|
-
sourceFile,
|
|
871
|
-
typeName
|
|
872
|
-
});
|
|
873
|
-
graphqlType = graphqlImport.name;
|
|
874
|
-
if (location === "enumTypes") {
|
|
875
|
-
const parts = String(propertyType[0]).split(" ");
|
|
876
|
-
parts.at(-1);
|
|
877
|
-
}
|
|
878
|
-
const shouldUseLazyType = config.esmCompatible && location === "inputObjectTypes";
|
|
879
|
-
if (graphqlImport.name === inputTypeArg.name && shouldUseLazyType) {
|
|
880
|
-
lazyTypes.add(graphqlImport.name);
|
|
881
|
-
useGetType = true;
|
|
882
|
-
} else if (graphqlImport.specifier !== null && graphqlImport.specifier !== void 0 && !importDeclarations.has(graphqlImport.name) && graphqlImport.name !== inputTypeArg.name) {
|
|
883
|
-
if (shouldUseLazyType) {
|
|
884
|
-
importDeclarations.addType(graphqlImport.name, graphqlImport.specifier);
|
|
885
|
-
lazyTypes.add(graphqlImport.name);
|
|
886
|
-
} else {
|
|
887
|
-
importDeclarations.set(graphqlImport.name, {
|
|
888
|
-
moduleSpecifier: graphqlImport.specifier,
|
|
889
|
-
namedImports: [{ name: graphqlImport.name }]
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
if (lazyTypes.has(graphqlImport.name)) {
|
|
894
|
-
useGetType = true;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
ok(
|
|
898
|
-
property.decorators !== void 0 && property.decorators !== null,
|
|
899
|
-
"property.decorators is undefined"
|
|
900
|
-
);
|
|
901
|
-
if (shouldHideField) {
|
|
902
|
-
importDeclarations.add("HideField", moduleSpecifier);
|
|
903
|
-
property.decorators.push({ arguments: [], name: "HideField" });
|
|
904
|
-
} else {
|
|
905
|
-
let typeExpression;
|
|
906
|
-
if (useGetType) {
|
|
907
|
-
typeExpression = isList ? `() => [getType('${graphqlType}')]` : `() => getType('${graphqlType}')`;
|
|
908
|
-
} else {
|
|
909
|
-
typeExpression = isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`;
|
|
910
|
-
}
|
|
911
|
-
property.decorators.push({
|
|
912
|
-
arguments: [
|
|
913
|
-
typeExpression,
|
|
914
|
-
JSON52.stringify({
|
|
915
|
-
...settings?.fieldArguments(),
|
|
916
|
-
nullable: !isRequired
|
|
917
|
-
})
|
|
918
|
-
],
|
|
919
|
-
name: "Field"
|
|
920
|
-
});
|
|
921
|
-
if (graphqlType === "GraphQLDecimal") {
|
|
922
|
-
const decimalHelpersPath = relativePath(
|
|
923
|
-
sourceFile.getFilePath(),
|
|
924
|
-
`${output}/decimal-helpers.ts`
|
|
925
|
-
);
|
|
926
|
-
importDeclarations.add("transformToDecimal", decimalHelpersPath);
|
|
927
|
-
importDeclarations.add("Transform", "class-transformer");
|
|
928
|
-
importDeclarations.add("Type", "class-transformer");
|
|
929
|
-
property.decorators.push(
|
|
930
|
-
{
|
|
931
|
-
arguments: ["() => Object"],
|
|
932
|
-
name: "Type"
|
|
933
|
-
},
|
|
934
|
-
{
|
|
935
|
-
arguments: ["transformToDecimal"],
|
|
936
|
-
name: "Transform"
|
|
937
|
-
}
|
|
938
|
-
);
|
|
939
|
-
} else if (location === "inputObjectTypes" && (modelField?.type === "Decimal" || [
|
|
940
|
-
"connect",
|
|
941
|
-
"connectOrCreate",
|
|
942
|
-
"create",
|
|
943
|
-
"createMany",
|
|
944
|
-
"data",
|
|
945
|
-
"delete",
|
|
946
|
-
"deleteMany",
|
|
947
|
-
"disconnect",
|
|
948
|
-
"set",
|
|
949
|
-
"update",
|
|
950
|
-
"updateMany",
|
|
951
|
-
"upsert",
|
|
952
|
-
"where"
|
|
953
|
-
].includes(name) || classTransformerTypeModels.has(getModelName2(graphqlType) ?? "") || modelField?.kind === "object" && models.get(modelField.type)?.fields.some(
|
|
954
|
-
(f) => f.kind === "object" && classTransformerTypeModels.has(f.type)
|
|
955
|
-
) === true)) {
|
|
956
|
-
importDeclarations.add("Type", "class-transformer");
|
|
957
|
-
if (useGetType) {
|
|
958
|
-
property.decorators.push({
|
|
959
|
-
arguments: [`getType('${graphqlType}')`],
|
|
960
|
-
name: "Type"
|
|
961
|
-
});
|
|
962
|
-
} else {
|
|
963
|
-
property.decorators.push({ arguments: [`() => ${graphqlType}`], name: "Type" });
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
if (isCustomsApplicable) {
|
|
967
|
-
for (const options of settings ?? []) {
|
|
968
|
-
if ((options.kind === "Decorator" && options.input && options.match?.(name)) ?? true) {
|
|
969
|
-
property.decorators.push({
|
|
970
|
-
arguments: options.arguments,
|
|
971
|
-
name: options.name
|
|
972
|
-
});
|
|
973
|
-
ok(
|
|
974
|
-
options.from !== void 0 && options.from !== null && options.from !== "",
|
|
975
|
-
"Missed 'from' part in configuration or field setting"
|
|
976
|
-
);
|
|
977
|
-
importDeclarations.create(options);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
for (const decorate of config.decorate) {
|
|
982
|
-
if (decorate.isMatchField(name) && decorate.isMatchType(inputTypeArg.name)) {
|
|
983
|
-
property.decorators.push({
|
|
984
|
-
arguments: decorate.arguments?.map((x) => pupa(x, { propertyType })),
|
|
985
|
-
name: decorate.name
|
|
986
|
-
});
|
|
987
|
-
importDeclarations.create(decorate);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
eventEmitter.emitSync("ClassProperty", property, {
|
|
992
|
-
isList,
|
|
993
|
-
location,
|
|
994
|
-
propertyType
|
|
995
|
-
});
|
|
996
|
-
}
|
|
997
|
-
const statements = [
|
|
998
|
-
...importDeclarations.toStatements(),
|
|
999
|
-
classStructure
|
|
1000
|
-
];
|
|
1001
|
-
if (config.esmCompatible) {
|
|
1002
|
-
statements.push(`
|
|
1003
|
-
registerType('${inputTypeArg.name}', ${inputTypeArg.name});`);
|
|
1004
|
-
}
|
|
1005
|
-
sourceFile.set({
|
|
1006
|
-
statements
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
var ObjectSettings = class extends Array {
|
|
1010
|
-
shouldHideField({
|
|
1011
|
-
input = false,
|
|
1012
|
-
name,
|
|
1013
|
-
output = false
|
|
1014
|
-
}) {
|
|
1015
|
-
const hideField = this.find((s) => s.name === "HideField");
|
|
1016
|
-
return Boolean(
|
|
1017
|
-
hideField?.input && input || hideField?.output && output || hideField?.match?.(name)
|
|
1018
|
-
);
|
|
1019
|
-
}
|
|
1020
|
-
getFieldType({
|
|
1021
|
-
input,
|
|
1022
|
-
name,
|
|
1023
|
-
output
|
|
1024
|
-
}) {
|
|
1025
|
-
const fieldType = this.find((s) => s.kind === "FieldType");
|
|
1026
|
-
if (!fieldType) {
|
|
1027
|
-
return void 0;
|
|
1028
|
-
}
|
|
1029
|
-
if (fieldType.match) {
|
|
1030
|
-
return fieldType.match(name) ? fieldType : void 0;
|
|
1031
|
-
}
|
|
1032
|
-
if (input && !fieldType.input) {
|
|
1033
|
-
return void 0;
|
|
1034
|
-
}
|
|
1035
|
-
if (output && !fieldType.output) {
|
|
1036
|
-
return void 0;
|
|
1037
|
-
}
|
|
1038
|
-
return fieldType;
|
|
1039
|
-
}
|
|
1040
|
-
getPropertyType({
|
|
1041
|
-
input,
|
|
1042
|
-
name,
|
|
1043
|
-
output
|
|
1044
|
-
}) {
|
|
1045
|
-
const propertyType = this.find((s) => s.kind === "PropertyType");
|
|
1046
|
-
if (!propertyType) {
|
|
1047
|
-
return void 0;
|
|
1048
|
-
}
|
|
1049
|
-
if (propertyType.match) {
|
|
1050
|
-
return propertyType.match(name) ? propertyType : void 0;
|
|
1051
|
-
}
|
|
1052
|
-
if (input && !propertyType.input) {
|
|
1053
|
-
return void 0;
|
|
1054
|
-
}
|
|
1055
|
-
if (output && !propertyType.output) {
|
|
1056
|
-
return void 0;
|
|
1057
|
-
}
|
|
1058
|
-
return propertyType;
|
|
1059
|
-
}
|
|
1060
|
-
getObjectTypeArguments(options) {
|
|
1061
|
-
const objectTypeOptions = merge({}, options);
|
|
1062
|
-
const resultArguments = [objectTypeOptions];
|
|
1063
|
-
const objectType = this.find((s) => s.kind === "ObjectType");
|
|
1064
|
-
if (objectType && isObject(objectType.arguments)) {
|
|
1065
|
-
const { name } = objectType.arguments;
|
|
1066
|
-
merge(objectTypeOptions, omit(objectType.arguments, "name"));
|
|
1067
|
-
if (name !== null && name !== void 0 && name !== "") {
|
|
1068
|
-
resultArguments.unshift(name);
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
return resultArguments.map((x) => JSON52.stringify(x));
|
|
1072
|
-
}
|
|
1073
|
-
fieldArguments() {
|
|
1074
|
-
const fieldItem = this.find((item) => item.kind === "Field");
|
|
1075
|
-
if (fieldItem) {
|
|
1076
|
-
return fieldItem.arguments;
|
|
1077
|
-
}
|
|
1078
|
-
return void 0;
|
|
1079
|
-
}
|
|
49
|
+
// Helper to get process.env in a type-safe way
|
|
50
|
+
// Using Record<string, unknown> to avoid NodeJS.Process type resolution issues
|
|
51
|
+
const getProcessEnv = () => {
|
|
52
|
+
const globalProcess = process;
|
|
53
|
+
const processLike = globalProcess;
|
|
54
|
+
return processLike.env;
|
|
1080
55
|
};
|
|
1081
|
-
function
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
fieldElement = newFieldElement;
|
|
1098
|
-
}
|
|
1099
|
-
for (const line of textLines) {
|
|
1100
|
-
const match = /^@(?<name>\w+(\.(\w+))?)\((?<args>.*)\)/.exec(line);
|
|
1101
|
-
const { documentLine, element } = createSettingElement({
|
|
1102
|
-
config,
|
|
1103
|
-
fieldElement,
|
|
1104
|
-
line,
|
|
1105
|
-
match
|
|
1106
|
-
});
|
|
1107
|
-
if (element) {
|
|
1108
|
-
result.push(element);
|
|
1109
|
-
}
|
|
1110
|
-
if (documentLine) {
|
|
1111
|
-
documentationLines.push(line);
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
return {
|
|
1115
|
-
documentation: documentationLines.filter(Boolean).join("\n") || void 0,
|
|
1116
|
-
settings: result
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
function createSettingElement({
|
|
1120
|
-
config,
|
|
1121
|
-
fieldElement,
|
|
1122
|
-
line,
|
|
1123
|
-
match
|
|
1124
|
-
}) {
|
|
1125
|
-
const result = {
|
|
1126
|
-
documentLine: "",
|
|
1127
|
-
element: void 0
|
|
1128
|
-
};
|
|
1129
|
-
if (line.startsWith("@deprecated")) {
|
|
1130
|
-
const DEPRECATED_PREFIX_LENGTH = 11;
|
|
1131
|
-
const updatedFieldElement = {
|
|
1132
|
-
...fieldElement,
|
|
1133
|
-
arguments: {
|
|
1134
|
-
...fieldElement.arguments,
|
|
1135
|
-
deprecationReason: trim(line.slice(DEPRECATED_PREFIX_LENGTH))
|
|
1136
|
-
}
|
|
1137
|
-
};
|
|
1138
|
-
result.element = updatedFieldElement;
|
|
1139
|
-
return result;
|
|
1140
|
-
}
|
|
1141
|
-
if (line.startsWith("@complexity")) {
|
|
1142
|
-
const COMPLEXITY_PREFIX_LENGTH = 11;
|
|
1143
|
-
const MIN_COMPLEXITY = 1;
|
|
1144
|
-
let n = Number.parseInt(trim(line.slice(COMPLEXITY_PREFIX_LENGTH)), 10);
|
|
1145
|
-
if (Number.isNaN(n) || n < MIN_COMPLEXITY) {
|
|
1146
|
-
n = MIN_COMPLEXITY;
|
|
1147
|
-
}
|
|
1148
|
-
const updatedFieldElement = {
|
|
1149
|
-
...fieldElement,
|
|
1150
|
-
arguments: {
|
|
1151
|
-
...fieldElement.arguments,
|
|
1152
|
-
complexity: n
|
|
1153
|
-
}
|
|
1154
|
-
};
|
|
1155
|
-
result.element = updatedFieldElement;
|
|
1156
|
-
return result;
|
|
1157
|
-
}
|
|
1158
|
-
const name = match?.groups?.name;
|
|
1159
|
-
if (!(match && name !== void 0 && name !== "")) {
|
|
1160
|
-
result.documentLine = line;
|
|
1161
|
-
return result;
|
|
1162
|
-
}
|
|
1163
|
-
const element = {
|
|
1164
|
-
arguments: [],
|
|
1165
|
-
from: "",
|
|
1166
|
-
input: false,
|
|
1167
|
-
kind: "Decorator",
|
|
1168
|
-
model: false,
|
|
1169
|
-
name: "",
|
|
1170
|
-
output: false
|
|
1171
|
-
};
|
|
1172
|
-
result.element = element;
|
|
1173
|
-
if (name === "TypeGraphQL.omit" || name === "HideField") {
|
|
1174
|
-
Object.assign(element, hideFieldDecorator(match));
|
|
1175
|
-
return result;
|
|
1176
|
-
}
|
|
1177
|
-
if (["FieldType", "PropertyType"].includes(name) && match.groups?.args !== void 0 && match.groups.args !== "") {
|
|
1178
|
-
const options2 = customType(match.groups.args);
|
|
1179
|
-
const namespaceConfig2 = options2.namespace !== void 0 && options2.namespace !== "" ? config.fields[options2.namespace] : void 0;
|
|
1180
|
-
merge(element, namespaceConfig2, options2, {
|
|
1181
|
-
kind: name
|
|
1182
|
-
});
|
|
1183
|
-
return result;
|
|
1184
|
-
}
|
|
1185
|
-
if (name === "ObjectType" && match.groups?.args !== void 0 && match.groups.args !== "") {
|
|
1186
|
-
element.kind = "ObjectType";
|
|
1187
|
-
const options2 = customType(match.groups.args);
|
|
1188
|
-
if (typeof options2[0] === "string" && options2[0] !== "") {
|
|
1189
|
-
options2.name = options2[0];
|
|
1190
|
-
}
|
|
1191
|
-
if (isObject(options2[1])) {
|
|
1192
|
-
merge(options2, options2[1]);
|
|
1193
|
-
}
|
|
1194
|
-
element.arguments = {
|
|
1195
|
-
isAbstract: options2.isAbstract,
|
|
1196
|
-
name: options2.name
|
|
1197
|
-
};
|
|
1198
|
-
return result;
|
|
1199
|
-
}
|
|
1200
|
-
if (name === "Directive" && match.groups?.args !== void 0 && match.groups.args !== "") {
|
|
1201
|
-
const options2 = customType(match.groups.args);
|
|
1202
|
-
merge(element, { from: "@nestjs/graphql", model: true }, options2, {
|
|
1203
|
-
arguments: Array.isArray(options2.arguments) ? options2.arguments.map((s) => JSON52.stringify(s)) : options2.arguments,
|
|
1204
|
-
kind: "Decorator",
|
|
1205
|
-
name,
|
|
1206
|
-
namespace: false
|
|
1207
|
-
});
|
|
1208
|
-
return result;
|
|
1209
|
-
}
|
|
1210
|
-
const namespace = getNamespace(name);
|
|
1211
|
-
element.namespaceImport = namespace;
|
|
1212
|
-
const args = match.groups?.args ?? "";
|
|
1213
|
-
const options = {
|
|
1214
|
-
arguments: args.split(",").map((s) => trim(s)).filter(Boolean),
|
|
1215
|
-
name
|
|
1216
|
-
};
|
|
1217
|
-
const namespaceConfig = namespace !== void 0 && namespace !== "" ? config.fields[namespace] : void 0;
|
|
1218
|
-
merge(element, namespaceConfig, options);
|
|
1219
|
-
return result;
|
|
1220
|
-
}
|
|
1221
|
-
function customType(args) {
|
|
1222
|
-
const result = {};
|
|
1223
|
-
let options = parseArgs(args);
|
|
1224
|
-
if (typeof options === "string") {
|
|
1225
|
-
options = { name: options };
|
|
1226
|
-
}
|
|
1227
|
-
Object.assign(result, options);
|
|
1228
|
-
const namespace = getNamespace(options.name);
|
|
1229
|
-
result.namespace = namespace;
|
|
1230
|
-
const optionsWithName = options;
|
|
1231
|
-
if (optionsWithName.name !== void 0 && optionsWithName.name !== "" && optionsWithName.name.includes(".")) {
|
|
1232
|
-
result.namespaceImport = namespace;
|
|
1233
|
-
}
|
|
1234
|
-
if (typeof options.match === "string" || Array.isArray(options.match)) {
|
|
1235
|
-
result.match = outmatch2(options.match, { separator: false });
|
|
1236
|
-
}
|
|
1237
|
-
return result;
|
|
1238
|
-
}
|
|
1239
|
-
function hideFieldDecorator(match) {
|
|
1240
|
-
const result = {
|
|
1241
|
-
arguments: [],
|
|
1242
|
-
defaultImport: void 0,
|
|
1243
|
-
from: "@nestjs/graphql",
|
|
1244
|
-
match: void 0,
|
|
1245
|
-
name: "HideField",
|
|
1246
|
-
namespaceImport: void 0
|
|
1247
|
-
};
|
|
1248
|
-
const args = match.groups?.args;
|
|
1249
|
-
if (args === void 0 || args === "") {
|
|
1250
|
-
result.output = true;
|
|
1251
|
-
return result;
|
|
1252
|
-
}
|
|
1253
|
-
if (args.includes("{") && args.includes("}")) {
|
|
1254
|
-
const options = parseArgs(args);
|
|
1255
|
-
result.output = Boolean(options.output);
|
|
1256
|
-
result.input = Boolean(options.input);
|
|
1257
|
-
if (typeof options.match === "string" || Array.isArray(options.match)) {
|
|
1258
|
-
result.match = outmatch2(options.match, { separator: false });
|
|
1259
|
-
}
|
|
1260
|
-
} else {
|
|
1261
|
-
if (/output:\s*true/.test(args)) {
|
|
1262
|
-
result.output = true;
|
|
1263
|
-
}
|
|
1264
|
-
if (/input:\s*true/.test(args)) {
|
|
1265
|
-
result.input = true;
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
return result;
|
|
1269
|
-
}
|
|
1270
|
-
function parseArgs(string) {
|
|
1271
|
-
try {
|
|
1272
|
-
return JSON52.parse(string);
|
|
1273
|
-
} catch {
|
|
1274
|
-
try {
|
|
1275
|
-
return JSON52.parse(`[${string}]`);
|
|
1276
|
-
} catch {
|
|
1277
|
-
throw new Error(`Failed to parse: ${string}`);
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
|
-
function getNamespace(name) {
|
|
1282
|
-
if (name === void 0 || name === null) {
|
|
1283
|
-
return void 0;
|
|
1284
|
-
}
|
|
1285
|
-
if (typeof name !== "string") {
|
|
1286
|
-
return void 0;
|
|
1287
|
-
}
|
|
1288
|
-
let result = name;
|
|
1289
|
-
if (result === "") {
|
|
1290
|
-
return void 0;
|
|
1291
|
-
}
|
|
1292
|
-
if (result.includes(".")) {
|
|
1293
|
-
const parts = result.split(".");
|
|
1294
|
-
result = parts[0] ?? "";
|
|
1295
|
-
}
|
|
1296
|
-
if (result === "") {
|
|
1297
|
-
return void 0;
|
|
1298
|
-
}
|
|
1299
|
-
return result;
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
// src/handlers/model-data.ts
|
|
1303
|
-
function modelData(model, args) {
|
|
1304
|
-
const {
|
|
1305
|
-
classTransformerTypeModels,
|
|
1306
|
-
config,
|
|
1307
|
-
fieldSettings,
|
|
1308
|
-
modelFields,
|
|
1309
|
-
modelNames,
|
|
1310
|
-
models
|
|
1311
|
-
} = args;
|
|
1312
|
-
modelNames.push(model.name);
|
|
1313
|
-
models.set(model.name, model);
|
|
1314
|
-
const modelFieldsValue = /* @__PURE__ */ new Map();
|
|
1315
|
-
modelFields.set(model.name, modelFieldsValue);
|
|
1316
|
-
const fieldSettingsValue = /* @__PURE__ */ new Map();
|
|
1317
|
-
fieldSettings.set(model.name, fieldSettingsValue);
|
|
1318
|
-
for (const field of model.fields) {
|
|
1319
|
-
if (field.documentation !== null && field.documentation !== void 0 && field.documentation.length > 0) {
|
|
1320
|
-
const { documentation, settings } = createObjectSettings({
|
|
1321
|
-
config,
|
|
1322
|
-
text: field.documentation
|
|
1323
|
-
});
|
|
1324
|
-
field.documentation = documentation;
|
|
1325
|
-
fieldSettingsValue.set(field.name, settings);
|
|
1326
|
-
}
|
|
1327
|
-
modelFieldsValue.set(field.name, field);
|
|
1328
|
-
}
|
|
1329
|
-
if (model.fields.some((field) => field.type === "Decimal")) {
|
|
1330
|
-
classTransformerTypeModels.add(model.name);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
// src/helpers/create-comment.ts
|
|
1335
|
-
function createComment(documentation, settings) {
|
|
1336
|
-
const documentationLines = documentation.split("\n");
|
|
1337
|
-
const commentLines = ["/**"];
|
|
1338
|
-
for (const line of documentationLines) {
|
|
1339
|
-
commentLines.push(` * ${line}`);
|
|
1340
|
-
}
|
|
1341
|
-
const fieldArgs = settings?.fieldArguments();
|
|
1342
|
-
let deprecationReason;
|
|
1343
|
-
if (fieldArgs === void 0) {
|
|
1344
|
-
deprecationReason = void 0;
|
|
1345
|
-
} else {
|
|
1346
|
-
deprecationReason = fieldArgs.deprecationReason;
|
|
1347
|
-
}
|
|
1348
|
-
if (deprecationReason !== void 0 && deprecationReason !== null && deprecationReason.length > 0) {
|
|
1349
|
-
commentLines.push(` * @deprecated ${deprecationReason}`);
|
|
1350
|
-
}
|
|
1351
|
-
commentLines.push(" */\n");
|
|
1352
|
-
return commentLines.join("\n");
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
// src/helpers/detect-circular-deps.ts
|
|
1356
|
-
function buildDependencyGraph(models) {
|
|
1357
|
-
const graph = /* @__PURE__ */ new Map();
|
|
1358
|
-
for (const model of models) {
|
|
1359
|
-
graph.set(model.name, /* @__PURE__ */ new Set());
|
|
1360
|
-
}
|
|
1361
|
-
for (const model of models) {
|
|
1362
|
-
const dependencies = graph.get(model.name);
|
|
1363
|
-
if (!dependencies) {
|
|
1364
|
-
continue;
|
|
1365
|
-
}
|
|
1366
|
-
for (const field of model.fields) {
|
|
1367
|
-
if (field.kind === "object" && field.type !== model.name) {
|
|
1368
|
-
if (graph.has(field.type)) {
|
|
1369
|
-
dependencies.add(field.type);
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
56
|
+
export function isGeneratorDisabled(options, env = getProcessEnv()) {
|
|
57
|
+
const envVarsToCheck = [
|
|
58
|
+
'DISABLE_NESTJS_PRISMA_GRAPHQL',
|
|
59
|
+
'CI_SKIP_PRISMA_GRAPHQL',
|
|
60
|
+
'PRISMA_GENERATOR_SKIP',
|
|
61
|
+
'SKIP_PRISMA_GENERATE',
|
|
62
|
+
];
|
|
63
|
+
for (const envVar of envVarsToCheck) {
|
|
64
|
+
const value = env[envVar];
|
|
65
|
+
if (value === 'true' || value === '1') {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const configDisabled = options.generator.config.disabled;
|
|
70
|
+
if (configDisabled === 'true' || configDisabled === '1' || configDisabled === 'yes') {
|
|
71
|
+
return true;
|
|
1372
72
|
}
|
|
1373
|
-
|
|
1374
|
-
return graph;
|
|
1375
|
-
}
|
|
1376
|
-
function detectCircularDependencies(graph) {
|
|
1377
|
-
const circularPairs = /* @__PURE__ */ new Set();
|
|
1378
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1379
|
-
const recursionStack = /* @__PURE__ */ new Set();
|
|
1380
|
-
const path = [];
|
|
1381
|
-
function dfs(node) {
|
|
1382
|
-
visited.add(node);
|
|
1383
|
-
recursionStack.add(node);
|
|
1384
|
-
path.push(node);
|
|
1385
|
-
const dependencies = graph.get(node) ?? /* @__PURE__ */ new Set();
|
|
1386
|
-
for (const dep of dependencies) {
|
|
1387
|
-
if (!visited.has(dep)) {
|
|
1388
|
-
dfs(dep);
|
|
1389
|
-
} else if (recursionStack.has(dep)) {
|
|
1390
|
-
const cycleStartIndex = path.indexOf(dep);
|
|
1391
|
-
if (cycleStartIndex !== -1) {
|
|
1392
|
-
const cyclePath = path.slice(cycleStartIndex);
|
|
1393
|
-
for (let i = 0; i < cyclePath.length; i++) {
|
|
1394
|
-
const a = cyclePath[i];
|
|
1395
|
-
const b = cyclePath[(i + 1) % cyclePath.length];
|
|
1396
|
-
const pair = a < b ? `${a}:${b}` : `${b}:${a}`;
|
|
1397
|
-
circularPairs.add(pair);
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
path.pop();
|
|
1403
|
-
recursionStack.delete(node);
|
|
1404
|
-
}
|
|
1405
|
-
for (const node of graph.keys()) {
|
|
1406
|
-
if (!visited.has(node)) {
|
|
1407
|
-
dfs(node);
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
return circularPairs;
|
|
1411
|
-
}
|
|
1412
|
-
function hasCircularDependency(circularDeps, modelA, modelB) {
|
|
1413
|
-
const pair = modelA < modelB ? `${modelA}:${modelB}` : `${modelB}:${modelA}`;
|
|
1414
|
-
return circularDeps.has(pair);
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
// src/helpers/get-output-type-name.ts
|
|
1418
|
-
function getOutputTypeName(name) {
|
|
1419
|
-
return name.replace(/(?:OutputType|Output)$/, "");
|
|
73
|
+
return false;
|
|
1420
74
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
getSourceFile,
|
|
1431
|
-
modelFields,
|
|
1432
|
-
models,
|
|
1433
|
-
output
|
|
1434
|
-
} = args;
|
|
1435
|
-
if (isManyAndReturnOutputType(outputType2.name)) {
|
|
1436
|
-
return;
|
|
1437
|
-
}
|
|
1438
|
-
const model = models.get(outputType2.name);
|
|
1439
|
-
ok(model, `Cannot find model by name ${outputType2.name}`);
|
|
1440
|
-
const sourceFile = getSourceFile({
|
|
1441
|
-
name: outputType2.name,
|
|
1442
|
-
type: "model"
|
|
1443
|
-
});
|
|
1444
|
-
const sourceFileStructure = sourceFile.getStructure();
|
|
1445
|
-
const exportDeclaration = getExportDeclaration(
|
|
1446
|
-
model.name,
|
|
1447
|
-
sourceFileStructure.statements
|
|
1448
|
-
);
|
|
1449
|
-
const importDeclarations = new ImportDeclarationMap();
|
|
1450
|
-
const classStructure = {
|
|
1451
|
-
decorators: [
|
|
1452
|
-
{
|
|
1453
|
-
arguments: [],
|
|
1454
|
-
name: "ObjectType"
|
|
1455
|
-
}
|
|
1456
|
-
],
|
|
1457
|
-
isExported: true,
|
|
1458
|
-
kind: StructureKind.Class,
|
|
1459
|
-
name: outputType2.name,
|
|
1460
|
-
properties: []
|
|
1461
|
-
};
|
|
1462
|
-
sourceFileStructure.statements.push(classStructure);
|
|
1463
|
-
ok(classStructure.decorators, "classStructure.decorators is undefined");
|
|
1464
|
-
const decorator = classStructure.decorators.find((d) => d.name === "ObjectType");
|
|
1465
|
-
ok(decorator, "ObjectType decorator not found");
|
|
1466
|
-
let modelSettings;
|
|
1467
|
-
if (model.documentation !== null && model.documentation !== void 0 && model.documentation.length > 0) {
|
|
1468
|
-
const objectTypeOptions = {};
|
|
1469
|
-
const { documentation, settings } = createObjectSettings({
|
|
1470
|
-
config,
|
|
1471
|
-
text: model.documentation
|
|
1472
|
-
});
|
|
1473
|
-
if (documentation !== void 0 && documentation.length > 0) {
|
|
1474
|
-
classStructure.leadingTrivia ??= createComment(documentation);
|
|
1475
|
-
objectTypeOptions.description = documentation;
|
|
1476
|
-
}
|
|
1477
|
-
decorator.arguments = settings.getObjectTypeArguments(objectTypeOptions);
|
|
1478
|
-
modelSettings = settings;
|
|
1479
|
-
}
|
|
1480
|
-
importDeclarations.add("Field", nestjsGraphql);
|
|
1481
|
-
importDeclarations.add("ObjectType", nestjsGraphql);
|
|
1482
|
-
const lazyTypes = /* @__PURE__ */ new Set();
|
|
1483
|
-
if (config.esmCompatible) {
|
|
1484
|
-
const typeRegistryPath = relativePath(
|
|
1485
|
-
sourceFile.getFilePath(),
|
|
1486
|
-
`${output}/type-registry.ts`
|
|
1487
|
-
);
|
|
1488
|
-
importDeclarations.add("registerType", typeRegistryPath);
|
|
1489
|
-
importDeclarations.add("getType", typeRegistryPath);
|
|
1490
|
-
}
|
|
1491
|
-
for (const field of outputType2.fields) {
|
|
1492
|
-
if (config.omitModelsCount && field.name === "_count") {
|
|
1493
|
-
continue;
|
|
1494
|
-
}
|
|
1495
|
-
let fileType = "model";
|
|
1496
|
-
const { isList, location, namespace, type } = field.outputType;
|
|
1497
|
-
let outputTypeName = type;
|
|
1498
|
-
if (namespace !== "model") {
|
|
1499
|
-
fileType = "output";
|
|
1500
|
-
outputTypeName = getOutputTypeName(outputTypeName);
|
|
1501
|
-
}
|
|
1502
|
-
const modelField = modelFields.get(model.name)?.get(field.name);
|
|
1503
|
-
const settings = fieldSettings.get(model.name)?.get(field.name);
|
|
1504
|
-
const fieldType = settings?.getFieldType({
|
|
1505
|
-
name: outputType2.name,
|
|
1506
|
-
output: true
|
|
1507
|
-
});
|
|
1508
|
-
const propertySettings = settings?.getPropertyType({
|
|
1509
|
-
name: outputType2.name,
|
|
1510
|
-
output: true
|
|
1511
|
-
});
|
|
1512
|
-
const propertyType = castArray(
|
|
1513
|
-
propertySettings?.name ?? getPropertyType({
|
|
1514
|
-
location,
|
|
1515
|
-
type: outputTypeName
|
|
1516
|
-
})
|
|
1517
|
-
);
|
|
1518
|
-
propertyType.splice(1, propertyType.length);
|
|
1519
|
-
if (field.isNullable === true && !isList) {
|
|
1520
|
-
propertyType.push("null");
|
|
1521
|
-
}
|
|
1522
|
-
let graphqlType;
|
|
1523
|
-
let useGetType = false;
|
|
1524
|
-
if (fieldType === void 0) {
|
|
1525
|
-
const graphqlImport = getGraphqlImport({
|
|
1526
|
-
config,
|
|
1527
|
-
fileType,
|
|
1528
|
-
getSourceFile,
|
|
1529
|
-
isId: modelField?.isId,
|
|
1530
|
-
location,
|
|
1531
|
-
noTypeId: config.noTypeId,
|
|
1532
|
-
sourceFile,
|
|
1533
|
-
typeName: outputTypeName
|
|
1534
|
-
});
|
|
1535
|
-
graphqlType = graphqlImport.name;
|
|
1536
|
-
if (graphqlImport.name !== outputType2.name && graphqlImport.specifier !== null && graphqlImport.specifier !== void 0 && graphqlImport.specifier.length > 0) {
|
|
1537
|
-
const isCircular = config.esmCompatible && location === "outputObjectTypes" && namespace === "model" && hasCircularDependency(circularDependencies, outputType2.name, outputTypeName);
|
|
1538
|
-
if (isCircular) {
|
|
1539
|
-
importDeclarations.add(graphqlImport.name, graphqlImport.specifier);
|
|
1540
|
-
lazyTypes.add(graphqlImport.name);
|
|
1541
|
-
useGetType = true;
|
|
1542
|
-
} else {
|
|
1543
|
-
importDeclarations.add(graphqlImport.name, graphqlImport.specifier);
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
} else {
|
|
1547
|
-
graphqlType = fieldType.name;
|
|
1548
|
-
importDeclarations.create({ ...fieldType });
|
|
1549
|
-
}
|
|
1550
|
-
const property = propertyStructure({
|
|
1551
|
-
hasExclamationToken: true,
|
|
1552
|
-
hasQuestionToken: location === "outputObjectTypes",
|
|
1553
|
-
isList,
|
|
1554
|
-
isNullable: field.isNullable,
|
|
1555
|
-
name: field.name,
|
|
1556
|
-
propertyType
|
|
1557
|
-
});
|
|
1558
|
-
if (typeof property.leadingTrivia === "string" && modelField?.documentation !== null && modelField?.documentation !== void 0 && modelField.documentation.length > 0) {
|
|
1559
|
-
property.leadingTrivia += createComment(modelField.documentation, settings);
|
|
1560
|
-
}
|
|
1561
|
-
if (classStructure.properties !== void 0) {
|
|
1562
|
-
classStructure.properties.push(property);
|
|
1563
|
-
}
|
|
1564
|
-
if (propertySettings !== void 0) {
|
|
1565
|
-
importDeclarations.create({ ...propertySettings });
|
|
1566
|
-
} else if (propertyType.some((p) => p.includes("Prisma.Decimal"))) {
|
|
1567
|
-
importDeclarations.add("Prisma", config.prismaClientImport);
|
|
1568
|
-
}
|
|
1569
|
-
ok(property.decorators !== void 0, "property.decorators is undefined");
|
|
1570
|
-
const shouldHideField = settings?.shouldHideField({ name: outputType2.name, output: true }) === true || config.decorate.some(
|
|
1571
|
-
(d) => d.name === "HideField" && d.from === "@nestjs/graphql" && d.isMatchField(field.name) && d.isMatchType(outputTypeName)
|
|
1572
|
-
);
|
|
1573
|
-
if (shouldHideField) {
|
|
1574
|
-
importDeclarations.add("HideField", nestjsGraphql);
|
|
1575
|
-
property.decorators.push({ arguments: [], name: "HideField" });
|
|
1576
|
-
} else {
|
|
1577
|
-
let typeExpression;
|
|
1578
|
-
if (useGetType) {
|
|
1579
|
-
typeExpression = isList ? `() => [getType('${graphqlType}')]` : `() => getType('${graphqlType}')`;
|
|
1580
|
-
} else {
|
|
1581
|
-
typeExpression = isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`;
|
|
1582
|
-
}
|
|
1583
|
-
property.decorators.push({
|
|
1584
|
-
arguments: [
|
|
1585
|
-
typeExpression,
|
|
1586
|
-
JSON52.stringify({
|
|
1587
|
-
...settings?.fieldArguments(),
|
|
1588
|
-
defaultValue: ["number", "string", "boolean"].includes(
|
|
1589
|
-
typeof modelField?.default
|
|
1590
|
-
) ? modelField?.default : void 0,
|
|
1591
|
-
description: modelField?.documentation !== null && modelField?.documentation !== void 0 && modelField.documentation !== "" ? modelField.documentation : void 0,
|
|
1592
|
-
nullable: Boolean(field.isNullable)
|
|
1593
|
-
})
|
|
1594
|
-
],
|
|
1595
|
-
name: "Field"
|
|
1596
|
-
});
|
|
1597
|
-
for (const setting of settings ?? []) {
|
|
1598
|
-
if (shouldBeDecorated(setting) && (setting.match?.(field.name) ?? true)) {
|
|
1599
|
-
property.decorators.push({
|
|
1600
|
-
arguments: setting.arguments,
|
|
1601
|
-
name: setting.name
|
|
1602
|
-
});
|
|
1603
|
-
ok(
|
|
1604
|
-
setting.from && setting.from.length > 0,
|
|
1605
|
-
"Missed 'from' part in configuration or field setting"
|
|
1606
|
-
);
|
|
1607
|
-
importDeclarations.create(setting);
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
for (const decorate of config.decorate) {
|
|
1611
|
-
if (decorate.isMatchField(field.name) && decorate.isMatchType(outputTypeName)) {
|
|
1612
|
-
property.decorators.push({
|
|
1613
|
-
arguments: decorate.arguments?.map((x) => pupa(x, { propertyType })),
|
|
1614
|
-
name: decorate.name
|
|
1615
|
-
});
|
|
1616
|
-
importDeclarations.create(decorate);
|
|
75
|
+
function countFilesRecursive(dir) {
|
|
76
|
+
let count = 0;
|
|
77
|
+
const readDirSyncTyped = readdirSync;
|
|
78
|
+
const rawEntries = readDirSyncTyped(dir, { withFileTypes: true });
|
|
79
|
+
const entries = rawEntries;
|
|
80
|
+
for (const entry of entries) {
|
|
81
|
+
const isDir = typeof entry.isDirectory === 'function' ? entry.isDirectory() : false;
|
|
82
|
+
if (isDir) {
|
|
83
|
+
count += countFilesRecursive(`${dir}/${entry.name}`);
|
|
1617
84
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
eventEmitter.emitSync("ClassProperty", property, {
|
|
1621
|
-
isList,
|
|
1622
|
-
location,
|
|
1623
|
-
propertyType
|
|
1624
|
-
});
|
|
1625
|
-
}
|
|
1626
|
-
for (const setting of modelSettings ?? []) {
|
|
1627
|
-
if (shouldBeDecorated(setting)) {
|
|
1628
|
-
classStructure.decorators.push({
|
|
1629
|
-
arguments: setting.arguments,
|
|
1630
|
-
name: setting.name
|
|
1631
|
-
});
|
|
1632
|
-
importDeclarations.create(setting);
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
const statements = [
|
|
1636
|
-
...importDeclarations.toStatements(),
|
|
1637
|
-
classStructure
|
|
1638
|
-
];
|
|
1639
|
-
if (config.esmCompatible) {
|
|
1640
|
-
statements.push(`
|
|
1641
|
-
registerType('${outputType2.name}', ${outputType2.name});`);
|
|
1642
|
-
}
|
|
1643
|
-
if (exportDeclaration) {
|
|
1644
|
-
sourceFile.set({
|
|
1645
|
-
statements: [exportDeclaration, "\n", classStructure]
|
|
1646
|
-
});
|
|
1647
|
-
const classDeclaration = sourceFile.getClassOrThrow(model.name);
|
|
1648
|
-
const commentedText = classDeclaration.getText().split("\n").map((x) => `// ${x}`);
|
|
1649
|
-
classDeclaration.remove();
|
|
1650
|
-
sourceFile.addStatements(["\n", ...commentedText]);
|
|
1651
|
-
} else {
|
|
1652
|
-
sourceFile.set({
|
|
1653
|
-
statements
|
|
1654
|
-
});
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
function shouldBeDecorated(setting) {
|
|
1658
|
-
return setting.kind === "Decorator" && (setting.output || setting.model) && !(setting.output && setting.model);
|
|
1659
|
-
}
|
|
1660
|
-
function getExportDeclaration(name, statements) {
|
|
1661
|
-
return statements.find((structure) => {
|
|
1662
|
-
return structure.kind === StructureKind.ExportDeclaration && structure.namedExports.some(
|
|
1663
|
-
(o) => (o.alias ?? o.name) === name
|
|
1664
|
-
);
|
|
1665
|
-
});
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
// src/handlers/no-atomic-operations.ts
|
|
1669
|
-
function noAtomicOperations(eventEmitter) {
|
|
1670
|
-
eventEmitter.on("BeforeInputType", beforeInputType2);
|
|
1671
|
-
eventEmitter.on("BeforeGenerateFiles", beforeGenerateFiles);
|
|
1672
|
-
}
|
|
1673
|
-
function beforeInputType2(args) {
|
|
1674
|
-
const { getModelName: getModelName2, inputType: inputType2 } = args;
|
|
1675
|
-
for (const field of inputType2.fields) {
|
|
1676
|
-
const fieldName = field.name;
|
|
1677
|
-
field.inputTypes = field.inputTypes.filter((it) => {
|
|
1678
|
-
const inputTypeName = it.type;
|
|
1679
|
-
const modelName = getModelName2(inputTypeName);
|
|
1680
|
-
const isModelNameValid = modelName !== null && modelName !== void 0 && modelName.length > 0;
|
|
1681
|
-
if (isAtomicOperation(inputTypeName) || isModelNameValid && isListInput(inputTypeName, modelName, fieldName)) {
|
|
1682
|
-
return false;
|
|
1683
|
-
}
|
|
1684
|
-
return true;
|
|
1685
|
-
});
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
function beforeGenerateFiles(args) {
|
|
1689
|
-
const { project } = args;
|
|
1690
|
-
for (const sourceFile of project.getSourceFiles()) {
|
|
1691
|
-
const className = sourceFile.getClass(() => true)?.getName();
|
|
1692
|
-
const isClassNameValid = className !== void 0 && className !== null && className.length > 0;
|
|
1693
|
-
if (isClassNameValid && isAtomicOperation(className)) {
|
|
1694
|
-
project.removeSourceFile(sourceFile);
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
function isAtomicOperation(typeName) {
|
|
1699
|
-
if (typeName.endsWith("FieldUpdateOperationsInput")) {
|
|
1700
|
-
return true;
|
|
1701
|
-
}
|
|
1702
|
-
return false;
|
|
1703
|
-
}
|
|
1704
|
-
function isListInput(typeName, model, field) {
|
|
1705
|
-
return typeName === `${model}Create${field}Input` || typeName === `${model}Update${field}Input`;
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
// src/helpers/get-enum-name.ts
|
|
1709
|
-
function getEnumName(referenceName) {
|
|
1710
|
-
return referenceName.slice(3, -2);
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
|
-
// src/handlers/output-type.ts
|
|
1714
|
-
var nestjsGraphql2 = "@nestjs/graphql";
|
|
1715
|
-
function outputType(outputTypeArg, args) {
|
|
1716
|
-
const { config, eventEmitter, fieldSettings, getModelName: getModelName2, getSourceFile, models } = args;
|
|
1717
|
-
const importDeclarations = new ImportDeclarationMap();
|
|
1718
|
-
const fileType = "output";
|
|
1719
|
-
const modelName = getModelName2(outputTypeArg.name);
|
|
1720
|
-
const model = modelName === void 0 ? void 0 : models.get(modelName);
|
|
1721
|
-
const isAggregateOutput = model !== void 0 && /(?:Count|Avg|Sum|Min|Max)AggregateOutputType$/.test(outputTypeArg.name) && outputTypeArg.name.startsWith(model.name);
|
|
1722
|
-
const isCountOutput = model?.name !== void 0 && model.name !== "" && outputTypeArg.name === `${model.name}CountOutputType`;
|
|
1723
|
-
if (config.emitBlocks.outputs || isCountOutput) ; else {
|
|
1724
|
-
return;
|
|
1725
|
-
}
|
|
1726
|
-
outputTypeArg.name = getOutputTypeName(outputTypeArg.name);
|
|
1727
|
-
if (isAggregateOutput) {
|
|
1728
|
-
eventEmitter.emitSync("AggregateOutput", { ...args, outputType: outputTypeArg });
|
|
1729
|
-
}
|
|
1730
|
-
const sourceFile = getSourceFile({
|
|
1731
|
-
name: outputTypeArg.name,
|
|
1732
|
-
type: fileType
|
|
1733
|
-
});
|
|
1734
|
-
const classStructure = {
|
|
1735
|
-
decorators: [
|
|
1736
|
-
{
|
|
1737
|
-
arguments: [],
|
|
1738
|
-
name: "ObjectType"
|
|
1739
|
-
}
|
|
1740
|
-
],
|
|
1741
|
-
isExported: true,
|
|
1742
|
-
kind: StructureKind.Class,
|
|
1743
|
-
name: outputTypeArg.name,
|
|
1744
|
-
properties: []
|
|
1745
|
-
};
|
|
1746
|
-
importDeclarations.add("Field", nestjsGraphql2);
|
|
1747
|
-
importDeclarations.add("ObjectType", nestjsGraphql2);
|
|
1748
|
-
for (const field of outputTypeArg.fields) {
|
|
1749
|
-
const { isList, location, type } = field.outputType;
|
|
1750
|
-
const outputTypeName = getOutputTypeName(type);
|
|
1751
|
-
let settings;
|
|
1752
|
-
if (isCountOutput) {
|
|
1753
|
-
settings = void 0;
|
|
1754
|
-
} else if (model === void 0) {
|
|
1755
|
-
settings = void 0;
|
|
1756
|
-
} else {
|
|
1757
|
-
settings = fieldSettings.get(model.name)?.get(field.name);
|
|
1758
|
-
}
|
|
1759
|
-
const propertySettings = settings?.getPropertyType({
|
|
1760
|
-
name: outputTypeArg.name,
|
|
1761
|
-
output: true
|
|
1762
|
-
});
|
|
1763
|
-
const isCustomsApplicable = outputTypeName === model?.fields.find((f) => f.name === field.name)?.type;
|
|
1764
|
-
field.outputType.type = outputTypeName;
|
|
1765
|
-
const propertyType = castArray(
|
|
1766
|
-
propertySettings?.name ?? getPropertyType({
|
|
1767
|
-
location,
|
|
1768
|
-
type: outputTypeName
|
|
1769
|
-
})
|
|
1770
|
-
);
|
|
1771
|
-
const property = propertyStructure({
|
|
1772
|
-
hasQuestionToken: isCountOutput ? true : void 0,
|
|
1773
|
-
isList,
|
|
1774
|
-
isNullable: field.isNullable,
|
|
1775
|
-
name: field.name,
|
|
1776
|
-
propertyType
|
|
1777
|
-
});
|
|
1778
|
-
classStructure.properties?.push(property);
|
|
1779
|
-
if (propertySettings !== void 0) {
|
|
1780
|
-
importDeclarations.create({ ...propertySettings });
|
|
1781
|
-
} else if (propertyType.some((p) => p.includes("Prisma.Decimal"))) {
|
|
1782
|
-
importDeclarations.add("Prisma", config.prismaClientImport);
|
|
1783
|
-
}
|
|
1784
|
-
let graphqlType;
|
|
1785
|
-
const shouldHideField = settings?.shouldHideField({
|
|
1786
|
-
name: outputTypeArg.name,
|
|
1787
|
-
output: true
|
|
1788
|
-
}) === true || config.decorate.some(
|
|
1789
|
-
(d) => d.name === "HideField" && d.from === "@nestjs/graphql" && d.isMatchField(field.name) && d.isMatchType(outputTypeName)
|
|
1790
|
-
);
|
|
1791
|
-
const fieldType = settings?.getFieldType({
|
|
1792
|
-
name: outputTypeArg.name,
|
|
1793
|
-
output: true
|
|
1794
|
-
});
|
|
1795
|
-
if (fieldType !== void 0 && isCustomsApplicable && !shouldHideField) {
|
|
1796
|
-
graphqlType = fieldType.name;
|
|
1797
|
-
importDeclarations.create({ ...fieldType });
|
|
1798
|
-
} else {
|
|
1799
|
-
const graphqlImport = getGraphqlImport({
|
|
1800
|
-
config,
|
|
1801
|
-
fileType,
|
|
1802
|
-
getSourceFile,
|
|
1803
|
-
isId: false,
|
|
1804
|
-
location,
|
|
1805
|
-
sourceFile,
|
|
1806
|
-
typeName: outputTypeName
|
|
1807
|
-
});
|
|
1808
|
-
const referenceName = location === "enumTypes" ? getEnumName(propertyType[0]) : propertyType[0];
|
|
1809
|
-
graphqlType = graphqlImport.name;
|
|
1810
|
-
if (graphqlImport.specifier !== null && graphqlImport.specifier !== void 0 && graphqlImport.specifier.length > 0 && !importDeclarations.has(graphqlImport.name) && (graphqlImport.name !== outputTypeArg.name && !shouldHideField || shouldHideField && referenceName === graphqlImport.name)) {
|
|
1811
|
-
importDeclarations.set(graphqlImport.name, {
|
|
1812
|
-
moduleSpecifier: graphqlImport.specifier,
|
|
1813
|
-
namedImports: [{ name: graphqlImport.name }]
|
|
1814
|
-
});
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
ok(property.decorators !== void 0, "property.decorators is undefined");
|
|
1818
|
-
if (shouldHideField) {
|
|
1819
|
-
importDeclarations.add("HideField", nestjsGraphql2);
|
|
1820
|
-
property.decorators.push({ arguments: [], name: "HideField" });
|
|
1821
|
-
} else {
|
|
1822
|
-
property.decorators.push({
|
|
1823
|
-
arguments: [
|
|
1824
|
-
isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`,
|
|
1825
|
-
JSON52.stringify({
|
|
1826
|
-
...settings?.fieldArguments(),
|
|
1827
|
-
nullable: Boolean(field.isNullable)
|
|
1828
|
-
})
|
|
1829
|
-
],
|
|
1830
|
-
name: "Field"
|
|
1831
|
-
});
|
|
1832
|
-
if (isCustomsApplicable) {
|
|
1833
|
-
for (const options of settings ?? []) {
|
|
1834
|
-
const shouldApplyDecorator = options.kind === "Decorator" && options.output && (options.match?.(field.name) ?? true);
|
|
1835
|
-
if (shouldApplyDecorator) {
|
|
1836
|
-
property.decorators.push({
|
|
1837
|
-
arguments: options.arguments,
|
|
1838
|
-
name: options.name
|
|
1839
|
-
});
|
|
1840
|
-
ok(
|
|
1841
|
-
options.from !== null && options.from !== void 0 && options.from.length > 0,
|
|
1842
|
-
"Missed 'from' part in configuration or field setting"
|
|
1843
|
-
);
|
|
1844
|
-
importDeclarations.create(options);
|
|
1845
|
-
}
|
|
85
|
+
else {
|
|
86
|
+
count++;
|
|
1846
87
|
}
|
|
1847
|
-
}
|
|
1848
88
|
}
|
|
1849
|
-
|
|
1850
|
-
isList,
|
|
1851
|
-
location,
|
|
1852
|
-
propertyType
|
|
1853
|
-
});
|
|
1854
|
-
}
|
|
1855
|
-
sourceFile.set({
|
|
1856
|
-
statements: [...importDeclarations.toStatements(), classStructure]
|
|
1857
|
-
});
|
|
89
|
+
return count;
|
|
1858
90
|
}
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
91
|
+
const globalConsole2 = globalThis.console;
|
|
92
|
+
const log = (msg) => {
|
|
93
|
+
globalConsole2.log(msg);
|
|
1862
94
|
};
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
path: `${directory.getPath()}/index.ts`,
|
|
1909
|
-
statements: exportDeclarations
|
|
1910
|
-
});
|
|
1911
|
-
} else {
|
|
1912
|
-
const subdirs = directory.getDirectories();
|
|
1913
|
-
if (subdirs.length > 0) {
|
|
1914
|
-
const namespaceExportDeclarations = subdirs.map(
|
|
1915
|
-
(sourceDirectory) => getNamespaceExportDeclaration(directory, sourceDirectory)
|
|
1916
|
-
);
|
|
1917
|
-
indexFiles.push({
|
|
1918
|
-
path: `${directory.getPath()}/index.ts`,
|
|
1919
|
-
statements: namespaceExportDeclarations
|
|
1920
|
-
});
|
|
95
|
+
generatorHandler({
|
|
96
|
+
async onGenerate(options) {
|
|
97
|
+
if (isGeneratorDisabled(options)) {
|
|
98
|
+
log('nestjs-prisma-graphql: generation skipped (disabled via environment variable or config)');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const outputPath = options.generator.output?.value ?? '<unknown>';
|
|
102
|
+
const startTime = Date.now();
|
|
103
|
+
const archTyped = arch;
|
|
104
|
+
const platformTyped = platform;
|
|
105
|
+
const archValue = String(archTyped());
|
|
106
|
+
const platformValue = String(platformTyped());
|
|
107
|
+
const globalProcess2Raw = process;
|
|
108
|
+
const processWithVersion = globalProcess2Raw;
|
|
109
|
+
const nodeVersion = processWithVersion.version;
|
|
110
|
+
log([
|
|
111
|
+
'nestjs-prisma-graphql: starting generation',
|
|
112
|
+
`(arch=${archValue}, platform=${platformValue}, node=${nodeVersion}, output=${outputPath})`,
|
|
113
|
+
].join(' '));
|
|
114
|
+
try {
|
|
115
|
+
await generate(options);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
const elapsed = Date.now() - startTime;
|
|
119
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
120
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
121
|
+
log(`nestjs-prisma-graphql: generation FAILED after ${String(elapsed)}ms: ${message}`);
|
|
122
|
+
if (typeof stack === 'string') {
|
|
123
|
+
log(stack);
|
|
124
|
+
}
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
const elapsed = Date.now() - startTime;
|
|
128
|
+
const existsSyncTyped = existsSync;
|
|
129
|
+
const pathExists = typeof outputPath === 'string' &&
|
|
130
|
+
outputPath !== '<unknown>' &&
|
|
131
|
+
existsSyncTyped(outputPath);
|
|
132
|
+
if (pathExists) {
|
|
133
|
+
const fileCount = countFilesRecursive(outputPath);
|
|
134
|
+
log(`nestjs-prisma-graphql: generated ${String(fileCount)} files in ${String(elapsed)}ms`);
|
|
135
|
+
if (fileCount === 0) {
|
|
136
|
+
const msg = 'nestjs-prisma-graphql: generation produced 0 files — this likely indicates a silent failure';
|
|
137
|
+
log(msg);
|
|
138
|
+
throw new Error(msg);
|
|
139
|
+
}
|
|
1921
140
|
}
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
}
|
|
1927
|
-
}
|
|
1928
|
-
if (config.reExport === "Single" /* Single */) {
|
|
1929
|
-
const sourceFiles = project.getSourceFiles().filter((sourceFile) => sourceFile.getBaseName() !== "index.ts");
|
|
1930
|
-
const exportDeclarations = sourceFiles.map(
|
|
1931
|
-
(sourceFile) => getExportDeclaration2(rootDirectory, sourceFile)
|
|
1932
|
-
);
|
|
1933
|
-
rootDirectory.createSourceFile(
|
|
1934
|
-
"index.ts",
|
|
1935
|
-
{ statements: exportDeclarations },
|
|
1936
|
-
{ overwrite: true }
|
|
1937
|
-
);
|
|
1938
|
-
}
|
|
1939
|
-
if (config.reExport === "All" /* All */) {
|
|
1940
|
-
const exportDeclarations = [];
|
|
1941
|
-
const directories = rootDirectory.getDirectories();
|
|
1942
|
-
for (const directory of directories) {
|
|
1943
|
-
if (directory.getBaseName() === "node_modules") {
|
|
1944
|
-
continue;
|
|
1945
|
-
}
|
|
1946
|
-
const indexFile = directory.getSourceFile("index.ts");
|
|
1947
|
-
if (indexFile) {
|
|
1948
|
-
const dirName = directory.getBaseName();
|
|
1949
|
-
exportDeclarations.push({
|
|
1950
|
-
kind: StructureKind.ExportDeclaration,
|
|
1951
|
-
moduleSpecifier: `./${dirName}/index.js`
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
if (exportDeclarations.length > 0) {
|
|
1956
|
-
rootDirectory.createSourceFile(
|
|
1957
|
-
"index.ts",
|
|
1958
|
-
{ statements: exportDeclarations },
|
|
1959
|
-
{ overwrite: true }
|
|
1960
|
-
);
|
|
1961
|
-
}
|
|
1962
|
-
}
|
|
1963
|
-
}
|
|
1964
|
-
function getExportDeclaration2(directory, sourceFile) {
|
|
1965
|
-
let moduleSpecifier = directory.getRelativePathAsModuleSpecifierTo(sourceFile);
|
|
1966
|
-
if (!moduleSpecifier.endsWith(".js") && !moduleSpecifier.endsWith(".ts")) {
|
|
1967
|
-
moduleSpecifier += ".js";
|
|
1968
|
-
} else if (moduleSpecifier.endsWith(".ts")) {
|
|
1969
|
-
moduleSpecifier = `${moduleSpecifier.slice(0, -3)}.js`;
|
|
1970
|
-
}
|
|
1971
|
-
return {
|
|
1972
|
-
kind: StructureKind.ExportDeclaration,
|
|
1973
|
-
moduleSpecifier
|
|
1974
|
-
};
|
|
1975
|
-
}
|
|
1976
|
-
function getNamespaceExportDeclaration(directory, sourceDirectory) {
|
|
1977
|
-
let moduleSpecifier = directory.getRelativePathAsModuleSpecifierTo(sourceDirectory);
|
|
1978
|
-
if (!moduleSpecifier.endsWith("/index.js")) {
|
|
1979
|
-
moduleSpecifier += "/index.js";
|
|
1980
|
-
}
|
|
1981
|
-
return {
|
|
1982
|
-
kind: StructureKind.ExportDeclaration,
|
|
1983
|
-
moduleSpecifier
|
|
1984
|
-
};
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
// src/handlers/register-all-types.ts
|
|
1988
|
-
function generateRegisterAllTypes(args) {
|
|
1989
|
-
const { config, output, project } = args;
|
|
1990
|
-
if (!config.esmCompatible) {
|
|
1991
|
-
return;
|
|
1992
|
-
}
|
|
1993
|
-
const rootDirectory = project.getDirectory(output) ?? project.createDirectory(output);
|
|
1994
|
-
const sourceFile = rootDirectory.createSourceFile("register-all-types.ts", void 0, {
|
|
1995
|
-
overwrite: true
|
|
1996
|
-
});
|
|
1997
|
-
const importPaths = [];
|
|
1998
|
-
const typeNames = [];
|
|
1999
|
-
const allSourceFiles = project.getSourceFiles(`${output}/**/*.ts`);
|
|
2000
|
-
for (const file of allSourceFiles) {
|
|
2001
|
-
const filePath = file.getFilePath();
|
|
2002
|
-
if (filePath.endsWith("type-registry.ts") || filePath.endsWith("register-all-types.ts") || filePath.endsWith("index.ts")) {
|
|
2003
|
-
continue;
|
|
2004
|
-
}
|
|
2005
|
-
const fileText = file.getText();
|
|
2006
|
-
const registerMatch = /registerType\(['"]([^'"]+)['"]/.exec(fileText);
|
|
2007
|
-
if (registerMatch) {
|
|
2008
|
-
const relPath = relativePath(sourceFile.getFilePath(), filePath);
|
|
2009
|
-
importPaths.push(relPath);
|
|
2010
|
-
typeNames.push(registerMatch[1]);
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
importPaths.sort();
|
|
2014
|
-
typeNames.sort();
|
|
2015
|
-
const fileContent = `/**
|
|
2016
|
-
* ESM Type Registration Module
|
|
2017
|
-
*
|
|
2018
|
-
* This file registers all generated types with the type registry to solve
|
|
2019
|
-
* ESM circular dependency issues. In ESM, unlike CommonJS, circular imports
|
|
2020
|
-
* can result in undefined values because modules are evaluated in a different order.
|
|
2021
|
-
*
|
|
2022
|
-
* IMPORTANT: Import this file at the very top of your application entry point,
|
|
2023
|
-
* BEFORE any other code that uses the generated types.
|
|
2024
|
-
*
|
|
2025
|
-
* Example usage in main.ts:
|
|
2026
|
-
*
|
|
2027
|
-
* // This MUST be the first import
|
|
2028
|
-
* import './@generated/register-all-types.js';
|
|
2029
|
-
*
|
|
2030
|
-
* // Now you can safely import and use generated types
|
|
2031
|
-
* import { NestFactory } from '@nestjs/core';
|
|
2032
|
-
* import { AppModule } from './app.module.js';
|
|
2033
|
-
*
|
|
2034
|
-
* Why this is needed:
|
|
2035
|
-
* - ESM uses "live bindings" where imports reference the actual export
|
|
2036
|
-
* - With circular deps (User -> Post -> User), one module isn't ready when imported
|
|
2037
|
-
* - CJS would give a partial object that fills in later; ESM gives undefined
|
|
2038
|
-
* - This registry pattern defers type resolution until runtime when all modules are loaded
|
|
2039
|
-
*/
|
|
2040
|
-
|
|
2041
|
-
import { markRegistrationComplete } from './type-registry.js';
|
|
2042
|
-
|
|
2043
|
-
// Import all generated type files to trigger their registerType() calls
|
|
2044
|
-
// These are side-effect imports that populate the type registry
|
|
2045
|
-
${importPaths.map((p) => `import '${p}';`).join("\n")}
|
|
2046
|
-
|
|
2047
|
-
// Mark registration as complete to enable warning messages
|
|
2048
|
-
markRegistrationComplete();
|
|
2049
|
-
|
|
2050
|
-
// Export type names for validation (optional)
|
|
2051
|
-
export const registeredTypes = [
|
|
2052
|
-
${typeNames.map((n) => ` '${n}',`).join("\n")}
|
|
2053
|
-
] as const;
|
|
2054
|
-
|
|
2055
|
-
export type RegisteredTypeName = typeof registeredTypes[number];
|
|
2056
|
-
`;
|
|
2057
|
-
sourceFile.addStatements(fileContent);
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2060
|
-
// src/handlers/prisma-enum-doc.ts
|
|
2061
|
-
function extractEnumValueDocs(values) {
|
|
2062
|
-
return Object.fromEntries(
|
|
2063
|
-
values.map((value) => {
|
|
2064
|
-
const { name } = value;
|
|
2065
|
-
const { documentation } = value;
|
|
2066
|
-
if (typeof documentation !== "string") {
|
|
2067
|
-
return null;
|
|
2068
|
-
}
|
|
2069
|
-
if (documentation.startsWith("@deprecated")) {
|
|
2070
|
-
return [name, { deprecationReason: documentation.slice(11).trim() }];
|
|
2071
|
-
}
|
|
2072
|
-
return [name, { description: documentation }];
|
|
2073
|
-
}).filter((entry) => entry !== null)
|
|
2074
|
-
);
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
// src/handlers/register-enum.ts
|
|
2078
|
-
function registerEnum(enumType, args) {
|
|
2079
|
-
const { config, enums, getSourceFile } = args;
|
|
2080
|
-
const enumTypeAsRecord = enumType;
|
|
2081
|
-
const rawName = enumTypeAsRecord.name;
|
|
2082
|
-
const enumName = typeof rawName === "string" ? rawName : String(rawName);
|
|
2083
|
-
const enumValue = enums[enumName];
|
|
2084
|
-
if (!config.emitBlocks.prismaEnums && enumValue === void 0) {
|
|
2085
|
-
return;
|
|
2086
|
-
}
|
|
2087
|
-
const dataModelEnum = enumValue;
|
|
2088
|
-
const enumTypesData = dataModelEnum?.values ?? [];
|
|
2089
|
-
const sourceFile = getSourceFile({
|
|
2090
|
-
name: enumName,
|
|
2091
|
-
type: "enum"
|
|
2092
|
-
});
|
|
2093
|
-
const importDeclarations = new ImportDeclarationMap();
|
|
2094
|
-
importDeclarations.set("registerEnumType", {
|
|
2095
|
-
moduleSpecifier: "@nestjs/graphql",
|
|
2096
|
-
namedImports: [{ name: "registerEnumType" }]
|
|
2097
|
-
});
|
|
2098
|
-
const valuesMap = extractEnumValueDocs(enumTypesData);
|
|
2099
|
-
const filteredValuesMap = Object.fromEntries(
|
|
2100
|
-
Object.entries(valuesMap).filter(([, v]) => Object.keys(v).length > 0)
|
|
2101
|
-
);
|
|
2102
|
-
const hasValuesMap = Object.keys(filteredValuesMap).length > 0;
|
|
2103
|
-
const formattedValuesMap = hasValuesMap ? JSON.stringify(filteredValuesMap, null, 2).replace(/"([^"]+)":/g, "$1:") : "";
|
|
2104
|
-
const valuesMapEntry = hasValuesMap ? `, valuesMap: ${formattedValuesMap}` : "";
|
|
2105
|
-
const enumTypeRecord = enumType;
|
|
2106
|
-
const rawValues = enumTypeRecord.values;
|
|
2107
|
-
const enumValues = Array.isArray(rawValues) ? rawValues.map((v) => String(v)) : [];
|
|
2108
|
-
const enumStructure = {
|
|
2109
|
-
isExported: true,
|
|
2110
|
-
kind: StructureKind.Enum,
|
|
2111
|
-
members: enumValues.map((v) => ({
|
|
2112
|
-
initializer: JSON.stringify(v),
|
|
2113
|
-
name: v
|
|
2114
|
-
})),
|
|
2115
|
-
name: enumName
|
|
2116
|
-
};
|
|
2117
|
-
const enumTypeName = enumName;
|
|
2118
|
-
sourceFile.set({
|
|
2119
|
-
statements: [
|
|
2120
|
-
...importDeclarations.toStatements(),
|
|
2121
|
-
enumStructure,
|
|
2122
|
-
"\n",
|
|
2123
|
-
`registerEnumType(${enumTypeName}, { name: '${enumTypeName}', description: ${JSON.stringify(
|
|
2124
|
-
dataModelEnum?.documentation
|
|
2125
|
-
)}${valuesMapEntry} })`
|
|
2126
|
-
]
|
|
2127
|
-
});
|
|
2128
|
-
}
|
|
2129
|
-
|
|
2130
|
-
// src/handlers/require-single-fields-in-whereunique-input.ts
|
|
2131
|
-
function requireSingleFieldsInWhereUniqueInput(eventEmitter) {
|
|
2132
|
-
eventEmitter.on("BeforeInputType", beforeInputType3);
|
|
2133
|
-
}
|
|
2134
|
-
function beforeInputType3(args) {
|
|
2135
|
-
const { inputType: inputType2 } = args;
|
|
2136
|
-
if (!isWhereUniqueInputType(inputType2.name) || inputType2.fields.length !== 1) {
|
|
2137
|
-
return;
|
|
2138
|
-
}
|
|
2139
|
-
for (const field of inputType2.fields) {
|
|
2140
|
-
field.isRequired = true;
|
|
2141
|
-
field.isNullable = false;
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
// src/handlers/type-registry.ts
|
|
2146
|
-
function generateTypeRegistry(args) {
|
|
2147
|
-
const { config, output, project } = args;
|
|
2148
|
-
if (!config.esmCompatible) {
|
|
2149
|
-
return;
|
|
2150
|
-
}
|
|
2151
|
-
const rootDirectory = project.getDirectory(output) ?? project.createDirectory(output);
|
|
2152
|
-
const sourceFile = rootDirectory.createSourceFile("type-registry.ts", void 0, {
|
|
2153
|
-
overwrite: true
|
|
2154
|
-
});
|
|
2155
|
-
const registryCode = `/**
|
|
2156
|
-
* Type Registry for ESM Circular Dependency Resolution
|
|
2157
|
-
*
|
|
2158
|
-
* In ESM, circular dependencies behave differently than CommonJS:
|
|
2159
|
-
* - CJS: Modules get a partial/incomplete export object that gets filled in
|
|
2160
|
-
* - ESM: Imports are "live bindings" but can be undefined if not yet initialized
|
|
2161
|
-
*
|
|
2162
|
-
* This registry solves this by:
|
|
2163
|
-
* 1. Deferring type resolution until runtime (after all modules are loaded)
|
|
2164
|
-
* 2. Providing a forwardRef pattern for GraphQL field type declarations
|
|
2165
|
-
* 3. Validating all types are registered before they're needed
|
|
2166
|
-
*/
|
|
2167
|
-
|
|
2168
|
-
const registry = new Map<string, unknown>();
|
|
2169
|
-
const pendingResolutions = new Map<string, Array<(type: unknown) => void>>();
|
|
2170
|
-
let registrationComplete = false;
|
|
2171
|
-
|
|
2172
|
-
/**
|
|
2173
|
-
* Register a type with the registry.
|
|
2174
|
-
* This should be called at module load time after the class is defined.
|
|
2175
|
-
*/
|
|
2176
|
-
export function registerType(name: string, type: unknown): void {
|
|
2177
|
-
if (type === undefined) {
|
|
2178
|
-
console.warn(\`[nestjs-prisma-graphql] Warning: Registering undefined type for "\${name}". This may indicate a circular dependency issue.\`);
|
|
2179
|
-
}
|
|
2180
|
-
registry.set(name, type);
|
|
2181
|
-
|
|
2182
|
-
// Resolve any pending forwardRef callbacks
|
|
2183
|
-
const pending = pendingResolutions.get(name);
|
|
2184
|
-
if (pending) {
|
|
2185
|
-
for (const callback of pending) {
|
|
2186
|
-
callback(type);
|
|
2187
|
-
}
|
|
2188
|
-
pendingResolutions.delete(name);
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
|
|
2192
|
-
/**
|
|
2193
|
-
* Get a type from the registry.
|
|
2194
|
-
* Returns the type if registered, undefined otherwise.
|
|
2195
|
-
*
|
|
2196
|
-
* For use in \\@Field(() => getType('TypeName')) decorators.
|
|
2197
|
-
*/
|
|
2198
|
-
export function getType<T = unknown>(name: string): T {
|
|
2199
|
-
const type = registry.get(name);
|
|
2200
|
-
if (type === undefined && registrationComplete) {
|
|
2201
|
-
console.warn(\`[nestjs-prisma-graphql] Warning: Type "\${name}" not found in registry. Ensure register-all-types is imported before using generated types.\`);
|
|
2202
|
-
}
|
|
2203
|
-
return type as T;
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2206
|
-
/**
|
|
2207
|
-
* Create a forward reference to a type that may not be registered yet.
|
|
2208
|
-
* This is useful for handling circular dependencies where type A references type B
|
|
2209
|
-
* and type B references type A.
|
|
2210
|
-
*
|
|
2211
|
-
* Usage: \\@Field(() => forwardRef('Post'))
|
|
2212
|
-
*/
|
|
2213
|
-
export function forwardRef<T = unknown>(name: string): () => T {
|
|
2214
|
-
return () => {
|
|
2215
|
-
const type = registry.get(name);
|
|
2216
|
-
if (type === undefined) {
|
|
2217
|
-
throw new Error(
|
|
2218
|
-
\`[nestjs-prisma-graphql] Type "\${name}" not registered. \\n\` +
|
|
2219
|
-
\`This usually means:\\n\` +
|
|
2220
|
-
\` 1. The register-all-types.ts file was not imported early enough\\n\` +
|
|
2221
|
-
\` 2. There's a circular dependency that couldn't be resolved\\n\` +
|
|
2222
|
-
\` 3. The type file failed to load\\n\\n\` +
|
|
2223
|
-
\`Make sure to import 'register-all-types' at the top of your main.ts or app.module.ts\`
|
|
2224
|
-
);
|
|
2225
|
-
}
|
|
2226
|
-
return type as T;
|
|
2227
|
-
};
|
|
2228
|
-
}
|
|
2229
|
-
|
|
2230
|
-
/**
|
|
2231
|
-
* Lazily resolve a type, returning a thunk that can be called later.
|
|
2232
|
-
* This is the safest pattern for circular references in ESM.
|
|
2233
|
-
*
|
|
2234
|
-
* Usage: \\@Field(lazyType('Post'))
|
|
2235
|
-
*/
|
|
2236
|
-
export function lazyType<T = unknown>(name: string): () => T {
|
|
2237
|
-
return () => getType<T>(name);
|
|
2238
|
-
}
|
|
2239
|
-
|
|
2240
|
-
/**
|
|
2241
|
-
* Mark registration as complete. Called after all types are imported.
|
|
2242
|
-
* This enables warning messages for missing types.
|
|
2243
|
-
*/
|
|
2244
|
-
export function markRegistrationComplete(): void {
|
|
2245
|
-
registrationComplete = true;
|
|
2246
|
-
|
|
2247
|
-
// Warn about any unresolved forward refs
|
|
2248
|
-
if (pendingResolutions.size > 0) {
|
|
2249
|
-
const missing = Array.from(pendingResolutions.keys()).join(', ');
|
|
2250
|
-
console.warn(\`[nestjs-prisma-graphql] Warning: Unresolved forward references: \${missing}\`);
|
|
2251
|
-
}
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
|
-
/**
|
|
2255
|
-
* Get all registered type names (useful for debugging)
|
|
2256
|
-
*/
|
|
2257
|
-
export function getRegisteredTypes(): string[] {
|
|
2258
|
-
return Array.from(registry.keys());
|
|
2259
|
-
}
|
|
2260
|
-
|
|
2261
|
-
/**
|
|
2262
|
-
* Check if a type is registered
|
|
2263
|
-
*/
|
|
2264
|
-
export function isTypeRegistered(name: string): boolean {
|
|
2265
|
-
return registry.has(name);
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
|
-
/**
|
|
2269
|
-
* Validate that all expected types are registered.
|
|
2270
|
-
* Throws an error if any types are missing.
|
|
2271
|
-
*/
|
|
2272
|
-
export function validateRegistry(expectedTypes: string[]): void {
|
|
2273
|
-
const missing = expectedTypes.filter(name => !registry.has(name));
|
|
2274
|
-
if (missing.length > 0) {
|
|
2275
|
-
throw new Error(
|
|
2276
|
-
\`[nestjs-prisma-graphql] Missing type registrations: \${missing.join(', ')}\\n\` +
|
|
2277
|
-
\`Ensure register-all-types.ts is imported before using these types.\`
|
|
2278
|
-
);
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
`;
|
|
2282
|
-
sourceFile.addStatements(registryCode);
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2285
|
-
// src/handlers/warning.ts
|
|
2286
|
-
var globalConsole = globalThis.console;
|
|
2287
|
-
var log = (msg) => {
|
|
2288
|
-
globalConsole.log(msg);
|
|
2289
|
-
};
|
|
2290
|
-
function warning(message) {
|
|
2291
|
-
if (Array.isArray(message)) {
|
|
2292
|
-
log("nestjs-prisma-graphql:");
|
|
2293
|
-
log(message.join("\n"));
|
|
2294
|
-
} else {
|
|
2295
|
-
log(`nestjs-prisma-graphql: ${message}`);
|
|
2296
|
-
}
|
|
2297
|
-
}
|
|
2298
|
-
|
|
2299
|
-
// src/helpers/create-emit-blocks.ts
|
|
2300
|
-
var allEmmittedBlocks = [
|
|
2301
|
-
"prismaEnums",
|
|
2302
|
-
"schemaEnums",
|
|
2303
|
-
"models",
|
|
2304
|
-
"inputs",
|
|
2305
|
-
"args",
|
|
2306
|
-
"outputs"
|
|
2307
|
-
];
|
|
2308
|
-
var blocksDependencyMap = {
|
|
2309
|
-
args: ["args", "inputs", "prismaEnums"],
|
|
2310
|
-
enums: ["schemaEnums", "prismaEnums"],
|
|
2311
|
-
inputs: ["inputs", "prismaEnums"],
|
|
2312
|
-
models: ["models", "schemaEnums"],
|
|
2313
|
-
outputs: ["outputs"]
|
|
2314
|
-
};
|
|
2315
|
-
function createEmitBlocks(data) {
|
|
2316
|
-
if (!data) {
|
|
2317
|
-
const entries = allEmmittedBlocks.map((block) => [block, true]);
|
|
2318
|
-
const allBlocks = Object.fromEntries(entries);
|
|
2319
|
-
return allBlocks;
|
|
2320
|
-
}
|
|
2321
|
-
const initialBlocks = {};
|
|
2322
|
-
let currentBlocks = initialBlocks;
|
|
2323
|
-
for (const block of data) {
|
|
2324
|
-
if (!Object.keys(blocksDependencyMap).includes(block)) {
|
|
2325
|
-
continue;
|
|
2326
|
-
}
|
|
2327
|
-
const blockEntries = blocksDependencyMap[block].map(
|
|
2328
|
-
(emittedBlock) => [emittedBlock, true]
|
|
2329
|
-
);
|
|
2330
|
-
const newBlocks = Object.fromEntries(blockEntries);
|
|
2331
|
-
currentBlocks = {
|
|
2332
|
-
...currentBlocks,
|
|
2333
|
-
...newBlocks
|
|
2334
|
-
};
|
|
2335
|
-
}
|
|
2336
|
-
return currentBlocks;
|
|
2337
|
-
}
|
|
2338
|
-
|
|
2339
|
-
// src/helpers/create-config.ts
|
|
2340
|
-
function createConfig(data) {
|
|
2341
|
-
const config = merge({}, unflatten(data, { delimiter: "_" }));
|
|
2342
|
-
const $warnings = [];
|
|
2343
|
-
const defaultPattern = `{model}/{name}.{type}.ts`;
|
|
2344
|
-
const outputFilePatternValue = config.outputFilePattern;
|
|
2345
|
-
const configOutputFilePattern = typeof outputFilePatternValue === "string" ? outputFilePatternValue : defaultPattern;
|
|
2346
|
-
const sanitizedStep1 = configOutputFilePattern.replaceAll("..", "/").replaceAll(/\/+/g, "/");
|
|
2347
|
-
const outputFilePattern = trim(sanitizedStep1, "/");
|
|
2348
|
-
if (outputFilePattern !== configOutputFilePattern) {
|
|
2349
|
-
$warnings.push(
|
|
2350
|
-
`Due to invalid filepath 'outputFilePattern' changed to '${outputFilePattern}'`
|
|
2351
|
-
);
|
|
2352
|
-
}
|
|
2353
|
-
if (config.reExportAll !== void 0 && config.reExportAll !== null && config.reExportAll !== false) {
|
|
2354
|
-
$warnings.push(`Option 'reExportAll' is deprecated, use 'reExport' instead`);
|
|
2355
|
-
if (toBoolean(config.reExportAll)) {
|
|
2356
|
-
config.reExport = "All";
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
const fields = Object.fromEntries(
|
|
2360
|
-
Object.entries(
|
|
2361
|
-
config.fields ?? {}
|
|
2362
|
-
).filter(({ 1: value }) => typeof value === "object").map(([name, value]) => {
|
|
2363
|
-
const fieldSetting = {
|
|
2364
|
-
arguments: [],
|
|
2365
|
-
defaultImport: toBoolean(value.defaultImport) ? true : value.defaultImport,
|
|
2366
|
-
from: value.from,
|
|
2367
|
-
input: toBoolean(value.input),
|
|
2368
|
-
model: toBoolean(value.model),
|
|
2369
|
-
namespaceImport: value.namespaceImport,
|
|
2370
|
-
output: toBoolean(value.output)
|
|
2371
|
-
};
|
|
2372
|
-
return [name, fieldSetting];
|
|
2373
|
-
})
|
|
2374
|
-
);
|
|
2375
|
-
const decorate = [];
|
|
2376
|
-
const decorateConfig = config.decorate !== void 0 && config.decorate !== null ? config.decorate : {};
|
|
2377
|
-
const configDecorate = Object.values(decorateConfig);
|
|
2378
|
-
for (const element of configDecorate) {
|
|
2379
|
-
if (element === void 0 || element === null) {
|
|
2380
|
-
continue;
|
|
2381
|
-
}
|
|
2382
|
-
ok(
|
|
2383
|
-
element.from !== void 0 && element.from !== "" && element.name !== void 0 && element.name !== "",
|
|
2384
|
-
`Missed 'from' or 'name' part in configuration for decorate`
|
|
2385
|
-
);
|
|
2386
|
-
decorate.push({
|
|
2387
|
-
arguments: element.arguments !== void 0 && element.arguments !== "" ? JSON52.parse(element.arguments) : void 0,
|
|
2388
|
-
defaultImport: toBoolean(element.defaultImport) ? true : element.defaultImport,
|
|
2389
|
-
from: element.from,
|
|
2390
|
-
isMatchField: outmatch2(element.field, { separator: false }),
|
|
2391
|
-
isMatchType: outmatch2(element.type, { separator: false }),
|
|
2392
|
-
name: element.name,
|
|
2393
|
-
namedImport: toBoolean(element.namedImport),
|
|
2394
|
-
namespaceImport: element.namespaceImport
|
|
2395
|
-
});
|
|
2396
|
-
}
|
|
2397
|
-
const customImport = [];
|
|
2398
|
-
const customImportConfig = config.customImport !== void 0 && config.customImport !== null ? config.customImport : {};
|
|
2399
|
-
const configCustomImport = Object.values(customImportConfig);
|
|
2400
|
-
for (const element of configCustomImport) {
|
|
2401
|
-
if (element === void 0 || element === null) {
|
|
2402
|
-
continue;
|
|
2403
|
-
}
|
|
2404
|
-
ok(
|
|
2405
|
-
element.from !== void 0 && element.from !== "" && element.name !== void 0 && element.name !== "",
|
|
2406
|
-
`Missed 'from' or 'name' part in configuration for customImport`
|
|
2407
|
-
);
|
|
2408
|
-
customImport.push({
|
|
2409
|
-
defaultImport: toBoolean(element.defaultImport) ? true : element.defaultImport,
|
|
2410
|
-
from: element.from,
|
|
2411
|
-
name: element.name,
|
|
2412
|
-
namedImport: toBoolean(element.namedImport),
|
|
2413
|
-
namespaceImport: element.namespaceImport
|
|
2414
|
-
});
|
|
2415
|
-
}
|
|
2416
|
-
return {
|
|
2417
|
-
$warnings,
|
|
2418
|
-
combineScalarFilters: toBoolean(config.combineScalarFilters),
|
|
2419
|
-
customImport,
|
|
2420
|
-
decorate,
|
|
2421
|
-
emitBlocks: createEmitBlocks(config.emitBlocks),
|
|
2422
|
-
emitCompiled: toBoolean(config.emitCompiled),
|
|
2423
|
-
emitSingle: toBoolean(config.emitSingle),
|
|
2424
|
-
esmCompatible: toBoolean(config.esmCompatible),
|
|
2425
|
-
fields,
|
|
2426
|
-
graphqlScalars: config.graphqlScalars ?? {},
|
|
2427
|
-
noAtomicOperations: toBoolean(config.noAtomicOperations),
|
|
2428
|
-
noTypeId: toBoolean(config.noTypeId),
|
|
2429
|
-
omitModelsCount: toBoolean(config.omitModelsCount),
|
|
2430
|
-
outputFilePattern,
|
|
2431
|
-
prismaClientImport: createPrismaImport(config.prismaClientImport),
|
|
2432
|
-
purgeOutput: toBoolean(config.purgeOutput),
|
|
2433
|
-
reExport: ReExport[String(config.reExport)] ?? "None" /* None */,
|
|
2434
|
-
requireSingleFieldsInWhereUniqueInput: toBoolean(
|
|
2435
|
-
config.requireSingleFieldsInWhereUniqueInput
|
|
2436
|
-
),
|
|
2437
|
-
tsConfigFilePath: createTsConfigFilePathValue(config.tsConfigFilePath),
|
|
2438
|
-
unsafeCompatibleWhereUniqueInput: toBoolean(config.unsafeCompatibleWhereUniqueInput),
|
|
2439
|
-
useInputType: createUseInputType(
|
|
2440
|
-
config.useInputType
|
|
2441
|
-
)
|
|
2442
|
-
};
|
|
2443
|
-
}
|
|
2444
|
-
var existsSyncTyped = existsSync;
|
|
2445
|
-
var tsConfigFileExistsRaw = memoize((filePath) => {
|
|
2446
|
-
const exists = existsSyncTyped(filePath);
|
|
2447
|
-
return exists;
|
|
2448
|
-
});
|
|
2449
|
-
var tsConfigFileExists = tsConfigFileExistsRaw;
|
|
2450
|
-
function createTsConfigFilePathValue(value) {
|
|
2451
|
-
if (typeof value === "string" && value !== "") {
|
|
2452
|
-
return value;
|
|
2453
|
-
}
|
|
2454
|
-
const fileExists = tsConfigFileExists("tsconfig.json");
|
|
2455
|
-
if (fileExists) {
|
|
2456
|
-
return "tsconfig.json";
|
|
2457
|
-
}
|
|
2458
|
-
return void 0;
|
|
2459
|
-
}
|
|
2460
|
-
function createPrismaImport(value) {
|
|
2461
|
-
if (typeof value === "string" && value !== "") {
|
|
2462
|
-
return value;
|
|
2463
|
-
}
|
|
2464
|
-
return "@prisma/client";
|
|
2465
|
-
}
|
|
2466
|
-
function createUseInputType(data) {
|
|
2467
|
-
if (data === void 0 || data === null) {
|
|
2468
|
-
return [];
|
|
2469
|
-
}
|
|
2470
|
-
const result = [];
|
|
2471
|
-
for (const [typeName, useInputs] of Object.entries(data)) {
|
|
2472
|
-
const entry = {
|
|
2473
|
-
ALL: void 0,
|
|
2474
|
-
typeName
|
|
2475
|
-
};
|
|
2476
|
-
if (useInputs.ALL !== void 0 && useInputs.ALL !== "") {
|
|
2477
|
-
entry.ALL = useInputs.ALL;
|
|
2478
|
-
delete useInputs.ALL;
|
|
2479
|
-
}
|
|
2480
|
-
for (const [propertyName, pattern] of Object.entries(useInputs)) {
|
|
2481
|
-
entry[propertyName] = pattern;
|
|
2482
|
-
}
|
|
2483
|
-
result.push(entry);
|
|
2484
|
-
}
|
|
2485
|
-
return result;
|
|
2486
|
-
}
|
|
2487
|
-
function toBoolean(value) {
|
|
2488
|
-
return ["true", "1", "on"].includes(String(value));
|
|
2489
|
-
}
|
|
2490
|
-
function generateFileName(args) {
|
|
2491
|
-
const { getModelName: getModelName2, name, template, type } = args;
|
|
2492
|
-
const rawPath = pupa(template, {
|
|
2493
|
-
get model() {
|
|
2494
|
-
const result = getModelName2(name) ?? "prisma";
|
|
2495
|
-
return kebabCase(result);
|
|
2496
|
-
},
|
|
2497
|
-
get name() {
|
|
2498
|
-
let result = kebabCase(name);
|
|
2499
|
-
for (const suffix of ["input", "args", "enum"]) {
|
|
2500
|
-
const ending = `-${suffix}`;
|
|
2501
|
-
if (type === suffix && result.endsWith(ending)) {
|
|
2502
|
-
result = result.slice(0, -ending.length);
|
|
141
|
+
else {
|
|
142
|
+
const msg = `nestjs-prisma-graphql: output directory not found after generation: ${outputPath}`;
|
|
143
|
+
log(msg);
|
|
144
|
+
throw new Error(msg);
|
|
2503
145
|
}
|
|
2504
|
-
}
|
|
2505
|
-
return result;
|
|
2506
146
|
},
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
type
|
|
2513
|
-
});
|
|
2514
|
-
return rawPath.split("/").map((segment) => filenamify(segment, { replacement: "-" })).join("/");
|
|
2515
|
-
}
|
|
2516
|
-
|
|
2517
|
-
// src/helpers/factory-get-source-file.ts
|
|
2518
|
-
function factoryGetSourceFile(args) {
|
|
2519
|
-
const { getModelName: getModelName2, output, outputFilePattern, project } = args;
|
|
2520
|
-
return function getSourceFile(getSourceFileArgs) {
|
|
2521
|
-
const { name, type } = getSourceFileArgs;
|
|
2522
|
-
let filePath = generateFileName({
|
|
2523
|
-
getModelName: getModelName2,
|
|
2524
|
-
name,
|
|
2525
|
-
template: outputFilePattern,
|
|
2526
|
-
type
|
|
2527
|
-
});
|
|
2528
|
-
filePath = `${output}/${filePath}`;
|
|
2529
|
-
return project.getSourceFile(filePath) ?? project.createSourceFile(filePath, void 0, { overwrite: true });
|
|
2530
|
-
};
|
|
2531
|
-
}
|
|
2532
|
-
var splitKeywords = [
|
|
2533
|
-
"CreateInput",
|
|
2534
|
-
"CreateMany",
|
|
2535
|
-
"CreateNested",
|
|
2536
|
-
"CreateOneWithout",
|
|
2537
|
-
"CreateOrConnect",
|
|
2538
|
-
"CreateWithout",
|
|
2539
|
-
"DistinctField",
|
|
2540
|
-
"Filter",
|
|
2541
|
-
"ManyWithout",
|
|
2542
|
-
"OrderByInput",
|
|
2543
|
-
"RelationFilter",
|
|
2544
|
-
"NullableRelationFilter",
|
|
2545
|
-
"ListRelationFilter",
|
|
2546
|
-
"ScalarWhereInput",
|
|
2547
|
-
"UpdateInput",
|
|
2548
|
-
"UpdateMany",
|
|
2549
|
-
"UpdateOneRequiredWithout",
|
|
2550
|
-
"UpdateOneWithout",
|
|
2551
|
-
"UpdateWith",
|
|
2552
|
-
"UpsertWith",
|
|
2553
|
-
"UpsertWithout",
|
|
2554
|
-
"WhereInput",
|
|
2555
|
-
"WhereUniqueInput",
|
|
2556
|
-
"AvgAggregate",
|
|
2557
|
-
"SumAggregate",
|
|
2558
|
-
"MinAggregate",
|
|
2559
|
-
"MaxAggregate",
|
|
2560
|
-
"CountAggregate",
|
|
2561
|
-
"ScalarField",
|
|
2562
|
-
"GroupBy",
|
|
2563
|
-
"OrderBy",
|
|
2564
|
-
"UncheckedUpdate",
|
|
2565
|
-
"UncheckedCreate",
|
|
2566
|
-
"ScalarWhere",
|
|
2567
|
-
"CountOutputType",
|
|
2568
|
-
"CountOrderBy",
|
|
2569
|
-
"SumOrderBy",
|
|
2570
|
-
"MinOrderBy",
|
|
2571
|
-
"MaxOrderBy",
|
|
2572
|
-
"AvgOrderBy",
|
|
2573
|
-
"Create",
|
|
2574
|
-
"Update",
|
|
2575
|
-
"ScalarRelationFilter",
|
|
2576
|
-
"NullableScalarRelationFilter"
|
|
2577
|
-
].sort((a, b) => b.length - a.length);
|
|
2578
|
-
var endsWithKeywords = [
|
|
2579
|
-
"Aggregate",
|
|
2580
|
-
"GroupBy",
|
|
2581
|
-
"CreateOne",
|
|
2582
|
-
"CreateMany",
|
|
2583
|
-
"DeleteMany",
|
|
2584
|
-
"DeleteOne",
|
|
2585
|
-
"FindMany",
|
|
2586
|
-
"FindOne",
|
|
2587
|
-
"FindUnique",
|
|
2588
|
-
"UpdateMany",
|
|
2589
|
-
"UpdateOne",
|
|
2590
|
-
"UpsertOne"
|
|
2591
|
-
];
|
|
2592
|
-
var middleKeywords = [
|
|
2593
|
-
["FindFirst", "OrThrowArgs"],
|
|
2594
|
-
["FindUnique", "OrThrowArgs"],
|
|
2595
|
-
["Aggregate", "Args"],
|
|
2596
|
-
["CreateOne", "Args"],
|
|
2597
|
-
["CreateMany", "Args"],
|
|
2598
|
-
["DeleteMany", "Args"],
|
|
2599
|
-
["DeleteOne", "Args"],
|
|
2600
|
-
["FindMany", "Args"],
|
|
2601
|
-
["FindFirst", "Args"],
|
|
2602
|
-
["FindOne", "Args"],
|
|
2603
|
-
["FindUnique", "Args"],
|
|
2604
|
-
["UpdateMany", "Args"],
|
|
2605
|
-
["UpdateMany", "AndReturnOutputType"],
|
|
2606
|
-
["UpdateOne", "Args"],
|
|
2607
|
-
["UpsertOne", "Args"],
|
|
2608
|
-
["GroupBy", "Args"],
|
|
2609
|
-
["OrderBy", "Args"]
|
|
2610
|
-
];
|
|
2611
|
-
function createGetModelName(modelNames) {
|
|
2612
|
-
return memoize(tryGetName);
|
|
2613
|
-
function tryGetName(name) {
|
|
2614
|
-
return getModelName({ modelNames, name });
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
function getModelName(args) {
|
|
2618
|
-
const { modelNames, name } = args;
|
|
2619
|
-
for (const keyword of splitKeywords) {
|
|
2620
|
-
const [test] = name.split(keyword, 1);
|
|
2621
|
-
if (test !== void 0 && modelNames.includes(test)) {
|
|
2622
|
-
return test;
|
|
2623
|
-
}
|
|
2624
|
-
}
|
|
2625
|
-
for (const keyword of endsWithKeywords) {
|
|
2626
|
-
const test = name.split(keyword).at(-1);
|
|
2627
|
-
if (test !== void 0 && modelNames.includes(test)) {
|
|
2628
|
-
return test;
|
|
2629
|
-
}
|
|
2630
|
-
}
|
|
2631
|
-
for (const [start, end2] of middleKeywords) {
|
|
2632
|
-
let test = name.slice(start.length).slice(0, -end2.length);
|
|
2633
|
-
if (modelNames.includes(test) && name.startsWith(start) && name.endsWith(end2)) {
|
|
2634
|
-
return test;
|
|
2635
|
-
}
|
|
2636
|
-
test = name.slice(0, -(start + end2).length);
|
|
2637
|
-
if (modelNames.includes(test) && name.endsWith(start + end2)) {
|
|
2638
|
-
return test;
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
if (name.endsWith("CompoundUniqueInput")) {
|
|
2642
|
-
const test = name.slice(0, -19);
|
|
2643
|
-
const models = modelNames.filter((x) => test.startsWith(x)).sort((a, b) => b.length - a.length);
|
|
2644
|
-
return models[0];
|
|
2645
|
-
}
|
|
2646
|
-
if (name.endsWith("Count")) {
|
|
2647
|
-
const test = name.slice(0, -5);
|
|
2648
|
-
if (modelNames.includes(test)) {
|
|
2649
|
-
return test;
|
|
2650
|
-
}
|
|
2651
|
-
}
|
|
2652
|
-
return void 0;
|
|
2653
|
-
}
|
|
2654
|
-
|
|
2655
|
-
// src/generate.ts
|
|
2656
|
-
var createRequireTyped = createRequire;
|
|
2657
|
-
var requireCjs = createRequireTyped(String(import.meta.url));
|
|
2658
|
-
var AwaitEventEmitter = requireCjs(
|
|
2659
|
-
"await-event-emitter"
|
|
2660
|
-
);
|
|
2661
|
-
var AwaitEventEmitterClass = AwaitEventEmitter.default;
|
|
2662
|
-
async function generate(args) {
|
|
2663
|
-
const { connectCallback, dmmf, generator, skipAddOutputSourceFiles } = args;
|
|
2664
|
-
const generatorOutputValue = generator.output?.value ?? "";
|
|
2665
|
-
ok(generatorOutputValue !== "", "Missing generator configuration: output");
|
|
2666
|
-
const config = createConfig(generator.config);
|
|
2667
|
-
const eventEmitter = new AwaitEventEmitterClass();
|
|
2668
|
-
eventEmitter.on("Warning", warning);
|
|
2669
|
-
if (config.emitBlocks.models) {
|
|
2670
|
-
eventEmitter.on("Model", modelData);
|
|
2671
|
-
}
|
|
2672
|
-
if (config.emitBlocks.prismaEnums || config.emitBlocks.schemaEnums) {
|
|
2673
|
-
eventEmitter.on("EnumType", registerEnum);
|
|
2674
|
-
}
|
|
2675
|
-
if (config.emitBlocks.outputs || config.emitBlocks.models && !config.omitModelsCount) {
|
|
2676
|
-
eventEmitter.on("OutputType", outputType);
|
|
2677
|
-
}
|
|
2678
|
-
if (config.emitBlocks.models) {
|
|
2679
|
-
eventEmitter.on("ModelOutputType", modelOutputType);
|
|
2680
|
-
}
|
|
2681
|
-
if (config.emitBlocks.outputs) {
|
|
2682
|
-
eventEmitter.on("AggregateOutput", createAggregateInput);
|
|
2683
|
-
}
|
|
2684
|
-
if (config.emitBlocks.inputs) {
|
|
2685
|
-
eventEmitter.on("InputType", inputType);
|
|
2686
|
-
}
|
|
2687
|
-
if (config.emitBlocks.args) {
|
|
2688
|
-
eventEmitter.on("ArgsType", argsType);
|
|
2689
|
-
}
|
|
2690
|
-
eventEmitter.on("GenerateFiles", generateFiles);
|
|
2691
|
-
for (const message of config.$warnings) {
|
|
2692
|
-
eventEmitter.emitSync("Warning", message);
|
|
2693
|
-
}
|
|
2694
|
-
const project = new Project({
|
|
2695
|
-
manipulationSettings: {
|
|
2696
|
-
quoteKind: QuoteKind.Single
|
|
147
|
+
onManifest() {
|
|
148
|
+
return {
|
|
149
|
+
defaultOutput: '.',
|
|
150
|
+
prettyName: 'NestJS Prisma GraphQL (ESM)',
|
|
151
|
+
};
|
|
2697
152
|
},
|
|
2698
|
-
skipAddingFilesFromTsConfig: true,
|
|
2699
|
-
skipLoadingLibFiles: !config.emitCompiled,
|
|
2700
|
-
tsConfigFilePath: config.tsConfigFilePath
|
|
2701
|
-
});
|
|
2702
|
-
if (skipAddOutputSourceFiles !== true) {
|
|
2703
|
-
project.addSourceFilesAtPaths([
|
|
2704
|
-
`${generatorOutputValue}/**/*.ts`,
|
|
2705
|
-
`!${generatorOutputValue}/**/*.d.ts`
|
|
2706
|
-
]);
|
|
2707
|
-
}
|
|
2708
|
-
if (config.combineScalarFilters) {
|
|
2709
|
-
combineScalarFilters(eventEmitter);
|
|
2710
|
-
}
|
|
2711
|
-
if (config.noAtomicOperations) {
|
|
2712
|
-
noAtomicOperations(eventEmitter);
|
|
2713
|
-
}
|
|
2714
|
-
if (config.reExport !== "None" /* None */) {
|
|
2715
|
-
reExport(eventEmitter);
|
|
2716
|
-
}
|
|
2717
|
-
if (config.emitSingle) {
|
|
2718
|
-
emitSingle(eventEmitter);
|
|
2719
|
-
}
|
|
2720
|
-
if (config.purgeOutput) {
|
|
2721
|
-
purgeOutput(eventEmitter);
|
|
2722
|
-
}
|
|
2723
|
-
if (config.requireSingleFieldsInWhereUniqueInput) {
|
|
2724
|
-
requireSingleFieldsInWhereUniqueInput(eventEmitter);
|
|
2725
|
-
}
|
|
2726
|
-
const models = /* @__PURE__ */ new Map();
|
|
2727
|
-
const modelNames = [];
|
|
2728
|
-
const modelFields = /* @__PURE__ */ new Map();
|
|
2729
|
-
const fieldSettings = /* @__PURE__ */ new Map();
|
|
2730
|
-
const getModelName2 = createGetModelName(modelNames);
|
|
2731
|
-
const getSourceFile = factoryGetSourceFile({
|
|
2732
|
-
getModelName: getModelName2,
|
|
2733
|
-
output: generatorOutputValue,
|
|
2734
|
-
outputFilePattern: config.outputFilePattern,
|
|
2735
|
-
project
|
|
2736
|
-
});
|
|
2737
|
-
const { datamodel, schema } = JSON.parse(JSON.stringify(dmmf));
|
|
2738
|
-
const removeTypes = /* @__PURE__ */ new Set();
|
|
2739
|
-
const datamodelTypes = datamodel.types ?? [];
|
|
2740
|
-
const allModels = [...datamodel.models, ...datamodelTypes];
|
|
2741
|
-
const dependencyGraph = buildDependencyGraph(allModels);
|
|
2742
|
-
const circularDependencies = detectCircularDependencies(dependencyGraph);
|
|
2743
|
-
const eventArguments = {
|
|
2744
|
-
circularDependencies,
|
|
2745
|
-
classTransformerTypeModels: /* @__PURE__ */ new Set(),
|
|
2746
|
-
config,
|
|
2747
|
-
enums: mapKeys(datamodel.enums, (x) => x.name),
|
|
2748
|
-
eventEmitter,
|
|
2749
|
-
fieldSettings,
|
|
2750
|
-
getModelName: getModelName2,
|
|
2751
|
-
getSourceFile,
|
|
2752
|
-
modelFields,
|
|
2753
|
-
modelNames,
|
|
2754
|
-
models,
|
|
2755
|
-
output: generatorOutputValue,
|
|
2756
|
-
project,
|
|
2757
|
-
removeTypes,
|
|
2758
|
-
schema,
|
|
2759
|
-
typeNames: /* @__PURE__ */ new Set()
|
|
2760
|
-
};
|
|
2761
|
-
if (connectCallback) {
|
|
2762
|
-
await connectCallback(eventEmitter, eventArguments);
|
|
2763
|
-
}
|
|
2764
|
-
await eventEmitter.emit("Begin", eventArguments);
|
|
2765
|
-
if (config.esmCompatible) {
|
|
2766
|
-
generateTypeRegistry(eventArguments);
|
|
2767
|
-
}
|
|
2768
|
-
generateDecimalHelpers(eventArguments);
|
|
2769
|
-
for (const model of datamodel.models) {
|
|
2770
|
-
await eventEmitter.emit("Model", model, eventArguments);
|
|
2771
|
-
}
|
|
2772
|
-
for (const model of datamodelTypes) {
|
|
2773
|
-
await eventEmitter.emit("Model", model, eventArguments);
|
|
2774
|
-
}
|
|
2775
|
-
const { enumTypes, inputObjectTypes, outputObjectTypes } = schema;
|
|
2776
|
-
await eventEmitter.emit("PostBegin", eventArguments);
|
|
2777
|
-
for (const enumType of enumTypes.prisma.concat(enumTypes.model ?? [])) {
|
|
2778
|
-
await eventEmitter.emit("EnumType", enumType, eventArguments);
|
|
2779
|
-
}
|
|
2780
|
-
for (const outputTypeItem of outputObjectTypes.model) {
|
|
2781
|
-
await eventEmitter.emit("ModelOutputType", outputTypeItem, eventArguments);
|
|
2782
|
-
}
|
|
2783
|
-
const queryOutputTypes = [];
|
|
2784
|
-
for (const outputTypeItem of outputObjectTypes.prisma) {
|
|
2785
|
-
if (["Query", "Mutation"].includes(outputTypeItem.name)) {
|
|
2786
|
-
queryOutputTypes.push(outputTypeItem);
|
|
2787
|
-
continue;
|
|
2788
|
-
}
|
|
2789
|
-
await eventEmitter.emit("OutputType", outputTypeItem, eventArguments);
|
|
2790
|
-
}
|
|
2791
|
-
const inputTypes = (inputObjectTypes.prisma ?? []).concat(inputObjectTypes.model ?? []);
|
|
2792
|
-
for (const inputTypeItem of inputTypes) {
|
|
2793
|
-
const event = {
|
|
2794
|
-
...eventArguments,
|
|
2795
|
-
classDecoratorName: "InputType",
|
|
2796
|
-
fileType: "input",
|
|
2797
|
-
inputType: inputTypeItem
|
|
2798
|
-
};
|
|
2799
|
-
if (inputTypeItem.fields.length === 0) {
|
|
2800
|
-
removeTypes.add(inputTypeItem.name);
|
|
2801
|
-
continue;
|
|
2802
|
-
}
|
|
2803
|
-
await eventEmitter.emit("BeforeInputType", event);
|
|
2804
|
-
await eventEmitter.emit("InputType", event);
|
|
2805
|
-
}
|
|
2806
|
-
for (const outputTypeItem of queryOutputTypes) {
|
|
2807
|
-
for (const field of outputTypeItem.fields) {
|
|
2808
|
-
await eventEmitter.emit("ArgsType", field, eventArguments);
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
|
-
if (config.esmCompatible) {
|
|
2812
|
-
generateRegisterAllTypes(eventArguments);
|
|
2813
|
-
}
|
|
2814
|
-
await eventEmitter.emit("BeforeGenerateFiles", eventArguments);
|
|
2815
|
-
await eventEmitter.emit("GenerateFiles", eventArguments);
|
|
2816
|
-
await eventEmitter.emit("End", eventArguments);
|
|
2817
|
-
for (const name of Object.keys(
|
|
2818
|
-
eventEmitter._events
|
|
2819
|
-
)) {
|
|
2820
|
-
eventEmitter.off(name);
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
|
|
2824
|
-
// src/index.ts
|
|
2825
|
-
var createRequireTyped2 = createRequire;
|
|
2826
|
-
var requireCjs2 = createRequireTyped2(String(import.meta.url));
|
|
2827
|
-
var gracefulFsRaw = requireCjs2("graceful-fs");
|
|
2828
|
-
var gracefulFs = gracefulFsRaw;
|
|
2829
|
-
var nodeFsRaw = requireCjs2("fs");
|
|
2830
|
-
var nodeFs = nodeFsRaw;
|
|
2831
|
-
gracefulFs.gracefulify(nodeFs);
|
|
2832
|
-
var globalConsole2 = globalThis.console;
|
|
2833
|
-
var logError = (msg) => {
|
|
2834
|
-
globalConsole2.log(msg);
|
|
2835
|
-
};
|
|
2836
|
-
var processTyped = process;
|
|
2837
|
-
processTyped.on("unhandledRejection", (reason) => {
|
|
2838
|
-
logError(`nestjs-prisma-graphql: unhandled rejection: ${String(reason)}`);
|
|
2839
|
-
if (reason instanceof Error && typeof reason.stack === "string") {
|
|
2840
|
-
logError(reason.stack);
|
|
2841
|
-
}
|
|
2842
|
-
});
|
|
2843
|
-
processTyped.on("uncaughtException", (error) => {
|
|
2844
|
-
const err = error;
|
|
2845
|
-
logError(`nestjs-prisma-graphql: uncaught exception: ${err.message}`);
|
|
2846
|
-
if (typeof err.stack === "string") {
|
|
2847
|
-
logError(err.stack);
|
|
2848
|
-
}
|
|
2849
|
-
});
|
|
2850
|
-
var { generatorHandler } = generatorHelper;
|
|
2851
|
-
var getProcessEnv = () => {
|
|
2852
|
-
const globalProcess = process;
|
|
2853
|
-
const processLike = globalProcess;
|
|
2854
|
-
return processLike.env;
|
|
2855
|
-
};
|
|
2856
|
-
function isGeneratorDisabled(options, env = getProcessEnv()) {
|
|
2857
|
-
const envVarsToCheck = [
|
|
2858
|
-
"DISABLE_NESTJS_PRISMA_GRAPHQL",
|
|
2859
|
-
"CI_SKIP_PRISMA_GRAPHQL",
|
|
2860
|
-
"PRISMA_GENERATOR_SKIP",
|
|
2861
|
-
"SKIP_PRISMA_GENERATE"
|
|
2862
|
-
];
|
|
2863
|
-
for (const envVar of envVarsToCheck) {
|
|
2864
|
-
const value = env[envVar];
|
|
2865
|
-
if (value === "true" || value === "1") {
|
|
2866
|
-
return true;
|
|
2867
|
-
}
|
|
2868
|
-
}
|
|
2869
|
-
const configDisabled = options.generator.config.disabled;
|
|
2870
|
-
if (configDisabled === "true" || configDisabled === "1" || configDisabled === "yes") {
|
|
2871
|
-
return true;
|
|
2872
|
-
}
|
|
2873
|
-
return false;
|
|
2874
|
-
}
|
|
2875
|
-
function countFilesRecursive(dir) {
|
|
2876
|
-
let count = 0;
|
|
2877
|
-
const readDirSyncTyped = readdirSync;
|
|
2878
|
-
const rawEntries = readDirSyncTyped(dir, { withFileTypes: true });
|
|
2879
|
-
const entries = rawEntries;
|
|
2880
|
-
for (const entry of entries) {
|
|
2881
|
-
const isDir = typeof entry.isDirectory === "function" ? entry.isDirectory() : false;
|
|
2882
|
-
if (isDir) {
|
|
2883
|
-
count += countFilesRecursive(`${dir}/${entry.name}`);
|
|
2884
|
-
} else {
|
|
2885
|
-
count++;
|
|
2886
|
-
}
|
|
2887
|
-
}
|
|
2888
|
-
return count;
|
|
2889
|
-
}
|
|
2890
|
-
var globalConsole22 = globalThis.console;
|
|
2891
|
-
var log2 = (msg) => {
|
|
2892
|
-
globalConsole22.log(msg);
|
|
2893
|
-
};
|
|
2894
|
-
generatorHandler({
|
|
2895
|
-
async onGenerate(options) {
|
|
2896
|
-
if (isGeneratorDisabled(options)) {
|
|
2897
|
-
log2(
|
|
2898
|
-
"nestjs-prisma-graphql: generation skipped (disabled via environment variable or config)"
|
|
2899
|
-
);
|
|
2900
|
-
return;
|
|
2901
|
-
}
|
|
2902
|
-
const outputPath = options.generator.output?.value ?? "<unknown>";
|
|
2903
|
-
const startTime = Date.now();
|
|
2904
|
-
const archTyped = arch;
|
|
2905
|
-
const platformTyped = platform;
|
|
2906
|
-
const archValue = String(archTyped());
|
|
2907
|
-
const platformValue = String(platformTyped());
|
|
2908
|
-
const globalProcess2Raw = process;
|
|
2909
|
-
const processWithVersion = globalProcess2Raw;
|
|
2910
|
-
const nodeVersion = processWithVersion.version;
|
|
2911
|
-
log2(
|
|
2912
|
-
[
|
|
2913
|
-
"nestjs-prisma-graphql: starting generation",
|
|
2914
|
-
`(arch=${archValue}, platform=${platformValue}, node=${nodeVersion}, output=${outputPath})`
|
|
2915
|
-
].join(" ")
|
|
2916
|
-
);
|
|
2917
|
-
try {
|
|
2918
|
-
await generate(options);
|
|
2919
|
-
} catch (error) {
|
|
2920
|
-
const elapsed2 = Date.now() - startTime;
|
|
2921
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2922
|
-
const stack = error instanceof Error ? error.stack : void 0;
|
|
2923
|
-
log2(
|
|
2924
|
-
`nestjs-prisma-graphql: generation FAILED after ${String(elapsed2)}ms: ${message}`
|
|
2925
|
-
);
|
|
2926
|
-
if (typeof stack === "string") {
|
|
2927
|
-
log2(stack);
|
|
2928
|
-
}
|
|
2929
|
-
throw error;
|
|
2930
|
-
}
|
|
2931
|
-
const elapsed = Date.now() - startTime;
|
|
2932
|
-
const existsSyncTyped2 = existsSync;
|
|
2933
|
-
const pathExists = typeof outputPath === "string" && outputPath !== "<unknown>" && existsSyncTyped2(outputPath);
|
|
2934
|
-
if (pathExists) {
|
|
2935
|
-
const fileCount = countFilesRecursive(outputPath);
|
|
2936
|
-
log2(
|
|
2937
|
-
`nestjs-prisma-graphql: generated ${String(fileCount)} files in ${String(elapsed)}ms`
|
|
2938
|
-
);
|
|
2939
|
-
if (fileCount === 0) {
|
|
2940
|
-
const msg = "nestjs-prisma-graphql: generation produced 0 files \u2014 this likely indicates a silent failure";
|
|
2941
|
-
log2(msg);
|
|
2942
|
-
throw new Error(msg);
|
|
2943
|
-
}
|
|
2944
|
-
} else {
|
|
2945
|
-
const msg = `nestjs-prisma-graphql: output directory not found after generation: ${outputPath}`;
|
|
2946
|
-
log2(msg);
|
|
2947
|
-
throw new Error(msg);
|
|
2948
|
-
}
|
|
2949
|
-
},
|
|
2950
|
-
onManifest() {
|
|
2951
|
-
return {
|
|
2952
|
-
defaultOutput: ".",
|
|
2953
|
-
prettyName: "NestJS Prisma GraphQL (ESM)"
|
|
2954
|
-
};
|
|
2955
|
-
}
|
|
2956
153
|
});
|
|
2957
|
-
|
|
2958
|
-
export { isGeneratorDisabled };
|
|
2959
|
-
//# sourceMappingURL=index.js.map
|
|
2960
154
|
//# sourceMappingURL=index.js.map
|