litzjs 0.0.0

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.
@@ -0,0 +1,161 @@
1
+ //#region src/form-data.ts
2
+ function createFormDataPayload(payload) {
3
+ if (payload instanceof FormData) return cloneFormData(payload);
4
+ const formData = new FormData();
5
+ if (!payload) return formData;
6
+ for (const [key, value] of Object.entries(payload)) appendFormDataValue(formData, key, value);
7
+ return formData;
8
+ }
9
+ function cloneFormData(source) {
10
+ const formData = new FormData();
11
+ for (const [key, value] of source.entries()) formData.append(key, value);
12
+ return formData;
13
+ }
14
+ function appendFormDataValue(formData, key, value) {
15
+ if (Array.isArray(value)) {
16
+ for (const entry of value) appendFormDataValue(formData, key, entry);
17
+ return;
18
+ }
19
+ if (value instanceof Blob) {
20
+ formData.append(key, value);
21
+ return;
22
+ }
23
+ if (value == null) {
24
+ formData.append(key, "");
25
+ return;
26
+ }
27
+ if (typeof value === "object") {
28
+ formData.append(key, JSON.stringify(value));
29
+ return;
30
+ }
31
+ if (typeof value === "string") {
32
+ formData.append(key, value);
33
+ return;
34
+ }
35
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
36
+ formData.append(key, String(value));
37
+ return;
38
+ }
39
+ }
40
+ //#endregion
41
+ //#region src/path-matching.ts
42
+ function trimPathSegments(value) {
43
+ if (value === "/") return [];
44
+ return value.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
45
+ }
46
+ function matchPathname(routePath, pathname) {
47
+ const routeSegments = trimPathSegments(routePath);
48
+ const pathSegments = trimPathSegments(pathname);
49
+ if (routeSegments.length !== pathSegments.length) return null;
50
+ const params = {};
51
+ for (let index = 0; index < routeSegments.length; index += 1) {
52
+ const routeSegment = routeSegments[index];
53
+ const pathSegment = pathSegments[index];
54
+ if (!routeSegment || pathSegment === void 0) return null;
55
+ if (routeSegment.startsWith(":")) {
56
+ params[routeSegment.slice(1)] = decodeURIComponent(pathSegment);
57
+ continue;
58
+ }
59
+ if (routeSegment !== pathSegment) return null;
60
+ }
61
+ return params;
62
+ }
63
+ function matchPrefixPathname(routePath, pathname) {
64
+ const routeSegments = trimPathSegments(routePath);
65
+ const pathSegments = trimPathSegments(pathname);
66
+ if (routeSegments.length > pathSegments.length) return null;
67
+ const params = {};
68
+ for (let index = 0; index < routeSegments.length; index += 1) {
69
+ const routeSegment = routeSegments[index];
70
+ const pathSegment = pathSegments[index];
71
+ if (!routeSegment || pathSegment === void 0) return null;
72
+ if (routeSegment.startsWith(":")) {
73
+ params[routeSegment.slice(1)] = decodeURIComponent(pathSegment);
74
+ continue;
75
+ }
76
+ if (routeSegment !== pathSegment) return null;
77
+ }
78
+ return params;
79
+ }
80
+ function extractRouteLikeParams(pathPattern, pathname) {
81
+ return matchPrefixPathname(pathPattern, pathname) ?? matchPathname(pathPattern, pathname);
82
+ }
83
+ function comparePathSpecificity(left, right) {
84
+ const leftSegments = trimPathSegments(left);
85
+ const rightSegments = trimPathSegments(right);
86
+ if (leftSegments.length !== rightSegments.length) return rightSegments.length - leftSegments.length;
87
+ for (let index = 0; index < leftSegments.length; index += 1) {
88
+ const leftSegment = leftSegments[index] ?? "";
89
+ const rightSegment = rightSegments[index] ?? "";
90
+ const leftRank = leftSegment.startsWith(":") ? 0 : 1;
91
+ const rightRank = rightSegment.startsWith(":") ? 0 : 1;
92
+ if (leftRank !== rightRank) return rightRank - leftRank;
93
+ if (leftRank === 1 && leftSegment.length !== rightSegment.length) return rightSegment.length - leftSegment.length;
94
+ }
95
+ return left.localeCompare(right);
96
+ }
97
+ function sortByPathSpecificity(entries) {
98
+ return [...entries].sort((left, right) => comparePathSpecificity(left.path, right.path));
99
+ }
100
+ //#endregion
101
+ //#region src/internal-transport.ts
102
+ const INTERNAL_REQUEST_HEADER = "x-litzjs-request";
103
+ const LITZ_RESULT_ACCEPT = "application/vnd.litzjs.result+json, text/x-component";
104
+ function createInternalActionRequestInit(metadata, payload) {
105
+ return {
106
+ headers: new Headers({
107
+ accept: LITZ_RESULT_ACCEPT,
108
+ [INTERNAL_REQUEST_HEADER]: JSON.stringify(metadata)
109
+ }),
110
+ body: createFormDataPayload(payload)
111
+ };
112
+ }
113
+ //#endregion
114
+ Object.defineProperty(exports, "INTERNAL_REQUEST_HEADER", {
115
+ enumerable: true,
116
+ get: function() {
117
+ return INTERNAL_REQUEST_HEADER;
118
+ }
119
+ });
120
+ Object.defineProperty(exports, "LITZ_RESULT_ACCEPT", {
121
+ enumerable: true,
122
+ get: function() {
123
+ return LITZ_RESULT_ACCEPT;
124
+ }
125
+ });
126
+ Object.defineProperty(exports, "createFormDataPayload", {
127
+ enumerable: true,
128
+ get: function() {
129
+ return createFormDataPayload;
130
+ }
131
+ });
132
+ Object.defineProperty(exports, "createInternalActionRequestInit", {
133
+ enumerable: true,
134
+ get: function() {
135
+ return createInternalActionRequestInit;
136
+ }
137
+ });
138
+ Object.defineProperty(exports, "extractRouteLikeParams", {
139
+ enumerable: true,
140
+ get: function() {
141
+ return extractRouteLikeParams;
142
+ }
143
+ });
144
+ Object.defineProperty(exports, "matchPathname", {
145
+ enumerable: true,
146
+ get: function() {
147
+ return matchPathname;
148
+ }
149
+ });
150
+ Object.defineProperty(exports, "sortByPathSpecificity", {
151
+ enumerable: true,
152
+ get: function() {
153
+ return sortByPathSpecificity;
154
+ }
155
+ });
156
+ Object.defineProperty(exports, "trimPathSegments", {
157
+ enumerable: true,
158
+ get: function() {
159
+ return trimPathSegments;
160
+ }
161
+ });
@@ -0,0 +1,114 @@
1
+ //#region src/form-data.ts
2
+ function createFormDataPayload(payload) {
3
+ if (payload instanceof FormData) return cloneFormData(payload);
4
+ const formData = new FormData();
5
+ if (!payload) return formData;
6
+ for (const [key, value] of Object.entries(payload)) appendFormDataValue(formData, key, value);
7
+ return formData;
8
+ }
9
+ function cloneFormData(source) {
10
+ const formData = new FormData();
11
+ for (const [key, value] of source.entries()) formData.append(key, value);
12
+ return formData;
13
+ }
14
+ function appendFormDataValue(formData, key, value) {
15
+ if (Array.isArray(value)) {
16
+ for (const entry of value) appendFormDataValue(formData, key, entry);
17
+ return;
18
+ }
19
+ if (value instanceof Blob) {
20
+ formData.append(key, value);
21
+ return;
22
+ }
23
+ if (value == null) {
24
+ formData.append(key, "");
25
+ return;
26
+ }
27
+ if (typeof value === "object") {
28
+ formData.append(key, JSON.stringify(value));
29
+ return;
30
+ }
31
+ if (typeof value === "string") {
32
+ formData.append(key, value);
33
+ return;
34
+ }
35
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
36
+ formData.append(key, String(value));
37
+ return;
38
+ }
39
+ }
40
+ //#endregion
41
+ //#region src/path-matching.ts
42
+ function trimPathSegments(value) {
43
+ if (value === "/") return [];
44
+ return value.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
45
+ }
46
+ function matchPathname(routePath, pathname) {
47
+ const routeSegments = trimPathSegments(routePath);
48
+ const pathSegments = trimPathSegments(pathname);
49
+ if (routeSegments.length !== pathSegments.length) return null;
50
+ const params = {};
51
+ for (let index = 0; index < routeSegments.length; index += 1) {
52
+ const routeSegment = routeSegments[index];
53
+ const pathSegment = pathSegments[index];
54
+ if (!routeSegment || pathSegment === void 0) return null;
55
+ if (routeSegment.startsWith(":")) {
56
+ params[routeSegment.slice(1)] = decodeURIComponent(pathSegment);
57
+ continue;
58
+ }
59
+ if (routeSegment !== pathSegment) return null;
60
+ }
61
+ return params;
62
+ }
63
+ function matchPrefixPathname(routePath, pathname) {
64
+ const routeSegments = trimPathSegments(routePath);
65
+ const pathSegments = trimPathSegments(pathname);
66
+ if (routeSegments.length > pathSegments.length) return null;
67
+ const params = {};
68
+ for (let index = 0; index < routeSegments.length; index += 1) {
69
+ const routeSegment = routeSegments[index];
70
+ const pathSegment = pathSegments[index];
71
+ if (!routeSegment || pathSegment === void 0) return null;
72
+ if (routeSegment.startsWith(":")) {
73
+ params[routeSegment.slice(1)] = decodeURIComponent(pathSegment);
74
+ continue;
75
+ }
76
+ if (routeSegment !== pathSegment) return null;
77
+ }
78
+ return params;
79
+ }
80
+ function extractRouteLikeParams(pathPattern, pathname) {
81
+ return matchPrefixPathname(pathPattern, pathname) ?? matchPathname(pathPattern, pathname);
82
+ }
83
+ function comparePathSpecificity(left, right) {
84
+ const leftSegments = trimPathSegments(left);
85
+ const rightSegments = trimPathSegments(right);
86
+ if (leftSegments.length !== rightSegments.length) return rightSegments.length - leftSegments.length;
87
+ for (let index = 0; index < leftSegments.length; index += 1) {
88
+ const leftSegment = leftSegments[index] ?? "";
89
+ const rightSegment = rightSegments[index] ?? "";
90
+ const leftRank = leftSegment.startsWith(":") ? 0 : 1;
91
+ const rightRank = rightSegment.startsWith(":") ? 0 : 1;
92
+ if (leftRank !== rightRank) return rightRank - leftRank;
93
+ if (leftRank === 1 && leftSegment.length !== rightSegment.length) return rightSegment.length - leftSegment.length;
94
+ }
95
+ return left.localeCompare(right);
96
+ }
97
+ function sortByPathSpecificity(entries) {
98
+ return [...entries].sort((left, right) => comparePathSpecificity(left.path, right.path));
99
+ }
100
+ //#endregion
101
+ //#region src/internal-transport.ts
102
+ const INTERNAL_REQUEST_HEADER = "x-litzjs-request";
103
+ const LITZ_RESULT_ACCEPT = "application/vnd.litzjs.result+json, text/x-component";
104
+ function createInternalActionRequestInit(metadata, payload) {
105
+ return {
106
+ headers: new Headers({
107
+ accept: LITZ_RESULT_ACCEPT,
108
+ [INTERNAL_REQUEST_HEADER]: JSON.stringify(metadata)
109
+ }),
110
+ body: createFormDataPayload(payload)
111
+ };
112
+ }
113
+ //#endregion
114
+ export { matchPathname as a, createFormDataPayload as c, extractRouteLikeParams as i, LITZ_RESULT_ACCEPT as n, sortByPathSpecificity as o, createInternalActionRequestInit as r, trimPathSegments as s, INTERNAL_REQUEST_HEADER as t };
@@ -0,0 +1,35 @@
1
+ import { t as INTERNAL_REQUEST_HEADER } from "./internal-transport-dsMykcNK.mjs";
2
+ //#region src/server/internal-requests.ts
3
+ async function parseInternalRequestBody(request) {
4
+ if ((request.headers.get("content-type") ?? "").includes("application/json")) return await request.json();
5
+ const metadataHeader = request.headers.get(INTERNAL_REQUEST_HEADER);
6
+ if (!metadataHeader) return {};
7
+ const metadata = JSON.parse(metadataHeader);
8
+ if (request.method === "GET" || request.method === "HEAD") return metadata;
9
+ const formData = await request.formData();
10
+ return {
11
+ ...metadata,
12
+ payload: {
13
+ type: "form-data",
14
+ entries: Array.from(formData.entries())
15
+ }
16
+ };
17
+ }
18
+ //#endregion
19
+ //#region src/server/request-headers.ts
20
+ const INTERNAL_REQUEST_HEADER_NAMES = new Set([
21
+ "content-length",
22
+ "content-type",
23
+ "transfer-encoding",
24
+ "x-litzjs-request"
25
+ ]);
26
+ function createInternalHandlerHeaders(headers) {
27
+ const forwarded = new Headers();
28
+ headers.forEach((value, key) => {
29
+ if (INTERNAL_REQUEST_HEADER_NAMES.has(key.toLowerCase())) return;
30
+ forwarded.append(key, value);
31
+ });
32
+ return forwarded;
33
+ }
34
+ //#endregion
35
+ export { parseInternalRequestBody as n, createInternalHandlerHeaders as t };
@@ -0,0 +1,46 @@
1
+ const require_internal_transport = require("./internal-transport-DR0r68ff.js");
2
+ //#region src/server/internal-requests.ts
3
+ async function parseInternalRequestBody(request) {
4
+ if ((request.headers.get("content-type") ?? "").includes("application/json")) return await request.json();
5
+ const metadataHeader = request.headers.get(require_internal_transport.INTERNAL_REQUEST_HEADER);
6
+ if (!metadataHeader) return {};
7
+ const metadata = JSON.parse(metadataHeader);
8
+ if (request.method === "GET" || request.method === "HEAD") return metadata;
9
+ const formData = await request.formData();
10
+ return {
11
+ ...metadata,
12
+ payload: {
13
+ type: "form-data",
14
+ entries: Array.from(formData.entries())
15
+ }
16
+ };
17
+ }
18
+ //#endregion
19
+ //#region src/server/request-headers.ts
20
+ const INTERNAL_REQUEST_HEADER_NAMES = new Set([
21
+ "content-length",
22
+ "content-type",
23
+ "transfer-encoding",
24
+ "x-litzjs-request"
25
+ ]);
26
+ function createInternalHandlerHeaders(headers) {
27
+ const forwarded = new Headers();
28
+ headers.forEach((value, key) => {
29
+ if (INTERNAL_REQUEST_HEADER_NAMES.has(key.toLowerCase())) return;
30
+ forwarded.append(key, value);
31
+ });
32
+ return forwarded;
33
+ }
34
+ //#endregion
35
+ Object.defineProperty(exports, "createInternalHandlerHeaders", {
36
+ enumerable: true,
37
+ get: function() {
38
+ return createInternalHandlerHeaders;
39
+ }
40
+ });
41
+ Object.defineProperty(exports, "parseInternalRequestBody", {
42
+ enumerable: true,
43
+ get: function() {
44
+ return parseInternalRequestBody;
45
+ }
46
+ });
@@ -0,0 +1,74 @@
1
+ import { ApiRouteMethod } from "./index.mjs";
2
+
3
+ //#region src/server/index.d.ts
4
+ type Awaitable<T> = T | Promise<T>;
5
+ type MiddlewareContextValue<TContext = unknown> = {
6
+ request: Request;
7
+ params: Record<string, string>;
8
+ signal: AbortSignal;
9
+ context: TContext | undefined;
10
+ };
11
+ type MiddlewareNext<TContext = unknown, TResult = unknown> = (overrides?: {
12
+ context?: TContext | undefined;
13
+ }) => Promise<TResult>;
14
+ type MiddlewareHandler<TContext = unknown, TResult = unknown> = (context: MiddlewareContextValue<TContext>, next: MiddlewareNext<TContext, TResult>) => Awaitable<TResult>;
15
+ type LayoutModule = {
16
+ id: string;
17
+ path: string;
18
+ options?: {
19
+ layout?: LayoutModule;
20
+ loader?: (context: unknown) => Awaitable<unknown>;
21
+ middleware?: MiddlewareHandler<unknown, unknown>[];
22
+ };
23
+ };
24
+ type RouteModule = {
25
+ id: string;
26
+ path: string;
27
+ route?: {
28
+ loader?: (context: unknown) => Awaitable<unknown>;
29
+ action?: (context: unknown) => Awaitable<unknown>;
30
+ options?: {
31
+ layout?: LayoutModule;
32
+ loader?: (context: unknown) => Awaitable<unknown>;
33
+ action?: (context: unknown) => Awaitable<unknown>;
34
+ middleware?: MiddlewareHandler<unknown, unknown>[];
35
+ };
36
+ };
37
+ };
38
+ type ResourceModule = {
39
+ path: string;
40
+ resource?: {
41
+ loader?: (context: unknown) => Awaitable<unknown>;
42
+ action?: (context: unknown) => Awaitable<unknown>;
43
+ middleware?: MiddlewareHandler<unknown, unknown>[];
44
+ };
45
+ };
46
+ type ApiModule = {
47
+ path: string;
48
+ api?: {
49
+ middleware?: MiddlewareHandler<unknown, Response>[];
50
+ methods?: Partial<Record<ApiRouteMethod, (context: {
51
+ request: Request;
52
+ params: Record<string, string>;
53
+ signal: AbortSignal;
54
+ context: unknown;
55
+ }) => Promise<Response> | Response>>;
56
+ };
57
+ };
58
+ type ServerManifest = {
59
+ routes?: RouteModule[];
60
+ resources?: ResourceModule[];
61
+ apiRoutes?: ApiModule[];
62
+ };
63
+ type CreateServerOptions<TContext = unknown> = {
64
+ createContext?(request: Request): Promise<TContext> | TContext;
65
+ onError?(error: unknown, context: TContext | undefined): void;
66
+ manifest?: ServerManifest;
67
+ document?: string | ((request: Request) => Promise<Response> | Response);
68
+ assets?: (request: Request) => Promise<Response | null | undefined> | Response | null | undefined;
69
+ };
70
+ declare function createServer<TContext = unknown>(options?: CreateServerOptions<TContext>): {
71
+ fetch(request: Request): Promise<Response>;
72
+ };
73
+ //#endregion
74
+ export { CreateServerOptions, createServer };
@@ -0,0 +1,74 @@
1
+ import { ApiRouteMethod } from "./index.js";
2
+
3
+ //#region src/server/index.d.ts
4
+ type Awaitable<T> = T | Promise<T>;
5
+ type MiddlewareContextValue<TContext = unknown> = {
6
+ request: Request;
7
+ params: Record<string, string>;
8
+ signal: AbortSignal;
9
+ context: TContext | undefined;
10
+ };
11
+ type MiddlewareNext<TContext = unknown, TResult = unknown> = (overrides?: {
12
+ context?: TContext | undefined;
13
+ }) => Promise<TResult>;
14
+ type MiddlewareHandler<TContext = unknown, TResult = unknown> = (context: MiddlewareContextValue<TContext>, next: MiddlewareNext<TContext, TResult>) => Awaitable<TResult>;
15
+ type LayoutModule = {
16
+ id: string;
17
+ path: string;
18
+ options?: {
19
+ layout?: LayoutModule;
20
+ loader?: (context: unknown) => Awaitable<unknown>;
21
+ middleware?: MiddlewareHandler<unknown, unknown>[];
22
+ };
23
+ };
24
+ type RouteModule = {
25
+ id: string;
26
+ path: string;
27
+ route?: {
28
+ loader?: (context: unknown) => Awaitable<unknown>;
29
+ action?: (context: unknown) => Awaitable<unknown>;
30
+ options?: {
31
+ layout?: LayoutModule;
32
+ loader?: (context: unknown) => Awaitable<unknown>;
33
+ action?: (context: unknown) => Awaitable<unknown>;
34
+ middleware?: MiddlewareHandler<unknown, unknown>[];
35
+ };
36
+ };
37
+ };
38
+ type ResourceModule = {
39
+ path: string;
40
+ resource?: {
41
+ loader?: (context: unknown) => Awaitable<unknown>;
42
+ action?: (context: unknown) => Awaitable<unknown>;
43
+ middleware?: MiddlewareHandler<unknown, unknown>[];
44
+ };
45
+ };
46
+ type ApiModule = {
47
+ path: string;
48
+ api?: {
49
+ middleware?: MiddlewareHandler<unknown, Response>[];
50
+ methods?: Partial<Record<ApiRouteMethod, (context: {
51
+ request: Request;
52
+ params: Record<string, string>;
53
+ signal: AbortSignal;
54
+ context: unknown;
55
+ }) => Promise<Response> | Response>>;
56
+ };
57
+ };
58
+ type ServerManifest = {
59
+ routes?: RouteModule[];
60
+ resources?: ResourceModule[];
61
+ apiRoutes?: ApiModule[];
62
+ };
63
+ type CreateServerOptions<TContext = unknown> = {
64
+ createContext?(request: Request): Promise<TContext> | TContext;
65
+ onError?(error: unknown, context: TContext | undefined): void;
66
+ manifest?: ServerManifest;
67
+ document?: string | ((request: Request) => Promise<Response> | Response);
68
+ assets?: (request: Request) => Promise<Response | null | undefined> | Response | null | undefined;
69
+ };
70
+ declare function createServer<TContext = unknown>(options?: CreateServerOptions<TContext>): {
71
+ fetch(request: Request): Promise<Response>;
72
+ };
73
+ //#endregion
74
+ export { CreateServerOptions, createServer };