remote-components 0.3.5 → 0.3.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 (124) hide show
  1. package/dist/app-63L5THIQ.js +12 -0
  2. package/dist/app-63L5THIQ.js.map +1 -0
  3. package/dist/app-A5QE7XRH.cjs +12 -0
  4. package/dist/app-A5QE7XRH.cjs.map +1 -0
  5. package/dist/chunk-2VQGCACH.js +190 -0
  6. package/dist/chunk-2VQGCACH.js.map +1 -0
  7. package/dist/chunk-42N2ZLE2.js +703 -0
  8. package/dist/chunk-42N2ZLE2.js.map +1 -0
  9. package/dist/chunk-6IUP26UK.cjs +57 -0
  10. package/dist/chunk-6IUP26UK.cjs.map +1 -0
  11. package/dist/chunk-7MVFHOIP.cjs +60 -0
  12. package/dist/chunk-7MVFHOIP.cjs.map +1 -0
  13. package/dist/chunk-CREXMFMF.cjs +155 -0
  14. package/dist/chunk-CREXMFMF.cjs.map +1 -0
  15. package/dist/chunk-CTUJSWCM.js +215 -0
  16. package/dist/chunk-CTUJSWCM.js.map +1 -0
  17. package/dist/chunk-ENYGL5CO.js +11 -0
  18. package/dist/chunk-ENYGL5CO.js.map +1 -0
  19. package/dist/chunk-ER73O65F.cjs +703 -0
  20. package/dist/chunk-ER73O65F.cjs.map +1 -0
  21. package/dist/chunk-F44NODUS.cjs +709 -0
  22. package/dist/chunk-F44NODUS.cjs.map +1 -0
  23. package/dist/chunk-GAXJTFBV.js +20 -0
  24. package/dist/chunk-GAXJTFBV.js.map +1 -0
  25. package/dist/chunk-HNZVEIKN.js +358 -0
  26. package/dist/chunk-HNZVEIKN.js.map +1 -0
  27. package/dist/chunk-KE7QPAQ4.cjs +21 -0
  28. package/dist/chunk-KE7QPAQ4.cjs.map +1 -0
  29. package/dist/chunk-KEPHL25S.js +60 -0
  30. package/dist/chunk-KEPHL25S.js.map +1 -0
  31. package/dist/chunk-KKBEMQU7.cjs +670 -0
  32. package/dist/chunk-KKBEMQU7.cjs.map +1 -0
  33. package/dist/chunk-KYJWRZ2B.js +709 -0
  34. package/dist/chunk-KYJWRZ2B.js.map +1 -0
  35. package/dist/chunk-N5VQR2PW.cjs +215 -0
  36. package/dist/chunk-N5VQR2PW.cjs.map +1 -0
  37. package/dist/chunk-OO4AMJWO.js +155 -0
  38. package/dist/chunk-OO4AMJWO.js.map +1 -0
  39. package/dist/chunk-R4QFK5TN.cjs +358 -0
  40. package/dist/chunk-R4QFK5TN.cjs.map +1 -0
  41. package/dist/chunk-RUWR74XQ.cjs +152 -0
  42. package/dist/chunk-RUWR74XQ.cjs.map +1 -0
  43. package/dist/chunk-S2A4TFLS.js +152 -0
  44. package/dist/chunk-S2A4TFLS.js.map +1 -0
  45. package/dist/chunk-SHFJ5OQA.cjs +11 -0
  46. package/dist/chunk-SHFJ5OQA.cjs.map +1 -0
  47. package/dist/chunk-TCFLEBQM.cjs +20 -0
  48. package/dist/chunk-TCFLEBQM.cjs.map +1 -0
  49. package/dist/chunk-W5ESPGHH.js +670 -0
  50. package/dist/chunk-W5ESPGHH.js.map +1 -0
  51. package/dist/chunk-X6YKUJKH.js +21 -0
  52. package/dist/chunk-X6YKUJKH.js.map +1 -0
  53. package/dist/chunk-XCFYWSLD.cjs +190 -0
  54. package/dist/chunk-XCFYWSLD.cjs.map +1 -0
  55. package/dist/chunk-ZPMTZ3KJ.js +57 -0
  56. package/dist/chunk-ZPMTZ3KJ.js.map +1 -0
  57. package/dist/config/nextjs.cjs +76 -351
  58. package/dist/config/nextjs.cjs.map +1 -1
  59. package/dist/config/nextjs.js +26 -266
  60. package/dist/config/nextjs.js.map +1 -1
  61. package/dist/config/webpack.cjs +12 -240
  62. package/dist/config/webpack.cjs.map +1 -1
  63. package/dist/config/webpack.js +6 -207
  64. package/dist/config/webpack.js.map +1 -1
  65. package/dist/host/html.cjs +128 -2494
  66. package/dist/host/html.cjs.map +1 -1
  67. package/dist/host/html.js +45 -2382
  68. package/dist/host/html.js.map +1 -1
  69. package/dist/host/nextjs/app/client-only.cjs +53 -2939
  70. package/dist/host/nextjs/app/client-only.cjs.map +1 -1
  71. package/dist/host/nextjs/app/client-only.js +31 -2894
  72. package/dist/host/nextjs/app/client-only.js.map +1 -1
  73. package/dist/host/proxy/client.cjs +8 -38
  74. package/dist/host/proxy/client.cjs.map +1 -1
  75. package/dist/host/proxy/client.js +4 -7
  76. package/dist/host/proxy/client.js.map +1 -1
  77. package/dist/host/proxy.cjs +19 -56
  78. package/dist/host/proxy.cjs.map +1 -1
  79. package/dist/host/proxy.js +8 -20
  80. package/dist/host/proxy.js.map +1 -1
  81. package/dist/host/react.cjs +17 -2870
  82. package/dist/host/react.cjs.map +1 -1
  83. package/dist/host/react.js +13 -2837
  84. package/dist/host/react.js.map +1 -1
  85. package/dist/internal/host/server/fetch-remote-component.cjs +1 -18
  86. package/dist/internal/host/server/fetch-remote-component.cjs.map +1 -1
  87. package/dist/internal/host/server/fetch-remote-component.js +1 -18
  88. package/dist/internal/host/server/fetch-remote-component.js.map +1 -1
  89. package/dist/internal/runtime/loaders/component-loader.cjs +5 -2
  90. package/dist/internal/runtime/loaders/component-loader.cjs.map +1 -1
  91. package/dist/internal/runtime/loaders/component-loader.js +5 -2
  92. package/dist/internal/runtime/loaders/component-loader.js.map +1 -1
  93. package/dist/internal/runtime/turbopack/remote-scope.cjs +1 -5
  94. package/dist/internal/runtime/turbopack/remote-scope.cjs.map +1 -1
  95. package/dist/internal/runtime/turbopack/remote-scope.js +1 -5
  96. package/dist/internal/runtime/turbopack/remote-scope.js.map +1 -1
  97. package/dist/internal/utils.cjs +1 -1
  98. package/dist/internal/utils.cjs.map +1 -1
  99. package/dist/internal/utils.d.ts +5 -5
  100. package/dist/internal/utils.js +1 -1
  101. package/dist/internal/utils.js.map +1 -1
  102. package/dist/remote/html.cjs +15 -314
  103. package/dist/remote/html.cjs.map +1 -1
  104. package/dist/remote/html.js +7 -305
  105. package/dist/remote/html.js.map +1 -1
  106. package/dist/remote/middleware.cjs +16 -41
  107. package/dist/remote/middleware.cjs.map +1 -1
  108. package/dist/script-6W5JRBZK.cjs +26 -0
  109. package/dist/script-6W5JRBZK.cjs.map +1 -0
  110. package/dist/script-IFEBOLIA.js +26 -0
  111. package/dist/script-IFEBOLIA.js.map +1 -0
  112. package/dist/static-loader-X4TSF5KW.js +11 -0
  113. package/dist/static-loader-X4TSF5KW.js.map +1 -0
  114. package/dist/static-loader-ZYD5BO4D.cjs +11 -0
  115. package/dist/static-loader-ZYD5BO4D.cjs.map +1 -0
  116. package/dist/turbopack-NPGO3MWS.js +55 -0
  117. package/dist/turbopack-NPGO3MWS.js.map +1 -0
  118. package/dist/turbopack-WRMKPNN4.cjs +55 -0
  119. package/dist/turbopack-WRMKPNN4.cjs.map +1 -0
  120. package/dist/webpack-DUBHPYD6.js +92 -0
  121. package/dist/webpack-DUBHPYD6.js.map +1 -0
  122. package/dist/webpack-KSCMCL7M.cjs +92 -0
  123. package/dist/webpack-KSCMCL7M.cjs.map +1 -0
  124. package/package.json +9 -2
