houdini 0.17.4 → 0.17.6

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 (55) hide show
  1. package/.turbo/turbo-compile.log +2 -2
  2. package/.turbo/turbo-typedefs.log +2 -2
  3. package/CHANGELOG.md +18 -0
  4. package/build/cmd/init.d.ts +2 -2
  5. package/build/cmd-cjs/index.js +9344 -10447
  6. package/build/cmd-esm/index.js +9344 -10447
  7. package/build/codegen/transforms/paginate.d.ts +10 -11
  8. package/build/codegen-cjs/index.js +9143 -10227
  9. package/build/codegen-esm/index.js +9143 -10227
  10. package/build/lib/constants.d.ts +7 -0
  11. package/build/lib/fs.d.ts +2 -0
  12. package/build/lib-cjs/index.js +9265 -10347
  13. package/build/lib-esm/index.js +9264 -10347
  14. package/build/runtime/cache/subscription.d.ts +2 -1
  15. package/build/runtime/lib/network.d.ts +5 -2
  16. package/build/runtime/lib/networkUtils.d.ts +8 -0
  17. package/build/runtime-cjs/cache/cache.js +5 -3
  18. package/build/runtime-cjs/cache/subscription.d.ts +2 -1
  19. package/build/runtime-cjs/cache/subscription.js +6 -4
  20. package/build/runtime-cjs/cache/tests/subscriptions.test.js +101 -0
  21. package/build/runtime-cjs/lib/network.d.ts +5 -2
  22. package/build/runtime-cjs/lib/network.js +39 -3
  23. package/build/runtime-cjs/lib/networkUtils.d.ts +8 -0
  24. package/build/runtime-cjs/lib/networkUtils.js +85 -0
  25. package/build/runtime-esm/cache/cache.js +5 -3
  26. package/build/runtime-esm/cache/subscription.d.ts +2 -1
  27. package/build/runtime-esm/cache/subscription.js +6 -4
  28. package/build/runtime-esm/cache/tests/subscriptions.test.js +101 -0
  29. package/build/runtime-esm/lib/network.d.ts +5 -2
  30. package/build/runtime-esm/lib/network.js +39 -3
  31. package/build/runtime-esm/lib/networkUtils.d.ts +8 -0
  32. package/build/runtime-esm/lib/networkUtils.js +60 -0
  33. package/build/test-cjs/index.js +9144 -10228
  34. package/build/test-esm/index.js +9144 -10228
  35. package/build/vite-cjs/index.js +9283 -10367
  36. package/build/vite-esm/index.js +9283 -10367
  37. package/package.json +2 -2
  38. package/src/cmd/init.ts +169 -187
  39. package/src/codegen/generators/artifacts/artifacts.test.ts +99 -66
  40. package/src/codegen/generators/artifacts/pagination.test.ts +12 -8
  41. package/src/codegen/generators/artifacts/policy.test.ts +12 -8
  42. package/src/codegen/generators/definitions/schema.test.ts +12 -36
  43. package/src/codegen/generators/persistedQueries/persistedQuery.test.ts +2 -2
  44. package/src/codegen/generators/runtime/index.ts +2 -2
  45. package/src/codegen/transforms/fragmentVariables.test.ts +24 -16
  46. package/src/codegen/transforms/paginate.test.ts +9 -6
  47. package/src/codegen/transforms/paginate.ts +2 -2
  48. package/src/lib/config.ts +3 -2
  49. package/src/lib/constants.ts +10 -0
  50. package/src/lib/fs.ts +59 -12
  51. package/src/runtime/cache/cache.ts +3 -1
  52. package/src/runtime/cache/subscription.ts +6 -4
  53. package/src/runtime/cache/tests/subscriptions.test.ts +115 -0
  54. package/src/runtime/lib/network.ts +65 -2
  55. package/src/runtime/lib/networkUtils.ts +151 -0
