mirror of
https://github.com/JonasunderscoreJones/api.jonasjones.dev.git
synced 2025-10-23 20:19:19 +02:00
Initial commit (by create-cloudflare CLI)
This commit is contained in:
commit
58a42872a0
1745 changed files with 741893 additions and 0 deletions
198
node_modules/wrangler/templates/pages-template-worker.ts
generated
vendored
Normal file
198
node_modules/wrangler/templates/pages-template-worker.ts
generated
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
import { match } from "path-to-regexp";
|
||||
|
||||
//note: this explicitly does not include the * character, as pages requires this
|
||||
const escapeRegex = /[.+?^${}()|[\]\\]/g;
|
||||
|
||||
type HTTPMethod =
|
||||
| "HEAD"
|
||||
| "OPTIONS"
|
||||
| "GET"
|
||||
| "POST"
|
||||
| "PUT"
|
||||
| "PATCH"
|
||||
| "DELETE";
|
||||
|
||||
/* TODO: Grab these from @cloudflare/workers-types instead */
|
||||
type Params<P extends string = string> = Record<P, string | string[]>;
|
||||
|
||||
type EventContext<Env, P extends string, Data> = {
|
||||
request: Request;
|
||||
functionPath: string;
|
||||
waitUntil: (promise: Promise<unknown>) => void;
|
||||
passThroughOnException: () => void;
|
||||
next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
||||
env: Env & { ASSETS: { fetch: typeof fetch } };
|
||||
params: Params<P>;
|
||||
data: Data;
|
||||
};
|
||||
|
||||
declare type PagesFunction<
|
||||
Env = unknown,
|
||||
P extends string = string,
|
||||
Data extends Record<string, unknown> = Record<string, unknown>
|
||||
> = (context: EventContext<Env, P, Data>) => Response | Promise<Response>;
|
||||
/* end @cloudflare/workers-types */
|
||||
|
||||
type RouteHandler = {
|
||||
routePath: string;
|
||||
mountPath: string;
|
||||
method?: HTTPMethod;
|
||||
modules: PagesFunction[];
|
||||
middlewares: PagesFunction[];
|
||||
};
|
||||
|
||||
// inject `routes` via ESBuild
|
||||
declare const routes: RouteHandler[];
|
||||
// define `__FALLBACK_SERVICE__` via ESBuild
|
||||
declare const __FALLBACK_SERVICE__: string;
|
||||
|
||||
// expect an ASSETS fetcher binding pointing to the asset-server stage
|
||||
type FetchEnv = {
|
||||
[name: string]: { fetch: typeof fetch };
|
||||
ASSETS: { fetch: typeof fetch };
|
||||
};
|
||||
|
||||
type WorkerContext = {
|
||||
waitUntil: (promise: Promise<unknown>) => void;
|
||||
passThroughOnException: () => void;
|
||||
};
|
||||
|
||||
function* executeRequest(request: Request) {
|
||||
const requestPath = new URL(request.url).pathname;
|
||||
|
||||
// First, iterate through the routes (backwards) and execute "middlewares" on partial route matches
|
||||
for (const route of [...routes].reverse()) {
|
||||
if (route.method && route.method !== request.method) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// replaces with "\\$&", this prepends a backslash to the matched string, e.g. "[" becomes "\["
|
||||
const routeMatcher = match(route.routePath.replace(escapeRegex, "\\$&"), {
|
||||
end: false,
|
||||
});
|
||||
const mountMatcher = match(route.mountPath.replace(escapeRegex, "\\$&"), {
|
||||
end: false,
|
||||
});
|
||||
const matchResult = routeMatcher(requestPath);
|
||||
const mountMatchResult = mountMatcher(requestPath);
|
||||
if (matchResult && mountMatchResult) {
|
||||
for (const handler of route.middlewares.flat()) {
|
||||
yield {
|
||||
handler,
|
||||
params: matchResult.params as Params,
|
||||
path: mountMatchResult.path,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then look for the first exact route match and execute its "modules"
|
||||
for (const route of routes) {
|
||||
if (route.method && route.method !== request.method) {
|
||||
continue;
|
||||
}
|
||||
const routeMatcher = match(route.routePath.replace(escapeRegex, "\\$&"), {
|
||||
end: true,
|
||||
});
|
||||
const mountMatcher = match(route.mountPath.replace(escapeRegex, "\\$&"), {
|
||||
end: false,
|
||||
});
|
||||
const matchResult = routeMatcher(requestPath);
|
||||
const mountMatchResult = mountMatcher(requestPath);
|
||||
if (matchResult && mountMatchResult && route.modules.length) {
|
||||
for (const handler of route.modules.flat()) {
|
||||
yield {
|
||||
handler,
|
||||
params: matchResult.params as Params,
|
||||
path: matchResult.path,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
async fetch(
|
||||
originalRequest: Request,
|
||||
env: FetchEnv,
|
||||
workerContext: WorkerContext
|
||||
) {
|
||||
let request = originalRequest;
|
||||
const handlerIterator = executeRequest(request);
|
||||
let data = {}; // arbitrary data the user can set between functions
|
||||
let isFailOpen = false;
|
||||
|
||||
const next = async (input?: RequestInfo, init?: RequestInit) => {
|
||||
if (input !== undefined) {
|
||||
let url = input;
|
||||
if (typeof input === "string") {
|
||||
url = new URL(input, request.url).toString();
|
||||
}
|
||||
request = new Request(url, init);
|
||||
}
|
||||
|
||||
const result = handlerIterator.next();
|
||||
// Note we can't use `!result.done` because this doesn't narrow to the correct type
|
||||
if (result.done === false) {
|
||||
const { handler, params, path } = result.value;
|
||||
const context = {
|
||||
request: new Request(request.clone()),
|
||||
functionPath: path,
|
||||
next,
|
||||
params,
|
||||
get data() {
|
||||
return data;
|
||||
},
|
||||
set data(value) {
|
||||
if (typeof value !== "object" || value === null) {
|
||||
throw new Error("context.data must be an object");
|
||||
}
|
||||
// user has overriden context.data, so we need to merge it with the existing data
|
||||
data = value;
|
||||
},
|
||||
env,
|
||||
waitUntil: workerContext.waitUntil.bind(workerContext),
|
||||
passThroughOnException: () => {
|
||||
isFailOpen = true;
|
||||
},
|
||||
};
|
||||
|
||||
const response = await handler(context);
|
||||
|
||||
if (!(response instanceof Response)) {
|
||||
throw new Error("Your Pages function should return a Response");
|
||||
}
|
||||
|
||||
return cloneResponse(response);
|
||||
} else if (__FALLBACK_SERVICE__) {
|
||||
// There are no more handlers so finish with the fallback service (`env.ASSETS.fetch` in Pages' case)
|
||||
const response = await env[__FALLBACK_SERVICE__].fetch(request);
|
||||
return cloneResponse(response);
|
||||
} else {
|
||||
// There was not fallback service so actually make the request to the origin.
|
||||
const response = await fetch(request);
|
||||
return cloneResponse(response);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
return await next();
|
||||
} catch (error) {
|
||||
if (isFailOpen) {
|
||||
const response = await env[__FALLBACK_SERVICE__].fetch(request);
|
||||
return cloneResponse(response);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// This makes a Response mutable
|
||||
const cloneResponse = (response: Response) =>
|
||||
// https://fetch.spec.whatwg.org/#null-body-status
|
||||
new Response(
|
||||
[101, 204, 205, 304].includes(response.status) ? null : response.body,
|
||||
response
|
||||
);
|
Loading…
Add table
Add a link
Reference in a new issue