@gqloom/core 0.10.1 → 0.11.1

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,415 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (all) => {
9
+ let target = {};
10
+ for (var name in all) __defProp(target, name, {
11
+ get: all[name],
12
+ enumerable: true
13
+ });
14
+ return target;
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
+ key = keys[i];
19
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
+ get: ((k) => from[k]).bind(null, key),
21
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
22
+ });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
27
+ value: mod,
28
+ enumerable: true
29
+ }) : target, mod));
30
+
31
+ //#endregion
32
+ let graphql = require("graphql");
33
+ graphql = __toESM(graphql);
34
+
35
+ //#region src/utils/constants.ts
36
+ const DERIVED_DEPENDENCIES = "loom.derived-from-dependencies";
37
+
38
+ //#endregion
39
+ //#region src/utils/type.ts
40
+ function unwrapType(gqlType) {
41
+ if ((0, graphql.isNonNullType)(gqlType)) return unwrapType(gqlType.ofType);
42
+ if ((0, graphql.isListType)(gqlType)) return unwrapType(gqlType.ofType);
43
+ return gqlType;
44
+ }
45
+
46
+ //#endregion
47
+ //#region src/utils/parse-resolving-fields.ts
48
+ /**
49
+ * Analyzes and processes field resolution in a GraphQL query deeply.
50
+ *
51
+ * @param payload - The resolver payload containing the current field resolution context
52
+ * @param [maxDepth=Infinity] - Maximum depth of nested fields to parse
53
+ * @returns A map of field paths to their resolving fields
54
+ */
55
+ function getDeepResolvingFields(payload, maxDepth = Infinity) {
56
+ const result = /* @__PURE__ */ new Map();
57
+ const requestedFieldsByPath = ResolvingFieldsParser.parseDeep(payload.info, maxDepth);
58
+ const rootType = unwrapType(payload.info.returnType);
59
+ for (const [path, requestedFields] of requestedFieldsByPath.entries()) {
60
+ let currentType = rootType;
61
+ if (path) {
62
+ const pathParts = path.split(".");
63
+ let tempType = rootType;
64
+ for (const part of pathParts) {
65
+ const unwrapped = unwrapType(tempType);
66
+ if ((0, graphql.isObjectType)(unwrapped) || (0, graphql.isInterfaceType)(unwrapped)) {
67
+ const field = unwrapped.getFields()[part];
68
+ if (field) tempType = field.type;
69
+ else {
70
+ tempType = void 0;
71
+ break;
72
+ }
73
+ } else {
74
+ tempType = void 0;
75
+ break;
76
+ }
77
+ }
78
+ if (!tempType) continue;
79
+ currentType = tempType;
80
+ }
81
+ const unwrappedCurrentType = unwrapType(currentType);
82
+ if ((0, graphql.isObjectType)(unwrappedCurrentType)) {
83
+ const derivedFields = /* @__PURE__ */ new Set();
84
+ const derivedDependencies = /* @__PURE__ */ new Set();
85
+ const objectFields = unwrappedCurrentType.getFields();
86
+ for (const requestedFieldName of requestedFields) {
87
+ const field = objectFields[requestedFieldName];
88
+ if (field) {
89
+ const deps = field.extensions?.[DERIVED_DEPENDENCIES];
90
+ if (deps && Array.isArray(deps) && deps.length > 0) {
91
+ derivedFields.add(requestedFieldName);
92
+ for (const d of deps) derivedDependencies.add(d);
93
+ }
94
+ }
95
+ }
96
+ const selectedFields = new Set(requestedFields);
97
+ for (const f of derivedFields) selectedFields.delete(f);
98
+ for (const d of derivedDependencies) selectedFields.add(d);
99
+ result.set(path, {
100
+ requestedFields,
101
+ derivedFields,
102
+ derivedDependencies,
103
+ selectedFields
104
+ });
105
+ }
106
+ }
107
+ return result;
108
+ }
109
+ /**
110
+ * Analyzes and processes field resolution in a GraphQL query.
111
+ *
112
+ * @param payload - The resolver payload containing the current field resolution context
113
+ * @returns An object containing sets of different field types
114
+ */
115
+ function getResolvingFields(payload) {
116
+ const requestedFields = parseResolvingFields(payload.info);
117
+ const derivedFields = /* @__PURE__ */ new Set();
118
+ const derivedDependencies = /* @__PURE__ */ new Set();
119
+ const resolvingObject = unwrapType(payload.info.returnType);
120
+ if ((0, graphql.isObjectType)(resolvingObject)) {
121
+ const objectFields = resolvingObject.getFields();
122
+ for (const fieldName of requestedFields) {
123
+ const field = objectFields[fieldName];
124
+ if (field) {
125
+ const deps = field.extensions?.[DERIVED_DEPENDENCIES];
126
+ if (deps && Array.isArray(deps)) {
127
+ derivedFields.add(fieldName);
128
+ for (const d of deps) derivedDependencies.add(d);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ const selectedFields = new Set(requestedFields);
134
+ for (const f of derivedFields) selectedFields.delete(f);
135
+ for (const d of derivedDependencies) selectedFields.add(d);
136
+ return {
137
+ requestedFields,
138
+ derivedFields,
139
+ derivedDependencies,
140
+ selectedFields
141
+ };
142
+ }
143
+ /**
144
+ * Parses the GraphQL resolve info to extract all requested fields.
145
+ * Returns a Set of field paths where nested fields are represented as 'parent.field'.
146
+ * Supports @include, @skip directives, fragments, and variables.
147
+ *
148
+ * @param info - The GraphQL resolve info object containing the query information
149
+ * @param maxDepth - Maximum depth of nested fields to parse (default: 1)
150
+ * @returns A Set of field paths
151
+ */
152
+ function parseResolvingFields(info, maxDepth = 1) {
153
+ return ResolvingFieldsParser.parse(info, maxDepth);
154
+ }
155
+ /**
156
+ * Class responsible for parsing GraphQL resolve info to extract all requested fields.
157
+ */
158
+ var ResolvingFieldsParser = class ResolvingFieldsParser {
159
+ /** Store unique field paths grouped by parent path */
160
+ fields = /* @__PURE__ */ new Map();
161
+ /** Track visited fragments to prevent circular references */
162
+ visitedFragments = /* @__PURE__ */ new Set();
163
+ /** The GraphQL resolve info object */
164
+ info;
165
+ /** Maximum depth of nested fields to parse */
166
+ maxDepth;
167
+ static parse(info, maxDepth) {
168
+ return new ResolvingFieldsParser(info, maxDepth).parse();
169
+ }
170
+ static parseDeep(info, maxDepth) {
171
+ return new ResolvingFieldsParser(info, maxDepth).parseDeep();
172
+ }
173
+ constructor(info, maxDepth) {
174
+ this.info = info;
175
+ this.maxDepth = maxDepth;
176
+ for (const fieldNode of this.info.fieldNodes) this.collectFields(fieldNode.selectionSet, "", 0);
177
+ }
178
+ /**
179
+ * Parses the GraphQL resolve info to extract all requested fields into a flat set.
180
+ * @returns A Set of field paths
181
+ */
182
+ parse() {
183
+ const flatFields = /* @__PURE__ */ new Set();
184
+ for (const [path, fieldSet] of this.fields.entries()) for (const fieldName of fieldSet) {
185
+ const fullPath = path ? `${path}.${fieldName}` : fieldName;
186
+ flatFields.add(fullPath);
187
+ }
188
+ for (const path of this.fields.keys()) if (path) flatFields.add(path);
189
+ return flatFields;
190
+ }
191
+ /**
192
+ * Parses the GraphQL resolve info to extract all requested fields.
193
+ * @returns A map of field paths to their requested fields
194
+ */
195
+ parseDeep() {
196
+ return this.fields;
197
+ }
198
+ /**
199
+ * Recursively collects fields from a selection set.
200
+ * Handles fields, inline fragments, and fragment spreads.
201
+ *
202
+ * @param selectionSet - The selection set to process
203
+ * @param parentPath - The path of the parent field (for nested fields)
204
+ * @param currentDepth - Current depth of recursion
205
+ */
206
+ collectFields(selectionSet, parentPath = "", currentDepth = 0) {
207
+ if (!selectionSet?.selections.length || currentDepth >= this.maxDepth) return;
208
+ if (!this.fields.has(parentPath)) this.fields.set(parentPath, /* @__PURE__ */ new Set());
209
+ const currentFields = this.fields.get(parentPath);
210
+ for (const selection of selectionSet.selections) {
211
+ if (!this.shouldIncludeNode(selection)) continue;
212
+ switch (selection.kind) {
213
+ case graphql.Kind.FIELD: {
214
+ const fieldName = selection.name.value;
215
+ currentFields.add(fieldName);
216
+ if (selection.selectionSet != null) {
217
+ const fieldPath = parentPath ? `${parentPath}.${fieldName}` : fieldName;
218
+ this.collectFields(selection.selectionSet, fieldPath, currentDepth + 1);
219
+ }
220
+ break;
221
+ }
222
+ case graphql.Kind.INLINE_FRAGMENT:
223
+ if (selection.selectionSet) this.collectFields(selection.selectionSet, parentPath, currentDepth);
224
+ break;
225
+ case graphql.Kind.FRAGMENT_SPREAD: {
226
+ const fragmentName = selection.name.value;
227
+ if (this.visitedFragments.has(fragmentName)) continue;
228
+ this.visitedFragments.add(fragmentName);
229
+ const fragment = this.info.fragments[fragmentName];
230
+ if (fragment) this.collectFields(fragment.selectionSet, parentPath, currentDepth);
231
+ break;
232
+ }
233
+ }
234
+ }
235
+ }
236
+ /**
237
+ * Extracts the boolean value from a directive's 'if' argument.
238
+ * Handles both literal boolean values and variables.
239
+ *
240
+ * @param directive - The directive node to extract value from
241
+ * @returns The boolean value of the directive's condition
242
+ */
243
+ getDirectiveValue(directive) {
244
+ const ifArg = directive.arguments?.find((arg) => arg.name.value === "if");
245
+ if (!ifArg) return true;
246
+ const value = ifArg.value;
247
+ if (value.kind === graphql.Kind.BOOLEAN) return value.value;
248
+ if (value.kind === graphql.Kind.VARIABLE) {
249
+ const variableName = value.name.value;
250
+ return this.info.variableValues?.[variableName] === true;
251
+ }
252
+ return true;
253
+ }
254
+ /**
255
+ * Determines if a selection node should be included based on its directives.
256
+ * Handles both @include and @skip directives.
257
+ *
258
+ * @param node - The selection node to check
259
+ * @returns Whether the node should be included
260
+ */
261
+ shouldIncludeNode(node) {
262
+ if (!node.directives?.length) return true;
263
+ return node.directives.every((directive) => {
264
+ if (directive.name.value === "include") return this.getDirectiveValue(directive);
265
+ if (directive.name.value === "skip") return !this.getDirectiveValue(directive);
266
+ return true;
267
+ });
268
+ }
269
+ };
270
+
271
+ //#endregion
272
+ //#region src/utils/symbols.ts
273
+ var symbols_exports = /* @__PURE__ */ __export({
274
+ CONTEXT_MAP_KEY: () => CONTEXT_MAP_KEY,
275
+ FIELD_HIDDEN: () => FIELD_HIDDEN,
276
+ GET_GRAPHQL_TYPE: () => GET_GRAPHQL_TYPE,
277
+ IS_RESOLVER: () => IS_RESOLVER,
278
+ RESOLVER_OPTIONS_KEY: () => RESOLVER_OPTIONS_KEY,
279
+ WEAVER_CONFIG: () => WEAVER_CONFIG
280
+ });
281
+ /**
282
+ * The symbol to get GraphQL type for schema
283
+ */
284
+ const GET_GRAPHQL_TYPE = Symbol.for("gqloom.get_graphql_type");
285
+ /**
286
+ * The symbol to get and store weaver config
287
+ */
288
+ const WEAVER_CONFIG = Symbol.for("gqloom.weaver_config");
289
+ /**
290
+ * The symbol to get resolver options
291
+ */
292
+ const RESOLVER_OPTIONS_KEY = Symbol.for("gqloom.resolver-options");
293
+ /**
294
+ * The symbol to check if an object is a resolver
295
+ */
296
+ const IS_RESOLVER = Symbol.for("gqloom.is-resolver");
297
+ /**
298
+ * The symbol to assign a WeakMap to an object
299
+ */
300
+ const CONTEXT_MAP_KEY = Symbol.for("gqloom.context-map");
301
+ /**
302
+ * Set fields to be hidden
303
+ */
304
+ const FIELD_HIDDEN = false;
305
+
306
+ //#endregion
307
+ //#region src/utils/context.ts
308
+ /**
309
+ * Create an empty memoization payload for the resolver
310
+ * @returns the empty memoization payload
311
+ */
312
+ function onlyMemoization() {
313
+ return {
314
+ memoization: /* @__PURE__ */ new WeakMap(),
315
+ isMemoization: true
316
+ };
317
+ }
318
+ function isOnlyMemoryPayload(payload) {
319
+ return payload.isMemoization === true;
320
+ }
321
+ function getMemoizationMap(payload) {
322
+ if (isOnlyMemoryPayload(payload)) return payload.memoization;
323
+ if (typeof payload.context === "undefined") Object.defineProperty(payload, "context", { value: {} });
324
+ return assignContextMap(payload.context);
325
+ }
326
+ function assignContextMap(target) {
327
+ target[CONTEXT_MAP_KEY] ??= /* @__PURE__ */ new WeakMap();
328
+ return target[CONTEXT_MAP_KEY];
329
+ }
330
+
331
+ //#endregion
332
+ Object.defineProperty(exports, 'DERIVED_DEPENDENCIES', {
333
+ enumerable: true,
334
+ get: function () {
335
+ return DERIVED_DEPENDENCIES;
336
+ }
337
+ });
338
+ Object.defineProperty(exports, 'FIELD_HIDDEN', {
339
+ enumerable: true,
340
+ get: function () {
341
+ return FIELD_HIDDEN;
342
+ }
343
+ });
344
+ Object.defineProperty(exports, 'GET_GRAPHQL_TYPE', {
345
+ enumerable: true,
346
+ get: function () {
347
+ return GET_GRAPHQL_TYPE;
348
+ }
349
+ });
350
+ Object.defineProperty(exports, 'IS_RESOLVER', {
351
+ enumerable: true,
352
+ get: function () {
353
+ return IS_RESOLVER;
354
+ }
355
+ });
356
+ Object.defineProperty(exports, 'WEAVER_CONFIG', {
357
+ enumerable: true,
358
+ get: function () {
359
+ return WEAVER_CONFIG;
360
+ }
361
+ });
362
+ Object.defineProperty(exports, '__toESM', {
363
+ enumerable: true,
364
+ get: function () {
365
+ return __toESM;
366
+ }
367
+ });
368
+ Object.defineProperty(exports, 'assignContextMap', {
369
+ enumerable: true,
370
+ get: function () {
371
+ return assignContextMap;
372
+ }
373
+ });
374
+ Object.defineProperty(exports, 'getDeepResolvingFields', {
375
+ enumerable: true,
376
+ get: function () {
377
+ return getDeepResolvingFields;
378
+ }
379
+ });
380
+ Object.defineProperty(exports, 'getMemoizationMap', {
381
+ enumerable: true,
382
+ get: function () {
383
+ return getMemoizationMap;
384
+ }
385
+ });
386
+ Object.defineProperty(exports, 'getResolvingFields', {
387
+ enumerable: true,
388
+ get: function () {
389
+ return getResolvingFields;
390
+ }
391
+ });
392
+ Object.defineProperty(exports, 'isOnlyMemoryPayload', {
393
+ enumerable: true,
394
+ get: function () {
395
+ return isOnlyMemoryPayload;
396
+ }
397
+ });
398
+ Object.defineProperty(exports, 'onlyMemoization', {
399
+ enumerable: true,
400
+ get: function () {
401
+ return onlyMemoization;
402
+ }
403
+ });
404
+ Object.defineProperty(exports, 'parseResolvingFields', {
405
+ enumerable: true,
406
+ get: function () {
407
+ return parseResolvingFields;
408
+ }
409
+ });
410
+ Object.defineProperty(exports, 'symbols_exports', {
411
+ enumerable: true,
412
+ get: function () {
413
+ return symbols_exports;
414
+ }
415
+ });