houdini 0.17.13 → 0.18.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 (57) hide show
  1. package/build/cmd-cjs/index.js +438 -201
  2. package/build/cmd-esm/index.js +438 -201
  3. package/build/codegen/utils/flattenSelections.d.ts +3 -1
  4. package/build/codegen-cjs/index.js +405 -180
  5. package/build/codegen-esm/index.js +405 -180
  6. package/build/lib/config.d.ts +8 -3
  7. package/build/lib-cjs/index.js +141 -81
  8. package/build/lib-esm/index.js +141 -81
  9. package/build/runtime/cache/subscription.d.ts +3 -3
  10. package/build/runtime/lib/config.d.ts +2 -1
  11. package/build/runtime/lib/scalars.d.ts +2 -2
  12. package/build/runtime/lib/selection.d.ts +2 -0
  13. package/build/runtime/lib/types.d.ts +26 -16
  14. package/build/runtime-cjs/cache/cache.js +38 -23
  15. package/build/runtime-cjs/cache/lists.js +40 -26
  16. package/build/runtime-cjs/cache/subscription.d.ts +3 -3
  17. package/build/runtime-cjs/cache/subscription.js +23 -21
  18. package/build/runtime-cjs/lib/config.d.ts +2 -1
  19. package/build/runtime-cjs/lib/scalars.d.ts +2 -2
  20. package/build/runtime-cjs/lib/scalars.js +9 -6
  21. package/build/runtime-cjs/lib/selection.d.ts +2 -0
  22. package/build/runtime-cjs/lib/selection.js +39 -0
  23. package/build/runtime-cjs/lib/types.d.ts +26 -16
  24. package/build/runtime-esm/cache/cache.js +38 -23
  25. package/build/runtime-esm/cache/lists.js +40 -26
  26. package/build/runtime-esm/cache/subscription.d.ts +3 -3
  27. package/build/runtime-esm/cache/subscription.js +23 -21
  28. package/build/runtime-esm/lib/config.d.ts +2 -1
  29. package/build/runtime-esm/lib/scalars.d.ts +2 -2
  30. package/build/runtime-esm/lib/scalars.js +9 -6
  31. package/build/runtime-esm/lib/selection.d.ts +2 -0
  32. package/build/runtime-esm/lib/selection.js +15 -0
  33. package/build/runtime-esm/lib/types.d.ts +26 -16
  34. package/build/test/index.d.ts +1 -2
  35. package/build/test-cjs/index.js +485 -195
  36. package/build/test-esm/index.js +485 -195
  37. package/build/vite-cjs/index.js +438 -193
  38. package/build/vite-esm/index.js +438 -193
  39. package/package.json +2 -2
  40. package/build/runtime-cjs/cache/tests/availability.test.js +0 -357
  41. package/build/runtime-cjs/cache/tests/gc.test.js +0 -271
  42. package/build/runtime-cjs/cache/tests/keys.test.js +0 -34
  43. package/build/runtime-cjs/cache/tests/list.test.js +0 -3390
  44. package/build/runtime-cjs/cache/tests/readwrite.test.js +0 -1076
  45. package/build/runtime-cjs/cache/tests/scalars.test.js +0 -181
  46. package/build/runtime-cjs/cache/tests/storage.test.js +0 -280
  47. package/build/runtime-cjs/cache/tests/subscriptions.test.js +0 -1469
  48. package/build/runtime-cjs/lib/scalars.test.js +0 -736
  49. package/build/runtime-esm/cache/tests/availability.test.js +0 -356
  50. package/build/runtime-esm/cache/tests/gc.test.js +0 -270
  51. package/build/runtime-esm/cache/tests/keys.test.js +0 -33
  52. package/build/runtime-esm/cache/tests/list.test.js +0 -3389
  53. package/build/runtime-esm/cache/tests/readwrite.test.js +0 -1075
  54. package/build/runtime-esm/cache/tests/scalars.test.js +0 -180
  55. package/build/runtime-esm/cache/tests/storage.test.js +0 -279
  56. package/build/runtime-esm/cache/tests/subscriptions.test.js +0 -1468
  57. package/build/runtime-esm/lib/scalars.test.js +0 -735
