lynnix 0.0.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.
Files changed (70) hide show
  1. package/README.md +542 -0
  2. package/dist/index.d.ts +17 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +13 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lynnix.d.ts +46 -0
  7. package/dist/lynnix.d.ts.map +1 -0
  8. package/dist/lynnix.js +199 -0
  9. package/dist/lynnix.js.map +1 -0
  10. package/dist/utils/augmentRequest.d.ts +12 -0
  11. package/dist/utils/augmentRequest.d.ts.map +1 -0
  12. package/dist/utils/augmentRequest.js +66 -0
  13. package/dist/utils/augmentRequest.js.map +1 -0
  14. package/dist/utils/augmentResponse.d.ts +17 -0
  15. package/dist/utils/augmentResponse.d.ts.map +1 -0
  16. package/dist/utils/augmentResponse.js +56 -0
  17. package/dist/utils/augmentResponse.js.map +1 -0
  18. package/dist/utils/buildRoutesMap.d.ts +19 -0
  19. package/dist/utils/buildRoutesMap.d.ts.map +1 -0
  20. package/dist/utils/buildRoutesMap.js +48 -0
  21. package/dist/utils/buildRoutesMap.js.map +1 -0
  22. package/dist/utils/error.d.ts +18 -0
  23. package/dist/utils/error.d.ts.map +1 -0
  24. package/dist/utils/error.js +20 -0
  25. package/dist/utils/error.js.map +1 -0
  26. package/dist/utils/findClosestBoundary.d.ts +14 -0
  27. package/dist/utils/findClosestBoundary.d.ts.map +1 -0
  28. package/dist/utils/findClosestBoundary.js +29 -0
  29. package/dist/utils/findClosestBoundary.js.map +1 -0
  30. package/dist/utils/getMiddlewareChain.d.ts +19 -0
  31. package/dist/utils/getMiddlewareChain.d.ts.map +1 -0
  32. package/dist/utils/getMiddlewareChain.js +31 -0
  33. package/dist/utils/getMiddlewareChain.js.map +1 -0
  34. package/dist/utils/handleHttpError.d.ts +24 -0
  35. package/dist/utils/handleHttpError.d.ts.map +1 -0
  36. package/dist/utils/handleHttpError.js +23 -0
  37. package/dist/utils/handleHttpError.js.map +1 -0
  38. package/dist/utils/handleNotFound.d.ts +33 -0
  39. package/dist/utils/handleNotFound.d.ts.map +1 -0
  40. package/dist/utils/handleNotFound.js +71 -0
  41. package/dist/utils/handleNotFound.js.map +1 -0
  42. package/dist/utils/lruCache.d.ts +17 -0
  43. package/dist/utils/lruCache.d.ts.map +1 -0
  44. package/dist/utils/lruCache.js +36 -0
  45. package/dist/utils/lruCache.js.map +1 -0
  46. package/dist/utils/lynnixRequest.d.ts +22 -0
  47. package/dist/utils/lynnixRequest.d.ts.map +1 -0
  48. package/dist/utils/lynnixRequest.js +21 -0
  49. package/dist/utils/lynnixRequest.js.map +1 -0
  50. package/dist/utils/lynnixResponse.d.ts +53 -0
  51. package/dist/utils/lynnixResponse.d.ts.map +1 -0
  52. package/dist/utils/lynnixResponse.js +142 -0
  53. package/dist/utils/lynnixResponse.js.map +1 -0
  54. package/dist/utils/matchRoute.d.ts +20 -0
  55. package/dist/utils/matchRoute.d.ts.map +1 -0
  56. package/dist/utils/matchRoute.js +55 -0
  57. package/dist/utils/matchRoute.js.map +1 -0
  58. package/dist/utils/parseReqBody.d.ts +28 -0
  59. package/dist/utils/parseReqBody.d.ts.map +1 -0
  60. package/dist/utils/parseReqBody.js +415 -0
  61. package/dist/utils/parseReqBody.js.map +1 -0
  62. package/dist/utils/runMiddlewares.d.ts +5 -0
  63. package/dist/utils/runMiddlewares.d.ts.map +1 -0
  64. package/dist/utils/runMiddlewares.js +18 -0
  65. package/dist/utils/runMiddlewares.js.map +1 -0
  66. package/dist/utils/sortRoutes.d.ts +16 -0
  67. package/dist/utils/sortRoutes.d.ts.map +1 -0
  68. package/dist/utils/sortRoutes.js +44 -0
  69. package/dist/utils/sortRoutes.js.map +1 -0
  70. package/package.json +68 -0
