create-frootjs 0.0.0-stage → 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +68 -2
  3. package/dist/generator.d.ts +21 -0
  4. package/dist/generator.d.ts.map +1 -0
  5. package/dist/generator.js +62 -0
  6. package/dist/generator.js.map +1 -0
  7. package/dist/index.d.ts +7 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +215 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/templates/fullstack.d.ts +7 -0
  12. package/dist/templates/fullstack.d.ts.map +1 -0
  13. package/dist/templates/fullstack.js +224 -0
  14. package/dist/templates/fullstack.js.map +1 -0
  15. package/dist/templates/index.d.ts +10 -0
  16. package/dist/templates/index.d.ts.map +1 -0
  17. package/dist/templates/index.js +26 -0
  18. package/dist/templates/index.js.map +1 -0
  19. package/dist/templates/minimal.d.ts +7 -0
  20. package/dist/templates/minimal.d.ts.map +1 -0
  21. package/dist/templates/minimal.js +89 -0
  22. package/dist/templates/minimal.js.map +1 -0
  23. package/dist/templates/modular.d.ts +7 -0
  24. package/dist/templates/modular.d.ts.map +1 -0
  25. package/dist/templates/modular.js +300 -0
  26. package/dist/templates/modular.js.map +1 -0
  27. package/dist/templates/mvc.d.ts +7 -0
  28. package/dist/templates/mvc.d.ts.map +1 -0
  29. package/dist/templates/mvc.js +239 -0
  30. package/dist/templates/mvc.js.map +1 -0
  31. package/dist/templates/openapi.d.ts +7 -0
  32. package/dist/templates/openapi.d.ts.map +1 -0
  33. package/dist/templates/openapi.js +206 -0
  34. package/dist/templates/openapi.js.map +1 -0
  35. package/dist/templates/streaming.d.ts +7 -0
  36. package/dist/templates/streaming.d.ts.map +1 -0
  37. package/dist/templates/streaming.js +211 -0
  38. package/dist/templates/streaming.js.map +1 -0
  39. package/dist/templates/types.d.ts +17 -0
  40. package/dist/templates/types.d.ts.map +1 -0
  41. package/dist/templates/types.js +47 -0
  42. package/dist/templates/types.js.map +1 -0
  43. package/dist/templates/websocket.d.ts +7 -0
  44. package/dist/templates/websocket.d.ts.map +1 -0
  45. package/dist/templates/websocket.js +198 -0
  46. package/dist/templates/websocket.js.map +1 -0
  47. package/dist/ui.d.ts +73 -0
  48. package/dist/ui.d.ts.map +1 -0
  49. package/dist/ui.js +236 -0
  50. package/dist/ui.js.map +1 -0
  51. package/package.json +45 -4
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Template Registry
3
+ * Central export of all available project architectural templates.
4
+ */
5
+ import { TemplateDefinition } from './types.js';
6
+ export * from './types.js';
7
+ export declare const TEMPLATES: Record<string, TemplateDefinition>;
8
+ export declare const TEMPLATE_LIST: TemplateDefinition[];
9
+ export declare function getTemplate(id: string): TemplateDefinition | undefined;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAShD,cAAc,YAAY,CAAC;AAE3B,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAQxD,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAA6B,CAAC;AAE5E,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEtE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Template Registry
3
+ * Central export of all available project architectural templates.
4
+ */
5
+ import { mvcTemplate } from './mvc.js';
6
+ import { modularTemplate } from './modular.js';
7
+ import { streamingTemplate } from './streaming.js';
8
+ import { websocketTemplate } from './websocket.js';
9
+ import { openapiTemplate } from './openapi.js';
10
+ import { fullstackTemplate } from './fullstack.js';
11
+ import { minimalTemplate } from './minimal.js';
12
+ export * from './types.js';
13
+ export const TEMPLATES = {
14
+ mvc: mvcTemplate,
15
+ modular: modularTemplate,
16
+ streaming: streamingTemplate,
17
+ websocket: websocketTemplate,
18
+ openapi: openapiTemplate,
19
+ fullstack: fullstackTemplate,
20
+ minimal: minimalTemplate,
21
+ };
22
+ export const TEMPLATE_LIST = Object.values(TEMPLATES);
23
+ export function getTemplate(id) {
24
+ return TEMPLATES[id.toLowerCase()];
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,cAAc,YAAY,CAAC;AAE3B,MAAM,CAAC,MAAM,SAAS,GAAuC;IAC3D,GAAG,EAAE,WAAW;IAChB,OAAO,EAAE,eAAe;IACxB,SAAS,EAAE,iBAAiB;IAC5B,SAAS,EAAE,iBAAiB;IAC5B,OAAO,EAAE,eAAe;IACxB,SAAS,EAAE,iBAAiB;IAC5B,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAyB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAE5E,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Minimal Starter Template
3
+ * Clean, single-file starter project for microservices, quick prototypes, or lightweight APIs.
4
+ */
5
+ import { TemplateDefinition } from './types.js';
6
+ export declare const minimalTemplate: TemplateDefinition;
7
+ //# sourceMappingURL=minimal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimal.d.ts","sourceRoot":"","sources":["../../src/templates/minimal.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAsD,MAAM,YAAY,CAAC;AAEpG,eAAO,MAAM,eAAe,EAAE,kBAyF7B,CAAC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Minimal Starter Template
3
+ * Clean, single-file starter project for microservices, quick prototypes, or lightweight APIs.
4
+ */
5
+ import { COMMON_GITIGNORE, COMMON_TSCONFIG } from './types.js';
6
+ export const minimalTemplate = {
7
+ id: 'minimal',
8
+ name: 'Minimal Starter (Single-file)',
9
+ description: 'Lean single-file API starter with basic JSON endpoints and CORS',
10
+ generate: (projectName) => {
11
+ return {
12
+ 'package.json': JSON.stringify({
13
+ name: projectName,
14
+ version: '1.0.0',
15
+ type: 'module',
16
+ scripts: {
17
+ dev: 'node --experimental-strip-types src/index.ts',
18
+ build: 'tsc',
19
+ start: 'node dist/index.js',
20
+ },
21
+ dependencies: {
22
+ frootjs: '^1.0.1',
23
+ },
24
+ devDependencies: {
25
+ '@types/node': '^22.10.0',
26
+ typescript: '^5.8.0',
27
+ },
28
+ }, null, 2) + '\n',
29
+ 'tsconfig.json': COMMON_TSCONFIG,
30
+ '.gitignore': COMMON_GITIGNORE,
31
+ 'README.md': `# ${projectName}
32
+
33
+ Lean, high-performance web service built with **Froot**.
34
+
35
+ ## Getting Started
36
+
37
+ \`\`\`bash
38
+ # 1. Install dependencies
39
+ pnpm install
40
+
41
+ # 2. Run in development mode
42
+ pnpm run dev
43
+
44
+ # 3. Test endpoint
45
+ curl http://localhost:3000/
46
+ \`\`\`
47
+ `,
48
+ 'src/index.ts': `import { Froot } from 'frootjs';
49
+ import { cors } from 'frootjs/cors';
50
+
51
+ export const app = new Froot();
52
+
53
+ // Middleware
54
+ app.use(cors());
55
+
56
+ // Routes
57
+ app.get('/', (c) => {
58
+ return c.json({
59
+ message: 'Hello from Froot!',
60
+ timestamp: new Date().toISOString(),
61
+ });
62
+ });
63
+
64
+ app.get('/health', (c) => {
65
+ return c.json({
66
+ status: 'ok',
67
+ uptime: process.uptime(),
68
+ });
69
+ });
70
+
71
+ app.post('/echo', async (c) => {
72
+ const body = await c.req.json();
73
+ return c.json({
74
+ received: body,
75
+ headers: {
76
+ userAgent: c.req.header('user-agent'),
77
+ },
78
+ });
79
+ });
80
+
81
+ const PORT = Number(process.env.PORT) || 3000;
82
+ app.listen(PORT, () => {
83
+ console.log(\`Server is running on http://localhost:\${PORT}\`);
84
+ });
85
+ `,
86
+ };
87
+ },
88
+ };
89
+ //# sourceMappingURL=minimal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimal.js","sourceRoot":"","sources":["../../src/templates/minimal.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpG,MAAM,CAAC,MAAM,eAAe,GAAuB;IACjD,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,+BAA+B;IACrC,WAAW,EAAE,iEAAiE;IAC9E,QAAQ,EAAE,CAAC,WAAmB,EAAmB,EAAE;QACjD,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACP,GAAG,EAAE,8CAA8C;oBACnD,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,oBAAoB;iBAC5B;gBACD,YAAY,EAAE;oBACZ,OAAO,EAAE,QAAQ;iBAClB;gBACD,eAAe,EAAE;oBACf,aAAa,EAAE,UAAU;oBACzB,UAAU,EAAE,QAAQ;iBACrB;aACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI;YAER,eAAe,EAAE,eAAe;YAChC,YAAY,EAAE,gBAAgB;YAE9B,WAAW,EAAE,KAAK,WAAW;;;;;;;;;;;;;;;;CAgBlC;YAEK,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCrB;SACI,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Modular / NestJS-Style Feature Modules Template
3
+ * Organizes code by domain feature: each module encapsulates its routes, service, schema, and types.
4
+ */
5
+ import { TemplateDefinition } from './types.js';
6
+ export declare const modularTemplate: TemplateDefinition;
7
+ //# sourceMappingURL=modular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modular.d.ts","sourceRoot":"","sources":["../../src/templates/modular.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAsD,MAAM,YAAY,CAAC;AAEpG,eAAO,MAAM,eAAe,EAAE,kBAuT7B,CAAC"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Modular / NestJS-Style Feature Modules Template
3
+ * Organizes code by domain feature: each module encapsulates its routes, service, schema, and types.
4
+ */
5
+ import { COMMON_GITIGNORE, COMMON_TSCONFIG } from './types.js';
6
+ export const modularTemplate = {
7
+ id: 'modular',
8
+ name: 'Modular Architecture (NestJS-style)',
9
+ description: 'Domain feature modules (routes, service, schema) with common guards & filters',
10
+ generate: (projectName) => {
11
+ return {
12
+ 'package.json': JSON.stringify({
13
+ name: projectName,
14
+ version: '1.0.0',
15
+ type: 'module',
16
+ scripts: {
17
+ dev: 'node --experimental-strip-types src/server.ts',
18
+ build: 'tsc',
19
+ start: 'node dist/server.js',
20
+ test: 'node --test tests/*.test.ts',
21
+ },
22
+ dependencies: {
23
+ frootjs: '^1.0.1',
24
+ },
25
+ devDependencies: {
26
+ '@types/node': '^22.10.0',
27
+ typescript: '^5.8.0',
28
+ },
29
+ }, null, 2) + '\n',
30
+ 'tsconfig.json': COMMON_TSCONFIG,
31
+ '.gitignore': COMMON_GITIGNORE,
32
+ 'README.md': `# ${projectName}
33
+
34
+ Froot application built with the **Modular Architecture (NestJS-style)** pattern.
35
+
36
+ ## Directory Structure
37
+
38
+ \`\`\`
39
+ src/
40
+ ├── common/ # Cross-cutting concerns
41
+ │ ├── guards/ # Auth & role guards
42
+ │ │ └── auth.guard.ts
43
+ │ └── filters/ # Global error filters
44
+ │ └── error.filter.ts
45
+ ├── modules/ # Feature modules
46
+ │ ├── auth/ # Authentication module (JWT & login)
47
+ │ │ ├── auth.routes.ts
48
+ │ │ └── auth.service.ts
49
+ │ ├── users/ # Users management module
50
+ │ │ ├── users.routes.ts
51
+ │ │ ├── users.service.ts
52
+ │ │ └── users.types.ts
53
+ │ └── products/ # Products catalog module
54
+ │ ├── products.routes.ts
55
+ │ ├── products.service.ts
56
+ │ └── products.types.ts
57
+ ├── app.ts # Root application module orchestrator
58
+ └── server.ts # Server bootstrap
59
+ \`\`\`
60
+
61
+ ## Getting Started
62
+
63
+ \`\`\`bash
64
+ # 1. Install dependencies
65
+ pnpm install
66
+
67
+ # 2. Run in development mode
68
+ pnpm run dev
69
+
70
+ # 3. Build for production
71
+ pnpm run build
72
+ pnpm start
73
+ \`\`\`
74
+ `,
75
+ 'src/common/guards/auth.guard.ts': `import type { Context, MiddlewareHandler } from 'frootjs';
76
+ import { verifyJwt } from 'frootjs/jwt';
77
+
78
+ const JWT_SECRET = process.env.JWT_SECRET || 'froot-secret-key-change-in-production';
79
+
80
+ export interface AuthContextVariables {
81
+ user: {
82
+ id: string;
83
+ email: string;
84
+ role: string;
85
+ };
86
+ }
87
+
88
+ export const authGuard: MiddlewareHandler = async (c, next) => {
89
+ const authHeader = c.req.header('authorization');
90
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
91
+ return c.json({ error: 'Unauthorized: missing or invalid authorization header' }, 401);
92
+ }
93
+
94
+ const token = authHeader.slice(7).trim();
95
+ const payload = await verifyJwt(token, JWT_SECRET);
96
+
97
+ if (!payload) {
98
+ return c.json({ error: 'Unauthorized: token is invalid or expired' }, 401);
99
+ }
100
+
101
+ c.set('user', payload);
102
+ await next();
103
+ };
104
+ `,
105
+ 'src/common/filters/error.filter.ts': `import type { Context } from 'frootjs';
106
+
107
+ export function errorHandler(err: unknown, c: Context): Response {
108
+ console.error('[ErrorFilter] Caught unhandled error:', err);
109
+
110
+ if (err instanceof Error) {
111
+ return c.json(
112
+ {
113
+ error: err.name,
114
+ message: err.message,
115
+ statusCode: 500,
116
+ },
117
+ 500
118
+ );
119
+ }
120
+
121
+ return c.json(
122
+ {
123
+ error: 'Internal Server Error',
124
+ message: 'An unexpected error occurred',
125
+ statusCode: 500,
126
+ },
127
+ 500
128
+ );
129
+ }
130
+ `,
131
+ 'src/modules/auth/auth.service.ts': `import { signJwt } from 'frootjs/jwt';
132
+
133
+ const JWT_SECRET = process.env.JWT_SECRET || 'froot-secret-key-change-in-production';
134
+
135
+ export class AuthService {
136
+ static async createToken(user: { id: string; email: string; role: string }): Promise<string> {
137
+ return signJwt(
138
+ {
139
+ sub: user.id,
140
+ email: user.email,
141
+ role: user.role,
142
+ exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24, // 24 hours
143
+ },
144
+ JWT_SECRET
145
+ );
146
+ }
147
+ }
148
+ `,
149
+ 'src/modules/auth/auth.routes.ts': `import { Froot } from 'frootjs';
150
+ import { AuthService } from './auth.service.js';
151
+
152
+ export const authModule = new Froot();
153
+
154
+ authModule.post('/auth/login', async (c) => {
155
+ const body = await c.req.json<{ email?: string; password?: string }>();
156
+ if (!body.email || !body.password) {
157
+ return c.json({ error: 'Email and password required' }, 400);
158
+ }
159
+
160
+ // Demo validation: any credentials pass for showcase
161
+ const user = {
162
+ id: 'usr_demo',
163
+ email: body.email,
164
+ role: 'admin',
165
+ };
166
+
167
+ const token = await AuthService.createToken(user);
168
+ return c.json({
169
+ token,
170
+ user,
171
+ message: 'Login successful',
172
+ });
173
+ });
174
+ `,
175
+ 'src/modules/users/users.types.ts': `export interface UserProfile {
176
+ id: string;
177
+ name: string;
178
+ email: string;
179
+ role: string;
180
+ }
181
+ `,
182
+ 'src/modules/users/users.service.ts': `import type { UserProfile } from './users.types.js';
183
+
184
+ const mockUsers: UserProfile[] = [
185
+ { id: 'usr_1', name: 'Ada Lovelace', email: 'ada@froot.dev', role: 'admin' },
186
+ { id: 'usr_2', name: 'Alan Turing', email: 'alan@froot.dev', role: 'engineer' },
187
+ ];
188
+
189
+ export class UsersService {
190
+ static getAll(): UserProfile[] {
191
+ return mockUsers;
192
+ }
193
+
194
+ static getById(id: string): UserProfile | undefined {
195
+ return mockUsers.find((u) => u.id === id);
196
+ }
197
+ }
198
+ `,
199
+ 'src/modules/users/users.routes.ts': `import { Froot } from 'frootjs';
200
+ import { UsersService } from './users.service.js';
201
+ import { authGuard } from '../../common/guards/auth.guard.js';
202
+
203
+ export const usersModule = new Froot();
204
+
205
+ // Public route: list users
206
+ usersModule.get('/users', (c) => {
207
+ return c.json(UsersService.getAll());
208
+ });
209
+
210
+ // Protected route: user details (guarded by JWT)
211
+ usersModule.get('/users/:id', authGuard, (c) => {
212
+ const id = c.req.param('id');
213
+ const user = UsersService.getById(id);
214
+ if (!user) {
215
+ return c.json({ error: 'User not found' }, 404);
216
+ }
217
+ return c.json(user);
218
+ });
219
+ `,
220
+ 'src/modules/products/products.types.ts': `export interface Product {
221
+ id: string;
222
+ title: string;
223
+ price: number;
224
+ inventory: number;
225
+ }
226
+ `,
227
+ 'src/modules/products/products.service.ts': `import type { Product } from './products.types.js';
228
+
229
+ const productsTable: Product[] = [
230
+ { id: 'prod_1', title: 'High-Performance Microservice', price: 99.0, inventory: 50 },
231
+ { id: 'prod_2', title: 'Real-Time Edge Gateway', price: 149.0, inventory: 25 },
232
+ ];
233
+
234
+ export class ProductsService {
235
+ static list(): Product[] {
236
+ return productsTable;
237
+ }
238
+
239
+ static find(id: string): Product | undefined {
240
+ return productsTable.find((p) => p.id === id);
241
+ }
242
+ }
243
+ `,
244
+ 'src/modules/products/products.routes.ts': `import { Froot } from 'frootjs';
245
+ import { ProductsService } from './products.service.js';
246
+
247
+ export const productsModule = new Froot();
248
+
249
+ productsModule.get('/products', (c) => {
250
+ return c.json(ProductsService.list());
251
+ });
252
+
253
+ productsModule.get('/products/:id', (c) => {
254
+ const id = c.req.param('id');
255
+ const product = ProductsService.find(id);
256
+ if (!product) {
257
+ return c.json({ error: 'Product not found' }, 404);
258
+ }
259
+ return c.json(product);
260
+ });
261
+ `,
262
+ 'src/app.ts': `import { Froot } from 'frootjs';
263
+ import { cors } from 'frootjs/cors';
264
+ import { errorHandler } from './common/filters/error.filter.js';
265
+ import { authModule } from './modules/auth/auth.routes.js';
266
+ import { usersModule } from './modules/users/users.routes.js';
267
+ import { productsModule } from './modules/products/products.routes.js';
268
+
269
+ export const app = new Froot();
270
+
271
+ // Global middleware & filters
272
+ app.use(cors());
273
+ app.onError(errorHandler);
274
+
275
+ // Mount feature modules under /api prefix
276
+ app.route('/api', authModule);
277
+ app.route('/api', usersModule);
278
+ app.route('/api', productsModule);
279
+
280
+ // Health check
281
+ app.get('/health', (c) => {
282
+ return c.json({
283
+ status: 'ok',
284
+ uptime: process.uptime(),
285
+ modules: ['auth', 'users', 'products'],
286
+ });
287
+ });
288
+ `,
289
+ 'src/server.ts': `import { app } from './app.js';
290
+
291
+ const PORT = Number(process.env.PORT) || 3000;
292
+
293
+ app.listen(PORT, () => {
294
+ console.log(\`Modular Froot Server running on http://localhost:\${PORT}\`);
295
+ });
296
+ `,
297
+ };
298
+ },
299
+ };
300
+ //# sourceMappingURL=modular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modular.js","sourceRoot":"","sources":["../../src/templates/modular.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpG,MAAM,CAAC,MAAM,eAAe,GAAuB;IACjD,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,qCAAqC;IAC3C,WAAW,EAAE,+EAA+E;IAC5F,QAAQ,EAAE,CAAC,WAAmB,EAAmB,EAAE;QACjD,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACP,GAAG,EAAE,+CAA+C;oBACpD,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,qBAAqB;oBAC5B,IAAI,EAAE,6BAA6B;iBACpC;gBACD,YAAY,EAAE;oBACZ,OAAO,EAAE,QAAQ;iBAClB;gBACD,eAAe,EAAE;oBACf,aAAa,EAAE,UAAU;oBACzB,UAAU,EAAE,QAAQ;iBACrB;aACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI;YAER,eAAe,EAAE,eAAe;YAChC,YAAY,EAAE,gBAAgB;YAE9B,WAAW,EAAE,KAAK,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0ClC;YAEK,iCAAiC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BxC;YAEK,oCAAoC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyB3C;YAEK,kCAAkC,EAAE;;;;;;;;;;;;;;;;;CAiBzC;YAEK,iCAAiC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyBxC;YAEK,kCAAkC,EAAE;;;;;;CAMzC;YAEK,oCAAoC,EAAE;;;;;;;;;;;;;;;;CAgB3C;YAEK,mCAAmC,EAAE;;;;;;;;;;;;;;;;;;;;CAoB1C;YAEK,wCAAwC,EAAE;;;;;;CAM/C;YAEK,0CAA0C,EAAE;;;;;;;;;;;;;;;;CAgBjD;YAEK,yCAAyC,EAAE;;;;;;;;;;;;;;;;;CAiBhD;YAEK,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BnB;YAEK,eAAe,EAAE;;;;;;;CAOtB;SACI,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MVC / Layered Architecture Template
3
+ * Organizes code by layer: Routes -> Controllers -> Services -> Models.
4
+ */
5
+ import { TemplateDefinition } from './types.js';
6
+ export declare const mvcTemplate: TemplateDefinition;
7
+ //# sourceMappingURL=mvc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mvc.d.ts","sourceRoot":"","sources":["../../src/templates/mvc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAsD,MAAM,YAAY,CAAC;AAEpG,eAAO,MAAM,WAAW,EAAE,kBAwPzB,CAAC"}