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.
- package/README.md +488 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +609 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-runtime.d.ts +31 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +46 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/router.d.ts +59 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +487 -0
- package/dist/router.js.map +1 -0
- package/dist/security.d.ts +84 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +233 -0
- package/dist/security.js.map +1 -0
- package/dist/tagliatelle.d.ts +90 -0
- package/dist/tagliatelle.d.ts.map +1 -0
- package/dist/tagliatelle.js +684 -0
- package/dist/tagliatelle.js.map +1 -0
- package/dist/types.d.ts +144 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/package.json +79 -0
|
@@ -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"}
|
package/dist/router.d.ts
ADDED
|
@@ -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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"}
|