@torpor/build 1.0.0 → 1.0.2
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/{flattenHeaders-C_YYLdOq.mjs → Server-BnjLJleZ.mjs} +2 -12
- package/dist/Server-BnjLJleZ.mjs.map +1 -0
- package/dist/{Server-C_IKav_e.d.mts → Server-Cler2w5O.d.mts} +3 -48
- package/dist/Server-Cler2w5O.d.mts.map +1 -0
- package/dist/ServerEvent-CTx3Q-hk.d.mts +48 -0
- package/dist/ServerEvent-CTx3Q-hk.d.mts.map +1 -0
- package/dist/{Site-CMa153FA.d.mts → Site-CE0_o5Ci.d.mts} +3 -2
- package/dist/Site-CE0_o5Ci.d.mts.map +1 -0
- package/dist/bin/index.js +1 -1
- package/dist/clientEntry.d.mts +1 -0
- package/dist/clientEntry.mjs +59 -0
- package/dist/clientEntry.mjs.map +1 -0
- package/dist/clientEntryDev.d.mts +1 -0
- package/dist/clientEntryDev.mjs +7 -0
- package/dist/clientEntryDev.mjs.map +1 -0
- package/dist/dev.d.mts +3 -0
- package/dist/dev.mjs +3 -0
- package/dist/endpoint-EULRGCKA.mjs +108 -0
- package/dist/endpoint-EULRGCKA.mjs.map +1 -0
- package/dist/flattenHeaders-DM5qsSqO.mjs +13 -0
- package/dist/flattenHeaders-DM5qsSqO.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/load-BntzvmwL.mjs +228 -0
- package/dist/load-BntzvmwL.mjs.map +1 -0
- package/dist/nav.mjs +1 -225
- package/dist/nav.mjs.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/run.d.mts +1 -1
- package/dist/run.d.mts.map +1 -1
- package/dist/run.mjs +1 -1
- package/dist/{runOpenApi-BUi1RH1l.mjs → runOpenApi-C8eI2Fh0.mjs} +54 -16
- package/dist/runOpenApi-C8eI2Fh0.mjs.map +1 -0
- package/dist/server/Server.d.mts +2 -0
- package/dist/server/Server.mjs +2 -0
- package/dist/server.d.mts +2 -1
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +2 -1
- package/dist/server.mjs.map +1 -1
- package/dist/serverEntry-1qY3wZig.mjs +351 -0
- package/dist/serverEntry-1qY3wZig.mjs.map +1 -0
- package/dist/serverEntry-BAO8m03V.d.mts +6 -0
- package/dist/serverEntry-BAO8m03V.d.mts.map +1 -0
- package/dist/serverEntry.d.mts +2 -0
- package/dist/serverEntry.mjs +2 -0
- package/dist/test.d.mts +2 -2
- package/dist/test.mjs +2 -104
- package/dist/test.mjs.map +1 -1
- package/package.json +9 -8
- package/dist/Server-C_IKav_e.d.mts.map +0 -1
- package/dist/Site-CMa153FA.d.mts.map +0 -1
- package/dist/flattenHeaders-C_YYLdOq.mjs.map +0 -1
- package/dist/runOpenApi-BUi1RH1l.mjs.map +0 -1
- package/src/bin/index.ts +0 -22
- package/src/dev.ts +0 -10
- package/src/form/formDataToRecord.ts +0 -23
- package/src/form/readForm.ts +0 -71
- package/src/form.ts +0 -4
- package/src/index.ts +0 -82
- package/src/nav/api.test-d.ts +0 -79
- package/src/nav/api.ts +0 -104
- package/src/nav/formSubmit.ts +0 -70
- package/src/nav/load.ts +0 -9
- package/src/nav/loadData.ts +0 -134
- package/src/nav/navigate.ts +0 -189
- package/src/nav/reload.ts +0 -9
- package/src/nav/route.ts +0 -38
- package/src/nav.ts +0 -6
- package/src/openapi/docsHtml.ts +0 -25
- package/src/openapi/document.ts +0 -154
- package/src/openapi/plugin.ts +0 -78
- package/src/openapi/types.ts +0 -82
- package/src/openapi.ts +0 -14
- package/src/response/TypedResponse.ts +0 -17
- package/src/response/badRequest.ts +0 -31
- package/src/response/created.ts +0 -31
- package/src/response/forbidden.ts +0 -21
- package/src/response/found.ts +0 -30
- package/src/response/methodNotAllowed.ts +0 -18
- package/src/response/movedPermanently.ts +0 -25
- package/src/response/notFound.ts +0 -24
- package/src/response/notModified.ts +0 -34
- package/src/response/ok.ts +0 -38
- package/src/response/permanentRedirect.ts +0 -30
- package/src/response/response.ts +0 -22
- package/src/response/seeOther.ts +0 -19
- package/src/response/serverError.ts +0 -24
- package/src/response/temporaryRedirect.ts +0 -31
- package/src/response/transfer.ts +0 -14
- package/src/response/unauthorized.ts +0 -21
- package/src/response/unprocessable.ts +0 -30
- package/src/response.ts +0 -37
- package/src/run/depCache.ts +0 -175
- package/src/run/devPlugin.ts +0 -128
- package/src/run/prepareTemplate.ts +0 -42
- package/src/run/run.ts +0 -86
- package/src/run/runBuild.ts +0 -128
- package/src/run/runDev.ts +0 -177
- package/src/run/runOpenApi.ts +0 -52
- package/src/run/runPreview.ts +0 -84
- package/src/run/staleTorpCopies.ts +0 -100
- package/src/run.ts +0 -7
- package/src/schema.ts +0 -7
- package/src/server/CookieHelper.ts +0 -46
- package/src/server/HeaderHelper.ts +0 -25
- package/src/server/Server.ts +0 -168
- package/src/server/ServerEvent.ts +0 -62
- package/src/server/connect/connectMiddleware.ts +0 -85
- package/src/server/connect/flattenHeaders.ts +0 -22
- package/src/server/connect/nodeMessageToNodeResponse.ts +0 -89
- package/src/server/connect/requestToNodeMessage.ts +0 -29
- package/src/server/contentType.ts +0 -85
- package/src/server/types/HttpMethod.ts +0 -12
- package/src/server/types/MiddlewareFunction.ts +0 -22
- package/src/server/types/ServerFunction.ts +0 -7
- package/src/server.ts +0 -7
- package/src/site/Router.ts +0 -175
- package/src/site/Site.ts +0 -388
- package/src/site/checkLayoutSlots.ts +0 -114
- package/src/site/checkRoutes.ts +0 -435
- package/src/site/clientEntry.ts +0 -121
- package/src/site/clientEntryDev.ts +0 -3
- package/src/site/defaultAdapter.ts +0 -11
- package/src/site/layoutSlots.ts +0 -53
- package/src/site/manifest.ts +0 -173
- package/src/site/serverEntry.ts +0 -648
- package/src/state/$page.ts +0 -25
- package/src/state/$serverPage.ts +0 -22
- package/src/state/client.ts +0 -15
- package/src/state.ts +0 -3
- package/src/test/runTest.ts +0 -538
- package/src/test.ts +0 -3
- package/src/types/Adapter.ts +0 -20
- package/src/types/ClientState.ts +0 -8
- package/src/types/InternalState.ts +0 -7
- package/src/types/Jsonify.ts +0 -20
- package/src/types/LayoutHandler.ts +0 -5
- package/src/types/LayoutPath.ts +0 -10
- package/src/types/ManifestRoute.ts +0 -6
- package/src/types/PageData.test-d.ts +0 -136
- package/src/types/PageData.ts +0 -35
- package/src/types/PageEndPoint.ts +0 -55
- package/src/types/PageForm.test-d.ts +0 -78
- package/src/types/PageForm.ts +0 -29
- package/src/types/PageLoadEvent.ts +0 -26
- package/src/types/PageLoadReturn.ts +0 -13
- package/src/types/PageProps.ts +0 -14
- package/src/types/PageServerAction.ts +0 -13
- package/src/types/PageServerEndPoint.test-d.ts +0 -105
- package/src/types/PageServerEndPoint.ts +0 -110
- package/src/types/PageServerLoad.ts +0 -15
- package/src/types/PageState.ts +0 -8
- package/src/types/ParseRouteParams.test-d.ts +0 -84
- package/src/types/ParseRouteParams.ts +0 -64
- package/src/types/Route.ts +0 -30
- package/src/types/RouteHandler.ts +0 -23
- package/src/types/RouteLayoutHandler.ts +0 -5
- package/src/types/RouteMatchResult.ts +0 -7
- package/src/types/RouteType.ts +0 -19
- package/src/types/ServerEndPoint.test-d.ts +0 -77
- package/src/types/ServerEndPoint.ts +0 -169
- package/src/types/ServerHook.ts +0 -18
- package/src/types/ServerLoadEvent.ts +0 -82
- package/src/types/ServerRequest.ts +0 -15
- package/src/types/SitePlugin.ts +0 -24
- package/src/types/StandardSchema.ts +0 -109
- package/src/utils/pathToRegex.ts +0 -17
- package/src/utils/pathTrie.ts +0 -182
- package/src/utils/searchParamsToRecord.ts +0 -18
- package/src/utils/torporPackages.ts +0 -150
- package/src/utils/tsconfigAliases.ts +0 -90
- package/src/validation/ValidationError.ts +0 -18
- package/src/validation/endpoint.ts +0 -83
- package/src/validation/validate.ts +0 -26
- package/src/vite-env.d.ts +0 -2
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type IncomingMessage,
|
|
3
|
-
type OutgoingHttpHeader,
|
|
4
|
-
type OutgoingHttpHeaders,
|
|
5
|
-
ServerResponse,
|
|
6
|
-
} from "node:http";
|
|
7
|
-
import { PassThrough, Readable } from "node:stream";
|
|
8
|
-
|
|
9
|
-
// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/createServerResponse.ts
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Creates a custom ServerResponse object that allows for intercepting and
|
|
13
|
-
* streaming the response.
|
|
14
|
-
*
|
|
15
|
-
* @param incomingMessage The incoming HTTP request message.
|
|
16
|
-
* @returns An object containing the custom ServerResponse and a function that
|
|
17
|
-
* takes a callback to invoke when the response is readable, providing an object
|
|
18
|
-
* with the readable stream, headers and status code.
|
|
19
|
-
*/
|
|
20
|
-
export default function nodeMessageToNodeResponse(
|
|
21
|
-
incomingMessage: IncomingMessage,
|
|
22
|
-
): ServerResponseResponse {
|
|
23
|
-
const res = new ServerResponse(incomingMessage);
|
|
24
|
-
const passThrough = new PassThrough();
|
|
25
|
-
let handled = false;
|
|
26
|
-
|
|
27
|
-
const onReadable = (
|
|
28
|
-
cb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,
|
|
29
|
-
) => {
|
|
30
|
-
const handleReadable = () => {
|
|
31
|
-
if (handled) return;
|
|
32
|
-
handled = true;
|
|
33
|
-
cb({
|
|
34
|
-
readable: Readable.from(passThrough),
|
|
35
|
-
headers: res.getHeaders(),
|
|
36
|
-
status: res.statusCode,
|
|
37
|
-
});
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
passThrough.once("readable", handleReadable);
|
|
41
|
-
passThrough.once("end", handleReadable);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
passThrough.once("finish", () => {
|
|
45
|
-
res.emit("finish");
|
|
46
|
-
});
|
|
47
|
-
passThrough.once("close", () => {
|
|
48
|
-
res.destroy();
|
|
49
|
-
res.emit("close");
|
|
50
|
-
});
|
|
51
|
-
passThrough.on("drain", () => {
|
|
52
|
-
res.emit("drain");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
res.write = passThrough.write.bind(passThrough);
|
|
56
|
-
res.end = passThrough.end.bind(passThrough) as any;
|
|
57
|
-
|
|
58
|
-
res.writeHead = function writeHead(
|
|
59
|
-
statusCode: number,
|
|
60
|
-
statusMessage?: string | OutgoingHttpHeaders | OutgoingHttpHeader[],
|
|
61
|
-
headers?: OutgoingHttpHeaders | OutgoingHttpHeader[],
|
|
62
|
-
): ServerResponse {
|
|
63
|
-
res.statusCode = statusCode;
|
|
64
|
-
if (typeof statusMessage === "object") {
|
|
65
|
-
headers = statusMessage;
|
|
66
|
-
statusMessage = undefined;
|
|
67
|
-
}
|
|
68
|
-
if (headers) {
|
|
69
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
70
|
-
if (value !== undefined) {
|
|
71
|
-
res.setHeader(key, value);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return res;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
res,
|
|
80
|
-
onReadable,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
interface ServerResponseResponse {
|
|
85
|
-
res: ServerResponse;
|
|
86
|
-
onReadable: (
|
|
87
|
-
cb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,
|
|
88
|
-
) => void;
|
|
89
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { type IncomingMessage } from "node:http";
|
|
2
|
-
import { Readable } from "node:stream";
|
|
3
|
-
|
|
4
|
-
// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts
|
|
5
|
-
|
|
6
|
-
const DUMMY_BASE_URL = "http://localhost";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates an IncomingMessage object from a web Request.
|
|
10
|
-
*
|
|
11
|
-
* The request body is intentionally not forwarded: this is only used to wrap
|
|
12
|
-
* Connect-style middlewares (e.g. Vite's dev middleware), which don't read
|
|
13
|
-
* the body. The actual route handler later reads `ev.request.body` directly,
|
|
14
|
-
* and forwarding the body here would consume it and break the handler.
|
|
15
|
-
*
|
|
16
|
-
* @param {Request} request - The web Request object.
|
|
17
|
-
* @returns {IncomingMessage} An IncomingMessage-like object compatible with Node.js HTTP module.
|
|
18
|
-
*/
|
|
19
|
-
export default function requestToNodeMessage(request: Request): IncomingMessage {
|
|
20
|
-
const parsedUrl = new URL(request.url, DUMMY_BASE_URL);
|
|
21
|
-
const pathAndQuery = (parsedUrl.pathname || "") + (parsedUrl.search || "");
|
|
22
|
-
const body = Readable.from([]);
|
|
23
|
-
|
|
24
|
-
return Object.assign(body, {
|
|
25
|
-
url: pathAndQuery,
|
|
26
|
-
method: request.method,
|
|
27
|
-
headers: Object.fromEntries(request.headers),
|
|
28
|
-
}) as IncomingMessage;
|
|
29
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// From https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types
|
|
2
|
-
|
|
3
|
-
export default function contentType(extension: string): string {
|
|
4
|
-
return types[extension] || "application/octet-stream";
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const types: Record<string, string> = {
|
|
8
|
-
".aac": "audio/aac",
|
|
9
|
-
".abw": "application/x-abiword",
|
|
10
|
-
".apng": "image/apng",
|
|
11
|
-
".arc": "application/x-freearc",
|
|
12
|
-
".avif": "image/avif",
|
|
13
|
-
".avi": "video/x-msvideo",
|
|
14
|
-
".azw": "application/vnd.amazon.ebook",
|
|
15
|
-
".bin": "application/octet-stream",
|
|
16
|
-
".bmp": "image/bmp",
|
|
17
|
-
".bz": "application/x-bzip",
|
|
18
|
-
".bz2": "application/x-bzip2",
|
|
19
|
-
".cda": "application/x-cdf",
|
|
20
|
-
".csh": "application/x-csh",
|
|
21
|
-
".css": "text/css",
|
|
22
|
-
".csv": "text/csv",
|
|
23
|
-
".doc": "application/msword",
|
|
24
|
-
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
25
|
-
".eot": "application/vnd.ms-fontobject",
|
|
26
|
-
".epub": "application/epub+zip",
|
|
27
|
-
".gz": "application/gzip",
|
|
28
|
-
".gif": "image/gif",
|
|
29
|
-
".htm": "text/html",
|
|
30
|
-
".html": "text/html",
|
|
31
|
-
".ico": "image/vnd.microsoft.icon",
|
|
32
|
-
".ics": "text/calendar",
|
|
33
|
-
".jar": "application/java-archive",
|
|
34
|
-
".jpeg": "image/jpeg",
|
|
35
|
-
".jpg": "image/jpeg",
|
|
36
|
-
".js": "text/javascript",
|
|
37
|
-
".json": "application/json",
|
|
38
|
-
".jsonld": "application/ld+json",
|
|
39
|
-
".mid": "audio/midi",
|
|
40
|
-
".midi": "audio/midi",
|
|
41
|
-
".mjs": "text/javascript",
|
|
42
|
-
".mp3": "audio/mpeg",
|
|
43
|
-
".mp4": "video/mp4",
|
|
44
|
-
".mpeg": "video/mpeg",
|
|
45
|
-
".mpkg": "application/vnd.apple.installer+xml",
|
|
46
|
-
".odp": "application/vnd.oasis.opendocument.presentation",
|
|
47
|
-
".ods": "application/vnd.oasis.opendocument.spreadsheet",
|
|
48
|
-
".odt": "application/vnd.oasis.opendocument.text",
|
|
49
|
-
".oga": "audio/ogg",
|
|
50
|
-
".ogv": "video/ogg",
|
|
51
|
-
".ogx": "application/ogg",
|
|
52
|
-
".opus": "audio/ogg",
|
|
53
|
-
".otf": "font/otf",
|
|
54
|
-
".png": "image/png",
|
|
55
|
-
".pdf": "application/pdf",
|
|
56
|
-
".php": "application/x-httpd-php",
|
|
57
|
-
".ppt": "application/vnd.ms-powerpoint",
|
|
58
|
-
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
59
|
-
".rar": "application/vnd.rar",
|
|
60
|
-
".rtf": "application/rtf",
|
|
61
|
-
".sh": "application/x-sh",
|
|
62
|
-
".svg": "image/svg+xml",
|
|
63
|
-
".tar": "application/x-tar",
|
|
64
|
-
".tif": "image/tiff",
|
|
65
|
-
".tiff": "image/tiff",
|
|
66
|
-
".ts": "video/mp2t",
|
|
67
|
-
".ttf": "font/ttf",
|
|
68
|
-
".txt": "text/plain",
|
|
69
|
-
".vsd": "application/vnd.visio",
|
|
70
|
-
".wav": "audio/wav",
|
|
71
|
-
".weba": "audio/webm",
|
|
72
|
-
".webm": "video/webm",
|
|
73
|
-
".webp": "image/webp",
|
|
74
|
-
".woff": "font/woff",
|
|
75
|
-
".woff2": "font/woff2",
|
|
76
|
-
".xhtml": "application/xhtml+xml",
|
|
77
|
-
".xls": "application/vnd.ms-excel",
|
|
78
|
-
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
79
|
-
".xml": "application/xml",
|
|
80
|
-
".xul": "application/vnd.mozilla.xul+xml",
|
|
81
|
-
".zip": "application/zip",
|
|
82
|
-
".3gp": "video/3gpp",
|
|
83
|
-
".3g2": "video/3gpp2",
|
|
84
|
-
".7z": "application/x-7z-compressed",
|
|
85
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import ServerEvent from "../ServerEvent";
|
|
2
|
-
|
|
3
|
-
type MiddlewareFunction = {
|
|
4
|
-
/**
|
|
5
|
-
* Called before the route handler. Middleware are run in the order they
|
|
6
|
-
* were added. Return a Response to short-circuit the request; the
|
|
7
|
-
* remaining middleware and the route handler are then skipped.
|
|
8
|
-
*/
|
|
9
|
-
enter?: (ev: ServerEvent) => Response | void | Promise<Response | void>;
|
|
10
|
-
/**
|
|
11
|
-
* Called after the route handler (even if it threw), in reverse order.
|
|
12
|
-
* Return a Response to replace the response. Middleware that were skipped
|
|
13
|
-
* by a short-circuit don't get their exit hook run.
|
|
14
|
-
*
|
|
15
|
-
* If the route handler (or a later enter hook) threw, the error is
|
|
16
|
-
* available as `ev.error`; returning a Response handles the error and
|
|
17
|
-
* stops it from propagating.
|
|
18
|
-
*/
|
|
19
|
-
exit?: (ev: ServerEvent) => Response | void | Promise<Response | void>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export default MiddlewareFunction;
|
package/src/server.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import CookieHelper from "./server/CookieHelper";
|
|
2
|
-
import HeaderHelper from "./server/HeaderHelper";
|
|
3
|
-
import Server from "./server/Server";
|
|
4
|
-
import ServerEvent from "./server/ServerEvent";
|
|
5
|
-
import connectMiddleware from "./server/connect/connectMiddleware";
|
|
6
|
-
|
|
7
|
-
export { Server, ServerEvent, CookieHelper, HeaderHelper, connectMiddleware };
|
package/src/site/Router.ts
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import type LayoutHandler from "../types/LayoutHandler";
|
|
2
|
-
import type ManifestRoute from "../types/ManifestRoute";
|
|
3
|
-
import type RouteHandler from "../types/RouteHandler";
|
|
4
|
-
import PathTrie from "../utils/pathTrie";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A router that handles file routes with layouts, hooks, etc.
|
|
8
|
-
*/
|
|
9
|
-
export default class Router {
|
|
10
|
-
routes: Route[] = [];
|
|
11
|
-
// Match index for the routes above. The routes list is kept for
|
|
12
|
-
// introspection (layouts/hooks lookup, client nav, tests); the trie is
|
|
13
|
-
// what `match` walks.
|
|
14
|
-
#trie = new PathTrie<Route>();
|
|
15
|
-
|
|
16
|
-
constructor() {}
|
|
17
|
-
|
|
18
|
-
//add(path: string, file: string) {
|
|
19
|
-
// // TODO: Call the specific addX method based on the file path
|
|
20
|
-
// this.addPage(route, file);
|
|
21
|
-
//}
|
|
22
|
-
|
|
23
|
-
addPages(routes: ManifestRoute[]): this {
|
|
24
|
-
for (let r of routes) {
|
|
25
|
-
this.addPage(r.path, r.type, r.endPoint, r.subFolder);
|
|
26
|
-
}
|
|
27
|
-
return this;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// TODO: Allow calling with the endpoint itself, so that you can setup an app with no scaffold
|
|
31
|
-
addPage(path: string, type: number, endPoint: () => Promise<any>, subFolder?: string): this {
|
|
32
|
-
let route = new Route(path, {
|
|
33
|
-
path,
|
|
34
|
-
type,
|
|
35
|
-
endPoint,
|
|
36
|
-
subFolder,
|
|
37
|
-
});
|
|
38
|
-
this.routes.push(route);
|
|
39
|
-
this.#trie.insert(path, route);
|
|
40
|
-
this.#sortRoutes();
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/*
|
|
45
|
-
loadPage(ev: ServerEvent, file: string): Response {
|
|
46
|
-
let page = this.pages.get(file);
|
|
47
|
-
if (!page) {
|
|
48
|
-
page = {};
|
|
49
|
-
this.pages.set(file, page);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
match(path: string, query: URLSearchParams): RouteMatch | undefined {
|
|
55
|
-
let found = this.#trie.match(path);
|
|
56
|
-
if (found) {
|
|
57
|
-
let route = found.value;
|
|
58
|
-
// Lazy load server endpoints and layouts
|
|
59
|
-
if (!route.handler.loaded) {
|
|
60
|
-
this.#loadHandler(route.handler, route.path);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
handler: route.handler,
|
|
65
|
-
params: found.params,
|
|
66
|
-
query,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
#loadHandler(handler: RouteHandler, path: string) {
|
|
72
|
-
handler.layouts = this.#findLayouts(path, handler);
|
|
73
|
-
handler.serverEndPoint = this.#findServer(path);
|
|
74
|
-
handler.serverHooks = this.#findServerHooks(handler);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
#findLayouts(path: string, handler: RouteHandler): LayoutHandler[] | undefined {
|
|
78
|
-
let layouts: LayoutHandler[] = [];
|
|
79
|
-
let parts = path
|
|
80
|
-
// Strip the trailing`~/server` (so we don't look for `~/server/_layout`
|
|
81
|
-
// which will never exist)
|
|
82
|
-
.replace(/\/~server$/, "")
|
|
83
|
-
// The path will always start with / so splitting e.g. `/first/second`
|
|
84
|
-
// will result in ['', 'first', 'second'] and checks for `/_layout`,
|
|
85
|
-
// `/first/_layout` and `/second/_layout`
|
|
86
|
-
.split("/");
|
|
87
|
-
let basePath = "";
|
|
88
|
-
for (let i = 0; i < parts.length; i++) {
|
|
89
|
-
if (i > 0) {
|
|
90
|
-
basePath += "/" + parts[i];
|
|
91
|
-
}
|
|
92
|
-
const layoutPath = basePath + "/_layout";
|
|
93
|
-
const layoutRoute = this.routes.find((r) => r.path === layoutPath);
|
|
94
|
-
if (layoutRoute && layoutRoute.handler.subFolder === handler.subFolder) {
|
|
95
|
-
layouts.push({
|
|
96
|
-
path: layoutPath,
|
|
97
|
-
endPoint: layoutRoute.handler.endPoint,
|
|
98
|
-
serverEndPoint: this.#findServer(layoutPath),
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return layouts.length ? layouts : undefined;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
#findServer(path: string): (() => Promise<any>) | undefined {
|
|
106
|
-
const serverPath = path.replace(/\/$/, "") + "/~server";
|
|
107
|
-
const serverRoute = this.routes.find((r) => r.path === serverPath);
|
|
108
|
-
return serverRoute && serverRoute.handler.endPoint;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
#findServerHooks(handler: RouteHandler): (() => Promise<any>)[] | undefined {
|
|
112
|
-
// Collect the hooks from the root down to the route path, like
|
|
113
|
-
// layouts. Only hooks with the same subFolder are included, so that
|
|
114
|
-
// e.g. an `api` set of routes can have its own hooks
|
|
115
|
-
const hooks: (() => Promise<any>)[] = [];
|
|
116
|
-
let parts = handler.path
|
|
117
|
-
// Strip the trailing `~server` (so we don't look for
|
|
118
|
-
// `~server/_hook/~server` which will never exist)
|
|
119
|
-
.replace(/\/~server$/, "")
|
|
120
|
-
// The path will always start with / so splitting e.g.
|
|
121
|
-
// `/first/second` will result in ['', 'first', 'second'] and
|
|
122
|
-
// checks for `/_hook/~server`, `/first/_hook/~server` and
|
|
123
|
-
// `/second/_hook/~server`
|
|
124
|
-
.split("/");
|
|
125
|
-
let basePath = "";
|
|
126
|
-
for (let i = 0; i < parts.length; i++) {
|
|
127
|
-
if (i > 0) {
|
|
128
|
-
basePath += "/" + parts[i];
|
|
129
|
-
}
|
|
130
|
-
const hookPath = basePath + "/_hook/~server";
|
|
131
|
-
const hookRoute = this.routes.find((r) => r.path === hookPath);
|
|
132
|
-
if (hookRoute && hookRoute.handler.subFolder === handler.subFolder) {
|
|
133
|
-
hooks.push(hookRoute.handler.endPoint);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return hooks.length ? hooks : undefined;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// HACK: We're doing this here as well as in Site, so that you can use the
|
|
140
|
-
// Router externally without Site
|
|
141
|
-
#sortRoutes() {
|
|
142
|
-
this.routes = this.routes.sort((a, b) => {
|
|
143
|
-
// Sort [param]s after paths
|
|
144
|
-
// There might be a quicker/easier way to do this
|
|
145
|
-
for (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {
|
|
146
|
-
if (a.path[i] === "[" && b.path[i] !== "[") {
|
|
147
|
-
return 1;
|
|
148
|
-
} else if (b.path[i] === "[" && a.path[i] !== "[") {
|
|
149
|
-
return -1;
|
|
150
|
-
} else if (a.path[i] === b.path[i]) {
|
|
151
|
-
// Keep going...
|
|
152
|
-
} else {
|
|
153
|
-
return a.path[i].localeCompare(b.path[i]);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return a.path.length - b.path.length;
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
class Route {
|
|
162
|
-
path: string;
|
|
163
|
-
handler: RouteHandler;
|
|
164
|
-
|
|
165
|
-
constructor(path: string, handler: RouteHandler) {
|
|
166
|
-
this.path = path;
|
|
167
|
-
this.handler = handler;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
interface RouteMatch {
|
|
172
|
-
handler: RouteHandler;
|
|
173
|
-
params?: Record<string, string>;
|
|
174
|
-
query: URLSearchParams;
|
|
175
|
-
}
|