@cloudflare/vite-plugin 2.0.0-beta.v.0 → 2.0.0-beta.v.1

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.
package/dist/index.mjs CHANGED
@@ -88427,7 +88427,7 @@ __name(createWorkerUploadForm, "createWorkerUploadForm");
88427
88427
  //#endregion
88428
88428
  //#region ../remote-bindings/dist/index.mjs
88429
88429
  var import_undici = require_undici();
88430
- var version$1 = "0.0.48";
88430
+ var version$1 = "0.0.49";
88431
88431
  var NoDefaultValueProvided = class extends UserError {
88432
88432
  constructor() {
88433
88433
  super("This command cannot be run in a non-interactive context", { telemetryMessage: "remote bindings prompt default missing" });
@@ -88482,7 +88482,7 @@ let logger;
88482
88482
  function initLogger(value) {
88483
88483
  logger = value;
88484
88484
  }
88485
- var ProxyWorker_default = "// src/startDevWorker/utils.ts\nimport assert from \"node:assert\";\nvar PREVIEW_TOKEN_REFRESH_INTERVAL = 50 * 60 * 1e3;\nfunction createDeferred(previousDeferred) {\n let resolve, reject;\n const newPromise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n assert(resolve);\n assert(reject);\n previousDeferred?.resolve(newPromise);\n return {\n promise: newPromise,\n resolve,\n reject\n };\n}\nfunction urlFromParts(parts, base = \"http://localhost\") {\n const url = new URL(base);\n Object.assign(url, parts);\n return url;\n}\nfunction rewriteUrlInHeaderValue(value, from, to) {\n return value.replace(\n /(https?:\\/\\/[^/?#\\s,;\"']+)([^\\s,;\"']*)/gi,\n (match, origin, rest) => {\n let url;\n try {\n url = new URL(origin);\n } catch {\n return match;\n }\n if (url.host !== from.host) {\n return match;\n }\n return to.origin + rest;\n }\n );\n}\n\n// templates/startDevWorker/ProxyWorker.ts\nvar ProxyWorker_default = {\n fetch(req, env) {\n const singleton = env.DURABLE_OBJECT.idFromName(\"\");\n const inspectorProxy = env.DURABLE_OBJECT.get(singleton);\n return inspectorProxy.fetch(req);\n }\n};\nvar ProxyWorker = class {\n constructor(_state, env) {\n this.env = env;\n }\n env;\n proxyData;\n requestQueue = /* @__PURE__ */ new Map();\n requestRetryQueue = /* @__PURE__ */ new Map();\n fetch(request) {\n if (isRequestFromProxyController(request, this.env)) {\n return this.processProxyControllerRequest(request);\n }\n const deferred = createDeferred();\n this.requestQueue.set(request, deferred);\n this.processQueue();\n return deferred.promise;\n }\n processProxyControllerRequest(request) {\n const event = request.cf?.hostMetadata;\n switch (event?.type) {\n case \"pause\":\n this.proxyData = void 0;\n break;\n case \"play\":\n this.proxyData = event.proxyData;\n this.processQueue();\n break;\n }\n return new Response(null, { status: 204 });\n }\n /**\n * Process requests that are being retried first, then process newer requests.\n * Requests that are being retried are, by definition, older than requests which haven't been processed yet.\n * We don't need to be more accurate than this re ordering, since the requests are being fired off synchronously.\n */\n *getOrderedQueue() {\n yield* this.requestRetryQueue;\n yield* this.requestQueue;\n }\n processQueue() {\n const { proxyData } = this;\n if (proxyData === void 0) {\n return;\n }\n for (const [request, deferredResponse] of this.getOrderedQueue()) {\n this.requestRetryQueue.delete(request);\n this.requestQueue.delete(request);\n const outerUrl = new URL(request.url);\n const headers = new Headers(request.headers);\n const userWorkerUrl = new URL(request.url);\n Object.assign(userWorkerUrl, proxyData.userWorkerUrl);\n const innerUrl = urlFromParts(\n proxyData.userWorkerInnerUrlOverrides ?? {},\n request.url\n );\n const encoding = request.cf?.clientAcceptEncoding;\n if (encoding !== void 0) {\n headers.set(\"Accept-Encoding\", encoding);\n }\n rewriteUrlRelatedHeaders(headers, outerUrl, innerUrl);\n headers.set(\"MF-Original-URL\", innerUrl.href);\n for (const [key, value] of Object.entries(proxyData.headers ?? {})) {\n if (value === void 0) {\n continue;\n }\n if (key.toLowerCase() === \"cookie\") {\n const existing = request.headers.get(\"cookie\") ?? \"\";\n headers.set(\"cookie\", `${existing};${value}`);\n } else {\n headers.set(key, value);\n }\n }\n void fetch(userWorkerUrl, new Request(request, { headers })).then(async (res) => {\n res = new Response(res.body, res);\n rewriteUrlRelatedHeaders(res.headers, innerUrl, outerUrl);\n await checkForPreviewTokenError(res, this.env, proxyData);\n deferredResponse.resolve(res);\n }).catch((error) => {\n const newUserWorkerUrl = this.proxyData && urlFromParts(this.proxyData.userWorkerUrl);\n if (userWorkerUrl.href === newUserWorkerUrl?.href) {\n void sendMessageToProxyController(this.env, {\n type: \"error\",\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n cause: error.cause\n }\n });\n deferredResponse.reject(error);\n } else if (request.method === \"GET\" || request.method === \"HEAD\") {\n this.requestRetryQueue.set(request, deferredResponse);\n } else {\n deferredResponse.resolve(\n new Response(\n \"Your worker restarted mid-request. Please try sending the request again. Only GET or HEAD requests are retried automatically.\",\n {\n status: 503,\n headers: { \"Retry-After\": \"0\" }\n }\n )\n );\n }\n });\n }\n }\n};\nfunction isRequestFromProxyController(req, env) {\n return req.headers.get(\"Authorization\") === env.PROXY_CONTROLLER_AUTH_SECRET;\n}\nfunction sendMessageToProxyController(env, message) {\n return env.PROXY_CONTROLLER.fetch(\"http://dummy\", {\n method: \"POST\",\n body: JSON.stringify(message)\n });\n}\nasync function checkForPreviewTokenError(response, env, proxyData) {\n if (response.status !== 400) {\n return;\n }\n const clone = response.clone();\n const text = await clone.text();\n if (text.includes(\"Invalid Workers Preview configuration\") || text.includes(\"error code: 1031\")) {\n void sendMessageToProxyController(env, {\n type: \"previewTokenExpired\",\n proxyData\n });\n }\n}\nfunction rewriteUrlRelatedHeaders(headers, from, to) {\n const setCookie = headers.getAll(\"Set-Cookie\");\n headers.delete(\"Set-Cookie\");\n headers.forEach((value, key) => {\n if (typeof value === \"string\" && value.includes(from.host)) {\n headers.set(key, rewriteUrlInHeaderValue(value, from, to));\n }\n });\n for (const cookie of setCookie) {\n headers.append(\n \"Set-Cookie\",\n cookie.replace(\n new RegExp(`Domain=${from.hostname}($|;|,)`),\n `Domain=${to.hostname}$1`\n )\n );\n }\n}\nexport {\n ProxyWorker,\n ProxyWorker_default as default\n};\n";
88485
+ var ProxyWorker_default = "// src/startDevWorker/utils.ts\nimport assert from \"node:assert\";\nvar PREVIEW_TOKEN_REFRESH_INTERVAL = 50 * 60 * 1e3;\nvar PREVIEW_TOKEN_REFRESH_RETRY_INTERVAL = 60 * 1e3;\nfunction createDeferred(previousDeferred) {\n let resolve, reject;\n const newPromise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n assert(resolve);\n assert(reject);\n previousDeferred?.resolve(newPromise);\n return {\n promise: newPromise,\n resolve,\n reject\n };\n}\nfunction urlFromParts(parts, base = \"http://localhost\") {\n const url = new URL(base);\n Object.assign(url, parts);\n return url;\n}\nfunction rewriteUrlInHeaderValue(value, from, to) {\n return value.replace(\n /(https?:\\/\\/[^/?#\\s,;\"']+)([^\\s,;\"']*)/gi,\n (match, origin, rest) => {\n let url;\n try {\n url = new URL(origin);\n } catch {\n return match;\n }\n if (url.host !== from.host) {\n return match;\n }\n return to.origin + rest;\n }\n );\n}\n\n// templates/startDevWorker/ProxyWorker.ts\nvar ProxyWorker_default = {\n fetch(req, env) {\n const singleton = env.DURABLE_OBJECT.idFromName(\"\");\n const inspectorProxy = env.DURABLE_OBJECT.get(singleton);\n return inspectorProxy.fetch(req);\n }\n};\nvar ProxyWorker = class {\n constructor(_state, env) {\n this.env = env;\n }\n env;\n proxyData;\n requestQueue = /* @__PURE__ */ new Map();\n requestRetryQueue = /* @__PURE__ */ new Map();\n fetch(request) {\n if (isRequestFromProxyController(request, this.env)) {\n return this.processProxyControllerRequest(request);\n }\n const deferred = createDeferred();\n this.requestQueue.set(request, deferred);\n this.processQueue();\n return deferred.promise;\n }\n processProxyControllerRequest(request) {\n const event = request.cf?.hostMetadata;\n switch (event?.type) {\n case \"pause\":\n this.proxyData = void 0;\n break;\n case \"play\":\n this.proxyData = event.proxyData;\n this.processQueue();\n break;\n }\n return new Response(null, { status: 204 });\n }\n /**\n * Process requests that are being retried first, then process newer requests.\n * Requests that are being retried are, by definition, older than requests which haven't been processed yet.\n * We don't need to be more accurate than this re ordering, since the requests are being fired off synchronously.\n */\n *getOrderedQueue() {\n yield* this.requestRetryQueue;\n yield* this.requestQueue;\n }\n processQueue() {\n const { proxyData } = this;\n if (proxyData === void 0) {\n return;\n }\n for (const [request, deferredResponse] of this.getOrderedQueue()) {\n this.requestRetryQueue.delete(request);\n this.requestQueue.delete(request);\n const outerUrl = new URL(request.url);\n const headers = new Headers(request.headers);\n const userWorkerUrl = new URL(request.url);\n Object.assign(userWorkerUrl, proxyData.userWorkerUrl);\n const innerUrl = urlFromParts(\n proxyData.userWorkerInnerUrlOverrides ?? {},\n request.url\n );\n const encoding = request.cf?.clientAcceptEncoding;\n if (encoding !== void 0) {\n headers.set(\"Accept-Encoding\", encoding);\n }\n rewriteUrlRelatedHeaders(headers, outerUrl, innerUrl);\n headers.set(\"MF-Original-URL\", innerUrl.href);\n for (const [key, value] of Object.entries(proxyData.headers ?? {})) {\n if (value === void 0) {\n continue;\n }\n if (key.toLowerCase() === \"cookie\") {\n const existing = request.headers.get(\"cookie\") ?? \"\";\n headers.set(\"cookie\", `${existing};${value}`);\n } else {\n headers.set(key, value);\n }\n }\n void fetch(userWorkerUrl, new Request(request, { headers })).then(async (res) => {\n res = new Response(res.body, res);\n rewriteUrlRelatedHeaders(res.headers, innerUrl, outerUrl);\n await checkForPreviewTokenError(res, this.env, proxyData);\n deferredResponse.resolve(res);\n }).catch((error) => {\n const newUserWorkerUrl = this.proxyData && urlFromParts(this.proxyData.userWorkerUrl);\n if (userWorkerUrl.href === newUserWorkerUrl?.href) {\n void sendMessageToProxyController(this.env, {\n type: \"error\",\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n cause: error.cause\n }\n });\n deferredResponse.reject(error);\n } else if (request.method === \"GET\" || request.method === \"HEAD\") {\n this.requestRetryQueue.set(request, deferredResponse);\n } else {\n deferredResponse.resolve(\n new Response(\n \"Your worker restarted mid-request. Please try sending the request again. Only GET or HEAD requests are retried automatically.\",\n {\n status: 503,\n headers: { \"Retry-After\": \"0\" }\n }\n )\n );\n }\n });\n }\n }\n};\nfunction isRequestFromProxyController(req, env) {\n return req.headers.get(\"Authorization\") === env.PROXY_CONTROLLER_AUTH_SECRET;\n}\nfunction sendMessageToProxyController(env, message) {\n return env.PROXY_CONTROLLER.fetch(\"http://dummy\", {\n method: \"POST\",\n body: JSON.stringify(message)\n });\n}\nasync function checkForPreviewTokenError(response, env, proxyData) {\n if (response.status !== 400) {\n return;\n }\n const clone = response.clone();\n const text = await clone.text();\n if (text.includes(\"Invalid Workers Preview configuration\") || text.includes(\"error code: 1031\")) {\n void sendMessageToProxyController(env, {\n type: \"previewTokenExpired\",\n proxyData\n });\n }\n}\nfunction rewriteUrlRelatedHeaders(headers, from, to) {\n const setCookie = headers.getAll(\"Set-Cookie\");\n headers.delete(\"Set-Cookie\");\n headers.forEach((value, key) => {\n if (typeof value === \"string\" && value.includes(from.host)) {\n headers.set(key, rewriteUrlInHeaderValue(value, from, to));\n }\n });\n for (const cookie of setCookie) {\n headers.append(\n \"Set-Cookie\",\n cookie.replace(\n new RegExp(`Domain=${from.hostname}($|;|,)`),\n `Domain=${to.hostname}$1`\n )\n );\n }\n}\nexport {\n ProxyWorker,\n ProxyWorker_default as default\n};\n";
88486
88486
  function castLogLevel(level) {
88487
88487
  let key = level.toUpperCase();
88488
88488
  if (key === "LOG") key = "INFO";
@@ -88515,6 +88515,15 @@ function castErrorCause(cause) {
88515
88515
  * Preview tokens expire after 1 hour (hardcoded in the Workers control plane), so we retry after 50 mins.
88516
88516
  */
88517
88517
  const PREVIEW_TOKEN_REFRESH_INTERVAL = 3e3 * 1e3;
88518
+ /**
88519
+ * How soon to try again after a proactive preview token refresh fails (e.g.
88520
+ * the machine is offline). A failed refresh must not give up the retry cycle
88521
+ * for good — otherwise a network outage longer than the API's own few quick
88522
+ * retries (see `retryOnAPIFailure`) permanently strands the session even
88523
+ * after connectivity returns, since nothing else re-triggers a refresh
88524
+ * attempt for a long-lived session like `getPlatformProxy()`'s.
88525
+ */
88526
+ const PREVIEW_TOKEN_REFRESH_RETRY_INTERVAL = 60 * 1e3;
88518
88527
  function createDeferred(previousDeferred) {
88519
88528
  let resolve$3, reject;
88520
88529
  const newPromise = new Promise((_resolve$1, _reject) => {
@@ -88930,6 +88939,7 @@ var RemoteRuntimeController = class {
88930
88939
  #latestBundle;
88931
88940
  #latestProxyData;
88932
88941
  #refreshTimer;
88942
+ #sessionCreatedAt;
88933
88943
  #tearingDown = false;
88934
88944
  constructor(onError$1, onReloadComplete) {
88935
88945
  this.onError = onError$1;
@@ -88937,7 +88947,9 @@ var RemoteRuntimeController = class {
88937
88947
  }
88938
88948
  async #previewSession(props) {
88939
88949
  try {
88940
- return await retryOnAPIFailure(() => createPreviewSession(props.complianceConfig, props, this.#abortController.signal, props.name, props.cliDisplayName), logger, void 0, void 0, this.#abortController.signal);
88950
+ const session = await retryOnAPIFailure(() => createPreviewSession(props.complianceConfig, props, this.#abortController.signal, props.name, props.cliDisplayName), logger, void 0, void 0, this.#abortController.signal);
88951
+ if (session) this.#sessionCreatedAt = Date.now();
88952
+ return session;
88941
88953
  } catch (err) {
88942
88954
  if (err instanceof Error && err.name == "AbortError") return;
88943
88955
  handlePreviewSessionCreationError(err, props.accountId);
@@ -89042,9 +89054,13 @@ var RemoteRuntimeController = class {
89042
89054
  }
89043
89055
  #scheduleRefresh(interval) {
89044
89056
  clearTimeout(this.#refreshTimer);
89057
+ const delay = interval === PREVIEW_TOKEN_REFRESH_INTERVAL && this.#sessionCreatedAt !== void 0 ? Math.max(0, PREVIEW_TOKEN_REFRESH_INTERVAL - (Date.now() - this.#sessionCreatedAt)) : interval;
89045
89058
  this.#refreshTimer = setTimeout(() => {
89059
+ this.#refreshTimer = void 0;
89046
89060
  if (this.#latestProxyData) this.onPreviewTokenExpired();
89047
- }, interval);
89061
+ else if (!this.#tearingDown) this.#scheduleRefresh(PREVIEW_TOKEN_REFRESH_RETRY_INTERVAL);
89062
+ }, delay);
89063
+ this.#refreshTimer.unref?.();
89048
89064
  }
89049
89065
  async #onBundleComplete({ config: config$3, bundle }, id) {
89050
89066
  if (id !== this.#currentBundleId) return;
@@ -89072,10 +89088,14 @@ var RemoteRuntimeController = class {
89072
89088
  logger.warn("Cannot refresh preview token: missing config or bundle data");
89073
89089
  return;
89074
89090
  }
89091
+ const bundleId = this.#currentBundleId;
89092
+ const abortSignal = this.#abortController.signal;
89093
+ const shouldRetry = () => bundleId === this.#currentBundleId && !abortSignal.aborted && !this.#tearingDown;
89075
89094
  try {
89076
89095
  const auth = await unwrapHook(this.#latestConfig.auth);
89077
89096
  this.#session = await this.#getPreviewSession(this.#latestConfig, auth);
89078
- if (await this.#updatePreviewToken(this.#latestConfig, this.#latestBundle, auth, this.#currentBundleId)) logger.log(source_default.green("✔ Preview token refreshed successfully"));
89097
+ if (await this.#updatePreviewToken(this.#latestConfig, this.#latestBundle, auth, bundleId)) logger.log(source_default.green("✔ Preview token refreshed successfully"));
89098
+ else if (shouldRetry()) this.#scheduleRefresh(PREVIEW_TOKEN_REFRESH_RETRY_INTERVAL);
89079
89099
  } catch (error$3) {
89080
89100
  if (error$3 instanceof Error && error$3.name == "AbortError") return;
89081
89101
  this.emitErrorEvent({
@@ -89085,12 +89105,13 @@ var RemoteRuntimeController = class {
89085
89105
  source: "RemoteRuntimeController",
89086
89106
  data: void 0
89087
89107
  });
89108
+ if (shouldRetry()) this.#scheduleRefresh(PREVIEW_TOKEN_REFRESH_RETRY_INTERVAL);
89088
89109
  }
89089
89110
  }
89090
89111
  onUpdateStart() {
89091
89112
  this.#abortController.abort();
89092
89113
  this.#abortController = new AbortController();
89093
- clearTimeout(this.#refreshTimer);
89114
+ if (!this.#refreshTimer && this.#latestProxyData && !this.#tearingDown) this.#scheduleRefresh(PREVIEW_TOKEN_REFRESH_RETRY_INTERVAL);
89094
89115
  }
89095
89116
  onBundleComplete(ev) {
89096
89117
  const id = ++this.#currentBundleId;
@@ -89695,7 +89716,7 @@ function createRemoteBindingsLogger(logger$2) {
89695
89716
  }
89696
89717
  function getWorkerZone(config$3) {
89697
89718
  const domain$1 = config$3.domains?.[0];
89698
- if (domain$1 !== void 0) return getZoneFromRoute(domain$1);
89719
+ if (domain$1 !== void 0) return getZoneFromRoute(typeof domain$1 === "string" ? domain$1 : domain$1.hostname);
89699
89720
  const fetchTrigger = config$3.triggers?.find((trigger) => trigger.type === "fetch");
89700
89721
  if (fetchTrigger?.type !== "fetch") return;
89701
89722
  return getZoneFromRoute(fetchTrigger.zone?.includes(".") ? {
@@ -1,7 +1,7 @@
1
1
  //#region package.json
2
2
  var package_default = {
3
3
  name: "@cloudflare/vite-plugin",
4
- version: "2.0.0-beta.v.0",
4
+ version: "2.0.0-beta.v.1",
5
5
  description: "Cloudflare plugin for Vite",
6
6
  keywords: [
7
7
  "cloudflare",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/vite-plugin",
3
- "version": "2.0.0-beta.v.0",
3
+ "version": "2.0.0-beta.v.1",
4
4
  "description": "Cloudflare plugin for Vite",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -42,11 +42,11 @@
42
42
  "dependencies": {
43
43
  "unenv": "2.0.0-rc.24",
44
44
  "ws": "8.21.0",
45
- "@cloudflare/build-output-utils": "0.9.2",
46
- "@cloudflare/config": "0.26.0",
47
- "@cloudflare/runtime-types": "0.1.11",
45
+ "@cloudflare/config": "0.27.0",
46
+ "@cloudflare/runtime-types": "0.1.12",
47
+ "@cloudflare/build-output-utils": "0.9.3",
48
48
  "@cloudflare/unenv-preset": "2.16.2",
49
- "miniflare": "5.20261012.0-beta"
49
+ "miniflare": "5.20261012.1-beta"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@cloudflare/workers-types": "^5.20261006.1",
@@ -70,13 +70,13 @@
70
70
  "vite": "8.1.5",
71
71
  "vite-legacy": "npm:vite@7.1.12",
72
72
  "vitest": "4.1.0",
73
- "@cloudflare/cli-shared-helpers": "0.2.6",
74
- "@cloudflare/containers-shared": "0.22.0",
75
73
  "@cloudflare/mock-npm-registry": "0.0.0",
76
- "@cloudflare/remote-bindings": "0.0.48",
74
+ "@cloudflare/containers-shared": "0.22.1",
77
75
  "@cloudflare/workers-auth": "0.14.0",
78
76
  "@cloudflare/workers-shared": "0.20.1",
77
+ "@cloudflare/remote-bindings": "0.0.49",
79
78
  "@cloudflare/workers-tsconfig": "0.0.0",
79
+ "@cloudflare/cli-shared-helpers": "0.2.6",
80
80
  "@cloudflare/workers-utils": "0.47.2"
81
81
  },
82
82
  "peerDependencies": {