@soda-gql/core 0.1.0 → 0.3.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.
Files changed (70) hide show
  1. package/README.md +108 -161
  2. package/dist/adapter.cjs +35 -0
  3. package/dist/adapter.cjs.map +1 -0
  4. package/dist/adapter.d.cts +35 -0
  5. package/dist/adapter.d.cts.map +1 -0
  6. package/dist/adapter.d.ts +35 -0
  7. package/dist/adapter.d.ts.map +1 -0
  8. package/dist/adapter.js +34 -0
  9. package/dist/adapter.js.map +1 -0
  10. package/dist/index-DH3lMepk.d.cts +569 -0
  11. package/dist/index-DH3lMepk.d.cts.map +1 -0
  12. package/dist/index-WU6aMZjg.d.ts +569 -0
  13. package/dist/index-WU6aMZjg.d.ts.map +1 -0
  14. package/dist/index.cjs +485 -470
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +97 -3
  17. package/dist/index.d.cts.map +1 -0
  18. package/dist/index.d.ts +97 -3
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +458 -443
  21. package/dist/index.js.map +1 -1
  22. package/dist/runtime.cjs +85 -0
  23. package/dist/runtime.cjs.map +1 -0
  24. package/dist/runtime.d.cts +40 -0
  25. package/dist/runtime.d.cts.map +1 -0
  26. package/dist/runtime.d.ts +40 -0
  27. package/dist/runtime.d.ts.map +1 -0
  28. package/dist/runtime.js +82 -0
  29. package/dist/runtime.js.map +1 -0
  30. package/dist/schema-BElqa12z.d.cts +520 -0
  31. package/dist/schema-BElqa12z.d.cts.map +1 -0
  32. package/dist/schema-BbCrsNkQ.js +86 -0
  33. package/dist/schema-BbCrsNkQ.js.map +1 -0
  34. package/dist/schema-C7q047S0.d.ts +520 -0
  35. package/dist/schema-C7q047S0.d.ts.map +1 -0
  36. package/dist/schema-DuWaRhdp.cjs +122 -0
  37. package/dist/schema-DuWaRhdp.cjs.map +1 -0
  38. package/dist/schema-builder-DDfulXP3.d.cts +40 -0
  39. package/dist/schema-builder-DDfulXP3.d.cts.map +1 -0
  40. package/dist/schema-builder-DfyTaFMt.d.ts +40 -0
  41. package/dist/schema-builder-DfyTaFMt.d.ts.map +1 -0
  42. package/package.json +34 -14
  43. package/dist/index-DYwkqPzd.d.ts +0 -1015
  44. package/dist/index-DYwkqPzd.d.ts.map +0 -1
  45. package/dist/index-Db9ogofS.d.ts +0 -365
  46. package/dist/index-Db9ogofS.d.ts.map +0 -1
  47. package/dist/index-Dth0NSJt.d.cts +0 -1015
  48. package/dist/index-Dth0NSJt.d.cts.map +0 -1
  49. package/dist/index-zGZ61WLt.d.cts +0 -365
  50. package/dist/index-zGZ61WLt.d.cts.map +0 -1
  51. package/dist/merge-CeMx09is.js +0 -74
  52. package/dist/merge-CeMx09is.js.map +0 -1
  53. package/dist/merge-ZxKV1syS.cjs +0 -85
  54. package/dist/metadata/index.cjs +0 -62
  55. package/dist/metadata/index.d.cts +0 -71
  56. package/dist/metadata/index.d.cts.map +0 -1
  57. package/dist/metadata/index.d.ts +0 -71
  58. package/dist/metadata/index.d.ts.map +0 -1
  59. package/dist/metadata/index.js +0 -59
  60. package/dist/metadata/index.js.map +0 -1
  61. package/dist/runtime/index.cjs +0 -107
  62. package/dist/runtime/index.d.cts +0 -72
  63. package/dist/runtime/index.d.cts.map +0 -1
  64. package/dist/runtime/index.d.ts +0 -72
  65. package/dist/runtime/index.d.ts.map +0 -1
  66. package/dist/runtime/index.js +0 -104
  67. package/dist/runtime/index.js.map +0 -1
  68. package/dist/slice-BuSNc8vw.js +0 -278
  69. package/dist/slice-BuSNc8vw.js.map +0 -1
  70. package/dist/slice-C-FIQK-f.cjs +0 -373
package/dist/index.js CHANGED
@@ -1,7 +1,53 @@
1
- import { a as createVarRefs, c as createExecutionResultParser, d as SlicedExecutionResultSuccess, f as Projection, g as getVarRefValue, h as getVarRefName, i as createVarAssignments, l as SlicedExecutionResultEmpty, m as getVarRefInner, n as handleProjectionBuilder, o as mergeVarDefinitions, p as VarRef, s as mapValues, u as SlicedExecutionResultError } from "./slice-BuSNc8vw.js";
2
- import { t as defaultMergeSliceMetadata } from "./merge-CeMx09is.js";
1
+ import { a as unsafeOutputType, i as unsafeInputType, n as defineOperationRoots, o as wrapByKey, r as defineScalar, t as define } from "./schema-BbCrsNkQ.js";
3
2
  import { Kind, OperationTypeNode } from "graphql";
4
3
 
