houdini 0.17.8 → 0.17.9

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 (48) hide show
  1. package/.turbo/turbo-compile.log +2 -2
  2. package/.turbo/turbo-typedefs.log +2 -2
  3. package/CHANGELOG.md +10 -0
  4. package/build/cmd-cjs/index.js +124 -38
  5. package/build/cmd-esm/index.js +124 -38
  6. package/build/codegen-cjs/index.js +112 -36
  7. package/build/codegen-esm/index.js +112 -36
  8. package/build/lib/config.d.ts +3 -0
  9. package/build/lib-cjs/index.js +31 -12
  10. package/build/lib-esm/index.js +31 -12
  11. package/build/runtime/cache/cache.d.ts +1 -1
  12. package/build/runtime/cache/lists.d.ts +1 -1
  13. package/build/runtime/lib/config.d.ts +10 -2
  14. package/build/runtime/lib/types.d.ts +1 -0
  15. package/build/runtime-cjs/cache/cache.d.ts +1 -1
  16. package/build/runtime-cjs/cache/cache.js +6 -6
  17. package/build/runtime-cjs/cache/lists.d.ts +1 -1
  18. package/build/runtime-cjs/cache/lists.js +15 -6
  19. package/build/runtime-cjs/cache/tests/list.test.js +160 -70
  20. package/build/runtime-cjs/lib/config.d.ts +10 -2
  21. package/build/runtime-cjs/lib/types.d.ts +1 -0
  22. package/build/runtime-esm/cache/cache.d.ts +1 -1
  23. package/build/runtime-esm/cache/cache.js +6 -6
  24. package/build/runtime-esm/cache/lists.d.ts +1 -1
  25. package/build/runtime-esm/cache/lists.js +15 -6
  26. package/build/runtime-esm/cache/tests/list.test.js +160 -70
  27. package/build/runtime-esm/lib/config.d.ts +10 -2
  28. package/build/runtime-esm/lib/types.d.ts +1 -0
  29. package/build/test-cjs/index.js +122 -36
  30. package/build/test-esm/index.js +122 -36
  31. package/build/vite-cjs/index.js +122 -36
  32. package/build/vite-esm/index.js +122 -36
  33. package/package.json +1 -1
  34. package/src/codegen/generators/artifacts/artifacts.test.ts +268 -0
  35. package/src/codegen/generators/artifacts/operations.ts +31 -13
  36. package/src/codegen/generators/definitions/schema.test.ts +9 -0
  37. package/src/codegen/transforms/list.ts +0 -1
  38. package/src/codegen/transforms/paginate.test.ts +47 -0
  39. package/src/codegen/transforms/paginate.ts +28 -8
  40. package/src/codegen/transforms/schema.ts +5 -0
  41. package/src/codegen/validators/typeCheck.test.ts +56 -0
  42. package/src/codegen/validators/typeCheck.ts +66 -11
  43. package/src/lib/config.ts +11 -0
  44. package/src/runtime/cache/cache.ts +9 -6
  45. package/src/runtime/cache/lists.ts +24 -10
  46. package/src/runtime/cache/tests/list.test.ts +173 -66
  47. package/src/runtime/lib/config.ts +12 -2
  48. package/src/runtime/lib/types.ts +1 -0
@@ -1,5 +1,5 @@
1
- houdini:compile: cache hit, replaying output 46091d3751e7378b
1
+ houdini:compile: cache hit, replaying output 0e01ddbb04113c7d
2
2
  houdini:compile:
3
- houdini:compile: > houdini@0.17.8 compile /home/runner/work/houdini/houdini/packages/houdini
3
+ houdini:compile: > houdini@0.17.9 compile /home/runner/work/houdini/houdini/packages/houdini
4
4
  houdini:compile: > scripts build
5
5
  houdini:compile:
@@ -1,5 +1,5 @@
1
- houdini:typedefs: cache hit, replaying output 56dc71f9cf5019cc
1
+ houdini:typedefs: cache hit, replaying output b1c668e379118489
2
2
  houdini:typedefs:
3
- houdini:typedefs: > houdini@0.17.8 typedefs /home/runner/work/houdini/houdini/packages/houdini
3
+ houdini:typedefs: > houdini@0.17.9 typedefs /home/runner/work/houdini/houdini/packages/houdini
4
4
  houdini:typedefs: > scripts typedefs
5
5
  houdini:typedefs:
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # houdini
2
2
 