@@ -3345,7 +3345,7 @@ var require_definition = __commonJS({
3345
3345
  exports.assertObjectType = assertObjectType;
3346
3346
  exports.isInterfaceType = isInterfaceType6;
3347
3347
  exports.assertInterfaceType = assertInterfaceType;
3348
- exports.isUnionType = isUnionType6;
3348
+ exports.isUnionType = isUnionType7;
3349
3349
  exports.assertUnionType = assertUnionType;
3350
3350
  exports.isEnumType = isEnumType4;
3351
3351
  exports.assertEnumType = assertEnumType;
@@ -3363,7 +3363,7 @@ var require_definition = __commonJS({
3363
3363
  exports.assertLeafType = assertLeafType;
3364
3364
  exports.isCompositeType = isCompositeType;
3365
3365
  exports.assertCompositeType = assertCompositeType;
3366
- exports.isAbstractType = isAbstractType;
3366
+ exports.isAbstractType = isAbstractType2;
3367
3367
  exports.assertAbstractType = assertAbstractType;
3368
3368
  exports.GraphQLList = GraphQLList2;
3369
3369
  exports.GraphQLNonNull = GraphQLNonNull2;
@@ -3418,7 +3418,7 @@ var require_definition = __commonJS({
3418
3418
  return Constructor;
3419
3419
  }
3420
3420
  function isType(type) {
3421
- return isScalarType6(type) || isObjectType2(type) || isInterfaceType6(type) || isUnionType6(type) || isEnumType4(type) || isInputObjectType(type) || isListType3(type) || isNonNullType6(type);
3421
+ return isScalarType6(type) || isObjectType2(type) || isInterfaceType6(type) || isUnionType7(type) || isEnumType4(type) || isInputObjectType(type) || isListType3(type) || isNonNullType6(type);
3422
3422
  }
3423
3423
  function assertType(type) {
3424
3424
  if (!isType(type)) {
@@ -3453,11 +3453,11 @@ var require_definition = __commonJS({
3453
3453
  }
3454
3454
  return type;
3455
3455
  }
3456
- function isUnionType6(type) {
3456
+ function isUnionType7(type) {
3457
3457
  return (0, _instanceOf.default)(type, GraphQLUnionType);
3458
3458
  }
3459
3459
  function assertUnionType(type) {
3460
- if (!isUnionType6(type)) {
3460
+ if (!isUnionType7(type)) {
3461
3461
  throw new Error("Expected ".concat((0, _inspect.default)(type), " to be a GraphQL Union type."));
3462
3462
  }
3463
3463
  return type;
@@ -3508,7 +3508,7 @@ var require_definition = __commonJS({
3508
3508
  return type;
3509
3509
  }
3510
3510
  function isOutputType(type) {
3511
- return isScalarType6(type) || isObjectType2(type) || isInterfaceType6(type) || isUnionType6(type) || isEnumType4(type) || isWrappingType(type) && isOutputType(type.ofType);
3511
+ return isScalarType6(type) || isObjectType2(type) || isInterfaceType6(type) || isUnionType7(type) || isEnumType4(type) || isWrappingType(type) && isOutputType(type.ofType);
3512
3512
  }
3513
3513
  function assertOutputType(type) {
3514
3514
  if (!isOutputType(type)) {
@@ -3526,7 +3526,7 @@ var require_definition = __commonJS({
3526
3526
  return type;
3527
3527
  }
3528
3528
  function isCompositeType(type) {
3529
- return isObjectType2(type) || isInterfaceType6(type) || isUnionType6(type);
3529
+ return isObjectType2(type) || isInterfaceType6(type) || isUnionType7(type);
3530
3530
  }
3531
3531
  function assertCompositeType(type) {
3532
3532
  if (!isCompositeType(type)) {
@@ -3534,11 +3534,11 @@ var require_definition = __commonJS({
3534
3534
  }
3535
3535
  return type;
3536
3536
  }
3537
- function isAbstractType(type) {
3538
- return isInterfaceType6(type) || isUnionType6(type);
3537
+ function isAbstractType2(type) {
3538
+ return isInterfaceType6(type) || isUnionType7(type);
3539
3539
  }
3540
3540
  function assertAbstractType(type) {
3541
- if (!isAbstractType(type)) {
3541
+ if (!isAbstractType2(type)) {
3542
3542
  throw new Error("Expected ".concat((0, _inspect.default)(type), " to be a GraphQL abstract type."));
3543
3543
  }
3544
3544
  return type;
@@ -3605,7 +3605,7 @@ var require_definition = __commonJS({
3605
3605
  }
3606
3606
  }
3607
3607
  function isNamedType(type) {
3608
- return isScalarType6(type) || isObjectType2(type) || isInterfaceType6(type) || isUnionType6(type) || isEnumType4(type) || isInputObjectType(type);
3608
+ return isScalarType6(type) || isObjectType2(type) || isInterfaceType6(type) || isUnionType7(type) || isEnumType4(type) || isInputObjectType(type);
3609
3609
  }
3610
3610
  function assertNamedType(type) {
3611
3611
  if (!isNamedType(type)) {
@@ -53467,6 +53467,20 @@ function deepEquals(objA, objB, map = /* @__PURE__ */ new WeakMap()) {
53467
53467
  return true;
53468
53468
  }
53469
53469
 
53470
+ // src/runtime/lib/selection.ts
53471
+ function getFieldsForType(selection2, __typename) {
53472
+ let targetSelection = selection2.fields || {};
53473
+ if (selection2.abstractFields && __typename) {
53474
+ const mappedType = selection2.abstractFields.typeMap[__typename];
53475
+ if (mappedType) {
53476
+ targetSelection = selection2.abstractFields.fields[mappedType];
53477
+ } else if (selection2.abstractFields.fields[__typename]) {
53478
+ targetSelection = selection2.abstractFields.fields[__typename];
53479
+ }
53480
+ }
53481
+ return targetSelection;
53482
+ }
53483
+
53470
53484
  // src/runtime/cache/gc.ts
53471
53485
  var GarbageCollector = class {
53472
53486
  cache;
@@ -53689,23 +53703,32 @@ var List = class {
53689
53703
  let insertData = data;
53690
53704
  if (this.connection) {
53691
53705
  insertSelection = {
53692
- newEntry: {
53693
- keyRaw: this.key,
53694
- type: "Connection",
53695
- fields: {
53696
- edges: {
53697
- keyRaw: "edges",
53698
- type: "ConnectionEdge",
53699
- update: where === "first" ? "prepend" : "append",
53706
+ fields: {
53707
+ newEntry: {
53708
+ keyRaw: this.key,
53709
+ type: "Connection",
53710
+ selection: {
53700
53711
  fields: {
53701
- node: {
53702
- type: listType,
53703
- keyRaw: "node",
53704
- fields: {
53705
- ...selection2,
53706
- __typename: {
53707
- keyRaw: "__typename",
53708
- type: "String"
53712
+ edges: {
53713
+ keyRaw: "edges",
53714
+ type: "ConnectionEdge",
53715
+ update: where === "first" ? "prepend" : "append",
53716
+ selection: {
53717
+ fields: {
53718
+ node: {
53719
+ type: listType,
53720
+ keyRaw: "node",
53721
+ selection: {
53722
+ ...selection2,
53723
+ fields: {
53724
+ ...selection2.fields,
53725
+ __typename: {
53726
+ keyRaw: "__typename",
53727
+ type: "String"
53728
+ }
53729
+ }
53730
+ }
53731
+ }
53709
53732
  }
53710
53733
  }
53711
53734
  }
@@ -53721,15 +53744,20 @@ var List = class {
53721
53744
  };
53722
53745
  } else {
53723
53746
  insertSelection = {
53724
- newEntries: {
53725
- keyRaw: this.key,
53726
- type: listType,
53727
- update: where === "first" ? "prepend" : "append",
53728
- fields: {
53729
- ...selection2,
53730
- __typename: {
53731
- keyRaw: "__typename",
53732
- type: "String"
53747
+ fields: {
53748
+ newEntries: {
53749
+ keyRaw: this.key,
53750
+ type: listType,
53751
+ update: where === "first" ? "prepend" : "append",
53752
+ selection: {
53753
+ ...selection2,
53754
+ fields: {
53755
+ ...selection2.fields,
53756
+ __typename: {
53757
+ keyRaw: "__typename",
53758
+ type: "String"
53759
+ }
53760
+ }
53733
53761
  }
53734
53762
  }
53735
53763
  }
@@ -53789,7 +53817,7 @@ var List = class {
53789
53817
  const subscribers = this.cache._internal_unstable.subscriptions.get(this.recordID, this.key);
53790
53818
  this.cache._internal_unstable.subscriptions.remove(
53791
53819
  targetID,
53792
- this.connection ? this.selection.edges.fields : this.selection,
53820
+ this.connection ? this.selection.fields.edges.selection : this.selection,
53793
53821
  subscribers,
53794
53822
  variables
53795
53823
  );
@@ -54278,18 +54306,20 @@ var InMemorySubscriptions = class {
54278
54306
  variables,
54279
54307
  parentType
54280
54308
  }) {
54281
- for (const fieldSelection of Object.values(selection2)) {
54282
- const { keyRaw, fields, type } = fieldSelection;
54309
+ const __typename = this.cache._internal_unstable.storage.get(parent, "__typename").value;
54310
+ let targetSelection = getFieldsForType(selection2, __typename);
54311
+ for (const fieldSelection of Object.values(targetSelection || {})) {
54312
+ const { keyRaw, selection: innerSelection, type } = fieldSelection;
54283
54313
  const key = evaluateKey(keyRaw, variables);
54284
54314
  this.addFieldSubscription({
54285
54315
  id: parent,
54286
54316
  key,
54287
- selection: fieldSelection,
54317
+ field: fieldSelection,
54288
54318
  spec,
54289
54319
  parentType: parentType || spec.rootType,
54290
54320
  variables
54291
54321
  });
54292
- if (fields) {
54322
+ if (innerSelection) {
54293
54323
  const { value: linkedRecord } = this.cache._internal_unstable.storage.get(
54294
54324
  parent,
54295
54325
  key
@@ -54302,7 +54332,7 @@ var InMemorySubscriptions = class {
54302
54332
  this.add({
54303
54333
  parent: child,
54304
54334
  spec,
54305
- selection: fields,
54335
+ selection: innerSelection,
54306
54336
  variables,
54307
54337
  parentType: type
54308
54338
  });
@@ -54313,7 +54343,7 @@ var InMemorySubscriptions = class {
54313
54343
  addFieldSubscription({
54314
54344
  id,
54315
54345
  key,
54316
- selection: selection2,
54346
+ field,
54317
54347
  spec,
54318
54348
  parentType,
54319
54349
  variables
@@ -54340,8 +54370,8 @@ var InMemorySubscriptions = class {
54340
54370
  const counts = this.referenceCounts[id][key];
54341
54371
  counts.set(spec.set, (counts.get(spec.set) || 0) + 1);
54342
54372
  this.cache._internal_unstable.lifetimes.resetLifetime(id, key);
54343
- const { fields, list, filters } = selection2;
54344
- if (fields && list) {
54373
+ const { selection: selection2, list, filters } = field;
54374
+ if (selection2 && list) {
54345
54375
  this.cache._internal_unstable.lists.add({
54346
54376
  name: list.name,
54347
54377
  connection: list.connection,
@@ -54349,7 +54379,7 @@ var InMemorySubscriptions = class {
54349
54379
  recordType: this.cache._internal_unstable.storage.get(id, "__typename")?.value || parentType,
54350
54380
  listType: list.type,
54351
54381
  key,
54352
- selection: fields,
54382
+ selection: selection2,
54353
54383
  filters: Object.entries(filters || {}).reduce((acc, [key2, { kind, value }]) => {
54354
54384
  return {
54355
54385
  ...acc,
@@ -54366,20 +54396,21 @@ var InMemorySubscriptions = class {
54366
54396
  subscribers,
54367
54397
  parentType
54368
54398
  }) {
54369
- for (const fieldSelection of Object.values(selection2)) {
54370
- const { type: linkedType, keyRaw, fields } = fieldSelection;
54399
+ let targetSelection = getFieldsForType(selection2, parentType);
54400
+ for (const fieldSelection of Object.values(targetSelection)) {
54401
+ const { type: linkedType, keyRaw, selection: innerSelection } = fieldSelection;
54371
54402
  const key = evaluateKey(keyRaw, variables);
54372
54403
  for (const spec of subscribers) {
54373
54404
  this.addFieldSubscription({
54374
54405
  id: parent,
54375
54406
  key,
54376
- selection: fieldSelection,
54407
+ field: fieldSelection,
54377
54408
  spec,
54378
54409
  parentType,
54379
54410
  variables
54380
54411
  });
54381
54412
  }
54382
- if (fields) {
54413
+ if (innerSelection) {
54383
54414
  const { value: link } = this.cache._internal_unstable.storage.get(parent, key);
54384
54415
  const children = !Array.isArray(link) ? [link] : flattenList(link);
54385
54416
  for (const linkedRecord of children) {
@@ -54388,7 +54419,7 @@ var InMemorySubscriptions = class {
54388
54419
  }
54389
54420
  this.addMany({
54390
54421
  parent: linkedRecord,
54391
- selection: fields,
54422
+ selection: innerSelection,
54392
54423
  variables,
54393
54424
  subscribers,
54394
54425
  parentType: linkedType
@@ -54400,22 +54431,20 @@ var InMemorySubscriptions = class {
54400
54431
  get(id, field) {
54401
54432
  return this.subscribers[id]?.[field] || [];
54402
54433
  }
54403
- remove(id, fields, targets, variables, visited = []) {
54434
+ remove(id, selection2, targets, variables, visited = []) {
54404
54435
  visited.push(id);
54405
54436
  const linkedIDs = [];
54406
- for (const selection2 of Object.values(fields)) {
54407
- const key = evaluateKey(selection2.keyRaw, variables);
54437
+ for (const fieldSelection of Object.values(selection2.fields || {})) {
54438
+ const key = evaluateKey(fieldSelection.keyRaw, variables);
54408
54439
  this.removeSubscribers(id, key, targets);
54409
- if (!selection2.fields) {
54440
+ if (!fieldSelection.selection?.fields) {
54410
54441
  continue;
54411
54442
  }
54412
- if (selection2.list) {
54413
- }
54414
54443
  const { value: previousValue } = this.cache._internal_unstable.storage.get(id, key);
54415
54444
  const links = !Array.isArray(previousValue) ? [previousValue] : flattenList(previousValue);
54416
54445
  for (const link of links) {
54417
54446
  if (link !== null) {
54418
- linkedIDs.push([link, selection2.fields]);
54447
+ linkedIDs.push([link, fieldSelection.selection || {}]);
54419
54448
  }
54420
54449
  }
54421
54450
  }
@@ -54593,8 +54622,9 @@ var CacheInternal = class {
54593
54622
  if (this._disabled) {
54594
54623
  return [];
54595
54624
  }
54625
+ let targetSelection = getFieldsForType(selection2, data["__typename"]);
54596
54626
  for (const [field, value] of Object.entries(data)) {
54597
- if (!selection2 || !selection2[field]) {
54627
+ if (!selection2 || !targetSelection[field]) {
54598
54628
  throw new Error(
54599
54629
  "Could not find field listing in selection for " + field + " @ " + JSON.stringify(selection2)
54600
54630
  );
@@ -54602,11 +54632,11 @@ var CacheInternal = class {
54602
54632
  let {
54603
54633
  type: linkedType,
54604
54634
  keyRaw,
54605
- fields,
54635
+ selection: fieldSelection,
54606
54636
  operations,
54607
54637
  abstract: isAbstract,
54608
54638
  update
54609
- } = selection2[field];
54639
+ } = targetSelection[field];
54610
54640
  const key = evaluateKey(keyRaw, variables);
54611
54641
  const currentSubscribers = this.subscriptions.get(parent, key);
54612
54642
  const { value: previousValue, displayLayers } = this.storage.get(parent, key);
@@ -54614,7 +54644,7 @@ var CacheInternal = class {
54614
54644
  if (displayLayer) {
54615
54645
  this.lifetimes.resetLifetime(parent, key);
54616
54646
  }
54617
- if (!fields) {
54647
+ if (!fieldSelection) {
54618
54648
  let newValue = value;
54619
54649
  if (Array.isArray(value) && applyUpdates && update) {
54620
54650
  if (update === "append") {
@@ -54634,7 +54664,7 @@ var CacheInternal = class {
54634
54664
  }
54635
54665
  const previousLinks = flattenList([previousValue]);
54636
54666
  for (const link of previousLinks) {
54637
- this.subscriptions.remove(link, fields, currentSubscribers, variables);
54667
+ this.subscriptions.remove(link, fieldSelection, currentSubscribers, variables);
54638
54668
  }
54639
54669
  layer.writeLink(parent, key, null);
54640
54670
  toNotify.push(...currentSubscribers);
@@ -54660,14 +54690,14 @@ var CacheInternal = class {
54660
54690
  if (previousValue && typeof previousValue === "string") {
54661
54691
  this.subscriptions.remove(
54662
54692
  previousValue,
54663
- fields,
54693
+ fieldSelection,
54664
54694
  currentSubscribers,
54665
54695
  variables
54666
54696
  );
54667
54697
  }
54668
54698
  this.subscriptions.addMany({
54669
54699
  parent: linkedID,
54670
- selection: fields,
54700
+ selection: fieldSelection,
54671
54701
  subscribers: currentSubscribers,
54672
54702
  variables,
54673
54703
  parentType: linkedType
@@ -54677,14 +54707,14 @@ var CacheInternal = class {
54677
54707
  if (linkedID) {
54678
54708
  this.writeSelection({
54679
54709
  root,
54680
- selection: fields,
54710
+ selection: fieldSelection,
54681
54711
  parent: linkedID,
54682
54712
  data: value,
54683
54713
  variables,
54684
54714
  toNotify,
54685
54715
  applyUpdates,
54686
54716
  layer,
54687
- forceNotify: true
54717
+ forceNotify
54688
54718
  });
54689
54719
  }
54690
54720
  } else if (Array.isArray(value) && (typeof previousValue === "undefined" || Array.isArray(previousValue))) {
@@ -54713,7 +54743,7 @@ var CacheInternal = class {
54713
54743
  key,
54714
54744
  linkedType,
54715
54745
  variables,
54716
- fields,
54746
+ fields: fieldSelection,
54717
54747
  layer,
54718
54748
  forceNotify
54719
54749
  });
@@ -54763,7 +54793,7 @@ var CacheInternal = class {
54763
54793
  if (linkedIDs.includes(lostID) || !lostID) {
54764
54794
  continue;
54765
54795
  }
54766
- this.subscriptions.remove(lostID, fields, currentSubscribers, variables);
54796
+ this.subscriptions.remove(lostID, fieldSelection, currentSubscribers, variables);
54767
54797
  }
54768
54798
  if (contentChanged || oldIDs.length === 0 && newIDs.length === 0) {
54769
54799
  layer.writeLink(parent, key, linkedIDs);
@@ -54774,7 +54804,7 @@ var CacheInternal = class {
54774
54804
  }
54775
54805
  this.subscriptions.addMany({
54776
54806
  parent: id,
54777
- selection: fields,
54807
+ selection: fieldSelection,
54778
54808
  subscribers: currentSubscribers,
54779
54809
  variables,
54780
54810
  parentType: linkedType
@@ -54799,9 +54829,14 @@ var CacheInternal = class {
54799
54829
  }
54800
54830
  const targets = Array.isArray(value) ? value : [value];
54801
54831
  for (const target of targets) {
54802
- if (operation.action === "insert" && target instanceof Object && fields && operation.list) {
54803
- this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).addToList(fields, target, variables, operation.position || "last");
54804
- } else if (operation.action === "remove" && target instanceof Object && fields && operation.list) {
54832
+ if (operation.action === "insert" && target instanceof Object && fieldSelection && operation.list) {
54833
+ this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).addToList(
54834
+ fieldSelection,
54835
+ target,
54836
+ variables,
54837
+ operation.position || "last"
54838
+ );
54839
+ } else if (operation.action === "remove" && target instanceof Object && fieldSelection && operation.list) {
54805
54840
  this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).remove(target, variables);
54806
54841
  } else if (operation.action === "delete" && operation.type) {
54807
54842
  if (typeof target !== "string") {
@@ -54812,8 +54847,13 @@ var CacheInternal = class {
54812
54847
  continue;
54813
54848
  }
54814
54849
  this.cache.delete(targetID);
54815
- } else if (operation.action === "toggle" && target instanceof Object && fields && operation.list) {
54816
- this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement(fields, target, variables, operation.position || "last");
54850
+ } else if (operation.action === "toggle" && target instanceof Object && fieldSelection && operation.list) {
54851
+ this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement(
54852
+ fieldSelection,
54853
+ target,
54854
+ variables,
54855
+ operation.position || "last"
54856
+ );
54817
54857
  }
54818
54858
  }
54819
54859
  }
@@ -54833,9 +54873,12 @@ var CacheInternal = class {
54833
54873
  let hasData = false;
54834
54874
  let partial = false;
54835
54875
  let cascadeNull = false;
54836
- for (const [attributeName, { type, keyRaw, fields, nullable, list }] of Object.entries(
54837
- selection2
54838
- )) {
54876
+ const typename = this.storage.get(parent, "__typename").value;
54877
+ let targetSelection = getFieldsForType(selection2, typename);
54878
+ for (const [
54879
+ attributeName,
54880
+ { type, keyRaw, selection: fieldSelection, nullable, list }
54881
+ ] of Object.entries(targetSelection)) {
54839
54882
  const key = evaluateKey(keyRaw, variables);
54840
54883
  const { value } = this.storage.get(parent, key);
54841
54884
  let nextStep = stepsFromConnection;
@@ -54858,7 +54901,7 @@ var CacheInternal = class {
54858
54901
  if (typeof value !== "undefined") {
54859
54902
  hasData = true;
54860
54903
  }
54861
- } else if (!fields) {
54904
+ } else if (!fieldSelection) {
54862
54905
  const fnUnmarshal = this.config?.scalars?.[type]?.unmarshal;
54863
54906
  if (fnUnmarshal) {
54864
54907
  target[attributeName] = fnUnmarshal(value);
@@ -54868,7 +54911,7 @@ var CacheInternal = class {
54868
54911
  hasData = true;
54869
54912
  } else if (Array.isArray(value)) {
54870
54913
  const listValue = this.hydrateNestedList({
54871
- fields,
54914
+ fields: fieldSelection,
54872
54915
  variables,
54873
54916
  linkedList: value,
54874
54917
  stepsFromConnection: nextStep
@@ -54883,7 +54926,7 @@ var CacheInternal = class {
54883
54926
  } else {
54884
54927
  const objectFields = this.getSelection({
54885
54928
  parent: value,
54886
- selection: fields,
54929
+ selection: fieldSelection,
54887
54930
  variables,
54888
54931
  stepsFromConnection: nextStep
54889
54932
  });
@@ -55385,7 +55428,7 @@ var Config = class {
55385
55428
  typeConfig;
55386
55429
  configFile;
55387
55430
  logLevel;
55388
- disableMasking;
55431
+ defaultFragmentMasking = "enable";
55389
55432
  configIsRoute = null;
55390
55433
  routesDir;
55391
55434
  schemaPollInterval;
@@ -55398,6 +55441,11 @@ var Config = class {
55398
55441
  ...configFile
55399
55442
  }) {
55400
55443
  this.configFile = defaultConfigValues(configFile);
55444
+ if (configFile.disableMasking !== void 0) {
55445
+ throw new HoudiniError({
55446
+ message: `"disableMasking" was replaced by "defaultFragmentMasking". Please update your config file.`
55447
+ });
55448
+ }
55401
55449
  let {
55402
55450
  schema,
55403
55451
  schemaPath = "./schema.graphql",
@@ -55414,7 +55462,7 @@ var Config = class {
55414
55462
  defaultKeys,
55415
55463
  types: types12 = {},
55416
55464
  logLevel,
55417
- disableMasking = false,
55465
+ defaultFragmentMasking = "enable",
55418
55466
  schemaPollInterval = 2e3,
55419
55467
  schemaPollHeaders = {},
55420
55468
  projectDir
@@ -55433,7 +55481,11 @@ var Config = class {
55433
55481
  logLevel = LogLevel.Summary;
55434
55482
  }
55435
55483
  this.schemaPath = schemaPath;
55436
- this.apiUrl = apiUrl;
55484
+ if (apiUrl && apiUrl.startsWith("env:")) {
55485
+ this.apiUrl = process.env[apiUrl.slice("env:".length)];
55486
+ } else {
55487
+ this.apiUrl = apiUrl;
55488
+ }
55437
55489
  this.filepath = filepath;
55438
55490
  this.exclude = Array.isArray(exclude) ? exclude : [exclude];
55439
55491
  this.module = module2;
@@ -55445,10 +55497,10 @@ var Config = class {
55445
55497
  this.defaultCachePolicy = defaultCachePolicy;
55446
55498
  this.defaultPartial = defaultPartial;
55447
55499
  this.internalListPosition = defaultListPosition === "append" ? "last" : "first";
55448
- this.defaultListTarget == defaultListTarget;
55500
+ this.defaultListTarget = defaultListTarget;
55449
55501
  this.definitionsFolder = definitionsPath;
55450
55502
  this.logLevel = (logLevel || LogLevel.Summary).toLowerCase();
55451
- this.disableMasking = disableMasking;
55503
+ this.defaultFragmentMasking = defaultFragmentMasking;
55452
55504
  this.routesDir = join(this.projectRoot, "src", "routes");
55453
55505
  this.schemaPollInterval = schemaPollInterval;
55454
55506
  this.schemaPollHeaders = schemaPollHeaders;
@@ -55642,8 +55694,14 @@ var Config = class {
55642
55694
  pluginDirectory(name2) {
55643
55695
  return houdini_mode.is_testing ? resolve("../../../", name2) : join(this.rootDir, "plugins", name2);
55644
55696
  }
55645
- get houdiniDirective() {
55646
- return "houdini";
55697
+ get manualLoadDirective() {
55698
+ return "manual_load";
55699
+ }
55700
+ get maskEnableDirective() {
55701
+ return "mask_enable";
55702
+ }
55703
+ get maskDisableDirective() {
55704
+ return "mask_disable";
55647
55705
  }
55648
55706
  get listDirective() {
55649
55707
  return "list";
@@ -55655,9 +55713,9 @@ var Config = class {
55655
55713
  return "append";
55656
55714
  }
55657
55715
  get listParentDirective() {
55658
- return this.listDirectiveParentIDArg;
55716
+ return "parentID";
55659
55717
  }
55660
- get listDirectiveParentIDArg() {
55718
+ get deprecatedlistDirectiveParentIDArg() {
55661
55719
  return "parentID";
55662
55720
  }
55663
55721
  get listAllListsDirective() {
@@ -55743,7 +55801,7 @@ var Config = class {
55743
55801
  this.listDirective,
55744
55802
  this.listPrependDirective,
55745
55803
  this.listAppendDirective,
55746
- this.listDirectiveParentIDArg,
55804
+ this.listParentDirective,
55747
55805
  this.listAllListsDirective,
55748
55806
  this.whenDirective,
55749
55807
  this.whenNotDirective,
@@ -55751,7 +55809,9 @@ var Config = class {
55751
55809
  this.withDirective,
55752
55810
  this.paginateDirective,
55753
55811
  this.cacheDirective,
55754
- this.houdiniDirective
55812
+ this.manualLoadDirective,
55813
+ this.maskEnableDirective,
55814
+ this.maskDisableDirective
55755
55815
  ].includes(name2.value) || this.isDeleteDirective(name2.value);
55756
55816
  }
55757
55817
  isListFragment(name2) {
@@ -55988,13 +56048,17 @@ function flattenSelections({
55988
56048
  config: config2,
55989
56049
  filepath,
55990
56050
  selections,
55991
- fragmentDefinitions
56051
+ fragmentDefinitions,
56052
+ applyFragments,
56053
+ ignoreMaskDisable
55992
56054
  }) {
55993
56055
  const fields = new FieldCollection({
55994
56056
  config: config2,
55995
56057
  filepath,
55996
56058
  selections,
55997
- fragmentDefinitions
56059
+ fragmentDefinitions,
56060
+ applyFragments,
56061
+ ignoreMaskDisable: !!ignoreMaskDisable
55998
56062
  });
55999
56063
  return fields.toSelectionSet();
56000
56064
  }
@@ -56005,9 +56069,13 @@ var FieldCollection = class {
56005
56069
  fields;
56006
56070
  inlineFragments;
56007
56071
  fragmentSpreads;
56072
+ applyFragments;
56073
+ ignoreMaskDisable;
56008
56074
  constructor(args) {
56009
56075
  this.config = args.config;
56010
56076
  this.fragmentDefinitions = args.fragmentDefinitions;
56077
+ this.applyFragments = args.applyFragments;
56078
+ this.ignoreMaskDisable = args.ignoreMaskDisable;
56011
56079
  this.fields = {};
56012
56080
  this.inlineFragments = {};
56013
56081
  this.fragmentSpreads = {};
@@ -56036,31 +56104,28 @@ var FieldCollection = class {
56036
56104
  }
56037
56105
  }
56038
56106
  if (selection2.kind === "InlineFragment" && selection2.typeCondition) {
56039
- const key = selection2.typeCondition.name.value;
56040
- if (!this.inlineFragments[key]) {
56041
- this.inlineFragments[key] = {
56042
- astNode: selection2,
56043
- selection: this.empty()
56044
- };
56045
- }
56046
- for (const subselect of selection2.selectionSet?.selections || []) {
56047
- this.inlineFragments[key].selection.add(subselect);
56048
- }
56107
+ this.walkInlineFragment(selection2);
56049
56108
  return;
56050
56109
  }
56051
56110
  if (selection2.kind === "FragmentSpread") {
56052
56111
  this.fragmentSpreads[selection2.name.value] = selection2;
56053
- const houdiniDirective = selection2.directives?.find(
56054
- ({ name: name2 }) => name2.value === this.config.houdiniDirective
56112
+ let includeFragments = this.config.defaultFragmentMasking === "disable";
56113
+ const maskEnableDirective = selection2.directives?.find(
56114
+ ({ name: name2 }) => name2.value === this.config.maskEnableDirective
56055
56115
  );
56056
- const maskArgument = houdiniDirective?.arguments?.find(
56057
- ({ name: name2 }) => name2.value === "mask"
56116
+ if (maskEnableDirective) {
56117
+ includeFragments = false;
56118
+ }
56119
+ const maskDisableDirective = selection2.directives?.find(
56120
+ ({ name: name2 }) => name2.value === this.config.maskDisableDirective
56058
56121
  );
56059
- let includeFragments = this.config.disableMasking;
56060
- if (maskArgument?.value.kind === "BooleanValue") {
56061
- includeFragments = !maskArgument.value.value;
56122
+ if (maskDisableDirective) {
56123
+ includeFragments = true;
56124
+ }
56125
+ if (this.ignoreMaskDisable) {
56126
+ includeFragments = true;
56062
56127
  }
56063
- if (!includeFragments) {
56128
+ if (!includeFragments || !this.applyFragments) {
56064
56129
  return;
56065
56130
  }
56066
56131
  const definition = this.fragmentDefinitions[selection2.name.value];
@@ -56070,9 +56135,20 @@ var FieldCollection = class {
56070
56135
  message: "Could not find referenced fragment definition: " + selection2.name.value
56071
56136
  });
56072
56137
  }
56073
- for (const subselect of definition.selectionSet.selections) {
56074
- this.add(subselect);
56075
- }
56138
+ this.add({
56139
+ kind: "InlineFragment",
56140
+ typeCondition: {
56141
+ kind: "NamedType",
56142
+ name: {
56143
+ kind: "Name",
56144
+ value: definition.typeCondition.name.value
56145
+ }
56146
+ },
56147
+ selectionSet: {
56148
+ kind: "SelectionSet",
56149
+ selections: [...definition.selectionSet.selections]
56150
+ }
56151
+ });
56076
56152
  }
56077
56153
  }
56078
56154
  toSelectionSet() {
@@ -56088,12 +56164,30 @@ var FieldCollection = class {
56088
56164
  })
56089
56165
  ).concat(Object.values(this.fragmentSpreads));
56090
56166
  }
56167
+ walkInlineFragment(selection2) {
56168
+ const key = selection2.typeCondition.name.value;
56169
+ if (!this.inlineFragments[key]) {
56170
+ this.inlineFragments[key] = {
56171
+ astNode: selection2,
56172
+ selection: this.empty()
56173
+ };
56174
+ }
56175
+ for (const subselect of selection2.selectionSet.selections || []) {
56176
+ if (subselect.kind !== "InlineFragment" || !subselect.typeCondition) {
56177
+ this.inlineFragments[key].selection.add(subselect);
56178
+ continue;
56179
+ }
56180
+ this.walkInlineFragment(subselect);
56181
+ }
56182
+ }
56091
56183
  empty() {
56092
56184
  return new FieldCollection({
56093
56185
  config: this.config,
56094
56186
  fragmentDefinitions: this.fragmentDefinitions,
56095
56187
  selections: [],
56096
- filepath: this.filepath
56188
+ filepath: this.filepath,
56189
+ applyFragments: this.applyFragments,
56190
+ ignoreMaskDisable: this.ignoreMaskDisable
56097
56191
  });
56098
56192
  }
56099
56193
  };
@@ -56448,11 +56542,6 @@ function operationObject({
56448
56542
  const when = internalDirectives.find(({ name: name2 }) => name2.value === "when");
56449
56543
  const when_not = internalDirectives.find(({ name: name2 }) => name2.value === "when_not");
56450
56544
  let parentIDArg = parent?.arguments?.find((argument) => argument.name.value === "value");
56451
- if (!parentIDArg) {
56452
- parentIDArg = (append || prepend)?.arguments?.find(
56453
- ({ name: name2 }) => name2.value === config2.listDirectiveParentIDArg
56454
- );
56455
- }
56456
56545
  if (parentIDArg) {
56457
56546
  if (parentIDArg.value.kind === "StringValue") {
56458
56547
  parentID = parentIDArg.value.value;
@@ -57480,6 +57569,8 @@ function selection({
57480
57569
  markEdges
57481
57570
  }) {
57482
57571
  let object = {};
57572
+ const typeMap = {};
57573
+ const abstractTypes = [];
57483
57574
  for (const field of selections) {
57484
57575
  if (field.kind === "FragmentSpread" && includeFragments) {
57485
57576
  const fragmentDefinition = document.document.definitions.find(
@@ -57506,20 +57597,68 @@ function selection({
57506
57597
  })
57507
57598
  );
57508
57599
  } else if (field.kind === "InlineFragment") {
57509
- object = deepMerge(
57510
- filepath,
57511
- object,
57512
- selection({
57513
- config: config2,
57600
+ if (!field.typeCondition || field.typeCondition.name.value === rootType) {
57601
+ object.fields = deepMerge(
57514
57602
  filepath,
57515
- rootType: field.typeCondition?.name.value || rootType,
57516
- operations,
57517
- selections: field.selectionSet.selections,
57518
- path: path2,
57519
- includeFragments,
57520
- document
57521
- })
57522
- );
57603
+ object.fields || {},
57604
+ selection({
57605
+ config: config2,
57606
+ filepath,
57607
+ rootType: field.typeCondition?.name.value || rootType,
57608
+ operations,
57609
+ selections: field.selectionSet.selections,
57610
+ path: path2,
57611
+ includeFragments,
57612
+ document
57613
+ }).fields || {}
57614
+ );
57615
+ } else {
57616
+ if (!object.abstractFields) {
57617
+ object.abstractFields = {
57618
+ fields: {},
57619
+ typeMap: {}
57620
+ };
57621
+ }
57622
+ const parentType = config2.schema.getType(rootType);
57623
+ const typeConditionName = field.typeCondition.name.value;
57624
+ const typeCondition = config2.schema.getType(typeConditionName);
57625
+ const possibleTypes = [];
57626
+ if (!graphql10.isAbstractType(typeCondition)) {
57627
+ } else if (graphql10.isAbstractType(parentType)) {
57628
+ const possibleParentTypes = config2.schema.getPossibleTypes(parentType).map((type) => type.name);
57629
+ for (const possible of config2.schema.getPossibleTypes(typeCondition)) {
57630
+ if (possibleParentTypes.includes(possible.name)) {
57631
+ possibleTypes.push(possible.name);
57632
+ }
57633
+ }
57634
+ } else {
57635
+ possibleTypes.push(rootType);
57636
+ }
57637
+ if (possibleTypes.length > 0) {
57638
+ for (const type of possibleTypes) {
57639
+ const existing = typeMap[type];
57640
+ if (!existing || !existing.includes(type)) {
57641
+ typeMap[type] = [typeConditionName].concat(existing || []);
57642
+ }
57643
+ if (!abstractTypes.includes(typeConditionName)) {
57644
+ abstractTypes.push(typeConditionName);
57645
+ }
57646
+ }
57647
+ }
57648
+ object.abstractFields.fields = {
57649
+ ...object.abstractFields.fields,
57650
+ [field.typeCondition.name.value]: selection({
57651
+ config: config2,
57652
+ filepath,
57653
+ rootType: field.typeCondition?.name.value || rootType,
57654
+ operations,
57655
+ selections: field.selectionSet.selections,
57656
+ path: path2,
57657
+ includeFragments,
57658
+ document
57659
+ }).fields
57660
+ };
57661
+ }
57523
57662
  } else if (field.kind === "Field") {
57524
57663
  const type = config2.schema.getType(rootType);
57525
57664
  if (!type) {
@@ -57577,7 +57716,7 @@ function selection({
57577
57716
  }
57578
57717
  if (field.selectionSet) {
57579
57718
  const edgesMark = paginated && document.refetch?.method === "cursor" ? document.refetch.update : markEdges;
57580
- fieldObj.fields = selection({
57719
+ fieldObj.selection = selection({
57581
57720
  config: config2,
57582
57721
  filepath,
57583
57722
  rootType: typeName,
@@ -57601,11 +57740,49 @@ function selection({
57601
57740
  if (graphql10.isInterfaceType(fieldType) || graphql10.isUnionType(fieldType)) {
57602
57741
  fieldObj.abstract = true;
57603
57742
  }
57604
- object[attributeName] = deepMerge(
57605
- filepath,
57606
- fieldObj,
57607
- object[attributeName] || {}
57608
- );
57743
+ object.fields = {
57744
+ ...object.fields,
57745
+ [attributeName]: fieldObj
57746
+ };
57747
+ }
57748
+ }
57749
+ if (Object.keys(object.fields || {}).length > 0 && object.abstractFields && Object.keys(object.abstractFields.fields).length > 0) {
57750
+ for (const [typeName, possibles] of Object.entries(typeMap)) {
57751
+ let overlap = false;
57752
+ for (const possible of possibles) {
57753
+ if (object.abstractFields.fields[typeName]) {
57754
+ object.abstractFields.fields[typeName] = deepMerge(
57755
+ filepath,
57756
+ object.abstractFields.fields[typeName] || {},
57757
+ object.abstractFields.fields[possible]
57758
+ );
57759
+ overlap = true;
57760
+ }
57761
+ }
57762
+ if (overlap) {
57763
+ delete typeMap[typeName];
57764
+ }
57765
+ }
57766
+ for (const [type, options] of Object.entries(typeMap)) {
57767
+ if (options.length > 1) {
57768
+ object.abstractFields.fields[type] = deepMerge(
57769
+ filepath,
57770
+ ...options.map((opt) => object.abstractFields.fields[opt] || {})
57771
+ );
57772
+ delete typeMap[type];
57773
+ }
57774
+ }
57775
+ for (const [type, sel] of Object.entries(object.abstractFields?.fields || {})) {
57776
+ object.abstractFields.fields[type] = deepMerge(filepath, sel || {}, object.fields);
57777
+ }
57778
+ for (const [type, options] of Object.entries(typeMap)) {
57779
+ object.abstractFields.typeMap[type] = options[0];
57780
+ }
57781
+ const usedTypes = Object.values(object.abstractFields.typeMap);
57782
+ for (const type of abstractTypes) {
57783
+ if (!usedTypes.includes(type)) {
57784
+ delete object.abstractFields.fields[type];
57785
+ }
57609
57786
  }
57610
57787
  }
57611
57788
  return object;
@@ -57740,6 +57917,22 @@ function artifactGenerator(stats) {
57740
57917
  selectionSet = matchingFragment.selectionSet;
57741
57918
  }
57742
57919
  const inputs = operations[0]?.variableDefinitions;
57920
+ const mergedSelection = flattenSelections({
57921
+ config: config2,
57922
+ filepath: doc.filename,
57923
+ selections: selectionSet.selections,
57924
+ fragmentDefinitions: doc.document.definitions.filter(
57925
+ (definition) => definition.kind === "FragmentDefinition"
57926
+ ).reduce(
57927
+ (prev, definition) => ({
57928
+ ...prev,
57929
+ [definition.name.value]: definition
57930
+ }),
57931
+ {}
57932
+ ),
57933
+ ignoreMaskDisable: docKind === "HoudiniQuery",
57934
+ applyFragments: docKind !== "HoudiniFragment"
57935
+ });
57743
57936
  const artifact = {
57744
57937
  name: name2,
57745
57938
  kind: docKind,
@@ -57751,7 +57944,7 @@ function artifactGenerator(stats) {
57751
57944
  config: config2,
57752
57945
  filepath: doc.filename,
57753
57946
  rootType,
57754
- selections: selectionSet.selections,
57947
+ selections: mergedSelection,
57755
57948
  operations: operationsByPath(
57756
57949
  config2,
57757
57950
  doc.filename,
@@ -58047,6 +58240,17 @@ function inlineType({
58047
58240
  continue;
58048
58241
  }
58049
58242
  const possibleParents = config2.schema.getPossibleTypes(type).map((t) => t.name);
58243
+ const freeSelections = [];
58244
+ const typeSpecificSelections = {};
58245
+ for (const node of selection2.selectionSet.selections) {
58246
+ if (node.kind !== "InlineFragment") {
58247
+ freeSelections.push(node);
58248
+ } else if (node.typeCondition) {
58249
+ typeSpecificSelections[node.typeCondition.name.value] = node.selectionSet.selections;
58250
+ } else {
58251
+ freeSelections.push(...node.selectionSet.selections);
58252
+ }
58253
+ }
58050
58254
  for (const possibleType of config2.schema.getPossibleTypes(fragmentType)) {
58051
58255
  if (!possibleParents.includes(possibleType.name)) {
58052
58256
  continue;
@@ -58054,7 +58258,12 @@ function inlineType({
58054
58258
  if (!inlineFragments[possibleType.name]) {
58055
58259
  inlineFragments[possibleType.name] = [];
58056
58260
  }
58057
- inlineFragments[possibleType.name].push(...selection2.selectionSet.selections);
58261
+ inlineFragments[possibleType.name].push(...freeSelections);
58262
+ if (typeSpecificSelections[possibleType.name]) {
58263
+ inlineFragments[possibleType.name].push(
58264
+ ...typeSpecificSelections[possibleType.name]
58265
+ );
58266
+ }
58058
58267
  }
58059
58268
  } else if (selection2.kind === "InlineFragment" && !selection2.typeCondition) {
58060
58269
  selectedFields.push(...selection2.selectionSet.selections);
@@ -58066,12 +58275,7 @@ function inlineType({
58066
58275
  ...(selectedFields || []).filter(
58067
58276
  (field) => field.kind === "Field"
58068
58277
  ).map((selection2) => {
58069
- const { type: type2, field } = selectionTypeInfo(
58070
- config2.schema,
58071
- filepath,
58072
- rootObj,
58073
- selection2
58074
- );
58278
+ const { field } = selectionTypeInfo(config2.schema, filepath, rootObj, selection2);
58075
58279
  const attributeName = selection2.alias?.value || selection2.name.value;
58076
58280
  let attributeType = inlineType({
58077
58281
  config: config2,
@@ -58270,7 +58474,8 @@ async function typescriptGenerator(config2, docs) {
58270
58474
  config: config2,
58271
58475
  filepath: filename,
58272
58476
  selections: definition.selectionSet.selections,
58273
- fragmentDefinitions
58477
+ fragmentDefinitions,
58478
+ applyFragments: definition.kind === "OperationDefinition"
58274
58479
  });
58275
58480
  if (definition?.kind === "OperationDefinition") {
58276
58481
  await generateOperationTypeDefs(
@@ -58783,14 +58988,12 @@ directive @${config2.paginateDirective}(${config2.paginateNameArg}: String) on F
58783
58988
  """
58784
58989
  @${config2.listPrependDirective} is used to tell the runtime to add the result to the end of the list
58785
58990
  """
58786
- directive @${config2.listPrependDirective}(
58787
- ${config2.listDirectiveParentIDArg}: ID
58788
- ) on FRAGMENT_SPREAD
58991
+ directive @${config2.listPrependDirective} on FRAGMENT_SPREAD
58789
58992
 
58790
58993
  """
58791
58994
  @${config2.listAppendDirective} is used to tell the runtime to add the result to the start of the list
58792
58995
  """
58793
- directive @${config2.listAppendDirective}(${config2.listDirectiveParentIDArg}: ID) on FRAGMENT_SPREAD
58996
+ directive @${config2.listAppendDirective} on FRAGMENT_SPREAD
58794
58997
 
58795
58998
  """
58796
58999
  @${config2.listAllListsDirective} is used to tell the runtime to add the result to all list
@@ -58824,18 +59027,19 @@ directive @${config2.argumentsDirective} on FRAGMENT_DEFINITION
58824
59027
  directive @${config2.cacheDirective}(${config2.cachePolicyArg}: CachePolicy, ${config2.cachePartialArg}: Boolean) on QUERY
58825
59028
 
58826
59029
  """
58827
- @${config2.houdiniDirective} is used to configure houdini's internal behavior
59030
+ @${config2.manualLoadDirective} is used to disable automatic fetch (no load, no auto fetch in component), you will have to do it manually.
58828
59031
  """
58829
- directive @${config2.houdiniDirective}(
58830
- """
58831
- Opt-in to an automatic load function (only valid when used at queries)
58832
- """
58833
- load: Boolean! = true
58834
- """
58835
- Mask fragment fields (only valid when used at a fragment spread)
58836
- """
58837
- mask: Boolean! = ${config2.disableMasking ? "false" : "true"}
58838
- ) on QUERY | FRAGMENT_SPREAD
59032
+ directive @${config2.manualLoadDirective} on QUERY
59033
+
59034
+ """
59035
+ @${config2.maskEnableDirective} to enable masking on fragment (overwriting the global conf)
59036
+ """
59037
+ directive @${config2.maskEnableDirective} on FRAGMENT_SPREAD
59038
+
59039
+ """
59040
+ @${config2.maskDisableDirective} to disable masking on fragment (overwriting the global conf)
59041
+ """
59042
+ directive @${config2.maskDisableDirective} on FRAGMENT_SPREAD
58839
59043
  `;
58840
59044
  let currentSchema = graphql19.printSchema(config2.schema);
58841
59045
  if (!currentSchema.includes(`directive @${config2.listDirective}`)) {
@@ -59328,26 +59532,42 @@ async function typeCheck(config2, docs) {
59328
59532
  ),
59329
59533
  targetField.selectionSet
59330
59534
  );
59331
- const missingIDFields = config2.keyFieldsForType(type.name).filter((fieldName) => !type.getFields()[fieldName]);
59332
- if (missingIDFields.length > 0) {
59333
- if (error) {
59334
- errors.push(
59335
- new HoudiniError({
59336
- filepath: filename,
59337
- message: error
59338
- })
59339
- );
59340
- } else {
59341
- errors.push(
59342
- new HoudiniError({
59343
- filepath: filename,
59344
- message: `@${config2.listDirective} can only be applied to types with the necessary id fields: ${missingIDFields.join(
59345
- ", "
59346
- )}.`
59347
- })
59348
- );
59535
+ let targetTypes = [type];
59536
+ if (graphql23.isUnionType(type)) {
59537
+ targetTypes = config2.schema.getPossibleTypes(type);
59538
+ } else if (graphql23.isInterfaceType(type)) {
59539
+ try {
59540
+ for (const key of config2.keyFieldsForType(type.name)) {
59541
+ if (!type.getFields()[key]) {
59542
+ throw new Error("continue");
59543
+ }
59544
+ }
59545
+ } catch {
59546
+ targetTypes = config2.schema.getPossibleTypes(type);
59547
+ }
59548
+ }
59549
+ for (const targetType of targetTypes) {
59550
+ const missingIDFields = config2.keyFieldsForType(targetType.name).filter((fieldName) => !targetType.getFields()[fieldName]);
59551
+ if (missingIDFields.length > 0) {
59552
+ if (error) {
59553
+ errors.push(
59554
+ new HoudiniError({
59555
+ filepath: filename,
59556
+ message: error
59557
+ })
59558
+ );
59559
+ } else {
59560
+ errors.push(
59561
+ new HoudiniError({
59562
+ filepath: filename,
59563
+ message: `@${config2.listDirective} can only be applied to types with the necessary id fields: ${missingIDFields.join(
59564
+ ", "
59565
+ )}.`
59566
+ })
59567
+ );
59568
+ }
59569
+ return;
59349
59570
  }
59350
- return;
59351
59571
  }
59352
59572
  lists.push(listName);
59353
59573
  listTypes.push(type.name);
@@ -59377,6 +59597,7 @@ async function typeCheck(config2, docs) {
59377
59597
  fragments
59378
59598
  }),
59379
59599
  checkMutationOperation(config2),
59600
+ checkMaskDirective(config2),
59380
59601
  nodeDirectives(config2, [config2.paginateDirective]),
59381
59602
  knownArguments(config2),
59382
59603
  validateFragmentArguments(config2, filepath, fragments),
@@ -59441,10 +59662,14 @@ var validateLists = ({
59441
59662
  ]);
59442
59663
  if (directive) {
59443
59664
  let parentArg = directive.arguments?.find(
59444
- (arg) => arg.name.value === config2.listDirectiveParentIDArg
59665
+ (arg) => arg.name.value === config2.deprecatedlistDirectiveParentIDArg
59445
59666
  );
59446
59667
  if (parentArg) {
59447
- parentIdFound = true;
59668
+ ctx.reportError(
59669
+ new graphql23.GraphQLError(
59670
+ `@${config2.deprecatedlistDirectiveParentIDArg} should be defined only in it's own directive now`
59671
+ )
59672
+ );
59448
59673
  }
59449
59674
  }
59450
59675
  if (parentIdFound) {
@@ -59840,6 +60065,28 @@ function checkMutationOperation(config2) {
59840
60065
  };
59841
60066
  };
59842
60067
  }
60068
+ function checkMaskDirective(config2) {
60069
+ return function(ctx) {
60070
+ return {
60071
+ FragmentSpread(node, _, __, ___, ancestors) {
60072
+ const maskEnableDirective = node.directives?.find(
60073
+ (c) => c.name.value === config2.maskEnableDirective
60074
+ );
60075
+ const maskDisableDirective = node.directives?.find(
60076
+ (c) => c.name.value === config2.maskDisableDirective
60077
+ );
60078
+ if (maskEnableDirective && maskDisableDirective) {
60079
+ ctx.reportError(
60080
+ new graphql23.GraphQLError(
60081
+ `You can't apply both @${config2.maskEnableDirective} and @${config2.maskDisableDirective} at the same time`
60082
+ )
60083
+ );
60084
+ return;
60085
+ }
60086
+ }
60087
+ };
60088
+ };
60089
+ }
59843
60090
  function getAndVerifyNodeInterface(config2) {
59844
60091
  const { schema } = config2;
59845
60092
  const nodeInterface = schema.getType("Node");
@@ -60118,8 +60365,9 @@ function testConfigFile(config2 = {}) {
60118
60365
  scalar Cursor
60119
60366
 
60120
60367
 
60121
- type User implements Node {
60368
+ type User implements Node & Friend & CatOwner {
60122
60369
  id: ID!
60370
+ name: String!
60123
60371
  firstName: String!
60124
60372
  friends: [User!]!
60125
60373
  friendsByCursor(first: Int, after: String, last: Int, before: String, filter: String): UserConnection!
@@ -60134,13 +60382,14 @@ function testConfigFile(config2 = {}) {
60134
60382
  field(filter: String): String
60135
60383
  }
60136
60384
 
60137
- type Ghost implements Friend {
60385
+ type Ghost implements Friend & CatOwner & IsGhost {
60138
60386
  name: String!
60139
60387
  aka: String!
60140
60388
  believers: [User!]!
60141
60389
  friends: [Ghost!]!
60142
60390
  friendsConnection(first: Int, after: String): GhostConnection!
60143
60391
  legends: [Legend!]!
60392
+ cats: [Cat!]!
60144
60393
  }
60145
60394
 
60146
60395
  type Legend {
@@ -60166,6 +60415,9 @@ function testConfigFile(config2 = {}) {
60166
60415
  usersByBackwardsCursor(last: Int, before: String): UserConnection!
60167
60416
  usersByForwardsCursor(first: Int, after: String): UserConnection!
60168
60417
  usersByOffset(offset: Int, limit: Int): [User!]!
60418
+ friendsByCursor(first: Int, after: String, last: Int, before: String): FriendConnection!
60419
+ ghostsByCursor(first: Int, after: String, last: Int, before: String): IsGhostConnection!
60420
+ entitiesByCursor(first: Int, after: String, last: Int, before: String): EntityConnection!
60169
60421
  node(id: ID!): Node
60170
60422
  }
60171
60423
 
@@ -60181,16 +60433,26 @@ function testConfigFile(config2 = {}) {
60181
60433
  node: User
60182
60434
  }
60183
60435
 
60184
- type UserEdgeScalar {
60185
- cursor: Cursor!
60186
- node: User
60187
- }
60188
-
60189
60436
  type UserConnection {
60190
60437
  pageInfo: PageInfo!
60191
60438
  edges: [UserEdge!]!
60192
60439
  }
60193
60440
 
60441
+ type FriendEdge {
60442
+ cursor: String!
60443
+ node: Friend
60444
+ }
60445
+
60446
+ type FriendConnection {
60447
+ pageInfo: PageInfo!
60448
+ edges: [FriendEdge!]!
60449
+ }
60450
+
60451
+ type UserEdgeScalar {
60452
+ cursor: Cursor!
60453
+ node: User
60454
+ }
60455
+
60194
60456
  type UserConnectionScalar {
60195
60457
  pageInfo: PageInfo!
60196
60458
  edges: [UserEdgeScalar!]!
@@ -60206,10 +60468,38 @@ function testConfigFile(config2 = {}) {
60206
60468
  edges: [GhostEdge!]!
60207
60469
  }
60208
60470
 
60471
+ type EntityEdge {
60472
+ cursor: String!
60473
+ node: Entity
60474
+ }
60475
+
60476
+ type EntityConnection {
60477
+ pageInfo: PageInfo!
60478
+ edges: [EntityEdge!]!
60479
+ }
60480
+
60481
+ type IsGhostEdge {
60482
+ cursor: String!
60483
+ node: IsGhost
60484
+ }
60485
+
60486
+ type IsGhostConnection {
60487
+ pageInfo: PageInfo!
60488
+ edges: [IsGhostEdge!]!
60489
+ }
60490
+
60209
60491
  interface Friend {
60210
60492
  name: String!
60211
60493
  }
60212
60494
 
60495
+ interface CatOwner {
60496
+ cats: [Cat!]!
60497
+ }
60498
+
60499
+ interface IsGhost {
60500
+ aka: String!
60501
+ }
60502
+
60213
60503
  union Entity = User | Cat | Ghost
60214
60504
 
60215
60505
  type Mutation {
@@ -60306,13 +60596,13 @@ function pipelineTest(config2, documents, shouldPass, testBody) {
60306
60596
  await runPipeline2(config2, docs);
60307
60597
  } catch (e) {
60308
60598
  if (shouldPass) {
60309
- throw e;
60599
+ console.error(e);
60600
+ throw "pipeline failed when it should have passed";
60310
60601
  }
60311
60602
  error = e;
60312
60603
  }
60313
60604
  if (!shouldPass && error.length === 0) {
60314
- throw "did not fail test";
60315
- return;
60605
+ throw "pipeline shouldn't have passed!";
60316
60606
  }
60317
60607
  if (testBody) {
60318
60608
  testBody(shouldPass ? docs : error);