@@ -1,36 +1,7 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/host/proxy/client.ts
21
- var client_exports = {};
22
- __export(client_exports, {
23
- routeThroughHostProxy: () => routeThroughHostProxy
24
- });
25
- module.exports = __toCommonJS(client_exports);
26
-
27
- // src/utils/constants.ts
28
- var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
29
2
 
30
- // src/runtime/url/protected-rc-fallback.ts
31
- function generateProtectedRcFallbackSrc(url) {
32
- return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;
33
- }
3
+ var _chunkKE7QPAQ4cjs = require('../../chunk-KE7QPAQ4.cjs');
4
+ require('../../chunk-SHFJ5OQA.cjs');
34
5
 
35
6
  // src/host/proxy/client.ts
36
7
  var routeThroughHostProxy = (remoteSrc, url) => {
@@ -44,14 +15,13 @@ var routeThroughHostProxy = (remoteSrc, url) => {
44
15
  try {
45
16
  const parsed = new URL(url, location.href);
46
17
  if (parsed.origin === remoteOrigin) {
47
- return generateProtectedRcFallbackSrc(url);
18
+ return _chunkKE7QPAQ4cjs.generateProtectedRcFallbackSrc.call(void 0, url);
48
19
  }
49
- } catch {
20
+ } catch (e) {
50
21
  }
51
22
  return void 0;
52
23
  };
53
- // Annotate the CommonJS export names for ESM import in node:
54
- 0 && (module.exports = {
55
- routeThroughHostProxy
56
- });
24
+
25
+
26
+ exports.routeThroughHostProxy = routeThroughHostProxy;
57
27
  //# sourceMappingURL=client.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/host/proxy/client.ts","../../../src/utils/constants.ts","../../../src/runtime/url/protected-rc-fallback.ts"],"sourcesContent":["import { generateProtectedRcFallbackSrc } from '../../runtime/url/protected-rc-fallback';\n\n/**\n * Called before each asset fetch (scripts, styles, chunks, images) for a remote component.\n * Return a rewritten URL string to redirect the fetch, or undefined to use the original URL.\n *\n * @param remoteSrc - The `src` of the remote component\n * @param url - The asset URL about to be fetched\n */\nexport type ResolveClientUrl = (\n remoteSrc: string,\n url: string,\n) => string | undefined;\n\n/**\n * A `ResolveClientUrl` that routes cross-origin remote component asset requests\n * through the host's `/rc-fetch-protected-remote` endpoint. Same-origin URLs pass through unchanged.\n *\n * Use this on Vercel preview deployments where deployment protection would otherwise\n * block direct cross-origin fetches — routing through the host means requests carry\n * the host's auth cookies.\n *\n * Requires `withRemoteComponentsHostProxy` on the host side to handle the proxied requests.\n *\n * @example\n * ```tsx\n * import { routeThroughHostProxy } from 'remote-components/host/proxy/client';\n *\n * <ConsumeRemoteComponent\n * src=\"https://remote-app.com/components/header\"\n * resolveClientUrl={routeThroughHostProxy}\n * />\n * ```\n */\nexport const routeThroughHostProxy: ResolveClientUrl = (remoteSrc, url) => {\n if (typeof location === 'undefined') {\n return undefined;\n }\n const remoteOrigin = new URL(remoteSrc, location.href).origin;\n if (remoteOrigin === location.origin) {\n return undefined;\n }\n try {\n const parsed = new URL(url, location.href);\n if (parsed.origin === remoteOrigin) {\n return generateProtectedRcFallbackSrc(url);\n }\n } catch {\n // If URL parsing fails, return undefined to use the original\n }\n return undefined;\n};\n","export const RC_PROTECTED_REMOTE_FETCH_PATHNAME = '/rc-fetch-protected-remote';\n\nexport const MISSING_SHARED_MODULES_MESSAGE =\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponentsConfig` on both host and remote?';\n\nexport const CORS_DOCS_URL =\n 'https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components';\n","import { RC_PROTECTED_REMOTE_FETCH_PATHNAME } from '#internal/utils/constants';\n\n/**\n * Generates a fallback URL that proxies the request through the host's protected remote fetch endpoint\n */\nexport function generateProtectedRcFallbackSrc(url: string): string {\n return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;\n}\n\nexport function isProxiedUrl(url: string): boolean {\n try {\n return (\n new URL(url, location.href).pathname ===\n RC_PROTECTED_REMOTE_FETCH_PATHNAME\n );\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,qCAAqC;;;ACK3C,SAAS,+BAA+B,KAAqB;AAClE,SAAO,GAAG,0CAA0C,mBAAmB,GAAG;AAC5E;;;AF2BO,IAAM,wBAA0C,CAAC,WAAW,QAAQ;AACzE,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,QAAM,eAAe,IAAI,IAAI,WAAW,SAAS,IAAI,EAAE;AACvD,MAAI,iBAAiB,SAAS,QAAQ;AACpC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI;AACzC,QAAI,OAAO,WAAW,cAAc;AAClC,aAAO,+BAA+B,GAAG;AAAA,IAC3C;AAAA,EACF,QAAE;AAAA,EAEF;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/host/proxy/client.ts"],"names":[],"mappings":";;;;;;AAkCO,IAAM,wBAA0C,CAAC,WAAW,QAAQ;AACzE,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,QAAM,eAAe,IAAI,IAAI,WAAW,SAAS,IAAI,EAAE;AACvD,MAAI,iBAAiB,SAAS,QAAQ;AACpC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI;AACzC,QAAI,OAAO,WAAW,cAAc;AAClC,aAAO,+BAA+B,GAAG;AAAA,IAC3C;AAAA,EACF,QAAE;AAAA,EAEF;AACA,SAAO;AACT","sourcesContent":["import { generateProtectedRcFallbackSrc } from '../../runtime/url/protected-rc-fallback';\n\n/**\n * Called before each asset fetch (scripts, styles, chunks, images) for a remote component.\n * Return a rewritten URL string to redirect the fetch, or undefined to use the original URL.\n *\n * @param remoteSrc - The `src` of the remote component\n * @param url - The asset URL about to be fetched\n */\nexport type ResolveClientUrl = (\n remoteSrc: string,\n url: string,\n) => string | undefined;\n\n/**\n * A `ResolveClientUrl` that routes cross-origin remote component asset requests\n * through the host's `/rc-fetch-protected-remote` endpoint. Same-origin URLs pass through unchanged.\n *\n * Use this on Vercel preview deployments where deployment protection would otherwise\n * block direct cross-origin fetches — routing through the host means requests carry\n * the host's auth cookies.\n *\n * Requires `withRemoteComponentsHostProxy` on the host side to handle the proxied requests.\n *\n * @example\n * ```tsx\n * import { routeThroughHostProxy } from 'remote-components/host/proxy/client';\n *\n * <ConsumeRemoteComponent\n * src=\"https://remote-app.com/components/header\"\n * resolveClientUrl={routeThroughHostProxy}\n * />\n * ```\n */\nexport const routeThroughHostProxy: ResolveClientUrl = (remoteSrc, url) => {\n if (typeof location === 'undefined') {\n return undefined;\n }\n const remoteOrigin = new URL(remoteSrc, location.href).origin;\n if (remoteOrigin === location.origin) {\n return undefined;\n }\n try {\n const parsed = new URL(url, location.href);\n if (parsed.origin === remoteOrigin) {\n return generateProtectedRcFallbackSrc(url);\n }\n } catch {\n // If URL parsing fails, return undefined to use the original\n }\n return undefined;\n};\n"]}
@@ -1,10 +1,7 @@
1
- // src/utils/constants.ts
2
- var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
3
-
4
- // src/runtime/url/protected-rc-fallback.ts
5
- function generateProtectedRcFallbackSrc(url) {
6
- return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;
7
- }
1
+ import {
2
+ generateProtectedRcFallbackSrc
3
+ } from "../../chunk-X6YKUJKH.js";
4
+ import "../../chunk-ENYGL5CO.js";
8
5
 
9
6
  // src/host/proxy/client.ts
10
7
  var routeThroughHostProxy = (remoteSrc, url) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/constants.ts","../../../src/runtime/url/protected-rc-fallback.ts","../../../src/host/proxy/client.ts"],"sourcesContent":["export const RC_PROTECTED_REMOTE_FETCH_PATHNAME = '/rc-fetch-protected-remote';\n\nexport const MISSING_SHARED_MODULES_MESSAGE =\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponentsConfig` on both host and remote?';\n\nexport const CORS_DOCS_URL =\n 'https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components';\n","import { RC_PROTECTED_REMOTE_FETCH_PATHNAME } from '#internal/utils/constants';\n\n/**\n * Generates a fallback URL that proxies the request through the host's protected remote fetch endpoint\n */\nexport function generateProtectedRcFallbackSrc(url: string): string {\n return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;\n}\n\nexport function isProxiedUrl(url: string): boolean {\n try {\n return (\n new URL(url, location.href).pathname ===\n RC_PROTECTED_REMOTE_FETCH_PATHNAME\n );\n } catch {\n return false;\n }\n}\n","import { generateProtectedRcFallbackSrc } from '../../runtime/url/protected-rc-fallback';\n\n/**\n * Called before each asset fetch (scripts, styles, chunks, images) for a remote component.\n * Return a rewritten URL string to redirect the fetch, or undefined to use the original URL.\n *\n * @param remoteSrc - The `src` of the remote component\n * @param url - The asset URL about to be fetched\n */\nexport type ResolveClientUrl = (\n remoteSrc: string,\n url: string,\n) => string | undefined;\n\n/**\n * A `ResolveClientUrl` that routes cross-origin remote component asset requests\n * through the host's `/rc-fetch-protected-remote` endpoint. Same-origin URLs pass through unchanged.\n *\n * Use this on Vercel preview deployments where deployment protection would otherwise\n * block direct cross-origin fetches — routing through the host means requests carry\n * the host's auth cookies.\n *\n * Requires `withRemoteComponentsHostProxy` on the host side to handle the proxied requests.\n *\n * @example\n * ```tsx\n * import { routeThroughHostProxy } from 'remote-components/host/proxy/client';\n *\n * <ConsumeRemoteComponent\n * src=\"https://remote-app.com/components/header\"\n * resolveClientUrl={routeThroughHostProxy}\n * />\n * ```\n */\nexport const routeThroughHostProxy: ResolveClientUrl = (remoteSrc, url) => {\n if (typeof location === 'undefined') {\n return undefined;\n }\n const remoteOrigin = new URL(remoteSrc, location.href).origin;\n if (remoteOrigin === location.origin) {\n return undefined;\n }\n try {\n const parsed = new URL(url, location.href);\n if (parsed.origin === remoteOrigin) {\n return generateProtectedRcFallbackSrc(url);\n }\n } catch {\n // If URL parsing fails, return undefined to use the original\n }\n return undefined;\n};\n"],"mappings":";AAAO,IAAM,qCAAqC;;;ACK3C,SAAS,+BAA+B,KAAqB;AAClE,SAAO,GAAG,0CAA0C,mBAAmB,GAAG;AAC5E;;;AC2BO,IAAM,wBAA0C,CAAC,WAAW,QAAQ;AACzE,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,QAAM,eAAe,IAAI,IAAI,WAAW,SAAS,IAAI,EAAE;AACvD,MAAI,iBAAiB,SAAS,QAAQ;AACpC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI;AACzC,QAAI,OAAO,WAAW,cAAc;AAClC,aAAO,+BAA+B,GAAG;AAAA,IAC3C;AAAA,EACF,QAAE;AAAA,EAEF;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/host/proxy/client.ts"],"sourcesContent":["import { generateProtectedRcFallbackSrc } from '../../runtime/url/protected-rc-fallback';\n\n/**\n * Called before each asset fetch (scripts, styles, chunks, images) for a remote component.\n * Return a rewritten URL string to redirect the fetch, or undefined to use the original URL.\n *\n * @param remoteSrc - The `src` of the remote component\n * @param url - The asset URL about to be fetched\n */\nexport type ResolveClientUrl = (\n remoteSrc: string,\n url: string,\n) => string | undefined;\n\n/**\n * A `ResolveClientUrl` that routes cross-origin remote component asset requests\n * through the host's `/rc-fetch-protected-remote` endpoint. Same-origin URLs pass through unchanged.\n *\n * Use this on Vercel preview deployments where deployment protection would otherwise\n * block direct cross-origin fetches — routing through the host means requests carry\n * the host's auth cookies.\n *\n * Requires `withRemoteComponentsHostProxy` on the host side to handle the proxied requests.\n *\n * @example\n * ```tsx\n * import { routeThroughHostProxy } from 'remote-components/host/proxy/client';\n *\n * <ConsumeRemoteComponent\n * src=\"https://remote-app.com/components/header\"\n * resolveClientUrl={routeThroughHostProxy}\n * />\n * ```\n */\nexport const routeThroughHostProxy: ResolveClientUrl = (remoteSrc, url) => {\n if (typeof location === 'undefined') {\n return undefined;\n }\n const remoteOrigin = new URL(remoteSrc, location.href).origin;\n if (remoteOrigin === location.origin) {\n return undefined;\n }\n try {\n const parsed = new URL(url, location.href);\n if (parsed.origin === remoteOrigin) {\n return generateProtectedRcFallbackSrc(url);\n }\n } catch {\n // If URL parsing fails, return undefined to use the original\n }\n return undefined;\n};\n"],"mappings":";;;;;;AAkCO,IAAM,wBAA0C,CAAC,WAAW,QAAQ;AACzE,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,QAAM,eAAe,IAAI,IAAI,WAAW,SAAS,IAAI,EAAE;AACvD,MAAI,iBAAiB,SAAS,QAAQ;AACpC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI;AACzC,QAAI,OAAO,WAAW,cAAc;AAClC,aAAO,+BAA+B,GAAG;AAAA,IAC3C;AAAA,EACF,QAAE;AAAA,EAEF;AACA,SAAO;AACT;","names":[]}
