summaryrefslogtreecommitdiff
path: root/node_modules/wrangler/templates/middleware
diff options
context:
space:
mode:
authorakiyamn2023-09-24 23:22:21 +1000
committerakiyamn2023-09-24 23:22:21 +1000
commit4e87195739f2a5d9a05451b48773c8afdc680765 (patch)
tree9cba501844a4a11dcbdffc4050ed8189561c55ed /node_modules/wrangler/templates/middleware
downloadprice-tracker-worker-4e87195739f2a5d9a05451b48773c8afdc680765.tar.gz
price-tracker-worker-4e87195739f2a5d9a05451b48773c8afdc680765.zip
Initial commit (by create-cloudflare CLI)
Diffstat (limited to 'node_modules/wrangler/templates/middleware')
-rw-r--r--node_modules/wrangler/templates/middleware/common.ts67
-rw-r--r--node_modules/wrangler/templates/middleware/loader-modules.ts137
-rw-r--r--node_modules/wrangler/templates/middleware/loader-sw.ts228
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-d1-beta.d.ts3
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts33
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-multiworker-dev.d.ts4
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-multiworker-dev.ts59
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-pretty-error.ts40
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-scheduled.ts15
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-serve-static-assets.d.ts6
-rw-r--r--node_modules/wrangler/templates/middleware/middleware-serve-static-assets.ts56
11 files changed, 648 insertions, 0 deletions
diff --git a/node_modules/wrangler/templates/middleware/common.ts b/node_modules/wrangler/templates/middleware/common.ts
new file mode 100644
index 0000000..1319e5d
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/common.ts
@@ -0,0 +1,67 @@
+export type Awaitable<T> = T | Promise<T>;
+// TODO: allow dispatching more events?
+export type Dispatcher = (
+ type: "scheduled",
+ init: { cron?: string }
+) => Awaitable<void>;
+
+export type IncomingRequest = Request<
+ unknown,
+ IncomingRequestCfProperties<unknown>
+>;
+
+export interface MiddlewareContext {
+ dispatch: Dispatcher;
+ next(request: IncomingRequest, env: any): Awaitable<Response>;
+}
+
+export type Middleware = (
+ request: IncomingRequest,
+ env: any,
+ ctx: ExecutionContext,
+ middlewareCtx: MiddlewareContext
+) => Awaitable<Response>;
+
+const __facade_middleware__: Middleware[] = [];
+
+// The register functions allow for the insertion of one or many middleware,
+// We register internal middleware first in the stack, but have no way of controlling
+// the order that addMiddleware is run in service workers so need an internal function.
+export function __facade_register__(...args: (Middleware | Middleware[])[]) {
+ __facade_middleware__.push(...args.flat());
+}
+export function __facade_registerInternal__(
+ ...args: (Middleware | Middleware[])[]
+) {
+ __facade_middleware__.unshift(...args.flat());
+}
+
+function __facade_invokeChain__(
+ request: IncomingRequest,
+ env: any,
+ ctx: ExecutionContext,
+ dispatch: Dispatcher,
+ middlewareChain: Middleware[]
+): Awaitable<Response> {
+ const [head, ...tail] = middlewareChain;
+ const middlewareCtx: MiddlewareContext = {
+ dispatch,
+ next(newRequest, newEnv) {
+ return __facade_invokeChain__(newRequest, newEnv, ctx, dispatch, tail);
+ },
+ };
+ return head(request, env, ctx, middlewareCtx);
+}
+
+export function __facade_invoke__(
+ request: IncomingRequest,
+ env: any,
+ ctx: ExecutionContext,
+ dispatch: Dispatcher,
+ finalMiddleware: Middleware
+): Awaitable<Response> {
+ return __facade_invokeChain__(request, env, ctx, dispatch, [
+ ...__facade_middleware__,
+ finalMiddleware,
+ ]);
+}
diff --git a/node_modules/wrangler/templates/middleware/loader-modules.ts b/node_modules/wrangler/templates/middleware/loader-modules.ts
new file mode 100644
index 0000000..3da0c44
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/loader-modules.ts
@@ -0,0 +1,137 @@
+// // This loads all middlewares exposed on the middleware object
+// // and then starts the invocation chain.
+// // The big idea is that we can add these to the middleware export dynamically
+// // through wrangler, or we can potentially let users directly add them as a sort
+// // of "plugin" system.
+
+import {
+ Dispatcher,
+ Middleware,
+ __facade_invoke__,
+ __facade_register__,
+} from "./common";
+
+import worker from "__ENTRY_POINT__";
+
+// We need to preserve all of the exports from the worker
+export * from "__ENTRY_POINT__";
+
+class __Facade_ScheduledController__ implements ScheduledController {
+ #noRetry: ScheduledController["noRetry"];
+
+ constructor(
+ readonly scheduledTime: number,
+ readonly cron: string,
+ noRetry: ScheduledController["noRetry"]
+ ) {
+ this.#noRetry = noRetry;
+ }
+
+ noRetry() {
+ if (!(this instanceof __Facade_ScheduledController__)) {
+ throw new TypeError("Illegal invocation");
+ }
+ // Need to call native method immediately in case uncaught error thrown
+ this.#noRetry();
+ }
+}
+
+const __facade_modules_fetch__: ExportedHandlerFetchHandler = function (
+ request,
+ env,
+ ctx
+) {
+ if (worker.fetch === undefined)
+ throw new Error("Handler does not export a fetch() function.");
+ return worker.fetch(request, env, ctx);
+};
+
+function getMaskedEnv(rawEnv: unknown) {
+ let env = rawEnv as Record<string, unknown>;
+ if (worker.envWrappers && worker.envWrappers.length > 0) {
+ for (const wrapFn of worker.envWrappers) {
+ env = wrapFn(env);
+ }
+ }
+ return env;
+}
+
+/**
+ * This type is here to cause a type error if a new export handler is added to
+ * `ExportHandler` without it being included in the `facade` below.
+ */
+type MissingExportHandlers = Omit<
+ Required<ExportedHandler>,
+ "tail" | "trace" | "scheduled" | "queue" | "test" | "email" | "fetch"
+>;
+
+let registeredMiddleware = false;
+
+const facade: ExportedHandler<unknown> & MissingExportHandlers = {
+ ...(worker.tail && {
+ tail: maskHandlerEnv(worker.tail),
+ }),
+ ...(worker.trace && {
+ trace: maskHandlerEnv(worker.trace),
+ }),
+ ...(worker.scheduled && {
+ scheduled: maskHandlerEnv(worker.scheduled),
+ }),
+ ...(worker.queue && {
+ queue: maskHandlerEnv(worker.queue),
+ }),
+ ...(worker.test && {
+ test: maskHandlerEnv(worker.test),
+ }),
+ ...(worker.email && {
+ email: maskHandlerEnv(worker.email),
+ }),
+
+ fetch(request, rawEnv, ctx) {
+ const env = getMaskedEnv(rawEnv);
+ // Get the chain of middleware from the worker object
+ if (worker.middleware && worker.middleware.length > 0) {
+ // Make sure we only register middleware once:
+ // https://github.com/cloudflare/workers-sdk/issues/2386#issuecomment-1614715911
+ if (!registeredMiddleware) {
+ registeredMiddleware = true;
+ for (const middleware of worker.middleware) {
+ __facade_register__(middleware);
+ }
+ }
+
+ const __facade_modules_dispatch__: Dispatcher = function (type, init) {
+ if (type === "scheduled" && worker.scheduled !== undefined) {
+ const controller = new __Facade_ScheduledController__(
+ Date.now(),
+ init.cron ?? "",
+ () => {}
+ );
+ return worker.scheduled(controller, env, ctx);
+ }
+ };
+
+ return __facade_invoke__(
+ request,
+ env,
+ ctx,
+ __facade_modules_dispatch__,
+ __facade_modules_fetch__
+ );
+ } else {
+ // We didn't have any middleware so we can skip the invocation chain,
+ // and just call the fetch handler directly
+
+ // We "don't care" if this is undefined as we want to have the same behavior
+ // as if the worker completely bypassed middleware.
+ return __facade_modules_fetch__(request, env, ctx);
+ }
+ },
+};
+
+type HandlerFn<D, R> = (data: D, env: unknown, ctx: ExecutionContext) => R;
+function maskHandlerEnv<D, R>(handler: HandlerFn<D, R>): HandlerFn<D, R> {
+ return (data, env, ctx) => handler(data, getMaskedEnv(env), ctx);
+}
+
+export default facade;
diff --git a/node_modules/wrangler/templates/middleware/loader-sw.ts b/node_modules/wrangler/templates/middleware/loader-sw.ts
new file mode 100644
index 0000000..9e465f9
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/loader-sw.ts
@@ -0,0 +1,228 @@
+import {
+ Awaitable,
+ Dispatcher,
+ IncomingRequest,
+ Middleware,
+ __facade_invoke__,
+ __facade_register__,
+ __facade_registerInternal__,
+} from "./common";
+export { __facade_register__, __facade_registerInternal__ };
+
+// Miniflare 2's `EventTarget` follows the spec and doesn't allow exceptions to
+// be caught by `dispatchEvent`. Instead it has a custom `ThrowingEventTarget`
+// class that rethrows errors from event listeners in `dispatchEvent`.
+// We'd like errors to be propagated to the top-level `addEventListener`, so
+// we'd like to use `ThrowingEventTarget`. Unfortunately, `ThrowingEventTarget`
+// isn't exposed on the global scope, but `WorkerGlobalScope` (which extends
+// `ThrowingEventTarget`) is. Therefore, we get at it in this nasty way.
+let __FACADE_EVENT_TARGET__: EventTarget;
+if ((globalThis as any).MINIFLARE) {
+ __FACADE_EVENT_TARGET__ = new (Object.getPrototypeOf(WorkerGlobalScope))();
+} else {
+ __FACADE_EVENT_TARGET__ = new EventTarget();
+}
+
+function __facade_isSpecialEvent__(
+ type: string
+): type is "fetch" | "scheduled" {
+ return type === "fetch" || type === "scheduled";
+}
+const __facade__originalAddEventListener__ = globalThis.addEventListener;
+const __facade__originalRemoveEventListener__ = globalThis.removeEventListener;
+const __facade__originalDispatchEvent__ = globalThis.dispatchEvent;
+
+globalThis.addEventListener = function (type, listener, options) {
+ if (__facade_isSpecialEvent__(type)) {
+ __FACADE_EVENT_TARGET__.addEventListener(
+ type,
+ listener as EventListenerOrEventListenerObject,
+ options
+ );
+ } else {
+ __facade__originalAddEventListener__(type, listener, options);
+ }
+};
+globalThis.removeEventListener = function (type, listener, options) {
+ if (__facade_isSpecialEvent__(type)) {
+ __FACADE_EVENT_TARGET__.removeEventListener(
+ type,
+ listener as EventListenerOrEventListenerObject,
+ options
+ );
+ } else {
+ __facade__originalRemoveEventListener__(type, listener, options);
+ }
+};
+globalThis.dispatchEvent = function (event) {
+ if (__facade_isSpecialEvent__(event.type)) {
+ return __FACADE_EVENT_TARGET__.dispatchEvent(event);
+ } else {
+ return __facade__originalDispatchEvent__(event);
+ }
+};
+
+declare global {
+ var addMiddleware: typeof __facade_register__;
+ var addMiddlewareInternal: typeof __facade_registerInternal__;
+}
+globalThis.addMiddleware = __facade_register__;
+globalThis.addMiddlewareInternal = __facade_registerInternal__;
+
+const __facade_waitUntil__ = Symbol("__facade_waitUntil__");
+const __facade_response__ = Symbol("__facade_response__");
+const __facade_dispatched__ = Symbol("__facade_dispatched__");
+
+class __Facade_ExtendableEvent__ extends Event {
+ [__facade_waitUntil__]: Awaitable<unknown>[] = [];
+
+ waitUntil(promise: Awaitable<any>) {
+ if (!(this instanceof __Facade_ExtendableEvent__)) {
+ throw new TypeError("Illegal invocation");
+ }
+ this[__facade_waitUntil__].push(promise);
+ }
+}
+
+interface FetchEventInit extends EventInit {
+ request: Request;
+ passThroughOnException: FetchEvent["passThroughOnException"];
+}
+
+class __Facade_FetchEvent__ extends __Facade_ExtendableEvent__ {
+ #request: Request;
+ #passThroughOnException: FetchEvent["passThroughOnException"];
+ [__facade_response__]?: Awaitable<Response>;
+ [__facade_dispatched__] = false;
+
+ constructor(type: "fetch", init: FetchEventInit) {
+ super(type);
+ this.#request = init.request;
+ this.#passThroughOnException = init.passThroughOnException;
+ }
+
+ get request() {
+ return this.#request;
+ }
+
+ respondWith(response: Awaitable<Response>) {
+ if (!(this instanceof __Facade_FetchEvent__)) {
+ throw new TypeError("Illegal invocation");
+ }
+ if (this[__facade_response__] !== undefined) {
+ throw new DOMException(
+ "FetchEvent.respondWith() has already been called; it can only be called once.",
+ "InvalidStateError"
+ );
+ }
+ if (this[__facade_dispatched__]) {
+ throw new DOMException(
+ "Too late to call FetchEvent.respondWith(). It must be called synchronously in the event handler.",
+ "InvalidStateError"
+ );
+ }
+ this.stopImmediatePropagation();
+ this[__facade_response__] = response;
+ }
+
+ passThroughOnException() {
+ if (!(this instanceof __Facade_FetchEvent__)) {
+ throw new TypeError("Illegal invocation");
+ }
+ // Need to call native method immediately in case uncaught error thrown
+ this.#passThroughOnException();
+ }
+}
+
+interface ScheduledEventInit extends EventInit {
+ scheduledTime: number;
+ cron: string;
+ noRetry: ScheduledEvent["noRetry"];
+}
+
+class __Facade_ScheduledEvent__ extends __Facade_ExtendableEvent__ {
+ #scheduledTime: number;
+ #cron: string;
+ #noRetry: ScheduledEvent["noRetry"];
+
+ constructor(type: "scheduled", init: ScheduledEventInit) {
+ super(type);
+ this.#scheduledTime = init.scheduledTime;
+ this.#cron = init.cron;
+ this.#noRetry = init.noRetry;
+ }
+
+ get scheduledTime() {
+ return this.#scheduledTime;
+ }
+
+ get cron() {
+ return this.#cron;
+ }
+
+ noRetry() {
+ if (!(this instanceof __Facade_ScheduledEvent__)) {
+ throw new TypeError("Illegal invocation");
+ }
+ // Need to call native method immediately in case uncaught error thrown
+ this.#noRetry();
+ }
+}
+
+__facade__originalAddEventListener__("fetch", (event) => {
+ const ctx: ExecutionContext = {
+ waitUntil: event.waitUntil.bind(event),
+ passThroughOnException: event.passThroughOnException.bind(event),
+ };
+
+ const __facade_sw_dispatch__: Dispatcher = function (type, init) {
+ if (type === "scheduled") {
+ const facadeEvent = new __Facade_ScheduledEvent__("scheduled", {
+ scheduledTime: Date.now(),
+ cron: init.cron ?? "",
+ noRetry() {},
+ });
+
+ __FACADE_EVENT_TARGET__.dispatchEvent(facadeEvent);
+ event.waitUntil(Promise.all(facadeEvent[__facade_waitUntil__]));
+ }
+ };
+
+ const __facade_sw_fetch__: Middleware = function (request, _env, ctx) {
+ const facadeEvent = new __Facade_FetchEvent__("fetch", {
+ request,
+ passThroughOnException: ctx.passThroughOnException,
+ });
+
+ __FACADE_EVENT_TARGET__.dispatchEvent(facadeEvent);
+ facadeEvent[__facade_dispatched__] = true;
+ event.waitUntil(Promise.all(facadeEvent[__facade_waitUntil__]));
+
+ const response = facadeEvent[__facade_response__];
+ if (response === undefined) {
+ throw new Error("No response!"); // TODO: proper error message
+ }
+ return response;
+ };
+
+ event.respondWith(
+ __facade_invoke__(
+ event.request as IncomingRequest,
+ globalThis,
+ ctx,
+ __facade_sw_dispatch__,
+ __facade_sw_fetch__
+ )
+ );
+});
+
+__facade__originalAddEventListener__("scheduled", (event) => {
+ const facadeEvent = new __Facade_ScheduledEvent__("scheduled", {
+ scheduledTime: event.scheduledTime,
+ cron: event.cron,
+ noRetry: event.noRetry.bind(event),
+ });
+
+ __FACADE_EVENT_TARGET__.dispatchEvent(facadeEvent);
+ event.waitUntil(Promise.all(facadeEvent[__facade_waitUntil__]));
+});
diff --git a/node_modules/wrangler/templates/middleware/middleware-d1-beta.d.ts b/node_modules/wrangler/templates/middleware/middleware-d1-beta.d.ts
new file mode 100644
index 0000000..5ee0e6f
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-d1-beta.d.ts
@@ -0,0 +1,3 @@
+declare module "config:middleware/d1-beta" {
+ export const D1_IMPORTS: string[];
+}
diff --git a/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts b/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts
new file mode 100644
index 0000000..9377781
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts
@@ -0,0 +1,33 @@
+import type { Middleware } from "./common";
+
+interface JsonError {
+ message?: string;
+ name?: string;
+ stack?: string;
+ cause?: JsonError;
+}
+
+function reduceError(e: any): JsonError {
+ return {
+ name: e?.name,
+ message: e?.message ?? String(e),
+ stack: e?.stack,
+ cause: e?.cause === undefined ? undefined : reduceError(e.cause),
+ };
+}
+
+// See comment in `bundle.ts` for details on why this is needed
+const jsonError: Middleware = async (request, env, _ctx, middlewareCtx) => {
+ try {
+ return await middlewareCtx.next(request, env);
+ } catch (e: any) {
+ const error = reduceError(e);
+ return Response.json(error, {
+ status: 500,
+ headers: { "MF-Experimental-Error-Stack": "true" },
+ });
+ }
+};
+
+export default jsonError;
+export const wrap = undefined;
diff --git a/node_modules/wrangler/templates/middleware/middleware-multiworker-dev.d.ts b/node_modules/wrangler/templates/middleware/middleware-multiworker-dev.d.ts
new file mode 100644
index 0000000..704b273
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-multiworker-dev.d.ts
@@ -0,0 +1,4 @@
+declare module "config:middleware/multiworker-dev" {
+ import type { WorkerRegistry } from "../../src/dev-registry";
+ export const workers: WorkerRegistry;
+}
diff --git a/node_modules/wrangler/templates/middleware/middleware-multiworker-dev.ts b/node_modules/wrangler/templates/middleware/middleware-multiworker-dev.ts
new file mode 100644
index 0000000..fee33d5
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-multiworker-dev.ts
@@ -0,0 +1,59 @@
+// @ts-nocheck
+/// <reference path="middleware-multiworker-dev.d.ts"/>
+
+import { workers } from "config:middleware/multiworker-dev";
+import type { WorkerRegistry } from "../../src/dev-registry";
+
+export function wrap(env: Record<string, unknown>) {
+ const facadeEnv = { ...env };
+ // For every Worker definition that's available,
+ // create a fetcher for it on the facade env.
+ // for const [name, binding] of env
+ // if Workers[name]
+ // const details = Workers[name];
+
+ for (const [name, details] of Object.entries(workers as WorkerRegistry)) {
+ if (details) {
+ facadeEnv[name] = {
+ async fetch(...reqArgs: Parameters<Fetcher["fetch"]>) {
+ const reqFromArgs = new Request(...reqArgs);
+ if (details.headers) {
+ for (const [key, value] of Object.entries(details.headers)) {
+ // In remote mode, you need to add a couple of headers
+ // to make sure it's talking to the 'dev' preview session
+ // (much like wrangler dev already does via proxy.ts)
+ reqFromArgs.headers.set(key, value);
+ }
+ return (env[name] as Fetcher).fetch(reqFromArgs);
+ }
+
+ const url = new URL(reqFromArgs.url);
+ if (details.protocol !== undefined) {
+ url.protocol = details.protocol;
+ }
+ if (details.host !== undefined) {
+ url.host = details.host;
+ }
+ if (details.port !== undefined) {
+ url.port = details.port.toString();
+ }
+
+ const request = new Request(url.toString(), reqFromArgs);
+ return fetch(request);
+ },
+ };
+ } else {
+ // This means there's no dev binding available.
+ // Let's use whatever's available, or put a shim with a message.
+ facadeEnv[name] = facadeEnv[name] || {
+ async fetch() {
+ return new Response(
+ `You should start up wrangler dev --local on the ${name} worker`,
+ { status: 404 }
+ );
+ },
+ };
+ }
+ }
+ return facadeEnv;
+}
diff --git a/node_modules/wrangler/templates/middleware/middleware-pretty-error.ts b/node_modules/wrangler/templates/middleware/middleware-pretty-error.ts
new file mode 100644
index 0000000..29dc6d0
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-pretty-error.ts
@@ -0,0 +1,40 @@
+import type { Middleware } from "./common";
+
+// A middleware has to be a function of type Middleware
+const prettyError: Middleware = async (request, env, _ctx, middlewareCtx) => {
+ try {
+ const response = await middlewareCtx.next(request, env);
+ return response;
+ } catch (e: any) {
+ const html = `
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Error 🚨</title>
+ <style>
+ pre {
+ margin: 16px auto;
+ max-width: 600px;
+ background-color: #eeeeee;
+ border-radius: 4px;
+ padding: 16px;
+ }
+ </style>
+ </head>
+ <body>
+ <pre>${e.stack}</pre>
+ </body>
+ </html>
+ `;
+
+ return new Response(html, {
+ status: 500,
+ headers: { "Content-Type": "text/html;charset=utf-8" },
+ });
+ }
+};
+
+export default prettyError;
diff --git a/node_modules/wrangler/templates/middleware/middleware-scheduled.ts b/node_modules/wrangler/templates/middleware/middleware-scheduled.ts
new file mode 100644
index 0000000..3d9da28
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-scheduled.ts
@@ -0,0 +1,15 @@
+import type { Middleware } from "./common";
+
+// A middleware has to be a function of type Middleware
+const scheduled: Middleware = async (request, env, _ctx, middlewareCtx) => {
+ const url = new URL(request.url);
+ if (url.pathname === "/__scheduled") {
+ const cron = url.searchParams.get("cron") ?? "";
+ await middlewareCtx.dispatch("scheduled", { cron });
+
+ return new Response("Ran scheduled event");
+ }
+ return middlewareCtx.next(request, env);
+};
+
+export default scheduled;
diff --git a/node_modules/wrangler/templates/middleware/middleware-serve-static-assets.d.ts b/node_modules/wrangler/templates/middleware/middleware-serve-static-assets.d.ts
new file mode 100644
index 0000000..88ff173
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-serve-static-assets.d.ts
@@ -0,0 +1,6 @@
+declare module "config:middleware/serve-static-assets" {
+ import type { CacheControl } from "@cloudflare/kv-asset-handler";
+
+ export const spaMode: boolean;
+ export const cacheControl: Partial<CacheControl>;
+}
diff --git a/node_modules/wrangler/templates/middleware/middleware-serve-static-assets.ts b/node_modules/wrangler/templates/middleware/middleware-serve-static-assets.ts
new file mode 100644
index 0000000..4f72f40
--- /dev/null
+++ b/node_modules/wrangler/templates/middleware/middleware-serve-static-assets.ts
@@ -0,0 +1,56 @@
+/// <reference path="middleware-serve-static-assets.d.ts"/>
+
+import {
+ getAssetFromKV,
+ NotFoundError,
+ MethodNotAllowedError,
+ serveSinglePageApp,
+} from "@cloudflare/kv-asset-handler";
+import type { Options } from "@cloudflare/kv-asset-handler";
+import { spaMode, cacheControl } from "config:middleware/serve-static-assets";
+import type * as kvAssetHandler from "@cloudflare/kv-asset-handler";
+import manifest from "__STATIC_CONTENT_MANIFEST";
+const ASSET_MANIFEST = JSON.parse(manifest);
+
+import type { Middleware } from "./common";
+
+const staticAssets: Middleware = async (request, env, _ctx, middlewareCtx) => {
+ let options: Partial<Options> = {
+ ASSET_MANIFEST,
+ ASSET_NAMESPACE: env.__STATIC_CONTENT,
+ cacheControl: cacheControl,
+ mapRequestToAsset: spaMode ? serveSinglePageApp : undefined,
+ };
+
+ try {
+ const page = await (getAssetFromKV as typeof kvAssetHandler.getAssetFromKV)(
+ {
+ request,
+ waitUntil(promise) {
+ return _ctx.waitUntil(promise);
+ },
+ },
+ options
+ );
+
+ // allow headers to be altered
+ const response = new Response(page.body, page);
+
+ response.headers.set("X-XSS-Protection", "1; mode=block");
+ response.headers.set("X-Content-Type-Options", "nosniff");
+ response.headers.set("X-Frame-Options", "DENY");
+ response.headers.set("Referrer-Policy", "unsafe-url");
+ response.headers.set("Feature-Policy", "none");
+
+ return response;
+ } catch (e) {
+ if (e instanceof NotFoundError || e instanceof MethodNotAllowedError) {
+ // if a known error is thrown then serve from actual worker
+ return await middlewareCtx.next(request, env);
+ }
+ // otherwise it's a real error, so throw it
+ throw e;
+ }
+};
+
+export default staticAssets;