@soda-gql/core 0.8.0 → 0.8.2

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 (45) hide show
  1. package/dist/adapter.cjs +1 -1
  2. package/dist/adapter.d.cts +2 -2
  3. package/dist/adapter.d.ts +2 -2
  4. package/dist/adapter.js +1 -1
  5. package/dist/{index-rBHv6RJz.d.ts → index-CGLXqMlv.d.cts} +386 -28
  6. package/dist/index-CGLXqMlv.d.cts.map +1 -0
  7. package/dist/{index-x4fr7bdv.d.cts → index-tyIBKIKa.d.ts} +386 -28
  8. package/dist/index-tyIBKIKa.d.ts.map +1 -0
  9. package/dist/index.cjs +244 -12
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +43 -4
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.ts +43 -4
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +244 -12
  16. package/dist/index.js.map +1 -1
  17. package/dist/runtime.cjs +16 -10
  18. package/dist/runtime.cjs.map +1 -1
  19. package/dist/runtime.d.cts +2 -2
  20. package/dist/runtime.d.ts +2 -2
  21. package/dist/runtime.js +16 -10
  22. package/dist/runtime.js.map +1 -1
  23. package/dist/{schema-CFMmSBhl.d.ts → schema-2qqtKss4.d.ts} +39 -37
  24. package/dist/schema-2qqtKss4.d.ts.map +1 -0
  25. package/dist/{schema-BbCrsNkQ.js → schema-BiYcVVvm.js} +86 -1
  26. package/dist/schema-BiYcVVvm.js.map +1 -0
  27. package/dist/{schema-C1lnWj-m.d.cts → schema-CPTxQbTv.d.cts} +39 -37
  28. package/dist/schema-CPTxQbTv.d.cts.map +1 -0
  29. package/dist/{schema-DuWaRhdp.cjs → schema-D2MW4DOF.cjs} +86 -1
  30. package/dist/schema-D2MW4DOF.cjs.map +1 -0
  31. package/dist/schema-builder-BYJd50o2.d.cts +97 -0
  32. package/dist/schema-builder-BYJd50o2.d.cts.map +1 -0
  33. package/dist/schema-builder-Dhss2O1I.d.ts +97 -0
  34. package/dist/schema-builder-Dhss2O1I.d.ts.map +1 -0
  35. package/package.json +1 -1
  36. package/dist/index-rBHv6RJz.d.ts.map +0 -1
  37. package/dist/index-x4fr7bdv.d.cts.map +0 -1
  38. package/dist/schema-BbCrsNkQ.js.map +0 -1
  39. package/dist/schema-C1lnWj-m.d.cts.map +0 -1
  40. package/dist/schema-CFMmSBhl.d.ts.map +0 -1
  41. package/dist/schema-DuWaRhdp.cjs.map +0 -1
  42. package/dist/schema-builder-CQa-dOw9.d.ts +0 -40
  43. package/dist/schema-builder-CQa-dOw9.d.ts.map +0 -1
  44. package/dist/schema-builder-QkY6hZn6.d.cts +0 -40
  45. package/dist/schema-builder-QkY6hZn6.d.cts.map +0 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as unsafeOutputType, i as unsafeInputType, n as defineOperationRoots, o as wrapByKey, r as defineScalar, t as define } from "./schema-BbCrsNkQ.js";
1
+ import { a as unsafeOutputType, i as unsafeInputType, n as defineOperationRoots, o as wrapByKey, r as defineScalar, t as define } from "./schema-BiYcVVvm.js";
2
2
  import { Kind, OperationTypeNode } from "graphql";
3
3
 
4
4
  //#region packages/core/src/types/type-foundation/var-ref.ts