package/dist/lynnix.js ADDED
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import { pathToFileURL } from "node:url";
10
+ import Mutor from "mutorjs/server";
11
+ import augmentRequest from "./utils/augmentRequest.js";
12
+ import augmentResponse from "./utils/augmentResponse.js";
13
+ import buildRoutes from "./utils/buildRoutesMap.js";
14
+ import { HttpError, NotFoundError } from "./utils/error.js";
15
+ import findClosestBoundary from "./utils/findClosestBoundary.js";
16
+ import { handleHttpError } from "./utils/handleHttpError.js";
17
+ import { handleNotFound } from "./utils/handleNotFound.js";
18
+ import LRUCache from "./utils/lruCache.js";
19
+ import matchRoute from "./utils/matchRoute.js";
20
+ import parseReqBody from "./utils/parseReqBody.js";
21
+ import runMiddlewares from "./utils/runMiddlewares.js";
22
+ import { sortRoutes } from "./utils/sortRoutes.js";
23
+ /**
24
+ * @param path The root directory of the mutor instance
25
+ * @returns A request handler function that serves the mutor instance
26
+ * @example
27
+ *
28
+ * import createLynnixApp from "lynnix";
29
+ * import * as http from "node:http";
30
+ * import sendStatic from "serve-static";
31
+ *
32
+ * const handler = createLynnixApp("app");
33
+ * const serve = serveStatic("./public", { index: false });
34
+ *
35
+ * const server = http.createServer((req, res) => {
36
+ * serve(req, res, () => handler(req, res));
37
+ * });
38
+ *
39
+ * // OR
40
+ *
41
+ * import express from "express";
42
+ *
43
+ * const server = express();
44
+ * const handler = createLynnixApp("app");
45
+ *
46
+ * server.use(express.urlencoded({ extended: true }));
47
+ * server.use(express.json());
48
+ * server.static("./public");
49
+ *
50
+ * server.use(handler);
51
+ *
52
+ * // FINALLY
53
+ *
54
+ * server.listen(3000);
55
+ */
56
+ export default async function createLynnixApp(path, mutorConfig = {}, bodyParserOptions = {}) {
57
+ if (!path || typeof path !== "string") {
58
+ throw new Error("path must be a string");
59
+ }
60
+ const MATCHED_ROUTES_CACHE = new LRUCache();
61
+ const mutor = new Mutor({ rootDir: path, ...mutorConfig });
62
+ const routesMap = await buildRoutes(path);
63
+ const sortedRoutes = sortRoutes(Object.keys(routesMap));
64
+ // Add layouts from the root directory
65
+ await mutor.addLayoutsInDir(path);
66
+ return async (_req, _res) => {
67
+ const isHtmxReq = _req.headers["hx-request"] === "true";
68
+ const req = await augmentRequest(_req);
69
+ const res = await augmentResponse(_res, isHtmxReq);
70
+ const { url } = req.raw;
71
+ const method = req.raw.method?.toUpperCase() ?? "GET";
72
+ if (!url) {
73
+ return res.raw.end();
74
+ }
75
+ const { pathname } = new URL(url, `http://${req.raw.headers.host ?? "localhost"}`);
76
+ const match = MATCHED_ROUTES_CACHE.get(pathname) ?? matchRoute(pathname, sortedRoutes);
77
+ if (!match) {
78
+ await handleNotFound({
79
+ req,
80
+ res,
81
+ mutor,
82
+ isHtmxReq,
83
+ routes: sortedRoutes,
84
+ routesMap,
85
+ pathname,
86
+ error: new NotFoundError(),
87
+ }, true);
88
+ return;
89
+ }
90
+ let data;
91
+ try {
92
+ req.params = match.params;
93
+ await parseReqBody(req, res, bodyParserOptions);
94
+ if (!MATCHED_ROUTES_CACHE.has(pathname)) {
95
+ MATCHED_ROUTES_CACHE.set(pathname, match);
96
+ }
97
+ await runMiddlewares(req, res, match.route, routesMap);
98
+ // If the response has already been ended, skip the loader and return early
99
+ if (res.raw.writableEnded) {
100
+ return;
101
+ }
102
+ const loaderPath = routesMap[match.route].loader;
103
+ if (loaderPath) {
104
+ const mod = await import(pathToFileURL(loaderPath).href);
105
+ const handler = mod[method];
106
+ if (typeof handler !== "function") {
107
+ if (method !== "GET") {
108
+ res.status(405);
109
+ res.raw.end();
110
+ return;
111
+ }
112
+ }
113
+ else {
114
+ data = await handler(req, res);
115
+ }
116
+ if (res.raw.writableEnded) {
117
+ return;
118
+ }
119
+ }
120
+ else {
121
+ // Return 405 for non-GET requests if no loader is found
122
+ if (method !== "GET") {
123
+ res.status(405);
124
+ res.raw.end();
125
+ return;
126
+ }
127
+ }
128
+ }
129
+ catch (err) {
130
+ if (err instanceof HttpError) {
131
+ handleHttpError({
132
+ res,
133
+ mutor,
134
+ isHtmxReq,
135
+ pathname,
136
+ routesMap,
137
+ routes: sortedRoutes,
138
+ data: err.meta,
139
+ code: err.code,
140
+ error: err,
141
+ });
142
+ return;
143
+ }
144
+ if (err instanceof NotFoundError) {
145
+ handleNotFound({
146
+ res,
147
+ req,
148
+ mutor,
149
+ isHtmxReq,
150
+ pathname,
151
+ routesMap,
152
+ routes: sortedRoutes,
153
+ data: err.meta,
154
+ error: err,
155
+ });
156
+ return;
157
+ }
158
+ const boundaryKey = isHtmxReq ? "fragmentError" : "error";
159
+ const nearestError = findClosestBoundary(pathname, boundaryKey, sortedRoutes, routesMap);
160
+ if (!nearestError?.paths?.[boundaryKey]) {
161
+ res.status(500);
162
+ res.raw.end();
163
+ return;
164
+ }
165
+ const html = mutor.renderFile(nearestError.paths[boundaryKey], {
166
+ error: err,
167
+ pathname,
168
+ });
169
+ res.status(500).html(html);
170
+ return;
171
+ }
172
+ if (isHtmxReq) {
173
+ const fragmentPath = routesMap[match.route].fragment;
174
+ if (!fragmentPath) {
175
+ res.status(200);
176
+ res.raw.end();
177
+ return;
178
+ }
179
+ const html = mutor.renderFile(fragmentPath, {
180
+ data,
181
+ isHtmxReq,
182
+ url: pathname,
183
+ });
184
+ res.status(200).html(html);
185
+ return;
186
+ }
187
+ const pagePath = routesMap[match.route].page;
188
+ if (!pagePath) {
189
+ res.raw.end();
190
+ return;
191
+ }
192
+ const html = mutor.renderFile(pagePath, {
193
+ data,
194
+ url: pathname,
195
+ });
196
+ res.status(200).html(html);
197
+ };
198
+ }
199
+ //# sourceMappingURL=lynnix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lynnix.js","sourceRoot":"","sources":["../src/lynnix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import type * as http from "node:http";
10
+ import LynnixRequest from "./lynnixRequest.js";
11
+ export default function augmentRequest(req: http.IncomingMessage): Promise<LynnixRequest>;
12
+ //# sourceMappingURL=augmentRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"augmentRequest.d.ts","sourceRoot":"","sources":["../../src/utils/augmentRequest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAQ/C,wBAA8B,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,0BAmBrE"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import LynnixRequest from "./lynnixRequest.js";
10
+ let cookieParserPromise = null;
11
+ let qsParserPromise = null;
12
+ export default async function augmentRequest(req) {
13
+ const augmentedRequest = new LynnixRequest(req);
14
+ const baseUrl = `http://${req.headers.host ?? "localhost"}`;
15
+ const cookieParser = await loadCookieParser();
16
+ augmentedRequest.cookies = cookieParser
17
+ ? cookieParser(req.headers.cookie ?? "")
18
+ : {};
19
+ augmentedRequest.isHtmx = req.headers["hx-request"] === "true";
20
+ augmentedRequest.htmx = Object.fromEntries(Object.entries(req.headers).filter(([k]) => k.startsWith("hx-")));
21
+ augmentedRequest.query = await parseQueryString(new URL(req.url ?? "", baseUrl).search.slice(1));
22
+ augmentedRequest.body = {};
23
+ augmentedRequest.files = {};
24
+ return augmentedRequest;
25
+ }
26
+ async function parseQueryString(queryString) {
27
+ if (!queryString) {
28
+ return {};
29
+ }
30
+ const qsParser = await loadQsParser();
31
+ if (qsParser) {
32
+ return qsParser(queryString);
33
+ }
34
+ const params = new URLSearchParams(queryString);
35
+ const result = {};
36
+ for (const [key, value] of params.entries()) {
37
+ const existing = result[key];
38
+ if (typeof existing === "undefined") {
39
+ result[key] = value;
40
+ continue;
41
+ }
42
+ if (Array.isArray(existing)) {
43
+ existing.push(value);
44
+ continue;
45
+ }
46
+ result[key] = [existing, value];
47
+ }
48
+ return result;
49
+ }
50
+ async function loadCookieParser() {
51
+ if (!cookieParserPromise) {
52
+ cookieParserPromise = import("cookie")
53
+ .then((mod) => mod.parse.bind(mod))
54
+ .catch(() => null);
55
+ }
56
+ return cookieParserPromise;
57
+ }
58
+ async function loadQsParser() {
59
+ if (!qsParserPromise) {
60
+ qsParserPromise = import("qs")
61
+ .then((mod) => mod.default.parse.bind(mod.default))
62
+ .catch(() => null);
63
+ }
64
+ return qsParserPromise;
65
+ }
66
+ //# sourceMappingURL=augmentRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"augmentRequest.js","sourceRoot":"","sources":["../../src/utils/augmentRequest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import type * as http from "node:http";
10
+ import LynnixResponse from "./lynnixResponse.js";
11
+ /**
12
+ * Augments the response object with utility methods.
13
+ *
14
+ * @param res The raw response object
15
+ */
16
+ export default function augmentResponse(res: http.ServerResponse<http.IncomingMessage>, isHtmx: boolean): Promise<LynnixResponse>;
17
+ //# sourceMappingURL=augmentResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"augmentResponse.d.ts","sourceRoot":"","sources":["../../src/utils/augmentResponse.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC,OAAO,cAAqC,MAAM,qBAAqB,CAAC;AAIxE;;;;GAIG;AACH,wBAA8B,eAAe,CAC5C,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,EAC9C,MAAM,EAAE,OAAO,2BAMf"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import LynnixResponse from "./lynnixResponse.js";
10
+ let cookieModulePromise = null;
11
+ /**
12
+ * Augments the response object with utility methods.
13
+ *
14
+ * @param res The raw response object
15
+ */
16
+ export default async function augmentResponse(res, isHtmx) {
17
+ const cookieModule = await loadCookieModule();
18
+ const responseCookies = readResponseCookies(res, cookieModule);
19
+ return new LynnixResponse(res, isHtmx, cookieModule, responseCookies);
20
+ }
21
+ function normalizeSetCookieHeader(header) {
22
+ if (Array.isArray(header)) {
23
+ return header.filter((value) => typeof value === "string");
24
+ }
25
+ if (typeof header === "string") {
26
+ return [header];
27
+ }
28
+ return [];
29
+ }
30
+ function readResponseCookies(res, cookieModule) {
31
+ const cookies = {};
32
+ const existingHeaders = normalizeSetCookieHeader(res.getHeader("Set-Cookie"));
33
+ if (!cookieModule) {
34
+ return cookies;
35
+ }
36
+ for (let i = 0; i < existingHeaders.length; i++) {
37
+ try {
38
+ const parsed = cookieModule.parseSetCookie(existingHeaders[i]);
39
+ cookies[parsed.name] = parsed.value;
40
+ }
41
+ catch { }
42
+ }
43
+ return cookies;
44
+ }
45
+ async function loadCookieModule() {
46
+ if (!cookieModulePromise) {
47
+ cookieModulePromise = import("cookie")
48
+ .then((mod) => ({
49
+ serialize: mod.serialize.bind(mod),
50
+ parseSetCookie: mod.parseSetCookie.bind(mod),
51
+ }))
52
+ .catch(() => null);
53
+ }
54
+ return cookieModulePromise;
55
+ }
56
+ //# sourceMappingURL=augmentResponse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"augmentResponse.js","sourceRoot":"","sources":["../../src/utils/augmentResponse.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,cAAqC,MAAM,qBAAqB,CAAC;AAExE,IAAI,mBAAmB,GAAwC,IAAI,CAAC;AAEpE;;;;GAIG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,eAAe,CAC5C,GAA8C,EAC9C,MAAe;IAEf,MAAM,YAAY,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,mBAAmB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAE/D,OAAO,IAAI,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,wBAAwB,CAChC,MAA8C;IAE9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,EAAE,CAAC;AACX,CAAC;AAED,SAAS,mBAAmB,CAC3B,GAA8C,EAC9C,YAAiC;IAEjC,MAAM,OAAO,GAAG,EAAa,CAAC;IAC9B,MAAM,eAAe,GAAG,wBAAwB,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IAE9E,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjD,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,gBAAgB;IAC9B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC1B,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC;aACpC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACf,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YAClC,cAAc,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;SAC5C,CAAC,CAAC;aACF,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,mBAAmB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import type { RoutesMap } from "../types.js";
10
+ /**
11
+ * Builds a file tree from the given path, recursively traversing directories and mapping file names to their full paths.
12
+ *
13
+ * @param path The root directory to build the file tree from.
14
+ * @param baseRoute The base route for the file tree.
15
+ * @param cache The cache to store the file tree.
16
+ * @returns The file tree.
17
+ */
18
+ export default function buildRoutes(path: string, baseRoute?: string, cache?: RoutesMap): Promise<RoutesMap>;
19
+ //# sourceMappingURL=buildRoutesMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildRoutesMap.d.ts","sourceRoot":"","sources":["../../src/utils/buildRoutesMap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAe7C;;;;;;;GAOG;AACH,wBAA8B,WAAW,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,SAAM,EACf,KAAK,GAAE,SAAc,GACnB,OAAO,CAAC,SAAS,CAAC,CAsBpB"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import { readdir } from "node:fs/promises";
10
+ import { resolve } from "node:path";
11
+ const FILE_MAP = {
12
+ "page.html": "page",
13
+ "fragment.html": "fragment",
14
+ "loader.js": "loader",
15
+ "loader.ts": "loader",
16
+ "error.html": "error",
17
+ "not-found.html": "notFound",
18
+ "fragment.not-found.html": "fragmentNotFound",
19
+ "fragment.error.html": "fragmentError",
20
+ "middleware.ts": "middleware",
21
+ "middleware.js": "middleware",
22
+ };
23
+ /**
24
+ * Builds a file tree from the given path, recursively traversing directories and mapping file names to their full paths.
25
+ *
26
+ * @param path The root directory to build the file tree from.
27
+ * @param baseRoute The base route for the file tree.
28
+ * @param cache The cache to store the file tree.
29
+ * @returns The file tree.
30
+ */
31
+ export default async function buildRoutes(path, baseRoute = "/", cache = {}) {
32
+ for (const entry of await readdir(path, { withFileTypes: true })) {
33
+ const fullPath = resolve(path, entry.name);
34
+ if (entry.isDirectory()) {
35
+ await buildRoutes(fullPath, `${baseRoute}/${entry.name}`, cache);
36
+ continue;
37
+ }
38
+ const key = FILE_MAP[entry.name];
39
+ if (!key) {
40
+ continue;
41
+ }
42
+ const parsedBaseRoute = baseRoute.replace(/^\/\//, "/");
43
+ cache[parsedBaseRoute] ?? (cache[parsedBaseRoute] = {});
44
+ cache[parsedBaseRoute][key] = fullPath;
45
+ }
46
+ return cache;
47
+ }
48
+ //# sourceMappingURL=buildRoutesMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildRoutesMap.js","sourceRoot":"","sources":["../../src/utils/buildRoutesMap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,QAAQ,GAAG;IAChB,WAAW,EAAE,MAAM;IACnB,eAAe,EAAE,UAAU;IAC3B,WAAW,EAAE,QAAQ;IACrB,WAAW,EAAE,QAAQ;IACrB,YAAY,EAAE,OAAO;IACrB,gBAAgB,EAAE,UAAU;IAC5B,yBAAyB,EAAE,kBAAkB;IAC7C,qBAAqB,EAAE,eAAe;IACtC,eAAe,EAAE,YAAY;IAC7B,eAAe,EAAE,YAAY;CACpB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,WAAW,CACxC,IAAY,EACZ,SAAS,GAAG,GAAG,EACf,QAAmB,EAAE;IAErB,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAClE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,WAAW,CAAC,QAAQ,EAAE,GAAG,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACjE,SAAS;QACV,CAAC;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,IAA6B,CAAC,CAAC;QAE1D,IAAI,CAAC,GAAG,EAAE,CAAC;YACV,SAAS;QACV,CAAC;QAED,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAExD,KAAK,CAAC,eAAe,MAArB,KAAK,CAAC,eAAe,IAAM,EAAE,EAAC;QAC9B,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IACxC,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ export declare class NotFoundError {
10
+ meta?: unknown;
11
+ constructor(meta?: unknown);
12
+ }
13
+ export declare class HttpError {
14
+ code: number;
15
+ meta?: unknown;
16
+ constructor(code: number, meta?: unknown);
17
+ }
18
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,aAAa;IACN,IAAI,CAAC,EAAE,OAAO;gBAAd,IAAI,CAAC,EAAE,OAAO;CACjC;AAED,qBAAa,SAAS;IAEb,IAAI,EAAE,MAAM;IACZ,IAAI,CAAC,EAAE,OAAO;gBADd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO;CAEtB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ export class NotFoundError {
10
+ constructor(meta) {
11
+ this.meta = meta;
12
+ }
13
+ }
14
+ export class HttpError {
15
+ constructor(code, meta) {
16
+ this.code = code;
17
+ this.meta = meta;
18
+ }
19
+ }
20
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,OAAO,aAAa;IACzB,YAAmB,IAAc;QAAd,SAAI,GAAJ,IAAI,CAAU;IAAG,CAAC;CACrC;AAED,MAAM,OAAO,SAAS;IACrB,YACQ,IAAY,EACZ,IAAc;QADd,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAU;IACnB,CAAC;CACJ"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import type { BoundaryKey, RoutesMap } from "../types.js";
10
+ export default function findClosestBoundary(path: string, key: BoundaryKey, routes: string[], routesMap: RoutesMap): {
11
+ paths: RoutesMap[string];
12
+ accessedRoute: string;
13
+ } | null;
14
+ //# sourceMappingURL=findClosestBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findClosestBoundary.d.ts","sourceRoot":"","sources":["../../src/utils/findClosestBoundary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG1D,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAC1C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,SAAS,EAAE,SAAS,GAClB;IAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6B5D"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import matchRoute from "./matchRoute.js";
10
+ export default function findClosestBoundary(path, key, routes, routesMap) {
11
+ // Find the boundary at the root level if it exists
12
+ if (path === "/") {
13
+ const routeEntry = routesMap["/"];
14
+ return routeEntry?.[key] ? { paths: routeEntry, accessedRoute: "/" } : null;
15
+ }
16
+ const match = matchRoute(path, routes);
17
+ if (match) {
18
+ const matchedBoundary = routesMap[match.route][key];
19
+ // Routes are pre-sorted (static before dynamic at equal depth), so matchRoute
20
+ // will never return a dynamic sibling over a static match.
21
+ if (matchedBoundary) {
22
+ return { paths: routesMap[match.route], accessedRoute: match.route };
23
+ }
24
+ }
25
+ const routeChunks = path.split("/").filter(Boolean);
26
+ routeChunks.pop();
27
+ return findClosestBoundary(`/${routeChunks.join("/")}`, key, routes, routesMap);
28
+ }
29
+ //# sourceMappingURL=findClosestBoundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findClosestBoundary.js","sourceRoot":"","sources":["../../src/utils/findClosestBoundary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAC1C,IAAY,EACZ,GAAgB,EAChB,MAAgB,EAChB,SAAoB;IAEpB,mDAAmD;IACnD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QAClB,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAEvC,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,eAAe,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;QAEpD,8EAA8E;QAC9E,2DAA2D;QAC3D,IAAI,eAAe,EAAE,CAAC;YACrB,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QACtE,CAAC;IACF,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEpD,WAAW,CAAC,GAAG,EAAE,CAAC;IAElB,OAAO,mBAAmB,CACzB,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAC3B,GAAG,EACH,MAAM,EACN,SAAS,CACT,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import type { RoutesMap } from "../types.js";
10
+ /**
11
+ * Recursively extracts the middleware chain for a given route
12
+ *
13
+ * @param route The route to extract the middleware chain for
14
+ * @param routesMap A map of routes to middleware functions
15
+ * @param chain The middleware chain to build (default: [])
16
+ * @returns The middleware chain for the given route
17
+ */
18
+ export default function getMiddlewareChain(route: string, routesMap: RoutesMap, chain?: string[]): string[];
19
+ //# sourceMappingURL=getMiddlewareChain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMiddlewareChain.d.ts","sourceRoot":"","sources":["../../src/utils/getMiddlewareChain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACzC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,SAAS,EACpB,KAAK,GAAE,MAAM,EAAO,YAkBpB"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ /**
10
+ * Recursively extracts the middleware chain for a given route
11
+ *
12
+ * @param route The route to extract the middleware chain for
13
+ * @param routesMap A map of routes to middleware functions
14
+ * @param chain The middleware chain to build (default: [])
15
+ * @returns The middleware chain for the given route
16
+ */
17
+ export default function getMiddlewareChain(route, routesMap, chain = []) {
18
+ if (route === "/") {
19
+ if (routesMap[route]?.middleware) {
20
+ chain.unshift(routesMap[route].middleware);
21
+ }
22
+ return chain;
23
+ }
24
+ if (routesMap[route]?.middleware) {
25
+ chain.unshift(routesMap[route].middleware);
26
+ }
27
+ const routesChunks = route.split("/").filter(Boolean);
28
+ routesChunks.pop();
29
+ return getMiddlewareChain(`/${routesChunks.join("/")}`, routesMap, chain);
30
+ }
31
+ //# sourceMappingURL=getMiddlewareChain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMiddlewareChain.js","sourceRoot":"","sources":["../../src/utils/getMiddlewareChain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACzC,KAAa,EACb,SAAoB,EACpB,QAAkB,EAAE;IAEpB,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QACnB,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;YAClC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;QAClC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtD,YAAY,CAAC,GAAG,EAAE,CAAC;IAEnB,OAAO,kBAAkB,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Lynnix
3
+ * File-based hypermedia routing middleware for Node.js, Mutor.js, and HTMX.
4
+ *
5
+ * @author Onah Victor <victoronah.dev@gmail.com>
6
+ * @repository https://github.com/allAboutJS/Lynnix
7
+ * @license MIT
8
+ */
9
+ import type Mutor from "mutorjs/server";
10
+ import type { RoutesMap } from "../types.js";
11
+ import type { HttpError } from "./error.js";
12
+ import type LynnixResponse from "./lynnixResponse.js";
13
+ export declare function handleHttpError({ res, mutor, pathname, isHtmxReq, routes, routesMap, data, code, error, }: {
14
+ code: number;
15
+ error: HttpError;
16
+ res: LynnixResponse;
17
+ mutor: Mutor;
18
+ isHtmxReq: boolean;
19
+ routes: string[];
20
+ routesMap: RoutesMap;
21
+ pathname: string;
22
+ data?: unknown;
23
+ }): void;
24
+ //# sourceMappingURL=handleHttpError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handleHttpError.d.ts","sourceRoot":"","sources":["../../src/utils/handleHttpError.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AAEtD,wBAAgB,eAAe,CAAC,EAC/B,GAAG,EACH,KAAK,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAK,GACL,EAAE;IACF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CACf,QAoBA"}