@aura-stack/router 0.1.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,233 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/router.ts
21
+ var router_exports = {};
22
+ __export(router_exports, {
23
+ createRouter: () => createRouter
24
+ });
25
+ module.exports = __toCommonJS(router_exports);
26
+
27
+ // src/assert.ts
28
+ var supportedBodyMethods = ["POST", "PUT", "PATCH"];
29
+ var isSupportedBodyMethod = (method) => {
30
+ return supportedBodyMethods.includes(method);
31
+ };
32
+
33
+ // src/error.ts
34
+ var statusCode = {
35
+ OK: 200,
36
+ CREATED: 201,
37
+ ACCEPTED: 202,
38
+ NO_CONTENT: 204,
39
+ MULTIPLE_CHOICES: 300,
40
+ MOVED_PERMANENTLY: 301,
41
+ FOUND: 302,
42
+ SEE_OTHER: 303,
43
+ NOT_MODIFIED: 304,
44
+ TEMPORARY_REDIRECT: 307,
45
+ BAD_REQUEST: 400,
46
+ UNAUTHORIZED: 401,
47
+ PAYMENT_REQUIRED: 402,
48
+ FORBIDDEN: 403,
49
+ NOT_FOUND: 404,
50
+ METHOD_NOT_ALLOWED: 405,
51
+ NOT_ACCEPTABLE: 406,
52
+ PROXY_AUTHENTICATION_REQUIRED: 407,
53
+ UNPROCESSABLE_ENTITY: 422,
54
+ INTERNAL_SERVER_ERROR: 500,
55
+ NOT_IMPLEMENTED: 501,
56
+ BAD_GATEWAY: 502,
57
+ SERVICE_UNAVAILABLE: 503,
58
+ HTTP_VERSION_NOT_SUPPORTED: 505
59
+ };
60
+ var statusText = Object.entries(statusCode).reduce(
61
+ (previous, [status, code]) => {
62
+ return { ...previous, [code]: status };
63
+ },
64
+ {}
65
+ );
66
+ var AuraStackRouterError = class extends Error {
67
+ constructor(type, message, name) {
68
+ super(message);
69
+ this.name = name ?? "AuraStackRouterError";
70
+ this.status = statusCode[type];
71
+ this.statusText = statusText[this.status];
72
+ }
73
+ };
74
+
75
+ // src/endpoint.ts
76
+ var createRoutePattern = (route) => {
77
+ const pattern = route.replace(/:[^/]+/g, "([^/]+)").replace(/\//g, "\\/");
78
+ return new RegExp(`^${pattern}$`);
79
+ };
80
+
81
+ // src/context.ts
82
+ var getRouteParams = (route, path) => {
83
+ const routeRegex = createRoutePattern(route);
84
+ if (!routeRegex.test(path)) {
85
+ throw new AuraStackRouterError("BAD_REQUEST", `Missing required route params for route: ${route}`);
86
+ }
87
+ const params = routeRegex.exec(route)?.slice(1).map((seg) => seg.replace(":", ""));
88
+ if (!params) return {};
89
+ const values = routeRegex.exec(path)?.slice(1);
90
+ return params.reduce(
91
+ (previous, now, idx) => ({
92
+ ...previous,
93
+ [now]: decodeURIComponent(values?.[idx] ?? "")
94
+ }),
95
+ {}
96
+ );
97
+ };
98
+ var getSearchParams = (url, config) => {
99
+ const route = new URL(url);
100
+ if (config.schemas?.searchParams) {
101
+ const parsed = config.schemas.searchParams.safeParse(Object.fromEntries(route.searchParams.entries()));
102
+ if (!parsed.success) {
103
+ throw new AuraStackRouterError("UNPROCESSABLE_ENTITY", "Invalid search parameters");
104
+ }
105
+ return parsed.data;
106
+ }
107
+ return new URLSearchParams(route.searchParams.toString());
108
+ };
109
+ var getHeaders = (request) => {
110
+ return new Headers(request.headers);
111
+ };
112
+ var getBody = async (request, config) => {
113
+ if (!isSupportedBodyMethod(request.method)) {
114
+ return void 0;
115
+ }
116
+ const contentType = request.headers.get("Content-Type") ?? "";
117
+ if (contentType.includes("application/json")) {
118
+ const json = await request.json();
119
+ if (config.schemas?.body) {
120
+ const parsed = config.schemas.body.safeParse(json);
121
+ if (!parsed.success) {
122
+ throw new AuraStackRouterError("UNPROCESSABLE_ENTITY", "Invalid request body");
123
+ }
124
+ return parsed.data;
125
+ }
126
+ return json;
127
+ }
128
+ if (contentType.includes("application/x-www-form-urlencoded") || contentType.includes("multipart/form-data")) {
129
+ return await request.formData();
130
+ }
131
+ if (contentType.includes("text/")) {
132
+ return await request.text();
133
+ }
134
+ if (contentType.includes("application/octet-stream")) {
135
+ return await request.arrayBuffer();
136
+ }
137
+ if (contentType.includes("image/") || contentType.includes("video/") || contentType.includes("audio/")) {
138
+ return await request.blob();
139
+ }
140
+ return null;
141
+ };
142
+
143
+ // src/middleware.ts
144
+ var executeGlobalMiddlewares = async (request, middlewares) => {
145
+ if (!middlewares) return request;
146
+ for (const middleware of middlewares) {
147
+ if (typeof middleware !== "function") {
148
+ throw new AuraStackRouterError("BAD_REQUEST", "Global middlewares must be functions");
149
+ }
150
+ const executed = await middleware(request);
151
+ if (executed instanceof Response) {
152
+ return executed;
153
+ }
154
+ request = executed;
155
+ }
156
+ if (!request || !(request instanceof Request)) {
157
+ throw new AuraStackRouterError("BAD_REQUEST", "Global middleware must return a Request or Response object");
158
+ }
159
+ return request;
160
+ };
161
+ var executeMiddlewares = async (request, context, middlewares = []) => {
162
+ try {
163
+ let ctx = context;
164
+ for (const middleware of middlewares) {
165
+ if (typeof middleware !== "function") {
166
+ throw new AuraStackRouterError("BAD_REQUEST", "Middleware must be a function");
167
+ }
168
+ ctx = await middleware(request, ctx);
169
+ }
170
+ return ctx;
171
+ } catch {
172
+ throw new AuraStackRouterError("BAD_REQUEST", "Handler threw an error");
173
+ }
174
+ };
175
+
176
+ // src/router.ts
177
+ var createRouter = (endpoints, config = {}) => {
178
+ const server = {};
179
+ const groups = {
180
+ GET: [],
181
+ POST: [],
182
+ DELETE: [],
183
+ PUT: [],
184
+ PATCH: []
185
+ };
186
+ endpoints.forEach((endpoint) => groups[endpoint.method].push(endpoint));
187
+ for (const method in groups) {
188
+ server[method] = async (request, ctx) => {
189
+ try {
190
+ const globalRequest = await executeGlobalMiddlewares(request, config.middlewares);
191
+ if (globalRequest instanceof Response) {
192
+ return globalRequest;
193
+ }
194
+ const url = new URL(globalRequest.url);
195
+ const pathname = url.pathname;
196
+ const endpoint = groups[method].find((endpoint2) => {
197
+ const withBasePath = config.basePath ? `${config.basePath}${endpoint2.route}` : endpoint2.route;
198
+ const regex = createRoutePattern(withBasePath);
199
+ return regex.test(pathname);
200
+ });
201
+ if (endpoint) {
202
+ const withBasePath = config.basePath ? `${config.basePath}${endpoint.route}` : endpoint.route;
203
+ const body = await getBody(globalRequest, endpoint.config);
204
+ const params = getRouteParams(withBasePath, pathname);
205
+ const searchParams = getSearchParams(globalRequest.url, endpoint.config);
206
+ const headers = getHeaders(globalRequest);
207
+ const context = {
208
+ ...ctx,
209
+ params,
210
+ searchParams,
211
+ headers,
212
+ body
213
+ };
214
+ await executeMiddlewares(globalRequest, context, endpoint.config.middlewares);
215
+ return endpoint.handler(globalRequest, context);
216
+ }
217
+ return Response.json({ message: "Not Found" }, { status: 404 });
218
+ } catch (error) {
219
+ if (error instanceof AuraStackRouterError) {
220
+ const { message, status, statusText: statusText2 } = error;
221
+ console.log("StatusText: ", statusText2);
222
+ return Response.json({ message }, { status, statusText: statusText2 });
223
+ }
224
+ return Response.json({ message: "Internal Server Error" }, { status: 500 });
225
+ }
226
+ };
227
+ }
228
+ return server;
229
+ };
230
+ // Annotate the CommonJS export names for ESM import in node:
231
+ 0 && (module.exports = {
232
+ createRouter
233
+ });
@@ -0,0 +1,15 @@
1
+ import { RouteEndpoint, RouterConfig, GetHttpHandlers } from './types.cjs';
2
+ import 'zod';
3
+
4
+ /**
5
+ * Creates the entry point for the server, handling the endpoints defined in the router.
6
+ * It groups endpoints by HTTP method and matches incoming requests to the appropriate endpoint.
7
+ * It accepts an optional configuration object to set a base path and middlewares for all endpoints.
8
+ *
9
+ * @param endpoints - Array of route endpoints to be handled by the router
10
+ * @param config - Optional configuration object for the router
11
+ * @returns An object with methods corresponding to HTTP methods, each handling requests for that method
12
+ */
13
+ declare const createRouter: <const Endpoints extends RouteEndpoint[]>(endpoints: Endpoints, config?: RouterConfig) => GetHttpHandlers<Endpoints>;
14
+
15
+ export { createRouter };
@@ -0,0 +1,15 @@
1
+ import { RouteEndpoint, RouterConfig, GetHttpHandlers } from './types.js';
2
+ import 'zod';
3
+
4
+ /**
5
+ * Creates the entry point for the server, handling the endpoints defined in the router.
6
+ * It groups endpoints by HTTP method and matches incoming requests to the appropriate endpoint.
7
+ * It accepts an optional configuration object to set a base path and middlewares for all endpoints.
8
+ *
9
+ * @param endpoints - Array of route endpoints to be handled by the router
10
+ * @param config - Optional configuration object for the router
11
+ * @returns An object with methods corresponding to HTTP methods, each handling requests for that method
12
+ */
13
+ declare const createRouter: <const Endpoints extends RouteEndpoint[]>(endpoints: Endpoints, config?: RouterConfig) => GetHttpHandlers<Endpoints>;
14
+
15
+ export { createRouter };
package/dist/router.js ADDED
@@ -0,0 +1,11 @@
1
+ import {
2
+ createRouter
3
+ } from "./chunk-VBI7H3AK.js";
4
+ import "./chunk-NNCUFWPI.js";
5
+ import "./chunk-6UBPSXKR.js";
6
+ import "./chunk-ENOBC3XN.js";
7
+ import "./chunk-RVJ2F7OL.js";
8
+ import "./chunk-RFYOPPMW.js";
9
+ export {
10
+ createRouter
11
+ };
package/dist/types.cjs ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1,134 @@
1
+ import { ZodObject, z } from 'zod';
2
+
3
+ /**
4
+ * Route pattern must start with a slash and can contain parameters prefixed with a colon.
5
+ * @example
6
+ * const getUser:RoutePattern = "/users/:userId"
7
+ * const getPostsComments:RoutePattern = "/posts/:postId/comments/:commentId"
8
+ */
9
+ type RoutePattern = `/${string}`;
10
+ /**
11
+ * HTTP methods supported by the router.
12
+ */
13
+ type HTTPMethod = "GET" | "POST" | "DELETE" | "PUT" | "PATCH";
14
+ /**
15
+ * Content types supported by the router.
16
+ */
17
+ type ContentType = "application/json" | "application/x-www-form-urlencoded" | "text/plain";
18
+ type Prettify<Obj extends object> = {
19
+ [Key in keyof Obj]: Obj[Key];
20
+ } & {};
21
+ /**
22
+ * Extracts route parameters from a given route pattern through colon-prefixed segments.
23
+ * Returns an object type where keys are parameter names and values are strings.
24
+ * If no parameters are found, returns an empty object type.
25
+ *
26
+ * @example
27
+ * // Expected: { userId: string }
28
+ * type UserParams = Params<"/users/:userId">;
29
+ *
30
+ * // Expected: { postId: string; commentId: string }
31
+ * type PostCommentParams = Params<"/posts/:postId/comments/:commentId">;
32
+ *
33
+ * // Expected: {}
34
+ * type NoParams = Params<"/about">;
35
+ */
36
+ type Params<Route extends RoutePattern> = Route extends `/${string}/:${infer Param}/${infer Str}` ? Prettify<{
37
+ [K in Param]: string;
38
+ } & Params<`/${Str}`>> : Route extends `/${string}/:${infer Param}` ? Prettify<{
39
+ [K in Param]: string;
40
+ }> : Route extends `/:${infer Param}` ? Prettify<{
41
+ [K in Param]: string;
42
+ }> : {};
43
+ type GetRouteParams<T extends RoutePattern> = Params<T>;
44
+ /**
45
+ * Available schemas validation for an endpoint. It can include body and searchParams schemas.
46
+ */
47
+ interface EndpointSchemas {
48
+ body?: ZodObject<any>;
49
+ searchParams?: ZodObject<any>;
50
+ }
51
+ /**
52
+ * Configuration for an endpoint, including optional schemas for request validation and middlewares.
53
+ */
54
+ type EndpointConfig<RouteParams extends RoutePattern = RoutePattern, Schemas extends EndpointSchemas = EndpointSchemas> = Prettify<{
55
+ schemas?: Schemas;
56
+ middlewares?: MiddlewareFunction<GetRouteParams<RouteParams>, {
57
+ schemas: Schemas;
58
+ }>[];
59
+ }>;
60
+ /**
61
+ * Infer the type of search parameters from the provided value in the `EndpointConfig`.
62
+ */
63
+ type ContextSearchParams<Schemas extends EndpointConfig["schemas"]> = Schemas extends {
64
+ searchParams: ZodObject;
65
+ } ? {
66
+ searchParams: z.infer<Schemas["searchParams"]>;
67
+ } : {
68
+ searchParams: URLSearchParams;
69
+ };
70
+ /**
71
+ * Infer the type of body from the provided value in the `EndpointConfig`.
72
+ */
73
+ type ContextBody<Schemas extends EndpointConfig["schemas"]> = Schemas extends {
74
+ body: ZodObject;
75
+ } ? {
76
+ body: z.infer<Schemas["body"]>;
77
+ } : {
78
+ body: undefined;
79
+ };
80
+ /**
81
+ * Context object passed to route handlers and middlewares defined in the
82
+ * `createEndpoint/createEndpointConfig` function or globally in the `createRouter` function.
83
+ */
84
+ interface RequestContext<RouteParams = Record<string, string>, Config extends EndpointConfig = EndpointConfig> {
85
+ params: RouteParams;
86
+ headers: Headers;
87
+ body: ContextBody<Config["schemas"]>["body"];
88
+ searchParams: ContextSearchParams<Config["schemas"]>["searchParams"];
89
+ }
90
+ /**
91
+ * Global middleware function type that represent a function that runs before the route matching.
92
+ */
93
+ type GlobalMiddleware = (request: Request) => Promise<Request | Response>;
94
+ /**
95
+ * Middleware function type that represent a function that runs before the route handler
96
+ * defined in the `createEndpoint/createEndpointConfig` function or globally in the `createRouter` function.
97
+ */
98
+ type MiddlewareFunction<RouteParams = Record<string, string>, Config extends EndpointConfig = EndpointConfig> = (request: Request, ctx: Prettify<RequestContext<RouteParams, Config>>) => Promise<RequestContext<RouteParams, Config>>;
99
+ /**
100
+ * Defines a route handler function that processes an incoming request and returns a response.
101
+ * The handler receives the request object and a context containing route parameters, headers,
102
+ * and optionally validated body and search parameters based on the endpoint configuration.
103
+ */
104
+ type RouteHandler<Route extends RoutePattern, Config extends EndpointConfig> = (request: Request, ctx: Prettify<RequestContext<GetRouteParams<Route>, Config>>) => Promise<Response>;
105
+ /**
106
+ * Represents a route endpoint definition, specifying the HTTP method, route pattern,
107
+ * handler function with inferred context types, and associated configuration.
108
+ */
109
+ interface RouteEndpoint<Method extends HTTPMethod = HTTPMethod, Route extends RoutePattern = RoutePattern, Config extends EndpointConfig = EndpointConfig> {
110
+ method: Method;
111
+ route: Route;
112
+ handler: RouteHandler<Route, Config>;
113
+ config: Config;
114
+ }
115
+ /**
116
+ * Infer the HTTP methods defined in the provided array of route endpoints.
117
+ */
118
+ type InferMethod<Endpoints extends RouteEndpoint[]> = Endpoints extends unknown[] ? Endpoints[number]["method"] : "unknown";
119
+ /**
120
+ * Generates an object with HTTP methods available by the router from `createRouter` function.
121
+ * Each method is a function that takes a request and context, returning a promise of a response.
122
+ */
123
+ type GetHttpHandlers<Endpoints extends RouteEndpoint[]> = {
124
+ [Method in InferMethod<Endpoints>]: (req: Request, ctx: RequestContext) => Promise<Response>;
125
+ };
126
+ /**
127
+ * Configuration options for `createRouter` function.
128
+ */
129
+ interface RouterConfig {
130
+ basePath?: RoutePattern;
131
+ middlewares?: GlobalMiddleware[];
132
+ }
133
+
134
+ export type { ContentType, ContextBody, ContextSearchParams, EndpointConfig, EndpointSchemas, GetHttpHandlers, GetRouteParams, GlobalMiddleware, HTTPMethod, InferMethod, MiddlewareFunction, Params, Prettify, RequestContext, RouteEndpoint, RouteHandler, RoutePattern, RouterConfig };
@@ -0,0 +1,134 @@
1
+ import { ZodObject, z } from 'zod';
2
+
3
+ /**
4
+ * Route pattern must start with a slash and can contain parameters prefixed with a colon.
5
+ * @example
6
+ * const getUser:RoutePattern = "/users/:userId"
7
+ * const getPostsComments:RoutePattern = "/posts/:postId/comments/:commentId"
8
+ */
9
+ type RoutePattern = `/${string}`;
10
+ /**
11
+ * HTTP methods supported by the router.
12
+ */
13
+ type HTTPMethod = "GET" | "POST" | "DELETE" | "PUT" | "PATCH";
14
+ /**
15
+ * Content types supported by the router.
16
+ */
17
+ type ContentType = "application/json" | "application/x-www-form-urlencoded" | "text/plain";
18
+ type Prettify<Obj extends object> = {
19
+ [Key in keyof Obj]: Obj[Key];
20
+ } & {};
21
+ /**
22
+ * Extracts route parameters from a given route pattern through colon-prefixed segments.
23
+ * Returns an object type where keys are parameter names and values are strings.
24
+ * If no parameters are found, returns an empty object type.
25
+ *
26
+ * @example
27
+ * // Expected: { userId: string }
28
+ * type UserParams = Params<"/users/:userId">;
29
+ *
30
+ * // Expected: { postId: string; commentId: string }
31
+ * type PostCommentParams = Params<"/posts/:postId/comments/:commentId">;
32
+ *
33
+ * // Expected: {}
34
+ * type NoParams = Params<"/about">;
35
+ */
36
+ type Params<Route extends RoutePattern> = Route extends `/${string}/:${infer Param}/${infer Str}` ? Prettify<{
37
+ [K in Param]: string;
38
+ } & Params<`/${Str}`>> : Route extends `/${string}/:${infer Param}` ? Prettify<{
39
+ [K in Param]: string;
40
+ }> : Route extends `/:${infer Param}` ? Prettify<{
41
+ [K in Param]: string;
42
+ }> : {};
43
+ type GetRouteParams<T extends RoutePattern> = Params<T>;
44
+ /**
45
+ * Available schemas validation for an endpoint. It can include body and searchParams schemas.
46
+ */
47
+ interface EndpointSchemas {
48
+ body?: ZodObject<any>;
49
+ searchParams?: ZodObject<any>;
50
+ }
51
+ /**
52
+ * Configuration for an endpoint, including optional schemas for request validation and middlewares.
53
+ */
54
+ type EndpointConfig<RouteParams extends RoutePattern = RoutePattern, Schemas extends EndpointSchemas = EndpointSchemas> = Prettify<{
55
+ schemas?: Schemas;
56
+ middlewares?: MiddlewareFunction<GetRouteParams<RouteParams>, {
57
+ schemas: Schemas;
58
+ }>[];
59
+ }>;
60
+ /**
61
+ * Infer the type of search parameters from the provided value in the `EndpointConfig`.
62
+ */
63
+ type ContextSearchParams<Schemas extends EndpointConfig["schemas"]> = Schemas extends {
64
+ searchParams: ZodObject;
65
+ } ? {
66
+ searchParams: z.infer<Schemas["searchParams"]>;
67
+ } : {
68
+ searchParams: URLSearchParams;
69
+ };
70
+ /**
71
+ * Infer the type of body from the provided value in the `EndpointConfig`.
72
+ */
73
+ type ContextBody<Schemas extends EndpointConfig["schemas"]> = Schemas extends {
74
+ body: ZodObject;
75
+ } ? {
76
+ body: z.infer<Schemas["body"]>;
77
+ } : {
78
+ body: undefined;
79
+ };
80
+ /**
81
+ * Context object passed to route handlers and middlewares defined in the
82
+ * `createEndpoint/createEndpointConfig` function or globally in the `createRouter` function.
83
+ */
84
+ interface RequestContext<RouteParams = Record<string, string>, Config extends EndpointConfig = EndpointConfig> {
85
+ params: RouteParams;
86
+ headers: Headers;
87
+ body: ContextBody<Config["schemas"]>["body"];
88
+ searchParams: ContextSearchParams<Config["schemas"]>["searchParams"];
89
+ }
90
+ /**
91
+ * Global middleware function type that represent a function that runs before the route matching.
92
+ */
93
+ type GlobalMiddleware = (request: Request) => Promise<Request | Response>;
94
+ /**
95
+ * Middleware function type that represent a function that runs before the route handler
96
+ * defined in the `createEndpoint/createEndpointConfig` function or globally in the `createRouter` function.
97
+ */
98
+ type MiddlewareFunction<RouteParams = Record<string, string>, Config extends EndpointConfig = EndpointConfig> = (request: Request, ctx: Prettify<RequestContext<RouteParams, Config>>) => Promise<RequestContext<RouteParams, Config>>;
99
+ /**
100
+ * Defines a route handler function that processes an incoming request and returns a response.
101
+ * The handler receives the request object and a context containing route parameters, headers,
102
+ * and optionally validated body and search parameters based on the endpoint configuration.
103
+ */
104
+ type RouteHandler<Route extends RoutePattern, Config extends EndpointConfig> = (request: Request, ctx: Prettify<RequestContext<GetRouteParams<Route>, Config>>) => Promise<Response>;
105
+ /**
106
+ * Represents a route endpoint definition, specifying the HTTP method, route pattern,
107
+ * handler function with inferred context types, and associated configuration.
108
+ */
109
+ interface RouteEndpoint<Method extends HTTPMethod = HTTPMethod, Route extends RoutePattern = RoutePattern, Config extends EndpointConfig = EndpointConfig> {
110
+ method: Method;
111
+ route: Route;
112
+ handler: RouteHandler<Route, Config>;
113
+ config: Config;
114
+ }
115
+ /**
116
+ * Infer the HTTP methods defined in the provided array of route endpoints.
117
+ */
118
+ type InferMethod<Endpoints extends RouteEndpoint[]> = Endpoints extends unknown[] ? Endpoints[number]["method"] : "unknown";
119
+ /**
120
+ * Generates an object with HTTP methods available by the router from `createRouter` function.
121
+ * Each method is a function that takes a request and context, returning a promise of a response.
122
+ */
123
+ type GetHttpHandlers<Endpoints extends RouteEndpoint[]> = {
124
+ [Method in InferMethod<Endpoints>]: (req: Request, ctx: RequestContext) => Promise<Response>;
125
+ };
126
+ /**
127
+ * Configuration options for `createRouter` function.
128
+ */
129
+ interface RouterConfig {
130
+ basePath?: RoutePattern;
131
+ middlewares?: GlobalMiddleware[];
132
+ }
133
+
134
+ export type { ContentType, ContextBody, ContextSearchParams, EndpointConfig, EndpointSchemas, GetHttpHandlers, GetRouteParams, GlobalMiddleware, HTTPMethod, InferMethod, MiddlewareFunction, Params, Prettify, RequestContext, RouteEndpoint, RouteHandler, RoutePattern, RouterConfig };
package/dist/types.js ADDED
File without changes
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@aura-stack/router",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "A lightweight TypeScript library for building, managing, and validating API routes and endpoints in Node.js applications.",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./router": {
16
+ "types": "./dist/router.d.ts",
17
+ "import": "./dist/router.js",
18
+ "require": "./dist/router.cjs"
19
+ },
20
+ "./endpoint": {
21
+ "types": "./dist/endpoint.d.ts",
22
+ "import": "./dist/endpoint.js",
23
+ "require": "./dist/endpoint.cjs"
24
+ },
25
+ "./types": "./dist/types.d.ts"
26
+ },
27
+ "keywords": [
28
+ "router",
29
+ "endpoints",
30
+ "api",
31
+ "aura",
32
+ "aura stack",
33
+ "typescript",
34
+ "nodejs"
35
+ ],
36
+ "author": "Aura Stack <auraauthoss@gmail.com> | Hernan Alvarado <hernanvid123@gmail.com>",
37
+ "license": "MIT",
38
+ "devDependencies": {
39
+ "prettier": "^3.6.2",
40
+ "tsup": "^8.5.0",
41
+ "typescript": "^5.9.3",
42
+ "vitest": "^3.2.4",
43
+ "zod": "^4.1.11"
44
+ },
45
+ "scripts": {
46
+ "dev": "tsup --watch",
47
+ "build": "tsup",
48
+ "format": "prettier --write .",
49
+ "format:check": "prettier --check .",
50
+ "test": "vitest --run",
51
+ "test:watch": "vitest",
52
+ "type-check": "tsc --noEmit",
53
+ "clean": "rm -rf dist"
54
+ }
55
+ }