tagliatelle 1.0.0-beta.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.d.ts","sourceRoot":"","sources":["../src/jsx-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEtE;;GAEG;AACH,eAAO,MAAM,QAAQ,eAAqC,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,eAAe,CAAA;CAAE,EAC/D,IAAI,CAAC,EAAE,MAAM,GACZ,kBAAkB,CAapB;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAClB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,EACjE,IAAI,CAAC,EAAE,MAAM,GACZ,kBAAkB,CAWpB;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,YAAM,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 🍝 JSX Runtime for <Tag>liatelle.js
3
+ *
4
+ * This provides the modern JSX transform runtime (React 17+ style).
5
+ * TypeScript/esbuild/tsx will automatically import from here when using:
6
+ * { "jsx": "react-jsx", "jsxImportSource": "tagliatelle" }
7
+ */
8
+ /**
9
+ * Fragment component - groups children without a wrapper
10
+ */
11
+ export const Fragment = Symbol.for('tagliatelle.fragment');
12
+ /**
13
+ * JSX runtime function for production
14
+ * Called for elements with a single child or no children
15
+ */
16
+ export function jsx(type, props, _key) {
17
+ const { children, ...restProps } = props || {};
18
+ // Normalize children to array
19
+ const childArray = children !== undefined
20
+ ? (Array.isArray(children) ? children : [children])
21
+ : [];
22
+ return {
23
+ type: type,
24
+ props: restProps,
25
+ children: childArray.flat().filter(c => c != null && c !== false && c !== true),
26
+ };
27
+ }
28
+ /**
29
+ * JSX runtime function for elements with multiple static children
30
+ * Same as jsx but called when there are multiple children
31
+ */
32
+ export function jsxs(type, props, _key) {
33
+ const { children, ...restProps } = props || {};
34
+ // Children is already an array for jsxs
35
+ const childArray = children || [];
36
+ return {
37
+ type: type,
38
+ props: restProps,
39
+ children: childArray.flat().filter(c => c != null && c !== false && c !== true),
40
+ };
41
+ }
42
+ /**
43
+ * JSX dev runtime function (same as jsx for our purposes)
44
+ */
45
+ export const jsxDEV = jsx;
46
+ //# sourceMappingURL=jsx-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.js","sourceRoot":"","sources":["../src/jsx-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAE3D;;;GAGG;AACH,MAAM,UAAU,GAAG,CACjB,IAAgC,EAChC,KAA+D,EAC/D,IAAa;IAEb,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;IAE/C,8BAA8B;IAC9B,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS;QACvC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;QACL,IAAI,EAAE,IAAyB;QAC/B,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;KAChF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAClB,IAAgC,EAChC,KAAiE,EACjE,IAAa;IAEb,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;IAE/C,wCAAwC;IACxC,MAAM,UAAU,GAAG,QAAQ,IAAI,EAAE,CAAC;IAElC,OAAO;QACL,IAAI,EAAE,IAAyB;QAC/B,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;KAChF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * 🍝 <Tag>liatelle.js - File-Based Router
3
+ *
4
+ * file routing for your API.
5
+ *
6
+ * routes/
7
+ * ├── _config.tsx → JSX Config for all routes
8
+ * ├── health.tsx → GET /health
9
+ * ├── posts/
10
+ * │ ├── _config.tsx → JSX Config for /posts/* (overrides parent)
11
+ * │ ├── index.tsx → GET/POST /posts
12
+ * │ └── [id].tsx → GET/PUT/DELETE /posts/:id
13
+ */
14
+ import type { FastifyInstance } from 'fastify';
15
+ import type { Handler, MiddlewareFunction, CorsConfig } from './types.js';
16
+ export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
17
+ export interface ParsedConfig {
18
+ middleware: MiddlewareFunction[];
19
+ cors?: boolean | CorsConfig;
20
+ rateLimit?: {
21
+ max: number;
22
+ timeWindow: string;
23
+ };
24
+ logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent';
25
+ prefix?: string;
26
+ }
27
+ export interface RouteModule {
28
+ GET?: Handler;
29
+ POST?: Handler;
30
+ PUT?: Handler;
31
+ DELETE?: Handler;
32
+ PATCH?: Handler;
33
+ HEAD?: Handler;
34
+ OPTIONS?: Handler;
35
+ middleware?: MiddlewareFunction | MiddlewareFunction[];
36
+ }
37
+ export interface RouteInfo {
38
+ filePath: string;
39
+ urlPath: string;
40
+ methods: HTTPMethod[];
41
+ config: ParsedConfig;
42
+ }
43
+ export interface RouterOptions {
44
+ routesDir: string;
45
+ prefix?: string;
46
+ middleware?: MiddlewareFunction[];
47
+ }
48
+ export declare function registerRoutes(fastify: FastifyInstance, options: RouterOptions, context: {
49
+ get: <T>(key: string) => T | undefined;
50
+ set: <T>(key: string, value: T) => void;
51
+ }): Promise<RouteInfo[]>;
52
+ export declare function createRouter(options: RouterOptions): {
53
+ register: (fastify: FastifyInstance, context: {
54
+ get: <T>(key: string) => T | undefined;
55
+ set: <T>(key: string, value: T) => void;
56
+ }) => Promise<RouteInfo[]>;
57
+ };
58
+ export default createRouter;
59
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAgB,UAAU,EAAE,MAAM,YAAY,CAAC;AAyCxF,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5B,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,CAAC;CACxD;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAocD,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE;IAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;CAAE,GAC3F,OAAO,CAAC,SAAS,EAAE,CAAC,CA4FtB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa;wBAErB,eAAe,WAAW;QAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;QAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;KAAE;EAI1I;AAED,eAAe,YAAY,CAAC"}
package/dist/router.js ADDED
@@ -0,0 +1,487 @@
1
+ /**
2
+ * 🍝 <Tag>liatelle.js - File-Based Router
3
+ *
4
+ * file routing for your API.
5
+ *
6
+ * routes/
7
+ * ├── _config.tsx → JSX Config for all routes
8
+ * ├── health.tsx → GET /health
9
+ * ├── posts/
10
+ * │ ├── _config.tsx → JSX Config for /posts/* (overrides parent)
11
+ * │ ├── index.tsx → GET/POST /posts
12
+ * │ └── [id].tsx → GET/PUT/DELETE /posts/:id
13
+ */
14
+ import { promises as fs } from 'node:fs';
15
+ import path from 'node:path';
16
+ import { pathToFileURL } from 'node:url';
17
+ import { COMPONENT_TYPES } from './types.js';
18
+ import { safeMerge, sanitizeErrorMessage, withTimeout } from './security.js';
19
+ import { Fragment } from './jsx-runtime.js';
20
+ // ═══════════════════════════════════════════════════════════════════════════
21
+ // 🎨 CONSOLE COLORS
22
+ // ═══════════════════════════════════════════════════════════════════════════
23
+ const c = {
24
+ reset: '\x1b[0m',
25
+ bold: '\x1b[1m',
26
+ dim: '\x1b[2m',
27
+ green: '\x1b[32m',
28
+ yellow: '\x1b[33m',
29
+ blue: '\x1b[34m',
30
+ cyan: '\x1b[36m',
31
+ white: '\x1b[37m',
32
+ red: '\x1b[91m',
33
+ brightGreen: '\x1b[92m',
34
+ brightYellow: '\x1b[93m',
35
+ brightBlue: '\x1b[94m',
36
+ brightCyan: '\x1b[96m',
37
+ };
38
+ const methodColor = (method) => {
39
+ switch (method) {
40
+ case 'GET': return c.brightGreen;
41
+ case 'POST': return c.brightYellow;
42
+ case 'PUT': return c.brightBlue;
43
+ case 'PATCH': return c.brightCyan;
44
+ case 'DELETE': return c.red;
45
+ default: return c.white;
46
+ }
47
+ };
48
+ // ═══════════════════════════════════════════════════════════════════════════
49
+ // 🔧 PATH UTILITIES
50
+ // ═══════════════════════════════════════════════════════════════════════════
51
+ function filePathToUrlPath(filePath, routesDir) {
52
+ let relativePath = path.relative(routesDir, filePath);
53
+ relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
54
+ relativePath = relativePath.replace(/\/index$/, '').replace(/^index$/, '');
55
+ relativePath = relativePath.replace(/\[\.\.\.(\w+)\]/g, '*');
56
+ relativePath = relativePath.replace(/\[(\w+)\]/g, ':$1');
57
+ const urlPath = '/' + relativePath;
58
+ return urlPath.replace(/\/+/g, '/').replace(/\/$/, '') || '/';
59
+ }
60
+ function isRouteFile(filePath) {
61
+ const fileName = path.basename(filePath);
62
+ return (/\.(tsx?|jsx?)$/.test(filePath) &&
63
+ !filePath.includes('.test.') &&
64
+ !filePath.includes('.spec.') &&
65
+ !fileName.startsWith('_'));
66
+ }
67
+ function isConfigFile(fileName) {
68
+ return /^_config\.(tsx?|jsx?)$/.test(fileName);
69
+ }
70
+ // ═══════════════════════════════════════════════════════════════════════════
71
+ // 🔍 JSX CONFIG PARSER
72
+ // ═══════════════════════════════════════════════════════════════════════════
73
+ /**
74
+ * Parse JSX config components into a ParsedConfig object
75
+ */
76
+ function parseJSXConfig(element) {
77
+ const config = {
78
+ middleware: []
79
+ };
80
+ function processNode(node) {
81
+ if (!node)
82
+ return;
83
+ // Handle arrays (fragments)
84
+ if (Array.isArray(node)) {
85
+ node.forEach(processNode);
86
+ return;
87
+ }
88
+ // Check if this is a JSX element
89
+ if (typeof node === 'object' && node !== null && 'type' in node) {
90
+ const el = node;
91
+ // Handle Fragment (from new JSX runtime) - just process children
92
+ const elType = el.type;
93
+ if (elType === Fragment || (typeof elType === 'symbol' && String(elType).includes('fragment'))) {
94
+ if (el.children) {
95
+ el.children.forEach(child => processNode(child));
96
+ }
97
+ return;
98
+ }
99
+ // Handle function components - call them to get the resolved value
100
+ if (typeof el.type === 'function') {
101
+ const props = { ...el.props, children: el.children };
102
+ const componentFn = el.type;
103
+ const resolved = componentFn(props);
104
+ // If resolution returned an array, process each item
105
+ if (Array.isArray(resolved)) {
106
+ resolved.forEach(processNode);
107
+ return;
108
+ }
109
+ // Process the resolved component
110
+ processNode(resolved);
111
+ return;
112
+ }
113
+ }
114
+ // Resolve JSX elements (legacy path for classic runtime)
115
+ let resolved = node;
116
+ // Process TagliatelleComponent
117
+ if (typeof resolved === 'object' && resolved !== null && '__tagliatelle' in resolved) {
118
+ const component = resolved;
119
+ switch (component.__tagliatelle) {
120
+ case COMPONENT_TYPES.LOGGER:
121
+ config.logLevel = component.level;
122
+ break;
123
+ case COMPONENT_TYPES.MIDDLEWARE:
124
+ if (component.use) {
125
+ config.middleware.push(component.use);
126
+ }
127
+ break;
128
+ case COMPONENT_TYPES.RATE_LIMITER:
129
+ config.rateLimit = {
130
+ max: component.max,
131
+ timeWindow: component.timeWindow
132
+ };
133
+ break;
134
+ case COMPONENT_TYPES.GROUP:
135
+ if (component.prefix) {
136
+ config.prefix = (config.prefix || '') + component.prefix;
137
+ }
138
+ break;
139
+ }
140
+ // Process children
141
+ if (component.children) {
142
+ component.children.forEach(processNode);
143
+ }
144
+ }
145
+ }
146
+ processNode(element);
147
+ return config;
148
+ }
149
+ async function scanDirectory(dir, routesDir) {
150
+ const result = { routes: [], configs: new Map() };
151
+ try {
152
+ const entries = await fs.readdir(dir, { withFileTypes: true });
153
+ for (const entry of entries) {
154
+ const fullPath = path.join(dir, entry.name);
155
+ if (entry.isDirectory()) {
156
+ const subResult = await scanDirectory(fullPath, routesDir);
157
+ result.routes.push(...subResult.routes);
158
+ subResult.configs.forEach((v, k) => result.configs.set(k, v));
159
+ }
160
+ else if (entry.isFile()) {
161
+ if (isConfigFile(entry.name)) {
162
+ result.configs.set(dir, fullPath);
163
+ }
164
+ else if (isRouteFile(entry.name)) {
165
+ result.routes.push(fullPath);
166
+ }
167
+ }
168
+ }
169
+ }
170
+ catch (error) {
171
+ const err = error;
172
+ if (err.code !== 'ENOENT')
173
+ throw error;
174
+ }
175
+ return result;
176
+ }
177
+ async function loadModule(filePath) {
178
+ const fileUrl = pathToFileURL(filePath).href;
179
+ return await import(fileUrl);
180
+ }
181
+ function getConfigChain(routeDir, routesDir, configs) {
182
+ const chain = [];
183
+ let current = routeDir;
184
+ while (current.startsWith(routesDir) || current === routesDir) {
185
+ const configPath = configs.get(current);
186
+ if (configPath) {
187
+ chain.unshift(configPath);
188
+ }
189
+ const parent = path.dirname(current);
190
+ if (parent === current)
191
+ break;
192
+ current = parent;
193
+ }
194
+ return chain;
195
+ }
196
+ function mergeConfigs(configs, baseMiddleware) {
197
+ const resolved = {
198
+ middleware: [...baseMiddleware],
199
+ prefix: ''
200
+ };
201
+ for (const config of configs) {
202
+ // Middleware is additive
203
+ resolved.middleware.push(...config.middleware);
204
+ // Rate limit overrides
205
+ if (config.rateLimit) {
206
+ resolved.rateLimit = config.rateLimit;
207
+ }
208
+ // Log level overrides
209
+ if (config.logLevel) {
210
+ resolved.logLevel = config.logLevel;
211
+ }
212
+ // Prefix is additive
213
+ if (config.prefix) {
214
+ resolved.prefix = (resolved.prefix || '') + config.prefix;
215
+ }
216
+ // CORS overrides
217
+ if (config.cors !== undefined) {
218
+ resolved.cors = config.cors;
219
+ }
220
+ }
221
+ return resolved;
222
+ }
223
+ function resolveMiddlewareResult(result) {
224
+ const resolved = { halt: false };
225
+ // Check if it's a JSX element that needs resolution
226
+ let component = result;
227
+ if (typeof result === 'object' && result !== null && 'type' in result && typeof result.type === 'function') {
228
+ const el = result;
229
+ const props = { ...el.props, children: el.children };
230
+ const componentFn = el.type;
231
+ component = componentFn(props);
232
+ }
233
+ // Check for TagliatelleComponent
234
+ if (typeof component === 'object' && component !== null && '__tagliatelle' in component) {
235
+ const comp = component;
236
+ switch (comp.__tagliatelle) {
237
+ case COMPONENT_TYPES.AUGMENT:
238
+ resolved.augment = comp.data;
239
+ break;
240
+ case COMPONENT_TYPES.HALT:
241
+ resolved.halt = true;
242
+ if (comp.code || comp.message) {
243
+ resolved.error = {
244
+ code: comp.code ?? 500,
245
+ message: comp.message ?? 'Request halted'
246
+ };
247
+ }
248
+ break;
249
+ case COMPONENT_TYPES.ERR:
250
+ resolved.halt = true;
251
+ resolved.error = {
252
+ code: comp.code ?? 500,
253
+ message: comp.message ?? 'Error'
254
+ };
255
+ break;
256
+ }
257
+ }
258
+ else if (typeof component === 'object' && component !== null) {
259
+ // Plain object - treat as augment data (backward compatible)
260
+ resolved.augment = component;
261
+ }
262
+ return resolved;
263
+ }
264
+ function wrapRouteHandler(handler, middlewares, context, _logLevel) {
265
+ return async (request, reply) => {
266
+ // Use our pretty logger instead of Fastify's JSON logger
267
+ const prettyLog = context.get('prettyLog') || {
268
+ info: () => { },
269
+ warn: () => { },
270
+ error: () => { },
271
+ debug: () => { },
272
+ };
273
+ const props = {
274
+ params: request.params,
275
+ query: request.query,
276
+ body: request.body,
277
+ headers: request.headers,
278
+ request,
279
+ reply,
280
+ db: context.get('db'),
281
+ log: prettyLog,
282
+ };
283
+ // Middleware timeout (30 seconds max)
284
+ const MIDDLEWARE_TIMEOUT = 30000;
285
+ for (const mw of middlewares) {
286
+ try {
287
+ // Wrap middleware in timeout to prevent hanging
288
+ const result = await withTimeout(async () => mw(props, request, reply), MIDDLEWARE_TIMEOUT, 'Middleware timeout');
289
+ if (result === false)
290
+ return;
291
+ // Handle JSX middleware responses
292
+ if (result && typeof result === 'object') {
293
+ const resolved = resolveMiddlewareResult(result);
294
+ if (resolved.halt) {
295
+ if (resolved.error) {
296
+ // Sanitize error message before sending
297
+ reply.status(resolved.error.code).send({
298
+ error: sanitizeErrorMessage(resolved.error.message, 'Request failed')
299
+ });
300
+ }
301
+ return;
302
+ }
303
+ if (resolved.augment) {
304
+ // Use safeMerge to prevent prototype pollution
305
+ safeMerge(props, resolved.augment);
306
+ }
307
+ }
308
+ }
309
+ catch (error) {
310
+ const err = error;
311
+ // Sanitize error message to prevent info leakage
312
+ reply.status(err.statusCode ?? 500).send({
313
+ error: sanitizeErrorMessage(err, 'Middleware error')
314
+ });
315
+ return;
316
+ }
317
+ }
318
+ try {
319
+ const result = await handler(props);
320
+ if (reply.sent)
321
+ return;
322
+ if (result !== undefined) {
323
+ if (isJSXResponse(result)) {
324
+ const response = resolveResponse(result);
325
+ for (const [key, value] of Object.entries(response.headers)) {
326
+ reply.header(key, value);
327
+ }
328
+ reply.status(response.statusCode).send(response.body);
329
+ }
330
+ else {
331
+ reply.send(result);
332
+ }
333
+ }
334
+ }
335
+ catch (error) {
336
+ if (!reply.sent) {
337
+ const err = error;
338
+ // Sanitize error to prevent stack trace and info leakage
339
+ reply.status(err.statusCode ?? 500).send({
340
+ error: sanitizeErrorMessage(err, 'Internal server error')
341
+ });
342
+ }
343
+ }
344
+ };
345
+ }
346
+ function resolveResponse(element) {
347
+ const response = { statusCode: 200, headers: {}, body: undefined };
348
+ function processNode(node) {
349
+ if (!node)
350
+ return;
351
+ if (Array.isArray(node)) {
352
+ node.forEach(processNode);
353
+ return;
354
+ }
355
+ let resolved = node;
356
+ if (typeof node === 'object' && node !== null && 'type' in node && typeof node.type === 'function') {
357
+ const el = node;
358
+ const props = { ...el.props, children: el.children };
359
+ const componentFn = el.type;
360
+ resolved = componentFn(props);
361
+ }
362
+ if (typeof resolved === 'object' && resolved !== null && '__tagliatelle' in resolved) {
363
+ const component = resolved;
364
+ switch (component.__tagliatelle) {
365
+ case COMPONENT_TYPES.RESPONSE:
366
+ if (component.children)
367
+ component.children.forEach(processNode);
368
+ break;
369
+ case COMPONENT_TYPES.STATUS:
370
+ response.statusCode = component.code;
371
+ break;
372
+ case COMPONENT_TYPES.BODY:
373
+ response.body = component.data;
374
+ break;
375
+ case COMPONENT_TYPES.HEADERS:
376
+ Object.assign(response.headers, component.headers);
377
+ break;
378
+ case COMPONENT_TYPES.ERR:
379
+ response.statusCode = component.code;
380
+ const errBody = { error: component.message };
381
+ if (component.details)
382
+ errBody.details = component.details;
383
+ response.body = errBody;
384
+ break;
385
+ }
386
+ }
387
+ }
388
+ processNode(element);
389
+ return response;
390
+ }
391
+ function isJSXResponse(value) {
392
+ if (!value || typeof value !== 'object')
393
+ return false;
394
+ if ('__tagliatelle' in value) {
395
+ const component = value;
396
+ return [COMPONENT_TYPES.RESPONSE, COMPONENT_TYPES.STATUS, COMPONENT_TYPES.BODY, COMPONENT_TYPES.HEADERS, COMPONENT_TYPES.ERR].includes(component.__tagliatelle);
397
+ }
398
+ if ('type' in value && typeof value.type === 'function')
399
+ return true;
400
+ return false;
401
+ }
402
+ // ═══════════════════════════════════════════════════════════════════════════
403
+ // 🚀 ROUTER
404
+ // ═══════════════════════════════════════════════════════════════════════════
405
+ export async function registerRoutes(fastify, options, context) {
406
+ const { routesDir, prefix = '', middleware = [] } = options;
407
+ const routes = [];
408
+ console.log(` ${c.dim}Routes:${c.reset} ${c.cyan}${path.basename(routesDir)}/${c.reset}`);
409
+ // Scan for routes and configs
410
+ const { routes: routeFiles, configs } = await scanDirectory(routesDir, routesDir);
411
+ // Load and parse all config files
412
+ const loadedConfigs = new Map();
413
+ for (const [dir, configPath] of configs) {
414
+ try {
415
+ const configModule = await loadModule(configPath);
416
+ const jsxTree = configModule.default();
417
+ const parsedConfig = parseJSXConfig(jsxTree);
418
+ loadedConfigs.set(dir, parsedConfig);
419
+ // Config loaded silently
420
+ }
421
+ catch (error) {
422
+ console.error(` ${c.red}✗${c.reset} Config error: ${path.relative(routesDir, configPath)}`);
423
+ }
424
+ }
425
+ // Process each route
426
+ for (const filePath of routeFiles) {
427
+ try {
428
+ const module = await loadModule(filePath);
429
+ const routeDir = path.dirname(filePath);
430
+ // Get config chain and merge
431
+ const configChain = getConfigChain(routeDir, routesDir, configs);
432
+ const chainedConfigs = [];
433
+ for (const configPath of configChain) {
434
+ // Find the config for this path
435
+ for (const [dir, cfg] of loadedConfigs) {
436
+ if (configs.get(dir) === configPath) {
437
+ chainedConfigs.push(cfg);
438
+ break;
439
+ }
440
+ }
441
+ }
442
+ const resolvedConfig = mergeConfigs(chainedConfigs, middleware);
443
+ // Add route-level middleware
444
+ if (module.middleware) {
445
+ const routeMw = Array.isArray(module.middleware) ? module.middleware : [module.middleware];
446
+ resolvedConfig.middleware.push(...routeMw);
447
+ }
448
+ // Calculate URL path
449
+ const urlPath = prefix + (resolvedConfig.prefix || '') + filePathToUrlPath(filePath, routesDir);
450
+ // Register each HTTP method
451
+ const httpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
452
+ const methods = [];
453
+ for (const method of httpMethods) {
454
+ if (typeof module[method] === 'function') {
455
+ methods.push(method);
456
+ fastify.route({
457
+ method,
458
+ url: urlPath,
459
+ handler: wrapRouteHandler(module[method], resolvedConfig.middleware, context, resolvedConfig.logLevel)
460
+ });
461
+ console.log(` ${c.dim}├${c.reset} ${methodColor(method)}${method.padEnd(6)}${c.reset} ${c.white}${urlPath}${c.reset}`);
462
+ }
463
+ }
464
+ if (methods.length > 0) {
465
+ routes.push({
466
+ filePath,
467
+ urlPath,
468
+ methods,
469
+ config: resolvedConfig
470
+ });
471
+ }
472
+ }
473
+ catch (error) {
474
+ console.error(` ${c.red}✗${c.reset} Route error: ${path.relative(routesDir, filePath)}`);
475
+ }
476
+ }
477
+ return routes;
478
+ }
479
+ export function createRouter(options) {
480
+ return {
481
+ register: async (fastify, context) => {
482
+ return registerRoutes(fastify, options, context);
483
+ }
484
+ };
485
+ }
486
+ export default createRouter;
487
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}