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