4
+ //#region packages/core/src/types/type-foundation/var-ref.ts
5
+ var VarRef = class {
6
+ constructor(inner) {
7
+ this.inner = inner;
8
+ }
9
+ static getInner(varRef) {
10
+ return varRef.inner;
11
+ }
12
+ };
13
+ const isVarRef = (value) => {
14
+ return typeof value === "object" && value !== null && value instanceof VarRef;
15
+ };
16
+ const createVarRefFromVariable = (name) => {
17
+ return new VarRef({
18
+ type: "variable",
19
+ name
20
+ });
21
+ };
22
+ const createVarRefFromConstValue = (value) => {
23
+ return new VarRef({
24
+ type: "const-value",
25
+ value
26
+ });
27
+ };
28
+ const getVarRefInner = (varRef) => {
29
+ return VarRef.getInner(varRef);
30
+ };
31
+ /**
32
+ * Get the variable name from a VarRef.
33
+ * Throws if the VarRef contains a const-value instead of a variable reference.
34
+ */
35
+ const getVarRefName = (varRef) => {
36
+ const inner = VarRef.getInner(varRef);
37
+ if (inner.type !== "variable") throw new Error("Expected variable reference, got const-value");
38
+ return inner.name;
39
+ };
40
+ /**
41
+ * Get the const value from a VarRef.
42
+ * Throws if the VarRef contains a variable reference instead of a const-value.
43
+ */
44
+ const getVarRefValue = (varRef) => {
45
+ const inner = VarRef.getInner(varRef);
46
+ if (inner.type !== "const-value") throw new Error("Expected const-value, got variable reference");
47
+ return inner.value;
48
+ };
49
+
50
+ //#endregion
5
51
  //#region packages/core/src/composer/build-document.ts
6
52
  const buildArgumentValue = (value) => {
7
53
  if (value === void 0) return null;
@@ -236,6 +282,245 @@ const buildDocument = (options) => {
236
282
  };
237
283
  };
238
284
 
285
+ //#endregion
286
+ //#region packages/core/src/composer/colocate.ts
287
+ /**
288
+ * Creates a $colocate helper function for fragment colocation.
289
+ *
290
+ * $colocate takes an object of { label: fields } and applies prefix-based
291
+ * aliasing to each entry. This mirrors the structure of createExecutionResultParser
292
+ * from @soda-gql/colocation-tools.
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * // In operation definition
297
+ * query.operation({
298
+ * name: "GetData",
299
+ * fields: ({ $ }) => $colocate({
300
+ * userCard: userCardFragment.embed({ userId: $.userId }),
301
+ * posts: postsFragment.embed({ userId: $.userId }),
302
+ * }),
303
+ * });
304
+ *
305
+ * // In parser definition (same labels)
306
+ * createExecutionResultParser({
307
+ * userCard: userCardProjection,
308
+ * posts: postsProjection,
309
+ * });
310
+ * ```
311
+ */
312
+ const createColocateHelper = () => {
313
+ /**
314
+ * Colocate multiple field selections with labeled prefixes.
315
+ *
316
+ * @param entries - Object mapping labels to field selections
317
+ * @returns Merged object of all prefixed field entries
318
+ */
319
+ const $colocate = (entries) => Object.fromEntries(Object.entries(entries).flatMap(([label, fields]) => Object.entries(fields).map(([key, value]) => [`${label}_${key}`, value])));
320
+ return $colocate;
321
+ };
322
+
323
+ //#endregion
324
+ //#region packages/core/src/composer/field-path-context.ts
325
+ /**
326
+ * Shared mutable container for field path context.
327
+ * Only synchronous access is supported.
328
+ */
329
+ const fieldPathContext = { current: null };
330
+ /**
331
+ * Get the current field path.
332
+ * Returns null if not in a field building context.
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * import { getCurrentFieldPath } from '@soda-gql/core';
337
+ *
338
+ * // Inside a field builder or model embed:
339
+ * const path = getCurrentFieldPath();
340
+ * console.log(path?.full); // "$.user.posts[].author"
341
+ * ```
342
+ */
343
+ const getCurrentFieldPath = () => fieldPathContext.current;
344
+ /**
345
+ * Run a function with a specific field path context.
346
+ * Restores the previous path after the function completes.
347
+ *
348
+ * @internal
349
+ */
350
+ const withFieldPath = (path, fn) => {
351
+ const previousPath = fieldPathContext.current;
352
+ fieldPathContext.current = path;
353
+ try {
354
+ return fn();
355
+ } finally {
356
+ fieldPathContext.current = previousPath;
357
+ }
358
+ };
359
+ /**
360
+ * Append a new segment to the current path.
361
+ *
362
+ * @internal
363
+ */
364
+ const appendToPath = (parent, segment) => {
365
+ const listSuffix = segment.isList ? "[]" : "";
366
+ const newSegment = {
367
+ field: segment.field,
368
+ parent: segment.parentType,
369
+ isList: segment.isList
370
+ };
371
+ if (!parent) return {
372
+ full: `$.${segment.field}${listSuffix}`,
373
+ segments: [newSegment]
374
+ };
375
+ return {
376
+ full: `${parent.full}.${segment.field}${listSuffix}`,
377
+ segments: [...parent.segments, newSegment]
378
+ };
379
+ };
380
+ /**
381
+ * Check if a type specifier represents a list type.
382
+ * Matches patterns like "Type:![]!", "Type:![]?", "Type:?[]!", etc.
383
+ *
384
+ * @internal
385
+ */
386
+ const isListType = (typeString) => {
387
+ return typeString.includes("[]");
388
+ };
389
+
390
+ //#endregion
391
+ //#region packages/core/src/utils/map-values.ts
392
+ function mapValues(obj, fn) {
393
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, fn(value, key)]));
394
+ }
395
+
396
+ //#endregion
397
+ //#region packages/core/src/composer/fields-builder.ts
398
+ const cacheMapBySchema = /* @__PURE__ */ new WeakMap();
399
+ const ensureCacheMapBySchema = (schema) => {
400
+ const cachedCacheMap = cacheMapBySchema.get(schema);
401
+ if (cachedCacheMap) return cachedCacheMap;
402
+ const cacheMap = /* @__PURE__ */ new Map();
403
+ cacheMapBySchema.set(schema, cacheMap);
404
+ return cacheMap;
405
+ };
406
+ const createFieldFactories = (schema, typeName) => {
407
+ const cacheMap = ensureCacheMapBySchema(schema);
408
+ const cached = cacheMap.get(typeName);
409
+ if (cached) return cached;
410
+ const factories = createFieldFactoriesInner(schema, typeName);
411
+ cacheMap.set(typeName, factories);
412
+ return factories;
413
+ };
414
+ const createFieldFactoriesInner = (schema, typeName) => {
415
+ const typeDef = schema.object[typeName];
416
+ if (!typeDef) throw new Error(`Type ${typeName} is not defined in schema objects`);
417
+ const entries = Object.entries(typeDef.fields).map(([fieldName, type]) => {
418
+ const factory = (fieldArgs, extras) => {
419
+ const wrap = (value) => wrapByKey(extras?.alias ?? fieldName, value);
420
+ if (type.kind === "object") {
421
+ const factoryReturn = ((nest) => {
422
+ const nestedFields = withFieldPath(appendToPath(getCurrentFieldPath(), {
423
+ field: fieldName,
424
+ parentType: typeName,
425
+ isList: isListType(type.modifier)
426
+ }), () => nest({ f: createFieldFactories(schema, type.name) }));
427
+ return wrap({
428
+ parent: typeName,
429
+ field: fieldName,
430
+ type,
431
+ args: fieldArgs ?? {},
432
+ directives: extras?.directives ?? {},
433
+ object: nestedFields,
434
+ union: null
435
+ });
436
+ });
437
+ return factoryReturn;
438
+ }
439
+ if (type.kind === "union") {
440
+ const factoryReturn = ((nest) => {
441
+ const nestedUnion = withFieldPath(appendToPath(getCurrentFieldPath(), {
442
+ field: fieldName,
443
+ parentType: typeName,
444
+ isList: isListType(type.modifier)
445
+ }), () => mapValues(nest, (builder, memberName) => {
446
+ if (!builder) throw new Error(`Builder is undefined for member name: ${memberName}`);
447
+ return builder({ f: createFieldFactories(schema, memberName) });
448
+ }));
449
+ return wrap({
450
+ parent: typeName,
451
+ field: fieldName,
452
+ type,
453
+ args: fieldArgs ?? {},
454
+ directives: extras?.directives ?? {},
455
+ object: null,
456
+ union: nestedUnion
457
+ });
458
+ });
459
+ return factoryReturn;
460
+ }
461
+ if (type.kind === "scalar" || type.kind === "enum" || type.kind === "typename") return wrap({
462
+ parent: typeName,
463
+ field: fieldName,
464
+ type,
465
+ args: fieldArgs ?? {},
466
+ directives: extras?.directives ?? {},
467
+ object: null,
468
+ union: null
469
+ });
470
+ throw new Error(`Unsupported field type: ${type}`);
471
+ };
472
+ return [fieldName, factory];
473
+ });
474
+ return Object.fromEntries(entries);
475
+ };
476
+
477
+ //#endregion
478
+ //#region packages/core/src/types/element/lazy-evaluator.ts
479
+ /**
480
+ * Creates a lazy evaluator with caching, async support, and dependency ordering.
481
+ *
482
+ * @param define - Factory function that produces the value
483
+ * @param getDeps - Optional function returning dependencies to evaluate first
484
+ * @param createDepGenerator - Function to create evaluation generator for a dependency
485
+ * @returns An executor generator function
486
+ */
487
+ const createLazyEvaluator = (define$1, getDeps, createDepGenerator) => {
488
+ let cache = null;
489
+ let promise = null;
490
+ return function* execute(context) {
491
+ if (cache) return cache.value;
492
+ if (promise) {
493
+ yield promise;
494
+ return cache.value;
495
+ }
496
+ if (getDeps) for (const dep of getDeps()) yield* createDepGenerator(dep);
497
+ const defined = define$1(context);
498
+ if (!(defined instanceof Promise)) return (cache = { value: defined }).value;
499
+ promise = defined.then((value) => {
500
+ cache = { value };
501
+ promise = null;
502
+ });
503
+ yield promise;
504
+ return cache.value;
505
+ };
506
+ };
507
+ /**
508
+ * Creates an evaluation generator from an executor.
509
+ * Wraps the executor's generator and discards its return value.
510
+ */
511
+ function* createEvaluationGenerator(executor, context) {
512
+ yield* executor(context);
513
+ }
514
+ /**
515
+ * Executes the evaluator synchronously.
516
+ * Throws if async operation is encountered.
517
+ */
518
+ const evaluateSync = (executor, context) => {
519
+ const result = executor(context).next();
520
+ if (!result.done) throw new Error("Async operation is not supported in sync evaluation.");
521
+ return result.value;
522
+ };
523
+
239
524
  //#endregion