@@ -1,54 +1,18 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkTCFLEBQMcjs = require('../chunk-TCFLEBQM.cjs');
19
4
 
20
- // src/host/proxy/index.ts
21
- var proxy_exports = {};
22
- __export(proxy_exports, {
23
- withConsumeRemoteComponentsProxy: () => withConsumeRemoteComponentsProxy
24
- });
25
- module.exports = __toCommonJS(proxy_exports);
26
- var import_server = require("next/server");
27
5
 
28
- // src/host/server/fetch-headers.ts
29
- function remoteFetchHeaders() {
30
- return {
31
- /**
32
- * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
33
- * If the remote component uses vercel deployment protection, ensure the host and remote vercel
34
- * projects share a common automation bypass secret, and the shared secret is used as the
35
- * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
36
- */
37
- ...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
38
- "x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
39
- } : {},
40
- Accept: "text/html"
41
- };
42
- }
43
6
 
44
- // src/utils/constants.ts
45
- var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
46
- var CORS_DOCS_URL = "https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components";
7
+ var _chunkSHFJ5OQAcjs = require('../chunk-SHFJ5OQA.cjs');
8
+
9
+ // src/host/proxy/index.ts
10
+ var _server = require('next/server');
47
11
 
48
12
  // src/host/proxy/protected-fetch.ts
