@prisma/param-graph-builder 7.3.0-integration-parameterization.15 → 7.4.0-dev.22

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.
@@ -0,0 +1,367 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var dmmf_traverser_exports = {};
20
+ __export(dmmf_traverser_exports, {
21
+ DMMFTraverser: () => DMMFTraverser
22
+ });
23
+ module.exports = __toCommonJS(dmmf_traverser_exports);
24
+ var import_dmmf = require("@prisma/dmmf");
25
+ var import_param_graph = require("@prisma/param-graph");
26
+ class DMMFTraverser {
27
+ #builder;
28
+ #inputTypeMap;
29
+ #outputTypeMap;
30
+ #pendingInputNodes = [];
31
+ #pendingUnionNodes = [];
32
+ constructor(builder, dmmf) {
33
+ this.#builder = builder;
34
+ this.#inputTypeMap = /* @__PURE__ */ new Map();
35
+ this.#outputTypeMap = /* @__PURE__ */ new Map();
36
+ for (const inputType of dmmf.schema.inputObjectTypes.prisma ?? []) {
37
+ this.#inputTypeMap.set(getTypeName(inputType.name, "prisma"), inputType);
38
+ }
39
+ for (const inputType of dmmf.schema.inputObjectTypes.model ?? []) {
40
+ this.#inputTypeMap.set(getTypeName(inputType.name, "model"), inputType);
41
+ }
42
+ for (const outputType of dmmf.schema.outputObjectTypes.prisma ?? []) {
43
+ this.#outputTypeMap.set(getTypeName(outputType.name, "prisma"), outputType);
44
+ }
45
+ for (const outputType of dmmf.schema.outputObjectTypes.model ?? []) {
46
+ this.#outputTypeMap.set(getTypeName(outputType.name, "model"), outputType);
47
+ }
48
+ }
49
+ /**
50
+ * Process all root operations from model mappings.
51
+ */
52
+ processRoots(mappings) {
53
+ for (const mapping of mappings) {
54
+ const modelName = mapping.model;
55
+ const actions = Object.keys(import_dmmf.ModelAction);
56
+ for (const action of actions) {
57
+ const fieldName = mapping[action];
58
+ if (!fieldName) continue;
59
+ const rootField = this.#findRootField(fieldName);
60
+ if (!rootField) continue;
61
+ const argsNodeId = this.buildInputNodeFromArgs(rootField.args);
62
+ let outputNodeId;
63
+ if (rootField.outputType.location === "outputObjectTypes") {
64
+ outputNodeId = this.buildOutputTypeNode(
65
+ getTypeName(rootField.outputType.type, rootField.outputType.namespace)
66
+ );
67
+ }
68
+ const dmmfActionToJsonAction = {
69
+ create: "createOne",
70
+ update: "updateOne",
71
+ delete: "deleteOne",
72
+ upsert: "upsertOne"
73
+ };
74
+ const jsonAction = dmmfActionToJsonAction[action] ?? action;
75
+ const rootKey = `${modelName}.${jsonAction}`;
76
+ this.#builder.setRoot(rootKey, {
77
+ argsNodeId,
78
+ outputNodeId
79
+ });
80
+ }
81
+ }
82
+ this.#drainPendingWork();
83
+ }
84
+ /**
85
+ * Iteratively processes all pending input and union nodes.
86
+ * This avoids deep recursion that can cause stack overflow on complex schemas.
87
+ */
88
+ #drainPendingWork() {
89
+ while (this.#pendingInputNodes.length > 0 || this.#pendingUnionNodes.length > 0) {
90
+ while (this.#pendingInputNodes.length > 0) {
91
+ const pending = this.#pendingInputNodes.pop();
92
+ this.#processInputNodeFields(pending.nodeId, pending.fields);
93
+ }
94
+ while (this.#pendingUnionNodes.length > 0) {
95
+ const pending = this.#pendingUnionNodes.pop();
96
+ this.#processUnionNodeFields(pending.nodeId, pending.typeNames);
97
+ }
98
+ }
99
+ }
100
+ #findRootField(fieldName) {
101
+ const queryType = this.#outputTypeMap.get("prisma.Query");
102
+ if (queryType) {
103
+ const field = queryType.fields.find((f) => f.name === fieldName);
104
+ if (field) return field;
105
+ }
106
+ const mutationType = this.#outputTypeMap.get("prisma.Mutation");
107
+ if (mutationType) {
108
+ const field = mutationType.fields.find((f) => f.name === fieldName);
109
+ if (field) return field;
110
+ }
111
+ return void 0;
112
+ }
113
+ /**
114
+ * Builds an input node from schema arguments.
115
+ */
116
+ buildInputNodeFromArgs(args) {
117
+ const edges = {};
118
+ let hasAnyEdge = false;
119
+ for (const arg of args) {
120
+ const edge = this.#mergeFieldVariants([arg]);
121
+ if (edge) {
122
+ const stringIndex = this.#builder.internString(arg.name);
123
+ edges[stringIndex] = edge;
124
+ hasAnyEdge = true;
125
+ }
126
+ }
127
+ if (!hasAnyEdge) {
128
+ return void 0;
129
+ }
130
+ const nodeId = this.#builder.allocateInputNode();
131
+ this.#builder.setInputNodeEdges(nodeId, edges);
132
+ return nodeId;
133
+ }
134
+ /**
135
+ * Builds an input node for a named input type.
136
+ * Node allocation happens immediately, but field processing is deferred
137
+ * to avoid deep recursion.
138
+ */
139
+ buildInputTypeNode(typeName) {
140
+ if (this.#builder.hasInputTypeNode(typeName)) {
141
+ return this.#builder.getInputTypeNode(typeName);
142
+ }
143
+ const inputType = this.#inputTypeMap.get(typeName);
144
+ if (!inputType) {
145
+ this.#builder.setInputTypeNode(typeName, void 0);
146
+ return void 0;
147
+ }
148
+ const nodeId = this.#builder.allocateInputNode();
149
+ this.#builder.setInputTypeNode(typeName, nodeId);
150
+ this.#pendingInputNodes.push({ nodeId, fields: inputType.fields });
151
+ return nodeId;
152
+ }
153
+ /**
154
+ * Process fields for an input node (called from drainPendingWork).
155
+ */
156
+ #processInputNodeFields(nodeId, fields) {
157
+ const edges = {};
158
+ let hasAnyEdge = false;
159
+ for (const field of fields) {
160
+ const edge = this.#mergeFieldVariants([field]);
161
+ if (edge) {
162
+ const stringIndex = this.#builder.internString(field.name);
163
+ edges[stringIndex] = edge;
164
+ hasAnyEdge = true;
165
+ }
166
+ }
167
+ if (hasAnyEdge) {
168
+ this.#builder.setInputNodeEdges(nodeId, edges);
169
+ }
170
+ }
171
+ /**
172
+ * Builds a union node for multiple input types.
173
+ * Node allocation happens immediately, but field processing is deferred
174
+ * to avoid deep recursion.
175
+ */
176
+ buildUnionNode(typeNames) {
177
+ const sortedNames = [...typeNames].sort();
178
+ const cacheKey = sortedNames.join("|");
179
+ if (this.#builder.hasUnionNode(cacheKey)) {
180
+ return this.#builder.getUnionNode(cacheKey);
181
+ }
182
+ const nodeId = this.#builder.allocateInputNode();
183
+ this.#builder.setUnionNode(cacheKey, nodeId);
184
+ this.#pendingUnionNodes.push({ nodeId, typeNames });
185
+ return nodeId;
186
+ }
187
+ /**
188
+ * Process fields for a union node (called from drainPendingWork).
189
+ */
190
+ #processUnionNodeFields(nodeId, typeNames) {
191
+ const fieldsByName = /* @__PURE__ */ new Map();
192
+ for (const typeName of typeNames) {
193
+ const inputType = this.#inputTypeMap.get(typeName);
194
+ if (!inputType) continue;
195
+ for (const field of inputType.fields) {
196
+ let fieldsForName = fieldsByName.get(field.name);
197
+ if (!fieldsForName) {
198
+ fieldsForName = [];
199
+ fieldsByName.set(field.name, fieldsForName);
200
+ }
201
+ fieldsForName.push(field);
202
+ }
203
+ }
204
+ const mergedEdges = {};
205
+ let hasAnyEdge = false;
206
+ for (const [fieldName, variantFields] of fieldsByName) {
207
+ const mergedEdge = this.#mergeFieldVariants(variantFields);
208
+ if (mergedEdge) {
209
+ const stringIndex = this.#builder.internString(fieldName);
210
+ mergedEdges[stringIndex] = mergedEdge;
211
+ hasAnyEdge = true;
212
+ }
213
+ }
214
+ if (hasAnyEdge) {
215
+ this.#builder.setInputNodeEdges(nodeId, mergedEdges);
216
+ }
217
+ }
218
+ /**
219
+ * Merges field variants to produce a single edge descriptor.
220
+ * This is the most complex part of the traversal - it handles
221
+ * union types and determines what kinds of values a field accepts.
222
+ */
223
+ #mergeFieldVariants(variants) {
224
+ let flags = 0;
225
+ let scalarMask = 0;
226
+ let childNodeId;
227
+ let enumNameIndex;
228
+ const scalarTypes = [];
229
+ const enumTypes = [];
230
+ const inputObjectTypes = [];
231
+ for (const variant of variants) {
232
+ for (const inputType of variant.inputTypes) {
233
+ switch (inputType.location) {
234
+ case "scalar":
235
+ if (variant.isParameterizable) {
236
+ scalarTypes.push(inputType);
237
+ }
238
+ break;
239
+ case "enumTypes":
240
+ if (variant.isParameterizable) {
241
+ enumTypes.push(inputType);
242
+ }
243
+ break;
244
+ case "inputObjectTypes":
245
+ if (!inputObjectTypes.some(
246
+ (ot) => ot.type === inputType.type && ot.namespace === inputType.namespace && ot.isList === inputType.isList
247
+ )) {
248
+ inputObjectTypes.push(inputType);
249
+ }
250
+ break;
251
+ case "fieldRefTypes":
252
+ break;
253
+ default:
254
+ throw new Error(`Invalid location ${inputType.location}`);
255
+ }
256
+ }
257
+ }
258
+ for (const st of scalarTypes) {
259
+ scalarMask |= (0, import_param_graph.scalarTypeToMask)(st.type);
260
+ if (st.isList) {
261
+ flags |= import_param_graph.EdgeFlag.ParamListScalar;
262
+ } else {
263
+ flags |= import_param_graph.EdgeFlag.ParamScalar;
264
+ }
265
+ }
266
+ for (const et of enumTypes) {
267
+ if (et.namespace === "model") {
268
+ enumNameIndex = this.#builder.internString(et.type);
269
+ if (et.isList) {
270
+ flags |= import_param_graph.EdgeFlag.ParamListEnum;
271
+ } else {
272
+ flags |= import_param_graph.EdgeFlag.ParamEnum;
273
+ }
274
+ break;
275
+ }
276
+ }
277
+ if (inputObjectTypes.length > 0) {
278
+ const hasObjectList = inputObjectTypes.some((iot) => iot.isList);
279
+ const hasSingleObject = inputObjectTypes.some((iot) => !iot.isList);
280
+ if (hasObjectList) {
281
+ flags |= import_param_graph.EdgeFlag.ListObject;
282
+ }
283
+ if (hasSingleObject) {
284
+ flags |= import_param_graph.EdgeFlag.Object;
285
+ }
286
+ if (inputObjectTypes.length === 1) {
287
+ childNodeId = this.buildInputTypeNode(getTypeName(inputObjectTypes[0].type, inputObjectTypes[0].namespace));
288
+ } else {
289
+ childNodeId = this.buildUnionNode(inputObjectTypes.map((iot) => getTypeName(iot.type, iot.namespace)));
290
+ }
291
+ }
292
+ if (flags === 0) {
293
+ return void 0;
294
+ }
295
+ const edge = { flags };
296
+ if (childNodeId !== void 0) {
297
+ edge.childNodeId = childNodeId;
298
+ }
299
+ if (scalarMask !== 0) {
300
+ edge.scalarMask = scalarMask;
301
+ }
302
+ if (enumNameIndex !== void 0) {
303
+ edge.enumNameIndex = enumNameIndex;
304
+ }
305
+ return edge;
306
+ }
307
+ /**
308
+ * Builds an output node for a named output type.
309
+ */
310
+ buildOutputTypeNode(typeName) {
311
+ if (this.#builder.hasOutputTypeNode(typeName)) {
312
+ return this.#builder.getOutputTypeNode(typeName);
313
+ }
314
+ const outputType = this.#outputTypeMap.get(typeName);
315
+ if (!outputType) {
316
+ this.#builder.setOutputTypeNode(typeName, void 0);
317
+ return void 0;
318
+ }
319
+ const nodeId = this.#builder.allocateOutputNode();
320
+ this.#builder.setOutputTypeNode(typeName, nodeId);
321
+ const edges = {};
322
+ let hasAnyEdge = false;
323
+ for (const field of outputType.fields) {
324
+ const edge = this.#buildOutputEdge(field);
325
+ if (edge) {
326
+ const stringIndex = this.#builder.internString(field.name);
327
+ edges[stringIndex] = edge;
328
+ hasAnyEdge = true;
329
+ }
330
+ }
331
+ if (hasAnyEdge) {
332
+ this.#builder.setOutputNodeEdges(nodeId, edges);
333
+ }
334
+ return nodeId;
335
+ }
336
+ #buildOutputEdge(field) {
337
+ let argsNodeId;
338
+ let outputNodeId;
339
+ if (field.args.length > 0) {
340
+ argsNodeId = this.buildInputNodeFromArgs(field.args);
341
+ }
342
+ if (field.outputType.location === "outputObjectTypes") {
343
+ outputNodeId = this.buildOutputTypeNode(getTypeName(field.outputType.type, field.outputType.namespace));
344
+ }
345
+ if (argsNodeId === void 0 && outputNodeId === void 0) {
346
+ return void 0;
347
+ }
348
+ const edge = {};
349
+ if (argsNodeId !== void 0) {
350
+ edge.argsNodeId = argsNodeId;
351
+ }
352
+ if (outputNodeId !== void 0) {
353
+ edge.outputNodeId = outputNodeId;
354
+ }
355
+ return edge;
356
+ }
357
+ }
358
+ function getTypeName(name, namespace) {
359
+ if (namespace === void 0) {
360
+ return name;
361
+ }
362
+ return `${namespace}.${name}`;
363
+ }
364
+ // Annotate the CommonJS export names for ESM import in node:
365
+ 0 && (module.exports = {
366
+ DMMFTraverser
367
+ });
@@ -0,0 +1,343 @@
1
+ import { ModelAction } from "@prisma/dmmf";
2
+ import { EdgeFlag, scalarTypeToMask } from "@prisma/param-graph";
3
+ class DMMFTraverser {
4
+ #builder;
5
+ #inputTypeMap;
6
+ #outputTypeMap;
7
+ #pendingInputNodes = [];
8
+ #pendingUnionNodes = [];
9
+ constructor(builder, dmmf) {
10
+ this.#builder = builder;
11
+ this.#inputTypeMap = /* @__PURE__ */ new Map();
12
+ this.#outputTypeMap = /* @__PURE__ */ new Map();
13
+ for (const inputType of dmmf.schema.inputObjectTypes.prisma ?? []) {
14
+ this.#inputTypeMap.set(getTypeName(inputType.name, "prisma"), inputType);
15
+ }
16
+ for (const inputType of dmmf.schema.inputObjectTypes.model ?? []) {
17
+ this.#inputTypeMap.set(getTypeName(inputType.name, "model"), inputType);
18
+ }
19
+ for (const outputType of dmmf.schema.outputObjectTypes.prisma ?? []) {
20
+ this.#outputTypeMap.set(getTypeName(outputType.name, "prisma"), outputType);
21
+ }
22
+ for (const outputType of dmmf.schema.outputObjectTypes.model ?? []) {
23
+ this.#outputTypeMap.set(getTypeName(outputType.name, "model"), outputType);
24
+ }
25
+ }
26
+ /**
27
+ * Process all root operations from model mappings.
28
+ */
29
+ processRoots(mappings) {
30
+ for (const mapping of mappings) {
31
+ const modelName = mapping.model;
32
+ const actions = Object.keys(ModelAction);
33
+ for (const action of actions) {
34
+ const fieldName = mapping[action];
35
+ if (!fieldName) continue;
36
+ const rootField = this.#findRootField(fieldName);
37
+ if (!rootField) continue;
38
+ const argsNodeId = this.buildInputNodeFromArgs(rootField.args);
39
+ let outputNodeId;
40
+ if (rootField.outputType.location === "outputObjectTypes") {
41
+ outputNodeId = this.buildOutputTypeNode(
42
+ getTypeName(rootField.outputType.type, rootField.outputType.namespace)
43
+ );
44
+ }
45
+ const dmmfActionToJsonAction = {
46
+ create: "createOne",
47
+ update: "updateOne",
48
+ delete: "deleteOne",
49
+ upsert: "upsertOne"
50
+ };
51
+ const jsonAction = dmmfActionToJsonAction[action] ?? action;
52
+ const rootKey = `${modelName}.${jsonAction}`;
53
+ this.#builder.setRoot(rootKey, {
54
+ argsNodeId,
55
+ outputNodeId
56
+ });
57
+ }
58
+ }
59
+ this.#drainPendingWork();
60
+ }
61
+ /**
62
+ * Iteratively processes all pending input and union nodes.
63
+ * This avoids deep recursion that can cause stack overflow on complex schemas.
64
+ */
65
+ #drainPendingWork() {
66
+ while (this.#pendingInputNodes.length > 0 || this.#pendingUnionNodes.length > 0) {
67
+ while (this.#pendingInputNodes.length > 0) {
68
+ const pending = this.#pendingInputNodes.pop();
69
+ this.#processInputNodeFields(pending.nodeId, pending.fields);
70
+ }
71
+ while (this.#pendingUnionNodes.length > 0) {
72
+ const pending = this.#pendingUnionNodes.pop();
73
+ this.#processUnionNodeFields(pending.nodeId, pending.typeNames);
74
+ }
75
+ }
76
+ }
77
+ #findRootField(fieldName) {
78
+ const queryType = this.#outputTypeMap.get("prisma.Query");
79
+ if (queryType) {
80
+ const field = queryType.fields.find((f) => f.name === fieldName);
81
+ if (field) return field;
82
+ }
83
+ const mutationType = this.#outputTypeMap.get("prisma.Mutation");
84
+ if (mutationType) {
85
+ const field = mutationType.fields.find((f) => f.name === fieldName);
86
+ if (field) return field;
87
+ }
88
+ return void 0;
89
+ }
90
+ /**
91
+ * Builds an input node from schema arguments.
92
+ */
93
+ buildInputNodeFromArgs(args) {
94
+ const edges = {};
95
+ let hasAnyEdge = false;
96
+ for (const arg of args) {
97
+ const edge = this.#mergeFieldVariants([arg]);
98
+ if (edge) {
99
+ const stringIndex = this.#builder.internString(arg.name);
100
+ edges[stringIndex] = edge;
101
+ hasAnyEdge = true;
102
+ }
103
+ }
104
+ if (!hasAnyEdge) {
105
+ return void 0;
106
+ }
107
+ const nodeId = this.#builder.allocateInputNode();
108
+ this.#builder.setInputNodeEdges(nodeId, edges);
109
+ return nodeId;
110
+ }
111
+ /**
112
+ * Builds an input node for a named input type.
113
+ * Node allocation happens immediately, but field processing is deferred
114
+ * to avoid deep recursion.
115
+ */
116
+ buildInputTypeNode(typeName) {
117
+ if (this.#builder.hasInputTypeNode(typeName)) {
118
+ return this.#builder.getInputTypeNode(typeName);
119
+ }
120
+ const inputType = this.#inputTypeMap.get(typeName);
121
+ if (!inputType) {
122
+ this.#builder.setInputTypeNode(typeName, void 0);
123
+ return void 0;
124
+ }
125
+ const nodeId = this.#builder.allocateInputNode();
126
+ this.#builder.setInputTypeNode(typeName, nodeId);
127
+ this.#pendingInputNodes.push({ nodeId, fields: inputType.fields });
128
+ return nodeId;
129
+ }
130
+ /**
131
+ * Process fields for an input node (called from drainPendingWork).
132
+ */
133
+ #processInputNodeFields(nodeId, fields) {
134
+ const edges = {};
135
+ let hasAnyEdge = false;
136
+ for (const field of fields) {
137
+ const edge = this.#mergeFieldVariants([field]);
138
+ if (edge) {
139
+ const stringIndex = this.#builder.internString(field.name);
140
+ edges[stringIndex] = edge;
141
+ hasAnyEdge = true;
142
+ }
143
+ }
144
+ if (hasAnyEdge) {
145
+ this.#builder.setInputNodeEdges(nodeId, edges);
146
+ }
147
+ }
148
+ /**
149
+ * Builds a union node for multiple input types.
150
+ * Node allocation happens immediately, but field processing is deferred
151
+ * to avoid deep recursion.
152
+ */
153
+ buildUnionNode(typeNames) {
154
+ const sortedNames = [...typeNames].sort();
155
+ const cacheKey = sortedNames.join("|");
156
+ if (this.#builder.hasUnionNode(cacheKey)) {
157
+ return this.#builder.getUnionNode(cacheKey);
158
+ }
159
+ const nodeId = this.#builder.allocateInputNode();
160
+ this.#builder.setUnionNode(cacheKey, nodeId);
161
+ this.#pendingUnionNodes.push({ nodeId, typeNames });
162
+ return nodeId;
163
+ }
164
+ /**
165
+ * Process fields for a union node (called from drainPendingWork).
166
+ */
167
+ #processUnionNodeFields(nodeId, typeNames) {
168
+ const fieldsByName = /* @__PURE__ */ new Map();
169
+ for (const typeName of typeNames) {
170
+ const inputType = this.#inputTypeMap.get(typeName);
171
+ if (!inputType) continue;
172
+ for (const field of inputType.fields) {
173
+ let fieldsForName = fieldsByName.get(field.name);
174
+ if (!fieldsForName) {
175
+ fieldsForName = [];
176
+ fieldsByName.set(field.name, fieldsForName);
177
+ }
178
+ fieldsForName.push(field);
179
+ }
180
+ }
181
+ const mergedEdges = {};
182
+ let hasAnyEdge = false;
183
+ for (const [fieldName, variantFields] of fieldsByName) {
184
+ const mergedEdge = this.#mergeFieldVariants(variantFields);
185
+ if (mergedEdge) {
186
+ const stringIndex = this.#builder.internString(fieldName);
187
+ mergedEdges[stringIndex] = mergedEdge;
188
+ hasAnyEdge = true;
189
+ }
190
+ }
191
+ if (hasAnyEdge) {
192
+ this.#builder.setInputNodeEdges(nodeId, mergedEdges);
193
+ }
194
+ }
195
+ /**
196
+ * Merges field variants to produce a single edge descriptor.
197
+ * This is the most complex part of the traversal - it handles
198
+ * union types and determines what kinds of values a field accepts.
199
+ */
200
+ #mergeFieldVariants(variants) {
201
+ let flags = 0;
202
+ let scalarMask = 0;
203
+ let childNodeId;
204
+ let enumNameIndex;
205
+ const scalarTypes = [];
206
+ const enumTypes = [];
207
+ const inputObjectTypes = [];
208
+ for (const variant of variants) {
209
+ for (const inputType of variant.inputTypes) {
210
+ switch (inputType.location) {
211
+ case "scalar":
212
+ if (variant.isParameterizable) {
213
+ scalarTypes.push(inputType);
214
+ }
215
+ break;
216
+ case "enumTypes":
217
+ if (variant.isParameterizable) {
218
+ enumTypes.push(inputType);
219
+ }
220
+ break;
221
+ case "inputObjectTypes":
222
+ if (!inputObjectTypes.some(
223
+ (ot) => ot.type === inputType.type && ot.namespace === inputType.namespace && ot.isList === inputType.isList
224
+ )) {
225
+ inputObjectTypes.push(inputType);
226
+ }
227
+ break;
228
+ case "fieldRefTypes":
229
+ break;
230
+ default:
231
+ throw new Error(`Invalid location ${inputType.location}`);
232
+ }
233
+ }
234
+ }
235
+ for (const st of scalarTypes) {
236
+ scalarMask |= scalarTypeToMask(st.type);
237
+ if (st.isList) {
238
+ flags |= EdgeFlag.ParamListScalar;
239
+ } else {
240
+ flags |= EdgeFlag.ParamScalar;
241
+ }
242
+ }
243
+ for (const et of enumTypes) {
244
+ if (et.namespace === "model") {
245
+ enumNameIndex = this.#builder.internString(et.type);
246
+ if (et.isList) {
247
+ flags |= EdgeFlag.ParamListEnum;
248
+ } else {
249
+ flags |= EdgeFlag.ParamEnum;
250
+ }
251
+ break;
252
+ }
253
+ }
254
+ if (inputObjectTypes.length > 0) {
255
+ const hasObjectList = inputObjectTypes.some((iot) => iot.isList);
256
+ const hasSingleObject = inputObjectTypes.some((iot) => !iot.isList);
257
+ if (hasObjectList) {
258
+ flags |= EdgeFlag.ListObject;
259
+ }
260
+ if (hasSingleObject) {
261
+ flags |= EdgeFlag.Object;
262
+ }
263
+ if (inputObjectTypes.length === 1) {
264
+ childNodeId = this.buildInputTypeNode(getTypeName(inputObjectTypes[0].type, inputObjectTypes[0].namespace));
265
+ } else {
266
+ childNodeId = this.buildUnionNode(inputObjectTypes.map((iot) => getTypeName(iot.type, iot.namespace)));
267
+ }
268
+ }
269
+ if (flags === 0) {
270
+ return void 0;
271
+ }
272
+ const edge = { flags };
273
+ if (childNodeId !== void 0) {
274
+ edge.childNodeId = childNodeId;
275
+ }
276
+ if (scalarMask !== 0) {
277
+ edge.scalarMask = scalarMask;
278
+ }
279
+ if (enumNameIndex !== void 0) {
280
+ edge.enumNameIndex = enumNameIndex;
281
+ }
282
+ return edge;
283
+ }
284
+ /**
285
+ * Builds an output node for a named output type.
286
+ */
287
+ buildOutputTypeNode(typeName) {
288
+ if (this.#builder.hasOutputTypeNode(typeName)) {
289
+ return this.#builder.getOutputTypeNode(typeName);
290
+ }
291
+ const outputType = this.#outputTypeMap.get(typeName);
292
+ if (!outputType) {
293
+ this.#builder.setOutputTypeNode(typeName, void 0);
294
+ return void 0;
295
+ }
296
+ const nodeId = this.#builder.allocateOutputNode();
297
+ this.#builder.setOutputTypeNode(typeName, nodeId);
298
+ const edges = {};
299
+ let hasAnyEdge = false;
300
+ for (const field of outputType.fields) {
301
+ const edge = this.#buildOutputEdge(field);
302
+ if (edge) {
303
+ const stringIndex = this.#builder.internString(field.name);
304
+ edges[stringIndex] = edge;
305
+ hasAnyEdge = true;
306
+ }
307
+ }
308
+ if (hasAnyEdge) {
309
+ this.#builder.setOutputNodeEdges(nodeId, edges);
310
+ }
311
+ return nodeId;
312
+ }
313
+ #buildOutputEdge(field) {
314
+ let argsNodeId;
315
+ let outputNodeId;
316
+ if (field.args.length > 0) {
317
+ argsNodeId = this.buildInputNodeFromArgs(field.args);
318
+ }
319
+ if (field.outputType.location === "outputObjectTypes") {
320
+ outputNodeId = this.buildOutputTypeNode(getTypeName(field.outputType.type, field.outputType.namespace));
321
+ }
322
+ if (argsNodeId === void 0 && outputNodeId === void 0) {
323
+ return void 0;
324
+ }
325
+ const edge = {};
326
+ if (argsNodeId !== void 0) {
327
+ edge.argsNodeId = argsNodeId;
328
+ }
329
+ if (outputNodeId !== void 0) {
330
+ edge.outputNodeId = outputNodeId;
331
+ }
332
+ return edge;
333
+ }
334
+ }
335
+ function getTypeName(name, namespace) {
336
+ if (namespace === void 0) {
337
+ return name;
338
+ }
339
+ return `${namespace}.${name}`;
340
+ }
341
+ export {
342
+ DMMFTraverser
343
+ };
package/dist/index.d.ts CHANGED
@@ -1 +1,4 @@
1
- export { buildParamGraph } from './build-param-graph';
1
+ export { buildAndSerializeParamGraph, buildParamGraph } from './build-param-graph';
2
+ export { DMMFTraverser } from './dmmf-traverser';
3
+ export type { NodeId } from './param-graph-builder';
4
+ export { ParamGraphBuilder } from './param-graph-builder';