@@ -33,6 +33,12 @@ function createVarRefFromNestedValue(value) {
33
33
 
34
34
  //#endregion
35
35
  //#region packages/core/src/composer/build-document.ts
36
+ /**
37
+ * Converts an assignable input value to a GraphQL AST ValueNode.
38
+ *
39
+ * Handles primitives, arrays, objects, and variable references.
40
+ * Returns null for undefined values (field is omitted).
41
+ */
36
42
  const buildArgumentValue = (value) => {
37
43
  if (value === void 0) return null;
38
44
  if (value === null) return { kind: Kind.NULL };
@@ -126,6 +132,12 @@ const buildField = (field) => Object.entries(field).map(([alias, { args, field:
126
132
  selections: buildUnionSelection(union)
127
133
  } : void 0
128
134
  }));
135
+ /**
136
+ * Converts a constant value to a GraphQL AST ConstValueNode.
137
+ *
138
+ * Unlike `buildArgumentValue`, this only handles literal values
139
+ * (no variable references). Used for default values.
140
+ */
129
141
  const buildConstValueNode = (value) => {
130
142
  if (value === void 0) return null;
131
143
  if (value === null) return { kind: Kind.NULL };
@@ -161,6 +173,18 @@ const buildConstValueNode = (value) => {
161
173
  };
162
174
  throw new Error(`Unknown value type: ${typeof value}`);
163
175
  };
176
+ /**
177
+ * Wraps a named type with modifiers (non-null, list).
178
+ *
179
+ * Modifier format: starts with `?` (nullable) or `!` (non-null),
180
+ * followed by `[]?` or `[]!` pairs for lists.
181
+ *
182
+ * @example
183
+ * - `"!"` → `String!`
184
+ * - `"?"` → `String`
185
+ * - `"![]!"` → `[String!]!`
186
+ * - `"?[]?"` → `[String]`
187
+ */
164
188
  const buildWithTypeModifier = (modifier, buildType) => {
165
189
  const baseType = buildType();
166
190
  if (modifier === "?") return baseType;
@@ -238,6 +262,9 @@ const buildVariables = (variables) => {
238
262
  }))
239
263
  }));
240
264
  };
