@prisma/param-graph-builder 7.4.0-integration-parameterization.6 → 7.4.0-integration-parameterization.7

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.
@@ -1,410 +1,18 @@
1
- import { ModelAction } from "@prisma/dmmf";
2
- import {
3
- EdgeFlag,
4
- scalarTypeToMask
5
- } from "@prisma/param-graph";
6
- class ParamGraphBuilder {
7
- stringTable = [];
8
- stringToIndex = /* @__PURE__ */ new Map();
9
- enumNames = [];
10
- enumToIndex = /* @__PURE__ */ new Map();
11
- inputNodes = [];
12
- outputNodes = [];
13
- roots = {};
14
- inputTypeNodeCache = /* @__PURE__ */ new Map();
15
- unionNodeCache = /* @__PURE__ */ new Map();
16
- outputTypeNodeCache = /* @__PURE__ */ new Map();
17
- /**
18
- * Interns a string into the string table, returning its index.
19
- */
20
- internString(str) {
21
- let index = this.stringToIndex.get(str);
22
- if (index === void 0) {
23
- index = this.stringTable.length;
24
- this.stringTable.push(str);
25
- this.stringToIndex.set(str, index);
26
- }
27
- return index;
28
- }
29
- /**
30
- * Registers a user enum name, returning its index.
31
- */
32
- registerEnum(enumName) {
33
- let index = this.enumToIndex.get(enumName);
34
- if (index === void 0) {
35
- index = this.enumNames.length;
36
- this.enumNames.push(enumName);
37
- this.enumToIndex.set(enumName, index);
38
- }
39
- return index;
40
- }
41
- /**
42
- * Allocates a new input node and returns its ID.
43
- */
44
- allocateInputNode() {
45
- const id = this.inputNodes.length;
46
- this.inputNodes.push({});
47
- return id;
48
- }
49
- /**
50
- * Sets fields on an input node.
51
- */
52
- setInputNodeFields(nodeId, fields) {
53
- if (Object.keys(fields).length > 0) {
54
- this.inputNodes[nodeId].f = fields;
55
- }
56
- }
57
- /**
58
- * Allocates a new output node and returns its ID.
59
- */
60
- allocateOutputNode() {
61
- const id = this.outputNodes.length;
62
- this.outputNodes.push({});
63
- return id;
64
- }
65
- /**
66
- * Sets fields on an output node.
67
- */
68
- setOutputNodeFields(nodeId, fields) {
69
- if (Object.keys(fields).length > 0) {
70
- this.outputNodes[nodeId].f = fields;
71
- }
72
- }
73
- /**
74
- * Records a root entry for an operation.
75
- */
76
- setRoot(key, entry) {
77
- if (entry.a !== void 0 || entry.o !== void 0) {
78
- this.roots[key] = entry;
79
- }
80
- }
81
- /**
82
- * Gets or sets a cached input type node ID.
83
- */
84
- getInputTypeNode(typeName) {
85
- return this.inputTypeNodeCache.get(typeName);
86
- }
87
- setInputTypeNode(typeName, nodeId) {
88
- this.inputTypeNodeCache.set(typeName, nodeId);
89
- }
90
- hasInputTypeNode(typeName) {
91
- return this.inputTypeNodeCache.has(typeName);
92
- }
93
- /**
94
- * Gets or sets a cached union node ID.
95
- */
96
- getUnionNode(key) {
97
- return this.unionNodeCache.get(key);
98
- }
99
- setUnionNode(key, nodeId) {
100
- this.unionNodeCache.set(key, nodeId);
101
- }
102
- hasUnionNode(key) {
103
- return this.unionNodeCache.has(key);
104
- }
105
- /**
106
- * Gets or sets a cached output type node ID.
107
- */
108
- getOutputTypeNode(typeName) {
109
- return this.outputTypeNodeCache.get(typeName);
110
- }
111
- setOutputTypeNode(typeName, nodeId) {
112
- this.outputTypeNodeCache.set(typeName, nodeId);
113
- }
114
- hasOutputTypeNode(typeName) {
115
- return this.outputTypeNodeCache.has(typeName);
116
- }
117
- /**
118
- * Builds the final ParamGraph.
119
- */
120
- build() {
121
- return {
122
- s: this.stringTable,
123
- e: this.enumNames,
124
- i: this.inputNodes,
125
- o: this.outputNodes,
126
- r: this.roots
127
- };
128
- }
129
- }
1
+ import { DMMFTraverser } from "./dmmf-traverser";
2
+ import { ParamGraphBuilder } from "./param-graph-builder";
130
3
  function buildParamGraph(dmmf) {
131
4
  const builder = new ParamGraphBuilder();
132
- const inputTypeMap = /* @__PURE__ */ new Map();
133
- const outputTypeMap = /* @__PURE__ */ new Map();
134
- const userEnumNames = /* @__PURE__ */ new Set();
135
- for (const e of dmmf.datamodel.enums) {
136
- userEnumNames.add(e.name);
137
- }
138
- for (const inputType of dmmf.schema.inputObjectTypes.prisma ?? []) {
139
- inputTypeMap.set(getTypeName(inputType.name, "prisma"), inputType);
140
- }
141
- for (const inputType of dmmf.schema.inputObjectTypes.model ?? []) {
142
- inputTypeMap.set(getTypeName(inputType.name, "model"), inputType);
143
- }
144
- for (const outputType of dmmf.schema.outputObjectTypes.prisma ?? []) {
145
- outputTypeMap.set(getTypeName(outputType.name, "prisma"), outputType);
146
- }
147
- for (const outputType of dmmf.schema.outputObjectTypes.model ?? []) {
148
- outputTypeMap.set(getTypeName(outputType.name, "model"), outputType);
149
- }
150
- function buildInputNodeFromArgs(args) {
151
- const fields = {};
152
- let hasAnyField = false;
153
- for (const arg of args) {
154
- const edge = buildInputEdge(arg);
155
- if (edge) {
156
- const stringIndex = builder.internString(arg.name);
157
- fields[stringIndex] = edge;
158
- hasAnyField = true;
159
- }
160
- }
161
- if (!hasAnyField) {
162
- return void 0;
163
- }
164
- const nodeId = builder.allocateInputNode();
165
- builder.setInputNodeFields(nodeId, fields);
166
- return nodeId;
167
- }
168
- function buildInputEdge(arg) {
169
- return mergeFieldVariants([arg]);
170
- }
171
- function buildInputTypeNode(typeName) {
172
- if (builder.hasInputTypeNode(typeName)) {
173
- return builder.getInputTypeNode(typeName);
174
- }
175
- const inputType = inputTypeMap.get(typeName);
176
- if (!inputType) {
177
- builder.setInputTypeNode(typeName, void 0);
178
- return void 0;
179
- }
180
- const nodeId = builder.allocateInputNode();
181
- builder.setInputTypeNode(typeName, nodeId);
182
- const fields = {};
183
- let hasAnyField = false;
184
- for (const field of inputType.fields) {
185
- const edge = buildInputEdge(field);
186
- if (edge) {
187
- const stringIndex = builder.internString(field.name);
188
- fields[stringIndex] = edge;
189
- hasAnyField = true;
190
- }
191
- }
192
- if (hasAnyField) {
193
- builder.setInputNodeFields(nodeId, fields);
194
- return nodeId;
195
- }
196
- return nodeId;
197
- }
198
- function buildUnionNode(typeNames) {
199
- const sortedNames = [...typeNames].sort();
200
- const cacheKey = sortedNames.join("|");
201
- if (builder.hasUnionNode(cacheKey)) {
202
- return builder.getUnionNode(cacheKey);
203
- }
204
- const nodeId = builder.allocateInputNode();
205
- builder.setUnionNode(cacheKey, nodeId);
206
- const fieldsByName = /* @__PURE__ */ new Map();
207
- for (const typeName of typeNames) {
208
- const inputType = inputTypeMap.get(typeName);
209
- if (!inputType) continue;
210
- for (const field of inputType.fields) {
211
- let fieldsForName = fieldsByName.get(field.name);
212
- if (!fieldsForName) {
213
- fieldsForName = [];
214
- fieldsByName.set(field.name, fieldsForName);
215
- }
216
- fieldsForName.push(field);
217
- }
218
- }
219
- const mergedFields = {};
220
- let hasAnyField = false;
221
- for (const [fieldName, variantFields] of fieldsByName) {
222
- const mergedEdge = mergeFieldVariants(variantFields);
223
- if (mergedEdge) {
224
- const stringIndex = builder.internString(fieldName);
225
- mergedFields[stringIndex] = mergedEdge;
226
- hasAnyField = true;
227
- }
228
- }
229
- if (hasAnyField) {
230
- builder.setInputNodeFields(nodeId, mergedFields);
231
- }
232
- return nodeId;
233
- }
234
- function mergeFieldVariants(variants) {
235
- let flags = 0;
236
- let scalarMask = 0;
237
- let childNodeId;
238
- let enumNameId;
239
- const scalarTypes = [];
240
- const enumTypes = [];
241
- const inputObjectTypes = [];
242
- for (const variant of variants) {
243
- for (const inputType of variant.inputTypes) {
244
- switch (inputType.location) {
245
- case "scalar":
246
- if (variant.isParameterizable) {
247
- scalarTypes.push(inputType);
248
- }
249
- break;
250
- case "enumTypes":
251
- if (variant.isParameterizable) {
252
- enumTypes.push(inputType);
253
- }
254
- break;
255
- case "inputObjectTypes":
256
- if (!inputObjectTypes.some(
257
- (ot) => ot.type === inputType.type && ot.namespace === inputType.namespace && ot.isList === inputType.isList
258
- )) {
259
- inputObjectTypes.push(inputType);
260
- }
261
- break;
262
- case "fieldRefTypes":
263
- break;
264
- default:
265
- inputType.location;
266
- }
267
- }
268
- }
269
- for (const st of scalarTypes) {
270
- scalarMask |= scalarTypeToMask(st.type);
271
- if (st.isList) {
272
- flags |= EdgeFlag.ParamListScalar;
273
- } else {
274
- flags |= EdgeFlag.ParamScalar;
275
- }
276
- }
277
- for (const et of enumTypes) {
278
- if (et.namespace === "model") {
279
- enumNameId = builder.registerEnum(et.type);
280
- if (et.isList) {
281
- flags |= EdgeFlag.ParamListEnum;
282
- } else {
283
- flags |= EdgeFlag.ParamEnum;
284
- }
285
- break;
286
- }
287
- }
288
- if (inputObjectTypes.length > 0) {
289
- const hasObjectList = inputObjectTypes.some((iot) => iot.isList);
290
- const hasSingleObject = inputObjectTypes.some((iot) => !iot.isList);
291
- if (hasObjectList) {
292
- flags |= EdgeFlag.ListObject;
293
- }
294
- if (hasSingleObject) {
295
- flags |= EdgeFlag.Object;
296
- }
297
- if (inputObjectTypes.length === 1) {
298
- childNodeId = buildInputTypeNode(getTypeName(inputObjectTypes[0].type, inputObjectTypes[0].namespace));
299
- } else {
300
- childNodeId = buildUnionNode(inputObjectTypes.map((iot) => getTypeName(iot.type, iot.namespace)));
301
- }
302
- }
303
- if (flags === 0) {
304
- return void 0;
305
- }
306
- const edge = { k: flags };
307
- if (childNodeId !== void 0) {
308
- edge.c = childNodeId;
309
- }
310
- if (scalarMask !== 0) {
311
- edge.m = scalarMask;
312
- }
313
- if (enumNameId !== void 0) {
314
- edge.e = enumNameId;
315
- }
316
- return edge;
317
- }
318
- function buildOutputTypeNode(typeName) {
319
- if (builder.hasOutputTypeNode(typeName)) {
320
- return builder.getOutputTypeNode(typeName);
321
- }
322
- const outputType = outputTypeMap.get(typeName);
323
- if (!outputType) {
324
- builder.setOutputTypeNode(typeName, void 0);
325
- return void 0;
326
- }
327
- const nodeId = builder.allocateOutputNode();
328
- builder.setOutputTypeNode(typeName, nodeId);
329
- const fields = {};
330
- let hasAnyField = false;
331
- for (const field of outputType.fields) {
332
- const edge = buildOutputEdge(field);
333
- if (edge) {
334
- const stringIndex = builder.internString(field.name);
335
- fields[stringIndex] = edge;
336
- hasAnyField = true;
337
- }
338
- }
339
- if (hasAnyField) {
340
- builder.setOutputNodeFields(nodeId, fields);
341
- return nodeId;
342
- }
343
- return nodeId;
344
- }
345
- function buildOutputEdge(field) {
346
- let argsNodeId;
347
- let childOutputNodeId;
348
- if (field.args.length > 0) {
349
- argsNodeId = buildInputNodeFromArgs(field.args);
350
- }
351
- if (field.outputType.location === "outputObjectTypes") {
352
- childOutputNodeId = buildOutputTypeNode(getTypeName(field.outputType.type, field.outputType.namespace));
353
- }
354
- if (argsNodeId === void 0 && childOutputNodeId === void 0) {
355
- return void 0;
356
- }
357
- const edge = {};
358
- if (argsNodeId !== void 0) {
359
- edge.a = argsNodeId;
360
- }
361
- if (childOutputNodeId !== void 0) {
362
- edge.o = childOutputNodeId;
363
- }
364
- return edge;
365
- }
366
- for (const mapping of dmmf.mappings.modelOperations) {
367
- const modelName = mapping.model;
368
- const actions = Object.keys(ModelAction);
369
- for (const action of actions) {
370
- const fieldName = mapping[action];
371
- if (!fieldName) continue;
372
- let rootField;
373
- const queryType = outputTypeMap.get("prisma.Query");
374
- if (queryType) {
375
- rootField = queryType.fields.find((f) => f.name === fieldName);
376
- }
377
- if (!rootField) {
378
- const mutationType = outputTypeMap.get("prisma.Mutation");
379
- if (mutationType) {
380
- rootField = mutationType.fields.find((f) => f.name === fieldName);
381
- }
382
- }
383
- if (!rootField) continue;
384
- const argsNodeId = buildInputNodeFromArgs(rootField.args);
385
- let outputNodeId;
386
- if (rootField.outputType.location === "outputObjectTypes") {
387
- outputNodeId = buildOutputTypeNode(getTypeName(rootField.outputType.type, rootField.outputType.namespace));
388
- }
389
- const dmmfActionToJsonAction = {
390
- create: "createOne",
391
- update: "updateOne",
392
- delete: "deleteOne",
393
- upsert: "upsertOne"
394
- };
395
- const jsonAction = dmmfActionToJsonAction[action] ?? action;
396
- const rootKey = `${modelName}.${jsonAction}`;
397
- builder.setRoot(rootKey, { a: argsNodeId, o: outputNodeId });
398
- }
399
- }
5
+ const traverser = new DMMFTraverser(builder, dmmf);
6
+ traverser.processRoots(dmmf.mappings.modelOperations);
400
7
  return builder.build();
401
8
  }