240
525
  //#region packages/core/src/types/element/gql-element.ts
241
526
  const GQL_ELEMENT_FACTORY = Symbol("GQL_ELEMENT_FACTORY");
@@ -244,40 +529,28 @@ var GqlElement = class GqlElement {
244
529
  [GQL_ELEMENT_FACTORY];
245
530
  [GQL_ELEMENT_CONTEXT] = null;
246
531
  constructor(define$1, getDeps) {
247
- let cache = null;
248
- let promise = null;
249
- this[GQL_ELEMENT_FACTORY] = function* execute(context) {
250
- if (cache) return cache.value;
251
- if (promise) {
252
- yield promise;
253
- return cache.value;
254
- }
255
- if (getDeps) for (const dep of getDeps()) yield* GqlElement.createEvaluationGenerator(dep);
256
- const defined = define$1(context);
257
- if (!(defined instanceof Promise)) return (cache = { value: defined }).value;
258
- promise = defined.then((value) => {
259
- cache = { value };
260
- promise = null;
261
- });
262
- yield promise;
263
- return cache.value;
264
- };
532
+ this[GQL_ELEMENT_FACTORY] = createLazyEvaluator(define$1, getDeps, GqlElement.createEvaluationGenerator);
265
533
  Object.defineProperty(this, "$infer", { get() {
266
534
  throw new Error("This property is only for type meta. Do not access this property directly.");
267
535
  } });
268
536
  }
537
+ attach(attachment) {
538
+ let cache = null;
539
+ Object.defineProperty(this, attachment.name, { get() {
540
+ if (cache) return cache;
541
+ GqlElement.evaluateInstantly(this);
542
+ return cache = attachment.createValue(this);
543
+ } });
544
+ return this;
545
+ }
269
546
  static setContext(element, context) {
270
547
  element[GQL_ELEMENT_CONTEXT] = context;
271
548
  }
272
- static *createEvaluationGenerator(element) {
273
- const context = element[GQL_ELEMENT_CONTEXT];
274
- yield* element[GQL_ELEMENT_FACTORY](context);
549
+ static createEvaluationGenerator(element) {
550
+ return createEvaluationGenerator(element[GQL_ELEMENT_FACTORY], element[GQL_ELEMENT_CONTEXT]);
275
551
  }
276
552
  static evaluateInstantly(element) {
277
- const context = element[GQL_ELEMENT_CONTEXT];
278
- const result = element[GQL_ELEMENT_FACTORY](context).next();
279
- if (!result.done) throw new Error("Async operation is not supported in sync evaluation.");
280
- return result.value;
553
+ return evaluateSync(element[GQL_ELEMENT_FACTORY], element[GQL_ELEMENT_CONTEXT]);
281
554
  }
282
555
  static evaluateSync(element) {
283
556
  GqlElement.evaluateInstantly(element);
@@ -288,44 +561,25 @@ var GqlElement = class GqlElement {
288
561
  };
289
562
 
290
563
  //#endregion
291
- //#region packages/core/src/types/element/composed-operation.ts
292
- var ComposedOperation = class ComposedOperation extends GqlElement {
564
+ //#region packages/core/src/types/element/fragment.ts
565
+ var Fragment = class Fragment extends GqlElement {
293
566
  constructor(define$1) {
294
567
  super(define$1);
295
568
  }
296
- get operationType() {
297
- return GqlElement.get(this).operationType;
298
- }
299
- get operationName() {
300
- return GqlElement.get(this).operationName;
301
- }
302
- get variableNames() {
303
- return GqlElement.get(this).variableNames;
304
- }
305
- get projectionPathGraph() {
306
- return GqlElement.get(this).projectionPathGraph;
307
- }
308
- get document() {
309
- return GqlElement.get(this).document;
310
- }
311
- get parse() {
312
- return GqlElement.get(this).parse;
569
+ get typename() {
570
+ return GqlElement.get(this).typename;
313
571
  }
314
- get metadata() {
315
- return GqlElement.get(this).metadata;
572
+ get embed() {
573
+ return GqlElement.get(this).embed;
316
574
  }
317
575
  static create(define$1) {
318
- return new ComposedOperation(define$1);
576
+ return new Fragment(define$1);
319
577
  }
320
578
  };
321
579
 
322
580
  //#endregion
323
- //#region packages/core/src/types/element/fields-builder.ts
324
- const mergeFields = (fields) => Object.assign({}, ...fields);
325
-
326
- //#endregion
327
- //#region packages/core/src/types/element/inline-operation.ts
328
- var InlineOperation = class InlineOperation extends GqlElement {
581
+ //#region packages/core/src/types/element/operation.ts
582
+ var Operation = class Operation extends GqlElement {
329
583
  constructor(define$1) {
330
584
  super(define$1);
331
585
  }
@@ -348,213 +602,113 @@ var InlineOperation = class InlineOperation extends GqlElement {
348
602
  return GqlElement.get(this).metadata;
349
603
  }
350
604
  static create(define$1) {
351
- return new InlineOperation(define$1);
605
+ return new Operation(define$1);
352
606
  }
353
607
  };
354
608
 
355
609
  //#endregion
356
- //#region packages/core/src/types/element/model.ts
357
- var Model = class Model extends GqlElement {
358
- constructor(define$1) {
359
- super(define$1);
360
- }
361
- get typename() {
362
- return GqlElement.get(this).typename;
363
- }
364
- get fragment() {
365
- return GqlElement.get(this).fragment;
366
- }
367
- get normalize() {
368
- return GqlElement.get(this).normalize;
369
- }
370
- static create(define$1) {
371
- return new Model(define$1);
610
+ //#region packages/core/src/composer/fragment-usage-context.ts
611
+ /**
612
+ * Shared mutable container for collecting fragment usages.
613
+ * Only synchronous access is supported.
614
+ */
615
+ const fragmentUsageContext = { current: null };
616
+ /**
617
+ * Run a function with fragment usage collection enabled.
618
+ * Returns both the function result and collected fragment usages.
619
+ *
620
+ * @internal
621
+ */
622
+ const withFragmentUsageCollection = (fn) => {
623
+ const previousCollector = fragmentUsageContext.current;
624
+ const usages = [];
625
+ fragmentUsageContext.current = usages;
626
+ try {
627
+ return {
628
+ result: fn(),
629
+ usages
630
+ };
631
+ } finally {
632
+ fragmentUsageContext.current = previousCollector;
372
633
  }
373
634
  };
374
-
375
- //#endregion
376
- //#region packages/core/src/types/element/slice.ts
377
- var Slice = class Slice extends GqlElement {
378
- constructor(define$1) {
379
- super(define$1);
380
- }
381
- get operationType() {
382
- return GqlElement.get(this).operationType;
383
- }
384
- get embed() {
385
- return GqlElement.get(this).embed;
386
- }
387
- static create(define$1) {
388
- return new Slice(define$1);
389
- }
635
+ /**
636
+ * Record a fragment usage. Called when fragment.embed() is invoked.
637
+ * No-op if not in a collection context.
638
+ *
639
+ * @internal
640
+ */
641
+ const recordFragmentUsage = (record) => {
642
+ if (fragmentUsageContext.current) fragmentUsageContext.current.push(record);
390
643
  };
391
644
 
392
645
  //#endregion
393
- //#region packages/core/src/composer/projection-path-graph.ts
394
- function createPathGraph(paths) {
395
- const intermediate = paths.reduce((acc, { label, raw, segments: [segment, ...segments] }) => {
396
- if (segment) (acc[segment] || (acc[segment] = [])).push({
397
- label,
398
- raw,
399
- segments
400
- });
401
- return acc;
402
- }, {});
403
- return {
404
- matches: paths.map(({ label, raw, segments }) => ({
405
- label,
406
- path: raw,
407
- exact: segments.length === 0
408
- })),
409
- children: mapValues(intermediate, (paths$1) => createPathGraph(paths$1))
410
- };
411
- }
412
- function createPathGraphFromSliceEntries(fragments) {
413
- return createPathGraph(Object.entries(fragments).flatMap(([label, slice]) => Array.from(new Map(slice.projection.paths.map(({ full: raw, segments }) => {
414
- const [first, ...rest] = segments;
415
- return [raw, {
416
- label,
417
- raw,
418
- segments: [`${label}_${first}`, ...rest]
419
- }];
420
- })).values())));
421
- }
646
+ //#region packages/core/src/composer/input.ts
647
+ const createVarAssignments = (definitions, providedValues) => {
648
+ return mapValues(definitions, (_definition, key) => {
649
+ const varName = key;
650
+ if (!providedValues || providedValues[varName] === void 0) return createVarRefFromConstValue(void 0);
651
+ const provided = providedValues[varName];
652
+ if (isVarRef(provided)) return provided;
653
+ return createVarRefFromConstValue(provided);
654
+ });
655
+ };
656
+ const createVarRefs = (definitions) => mapValues(definitions, (_ref, name) => createVarRefFromVariable(name));
422
657
 
423
658
  //#endregion
424
- //#region packages/core/src/composer/composed-operation.ts
425
- const createComposedOperationComposerFactory = (options = {}) => {
426
- const { metadataAdapter } = options;
427
- return (operationType) => {
428
- return (options$1, builder) => {
429
- return ComposedOperation.create(() => {
430
- const { operationName } = options$1;
431
- const variables = mergeVarDefinitions(options$1.variables ?? []);
432
- const $ = createVarRefs(variables);
433
- const fragments = builder({ $ });
434
- const fields = Object.fromEntries(Object.entries(fragments).flatMap(([label, { getFields: fields$1 }]) => Object.entries(fields$1).map(([key, reference]) => [`${label}_${key}`, reference])));
435
- const projectionPathGraph = createPathGraphFromSliceEntries(fragments);
436
- const document = buildDocument({
437
- operationName,
438
- operationType,
439
- variables,
440
- fields
441
- });
442
- const operationMetadataResult = options$1.metadata?.({
443
- $,
444
- document
445
- });
446
- const sliceMetadataResults = Object.values(fragments).map((fragment) => fragment.metadata).filter((m) => m != null);
447
- const mergeSliceMetadata = metadataAdapter?.mergeSliceMetadata ?? defaultMergeSliceMetadata;
448
- const createDefinition = (operationMetadata, sliceMetadataList) => {
449
- const metadata = mergeSliceMetadata(operationMetadata ?? {}, sliceMetadataList);
450
- return {
451
- operationType,
452
- operationName,
453
- variableNames: Object.keys(variables),
454
- projectionPathGraph,
455
- document,
456
- parse: createExecutionResultParser({
457
- fragments,
458
- projectionPathGraph
459
- }),
460
- metadata: Object.keys(metadata).length > 0 ? metadata : void 0
461
- };
462
- };
463
- const hasAsyncOperationMetadata = operationMetadataResult instanceof Promise;
464
- const hasAsyncSliceMetadata = sliceMetadataResults.some((m) => m instanceof Promise);
465
- if (hasAsyncOperationMetadata || hasAsyncSliceMetadata) return Promise.all([hasAsyncOperationMetadata ? operationMetadataResult : Promise.resolve(operationMetadataResult), Promise.all(sliceMetadataResults.map((m) => m instanceof Promise ? m : Promise.resolve(m)))]).then(([operationMetadata, sliceMetadataList]) => createDefinition(operationMetadata, sliceMetadataList));
466
- return createDefinition(operationMetadataResult, sliceMetadataResults);
467
- });
659
+ //#region packages/core/src/composer/fragment.ts
660
+ const createGqlFragmentComposers = (schema, _adapter) => {
661
+ const createFragmentComposer = (typename) => {
662
+ return (options) => {
663
+ const varDefinitions = options.variables ?? {};
664
+ const { metadata, fields } = options;
665
+ return Fragment.create(() => ({
666
+ typename,
667
+ embed: (variables) => {
668
+ const f = createFieldFactories(schema, typename);
669
+ const $ = createVarAssignments(varDefinitions, variables);
670
+ recordFragmentUsage({
671
+ metadataBuilder: metadata ? () => metadata({ $ }) : null,
672
+ path: getCurrentFieldPath()
673
+ });
674
+ return fields({
675
+ f,
676
+ $
677
+ });
678
+ }
679
+ }));
468
680
  };
469
681
  };
682
+ return mapValues(schema.object, (_, typename) => createFragmentComposer(typename));
470
683
  };
471
684
 
472
685
  //#endregion
473
- //#region packages/core/src/utils/wrap-by-key.ts
474
- function wrapByKey(name, value) {
475
- return { [name]: value };
476
- }
477
-
478
- //#endregion
479
- //#region packages/core/src/composer/fields-builder.ts
480
- const cacheMapBySchema = /* @__PURE__ */ new WeakMap();
481
- const ensureCacheMapBySchema = (schema) => {
482
- const cachedCacheMap = cacheMapBySchema.get(schema);
483
- if (cachedCacheMap) return cachedCacheMap;
484
- const cacheMap = /* @__PURE__ */ new Map();
485
- cacheMapBySchema.set(schema, cacheMap);
486
- return cacheMap;
487
- };
488
- const createFieldFactories = (schema, typeName) => {
489
- const cacheMap = ensureCacheMapBySchema(schema);
490
- const cached = cacheMap.get(typeName);
491
- if (cached) return cached;
492
- const factories = createFieldFactoriesInner(schema, typeName);
493
- cacheMap.set(typeName, factories);
494
- return factories;
495
- };
496
- const createFieldFactoriesInner = (schema, typeName) => {
497
- const typeDef = schema.object[typeName];
498
- if (!typeDef) throw new Error(`Type ${typeName} is not defined in schema objects`);
499
- const entries = Object.entries(typeDef.fields).map(([fieldName, type]) => {
500
- const factory = (fieldArgs, extras) => {
501
- const wrap = (value) => wrapByKey(extras?.alias ?? fieldName, value);
502
- if (type.kind === "object") {
503
- const factoryReturn = ((nest) => wrap({
504
- parent: typeName,
505
- field: fieldName,
506
- type,
507
- args: fieldArgs ?? {},
508
- directives: extras?.directives ?? {},
509
- object: mergeFields(nest({ f: createFieldFactories(schema, type.name) })),
510
- union: null
511
- }));
512
- return factoryReturn;
513
- }
514
- if (type.kind === "union") {
515
- const factoryReturn = ((nest) => wrap({
516
- parent: typeName,
517
- field: fieldName,
518
- type,
519
- args: fieldArgs ?? {},
520
- directives: extras?.directives ?? {},
521
- object: null,
522
- union: mapValues(nest, (builder, memberName) => {
523
- if (!builder) throw new Error(`Builder is undefined for member name: ${memberName}`);
524
- return mergeFields(builder({ f: createFieldFactories(schema, memberName) }));
525
- })
526
- }));
527
- return factoryReturn;
528
- }
529
- if (type.kind === "scalar" || type.kind === "enum" || type.kind === "typename") return wrap({
530
- parent: typeName,
531
- field: fieldName,
532
- type,
533
- args: fieldArgs ?? {},
534
- directives: extras?.directives ?? {},
535
- object: null,
536
- union: null
537
- });
538
- throw new Error(`Unsupported field type: ${type}`);
539
- };
540
- return [fieldName, factory];
541
- });
542
- return Object.fromEntries(entries);
543
- };
686
+ //#region packages/core/src/types/metadata/adapter.ts
687
+ /**
688
+ * Creates the default adapter instance.
689
+ * @internal
690
+ */
691
+ const createDefaultAdapter = () => ({ aggregateFragmentMetadata: (fragments) => fragments.map((m) => m.metadata) });
692
+ /**
693
+ * The default adapter instance.
694
+ */
695
+ const defaultMetadataAdapter = createDefaultAdapter();
544
696
 
545
697
  //#endregion
546
- //#region packages/core/src/composer/inline-operation.ts
547
- const createInlineOperationComposerFactory = (schema) => {
698
+ //#region packages/core/src/composer/operation.ts
699
+ const createOperationComposerFactory = (schema, adapter) => {
700
+ const resolvedAdapter = adapter ?? defaultMetadataAdapter;
548
701
  return (operationType) => {
549
702
  const operationTypeName = schema.operations[operationType];
550
703
  if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
551
- return (options, fieldBuilder) => {
552
- return InlineOperation.create(() => {
553
- const { operationName } = options;
554
- const variables = mergeVarDefinitions(options.variables ?? []);
704
+ return (options) => {
705
+ return Operation.create(() => {
706
+ const { name: operationName } = options;
707
+ const variables = options.variables ?? {};
555
708
  const $ = createVarRefs(variables);
556
- const fields = mergeFields(fieldBuilder({
557
- f: createFieldFactories(schema, operationTypeName),
709
+ const f = createFieldFactories(schema, operationTypeName);
710
+ const { result: fields, usages: fragmentUsages } = withFragmentUsageCollection(() => options.fields({
711
+ f,
558
712
  $
559
713
  }));
560
714
  const document = buildDocument({
@@ -563,10 +717,6 @@ const createInlineOperationComposerFactory = (schema) => {
563
717
  variables,
564
718
  fields
565
719
  });
566
- const metadataResult = options.metadata?.({
567
- $,
568
- document
569
- });
570
720
  const createDefinition = (metadata) => ({
571
721
  operationType,
572
722
  operationName,
@@ -575,133 +725,85 @@ const createInlineOperationComposerFactory = (schema) => {
575
725
  document,
576
726
  metadata
577
727
  });
578
- if (metadataResult instanceof Promise) return metadataResult.then(createDefinition);
579
- return createDefinition(metadataResult);
728
+ if (!fragmentUsages.some((u) => u.metadataBuilder) && !options.metadata) return createDefinition(void 0);
729
+ const fragmentMetadataResults = fragmentUsages.map((usage) => usage.metadataBuilder ? usage.metadataBuilder() : void 0);
730
+ const hasAsyncFragmentMetadata = fragmentMetadataResults.some((r) => r instanceof Promise);
731
+ const buildOperationMetadata = (resolvedFragmentMetadata) => {
732
+ const fragmentMetaInfos = fragmentUsages.map((usage, index) => ({
733
+ metadata: resolvedFragmentMetadata[index],
734
+ fieldPath: usage.path
735
+ }));
736
+ const aggregatedFragmentMetadata = resolvedAdapter.aggregateFragmentMetadata(fragmentMetaInfos);
737
+ const schemaLevel = resolvedAdapter.schemaLevel;
738
+ return options.metadata?.({
739
+ $,
740
+ document,
741
+ fragmentMetadata: aggregatedFragmentMetadata,
742
+ schemaLevel
743
+ });
744
+ };
745
+ if (hasAsyncFragmentMetadata) return Promise.all(fragmentMetadataResults).then(async (resolvedFragmentMetadata) => {
746
+ return createDefinition(await buildOperationMetadata(resolvedFragmentMetadata));
747
+ });
748
+ const operationMetadataResult = buildOperationMetadata(fragmentMetadataResults);
749
+ if (operationMetadataResult instanceof Promise) return operationMetadataResult.then(createDefinition);
750
+ return createDefinition(operationMetadataResult);
580
751
  });
581
752
  };
582
753
  };
583
754
  };
584
755
 
585
- //#endregion
586
- //#region packages/core/src/composer/model.ts
587
- const createGqlModelComposers = (schema) => {
588
- const createModelComposer = (typename) => {
589
- return (options, builder, normalize) => Model.create(() => {
590
- const varDefinitions = mergeVarDefinitions(options.variables ?? []);
591
- return {
592
- typename,
593
- fragment: (variables) => {
594
- return mergeFields(builder({
595
- f: createFieldFactories(schema, typename),
596
- $: createVarAssignments(varDefinitions, variables)
597
- }));
598
- },
599
- normalize
600
- };
601
- });
602
- };
603
- return mapValues(schema.object, (_, typename) => createModelComposer(typename));
604
- };
605
-
606
- //#endregion
607
- //#region packages/core/src/composer/slice.ts
608
- const createSliceComposerFactory = (schema) => {
609
- return (operationType) => {
610
- const operationTypeName = schema.operations[operationType];
611
- if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
612
- return (options, fieldBuilder, projectionBuilder) => Slice.create(() => {
613
- const varDefinitions = mergeVarDefinitions(options.variables ?? []);
614
- const projection = handleProjectionBuilder(projectionBuilder);
615
- const { metadata: metadataOption } = options;
616
- return {
617
- operationType,
618
- embed: (variables) => {
619
- const f = createFieldFactories(schema, operationTypeName);
620
- const $ = createVarAssignments(varDefinitions, variables);
621
- const fields = mergeFields(fieldBuilder({
622
- f,
623
- $
624
- }));
625
- return {
626
- variables,
627
- getFields: () => fields,
628
- projection,
629
- metadata: metadataOption?.({ $ })
630
- };
631
- }
632
- };
633
- });
634
- };
635
- };
636
-
637
- //#endregion
638
- //#region packages/core/src/types/type-foundation/modified-type-name.ts
639
- function parseModifiedTypeName(nameAndModifier) {
640
- if (typeof nameAndModifier !== "string") throw new Error(`Invalid modified type name: ${nameAndModifier}`);
641
- const [name, modifier] = nameAndModifier.split(":");
642
- return {
643
- name,
644
- modifier
645
- };
646
- }
647
-
648
756
  //#endregion
649
757
  //#region packages/core/src/composer/var-builder.ts
650
- const createVarBuilder = (schema) => {
758
+ /**
759
+ * Creates a variable method for a specific input type.
760
+ * This is used by codegen to generate type-specific variable methods.
761
+ */
762
+ const createVarMethod = (kind, typeName) => {
763
+ return (modifier, extras) => ({
764
+ kind,
765
+ name: typeName,
766
+ modifier,
767
+ defaultValue: extras?.default ? { default: extras.default() } : null,
768
+ directives: extras?.directives ?? {}
769
+ });
770
+ };
771
+ /**
772
+ * Creates a variable builder that uses injected input type methods.
773
+ */
774
+ const createVarBuilder = (inputTypeMethods) => {
651
775
  const varBuilder = (varName) => {
652
- const createVarSpecifierBuilder = (kind) => {
653
- return (type, extras) => wrapByKey(varName, {
654
- kind,
655
- ...parseModifiedTypeName(type),
656
- defaultValue: extras?.default ? { default: extras.default() } : null
657
- });
658
- };
659
- return {
660
- scalar: createVarSpecifierBuilder("scalar"),
661
- enum: createVarSpecifierBuilder("enum"),
662
- input: createVarSpecifierBuilder("input"),
663
- byField: (typeName, fieldName, argName) => {
664
- const argTypeRef = schema.object[typeName]?.fields[fieldName]?.arguments[argName];
665
- if (!argTypeRef) throw new Error(`Argument ${argName} not found in field ${fieldName} of type ${typeName}`);
666
- return { ...argTypeRef };
667
- }
668
- };
776
+ const wrappedMethods = {};
777
+ for (const [typeName, method] of Object.entries(inputTypeMethods)) Object.defineProperty(wrappedMethods, typeName, {
778
+ value: ((modifier, extras) => wrapByKey(varName, method(modifier, extras))),
779
+ writable: false,
780
+ configurable: true
781
+ });
782
+ return wrappedMethods;
669
783
  };
670
- return { $var: Object.assign(varBuilder, {
671
- getName: getVarRefName,
672
- getValue: getVarRefValue,
673
- getInner: getVarRefInner
674
- }) };
784
+ varBuilder.getName = getVarRefName;
785
+ varBuilder.getValue = getVarRefValue;
786
+ varBuilder.getInner = getVarRefInner;
787
+ return varBuilder;
675
788
  };
676
789
 
677
790
  //#endregion
678
791
  //#region packages/core/src/composer/gql-composer.ts
679
- const createGqlElementComposer = (schema, options = {}) => {
680
- const { metadataAdapter, helpers } = options;
681
- const model = createGqlModelComposers(schema);
682
- const createSliceComposer = createSliceComposerFactory(schema);
683
- const createComposedOperationFactory = createComposedOperationComposerFactory({ metadataAdapter });
684
- const createInlineOperationComposer = createInlineOperationComposerFactory(schema);
792
+ const createGqlElementComposer = (schema, options) => {
793
+ const { adapter, inputTypeMethods } = options;
794
+ const helpers = adapter?.helpers;
795
+ const metadataAdapter = adapter?.metadata;
796
+ const fragment = createGqlFragmentComposers(schema, metadataAdapter);
797
+ const createOperationComposer = createOperationComposerFactory(schema, metadataAdapter);
685
798
  const composers = {
686
- model,
687
- query: {
688
- slice: createSliceComposer("query"),
689
- composed: createComposedOperationFactory("query"),
690
- inline: createInlineOperationComposer("query")
691
- },
692
- mutation: {
693
- slice: createSliceComposer("mutation"),
694
- composed: createComposedOperationFactory("mutation"),
695
- inline: createInlineOperationComposer("mutation")
696
- },
697
- subscription: {
698
- slice: createSliceComposer("subscription"),
699
- composed: createComposedOperationFactory("subscription"),
700
- inline: createInlineOperationComposer("subscription")
701
- }
799
+ fragment,
800
+ query: { operation: createOperationComposer("query") },
801
+ mutation: { operation: createOperationComposer("mutation") },
802
+ subscription: { operation: createOperationComposer("subscription") }
702
803
  };
703
804
  const helper = {
704
- ...createVarBuilder(schema),
805
+ $var: createVarBuilder(inputTypeMethods),
806
+ $colocate: createColocateHelper(),
705
807
  ...helpers ?? {}
706
808
  };
707
809
  const elementComposer = (composeElement) => composeElement(composers, helper);
@@ -709,92 +811,5 @@ const createGqlElementComposer = (schema, options = {}) => {
709
811
  };
710
812
 
711
813
  //#endregion
712
- //#region packages/core/src/composer/helpers.ts
713
- /**
714
- * Helper function for defining typed helpers with better inference.
715
- * Use this when you need explicit typing or when type inference needs assistance.
716
- *
717
- * @example
718
- * ```typescript
719
- * const gql = createGqlElementComposer(schema, {
720
- * helpers: defineHelpers({
721
- * auth: {
722
- * requiresLogin: () => ({ requiresAuth: true }),
723
- * adminOnly: () => ({ requiresAuth: true, role: 'admin' }),
724
- * },
725
- * }),
726
- * });
727
- * ```
728
- */
729
- const defineHelpers = (helpers) => helpers;
730
-
731
- //#endregion
732
- //#region packages/core/src/utils/type-meta.ts
733
- const withTypeMeta = (target) => {
734
- if (process.env.NODE_ENV !== "production") {
735
- if (typeof target !== "object" && typeof target !== "function" || target === null) throw new Error("Target must be an object or a function.");
736
- Object.defineProperty(target, "$type", { get() {
737
- throw new Error("This property is only for type inference. Do not access this property directly.");
738
- } });
739
- }
740
- return target;
741
- };
742
-
743
- //#endregion
744
- //#region packages/core/src/schema/type-specifier-builder.ts
745
- const createUnsafeInputTypeSpecifierFactory = (kind) => {
746
- return (type, extras) => ({
747
- kind,
748
- ...parseModifiedTypeName(type),
749
- defaultValue: extras.default ? { default: extras.default() } : null
750
- });
751
- };
752
- const unsafeInputType = {
753
- scalar: createUnsafeInputTypeSpecifierFactory("scalar"),
754
- enum: createUnsafeInputTypeSpecifierFactory("enum"),
755
- input: createUnsafeInputTypeSpecifierFactory("input")
756
- };
757
- const createUnsafeOutputTypeSpecifierFactory = (kind) => {
758
- return (type, extras) => ({
759
- kind,
760
- ...parseModifiedTypeName(type),
761
- arguments: extras.arguments ?? {}
762
- });
763
- };
764
- const unsafeOutputType = {
765
- scalar: createUnsafeOutputTypeSpecifierFactory("scalar"),
766
- enum: createUnsafeOutputTypeSpecifierFactory("enum"),
767
- object: createUnsafeOutputTypeSpecifierFactory("object"),
768
- union: createUnsafeOutputTypeSpecifierFactory("union"),
769
- typename: createUnsafeOutputTypeSpecifierFactory("typename")
770
- };
771
-
772
- //#endregion
773
- //#region packages/core/src/schema/schema-builder.ts
774
- const defineScalar = (name) => wrapByKey(name, withTypeMeta({ name }));
775
- const define = (name) => ({
776
- enum: (values) => withTypeMeta({
777
- name,
778
- values
779
- }),
780
- input: (fields) => ({
781
- name,
782
- fields
783
- }),
784
- object: (fields) => ({
785
- name,
786
- fields: {
787
- __typename: unsafeOutputType.typename(`${name}:!`, {}),
788
- ...fields
789
- }
790
- }),
791
- union: (types) => ({
792
- name,
793
- types
794
- })
795
- });
796
- const defineOperationRoots = (operationRoots) => operationRoots;
797
-
798
- //#endregion
799
- export { ComposedOperation, GqlElement, InlineOperation, Model, Projection, Slice, SlicedExecutionResultEmpty, SlicedExecutionResultError, SlicedExecutionResultSuccess, buildArgumentValue, buildConstValueNode, buildDocument, buildOperationTypeNode, buildWithTypeModifier, createComposedOperationComposerFactory, createFieldFactories, createGqlElementComposer, createGqlModelComposers, createPathGraphFromSliceEntries, createSliceComposerFactory, createVarAssignments, createVarBuilder, createVarRefs, define, defineHelpers, defineOperationRoots, defineScalar, getVarRefInner, getVarRefName, getVarRefValue, mergeFields, mergeVarDefinitions, unsafeInputType, unsafeOutputType };
814
+ export { Fragment, GqlElement, Operation, appendToPath, buildArgumentValue, buildConstValueNode, buildDocument, buildOperationTypeNode, buildWithTypeModifier, createColocateHelper, createDefaultAdapter, createFieldFactories, createGqlElementComposer, createGqlFragmentComposers, createOperationComposerFactory, createVarAssignments, createVarBuilder, createVarMethod, createVarRefs, defaultMetadataAdapter, define, defineOperationRoots, defineScalar, getCurrentFieldPath, getVarRefInner, getVarRefName, getVarRefValue, isListType, recordFragmentUsage, unsafeInputType, unsafeOutputType, withFieldPath, withFragmentUsageCollection };
800
815
  //# sourceMappingURL=index.js.map