265
+ /**
266
+ * Converts an operation type string to a GraphQL AST OperationTypeNode.
267
+ */
241
268
  const buildOperationTypeNode = (operation) => {
242
269
  switch (operation) {
243
270
  case "query": return OperationTypeNode.QUERY;
@@ -246,6 +273,16 @@ const buildOperationTypeNode = (operation) => {
246
273
  default: throw new Error(`Unknown operation type: ${operation}`);
247
274
  }
248
275
  };
276
+ /**
277
+ * Builds a TypedDocumentNode from operation options.
278
+ *
279
+ * This is the main entry point for converting field selections into
280
+ * a GraphQL document AST. The result can be used with any GraphQL
281
+ * client that supports TypedDocumentNode.
282
+ *
283
+ * @param options - Operation configuration (name, type, variables, fields)
284
+ * @returns TypedDocumentNode with inferred input/output types
285
+ */
249
286
  const buildDocument = (options) => {
250
287
  const { operationName, operationType, variables, fields } = options;
251
288
  return {
@@ -387,6 +424,18 @@ const ensureCacheMapBySchema = (schema) => {
387
424
  cacheMapBySchema.set(schema, cacheMap);
388
425
  return cacheMap;
389
426
  };
427
+ /**
428
+ * Creates field selection factories for a given object type.
429
+ *
430
+ * Returns an object with a factory for each field defined on the type.
431
+ * Factories are cached per schema+type to avoid recreation.
432
+ *
433
+ * @param schema - The GraphQL schema definition
434
+ * @param typeName - The object type name to create factories for
435
+ * @returns Object mapping field names to their selection factories
436
+ *
437
+ * @internal Used by operation and fragment composers
438
+ */
390
439
  const createFieldFactories = (schema, typeName) => {
391
440
  const cacheMap = ensureCacheMapBySchema(schema);
392
441
  const cached = cacheMap.get(typeName);
@@ -509,6 +558,15 @@ const evaluateSync = (executor, context) => {
509
558
  //#region packages/core/src/types/element/gql-element.ts
510
559
  const GQL_ELEMENT_FACTORY = Symbol("GQL_ELEMENT_FACTORY");
511
560
  const GQL_ELEMENT_CONTEXT = Symbol("GQL_ELEMENT_CONTEXT");
561
+ /**
562
+ * Abstract base class for all GraphQL elements (Fragment, Operation).
563
+ *
564
+ * Uses lazy evaluation with caching - definition is computed on first access.
565
+ * Subclasses should not be instantiated directly; use static `create` methods.
566
+ *
567
+ * @template TDefinition - The shape of the evaluated definition
568
+ * @template TInfer - Type inference metadata (access via `$infer`)
569
+ */
512
570
  var GqlElement = class GqlElement {
513
571
  [GQL_ELEMENT_FACTORY];
514
572
  [GQL_ELEMENT_CONTEXT] = null;
@@ -518,30 +576,55 @@ var GqlElement = class GqlElement {
518
576
  throw new Error("This property is only for type meta. Do not access this property directly.");
519
577
  } });
520
578
  }
521
- attach(attachment) {
522
- let cache = null;
523
- Object.defineProperty(this, attachment.name, { get() {
524
- if (cache) return cache;
525
- GqlElement.evaluateInstantly(this);
526
- return cache = attachment.createValue(this);
527
- } });
579
+ attach(attachmentOrAttachments) {
580
+ const attachments = Array.isArray(attachmentOrAttachments) ? attachmentOrAttachments : [attachmentOrAttachments];
581
+ for (const attachment of attachments) {
582
+ let cache = null;
583
+ const self = this;
584
+ Object.defineProperty(this, attachment.name, { get() {
585
+ if (cache) return cache;
586
+ GqlElement.evaluateInstantly(self);
587
+ return cache = attachment.createValue(self);
588
+ } });
589
+ }
528
590
  return this;
529
591
  }
592
+ /**
593
+ * Sets the canonical context for an element. Used by the builder.
594
+ * @internal
595
+ */
530
596
  static setContext(element, context) {
531
597
  element[GQL_ELEMENT_CONTEXT] = context;
532
598
  }
599
+ /**
600
+ * Gets the canonical context of an element, if set.
601
+ * @internal
602
+ */
533
603
  static getContext(element) {
534
604
  return element[GQL_ELEMENT_CONTEXT];
535
605
  }
606
+ /**
607
+ * Creates a generator for async evaluation. Used by the builder.
608
+ * @internal
609
+ */
536
610
  static createEvaluationGenerator(element) {
537
611
  return createEvaluationGenerator(element[GQL_ELEMENT_FACTORY], element[GQL_ELEMENT_CONTEXT]);
538
612
  }
539
613
  static evaluateInstantly(element) {
540
614
  return evaluateSync(element[GQL_ELEMENT_FACTORY], element[GQL_ELEMENT_CONTEXT]);
541
615
  }
616
+ /**
617
+ * Forces synchronous evaluation. Throws if async operation is needed.
618
+ * @internal
619
+ */
542
620
  static evaluateSync(element) {
543
621
  GqlElement.evaluateInstantly(element);
544
622
  }
623
+ /**
624
+ * Evaluates and returns the element's definition.
625
+ * Throws if async operation is needed.
626
+ * @internal
627
+ */
545
628
  static get(element) {
546
629
  return GqlElement.evaluateInstantly(element);
547
630
  }
@@ -549,16 +632,37 @@ var GqlElement = class GqlElement {
549
632
 
550
633
  //#endregion
551
634
  //#region packages/core/src/types/element/fragment.ts
635
+ /**
636
+ * Represents a reusable GraphQL field selection on a specific type.
637
+ *
638
+ * Fragments are created via `gql(({ fragment }) => fragment.TypeName({ ... }))`.
639
+ * Use `spread()` to include the fragment's fields in an operation.
640
+ *
641
+ * @template TTypeName - The GraphQL type this fragment selects from
642
+ * @template TVariables - Variables required when spreading
643
+ * @template TFields - The selected fields structure
644
+ * @template TOutput - Inferred output type from selected fields
645
+ */
552
646
  var Fragment = class Fragment extends GqlElement {
553
647
  constructor(define$1) {
554
648
  super(define$1);
555
649
  }
650
+ /** The GraphQL type name this fragment selects from. */
556
651
  get typename() {
557
652
  return GqlElement.get(this).typename;
558
653
  }
654
+ /**
655
+ * Spreads this fragment's fields into a parent selection.
656
+ * Pass variables if the fragment defines any.
657
+ */
559
658
  get spread() {
560
659
  return GqlElement.get(this).spread;
561
660
  }
661
+ /**
662
+ * Creates a new Fragment instance.
663
+ * Prefer using the `gql(({ fragment }) => ...)` API instead.
664
+ * @internal
665
+ */
562
666
  static create(define$1) {
563
667
  return new Fragment(define$1);
564
668
  }
@@ -566,28 +670,55 @@ var Fragment = class Fragment extends GqlElement {
566
670
 
567
671
  //#endregion
568
672
  //#region packages/core/src/types/element/operation.ts
673
+ /**
674
+ * Represents a GraphQL operation (query, mutation, or subscription).
675
+ *
676
+ * Operations are created via `gql(({ query }) => query.operation({ ... }))`.
677
+ * Produces a TypedDocumentNode for type-safe execution with GraphQL clients.
678
+ *
679
+ * @template TOperationType - 'query' | 'mutation' | 'subscription'
680
+ * @template TOperationName - The unique operation name
681
+ * @template TVariableNames - Tuple of variable names
682
+ * @template TVariables - Variable types for the operation
683
+ * @template TFields - Selected fields structure
684
+ * @template TData - Inferred response data type
685
+ */
569
686
  var Operation = class Operation extends GqlElement {
570
687
  constructor(define$1) {
571
688
  super(define$1);
572
689
  }
690
+ /** The operation type: 'query', 'mutation', or 'subscription'. */
573
691
  get operationType() {
574
692
  return GqlElement.get(this).operationType;
575
693
  }
694
+ /** The unique name of this operation. */
576
695
  get operationName() {
577
696
  return GqlElement.get(this).operationName;
578
697
  }
698
+ /** List of variable names defined for this operation. */
579
699
  get variableNames() {
580
700
  return GqlElement.get(this).variableNames;
581
701
  }
702
+ /**
703
+ * Returns the field selections. Used for document reconstruction.
704
+ * @internal
705
+ */
582
706
  get documentSource() {
583
707
  return GqlElement.get(this).documentSource;
584
708
  }
709
+ /** The TypedDocumentNode for use with GraphQL clients. */
585
710
  get document() {
586
711
  return GqlElement.get(this).document;
587
712
  }
713
+ /** Custom metadata attached to this operation, if any. */
588
714
  get metadata() {
589
715
  return GqlElement.get(this).metadata;
590
716
  }
717
+ /**
718
+ * Creates a new Operation instance.
719
+ * Prefer using the `gql(({ query }) => ...)` API instead.
720
+ * @internal
721
+ */
591
722
  static create(define$1) {
592
723
  return new Operation(define$1);
593
724
  }
@@ -631,6 +762,21 @@ const recordFragmentUsage = (record) => {
631
762
 
632
763
  //#endregion
633
764
  //#region packages/core/src/composer/input.ts
765
+ /**
766
+ * Utilities for creating variable assignments and references.
767
+ * @module
768
+ */
769
+ /**
770
+ * Creates variable assignments from provided values.
771
+ *
772
+ * Maps variable definitions to VarRefs. If a value is provided,
773
+ * wraps it as a nested-value VarRef. If not provided, creates
774
+ * an undefined VarRef (field will be omitted).
775
+ *
776
+ * Used when spreading fragments with partial variable values.
777
+ *
778
+ * @internal
779
+ */
634
780
  const createVarAssignments = (definitions, providedValues) => {
635
781
  return mapValues(definitions, (_, key) => {
636
782
  const varName = key;
@@ -640,10 +786,34 @@ const createVarAssignments = (definitions, providedValues) => {
640
786
  return createVarRefFromNestedValue(provided);
641
787
  });
642
788
  };
789
+ /**
790
+ * Creates variable references from variable definitions.
791
+ *
792
+ * Maps each variable definition to a VarRef pointing to that variable.
793
+ * Used in operation builders to create the `$` context object.
794
+ *
795
+ * @internal
796
+ */
643
797
  const createVarRefs = (definitions) => mapValues(definitions, (_, name) => createVarRefFromVariable(name));
644
798
 
645
799
  //#endregion
646
800
  //#region packages/core/src/composer/fragment.ts
801
+ /**
802
+ * Fragment composer factory for creating reusable field selections.
803
+ * @module
804
+ */
805
+ /**
806
+ * Creates fragment builder functions for all object types in the schema.
807
+ *
808
+ * Returns an object with a builder for each type (e.g., `fragment.User`, `fragment.Post`).
809
+ * Each builder creates a `Fragment` that can be spread into operations.
810
+ *
811
+ * @param schema - The GraphQL schema definition
812
+ * @param _adapter - Optional metadata adapter (for fragment metadata)
813
+ * @returns Object mapping type names to fragment builder functions
814
+ *
815
+ * @internal Used by `createGqlElementComposer`
816
+ */
647
817
  const createGqlFragmentComposers = (schema, _adapter) => {
648
818
  const createFragmentComposer = (typename) => {
649
819
  return (options) => {
@@ -683,6 +853,25 @@ const defaultMetadataAdapter = createDefaultAdapter();
683
853
 
684
854
  //#endregion
685
855
  //#region packages/core/src/composer/operation.ts
856
+ /**
857
+ * Operation composer factory for creating typed GraphQL operations.
858
+ * @module
859
+ */
860
+ /**
861
+ * Creates a factory for composing GraphQL operations.
862
+ *
863
+ * Returns a curried function: first select operation type (query/mutation/subscription),
864
+ * then define the operation with name, variables, and fields.
865
+ *
866
+ * Handles metadata aggregation from fragments (sync or async) and builds
867
+ * the TypedDocumentNode automatically.
868
+ *
869
+ * @param schema - The GraphQL schema definition
870
+ * @param adapter - Optional metadata adapter for custom metadata handling
871
+ * @returns Operation type selector function
872
+ *
873
+ * @internal Used by `createGqlElementComposer`
874
+ */
686
875
  const createOperationComposerFactory = (schema, adapter) => {
687
876
  const resolvedAdapter = adapter ?? defaultMetadataAdapter;
688
877
  return (operationType) => {
@@ -744,7 +933,9 @@ const createOperationComposerFactory = (schema, adapter) => {
744
933
  //#region packages/core/src/composer/var-ref-tools.ts
745
934
  /**
746
935
  * Recursively checks if a NestedValue contains any VarRef.
936
+ *
747
937
  * Used by getVarRefValue to determine if it's safe to return as ConstValue.
938
+ * @internal
748
939
  */
749
940
  const hasVarRefInside = (value) => {
750
941
  if (value instanceof VarRef) return true;
@@ -856,6 +1047,18 @@ const getValueAt = (varRef, selector) => {
856
1047
  if (hasVarRefInside(inner.varInner.value)) throw new Error(`Value at path [${inner.segments.join(".")}] contains nested VarRef`);
857
1048
  return inner.varInner.value;
858
1049
  };
1050
+ /**
1051
+ * Gets the full path to a variable within a nested structure.
1052
+ *
1053
+ * Returns path segments starting with `$variableName` followed by
1054
+ * property accesses within that variable's value.
1055
+ *
1056
+ * @example
1057
+ * ```typescript
1058
+ * getVariablePath($.filter, p => p.user.id)
1059
+ * // Returns: ["$filter", "user", "id"]
1060
+ * ```
1061
+ */
859
1062
  const getVariablePath = (varRef, selector) => {
860
1063
  const inner = getSelectableProxyInner(selector(createSelectableProxy({
861
1064
  varInner: VarRef.getInner(varRef),
@@ -908,7 +1111,16 @@ const createVarMethodFactory = () => {
908
1111
  };
909
1112
  };
910
1113
  /**
911
- * Creates a variable builder that uses injected input type methods.
1114
+ * Creates a variable builder using injected input type methods.
1115
+ *
1116
+ * The returned builder provides type-safe variable definition methods
1117
+ * for all input types in the schema. Also includes utilities for
1118
+ * extracting variable names and values from VarRefs.
1119
+ *
1120
+ * @param inputTypeMethods - Methods for each input type (from codegen)
1121
+ * @returns Variable builder with methods for all input types
1122
+ *
1123
+ * @internal Used by `createGqlElementComposer`
912
1124
  */
913
1125
  const createVarBuilder = (inputTypeMethods) => {
914
1126
  const varBuilder = (varName) => {
@@ -933,9 +1145,29 @@ const createVarBuilder = (inputTypeMethods) => {
933
1145
  /**
934
1146
  * Creates a GQL element composer for a given schema.
935
1147
  *
936
- * @typeParam TSchema - The GraphQL schema type
937
- * @typeParam TAdapter - The adapter type (optional)
938
- * @typeParam TFragmentBuilders - Pre-computed fragment builders type (optional, for codegen optimization)
1148
+ * This is the main entry point for defining GraphQL operations and fragments.
1149
+ * The returned function provides a context with:
1150
+ * - `fragment`: Builders for each object type
1151
+ * - `query/mutation/subscription`: Operation builders
1152
+ * - `$var`: Variable definition helpers
1153
+ * - `$colocate`: Fragment colocation utilities
1154
+ *
1155
+ * @param schema - The GraphQL schema definition
1156
+ * @param options - Configuration including input type methods and optional adapter
1157
+ * @returns Element composer function
1158
+ *
1159
+ * @example
1160
+ * ```typescript
1161
+ * const gql = createGqlElementComposer(schema, { inputTypeMethods });
1162
+ *
1163
+ * const GetUser = gql(({ query, $var }) =>
1164
+ * query.operation({
1165
+ * name: "GetUser",
1166
+ * variables: { id: $var.ID("!") },
1167
+ * fields: ({ f, $ }) => ({ ...f.user({ id: $.id })(...) }),
1168
+ * })
1169
+ * );
1170
+ * ```
939
1171
  */
940
1172
  const createGqlElementComposer = (schema, options) => {
941
1173
  const { adapter, inputTypeMethods } = options;