@@ -5,6 +5,7 @@ export declare class HoudiniClient {
5
5
  private fetchFn;
6
6
  socket: SubscriptionHandler | null | undefined;
7
7
  constructor(networkFn: RequestHandler<any>, subscriptionHandler?: SubscriptionHandler | null);
8
+ handleMultipart(params: FetchParams, args: Parameters<FetchContext['fetch']>): Parameters<FetchContext['fetch']> | undefined;
8
9
  sendRequest<_Data>(ctx: FetchContext, params: FetchParams): Promise<RequestPayloadMagic<_Data>>;
9
10
  }
10
11
  export declare class Environment extends HoudiniClient {
@@ -53,11 +54,12 @@ export declare type RequestHandlerArgs = FetchContext & FetchParams & {
53
54
  session?: App.Session;
54
55
  };
55
56
  export declare type RequestHandler<_Data> = (args: RequestHandlerArgs) => Promise<RequestPayload<_Data>>;
56
- export declare function executeQuery<_Data extends GraphQLObject, _Input extends {}>({ client, artifact, variables, session, cached, fetch, metadata, }: {
57
+ export declare function executeQuery<_Data extends GraphQLObject, _Input extends {}>({ client, artifact, variables, session, setFetching, cached, fetch, metadata, }: {
57
58
  client: HoudiniClient;
58
59
  artifact: QueryArtifact | MutationArtifact;
59
60
  variables: _Input;
60
61
  session: any;
62
+ setFetching: (fetching: boolean) => void;
61
63
  cached: boolean;
62
64
  config: ConfigFile;
63
65
  fetch?: typeof globalThis.fetch;
@@ -66,11 +68,12 @@ export declare function executeQuery<_Data extends GraphQLObject, _Input extends
66
68
  result: RequestPayload;
67
69
  partial: boolean;
68
70
  }>;
69
- export declare function fetchQuery<_Data extends GraphQLObject, _Input extends {}>({ client, artifact, variables, cached, policy, context, }: {
71
+ export declare function fetchQuery<_Data extends GraphQLObject, _Input extends {}>({ client, context, artifact, variables, setFetching, cached, policy, }: {
70
72
  client: HoudiniClient;
71
73
  context: FetchContext;
72
74
  artifact: QueryArtifact | MutationArtifact;
73
75
  variables: _Input;
76
+ setFetching: (fetching: boolean) => void;
74
77
  cached?: boolean;
75
78
  policy?: CachePolicy;
76
79
  }): Promise<FetchQueryResult<_Data>>;
@@ -1,5 +1,6 @@
1
1
  import cache from "../cache";
2
2
  import * as log from "./log";
3
+ import { extractFiles } from "./networkUtils";
3
4
  import {
4
5
  CachePolicy,
5
6
  DataSource
@@ -11,11 +12,42 @@ class HoudiniClient {
11
12
  this.fetchFn = networkFn;
12
13
  this.socket = subscriptionHandler;
13
14
  }
15
+ handleMultipart(params, args) {
16
+ const { clone, files } = extractFiles({
17
+ query: params.text,
18
+ variables: params.variables
19
+ });
20
+ if (files.size) {
21
+ const [url, req] = args;
22
+ let headers = {};
23
+ if (req?.headers) {
24
+ const filtered = Object.entries(req?.headers).filter(([key, value]) => {
25
+ return !(key.toLowerCase() == "content-type" && value.toLowerCase() == "application/json");
26
+ });
27
+ headers = Object.fromEntries(filtered);
28
+ }
29
+ const form = new FormData();
30
+ const operationJSON = JSON.stringify(clone);
31
+ form.set("operations", operationJSON);
32
+ const map = {};
33
+ let i = 0;
34
+ files.forEach((paths) => {
35
+ map[++i] = paths;
36
+ });
37
+ form.set("map", JSON.stringify(map));
38
+ i = 0;
39
+ files.forEach((paths, file) => {
40
+ form.set(`${++i}`, file, file.name);
41
+ });
42
+ return [url, { ...req, headers, body: form }];
43
+ }
44
+ }
14
45
  async sendRequest(ctx, params) {
15
46
  let url = "";
16
47
  const result = await this.fetchFn({
17
48
  fetch: async (...args) => {
18
- const response = await ctx.fetch(...args);
49
+ const newArgs = this.handleMultipart(params, args);
50
+ const response = await ctx.fetch(...newArgs || args);
19
51
  if (response.url) {
20
52
  url = response.url;
21
53
  }
@@ -50,6 +82,7 @@ async function executeQuery({
50
82
  artifact,
51
83
  variables,
52
84
  session,
85
+ setFetching,
53
86
  cached,
54
87
  fetch,
55
88
  metadata
@@ -62,6 +95,7 @@ async function executeQuery({
62
95
  session
63
96
  },
64
97
  artifact,
98
+ setFetching,
65
99
  variables,
66
100
  cached
67
101
  });
@@ -75,11 +109,12 @@ async function executeQuery({
75
109
  }
76
110
  async function fetchQuery({
77
111
  client,
112
+ context,
78
113
  artifact,
79
114
  variables,
115
+ setFetching,
80
116
  cached = true,
81
- policy,
82
- context
117
+ policy
83
118
  }) {
84
119
  if (!client) {
85
120
  throw new Error("could not find houdini environment");
@@ -115,6 +150,7 @@ async function fetchQuery({
115
150
  setTimeout(() => {
116
151
  cache._internal_unstable.collectGarbage();
117
152
  }, 0);
153
+ setFetching(true);
118
154
  const result = await client.sendRequest(context, {
119
155
  text: artifact.raw,
120
156
  hash: artifact.hash,
@@ -0,0 +1,8 @@
1
+ export declare function isExtractableFile(value: any): value is ExtractableFile;
2
+ declare type ExtractableFile = File | Blob;
3
+ /** @typedef {import("./isExtractableFile.mjs").default} isExtractableFile */
4
+ export declare function extractFiles(value: any): {
5
+ clone: any;
6
+ files: Map<any, any>;
7
+ };
8
+ export {};
@@ -0,0 +1,60 @@
1
+ function isExtractableFile(value) {
2
+ return typeof File !== "undefined" && value instanceof File || typeof Blob !== "undefined" && value instanceof Blob;
3
+ }
4
+ function extractFiles(value) {
5
+ if (!arguments.length)
6
+ throw new TypeError("Argument 1 `value` is required.");
7
+ const clones = /* @__PURE__ */ new Map();
8
+ const files = /* @__PURE__ */ new Map();
9
+ function recurse(value2, path, recursed) {
10
+ if (isExtractableFile(value2)) {
11
+ const filePaths = files.get(value2);
12
+ filePaths ? filePaths.push(path) : files.set(value2, [path]);
13
+ return null;
14
+ }
15
+ const valueIsList = Array.isArray(value2) || typeof FileList !== "undefined" && value2 instanceof FileList;
16
+ const valueIsPlainObject = isPlainObject(value2);
17
+ if (valueIsList || valueIsPlainObject) {
18
+ let clone = clones.get(value2);
19
+ const uncloned = !clone;
20
+ if (uncloned) {
21
+ clone = valueIsList ? [] : value2 instanceof Object ? {} : /* @__PURE__ */ Object.create(null);
22
+ clones.set(value2, clone);
23
+ }
24
+ if (!recursed.has(value2)) {
25
+ const pathPrefix = path ? `${path}.` : "";
26
+ const recursedDeeper = new Set(recursed).add(value2);
27
+ if (valueIsList) {
28
+ let index = 0;
29
+ for (const item of value2) {
30
+ const itemClone = recurse(item, pathPrefix + index++, recursedDeeper);
31
+ if (uncloned)
32
+ clone.push(itemClone);
33
+ }
34
+ } else
35
+ for (const key in value2) {
36
+ const propertyClone = recurse(value2[key], pathPrefix + key, recursedDeeper);
37
+ if (uncloned)
38
+ clone[key] = propertyClone;
39
+ }
40
+ }
41
+ return clone;
42
+ }
43
+ return value2;
44
+ }
45
+ return {
46
+ clone: recurse(value, "", /* @__PURE__ */ new Set()),
47
+ files
48
+ };
49
+ }
50
+ function isPlainObject(value) {
51
+ if (typeof value !== "object" || value === null) {
52
+ return false;
53
+ }
54
+ const prototype = Object.getPrototypeOf(value);
55
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
56
+ }
57
+ export {
58
+ extractFiles,
59
+ isExtractableFile
60
+ };