402
- function getTypeName(name, namespace) {
403
- if (namespace === void 0) {
404
- return name;
405
- }
406
- return `${namespace}.${name}`;
9
+ function buildAndSerializeParamGraph(dmmf) {
10
+ const builder = new ParamGraphBuilder();
11
+ const traverser = new DMMFTraverser(builder, dmmf);
12
+ traverser.processRoots(dmmf.mappings.modelOperations);
13
+ return builder.buildAndSerialize();
407
14
  }
408
15
  export {
16
+ buildAndSerializeParamGraph,
409
17
  buildParamGraph
410
18
  };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * DMMFTraverser: DMMF traversal logic for building ParamGraph.
3
+ *
4
+ * This class contains the traversal algorithms that walk DMMF structures
5
+ * and build the param graph. It uses ParamGraphBuilder for allocation
6
+ * and caching.
7
+ */
8
+ import type * as DMMF from '@prisma/dmmf';
9
+ import type { NodeId, ParamGraphBuilder } from './param-graph-builder';
10
+ /**
11
+ * Traverses DMMF and populates a ParamGraphBuilder.
12
+ */
13
+ export declare class DMMFTraverser {
14
+ #private;
15
+ constructor(builder: ParamGraphBuilder, dmmf: DMMF.Document);
16
+ /**
17
+ * Process all root operations from model mappings.
18
+ */
19
+ processRoots(mappings: readonly DMMF.ModelMapping[]): void;
20
+ /**
21
+ * Builds an input node from schema arguments.
22
+ */
23
+ buildInputNodeFromArgs(args: readonly DMMF.SchemaArg[]): NodeId | undefined;
24
+ /**
25
+ * Builds an input node for a named input type.
26
+ */
27
+ buildInputTypeNode(typeName: string): NodeId | undefined;
28
+ /**
29
+ * Builds a union node for multiple input types.
30
+ */
31
+ buildUnionNode(typeNames: string[]): NodeId | undefined;
32
+ /**
33
+ * Builds an output node for a named output type.
34
+ */
35
+ buildOutputTypeNode(typeName: string): NodeId | undefined;
36
+ }