houdini-react 1.2.13 → 1.2.14

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 (56) hide show
  1. package/build/plugin/codegen/render.d.ts +5 -2
  2. package/build/plugin/vite.d.ts +8 -10
  3. package/build/plugin-cjs/index.js +263 -523
  4. package/build/plugin-esm/index.js +263 -523
  5. package/build/runtime/client.d.ts +1 -1
  6. package/build/runtime/index.d.ts +2 -9
  7. package/build/runtime/manifest.d.ts +1 -1
  8. package/build/runtime/routing/{components/Router.d.ts → Router.d.ts} +5 -9
  9. package/build/runtime/routing/index.d.ts +2 -3
  10. package/build/runtime-cjs/client.d.ts +1 -1
  11. package/build/runtime-cjs/client.js +2 -1
  12. package/build/runtime-cjs/hooks/useDocumentHandle.js +1 -1
  13. package/build/runtime-cjs/hooks/useDocumentSubscription.js +1 -1
  14. package/build/runtime-cjs/hooks/useFragment.js +5 -3
  15. package/build/runtime-cjs/hooks/useMutation.js +1 -1
  16. package/build/runtime-cjs/index.d.ts +2 -9
  17. package/build/runtime-cjs/index.js +7 -20
  18. package/build/runtime-cjs/manifest.d.ts +1 -1
  19. package/build/runtime-cjs/routing/{components/Router.d.ts → Router.d.ts} +5 -9
  20. package/build/runtime-cjs/routing/{components/Router.js → Router.js} +3 -17
  21. package/build/runtime-cjs/routing/index.d.ts +2 -3
  22. package/build/runtime-cjs/routing/index.js +2 -2
  23. package/build/runtime-esm/client.d.ts +1 -1
  24. package/build/runtime-esm/client.js +2 -1
  25. package/build/runtime-esm/hooks/useDocumentHandle.js +1 -1
  26. package/build/runtime-esm/hooks/useDocumentSubscription.js +1 -1
  27. package/build/runtime-esm/hooks/useFragment.js +4 -2
  28. package/build/runtime-esm/hooks/useMutation.js +1 -1
  29. package/build/runtime-esm/index.d.ts +2 -9
  30. package/build/runtime-esm/index.js +7 -16
  31. package/build/runtime-esm/manifest.d.ts +1 -1
  32. package/build/runtime-esm/routing/{components/Router.d.ts → Router.d.ts} +5 -9
  33. package/build/runtime-esm/routing/{components/Router.js → Router.js} +3 -17
  34. package/build/runtime-esm/routing/index.d.ts +2 -3
  35. package/build/runtime-esm/routing/index.js +2 -2
  36. package/package.json +3 -2
  37. package/build/runtime/routing/components/index.d.ts +0 -1
  38. package/build/runtime/routing/lib/match.d.ts +0 -38
  39. package/build/runtime/routing/lib/types.d.ts +0 -19
  40. package/build/runtime-cjs/routing/components/index.d.ts +0 -1
  41. package/build/runtime-cjs/routing/components/index.js +0 -34
  42. package/build/runtime-cjs/routing/lib/match.d.ts +0 -38
  43. package/build/runtime-cjs/routing/lib/match.js +0 -149
  44. package/build/runtime-cjs/routing/lib/types.d.ts +0 -19
  45. package/build/runtime-cjs/routing/lib/types.js +0 -16
  46. package/build/runtime-esm/routing/components/index.d.ts +0 -1
  47. package/build/runtime-esm/routing/components/index.js +0 -7
  48. package/build/runtime-esm/routing/lib/match.d.ts +0 -38
  49. package/build/runtime-esm/routing/lib/match.js +0 -122
  50. package/build/runtime-esm/routing/lib/types.d.ts +0 -19
  51. package/build/runtime-esm/routing/lib/types.js +0 -0
  52. /package/build/runtime/routing/{lib/cache.d.ts → cache.d.ts} +0 -0
  53. /package/build/runtime-cjs/routing/{lib/cache.d.ts → cache.d.ts} +0 -0
  54. /package/build/runtime-cjs/routing/{lib/cache.js → cache.js} +0 -0
  55. /package/build/runtime-esm/routing/{lib/cache.d.ts → cache.d.ts} +0 -0
  56. /package/build/runtime-esm/routing/{lib/cache.js → cache.js} +0 -0
@@ -74883,8 +74883,8 @@ function computeID(configFile, type, data) {
74883
74883
  return id.slice(0, -2);
74884
74884
  }
74885
74885
  var _configFile = null;
74886
- function localApiSessionKeys(configFile) {
74887
- return configFile.router?.auth?.sessionKeys ?? [];
74886
+ function localApiEndpoint(configFile) {
74887
+ return configFile.router?.apiEndpoint ?? "/_api";
74888
74888
  }
74889
74889
  function getCurrentConfig() {
74890
74890
  const mockConfig2 = getMockConfig();
@@ -75576,10 +75576,10 @@ var validateHeaderValue = typeof http.validateHeaderValue === "function" ? http.
75576
75576
  throw error;
75577
75577
  }
75578
75578
  };