3
+ ## 0.17.9
4
+
5
+ ### 🐛 Fixes
6
+
7
+ - [#693](https://github.com/HoudiniGraphql/houdini/pull/693) [`6e36775`](https://github.com/HoudiniGraphql/houdini/commit/6e367755d902eca3242519b4c609c0d5bc76f4ff) Thanks [@AlecAivazis](https://github.com/AlecAivazis)! - Fix bug causing `@parentID` to be ignored when there was only one version of the list
8
+
9
+ ### ✨ Features
10
+
11
+ - [#693](https://github.com/HoudiniGraphql/houdini/pull/693) [`6e36775`](https://github.com/HoudiniGraphql/houdini/commit/6e367755d902eca3242519b4c609c0d5bc76f4ff) Thanks [@jycouet](https://github.com/jycouet)! - Adding a new directive @allLists to update all lists after a mutation
12
+
3
13
  ## 0.17.6
4
14
 
5
15
  ### 🐛 Fixes
@@ -67825,22 +67825,31 @@ var ListManager = class {
67825
67825
  }
67826
67826
  lists = /* @__PURE__ */ new Map();
67827
67827
  listsByField = /* @__PURE__ */ new Map();
67828
- get(listName, id) {
67828
+ get(listName, id, allLists) {
67829
67829
  const matches = this.lists.get(listName);
67830
67830
  if (!matches || matches.size === 0) {
67831
67831
  return null;
67832
67832
  }
67833
+ if (allLists) {
67834
+ return new ListCollection(
67835
+ Array.from(matches, ([key, value]) => [...value.lists]).flat()
67836
+ );
67837
+ }
67833
67838
  const head = [...matches.values()][0];
67839
+ const { recordType } = head.lists[0];
67840
+ const parentID = id ? this.cache._internal_unstable.id(recordType || "", id) : this.rootID;
67834
67841
  if (matches?.size === 1) {
67835
- return head;
67842
+ if (!id) {
67843
+ return head;
67844
+ }
67845
+ return parentID === Array.from(matches.keys())[0] ? head : null;
67836
67846
  }
67837
67847
  if (!id) {
67838
- throw new Error(
67839
- `Found multiple instances of "${listName}". Please provide a parentID that corresponds to the object containing the field marked with @list or @paginate.`
67848
+ console.error(
67849
+ `Found multiple instances of "${listName}". Please provide one of @parentID or @allLists directives to help identify which list you want modify. For more information, visit this guide: https://www.houdinigraphql.com/api/graphql#parentidvalue-string `
67840
67850
  );
67851
+ return null;
67841
67852
  }
67842
- const { recordType } = head.lists[0];
67843
- const parentID = id ? this.cache._internal_unstable.id(recordType || "", id) : this.rootID;
67844
67853
  return this.lists.get(listName)?.get(parentID);
67845
67854
  }
67846
67855
  remove(listName, id) {
@@ -68786,8 +68795,8 @@ var Cache2 = class {
68786
68795
  variables
68787
68796
  );
68788
68797
  }
68789
- list(name2, parentID) {
68790
- const handler = this._internal_unstable.lists.get(name2, parentID);
68798
+ list(name2, parentID, allLists) {
68799
+ const handler = this._internal_unstable.lists.get(name2, parentID, allLists);
68791
68800
  if (!handler) {
68792
68801
  throw new Error(
68793
68802
  `Cannot find list with name: ${name2}${parentID ? " under parent " + parentID : ""}. Is it possible that the query is not mounted?`
@@ -69054,15 +69063,15 @@ var CacheInternal = class {
69054
69063
  parentID = id;
69055
69064
  }
69056
69065
  }
69057
- if (operation.list && !this.lists.get(operation.list, parentID)) {
69066
+ if (operation.list && !this.lists.get(operation.list, parentID, operation.target === "all")) {
69058
69067
  continue;
69059
69068
  }
69060
69069
  const targets = Array.isArray(value) ? value : [value];
69061
69070
  for (const target of targets) {
69062
69071
  if (operation.action === "insert" && target instanceof Object && fields && operation.list) {
69063
- this.cache.list(operation.list, parentID).when(operation.when).addToList(fields, target, variables, operation.position || "last");
69072
+ this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).addToList(fields, target, variables, operation.position || "last");
69064
69073
  } else if (operation.action === "remove" && target instanceof Object && fields && operation.list) {
69065
- this.cache.list(operation.list, parentID).when(operation.when).remove(target, variables);
69074
+ this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).remove(target, variables);
69066
69075
  } else if (operation.action === "delete" && operation.type) {
69067
69076
  if (typeof target !== "string") {
69068
69077
  throw new Error("Cannot delete a record with a non-string ID");
@@ -69073,7 +69082,7 @@ var CacheInternal = class {
69073
69082
  }
69074
69083
  this.cache.delete(targetID);
69075
69084
  } else if (operation.action === "toggle" && target instanceof Object && fields && operation.list) {
69076
- this.cache.list(operation.list, parentID).when(operation.when).toggleElement(fields, target, variables, operation.position || "last");
69085
+ this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement(fields, target, variables, operation.position || "last");
69077
69086
  }
69078
69087
  }
69079
69088
  }
@@ -70868,6 +70877,8 @@ var Config = class {
70868
70877
  cacheBufferSize;
70869
70878
  defaultCachePolicy;
70870
70879
  defaultPartial;
70880
+ internalListPosition;
70881
+ defaultListTarget = null;
70871
70882
  definitionsFolder;
70872
70883
  newSchema = "";
70873
70884
  newDocuments = "";
@@ -70899,6 +70910,8 @@ var Config = class {
70899
70910
  definitionsPath,
70900
70911
  defaultCachePolicy = "CacheOrNetwork" /* CacheOrNetwork */,
70901
70912
  defaultPartial = false,
70913
+ defaultListPosition = "append",
70914
+ defaultListTarget = null,
70902
70915
  defaultKeys,
70903
70916
  types: types14 = {},
70904
70917
  logLevel,
@@ -70932,6 +70945,8 @@ var Config = class {
70932
70945
  this.cacheBufferSize = cacheBufferSize;
70933
70946
  this.defaultCachePolicy = defaultCachePolicy;
70934
70947
  this.defaultPartial = defaultPartial;
70948
+ this.internalListPosition = defaultListPosition === "append" ? "last" : "first";
70949
+ this.defaultListTarget == defaultListTarget;
70935
70950
  this.definitionsFolder = definitionsPath;
70936
70951
  this.logLevel = (logLevel || LogLevel.Summary).toLowerCase();
70937
70952
  this.disableMasking = disableMasking;
@@ -71146,6 +71161,9 @@ var Config = class {
71146
71161
  get listDirectiveParentIDArg() {
71147
71162
  return "parentID";
71148
71163
  }
71164
+ get listAllListsDirective() {
71165
+ return "allLists";
71166
+ }
71149
71167
  get listNameArg() {
71150
71168
  return "name";
71151
71169
  }
@@ -71227,6 +71245,7 @@ var Config = class {
71227
71245
  this.listPrependDirective,
71228
71246
  this.listAppendDirective,
71229
71247
  this.listDirectiveParentIDArg,
71248
+ this.listAllListsDirective,
71230
71249
  this.whenDirective,
71231
71250
  this.whenNotDirective,
71232
71251
  this.argumentsDirective,
@@ -72235,7 +72254,8 @@ function operationObject({
72235
72254
  }) {
72236
72255
  let parentID;
72237
72256
  let parentKind = "String";
72238
- let position = "last";
72257
+ let position = config2.internalListPosition;
72258
+ let allLists = config2.defaultListTarget ?? void 0;
72239
72259
  let operationWhen;
72240
72260
  const internalDirectives = selection2.directives?.filter(
72241
72261
  (directive) => config2.isInternalDirective(directive)
@@ -72247,15 +72267,21 @@ function operationObject({
72247
72267
  const append = internalDirectives.find(
72248
72268
  ({ name: name2 }) => name2.value === config2.listAppendDirective
72249
72269
  );
72250
- const when = internalDirectives.find(({ name: name2 }) => name2.value === "when");
72251
- const when_not = internalDirectives.find(({ name: name2 }) => name2.value === "when_not");
72270
+ if (append) {
72271
+ position = "last";
72272
+ }
72273
+ if (prepend) {
72274
+ position = "first";
72275
+ }
72276
+ const allListsDirective = internalDirectives.find(
72277
+ ({ name: name2 }) => name2.value === config2.listAllListsDirective
72278
+ );
72252
72279
  let parent = internalDirectives.find(
72253
72280
  ({ name: name2 }) => name2.value === config2.listParentDirective
72254
72281
  );
72255
- if (append && prepend) {
72256
- throw new HoudiniError({ filepath, message: "you have both applied" });
72257
- }
72258
- position = prepend ? "first" : "last";
72282
+ allLists = allListsDirective ? "all" : void 0;
72283
+ const when = internalDirectives.find(({ name: name2 }) => name2.value === "when");
72284
+ const when_not = internalDirectives.find(({ name: name2 }) => name2.value === "when_not");
72259
72285
  let parentIDArg = parent?.arguments?.find((argument) => argument.name.value === "value");
72260
72286
  if (!parentIDArg) {
72261
72287
  parentIDArg = (append || prepend)?.arguments?.find(
@@ -72317,7 +72343,10 @@ function operationObject({
72317
72343
  operation.type = type;
72318
72344
  }
72319
72345
  if (operationKind === "insert" || operationKind === "toggle") {
72320
- operation.position = position || "last";
72346
+ operation.position = position;
72347
+ }
72348
+ if (operationKind === "insert" && allLists) {
72349
+ operation.target = "all";
72321
72350
  }
72322
72351
  if (parentID) {
72323
72352
  operation.parentID = {
@@ -72478,12 +72507,15 @@ async function paginate(config2, documents) {
72478
72507
  {}
72479
72508
  ) || {};
72480
72509
  let newVariables = Object.fromEntries(
72481
- Object.entries(flags).filter(([, spec]) => spec.enabled).map(([fieldName, spec]) => [
72510
+ Object.entries(flags).filter(
72511
+ ([, spec]) => spec.enabled && spec.variableName === void 0
72512
+ ).map(([fieldName, spec]) => [
72482
72513
  fieldName,
72483
72514
  staticVariableDefinition(
72484
72515
  fieldName,
72485
72516
  spec.type,
72486
- spec.defaultValue
72517
+ spec.defaultValue,
72518
+ spec.variableName
72487
72519
  )
72488
72520
  ])
72489
72521
  );
@@ -72735,8 +72767,11 @@ function replaceArgumentsWithVariables(args, flags) {
72735
72767
  const oldValue = arg.value.value;
72736
72768
  flags[arg.name.value].defaultValue = spec.type === "Int" ? parseInt(oldValue) : oldValue;
72737
72769
  }
72770
+ if (arg.value.kind === "Variable") {
72771
+ flags[arg.name.value].variableName = arg.value.name.value;
72772
+ }
72738
72773
  seenArgs[arg.name.value] = true;
72739
- return variableAsArgument(arg.name.value);
72774
+ return variableAsArgument(arg.name.value, flags[arg.name.value].variableName);
72740
72775
  });
72741
72776
  for (const name2 of Object.keys(flags)) {
72742
72777
  const spec = flags[name2];
@@ -72753,7 +72788,7 @@ function replaceArgumentsWithVariables(args, flags) {
72753
72788
  }
72754
72789
  return newArgs;
72755
72790
  }
72756
- function variableAsArgument(name2) {
72791
+ function variableAsArgument(name2, variable) {
72757
72792
  return {
72758
72793
  kind: graphql9.Kind.ARGUMENT,
72759
72794
  name: {
@@ -72764,12 +72799,12 @@ function variableAsArgument(name2) {
72764
72799
  kind: graphql9.Kind.VARIABLE,
72765
72800
  name: {
72766
72801
  kind: graphql9.Kind.NAME,
72767
- value: name2
72802
+ value: variable ?? name2
72768
72803
  }
72769
72804
  }
72770
72805
  };
72771
72806
  }
72772
- function staticVariableDefinition(name2, type, defaultValue) {
72807
+ function staticVariableDefinition(name2, type, defaultValue, variableName) {
72773
72808
  return {
72774
72809
  kind: graphql9.Kind.VARIABLE_DEFINITION,
72775
72810
  type: {
@@ -72783,7 +72818,7 @@ function staticVariableDefinition(name2, type, defaultValue) {
72783
72818
  kind: graphql9.Kind.VARIABLE,
72784
72819
  name: {
72785
72820
  kind: graphql9.Kind.NAME,
72786
- value: name2
72821
+ value: variableName ?? name2
72787
72822
  }
72788
72823
  },
72789
72824
  defaultValue: !defaultValue ? void 0 : {
@@ -74592,6 +74627,11 @@ directive @${config2.listPrependDirective}(
74592
74627
  """
74593
74628
  directive @${config2.listAppendDirective}(${config2.listDirectiveParentIDArg}: ID) on FRAGMENT_SPREAD
74594
74629
 
74630
+ """
74631
+ @${config2.listAllListsDirective} is used to tell the runtime to add the result to all list
74632
+ """
74633
+ directive @${config2.listAllListsDirective} on FRAGMENT_SPREAD
74634
+
74595
74635
  """
74596
74636
  @${config2.listParentDirective} is used to provide a parentID without specifying position or in situations
74597
74637
  where it doesn't make sense (eg when deleting a node.)
@@ -75171,6 +75211,7 @@ async function typeCheck(config2, docs) {
75171
75211
  listTypes,
75172
75212
  fragments
75173
75213
  }),
75214
+ checkMutationOperation(config2),
75174
75215
  nodeDirectives(config2, [config2.paginateDirective]),
75175
75216
  knownArguments(config2),
75176
75217
  validateFragmentArguments(config2, filepath, fragments),
@@ -75229,24 +75270,33 @@ var validateLists = ({
75229
75270
  if (directive) {
75230
75271
  return;
75231
75272
  }
75273
+ let parentIdFound = false;
75232
75274
  directive = node.directives?.find(({ name: name2 }) => [
75233
75275
  [config2.listPrependDirective, config2.listAppendDirective].includes(name2.value)
75234
75276
  ]);
75235
- if (!directive) {
75236
- ctx.reportError(
75237
- new graphql25.GraphQLError("parentID is required for this list fragment")
75277
+ if (directive) {
75278
+ let parentArg = directive.arguments?.find(
75279
+ (arg) => arg.name.value === config2.listDirectiveParentIDArg
75238
75280
  );
75281
+ if (parentArg) {
75282
+ parentIdFound = true;
75283
+ }
75284
+ }
75285
+ if (parentIdFound) {
75239
75286
  return;
75240
75287
  }
75241
- let parentArg = directive.arguments?.find(
75242
- (arg) => arg.name.value === config2.listDirectiveParentIDArg
75288
+ const allLists = node.directives?.find(
75289
+ ({ name: name2 }) => config2.listAllListsDirective === name2.value
75243
75290
  );
75244
- if (!parentArg) {
75245
- ctx.reportError(
75246
- new graphql25.GraphQLError("parentID is required for this list fragment")
75247
- );
75291
+ if (allLists || config2.defaultListTarget === "all") {
75248
75292
  return;
75249
75293
  }
75294
+ ctx.reportError(
75295
+ new graphql25.GraphQLError(
75296
+ `For this list fragment, you need to add or @${config2.listParentDirective} or @${config2.listAllListsDirective} directive to specify the behavior`
75297
+ )
75298
+ );
75299
+ return;
75250
75300
  },
75251
75301
  Directive(node) {
75252
75302
  const directiveName = node.name.value;
@@ -75589,6 +75639,42 @@ function nodeDirectives(config2, directives) {
75589
75639
  };
75590
75640
  };
75591
75641
  }
75642
+ function checkMutationOperation(config2) {
75643
+ return function(ctx) {
75644
+ return {
75645
+ FragmentSpread(node, _, __, ___, ancestors) {
75646
+ const append = node.directives?.find(
75647
+ (c) => c.name.value === config2.listAppendDirective
75648
+ );
75649
+ const prepend = node.directives?.find(
75650
+ (c) => c.name.value === config2.listPrependDirective
75651
+ );
75652
+ if (append && prepend) {
75653
+ ctx.reportError(
75654
+ new graphql25.GraphQLError(
75655
+ `You can't apply both @${config2.listPrependDirective} and @${config2.listAppendDirective} at the same time`
75656
+ )
75657
+ );
75658
+ return;
75659
+ }
75660
+ const parentId = node.directives?.find(
75661
+ (c) => c.name.value === config2.listParentDirective
75662
+ );
75663
+ const allLists = node.directives?.find(
75664
+ (c) => c.name.value === config2.listAllListsDirective
75665
+ );
75666
+ if (parentId && allLists) {
75667
+ ctx.reportError(
75668
+ new graphql25.GraphQLError(
75669
+ `You can't apply both @${config2.listParentDirective} and @${config2.listAllListsDirective} at the same time`
75670
+ )
75671
+ );
75672
+ return;
75673
+ }
75674
+ }
75675
+ };
75676
+ };
75677
+ }
75592
75678
  function getAndVerifyNodeInterface(config2) {
75593
75679
  const { schema } = config2;
75594
75680
  const nodeInterface = schema.getType("Node");
@@ -76449,8 +76535,8 @@ async function updatePackageJSON(targetPath) {
76449
76535
  }
76450
76536
  packageJSON.devDependencies = {
76451
76537
  ...packageJSON.devDependencies,
76452
- houdini: "^0.17.8",
76453
- "houdini-svelte": "^0.17.8",
76538
+ houdini: "^0.17.9",
76539
+ "houdini-svelte": "^0.17.9",
76454
76540
  graphql: "^15.8.0"
76455
76541
  };
76456
76542
  await fs_exports.writeFile(packagePath, JSON.stringify(packageJSON, null, 4));