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
package/dist/cli.js
ADDED
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 🍝 Tagliatelle CLI
|
|
4
|
+
*
|
|
5
|
+
* Create new Tagliatelle projects with a single command!
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx tagliatelle init my-api
|
|
9
|
+
* npx tagliatelle init my-api --skip-install
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'node:fs';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { execSync } from 'node:child_process';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
17
|
+
// 🎨 COLORS
|
|
18
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
19
|
+
const c = {
|
|
20
|
+
reset: '\x1b[0m',
|
|
21
|
+
bold: '\x1b[1m',
|
|
22
|
+
dim: '\x1b[2m',
|
|
23
|
+
green: '\x1b[32m',
|
|
24
|
+
yellow: '\x1b[33m',
|
|
25
|
+
blue: '\x1b[34m',
|
|
26
|
+
magenta: '\x1b[35m',
|
|
27
|
+
cyan: '\x1b[36m',
|
|
28
|
+
red: '\x1b[31m',
|
|
29
|
+
};
|
|
30
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
31
|
+
// 📦 TEMPLATE FILES
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
+
const templates = {
|
|
34
|
+
'package.json': `{
|
|
35
|
+
"name": "{{PROJECT_NAME}}",
|
|
36
|
+
"version": "0.1.0",
|
|
37
|
+
"type": "module",
|
|
38
|
+
"scripts": {
|
|
39
|
+
"dev": "tsx watch server.tsx",
|
|
40
|
+
"start": "tsx server.tsx",
|
|
41
|
+
"build": "tsc",
|
|
42
|
+
"serve": "node dist/server.js"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"tagliatelle": "^1.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"typescript": "^5.3.0",
|
|
49
|
+
"tsx": "^4.6.0",
|
|
50
|
+
"@types/node": "^20.10.0"
|
|
51
|
+
}
|
|
52
|
+
}`,
|
|
53
|
+
'tsconfig.json': `{
|
|
54
|
+
"compilerOptions": {
|
|
55
|
+
"target": "ES2022",
|
|
56
|
+
"module": "ESNext",
|
|
57
|
+
"moduleResolution": "bundler",
|
|
58
|
+
"lib": ["ES2022"],
|
|
59
|
+
"types": ["node"],
|
|
60
|
+
"outDir": "./dist",
|
|
61
|
+
"strict": true,
|
|
62
|
+
"esModuleInterop": true,
|
|
63
|
+
"skipLibCheck": true,
|
|
64
|
+
"forceConsistentCasingInFileNames": true,
|
|
65
|
+
"declaration": true,
|
|
66
|
+
|
|
67
|
+
"jsx": "react-jsx",
|
|
68
|
+
"jsxImportSource": "tagliatelle"
|
|
69
|
+
},
|
|
70
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
71
|
+
"exclude": ["node_modules", "dist"]
|
|
72
|
+
}`,
|
|
73
|
+
'server.tsx': `/**
|
|
74
|
+
* 🍝 {{PROJECT_NAME}} - Powered by Tagliatelle
|
|
75
|
+
*
|
|
76
|
+
* Start your server:
|
|
77
|
+
* npm run dev - Development with hot reload
|
|
78
|
+
* npm run start - Production mode
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
import path from 'node:path';
|
|
82
|
+
import { fileURLToPath } from 'node:url';
|
|
83
|
+
import { render, Server, Logger, Cors, Routes, DB } from 'tagliatelle';
|
|
84
|
+
import { dbPlugin } from './plugins/db.js';
|
|
85
|
+
|
|
86
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
87
|
+
|
|
88
|
+
const App = () => (
|
|
89
|
+
<Server port={3000}>
|
|
90
|
+
<Logger level="info" />
|
|
91
|
+
<DB provider={dbPlugin}>
|
|
92
|
+
<Cors origin="*">
|
|
93
|
+
<Routes dir={path.join(__dirname, 'routes')} />
|
|
94
|
+
</Cors>
|
|
95
|
+
</DB>
|
|
96
|
+
</Server>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
render(<App />);
|
|
100
|
+
`,
|
|
101
|
+
'routes/index.tsx': `/**
|
|
102
|
+
* 🍝 Root Route
|
|
103
|
+
*
|
|
104
|
+
* GET /
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
import { Response, Status, Body } from 'tagliatelle';
|
|
108
|
+
import type { HandlerProps } from 'tagliatelle';
|
|
109
|
+
|
|
110
|
+
export async function GET({ log }: HandlerProps) {
|
|
111
|
+
log.info('API info request');
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<Response>
|
|
115
|
+
<Status code={200} />
|
|
116
|
+
<Body data={{
|
|
117
|
+
name: '{{PROJECT_NAME}}',
|
|
118
|
+
version: '0.1.0',
|
|
119
|
+
powered_by: 'Tagliatelle 🍝'
|
|
120
|
+
}} />
|
|
121
|
+
</Response>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
`,
|
|
125
|
+
'routes/health.tsx': `/**
|
|
126
|
+
* 🍝 Health Check Route
|
|
127
|
+
*
|
|
128
|
+
* GET /health
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
import { Response, Status, Body } from 'tagliatelle';
|
|
132
|
+
import type { HandlerProps } from 'tagliatelle';
|
|
133
|
+
|
|
134
|
+
export async function GET({ log }: HandlerProps) {
|
|
135
|
+
log.info('Health check');
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<Response>
|
|
139
|
+
<Status code={200} />
|
|
140
|
+
<Body data={{
|
|
141
|
+
status: 'Al Dente 🍝',
|
|
142
|
+
timestamp: new Date().toISOString()
|
|
143
|
+
}} />
|
|
144
|
+
</Response>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
`,
|
|
148
|
+
'routes/posts/_config.tsx': `/**
|
|
149
|
+
* 🍝 Posts Routes Config
|
|
150
|
+
*
|
|
151
|
+
* This config applies to all routes in /posts/*
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
import { Logger, RateLimiter } from 'tagliatelle';
|
|
155
|
+
|
|
156
|
+
export default () => (
|
|
157
|
+
<>
|
|
158
|
+
<Logger level="debug" />
|
|
159
|
+
<RateLimiter max={100} timeWindow="1 minute" />
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
`,
|
|
163
|
+
'routes/posts/_data.ts': `/**
|
|
164
|
+
* 🍝 Posts Data Store
|
|
165
|
+
*
|
|
166
|
+
* In-memory data store for demo purposes.
|
|
167
|
+
* Replace with your actual database!
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
export interface Post {
|
|
171
|
+
id: string;
|
|
172
|
+
title: string;
|
|
173
|
+
content: string;
|
|
174
|
+
author: string;
|
|
175
|
+
createdAt: Date;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export const posts: Post[] = [
|
|
179
|
+
{
|
|
180
|
+
id: '1',
|
|
181
|
+
title: 'Welcome to Tagliatelle',
|
|
182
|
+
content: 'The most delicious backend framework ever made.',
|
|
183
|
+
author: 'Chef de Code',
|
|
184
|
+
createdAt: new Date()
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: '2',
|
|
188
|
+
title: 'File-Based Routing is Here!',
|
|
189
|
+
content: 'Just like Next.js, but for your API. Bellissimo!',
|
|
190
|
+
author: 'The Pasta Architect',
|
|
191
|
+
createdAt: new Date()
|
|
192
|
+
}
|
|
193
|
+
];
|
|
194
|
+
`,
|
|
195
|
+
'routes/posts/index.tsx': `/**
|
|
196
|
+
* 🍝 Posts Collection Route
|
|
197
|
+
*
|
|
198
|
+
* GET /posts - List all posts
|
|
199
|
+
* POST /posts - Create a new post
|
|
200
|
+
*/
|
|
201
|
+
|
|
202
|
+
import { Response, Status, Body, Err } from 'tagliatelle';
|
|
203
|
+
import type { HandlerProps } from 'tagliatelle';
|
|
204
|
+
import { posts } from './_data.js';
|
|
205
|
+
|
|
206
|
+
interface CreatePostBody {
|
|
207
|
+
title: string;
|
|
208
|
+
content: string;
|
|
209
|
+
author?: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export async function GET({ log }: HandlerProps) {
|
|
213
|
+
log.info('Fetching all posts');
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<Response>
|
|
217
|
+
<Status code={200} />
|
|
218
|
+
<Body data={{
|
|
219
|
+
success: true,
|
|
220
|
+
count: posts.length,
|
|
221
|
+
data: posts
|
|
222
|
+
}} />
|
|
223
|
+
</Response>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export async function POST({ body, log }: HandlerProps<unknown, CreatePostBody>) {
|
|
228
|
+
log.info('Creating new post');
|
|
229
|
+
|
|
230
|
+
if (!body.title || !body.content) {
|
|
231
|
+
return (
|
|
232
|
+
<Err
|
|
233
|
+
code={400}
|
|
234
|
+
message="Missing required fields"
|
|
235
|
+
details={{ required: ['title', 'content'] }}
|
|
236
|
+
/>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const newPost = {
|
|
241
|
+
id: String(posts.length + 1),
|
|
242
|
+
title: body.title,
|
|
243
|
+
content: body.content,
|
|
244
|
+
author: body.author || 'Anonymous',
|
|
245
|
+
createdAt: new Date()
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
posts.push(newPost);
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<Response>
|
|
252
|
+
<Status code={201} />
|
|
253
|
+
<Body data={{
|
|
254
|
+
success: true,
|
|
255
|
+
message: 'Post created successfully! 🍝',
|
|
256
|
+
data: newPost
|
|
257
|
+
}} />
|
|
258
|
+
</Response>
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
`,
|
|
262
|
+
'routes/posts/[id].tsx': `/**
|
|
263
|
+
* 🍝 Single Post Route
|
|
264
|
+
*
|
|
265
|
+
* GET /posts/:id - Get a post
|
|
266
|
+
* PUT /posts/:id - Update a post
|
|
267
|
+
* DELETE /posts/:id - Delete a post
|
|
268
|
+
*/
|
|
269
|
+
|
|
270
|
+
import { Response, Status, Body, Err } from 'tagliatelle';
|
|
271
|
+
import type { HandlerProps } from 'tagliatelle';
|
|
272
|
+
import { posts } from './_data.js';
|
|
273
|
+
|
|
274
|
+
interface PostParams {
|
|
275
|
+
id: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
interface UpdatePostBody {
|
|
279
|
+
title?: string;
|
|
280
|
+
content?: string;
|
|
281
|
+
author?: string;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export async function GET({ params, log }: HandlerProps<PostParams>) {
|
|
285
|
+
log.info(\`Fetching post \${params.id}\`);
|
|
286
|
+
|
|
287
|
+
const post = posts.find(p => p.id === params.id);
|
|
288
|
+
|
|
289
|
+
if (!post) {
|
|
290
|
+
return <Err code={404} message="Post not found" />;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
<Response>
|
|
295
|
+
<Status code={200} />
|
|
296
|
+
<Body data={{ success: true, data: post }} />
|
|
297
|
+
</Response>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export async function PUT({ params, body, log }: HandlerProps<PostParams, UpdatePostBody>) {
|
|
302
|
+
log.info(\`Updating post \${params.id}\`);
|
|
303
|
+
|
|
304
|
+
const postIndex = posts.findIndex(p => p.id === params.id);
|
|
305
|
+
|
|
306
|
+
if (postIndex === -1) {
|
|
307
|
+
return <Err code={404} message="Post not found" />;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
posts[postIndex] = { ...posts[postIndex], ...body };
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<Response>
|
|
314
|
+
<Status code={200} />
|
|
315
|
+
<Body data={{
|
|
316
|
+
success: true,
|
|
317
|
+
message: 'Post updated!',
|
|
318
|
+
data: posts[postIndex]
|
|
319
|
+
}} />
|
|
320
|
+
</Response>
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export async function DELETE({ params, log }: HandlerProps<PostParams>) {
|
|
325
|
+
log.info(\`Deleting post \${params.id}\`);
|
|
326
|
+
|
|
327
|
+
const postIndex = posts.findIndex(p => p.id === params.id);
|
|
328
|
+
|
|
329
|
+
if (postIndex === -1) {
|
|
330
|
+
return <Err code={404} message="Post not found" />;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const deleted = posts.splice(postIndex, 1)[0];
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
<Response>
|
|
337
|
+
<Status code={200} />
|
|
338
|
+
<Body data={{
|
|
339
|
+
success: true,
|
|
340
|
+
message: 'Post deleted!',
|
|
341
|
+
data: deleted
|
|
342
|
+
}} />
|
|
343
|
+
</Response>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
`,
|
|
347
|
+
'plugins/db.ts': `/**
|
|
348
|
+
* 🗄️ Database Plugin
|
|
349
|
+
*
|
|
350
|
+
* Example database provider for Tagliatelle.
|
|
351
|
+
* Replace with your actual database connection (PostgreSQL, MongoDB, etc.)
|
|
352
|
+
*/
|
|
353
|
+
|
|
354
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
355
|
+
// 📦 TYPES
|
|
356
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
357
|
+
|
|
358
|
+
export interface Database {
|
|
359
|
+
query: <T>(sql: string, params?: unknown[]) => Promise<T[]>;
|
|
360
|
+
insert: <T>(table: string, data: Record<string, unknown>) => Promise<T>;
|
|
361
|
+
update: (table: string, id: string, data: Record<string, unknown>) => Promise<boolean>;
|
|
362
|
+
delete: (table: string, id: string) => Promise<boolean>;
|
|
363
|
+
close: () => Promise<void>;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
367
|
+
// 🍝 DATABASE PROVIDER
|
|
368
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Creates a mock database connection
|
|
372
|
+
* Replace this with your actual database connection logic
|
|
373
|
+
*
|
|
374
|
+
* Examples:
|
|
375
|
+
* - PostgreSQL: pg or postgres
|
|
376
|
+
* - MongoDB: mongoose or mongodb
|
|
377
|
+
* - SQLite: better-sqlite3
|
|
378
|
+
* - Prisma: @prisma/client
|
|
379
|
+
*/
|
|
380
|
+
export async function dbPlugin(): Promise<Database> {
|
|
381
|
+
// Simulate connection delay
|
|
382
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
383
|
+
|
|
384
|
+
console.log('🗄️ Database connected');
|
|
385
|
+
|
|
386
|
+
// In-memory storage (replace with real DB)
|
|
387
|
+
const storage: Record<string, Record<string, unknown>[]> = {};
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
async query<T>(sql: string, _params?: unknown[]): Promise<T[]> {
|
|
391
|
+
console.log(\`🗄️ Query: \${sql}\`);
|
|
392
|
+
const table = sql.match(/FROM\\s+(\\w+)/i)?.[1] || 'default';
|
|
393
|
+
return (storage[table] || []) as T[];
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
async insert<T>(table: string, data: Record<string, unknown>): Promise<T> {
|
|
397
|
+
console.log(\`🗄️ Insert into \${table}:\`, data);
|
|
398
|
+
if (!storage[table]) storage[table] = [];
|
|
399
|
+
const record = { id: String(storage[table].length + 1), ...data };
|
|
400
|
+
storage[table].push(record);
|
|
401
|
+
return record as T;
|
|
402
|
+
},
|
|
403
|
+
|
|
404
|
+
async update(table: string, id: string, data: Record<string, unknown>): Promise<boolean> {
|
|
405
|
+
console.log(\`🗄️ Update \${table}/\${id}:\`, data);
|
|
406
|
+
if (!storage[table]) return false;
|
|
407
|
+
const index = storage[table].findIndex(r => r.id === id);
|
|
408
|
+
if (index === -1) return false;
|
|
409
|
+
storage[table][index] = { ...storage[table][index], ...data };
|
|
410
|
+
return true;
|
|
411
|
+
},
|
|
412
|
+
|
|
413
|
+
async delete(table: string, id: string): Promise<boolean> {
|
|
414
|
+
console.log(\`🗄️ Delete \${table}/\${id}\`);
|
|
415
|
+
if (!storage[table]) return false;
|
|
416
|
+
const index = storage[table].findIndex(r => r.id === id);
|
|
417
|
+
if (index === -1) return false;
|
|
418
|
+
storage[table].splice(index, 1);
|
|
419
|
+
return true;
|
|
420
|
+
},
|
|
421
|
+
|
|
422
|
+
async close(): Promise<void> {
|
|
423
|
+
console.log('🗄️ Database connection closed');
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
`,
|
|
428
|
+
'.gitignore': `node_modules/
|
|
429
|
+
dist/
|
|
430
|
+
.env
|
|
431
|
+
.env.local
|
|
432
|
+
*.log
|
|
433
|
+
.DS_Store
|
|
434
|
+
`,
|
|
435
|
+
'README.md': `# {{PROJECT_NAME}}
|
|
436
|
+
|
|
437
|
+
A delicious API powered by [Tagliatelle](https://github.com/malekabdelkader/Tagliatelle.js) 🍝
|
|
438
|
+
|
|
439
|
+
## Getting Started
|
|
440
|
+
|
|
441
|
+
\`\`\`bash
|
|
442
|
+
# Development with hot reload
|
|
443
|
+
npm run dev
|
|
444
|
+
|
|
445
|
+
# Production
|
|
446
|
+
npm run start
|
|
447
|
+
\`\`\`
|
|
448
|
+
|
|
449
|
+
## API Endpoints
|
|
450
|
+
|
|
451
|
+
| Method | Path | Description |
|
|
452
|
+
|--------|------|-------------|
|
|
453
|
+
| GET | \`/\` | API info |
|
|
454
|
+
| GET | \`/health\` | Health check |
|
|
455
|
+
| GET | \`/posts\` | List all posts |
|
|
456
|
+
| POST | \`/posts\` | Create a post |
|
|
457
|
+
| GET | \`/posts/:id\` | Get a post |
|
|
458
|
+
| PUT | \`/posts/:id\` | Update a post |
|
|
459
|
+
| DELETE | \`/posts/:id\` | Delete a post |
|
|
460
|
+
|
|
461
|
+
## Project Structure
|
|
462
|
+
|
|
463
|
+
\`\`\`
|
|
464
|
+
{{PROJECT_NAME}}/
|
|
465
|
+
├── server.tsx # Entry point
|
|
466
|
+
├── plugins/
|
|
467
|
+
│ └── db.ts # Database provider
|
|
468
|
+
├── routes/
|
|
469
|
+
│ ├── index.tsx # GET /
|
|
470
|
+
│ ├── health.tsx # GET /health
|
|
471
|
+
│ └── posts/
|
|
472
|
+
│ ├── _config.tsx # Route group config
|
|
473
|
+
│ ├── _data.ts # Data store
|
|
474
|
+
│ ├── index.tsx # GET/POST /posts
|
|
475
|
+
│ └── [id].tsx # GET/PUT/DELETE /posts/:id
|
|
476
|
+
├── package.json
|
|
477
|
+
└── tsconfig.json
|
|
478
|
+
\`\`\`
|
|
479
|
+
|
|
480
|
+
## Learn More
|
|
481
|
+
|
|
482
|
+
- [Tagliatelle Docs](https://github.com/malekabdelkader/Tagliatelle.js)
|
|
483
|
+
- [File-Based Routing](https://github.com/malekabdelkader/Tagliatelle.js#routing)
|
|
484
|
+
- [JSX Components](https://github.com/malekabdelkader/Tagliatelle.js#components)
|
|
485
|
+
`,
|
|
486
|
+
};
|
|
487
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
488
|
+
// 🛠️ HELPERS
|
|
489
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
490
|
+
function printBanner() {
|
|
491
|
+
console.log(`
|
|
492
|
+
${c.yellow} ╔══════════════════════════════════════════════════════════════╗
|
|
493
|
+
║ ${c.bold}🍝 Tagliatelle${c.reset}${c.yellow} ║
|
|
494
|
+
║ ${c.dim}The Declarative Backend Framework${c.reset}${c.yellow} ║
|
|
495
|
+
╚══════════════════════════════════════════════════════════════╝${c.reset}
|
|
496
|
+
`);
|
|
497
|
+
}
|
|
498
|
+
function printHelp() {
|
|
499
|
+
printBanner();
|
|
500
|
+
console.log(`${c.bold}Usage:${c.reset}
|
|
501
|
+
${c.cyan}npx tagliatelle init${c.reset} <project-name> [options]
|
|
502
|
+
|
|
503
|
+
${c.bold}Commands:${c.reset}
|
|
504
|
+
${c.green}init${c.reset} <name> Create a new Tagliatelle project
|
|
505
|
+
|
|
506
|
+
${c.bold}Options:${c.reset}
|
|
507
|
+
${c.yellow}--skip-install${c.reset} Skip npm install after scaffolding
|
|
508
|
+
${c.yellow}--help, -h${c.reset} Show this help message
|
|
509
|
+
|
|
510
|
+
${c.bold}Examples:${c.reset}
|
|
511
|
+
${c.dim}# Create a new project${c.reset}
|
|
512
|
+
${c.cyan}npx tagliatelle init my-api${c.reset}
|
|
513
|
+
|
|
514
|
+
${c.dim}# Create without installing dependencies${c.reset}
|
|
515
|
+
${c.cyan}npx tagliatelle init my-api --skip-install${c.reset}
|
|
516
|
+
`);
|
|
517
|
+
}
|
|
518
|
+
function createDir(dir) {
|
|
519
|
+
if (!fs.existsSync(dir)) {
|
|
520
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
function writeFile(filePath, content) {
|
|
524
|
+
const dir = path.dirname(filePath);
|
|
525
|
+
createDir(dir);
|
|
526
|
+
fs.writeFileSync(filePath, content);
|
|
527
|
+
}
|
|
528
|
+
function scaffold(projectName, targetDir) {
|
|
529
|
+
console.log(`\n${c.cyan}Creating project:${c.reset} ${c.bold}${projectName}${c.reset}\n`);
|
|
530
|
+
// Create all files from templates
|
|
531
|
+
for (const [relativePath, template] of Object.entries(templates)) {
|
|
532
|
+
const content = template.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
533
|
+
const filePath = path.join(targetDir, relativePath);
|
|
534
|
+
writeFile(filePath, content);
|
|
535
|
+
console.log(` ${c.green}✓${c.reset} ${relativePath}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
function runNpmInstall(targetDir) {
|
|
539
|
+
console.log(`\n${c.cyan}Installing dependencies...${c.reset}\n`);
|
|
540
|
+
try {
|
|
541
|
+
execSync('npm install', { cwd: targetDir, stdio: 'inherit' });
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
console.log(`\n${c.yellow}⚠${c.reset} Failed to install dependencies. Run ${c.cyan}npm install${c.reset} manually.\n`);
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
function printSuccess(projectName, skipInstall) {
|
|
550
|
+
console.log(`
|
|
551
|
+
${c.green}✓ Project created successfully!${c.reset}
|
|
552
|
+
|
|
553
|
+
${c.bold}Next steps:${c.reset}
|
|
554
|
+
|
|
555
|
+
${c.cyan}cd${c.reset} ${projectName}${skipInstall ? `
|
|
556
|
+
${c.cyan}npm install${c.reset}` : ''}
|
|
557
|
+
${c.cyan}npm run dev${c.reset}
|
|
558
|
+
|
|
559
|
+
${c.dim}Your API will be running at ${c.cyan}http://localhost:3000${c.reset}
|
|
560
|
+
|
|
561
|
+
${c.yellow}🍝 Buon appetito!${c.reset}
|
|
562
|
+
`);
|
|
563
|
+
}
|
|
564
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
565
|
+
// 🚀 MAIN
|
|
566
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
567
|
+
function main() {
|
|
568
|
+
const args = process.argv.slice(2);
|
|
569
|
+
// Handle help
|
|
570
|
+
if (args.includes('--help') || args.includes('-h') || args.length === 0) {
|
|
571
|
+
printHelp();
|
|
572
|
+
process.exit(0);
|
|
573
|
+
}
|
|
574
|
+
const command = args[0];
|
|
575
|
+
if (command !== 'init') {
|
|
576
|
+
console.log(`${c.red}Unknown command:${c.reset} ${command}\n`);
|
|
577
|
+
printHelp();
|
|
578
|
+
process.exit(1);
|
|
579
|
+
}
|
|
580
|
+
const projectName = args[1];
|
|
581
|
+
if (!projectName) {
|
|
582
|
+
console.log(`${c.red}Error:${c.reset} Please provide a project name\n`);
|
|
583
|
+
console.log(` ${c.cyan}npx tagliatelle init my-api${c.reset}\n`);
|
|
584
|
+
process.exit(1);
|
|
585
|
+
}
|
|
586
|
+
// Validate project name
|
|
587
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
|
|
588
|
+
console.log(`${c.red}Error:${c.reset} Invalid project name. Use only letters, numbers, dashes, and underscores.\n`);
|
|
589
|
+
process.exit(1);
|
|
590
|
+
}
|
|
591
|
+
const skipInstall = args.includes('--skip-install');
|
|
592
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
|
593
|
+
// Check if directory exists
|
|
594
|
+
if (fs.existsSync(targetDir)) {
|
|
595
|
+
console.log(`${c.red}Error:${c.reset} Directory ${c.bold}${projectName}${c.reset} already exists.\n`);
|
|
596
|
+
process.exit(1);
|
|
597
|
+
}
|
|
598
|
+
printBanner();
|
|
599
|
+
// Scaffold project
|
|
600
|
+
scaffold(projectName, targetDir);
|
|
601
|
+
// Install dependencies
|
|
602
|
+
if (!skipInstall) {
|
|
603
|
+
runNpmInstall(targetDir);
|
|
604
|
+
}
|
|
605
|
+
// Success message
|
|
606
|
+
printSuccess(projectName, skipInstall);
|
|
607
|
+
}
|
|
608
|
+
main();
|
|
609
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🍝 <Tag>liatelle.js - Main Export
|
|
3
|
+
*
|
|
4
|
+
* The Declarative Backend Framework
|
|
5
|
+
*/
|
|
6
|
+
export { h, Fragment, render, Context, Server, Get, Post, Put, Delete, Patch, Middleware, DB, Logger, Group, Cors, RateLimiter, Routes, Response, Status, Body, Headers, Err, Augment, Halt, COMPONENT_TYPES, } from './tagliatelle.js';
|
|
7
|
+
export type { TagliatelleElement, TagliatelleNode, TagliatelleComponent, ComponentType, Handler, HandlerProps, MiddlewareFunction, MiddlewareResult, ServerProps, RouteProps, MiddlewareProps, DBProps, LoggerProps, GroupProps, CorsProps, RateLimiterProps, RoutesProps, ResponseProps, StatusProps, BodyProps, HeadersProps, ErrProps, AugmentProps, HaltProps, } from './types.js';
|
|
8
|
+
export type { ParsedConfig, RouteModule, HTTPMethod } from './router.js';
|
|
9
|
+
export { sanitizeErrorMessage, safeErrorResponse, safeMerge, isNonEmptyString, isSafeString, isPositiveInt, isValidId, sanitizeForLog, withTimeout, AuthFailureTracker, authFailureTracker, } from './security.js';
|
|
10
|
+
export { default } from './tagliatelle.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,CAAC,EACD,QAAQ,EAGR,MAAM,EACN,OAAO,EAGP,MAAM,EACN,GAAG,EACH,IAAI,EACJ,GAAG,EACH,MAAM,EACN,KAAK,EACL,UAAU,EACV,EAAE,EACF,MAAM,EACN,KAAK,EACL,IAAI,EACJ,WAAW,EACX,MAAM,EAGN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,OAAO,EACP,GAAG,EAGH,OAAO,EACP,IAAI,EAGJ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,OAAO,EACP,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,eAAe,EACf,OAAO,EACP,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,WAAW,EACX,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzE,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🍝 <Tag>liatelle.js - Main Export
|
|
3
|
+
*
|
|
4
|
+
* The Declarative Backend Framework
|
|
5
|
+
*/
|
|
6
|
+
export {
|
|
7
|
+
// JSX Factory
|
|
8
|
+
h, Fragment,
|
|
9
|
+
// Core
|
|
10
|
+
render, Context,
|
|
11
|
+
// Server Components
|
|
12
|
+
Server, Get, Post, Put, Delete, Patch, Middleware, DB, Logger, Group, Cors, RateLimiter, Routes,
|
|
13
|
+
// Response Components
|
|
14
|
+
Response, Status, Body, Headers, Err,
|
|
15
|
+
// Middleware Components
|
|
16
|
+
Augment, Halt,
|
|
17
|
+
// Types
|
|
18
|
+
COMPONENT_TYPES, } from './tagliatelle.js';
|
|
19
|
+
// Security exports
|
|
20
|
+
export { sanitizeErrorMessage, safeErrorResponse, safeMerge, isNonEmptyString, isSafeString, isPositiveInt, isValidId, sanitizeForLog, withTimeout, AuthFailureTracker, authFailureTracker, } from './security.js';
|
|
21
|
+
// Default export
|
|
22
|
+
export { default } from './tagliatelle.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO;AACL,cAAc;AACd,CAAC,EACD,QAAQ;AAER,OAAO;AACP,MAAM,EACN,OAAO;AAEP,oBAAoB;AACpB,MAAM,EACN,GAAG,EACH,IAAI,EACJ,GAAG,EACH,MAAM,EACN,KAAK,EACL,UAAU,EACV,EAAE,EACF,MAAM,EACN,KAAK,EACL,IAAI,EACJ,WAAW,EACX,MAAM;AAEN,sBAAsB;AACtB,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,OAAO,EACP,GAAG;AAEH,wBAAwB;AACxB,OAAO,EACP,IAAI;AAEJ,QAAQ;AACR,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAgC1B,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,iBAAiB;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
import type { TagliatelleElement, TagliatelleNode } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Fragment component - groups children without a wrapper
|
|
11
|
+
*/
|
|
12
|
+
export declare const Fragment: unique symbol;
|
|
13
|
+
/**
|
|
14
|
+
* JSX runtime function for production
|
|
15
|
+
* Called for elements with a single child or no children
|
|
16
|
+
*/
|
|
17
|
+
export declare function jsx(type: string | Function | symbol, props: Record<string, unknown> & {
|
|
18
|
+
children?: TagliatelleNode;
|
|
19
|
+
}, _key?: string): TagliatelleElement;
|
|
20
|
+
/**
|
|
21
|
+
* JSX runtime function for elements with multiple static children
|
|
22
|
+
* Same as jsx but called when there are multiple children
|
|
23
|
+
*/
|
|
24
|
+
export declare function jsxs(type: string | Function | symbol, props: Record<string, unknown> & {
|
|
25
|
+
children?: TagliatelleNode[];
|
|
26
|
+
}, _key?: string): TagliatelleElement;
|
|
27
|
+
/**
|
|
28
|
+
* JSX dev runtime function (same as jsx for our purposes)
|
|
29
|
+
*/
|
|
30
|
+
export declare const jsxDEV: typeof jsx;
|
|
31
|
+
//# sourceMappingURL=jsx-runtime.d.ts.map
|