75579
- var Headers2 = class extends URLSearchParams {
75579
+ var Headers = class extends URLSearchParams {
75580
75580
  constructor(init) {
75581
75581
  let result = [];
75582
- if (init instanceof Headers2) {
75582
+ if (init instanceof Headers) {
75583
75583
  const raw = init.raw();
75584
75584
  for (const [name, values] of Object.entries(raw)) {
75585
75585
  result.push(...values.map((value) => [name, value]));
@@ -75703,7 +75703,7 @@ var Headers2 = class extends URLSearchParams {
75703
75703
  }
75704
75704
  };
75705
75705
  Object.defineProperties(
75706
- Headers2.prototype,
75706
+ Headers.prototype,
75707
75707
  ["get", "entries", "forEach", "values"].reduce((result, property) => {
75708
75708
  result[property] = { enumerable: true };
75709
75709
  return result;
@@ -75718,7 +75718,7 @@ var Response2 = class extends Body {
75718
75718
  constructor(body = null, options = {}) {
75719
75719
  super(body, options);
75720
75720
  const status = options.status != null ? options.status : 200;
75721
- const headers = new Headers2(options.headers);
75721
+ const headers = new Headers(options.headers);
75722
75722
  if (body !== null && !headers.has("Content-Type")) {
75723
75723
  const contentType = extractContentType(body, this);
75724
75724
  if (contentType) {
@@ -75793,7 +75793,7 @@ var Response2 = class extends Body {
75793
75793
  if (body === void 0) {
75794
75794
  throw new TypeError("data is not JSON serializable");
75795
75795
  }
75796
- const headers = new Headers2(init && init.headers);
75796
+ const headers = new Headers(init && init.headers);
75797
75797
  if (!headers.has("content-type")) {
75798
75798
  headers.set("content-type", "application/json");
75799
75799
  }
@@ -75869,7 +75869,7 @@ var Request2 = class extends Body {
75869
75869
  super(inputBody, {
75870
75870
  size: init.size || input.size || 0
75871
75871
  });
75872
- const headers = new Headers2(init.headers || input.headers || {});
75872
+ const headers = new Headers(init.headers || input.headers || {});
75873
75873
  if (inputBody !== null && !headers.has("Content-Type")) {
75874
75874
  const contentType = extractContentType(inputBody, this);
75875
75875
  if (contentType) {
@@ -78228,7 +78228,7 @@ var mutation = documentPlugin(ArtifactKind.Mutation, () => {
78228
78228
  }
78229
78229
  };
78230
78230
  });
78231
- var currentDir = global.__dirname || dirname(fileURLToPath(import.meta.url));
78231
+ var currentDir = dirname(fileURLToPath(import.meta.url));
78232
78232
  var DEFAULT_CONFIG_PATH = join2(process.cwd(), "houdini.config.js");
78233
78233
  var emptySchema = graphql2.buildSchema("type Query { hello: String }");
78234
78234
  var defaultDirectives = emptySchema.getDirectives().map((dir) => dir.name);
@@ -78310,6 +78310,122 @@ function ensureImports({
78310
78310
  }
78311
78311
  return Array.isArray(importID) ? toImport : toImport[0];
78312
78312
  }
78313
+ var param_pattern = /^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;
78314
+ function find_match(manifest3, current, allowNull = true) {
78315
+ let match = null;
78316
+ let matchVariables = null;
78317
+ for (const page of Object.values(manifest3.pages)) {
78318
+ const urlMatch = current.match(page.pattern);
78319
+ if (!urlMatch) {
78320
+ continue;
78321
+ }
78322
+ match = page;
78323
+ matchVariables = exec(urlMatch, page.params) || {};
78324
+ break;
78325
+ }
78326
+ if (!match && !allowNull) {
78327
+ throw new Error("404");
78328
+ }
78329
+ return [match, matchVariables];
78330
+ }
78331
+ function parse_page_pattern(id) {
78332
+ const params = [];
78333
+ const pattern = id === "/" ? /^\/$/ : new RegExp(
78334
+ `^${get_route_segments(id).map((segment) => {
78335
+ const rest_match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(segment);
78336
+ if (rest_match) {
78337
+ params.push({
78338
+ name: rest_match[1],
78339
+ matcher: rest_match[2],
78340
+ optional: false,
78341
+ rest: true,
78342
+ chained: true
78343
+ });
78344
+ return "(?:/(.*))?";
78345
+ }
78346
+ const optional_match = /^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(segment);
78347
+ if (optional_match) {
78348
+ params.push({
78349
+ name: optional_match[1],
78350
+ matcher: optional_match[2],
78351
+ optional: true,
78352
+ rest: false,
78353
+ chained: true
78354
+ });
78355
+ return "(?:/([^/]+))?";
78356
+ }
78357
+ if (!segment) {
78358
+ return;
78359
+ }
78360
+ const parts = segment.split(/\[(.+?)\](?!\])/);
78361
+ const result = parts.map((content, i2) => {
78362
+ if (i2 % 2) {
78363
+ if (content.startsWith("x+")) {
78364
+ return escape2(
78365
+ String.fromCharCode(parseInt(content.slice(2), 16))
78366
+ );
78367
+ }
78368
+ if (content.startsWith("u+")) {
78369
+ return escape2(
78370
+ String.fromCharCode(
78371
+ ...content.slice(2).split("-").map((code) => parseInt(code, 16))
78372
+ )
78373
+ );
78374
+ }
78375
+ const match = param_pattern.exec(content);
78376
+ if (!match) {
78377
+ throw new Error(
78378
+ `Invalid param: ${content}. Params and matcher names can only have underscores and alphanumeric characters.`
78379
+ );
78380
+ }
78381
+ const [, is_optional, is_rest, name, matcher] = match;
78382
+ params.push({
78383
+ name,
78384
+ matcher,
78385
+ optional: !!is_optional,
78386
+ rest: !!is_rest,
78387
+ chained: is_rest ? i2 === 1 && parts[0] === "" : false
78388
+ });
78389
+ return is_rest ? "(.*?)" : is_optional ? "([^/]*)?" : "([^/]+?)";
78390
+ }
78391
+ return escape2(content);
78392
+ }).join("");
78393
+ return "/" + result;
78394
+ }).join("")}/?$`
78395
+ );
78396
+ return { pattern, params, page_id: id };
78397
+ }
78398
+ function affects_path(segment) {
78399
+ return !/^\([^)]+\)$/.test(segment);
78400
+ }
78401
+ function get_route_segments(route) {
78402
+ return route.slice(1).split("/").filter(affects_path);
78403
+ }
78404
+ function exec(match, params) {
78405
+ const result = {};
78406
+ const values = match.slice(1);
78407
+ let buffered = "";
78408
+ for (let i2 = 0; i2 < params.length; i2 += 1) {
78409
+ const param = params[i2];
78410
+ let value = values[i2];
78411
+ if (param.chained && param.rest && buffered) {
78412
+ value = value ? buffered + "/" + value : buffered;
78413
+ }
78414
+ buffered = "";
78415
+ if (value === void 0) {
78416
+ if (param.rest)
78417
+ result[param.name] = "";
78418
+ } else {
78419
+ result[param.name] = value;
78420
+ }
78421
+ }
78422
+ if (buffered)
78423
+ return;
78424
+ return result;
78425
+ }
78426
+ function escape2(str) {
78427
+ return str.normalize().replace(/[[\]]/g, "\\$&").replace(/%/g, "%25").replace(/\//g, "%2[Ff]").replace(/\?/g, "%3[Ff]").replace(/#/g, "%23").replace(/[.*+?^${}()|\\]/g, "\\$&");
78428
+ }
78313
78429
  var WalkerBase = class {
78314
78430
  constructor() {
78315
78431
  this.should_skip = false;
@@ -78487,6 +78603,7 @@ async function find_graphql(config2, parsedScript, walker) {
78487
78603
  }
78488
78604
  var conventions_exports = {};
78489
78605
  __export(conventions_exports, {
78606
+ adapter_config_path: () => adapter_config_path,
78490
78607
  fallback_unit_path: () => fallback_unit_path,
78491
78608
  is_layout: () => is_layout,
78492
78609
  layout_unit_path: () => layout_unit_path,
@@ -78498,13 +78615,10 @@ __export(conventions_exports, {
78498
78615
  read_layoutView: () => read_layoutView,
78499
78616
  read_pageQuery: () => read_pageQuery,
78500
78617
  read_pageView: () => read_pageView,
78501
- render_app_path: () => render_app_path,
78502
- render_client_path: () => render_client_path,
78503
- render_server_path: () => render_server_path,
78504
- render_yoga_path: () => render_yoga_path,
78505
78618
  router_index_path: () => router_index_path,
78506
78619
  router_path: () => router_path,
78507
- serialized_manifest_path: () => serialized_manifest_path
78620
+ serialized_manifest_path: () => serialized_manifest_path,
78621
+ server_adapter_path: () => server_adapter_path
78508
78622
  });
78509
78623
  function router_path(config2) {
78510
78624
  return path_exports.join(base_dir(config2), "Router.jsx");
@@ -78512,17 +78626,11 @@ function router_path(config2) {
78512
78626
  function page_entry_path(config2, id, base) {
78513
78627
  return path_exports.join(page_entries_dir(config2, base), `${id}.jsx`);
78514
78628
  }
78515
- function render_client_path(config2, base) {
78516
- return path_exports.join(units_dir(config2, base), "render", "client.jsx");
78517
- }
78518
- function render_server_path(config2, base) {
78629
+ function server_adapter_path(config2, base) {
78519
78630
  return path_exports.join(units_dir(config2, base), "render", "server.js");
78520
78631
  }
78521
- function render_yoga_path(config2, base) {
78522
- return path_exports.join(units_dir(config2, base), "render", "yoga.js");
78523
- }
78524
- function render_app_path(config2, base) {
78525
- return path_exports.join(units_dir(config2, base), "render", "App.jsx");
78632
+ function adapter_config_path(config2, base) {
78633
+ return path_exports.join(units_dir(config2, base), "render", "config.js");
78526
78634
  }
78527
78635
  function page_unit_path(config2, id, base) {
78528
78636
  return path_exports.join(page_units_dir(config2, base), `${id}.jsx`);
@@ -78831,245 +78939,6 @@ async function extractQueries(source) {
78831
78939
  function isSecondaryBuild() {
78832
78940
  return process.env.HOUDINI_SCHEMA_BUILD === "true";
78833
78941
  }
78834
- function parse6(str, options) {
78835
- if (typeof str !== "string") {
78836
- throw new TypeError("argument str must be a string");
78837
- }
78838
- let obj = {};
78839
- let opt = options || {};
78840
- let dec = opt.decode || decode;
78841
- let index = 0;
78842
- while (index < str.length) {
78843
- let eqIdx = str.indexOf("=", index);
78844
- if (eqIdx === -1) {
78845
- break;
78846
- }
78847
- let endIdx = str.indexOf(";", index);
78848
- if (endIdx === -1) {
78849
- endIdx = str.length;
78850
- } else if (endIdx < eqIdx) {
78851
- index = str.lastIndexOf(";", eqIdx - 1) + 1;
78852
- continue;
78853
- }
78854
- let key = str.slice(index, eqIdx).trim();
78855
- if (void 0 === obj[key]) {
78856
- let val = str.slice(eqIdx + 1, endIdx).trim();
78857
- if (val.charCodeAt(0) === 34) {
78858
- val = val.slice(1, -1);
78859
- }
78860
- obj[key] = tryDecode(val, dec);
78861
- }
78862
- index = endIdx + 1;
78863
- }
78864
- return obj;
78865
- }
78866
- function decode(str) {
78867
- return str.indexOf("%") !== -1 ? decodeURIComponent(str) : str;
78868
- }
78869
- function tryDecode(str, decode3) {
78870
- try {
78871
- return decode3(str);
78872
- } catch (e2) {
78873
- return str;
78874
- }
78875
- }
78876
- function base64UrlParse(s2) {
78877
- return new Uint8Array(
78878
- Array.prototype.map.call(
78879
- atob(s2.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, "")),
78880
- (c) => c.charCodeAt(0)
78881
- )
78882
- );
78883
- }
78884
- function base64UrlStringify(a) {
78885
- return btoa(String.fromCharCode.apply(0, a)).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
78886
- }
78887
- var algorithms = {
78888
- ES256: { name: "ECDSA", namedCurve: "P-256", hash: { name: "SHA-256" } },
78889
- ES384: { name: "ECDSA", namedCurve: "P-384", hash: { name: "SHA-384" } },
78890
- ES512: { name: "ECDSA", namedCurve: "P-521", hash: { name: "SHA-512" } },
78891
- HS256: { name: "HMAC", hash: { name: "SHA-256" } },
78892
- HS384: { name: "HMAC", hash: { name: "SHA-384" } },
78893
- HS512: { name: "HMAC", hash: { name: "SHA-512" } },
78894
- RS256: { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } },
78895
- RS384: { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-384" } },
78896
- RS512: { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-512" } }
78897
- };
78898
- function _utf8ToUint8Array(str) {
78899
- return base64UrlParse(btoa(unescape(encodeURIComponent(str))));
78900
- }
78901
- function _str2ab(str) {
78902
- str = atob(str);
78903
- const buf = new ArrayBuffer(str.length);
78904
- const bufView = new Uint8Array(buf);
78905
- for (let i2 = 0, strLen = str.length; i2 < strLen; i2++) {
78906
- bufView[i2] = str.charCodeAt(i2);
78907
- }
78908
- return buf;
78909
- }
78910
- function _decodePayload(raw) {
78911
- switch (raw.length % 4) {
78912
- case 0:
78913
- break;
78914
- case 2:
78915
- raw += "==";
78916
- break;
78917
- case 3:
78918
- raw += "=";
78919
- break;
78920
- default:
78921
- throw new Error("Illegal base64url string!");
78922
- }
78923
- try {
78924
- return JSON.parse(decodeURIComponent(escape(atob(raw))));
78925
- } catch {
78926
- return null;
78927
- }
78928
- }
78929
- async function encode(payload, secret, options = { algorithm: "HS256", header: { typ: "JWT" } }) {
78930
- if (typeof options === "string")
78931
- options = { algorithm: options, header: { typ: "JWT" } };
78932
- options = { algorithm: "HS256", header: { typ: "JWT" }, ...options };
78933
- if (payload === null || typeof payload !== "object")
78934
- throw new Error("payload must be an object");
78935
- if (typeof secret !== "string" && typeof secret !== "object")
78936
- throw new Error("secret must be a string or a JWK object");
78937
- if (typeof options.algorithm !== "string")
78938
- throw new Error("options.algorithm must be a string");
78939
- const algorithm = algorithms[options.algorithm];
78940
- if (!algorithm)
78941
- throw new Error("algorithm not found");
78942
- if (!payload.iat)
78943
- payload.iat = Math.floor(Date.now() / 1e3);
78944
- const payloadAsJSON = JSON.stringify(payload);
78945
- const partialToken = `${base64UrlStringify(
78946
- _utf8ToUint8Array(JSON.stringify({ ...options.header, alg: options.algorithm }))
78947
- )}.${base64UrlStringify(_utf8ToUint8Array(payloadAsJSON))}`;
78948
- let keyFormat = "raw";
78949
- let keyData;
78950
- if (typeof secret === "object") {
78951
- keyFormat = "jwk";
78952
- keyData = secret;
78953
- } else if (typeof secret === "string" && secret.startsWith("-----BEGIN")) {
78954
- keyFormat = "pkcs8";
78955
- keyData = _str2ab(
78956
- secret.replace(/-----BEGIN.*?-----/g, "").replace(/-----END.*?-----/g, "").replace(/\s/g, "")
78957
- );
78958
- } else
78959
- keyData = _utf8ToUint8Array(secret);
78960
- const key = await crypto.subtle.importKey(keyFormat, keyData, algorithm, false, ["sign"]);
78961
- const signature = await crypto.subtle.sign(algorithm, key, _utf8ToUint8Array(partialToken));
78962
- return `${partialToken}.${base64UrlStringify(new Uint8Array(signature))}`;
78963
- }
78964
- async function verify(token, secret, options = { algorithm: "HS256", throwError: false }) {
78965
- if (typeof options === "string")
78966
- options = { algorithm: options, throwError: false };
78967
- options = { algorithm: "HS256", throwError: false, ...options };
78968
- if (typeof token !== "string")
78969
- throw new Error("token must be a string");
78970
- if (typeof secret !== "string" && typeof secret !== "object")
78971
- throw new Error("secret must be a string or a JWK object");
78972
- if (typeof options.algorithm !== "string")
78973
- throw new Error("options.algorithm must be a string");
78974
- const tokenParts = token.split(".");
78975
- if (tokenParts.length !== 3)
78976
- throw new Error("token must consist of 3 parts");
78977
- const algorithm = algorithms[options.algorithm];
78978
- if (!algorithm)
78979
- throw new Error("algorithm not found");
78980
- const { payload } = decode2(token);
78981
- if (!payload) {
78982
- if (options.throwError)
78983
- throw "PARSE_ERROR";
78984
- return false;
78985
- }
78986
- if (payload.nbf && payload.nbf > Math.floor(Date.now() / 1e3)) {
78987
- if (options.throwError)
78988
- throw "NOT_YET_VALID";
78989
- return false;
78990
- }
78991
- if (payload.exp && payload.exp <= Math.floor(Date.now() / 1e3)) {
78992
- if (options.throwError)
78993
- throw "EXPIRED";
78994
- return false;
78995
- }
78996
- let keyFormat = "raw";
78997
- let keyData;
78998
- if (typeof secret === "object") {
78999
- keyFormat = "jwk";
79000
- keyData = secret;
79001
- } else if (typeof secret === "string" && secret.startsWith("-----BEGIN")) {
79002
- keyFormat = "spki";
79003
- keyData = _str2ab(
79004
- secret.replace(/-----BEGIN.*?-----/g, "").replace(/-----END.*?-----/g, "").replace(/\s/g, "")
79005
- );
79006
- } else
79007
- keyData = _utf8ToUint8Array(secret);
79008
- const key = await crypto.subtle.importKey(keyFormat, keyData, algorithm, false, ["verify"]);
79009
- return await crypto.subtle.verify(
79010
- algorithm,
79011
- key,
79012
- base64UrlParse(tokenParts[2]),
79013
- _utf8ToUint8Array(`${tokenParts[0]}.${tokenParts[1]}`)
79014
- );
79015
- }
79016
- function decode2(token) {
79017
- return {
79018
- header: _decodePayload(
79019
- token.split(".")[0].replace(/-/g, "+").replace(/_/g, "/")
79020
- ),
79021
- payload: _decodePayload(
79022
- token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")
79023
- )
79024
- };
79025
- }
79026
- async function handle_request(args) {
79027
- const plugin_config = args.config.router ?? {};
79028
- if (plugin_config.auth && "redirect" in plugin_config.auth && args.url.startsWith(plugin_config.auth.redirect)) {
79029
- return await redirect_auth(args);
79030
- }
79031
- args.next();
79032
- }
79033
- async function redirect_auth(args) {
79034
- const { searchParams } = new URL(args.url, `http://${args.get_header("host")}`);
79035
- const { redirectTo, ...session } = Object.fromEntries(searchParams.entries());
79036
- await set_session(args, session);
79037
- if (redirectTo) {
79038
- return args.redirect(302, redirectTo);
79039
- }
79040
- args.next();
79041
- }
79042
- var session_cookie_name = "__houdini__";
79043
- async function set_session(req, value) {
79044
- const today = new Date();
79045
- const expires = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1e3);
79046
- const serialized = await encode(value, req.session_keys[0]);
79047
- req.set_header(
79048
- "Set-Cookie",
79049
- `${session_cookie_name}=${serialized}; Path=/; HttpOnly; Secure; SameSite=Lax; Expires=${expires.toUTCString()} `
79050
- );
79051
- }
79052
- async function get_session(req, secrets) {
79053
- const cookies = req.get("cookie");
79054
- if (!cookies) {
79055
- return {};
79056
- }
79057
- const cookie = parse6(cookies)[session_cookie_name];
79058
- if (!cookie) {
79059
- return {};
79060
- }
79061
- for (const secret of secrets) {
79062
- if (!await verify(cookie, secret)) {
79063
- continue;
79064
- }
79065
- const parsed = decode2(cookie);
79066
- if (!parsed) {
79067
- return {};
79068
- }
79069
- return parsed.payload;
79070
- }
79071
- return {};
79072
- }
79073
78942
 
79074
78943
  // src/plugin/index.ts
79075
78944
  import path2 from "node:path";
@@ -79106,7 +78975,7 @@ async function generate_routing_units(args) {
79106
78975
  const relative_path = path_exports.relative(path_exports.dirname(unit_path), page_path);
79107
78976
  const component_name = "Component_" + page.id;
79108
78977
  let source = [
79109
- "import { useQueryResult } from '$houdini/plugins/houdini-react/runtime/routing/components/Router'",
78978
+ "import { useQueryResult } from '$houdini/plugins/houdini-react/runtime/routing'",
79110
78979
  `import ${component_name} from "${relative_path}"`
79111
78980
  ];
79112
78981
  source.push(`export default ({ children }) => {
@@ -79298,52 +79167,96 @@ async function write_manifest({
79298
79167
  }
79299
79168
 
79300
79169
  // src/plugin/codegen/render.ts
79301
- async function generate_renders(config) {
79302
- await fs_exports.mkdirp(path_exports.dirname(conventions_exports.render_client_path(config)));
79303
- const app_index = `
79304
- import React from 'react'
79305
- import Shell from '../../../../../src/+index'
79306
- import { Router } from '$houdini'
79170
+ async function generate_renders({
79171
+ config,
79172
+ manifest: manifest3
79173
+ }) {
79174
+ await fs_exports.mkdirp(path_exports.dirname(conventions_exports.server_adapter_path(config)));
79175
+ let adapter_config = `
79176
+ import createAdapter from './server'
79307
79177
 
79308
- export default (props) => <Shell><Router {...props} /></Shell>
79309
- `;
79310
- const render_server = `
79178
+ export const endpoint = ${JSON.stringify(localApiEndpoint(config.configFile))}
79179
+
79180
+ ${manifest3.local_schema ? `import schema from '../../../../../src/api/+schema'` : " const schema = null"}
79181
+
79182
+ ${manifest3.local_yoga ? `import yoga from '.../../../../../src/api/+yoga'` : " const yoga = null"}
79183
+
79184
+ export function createServerAdapter(options) {
79185
+ return createAdapter({
79186
+ schema,
79187
+ yoga,
79188
+ graphqlEndpoint: endpoint,
79189
+ ...options,
79190
+ })
79191
+ }
79192
+ `;
79193
+ const server_adapter = `
79311
79194
  import React from 'react'
79312
79195
  import { renderToStream } from 'react-streaming/server'
79196
+ import { Cache } from '$houdini/runtime/cache/cache'
79197
+ import { serverAdapterFactory } from '$houdini/runtime/router/server'
79313
79198
 
79314
- import App from './App'
79315
- import { router_cache } from '$houdini'
79199
+ import { Router, router_cache } from '../../runtime'
79200
+ import manifest from '../../runtime/manifest'
79316
79201
 
79317
- export function render_to_stream({url, cache, loaded_queries, loaded_artifacts, session, assetPrefix, ...config}) {
79318
- return renderToStream(
79319
- React.createElement(App, {
79320
- initialURL: url,
79321
- cache,
79322
- ...router_cache(),
79323
- loaded_queries,
79324
- session,
79325
- loaded_artifacts,
79326
- assetPrefix,
79327
- }), config
79328
- )
79329
- }
79330
- `;
79331
- const create_yoga = `
79332
- import { createYoga } from 'graphql-yoga'
79333
- import internalSchema from '../../../../../src/api/+schema'
79202
+ import Shell from '../../../../../src/+index'
79203
+
79204
+ export default (options) => {
79205
+ return serverAdapterFactory({
79206
+ manifest,
79207
+ ...options,
79208
+ on_render: async ({url, match, session, pipe , manifest }) => {
79209
+ // instanitate a cache we can use for this request
79210
+ const cache = new Cache({ disabled: false })
79211
+
79212
+ if (!match) {
79213
+ return new Response('not found', { status: 404 })
79214
+ }
79215
+
79216
+ const { readable, injectToStream, pipe: pipeTo } = await renderToStream(
79217
+ React.createElement(Shell, {
79218
+ children: React.createElement(Router, {
79219
+ initialURL: url,
79220
+ cache: cache,
79221
+ session: session,
79222
+ assetPrefix: options.assetPrefix,
79223
+ manifest: manifest,
79224
+ ...router_cache()
79225
+ })
79226
+ }),
79227
+ {
79228
+ userAgent: 'Vite',
79229
+ }
79230
+ )
79334
79231
 
79335
- export default function({ schema = internalSchema, ...opts } = {}) {
79336
- return createYoga({
79337
- schema,
79338
- landingPage: false,
79339
- ...opts
79232
+ // add the initial scripts to the page
79233
+ injectToStream(\`
79234
+ <script>
79235
+ window.__houdini__initial__cache__ = \${cache.serialize()};
79236
+ window.__houdini__initial__session__ = \${JSON.stringify(session)};
79237
+ <\/script>
79238
+
79239
+ <!--
79240
+ add a virtual module that hydrates the client and sets up the initial pending cache.
79241
+ the dynamic extension is to support dev which sees the raw jsx, and production which sees the bundled asset
79242
+ -->
79243
+ <script type="module" src="\${options.assetPrefix}/pages/\${match.id}.\${options.production ? 'js' : 'jsx'}" async=""><\/script>
79244
+ \`)
79245
+
79246
+ if (pipe && pipeTo) {
79247
+ // pipe the response to the client
79248
+ pipeTo(pipe)
79249
+ } else {
79250
+ // and deliver our Response while that's running.
79251
+ return new Response(readable)
79252
+ }
79253
+ },
79340
79254
  })
79341
79255
  }
79342
79256
  `;
79343
79257
  await Promise.all([
79344
- fs_exports.writeFile(conventions_exports.render_server_path(config), render_server),
79345
- fs_exports.writeFile(conventions_exports.render_app_path(config), app_index),
79346
- fs_exports.writeFile(conventions_exports.render_yoga_path(config), create_yoga)
79258
+ fs_exports.writeFile(conventions_exports.server_adapter_path(config), server_adapter),
79259
+ fs_exports.writeFile(conventions_exports.adapter_config_path(config), adapter_config)
79347
79260
  ]);
79348
79261
  }
79349
79262
 
@@ -79473,130 +79386,12 @@ async function routerCodegen({
79473
79386
  }) {
79474
79387
  await Promise.all([
79475
79388
  generate_entries({ config, manifest: manifest3 }),
79476
- generate_renders(config),
79389
+ generate_renders({ config, manifest: manifest3 }),
79477
79390
  generate_type_root({ config, manifest: manifest3 }),
79478
79391
  write_manifest({ config, manifest: manifest3 })
79479
79392
  ]);
79480
79393
  }
79481
79394
 
79482
- // src/runtime/routing/lib/match.ts
79483
- var param_pattern = /^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;
79484
- function find_match(manifest3, current, allowNull) {
79485
- let match = null;
79486
- let matchVariables = null;
79487
- for (const page of Object.values(manifest3.pages)) {
79488
- const urlMatch = current.match(page.pattern);
79489
- if (!urlMatch) {
79490
- continue;
79491
- }
79492
- match = page;
79493
- matchVariables = exec(urlMatch, page.params) || {};
79494
- break;
79495
- }
79496
- if (!match && !allowNull) {
79497
- throw new Error("404");
79498
- }
79499
- return [match, matchVariables];
79500
- }
79501
- function parse_page_pattern(id) {
79502
- const params = [];
79503
- const pattern = id === "/" ? /^\/$/ : new RegExp(
79504
- `^${get_route_segments(id).map((segment) => {
79505
- const rest_match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(segment);
79506
- if (rest_match) {
79507
- params.push({
79508
- name: rest_match[1],
79509
- matcher: rest_match[2],
79510
- optional: false,
79511
- rest: true,
79512
- chained: true
79513
- });
79514
- return "(?:/(.*))?";
79515
- }
79516
- const optional_match = /^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(segment);
79517
- if (optional_match) {
79518
- params.push({
79519
- name: optional_match[1],
79520
- matcher: optional_match[2],
79521
- optional: true,
79522
- rest: false,
79523
- chained: true
79524
- });
79525
- return "(?:/([^/]+))?";
79526
- }
79527
- if (!segment) {
79528
- return;
79529
- }
79530
- const parts = segment.split(/\[(.+?)\](?!\])/);
79531
- const result = parts.map((content, i2) => {
79532
- if (i2 % 2) {
79533
- if (content.startsWith("x+")) {
79534
- return escape2(
79535
- String.fromCharCode(parseInt(content.slice(2), 16))
79536
- );
79537
- }
79538
- if (content.startsWith("u+")) {
79539
- return escape2(
79540
- String.fromCharCode(
79541
- ...content.slice(2).split("-").map((code) => parseInt(code, 16))
79542
- )
79543
- );
79544
- }
79545
- const match = param_pattern.exec(content);
79546
- if (!match) {
79547
- throw new Error(
79548
- `Invalid param: ${content}. Params and matcher names can only have underscores and alphanumeric characters.`
79549
- );
79550
- }
79551
- const [, is_optional, is_rest, name, matcher] = match;
79552
- params.push({
79553
- name,
79554
- matcher,
79555
- optional: !!is_optional,
79556
- rest: !!is_rest,
79557
- chained: is_rest ? i2 === 1 && parts[0] === "" : false
79558
- });
79559
- return is_rest ? "(.*?)" : is_optional ? "([^/]*)?" : "([^/]+?)";
79560
- }
79561
- return escape2(content);
79562
- }).join("");
79563
- return "/" + result;
79564
- }).join("")}/?$`
79565
- );
79566
- return { pattern, params, page_id: id };
79567
- }
79568
- function affects_path(segment) {
79569
- return !/^\([^)]+\)$/.test(segment);
79570
- }
79571
- function get_route_segments(route) {
79572
- return route.slice(1).split("/").filter(affects_path);
79573
- }
79574
- function exec(match, params) {
79575
- const result = {};
79576
- const values = match.slice(1);
79577
- let buffered = "";
79578
- for (let i2 = 0; i2 < params.length; i2 += 1) {
79579
- const param = params[i2];
79580
- let value = values[i2];
79581
- if (param.chained && param.rest && buffered) {
79582
- value = value ? buffered + "/" + value : buffered;
79583
- }
79584
- buffered = "";
79585
- if (value === void 0) {
79586
- if (param.rest)
79587
- result[param.name] = "";
79588
- } else {
79589
- result[param.name] = value;
79590
- }
79591
- }
79592
- if (buffered)
79593
- return;
79594
- return result;
79595
- }
79596
- function escape2(str) {
79597
- return str.normalize().replace(/[[\]]/g, "\\$&").replace(/%/g, "%25").replace(/\//g, "%2[Ff]").replace(/\?/g, "%3[Ff]").replace(/#/g, "%23").replace(/[.*+?^${}()|\\]/g, "\\$&");
79598
- }
79599
-
79600
79395
  // src/plugin/codegen/router.ts
79601
79396
  function format_router_manifest({
79602
79397
  config,
@@ -79744,6 +79539,7 @@ var vite_default = {
79744
79539
  }
79745
79540
  };
79746
79541
  if (!isSecondaryBuild()) {
79542
+ await fs_exports.mkdirp(config.compiledAssetsDir);
79747
79543
  rollupConfig.outDir = config.compiledAssetsDir;
79748
79544
  rollupConfig.rollupOptions.input = {};
79749
79545
  for (const [id, page] of Object.entries(manifest.pages)) {
@@ -79780,7 +79576,7 @@ var vite_default = {
79780
79576
  arg = parsedPath.name;
79781
79577
  if (which === "pages") {
79782
79578
  const [id2, query_names] = arg.split("@");
79783
- const queries = query_names.split(",");
79579
+ const queries = query_names ? query_names.split(",") : [];
79784
79580
  return `
79785
79581
  import { hydrateRoot } from 'react-dom/client';
79786
79582
  import App from '$houdini/plugins/houdini-react/units/render/App'
@@ -79789,6 +79585,7 @@ var vite_default = {
79789
79585
  import client from '$houdini/plugins/houdini-react/runtime/client'
79790
79586
  import Component from '$houdini/plugins/houdini-react/units/entries/${id2}.jsx'
79791
79587
 
79588
+
79792
79589
  // if there is pending data (or artifacts) then we should prime the caches
79793
79590
  let initialData = {}
79794
79591
  let initialArtifacts = {}
@@ -79796,7 +79593,7 @@ var vite_default = {
79796
79593
  if (!window.__houdini__cache__) {
79797
79594
  window.__houdini__cache__ = new Cache()
79798
79595
  window.__houdini__hydration__layer__ = window.__houdini__cache__._internal_unstable.storage.createLayer(true)
79799
- window.__houdini__client__ = client
79596
+ window.__houdini__client__ = client()
79800
79597
  }
79801
79598
 
79802
79599
  // the artifacts are the source of the zip (without them, we can't prime either cache)
@@ -79807,7 +79604,7 @@ var vite_default = {
79807
79604
  // if we also have data for the artifact, save it in the initial data cache
79808
79605
  if (window.__houdini__pending_data__?.[artifactName]) {
79809
79606
  // create the store we'll put in the cache
79810
- const observer = client.observe({ artifact, cache: window.__houdini__cache__, initialValue: window.__houdini__pending_data__[artifactName] })
79607
+ const observer = window.__houdini__client__.observe({ artifact, cache: window.__houdini__cache__, initialValue: window.__houdini__pending_data__[artifactName] })
79811
79608
 
79812
79609
  // save it in the cache
79813
79610
  initialData[artifactName] = observer
@@ -79850,113 +79647,56 @@ if (window.__houdini__nav_caches__ && window.__houdini__nav_caches__.artifact_ca
79850
79647
  `;
79851
79648
  }
79852
79649
  },
79853
- configureServer(server) {
79854
- if (manifest.local_schema) {
79855
- server.middlewares.use(async (req, res, next) => {
79856
- if (!req.url?.startsWith(server.houdiniConfig.localAPIUrl)) {
79650
+ async configureServer(server) {
79651
+ server.middlewares.use(async (req, res, next) => {
79652
+ const { default: router_manifest } = await server.ssrLoadModule(
79653
+ path_exports.join(
79654
+ server.houdiniConfig.pluginRuntimeDirectory("houdini-react"),
79655
+ "manifest.js"
79656
+ )
79657
+ );
79658
+ try {
79659
+ const [match] = find_match(router_manifest, req.url ?? "/");
79660
+ if (!match) {
79661
+ throw new Error();
79662
+ }
79663
+ } catch {
79664
+ if (req.url !== localApiEndpoint(server.houdiniConfig.configFile)) {
79857
79665
  return next();
79858
79666
  }
79859
- let yoga;
79860
- if (manifest.local_yoga) {
79861
- const yogaPath = path_exports.join(
79667
+ }
79668
+ const project_manifest = await load_manifest({ config: server.houdiniConfig });
79669
+ let schema = null;
79670
+ if (project_manifest.local_schema) {
79671
+ schema = (await server.ssrLoadModule(
79672
+ path_exports.join(
79862
79673
  server.houdiniConfig.localApiDir,
79863
- "+yoga?t=" + new Date().getTime()
79864
- );
79865
- yoga = await server.ssrLoadModule(yogaPath);
79866
- } else {
79867
- const { default: schema } = await server.ssrLoadModule(
79868
- path_exports.join(
79869
- server.houdiniConfig.localApiDir,
79870
- "+schema?t=" + new Date().getTime()
79871
- )
79872
- );
79873
- const { default: createYoga } = await server.ssrLoadModule(
79874
- conventions_exports.render_yoga_path(server.houdiniConfig) + "?t=" + new Date().getTime()
79875
- );
79876
- yoga = createYoga({
79877
- schema,
79878
- graphqlEndpoint: server.houdiniConfig.localAPIUrl,
79879
- landingPage: false
79880
- });
79881
- }
79882
- return yoga(req, res, next);
79883
- });
79884
- }
79885
- server.middlewares.use(houdini_auth_routes(server));
79886
- server.middlewares.use(render_stream(server));
79887
- }
79888
- };
79889
- var houdini_auth_routes = (server) => {
79890
- return async (req, res, next) => {
79891
- if (!req.url) {
79892
- return next();
79893
- }
79894
- handle_request({
79895
- config: server.houdiniConfig.configFile,
79896
- session_keys: localApiSessionKeys(server.houdiniConfig.configFile),
79897
- next,
79898
- url: req.url,
79899
- ...res,
79900
- redirect(status = 307, url) {
79901
- res.statusCode = status;
79902
- res.setHeader("location", url);
79903
- res.setHeader("content-length", "0");
79904
- return res.end();
79905
- },
79906
- get_header: res.getHeader.bind(res),
79907
- set_header: res.setHeader.bind(res)
79674
+ "+schema?t=" + new Date().getTime()
79675
+ )
79676
+ )).default;
79677
+ }
79678
+ const serverAdapter = (await server.ssrLoadModule(
79679
+ conventions_exports.server_adapter_path(server.houdiniConfig) + "?t=" + new Date().getTime()
79680
+ )).default;
79681
+ let yoga = null;
79682
+ if (project_manifest.local_yoga) {
79683
+ const yogaPath = path_exports.join(
79684
+ server.houdiniConfig.localApiDir,
79685
+ "+yoga?t=" + new Date().getTime()
79686
+ );
79687
+ yoga = await server.ssrLoadModule(yogaPath);
79688
+ }
79689
+ await serverAdapter({
79690
+ schema,
79691
+ yoga,
79692
+ assetPrefix: "/virtual:houdini",
79693
+ production: false,
79694
+ manifest: router_manifest,
79695
+ pipe: res
79696
+ })(req, res);
79908
79697
  });
79909
- };
79910
- };
79911
- var render_stream = (server) => async (request, response, next) => {
79912
- if (!request.url) {
79913
- return next();
79914
- }
79915
- const { default: manifest3 } = await server.ssrLoadModule(
79916
- path_exports.join(server.houdiniConfig.pluginRuntimeDirectory("houdini-react"), "manifest.js")
79917
- );
79918
- const [match] = find_match(manifest3, request.url, true);
79919
- if (!match) {
79920
- return next();
79921
79698
  }
79922
- const session = get_session(
79923
- new Headers(request.headers),
79924
- localApiSessionKeys(server.houdiniConfig.configFile)
79925
- );
79926
- const { render_to_stream } = await load_render(server);
79927
- const cache = new Cache({ disabled: false });
79928
- const loaded_queries = {};
79929
- const loaded_artifacts = {};
79930
- const { pipe, injectToStream } = await render_to_stream({
79931
- loaded_queries,
79932
- loaded_artifacts,
79933
- url: request.url,
79934
- cache,
79935
- session,
79936
- userAgent: "Vite",
79937
- assetPrefix: "/virtual:houdini"
79938
- });
79939
- const pending_queries = Object.keys(match.documents);
79940
- const pending_query_names = pending_queries.filter((q) => !(q in loaded_queries)).join(",");
79941
- pipe?.(response);
79942
- const entry = `/virtual:houdini/pages/${match.id}@${pending_query_names}.jsx`;
79943
- injectToStream(`
79944
- <script>
79945
- window.__houdini__initial__cache__ = ${cache.serialize()};
79946
- window.__houdini__initial__session__ = ${JSON.stringify(session)};
79947
- <\/script>
79948
-
79949
- <script type="module" src="/@vite/client" async=""><\/script>
79950
-
79951
- <!-- add a virtual module that hydrates the client and sets up the initial pending cache -->
79952
- <script type="module" src="${entry}" async=""><\/script>
79953
- `);
79954
79699
  };
79955
- async function load_render(server) {
79956
- return await server.ssrLoadModule(
79957
- conventions_exports.render_server_path(server.houdiniConfig) + "?t=" + new Date().getTime()
79958
- );
79959
- }
79960
79700
 
79961
79701
  // src/plugin/index.ts
79962
79702
  var manifest2;
@@ -79998,7 +79738,7 @@ var hooks = async () => ({
79998
79738
  path2.join(config.projectRoot, "src", "+client")
79999
79739
  );
80000
79740
  return `${importStatement(relativePath, "client")}
80001
- ${exportDefaultStatement("client")}
79741
+ ${exportDefaultStatement("() => client")}
80002
79742
  `;
80003
79743
  },
80004
79744
  "manifest.js": ({ config, exportDefaultStatement, importStatement }) => {