49
13
  async function handleProtectedRemoteFetchRequest(requestUrl, options) {
50
14
  const url = new URL(requestUrl, "https://fallback.com");
51
- if (url.pathname !== RC_PROTECTED_REMOTE_FETCH_PATHNAME) {
15
+ if (url.pathname !== _chunkSHFJ5OQAcjs.RC_PROTECTED_REMOTE_FETCH_PATHNAME) {
52
16
  return null;
53
17
  }
54
18
  const targetUrl = url.searchParams.get("url");
@@ -60,7 +24,7 @@ async function handleProtectedRemoteFetchRequest(requestUrl, options) {
60
24
  let parsedTargetUrl;
61
25
  try {
62
26
  parsedTargetUrl = new URL(targetUrl);
63
- } catch {
27
+ } catch (e) {
64
28
  return new Response("Bad request: invalid URL", { status: 400 });
65
29
  }
66
30
  if (parsedTargetUrl.protocol !== "https:" && parsedTargetUrl.protocol !== "http:") {
@@ -68,14 +32,14 @@ async function handleProtectedRemoteFetchRequest(requestUrl, options) {
68
32
  status: 400
69
33
  });
70
34
  }
71
- const envPatterns = process.env.REMOTE_COMPONENTS_ALLOWED_PROXY_URLS?.split(
35
+ const envPatterns = _optionalChain([process, 'access', _ => _.env, 'access', _2 => _2.REMOTE_COMPONENTS_ALLOWED_PROXY_URLS, 'optionalAccess', _3 => _3.split, 'call', _4 => _4(
72
36
  ","
73
- ).map((p) => p.trim());
74
- const optionPatterns = options?.allowedProxyUrls;
37
+ ), 'access', _5 => _5.map, 'call', _6 => _6((p) => p.trim())]);
38
+ const optionPatterns = _optionalChain([options, 'optionalAccess', _7 => _7.allowedProxyUrls]);
75
39
  const allowedPatterns = [...optionPatterns || [], ...envPatterns || []];
76
40
  if (allowedPatterns.length === 0) {
77
41
  return new Response(
78
- `Forbidden: no allowedProxyUrls or REMOTE_COMPONENTS_ALLOWED_PROXY_URLS configured. See: ${CORS_DOCS_URL}`,
42
+ `Forbidden: no allowedProxyUrls or REMOTE_COMPONENTS_ALLOWED_PROXY_URLS configured. See: ${_chunkSHFJ5OQAcjs.CORS_DOCS_URL}`,
79
43
  {
80
44
  status: 403
81
45
  }
@@ -98,13 +62,13 @@ async function handleProtectedRemoteFetchRequest(requestUrl, options) {
98
62
  });
99
63
  if (!isUrlAllowed) {
100
64
  return new Response(
101
- `Forbidden: origin "${parsedTargetUrl.origin}" does not match any allowedProxyUrls. Add a matching pattern to REMOTE_COMPONENTS_ALLOWED_PROXY_URLS or the allowedProxyUrls option. See: ${CORS_DOCS_URL}`,
65
+ `Forbidden: origin "${parsedTargetUrl.origin}" does not match any allowedProxyUrls. Add a matching pattern to REMOTE_COMPONENTS_ALLOWED_PROXY_URLS or the allowedProxyUrls option. See: ${_chunkSHFJ5OQAcjs.CORS_DOCS_URL}`,
102
66
  {
103
67
  status: 403
104
68
  }
105
69
  );
106
70
  }
107
- const response = await fetch(targetUrl, { headers: remoteFetchHeaders() });
71
+ const response = await fetch(targetUrl, { headers: _chunkTCFLEBQMcjs.remoteFetchHeaders.call(void 0, ) });
108
72
  const SAFE_HEADERS = [
109
73
  "content-type",
110
74
  "cache-control",
@@ -135,11 +99,10 @@ function withConsumeRemoteComponentsProxy(proxy, options) {
135
99
  if (protectedFetchResponse) {
136
100
  return protectedFetchResponse;
137
101
  }
138
- return typeof proxy === "function" ? await proxy(request) : import_server.NextResponse.next();
102
+ return typeof proxy === "function" ? await proxy(request) : _server.NextResponse.next();
139
103
  };
140
104
  }
141
- // Annotate the CommonJS export names for ESM import in node:
142
- 0 && (module.exports = {
143
- withConsumeRemoteComponentsProxy
144
- });
105
+
106
+
107
+ exports.withConsumeRemoteComponentsProxy = withConsumeRemoteComponentsProxy;
145
108
  //# sourceMappingURL=proxy.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/host/proxy/index.ts","../../src/host/server/fetch-headers.ts","../../src/utils/constants.ts","../../src/host/proxy/protected-fetch.ts"],"sourcesContent":["import { type NextRequest, NextResponse } from 'next/server';\nimport {\n type HostProxyOptions,\n handleProtectedRemoteFetchRequest,\n} from './protected-fetch';\n\n/**\n * Wraps a Next.js proxy handler to add remote component support:\n * handles cross-origin asset fetches via the `/rc-fetch-protected-remote` endpoint,\n * then falls through to your proxy handler (or `NextResponse.next()`) for all other requests.\n *\n * Add `/rc-fetch-protected-remote` to your proxy/middleware matchers to activate it.\n *\n * @param proxy - Optional Next.js proxy handler to run for non-remote-component requests\n * @param options - Configuration options for SSRF protection\n */\nexport function withConsumeRemoteComponentsProxy(\n proxy?: (request: NextRequest) => NextResponse | Promise<NextResponse>,\n options?: HostProxyOptions,\n) {\n return async (request: NextRequest) => {\n // Check if this is a protected remote fetch request\n const protectedFetchResponse = await handleProtectedRemoteFetchRequest(\n request.url,\n options,\n );\n\n if (protectedFetchResponse) {\n return protectedFetchResponse;\n }\n\n return typeof proxy === 'function'\n ? await proxy(request)\n : NextResponse.next();\n };\n}\n\nexport type { HostProxyOptions } from './protected-fetch';\n","/**\n * The headers to use when fetching the remote component.\n */\nexport function remoteFetchHeaders() {\n return {\n /**\n * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.\n * If the remote component uses vercel deployment protection, ensure the host and remote vercel\n * projects share a common automation bypass secret, and the shared secret is used as the\n * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.\n */\n ...(typeof process === 'object' &&\n typeof process.env === 'object' &&\n typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === 'string'\n ? {\n 'x-vercel-protection-bypass':\n process.env.VERCEL_AUTOMATION_BYPASS_SECRET,\n }\n : {}),\n Accept: 'text/html',\n };\n}\n","export const RC_PROTECTED_REMOTE_FETCH_PATHNAME = '/rc-fetch-protected-remote';\n\nexport const MISSING_SHARED_MODULES_MESSAGE =\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponentsConfig` on both host and remote?';\n\nexport const CORS_DOCS_URL =\n 'https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components';\n","/**\n * Proxy utilities for host applications that consume remote components.\n *\n * Hosts do NOT handle CORS - that's the remote's responsibility.\n * Hosts only handle protected fetch proxying.\n */\n\nimport { remoteFetchHeaders } from '#internal/host/server/fetch-headers';\nimport {\n CORS_DOCS_URL,\n RC_PROTECTED_REMOTE_FETCH_PATHNAME,\n} from '#internal/utils/constants';\n\nexport interface HostProxyOptions {\n /**\n * List of allowed URL patterns (as regex strings) that can be proxied.\n * These patterns are combined with REMOTE_COMPONENTS_ALLOWED_PROXY_URLS env var if both are set.\n * If neither is set, all URLs are blocked.\n */\n allowedProxyUrls?: string[];\n}\n\n/**\n * Handles protected remote component fetch requests by proxying them with\n * authentication headers. This is needed for accessing Vercel-protected remote\n * component deployments from client-side code.\n *\n * @param requestUrl - The full request URL\n * @param options - Host proxy configuration options\n * @returns Response object if this is a protected fetch request, or null if not\n */\nexport async function handleProtectedRemoteFetchRequest(\n requestUrl: string,\n options?: HostProxyOptions,\n): Promise<Response | null> {\n const url = new URL(requestUrl, 'https://fallback.com');\n\n if (url.pathname !== RC_PROTECTED_REMOTE_FETCH_PATHNAME) {\n return null;\n }\n\n const targetUrl = url.searchParams.get('url');\n if (!targetUrl) {\n return new Response('Bad request, missing url query param', {\n status: 400,\n });\n }\n\n // Only allow http/https URLs to prevent SSRF via file://, data:, etc.\n let parsedTargetUrl: URL;\n try {\n parsedTargetUrl = new URL(targetUrl);\n } catch {\n return new Response('Bad request: invalid URL', { status: 400 });\n }\n\n if (\n parsedTargetUrl.protocol !== 'https:' &&\n parsedTargetUrl.protocol !== 'http:'\n ) {\n return new Response('Bad request: only http/https URLs are supported', {\n status: 400,\n });\n }\n\n const envPatterns = process.env.REMOTE_COMPONENTS_ALLOWED_PROXY_URLS?.split(\n ',',\n ).map((p) => p.trim());\n const optionPatterns = options?.allowedProxyUrls;\n\n // Combine both sources if both are specified\n const allowedPatterns = [...(optionPatterns || []), ...(envPatterns || [])];\n\n if (allowedPatterns.length === 0) {\n return new Response(\n `Forbidden: no allowedProxyUrls or REMOTE_COMPONENTS_ALLOWED_PROXY_URLS configured. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Validate the target URL against allowed patterns to prevent SSRF.\n // matchTarget is origin + pathname (no query string or fragment).\n const matchTarget = parsedTargetUrl.origin + parsedTargetUrl.pathname;\n const isUrlAllowed = allowedPatterns.some((pattern) => {\n try {\n const anchored = pattern.startsWith('^') ? pattern : `^${pattern}`;\n const bounded = anchored.endsWith('$') ? anchored : `${anchored}(/|$)`;\n const regex = new RegExp(bounded);\n return regex.test(matchTarget);\n } catch (error) {\n console.error(\n `Invalid regex pattern in allowedProxyUrls: ${pattern}`,\n error,\n );\n return false;\n }\n });\n\n if (!isUrlAllowed) {\n return new Response(\n `Forbidden: origin \"${parsedTargetUrl.origin}\" does not match any allowedProxyUrls. ` +\n `Add a matching pattern to REMOTE_COMPONENTS_ALLOWED_PROXY_URLS or the allowedProxyUrls option. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Fetch the remote resource\n const response = await fetch(targetUrl, { headers: remoteFetchHeaders() });\n\n // Only forward safe headers — no set-cookie, CORS, or encoding headers.\n // content-length is excluded because fetch() auto-decompresses the upstream\n // response, making the original content-length incorrect for the decoded body.\n const SAFE_HEADERS = [\n 'content-type',\n 'cache-control',\n 'etag',\n 'last-modified',\n ] as const;\n const headers = new Headers();\n for (const name of SAFE_HEADERS) {\n const value = response.headers.get(name);\n if (value) {\n headers.set(name, value);\n }\n }\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/host/proxy/index.ts","../../src/host/proxy/protected-fetch.ts"],"names":[],"mappings":";;;;;;;;;AAAA,SAA2B,oBAAoB;;;AC+B/C,eAAsB,kCACpB,YACA,SAC0B;AAC1B,QAAM,MAAM,IAAI,IAAI,YAAY,sBAAsB;AAEtD,MAAI,IAAI,aAAa,oCAAoC;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,aAAa,IAAI,KAAK;AAC5C,MAAI,CAAC,WAAW;AACd,WAAO,IAAI,SAAS,wCAAwC;AAAA,MAC1D,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,MAAI;AACJ,MAAI;AACF,sBAAkB,IAAI,IAAI,SAAS;AAAA,EACrC,QAAE;AACA,WAAO,IAAI,SAAS,4BAA4B,EAAE,QAAQ,IAAI,CAAC;AAAA,EACjE;AAEA,MACE,gBAAgB,aAAa,YAC7B,gBAAgB,aAAa,SAC7B;AACA,WAAO,IAAI,SAAS,mDAAmD;AAAA,MACrE,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,QAAQ,IAAI,sCAAsC;AAAA,IACpE;AAAA,EACF,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACrB,QAAM,iBAAiB,SAAS;AAGhC,QAAM,kBAAkB,CAAC,GAAI,kBAAkB,CAAC,GAAI,GAAI,eAAe,CAAC,CAAE;AAE1E,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO,IAAI;AAAA,MACT,2FACU;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAIA,QAAM,cAAc,gBAAgB,SAAS,gBAAgB;AAC7D,QAAM,eAAe,gBAAgB,KAAK,CAAC,YAAY;AACrD,QAAI;AACF,YAAM,WAAW,QAAQ,WAAW,GAAG,IAAI,UAAU,IAAI;AACzD,YAAM,UAAU,SAAS,SAAS,GAAG,IAAI,WAAW,GAAG;AACvD,YAAM,QAAQ,IAAI,OAAO,OAAO;AAChC,aAAO,MAAM,KAAK,WAAW;AAAA,IAC/B,SAAS,OAAP;AACA,cAAQ;AAAA,QACN,8CAA8C;AAAA,QAC9C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,WAAO,IAAI;AAAA,MACT,sBAAsB,gBAAgB,oJAE5B;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,MAAM,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;AAKzE,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,IAAI,QAAQ;AAC5B,aAAW,QAAQ,cAAc;AAC/B,UAAM,QAAQ,SAAS,QAAQ,IAAI,IAAI;AACvC,QAAI,OAAO;AACT,cAAQ,IAAI,MAAM,KAAK;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;;;ADzHO,SAAS,iCACd,OACA,SACA;AACA,SAAO,OAAO,YAAyB;AAErC,UAAM,yBAAyB,MAAM;AAAA,MACnC,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,QAAI,wBAAwB;AAC1B,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,UAAU,aACpB,MAAM,MAAM,OAAO,IACnB,aAAa,KAAK;AAAA,EACxB;AACF","sourcesContent":["import { type NextRequest, NextResponse } from 'next/server';\nimport {\n type HostProxyOptions,\n handleProtectedRemoteFetchRequest,\n} from './protected-fetch';\n\n/**\n * Wraps a Next.js proxy handler to add remote component support:\n * handles cross-origin asset fetches via the `/rc-fetch-protected-remote` endpoint,\n * then falls through to your proxy handler (or `NextResponse.next()`) for all other requests.\n *\n * Add `/rc-fetch-protected-remote` to your proxy/middleware matchers to activate it.\n *\n * @param proxy - Optional Next.js proxy handler to run for non-remote-component requests\n * @param options - Configuration options for SSRF protection\n */\nexport function withConsumeRemoteComponentsProxy(\n proxy?: (request: NextRequest) => NextResponse | Promise<NextResponse>,\n options?: HostProxyOptions,\n) {\n return async (request: NextRequest) => {\n // Check if this is a protected remote fetch request\n const protectedFetchResponse = await handleProtectedRemoteFetchRequest(\n request.url,\n options,\n );\n\n if (protectedFetchResponse) {\n return protectedFetchResponse;\n }\n\n return typeof proxy === 'function'\n ? await proxy(request)\n : NextResponse.next();\n };\n}\n\nexport type { HostProxyOptions } from './protected-fetch';\n","/**\n * Proxy utilities for host applications that consume remote components.\n *\n * Hosts do NOT handle CORS - that's the remote's responsibility.\n * Hosts only handle protected fetch proxying.\n */\n\nimport { remoteFetchHeaders } from '#internal/host/server/fetch-headers';\nimport {\n CORS_DOCS_URL,\n RC_PROTECTED_REMOTE_FETCH_PATHNAME,\n} from '#internal/utils/constants';\n\nexport interface HostProxyOptions {\n /**\n * List of allowed URL patterns (as regex strings) that can be proxied.\n * These patterns are combined with REMOTE_COMPONENTS_ALLOWED_PROXY_URLS env var if both are set.\n * If neither is set, all URLs are blocked.\n */\n allowedProxyUrls?: string[];\n}\n\n/**\n * Handles protected remote component fetch requests by proxying them with\n * authentication headers. This is needed for accessing Vercel-protected remote\n * component deployments from client-side code.\n *\n * @param requestUrl - The full request URL\n * @param options - Host proxy configuration options\n * @returns Response object if this is a protected fetch request, or null if not\n */\nexport async function handleProtectedRemoteFetchRequest(\n requestUrl: string,\n options?: HostProxyOptions,\n): Promise<Response | null> {\n const url = new URL(requestUrl, 'https://fallback.com');\n\n if (url.pathname !== RC_PROTECTED_REMOTE_FETCH_PATHNAME) {\n return null;\n }\n\n const targetUrl = url.searchParams.get('url');\n if (!targetUrl) {\n return new Response('Bad request, missing url query param', {\n status: 400,\n });\n }\n\n // Only allow http/https URLs to prevent SSRF via file://, data:, etc.\n let parsedTargetUrl: URL;\n try {\n parsedTargetUrl = new URL(targetUrl);\n } catch {\n return new Response('Bad request: invalid URL', { status: 400 });\n }\n\n if (\n parsedTargetUrl.protocol !== 'https:' &&\n parsedTargetUrl.protocol !== 'http:'\n ) {\n return new Response('Bad request: only http/https URLs are supported', {\n status: 400,\n });\n }\n\n const envPatterns = process.env.REMOTE_COMPONENTS_ALLOWED_PROXY_URLS?.split(\n ',',\n ).map((p) => p.trim());\n const optionPatterns = options?.allowedProxyUrls;\n\n // Combine both sources if both are specified\n const allowedPatterns = [...(optionPatterns || []), ...(envPatterns || [])];\n\n if (allowedPatterns.length === 0) {\n return new Response(\n `Forbidden: no allowedProxyUrls or REMOTE_COMPONENTS_ALLOWED_PROXY_URLS configured. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Validate the target URL against allowed patterns to prevent SSRF.\n // matchTarget is origin + pathname (no query string or fragment).\n const matchTarget = parsedTargetUrl.origin + parsedTargetUrl.pathname;\n const isUrlAllowed = allowedPatterns.some((pattern) => {\n try {\n const anchored = pattern.startsWith('^') ? pattern : `^${pattern}`;\n const bounded = anchored.endsWith('$') ? anchored : `${anchored}(/|$)`;\n const regex = new RegExp(bounded);\n return regex.test(matchTarget);\n } catch (error) {\n console.error(\n `Invalid regex pattern in allowedProxyUrls: ${pattern}`,\n error,\n );\n return false;\n }\n });\n\n if (!isUrlAllowed) {\n return new Response(\n `Forbidden: origin \"${parsedTargetUrl.origin}\" does not match any allowedProxyUrls. ` +\n `Add a matching pattern to REMOTE_COMPONENTS_ALLOWED_PROXY_URLS or the allowedProxyUrls option. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Fetch the remote resource\n const response = await fetch(targetUrl, { headers: remoteFetchHeaders() });\n\n // Only forward safe headers — no set-cookie, CORS, or encoding headers.\n // content-length is excluded because fetch() auto-decompresses the upstream\n // response, making the original content-length incorrect for the decoded body.\n const SAFE_HEADERS = [\n 'content-type',\n 'cache-control',\n 'etag',\n 'last-modified',\n ] as const;\n const headers = new Headers();\n for (const name of SAFE_HEADERS) {\n const value = response.headers.get(name);\n if (value) {\n headers.set(name, value);\n }\n }\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n"]}
@@ -1,26 +1,14 @@
1
+ import {
2
+ remoteFetchHeaders
3
+ } from "../chunk-GAXJTFBV.js";
4
+ import {
5
+ CORS_DOCS_URL,
6
+ RC_PROTECTED_REMOTE_FETCH_PATHNAME
7
+ } from "../chunk-ENYGL5CO.js";
8
+
1
9
  // src/host/proxy/index.ts
2
10
  import { NextResponse } from "next/server";
3
11
 
4
- // src/host/server/fetch-headers.ts
5
- function remoteFetchHeaders() {
6
- return {
7
- /**
8
- * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
9
- * If the remote component uses vercel deployment protection, ensure the host and remote vercel
10
- * projects share a common automation bypass secret, and the shared secret is used as the
11
- * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
12
- */
13
- ...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
14
- "x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
15
- } : {},
16
- Accept: "text/html"
17
- };
18
- }
19
-
20
- // src/utils/constants.ts
21
- var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
22
- var CORS_DOCS_URL = "https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components";
23
-
24
12
  // src/host/proxy/protected-fetch.ts
25
13
  async function handleProtectedRemoteFetchRequest(requestUrl, options) {
26
14
  const url = new URL(requestUrl, "https://fallback.com");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/host/proxy/index.ts","../../src/host/server/fetch-headers.ts","../../src/utils/constants.ts","../../src/host/proxy/protected-fetch.ts"],"sourcesContent":["import { type NextRequest, NextResponse } from 'next/server';\nimport {\n type HostProxyOptions,\n handleProtectedRemoteFetchRequest,\n} from './protected-fetch';\n\n/**\n * Wraps a Next.js proxy handler to add remote component support:\n * handles cross-origin asset fetches via the `/rc-fetch-protected-remote` endpoint,\n * then falls through to your proxy handler (or `NextResponse.next()`) for all other requests.\n *\n * Add `/rc-fetch-protected-remote` to your proxy/middleware matchers to activate it.\n *\n * @param proxy - Optional Next.js proxy handler to run for non-remote-component requests\n * @param options - Configuration options for SSRF protection\n */\nexport function withConsumeRemoteComponentsProxy(\n proxy?: (request: NextRequest) => NextResponse | Promise<NextResponse>,\n options?: HostProxyOptions,\n) {\n return async (request: NextRequest) => {\n // Check if this is a protected remote fetch request\n const protectedFetchResponse = await handleProtectedRemoteFetchRequest(\n request.url,\n options,\n );\n\n if (protectedFetchResponse) {\n return protectedFetchResponse;\n }\n\n return typeof proxy === 'function'\n ? await proxy(request)\n : NextResponse.next();\n };\n}\n\nexport type { HostProxyOptions } from './protected-fetch';\n","/**\n * The headers to use when fetching the remote component.\n */\nexport function remoteFetchHeaders() {\n return {\n /**\n * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.\n * If the remote component uses vercel deployment protection, ensure the host and remote vercel\n * projects share a common automation bypass secret, and the shared secret is used as the\n * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.\n */\n ...(typeof process === 'object' &&\n typeof process.env === 'object' &&\n typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === 'string'\n ? {\n 'x-vercel-protection-bypass':\n process.env.VERCEL_AUTOMATION_BYPASS_SECRET,\n }\n : {}),\n Accept: 'text/html',\n };\n}\n","export const RC_PROTECTED_REMOTE_FETCH_PATHNAME = '/rc-fetch-protected-remote';\n\nexport const MISSING_SHARED_MODULES_MESSAGE =\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponentsConfig` on both host and remote?';\n\nexport const CORS_DOCS_URL =\n 'https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components';\n","/**\n * Proxy utilities for host applications that consume remote components.\n *\n * Hosts do NOT handle CORS - that's the remote's responsibility.\n * Hosts only handle protected fetch proxying.\n */\n\nimport { remoteFetchHeaders } from '#internal/host/server/fetch-headers';\nimport {\n CORS_DOCS_URL,\n RC_PROTECTED_REMOTE_FETCH_PATHNAME,\n} from '#internal/utils/constants';\n\nexport interface HostProxyOptions {\n /**\n * List of allowed URL patterns (as regex strings) that can be proxied.\n * These patterns are combined with REMOTE_COMPONENTS_ALLOWED_PROXY_URLS env var if both are set.\n * If neither is set, all URLs are blocked.\n */\n allowedProxyUrls?: string[];\n}\n\n/**\n * Handles protected remote component fetch requests by proxying them with\n * authentication headers. This is needed for accessing Vercel-protected remote\n * component deployments from client-side code.\n *\n * @param requestUrl - The full request URL\n * @param options - Host proxy configuration options\n * @returns Response object if this is a protected fetch request, or null if not\n */\nexport async function handleProtectedRemoteFetchRequest(\n requestUrl: string,\n options?: HostProxyOptions,\n): Promise<Response | null> {\n const url = new URL(requestUrl, 'https://fallback.com');\n\n if (url.pathname !== RC_PROTECTED_REMOTE_FETCH_PATHNAME) {\n return null;\n }\n\n const targetUrl = url.searchParams.get('url');\n if (!targetUrl) {\n return new Response('Bad request, missing url query param', {\n status: 400,\n });\n }\n\n // Only allow http/https URLs to prevent SSRF via file://, data:, etc.\n let parsedTargetUrl: URL;\n try {\n parsedTargetUrl = new URL(targetUrl);\n } catch {\n return new Response('Bad request: invalid URL', { status: 400 });\n }\n\n if (\n parsedTargetUrl.protocol !== 'https:' &&\n parsedTargetUrl.protocol !== 'http:'\n ) {\n return new Response('Bad request: only http/https URLs are supported', {\n status: 400,\n });\n }\n\n const envPatterns = process.env.REMOTE_COMPONENTS_ALLOWED_PROXY_URLS?.split(\n ',',\n ).map((p) => p.trim());\n const optionPatterns = options?.allowedProxyUrls;\n\n // Combine both sources if both are specified\n const allowedPatterns = [...(optionPatterns || []), ...(envPatterns || [])];\n\n if (allowedPatterns.length === 0) {\n return new Response(\n `Forbidden: no allowedProxyUrls or REMOTE_COMPONENTS_ALLOWED_PROXY_URLS configured. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Validate the target URL against allowed patterns to prevent SSRF.\n // matchTarget is origin + pathname (no query string or fragment).\n const matchTarget = parsedTargetUrl.origin + parsedTargetUrl.pathname;\n const isUrlAllowed = allowedPatterns.some((pattern) => {\n try {\n const anchored = pattern.startsWith('^') ? pattern : `^${pattern}`;\n const bounded = anchored.endsWith('$') ? anchored : `${anchored}(/|$)`;\n const regex = new RegExp(bounded);\n return regex.test(matchTarget);\n } catch (error) {\n console.error(\n `Invalid regex pattern in allowedProxyUrls: ${pattern}`,\n error,\n );\n return false;\n }\n });\n\n if (!isUrlAllowed) {\n return new Response(\n `Forbidden: origin \"${parsedTargetUrl.origin}\" does not match any allowedProxyUrls. ` +\n `Add a matching pattern to REMOTE_COMPONENTS_ALLOWED_PROXY_URLS or the allowedProxyUrls option. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Fetch the remote resource\n const response = await fetch(targetUrl, { headers: remoteFetchHeaders() });\n\n // Only forward safe headers — no set-cookie, CORS, or encoding headers.\n // content-length is excluded because fetch() auto-decompresses the upstream\n // response, making the original content-length incorrect for the decoded body.\n const SAFE_HEADERS = [\n 'content-type',\n 'cache-control',\n 'etag',\n 'last-modified',\n ] as const;\n const headers = new Headers();\n for (const name of SAFE_HEADERS) {\n const value = response.headers.get(name);\n if (value) {\n headers.set(name, value);\n }\n }\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n"],"mappings":";AAAA,SAA2B,oBAAoB;;;ACGxC,SAAS,qBAAqB;AACnC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL,GAAI,OAAO,YAAY,YACvB,OAAO,QAAQ,QAAQ,YACvB,OAAO,QAAQ,IAAI,oCAAoC,WACnD;AAAA,MACE,8BACE,QAAQ,IAAI;AAAA,IAChB,IACA,CAAC;AAAA,IACL,QAAQ;AAAA,EACV;AACF;;;ACrBO,IAAM,qCAAqC;AAK3C,IAAM,gBACX;;;ACyBF,eAAsB,kCACpB,YACA,SAC0B;AAC1B,QAAM,MAAM,IAAI,IAAI,YAAY,sBAAsB;AAEtD,MAAI,IAAI,aAAa,oCAAoC;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,aAAa,IAAI,KAAK;AAC5C,MAAI,CAAC,WAAW;AACd,WAAO,IAAI,SAAS,wCAAwC;AAAA,MAC1D,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,MAAI;AACJ,MAAI;AACF,sBAAkB,IAAI,IAAI,SAAS;AAAA,EACrC,QAAE;AACA,WAAO,IAAI,SAAS,4BAA4B,EAAE,QAAQ,IAAI,CAAC;AAAA,EACjE;AAEA,MACE,gBAAgB,aAAa,YAC7B,gBAAgB,aAAa,SAC7B;AACA,WAAO,IAAI,SAAS,mDAAmD;AAAA,MACrE,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,QAAQ,IAAI,sCAAsC;AAAA,IACpE;AAAA,EACF,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACrB,QAAM,iBAAiB,SAAS;AAGhC,QAAM,kBAAkB,CAAC,GAAI,kBAAkB,CAAC,GAAI,GAAI,eAAe,CAAC,CAAE;AAE1E,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO,IAAI;AAAA,MACT,2FACU;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAIA,QAAM,cAAc,gBAAgB,SAAS,gBAAgB;AAC7D,QAAM,eAAe,gBAAgB,KAAK,CAAC,YAAY;AACrD,QAAI;AACF,YAAM,WAAW,QAAQ,WAAW,GAAG,IAAI,UAAU,IAAI;AACzD,YAAM,UAAU,SAAS,SAAS,GAAG,IAAI,WAAW,GAAG;AACvD,YAAM,QAAQ,IAAI,OAAO,OAAO;AAChC,aAAO,MAAM,KAAK,WAAW;AAAA,IAC/B,SAAS,OAAP;AACA,cAAQ;AAAA,QACN,8CAA8C;AAAA,QAC9C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,WAAO,IAAI;AAAA,MACT,sBAAsB,gBAAgB,oJAE5B;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,MAAM,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;AAKzE,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,IAAI,QAAQ;AAC5B,aAAW,QAAQ,cAAc;AAC/B,UAAM,QAAQ,SAAS,QAAQ,IAAI,IAAI;AACvC,QAAI,OAAO;AACT,cAAQ,IAAI,MAAM,KAAK;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;;;AHzHO,SAAS,iCACd,OACA,SACA;AACA,SAAO,OAAO,YAAyB;AAErC,UAAM,yBAAyB,MAAM;AAAA,MACnC,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,QAAI,wBAAwB;AAC1B,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,UAAU,aACpB,MAAM,MAAM,OAAO,IACnB,aAAa,KAAK;AAAA,EACxB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/host/proxy/index.ts","../../src/host/proxy/protected-fetch.ts"],"sourcesContent":["import { type NextRequest, NextResponse } from 'next/server';\nimport {\n type HostProxyOptions,\n handleProtectedRemoteFetchRequest,\n} from './protected-fetch';\n\n/**\n * Wraps a Next.js proxy handler to add remote component support:\n * handles cross-origin asset fetches via the `/rc-fetch-protected-remote` endpoint,\n * then falls through to your proxy handler (or `NextResponse.next()`) for all other requests.\n *\n * Add `/rc-fetch-protected-remote` to your proxy/middleware matchers to activate it.\n *\n * @param proxy - Optional Next.js proxy handler to run for non-remote-component requests\n * @param options - Configuration options for SSRF protection\n */\nexport function withConsumeRemoteComponentsProxy(\n proxy?: (request: NextRequest) => NextResponse | Promise<NextResponse>,\n options?: HostProxyOptions,\n) {\n return async (request: NextRequest) => {\n // Check if this is a protected remote fetch request\n const protectedFetchResponse = await handleProtectedRemoteFetchRequest(\n request.url,\n options,\n );\n\n if (protectedFetchResponse) {\n return protectedFetchResponse;\n }\n\n return typeof proxy === 'function'\n ? await proxy(request)\n : NextResponse.next();\n };\n}\n\nexport type { HostProxyOptions } from './protected-fetch';\n","/**\n * Proxy utilities for host applications that consume remote components.\n *\n * Hosts do NOT handle CORS - that's the remote's responsibility.\n * Hosts only handle protected fetch proxying.\n */\n\nimport { remoteFetchHeaders } from '#internal/host/server/fetch-headers';\nimport {\n CORS_DOCS_URL,\n RC_PROTECTED_REMOTE_FETCH_PATHNAME,\n} from '#internal/utils/constants';\n\nexport interface HostProxyOptions {\n /**\n * List of allowed URL patterns (as regex strings) that can be proxied.\n * These patterns are combined with REMOTE_COMPONENTS_ALLOWED_PROXY_URLS env var if both are set.\n * If neither is set, all URLs are blocked.\n */\n allowedProxyUrls?: string[];\n}\n\n/**\n * Handles protected remote component fetch requests by proxying them with\n * authentication headers. This is needed for accessing Vercel-protected remote\n * component deployments from client-side code.\n *\n * @param requestUrl - The full request URL\n * @param options - Host proxy configuration options\n * @returns Response object if this is a protected fetch request, or null if not\n */\nexport async function handleProtectedRemoteFetchRequest(\n requestUrl: string,\n options?: HostProxyOptions,\n): Promise<Response | null> {\n const url = new URL(requestUrl, 'https://fallback.com');\n\n if (url.pathname !== RC_PROTECTED_REMOTE_FETCH_PATHNAME) {\n return null;\n }\n\n const targetUrl = url.searchParams.get('url');\n if (!targetUrl) {\n return new Response('Bad request, missing url query param', {\n status: 400,\n });\n }\n\n // Only allow http/https URLs to prevent SSRF via file://, data:, etc.\n let parsedTargetUrl: URL;\n try {\n parsedTargetUrl = new URL(targetUrl);\n } catch {\n return new Response('Bad request: invalid URL', { status: 400 });\n }\n\n if (\n parsedTargetUrl.protocol !== 'https:' &&\n parsedTargetUrl.protocol !== 'http:'\n ) {\n return new Response('Bad request: only http/https URLs are supported', {\n status: 400,\n });\n }\n\n const envPatterns = process.env.REMOTE_COMPONENTS_ALLOWED_PROXY_URLS?.split(\n ',',\n ).map((p) => p.trim());\n const optionPatterns = options?.allowedProxyUrls;\n\n // Combine both sources if both are specified\n const allowedPatterns = [...(optionPatterns || []), ...(envPatterns || [])];\n\n if (allowedPatterns.length === 0) {\n return new Response(\n `Forbidden: no allowedProxyUrls or REMOTE_COMPONENTS_ALLOWED_PROXY_URLS configured. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Validate the target URL against allowed patterns to prevent SSRF.\n // matchTarget is origin + pathname (no query string or fragment).\n const matchTarget = parsedTargetUrl.origin + parsedTargetUrl.pathname;\n const isUrlAllowed = allowedPatterns.some((pattern) => {\n try {\n const anchored = pattern.startsWith('^') ? pattern : `^${pattern}`;\n const bounded = anchored.endsWith('$') ? anchored : `${anchored}(/|$)`;\n const regex = new RegExp(bounded);\n return regex.test(matchTarget);\n } catch (error) {\n console.error(\n `Invalid regex pattern in allowedProxyUrls: ${pattern}`,\n error,\n );\n return false;\n }\n });\n\n if (!isUrlAllowed) {\n return new Response(\n `Forbidden: origin \"${parsedTargetUrl.origin}\" does not match any allowedProxyUrls. ` +\n `Add a matching pattern to REMOTE_COMPONENTS_ALLOWED_PROXY_URLS or the allowedProxyUrls option. ` +\n `See: ${CORS_DOCS_URL}`,\n {\n status: 403,\n },\n );\n }\n\n // Fetch the remote resource\n const response = await fetch(targetUrl, { headers: remoteFetchHeaders() });\n\n // Only forward safe headers — no set-cookie, CORS, or encoding headers.\n // content-length is excluded because fetch() auto-decompresses the upstream\n // response, making the original content-length incorrect for the decoded body.\n const SAFE_HEADERS = [\n 'content-type',\n 'cache-control',\n 'etag',\n 'last-modified',\n ] as const;\n const headers = new Headers();\n for (const name of SAFE_HEADERS) {\n const value = response.headers.get(name);\n if (value) {\n headers.set(name, value);\n }\n }\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n"],"mappings":";;;;;;;;;AAAA,SAA2B,oBAAoB;;;AC+B/C,eAAsB,kCACpB,YACA,SAC0B;AAC1B,QAAM,MAAM,IAAI,IAAI,YAAY,sBAAsB;AAEtD,MAAI,IAAI,aAAa,oCAAoC;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,aAAa,IAAI,KAAK;AAC5C,MAAI,CAAC,WAAW;AACd,WAAO,IAAI,SAAS,wCAAwC;AAAA,MAC1D,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,MAAI;AACJ,MAAI;AACF,sBAAkB,IAAI,IAAI,SAAS;AAAA,EACrC,QAAE;AACA,WAAO,IAAI,SAAS,4BAA4B,EAAE,QAAQ,IAAI,CAAC;AAAA,EACjE;AAEA,MACE,gBAAgB,aAAa,YAC7B,gBAAgB,aAAa,SAC7B;AACA,WAAO,IAAI,SAAS,mDAAmD;AAAA,MACrE,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,QAAQ,IAAI,sCAAsC;AAAA,IACpE;AAAA,EACF,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACrB,QAAM,iBAAiB,SAAS;AAGhC,QAAM,kBAAkB,CAAC,GAAI,kBAAkB,CAAC,GAAI,GAAI,eAAe,CAAC,CAAE;AAE1E,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO,IAAI;AAAA,MACT,2FACU;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAIA,QAAM,cAAc,gBAAgB,SAAS,gBAAgB;AAC7D,QAAM,eAAe,gBAAgB,KAAK,CAAC,YAAY;AACrD,QAAI;AACF,YAAM,WAAW,QAAQ,WAAW,GAAG,IAAI,UAAU,IAAI;AACzD,YAAM,UAAU,SAAS,SAAS,GAAG,IAAI,WAAW,GAAG;AACvD,YAAM,QAAQ,IAAI,OAAO,OAAO;AAChC,aAAO,MAAM,KAAK,WAAW;AAAA,IAC/B,SAAS,OAAP;AACA,cAAQ;AAAA,QACN,8CAA8C;AAAA,QAC9C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,WAAO,IAAI;AAAA,MACT,sBAAsB,gBAAgB,oJAE5B;AAAA,MACV;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,MAAM,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;AAKzE,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,IAAI,QAAQ;AAC5B,aAAW,QAAQ,cAAc;AAC/B,UAAM,QAAQ,SAAS,QAAQ,IAAI,IAAI;AACvC,QAAI,OAAO;AACT,cAAQ,IAAI,MAAM,KAAK;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;;;ADzHO,SAAS,iCACd,OACA,SACA;AACA,SAAO,OAAO,YAAyB;AAErC,UAAM,yBAAyB,MAAM;AAAA,MACnC,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,QAAI,wBAAwB;AAC1B,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,UAAU,aACpB,MAAM,MAAM,OAAO,IACnB,aAAa,KAAK;AAAA,EACxB;AACF;","names":[]}