alinea
Version:
Headless git-based CMS
184 lines (182 loc) • 5.77 kB
JavaScript
import {
parse
} from "../../chunks/chunk-467JA2PB.js";
import "../../chunks/chunk-NZLE2WMY.js";
// src/backend/router/Router.ts
import { CompressionStream, Headers, Response } from "@alinea/iso";
var Route = class _Route {
constructor(handle) {
this.handle = handle;
}
map(next) {
return new _Route((input) => {
const result = this.handle(input);
if (result instanceof Promise)
return result.then((v) => {
return v === void 0 ? void 0 : callHandler(next, v);
});
if (result !== void 0) return callHandler(next, result);
});
}
notFound(handler) {
return new _Route(async (input) => {
let result = this.handle(input);
if (result instanceof Promise) result = await result;
if (result === void 0) return handler(input);
return result;
});
}
recover(handler) {
return new _Route(async (input) => {
try {
let result = this.handle(input);
if (result instanceof Promise) result = await result;
return result;
} catch (e) {
const error = e instanceof Error ? e : new Error(`Could not serve request: ${e}`);
return handler(error);
}
});
}
};
function router(...routes) {
return new Route(async (request) => {
for (const handler of routes) {
if (!handler) continue;
let result = callHandler(handler, request);
if (result instanceof Promise) result = await result;
if (result !== void 0) return result;
}
});
}
function callHandler(handler, input) {
return typeof handler === "function" ? handler(input) : handler.handle(input);
}
((router2) => {
function use(handle) {
return new Route(handle);
}
router2.use = use;
function withMethod(method) {
return use((request) => {
if (request.method !== method) return void 0;
return request;
});
}
function withPath(path, getPathname) {
const matcher2 = parse(path);
return use((request) => {
const url = new URL(request.url);
const match = matcher2.pattern.exec(getPathname(url));
if (match === null) return void 0;
const params = {};
if (matcher2.keys)
for (let i = 0; i < matcher2.keys.length; i++)
params[matcher2.keys[i]] = match[i + 1];
return { request, url, params };
});
}
function matcher(getPathname = (url) => url.pathname) {
return {
get(path) {
return withMethod("GET").map(withPath(path, getPathname));
},
post(path) {
return withMethod("POST").map(withPath(path, getPathname));
},
put(path) {
return withMethod("PUT").map(withPath(path, getPathname));
},
delete(path) {
return withMethod("DELETE").map(withPath(path, getPathname));
},
all(path) {
return withPath(path, getPathname);
}
};
}
router2.matcher = matcher;
function base(url) {
const base2 = new URL(url).pathname;
const prefix = base2.endsWith("/") ? base2.slice(0, -1) : base2;
return matcher(({ pathname }) => {
if (pathname.startsWith(prefix)) return pathname.slice(prefix.length);
return pathname;
});
}
router2.base = base;
router2.queryMatcher = matcher(({ search }) => {
const rest = search.indexOf("&");
return rest > -1 ? search.slice(1, rest) : search.slice(1);
});
async function parseFormData(input) {
const body = await input.request.formData();
return { ...input, body };
}
router2.parseFormData = parseFormData;
async function parseBuffer(input) {
const body = await input.request.arrayBuffer();
return { ...input, body };
}
router2.parseBuffer = parseBuffer;
async function parseJson(input) {
const body = await input.request.json();
return { ...input, body };
}
router2.parseJson = parseJson;
function reportError(error) {
console.error(error);
return Response.json({ success: false, error }, { status: 500 });
}
router2.reportError = reportError;
function redirect(url, init = {}) {
return new Response("", {
...init,
headers: { location: String(url), ...init.headers },
status: init.status || 301
});
}
router2.redirect = redirect;
function cookieValue([key, value]) {
if (value === true) return `; ${key}`;
if (value === false) return "";
if (value instanceof Date) return `; ${key}=${value.toUTCString()}`;
return `; ${key}=${String(value)}`;
}
function cookie(...cookies) {
return cookies.map((cookie2) => {
const { name, value, ...rest } = cookie2;
return `${name}=${value}${Object.entries(rest).map(cookieValue).join("")}`;
}).join(", ");
}
router2.cookie = cookie;
function compress(...routes) {
const route = router2(...routes);
return new Route(
async (request) => {
const response = await route.handle(request);
if (response === void 0) return void 0;
const body = response.body;
if (!body) return response;
const isCompressed = response.headers.get("content-encoding");
if (isCompressed) return response;
const accept = request.headers.get("accept-encoding");
const method = accept?.includes("gzip") ? "gzip" : accept?.includes("deflate") ? "deflate" : void 0;
if (method === void 0) return response;
const stream = body.pipeThrough(new CompressionStream(method));
const headers = new Headers(response.headers);
headers.set("content-encoding", method);
headers.delete("content-length");
return new Response(stream, {
headers,
status: response.status
});
}
);
}
router2.compress = compress;
})(router || (router = {}));
export {
Route,
router
};