create-frootjs 1.0.6 → 1.0.8

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,22 @@
1
+ /**
2
+ * AI Agent Context & Rules Add-on for create-frootjs
3
+ * Generates AGENT.md and .cursorrules so AI assistants (Cursor, Claude, Copilot, Antigravity)
4
+ * instantly understand the exact architecture, conventions, and API methods of the project.
5
+ */
6
+ import { DatabaseOption } from './database.js';
7
+ import { LinterOption } from './linter.js';
8
+ import { TestingOption } from './testing.js';
9
+ export interface AgentContextOptions {
10
+ projectName: string;
11
+ templateId: string;
12
+ templateName: string;
13
+ pkgManager: string;
14
+ database?: DatabaseOption;
15
+ linter?: LinterOption;
16
+ testing?: TestingOption;
17
+ docker?: boolean;
18
+ }
19
+ export declare function generateAgentDoc(opts: AgentContextOptions): string;
20
+ export declare function generateCursorRules(opts: AgentContextOptions): string;
21
+ export declare function applyAgentAddon(files: Record<string, string>, opts: AgentContextOptions): void;
22
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/addons/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAsLlE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAgBrE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,IAAI,EAAE,mBAAmB,GACxB,IAAI,CAGN"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * AI Agent Context & Rules Add-on for create-frootjs
3
+ * Generates AGENT.md and .cursorrules so AI assistants (Cursor, Claude, Copilot, Antigravity)
4
+ * instantly understand the exact architecture, conventions, and API methods of the project.
5
+ */
6
+ export function generateAgentDoc(opts) {
7
+ const { projectName, templateId, templateName, pkgManager, database, linter, testing, docker } = opts;
8
+ let dbSection = '';
9
+ if (database === 'drizzle') {
10
+ dbSection = `
11
+ ### Database: Drizzle ORM + SQLite
12
+ - Schema location: \`src/db/schema.ts\`
13
+ - Database client: \`src/db/index.ts\` (better-sqlite3)
14
+ - Migration push command: \`${pkgManager} run db:push\`
15
+ - Studio GUI command: \`${pkgManager} run db:studio\`
16
+ - When creating tables, define schema in \`schema.ts\` and export relations.
17
+ `;
18
+ }
19
+ else if (database === 'prisma') {
20
+ dbSection = `
21
+ ### Database: Prisma + SQLite
22
+ - Schema location: \`prisma/schema.prisma\`
23
+ - Push schema to database: \`${pkgManager} run db:push\`
24
+ - Generate client: \`${pkgManager} exec prisma generate\`
25
+ - Studio GUI command: \`${pkgManager} run db:studio\`
26
+ `;
27
+ }
28
+ let linterSection = '';
29
+ if (linter === 'biome') {
30
+ linterSection = `
31
+ ### Linting & Formatting: Biome
32
+ - Lint command: \`${pkgManager} run lint\`
33
+ - Format command: \`${pkgManager} run format\`
34
+ - Configuration: \`biome.json\`
35
+ `;
36
+ }
37
+ else if (linter === 'eslint') {
38
+ linterSection = `
39
+ ### Linting & Formatting: ESLint + Prettier
40
+ - Lint command: \`${pkgManager} run lint\`
41
+ - Format command: \`${pkgManager} run format\`
42
+ - Configuration: \`eslint.config.js\` and \`.prettierrc\`
43
+ `;
44
+ }
45
+ let testSection = '';
46
+ if (testing === 'vitest') {
47
+ testSection = `
48
+ ### Testing: Vitest
49
+ - Run tests: \`${pkgManager} test\`
50
+ - Watch mode: \`${pkgManager} run test:watch\`
51
+ - Test files location: \`tests/**/*.test.ts\`
52
+ - Preferred testing pattern: Use \`app.fetch(new Request(...))\` to test routes in-memory without opening network ports.
53
+ `;
54
+ }
55
+ else if (testing === 'node') {
56
+ testSection = `
57
+ ### Testing: Node.js Native Test Runner
58
+ - Run tests: \`${pkgManager} test\`
59
+ - Test files location: \`tests/**/*.test.ts\`
60
+ - Uses \`node:test\` and \`node:assert/strict\`.
61
+ - Preferred testing pattern: Use \`app.fetch(new Request(...))\` to test routes in-memory without opening network ports.
62
+ `;
63
+ }
64
+ let archGuidelines = '';
65
+ if (templateId === 'mvc') {
66
+ archGuidelines = `
67
+ ### Architecture: MVC / Layered Architecture
68
+ - **Controllers** (\`src/controllers/\`): Handle incoming requests, extract params/body, format HTTP responses.
69
+ - **Services** (\`src/services/\`): Contain core business logic, validations, and database interactions.
70
+ - **Models** (\`src/models/\`): Define TypeScript interfaces and domain entity types.
71
+ - **Routes** (\`src/routes/\`): Mount endpoints and bind controller methods using \`new Froot()\`.
72
+ - **Middleware** (\`src/middleware/\`): Cross-cutting concerns (logging, auth, headers).
73
+ `;
74
+ }
75
+ else if (templateId === 'modular') {
76
+ archGuidelines = `
77
+ ### Architecture: Modular Feature Architecture (NestJS-style)
78
+ - **Feature Modules** (\`src/modules/<feature>/\`): Self-contained domain modules containing routes, services, and schemas.
79
+ - **Guards & Filters** (\`src/common/\`): Common auth guards and centralized error filters.
80
+ - To add a new feature: Create a new folder under \`src/modules/\` and mount the router in \`src/app.ts\` using \`app.route('/api', featureModule)\`.
81
+ `;
82
+ }
83
+ else if (templateId === 'streaming') {
84
+ archGuidelines = `
85
+ ### Architecture: Real-Time Streaming & SSE
86
+ - Uses \`streamSSE\` from \`frootjs/streaming\` for Server-Sent Events.
87
+ - Uses \`streamText\` for chunk-by-chunk token and text streaming.
88
+ `;
89
+ }
90
+ else if (templateId === 'websocket') {
91
+ archGuidelines = `
92
+ ### Architecture: WebSockets & Pub/Sub Hub
93
+ - Uses \`upgradeWebSocket\` and \`createHub\` from \`frootjs/ws\` for real-time room communication.
94
+ `;
95
+ }
96
+ else if (templateId === 'openapi') {
97
+ archGuidelines = `
98
+ ### Architecture: OpenAPI 3.1 & Interactive Docs
99
+ - Uses \`app.openapi()\` to auto-generate OpenAPI 3.1 schemas.
100
+ - Uses \`c.describe()\` or route doc options to declare parameters and response models.
101
+ - Interactive documentation UI available at \`/docs\`.
102
+ `;
103
+ }
104
+ else if (templateId === 'fullstack') {
105
+ archGuidelines = `
106
+ ### Architecture: Fullstack JSX & Server Rendering
107
+ - JSX components located in \`src/components/\` using \`frootjs/jsx\`.
108
+ - Routes return \`c.html(<Component />)\` with zero client-side JavaScript overhead.
109
+ `;
110
+ }
111
+ return `# AI Agent Guide: ${projectName}
112
+
113
+ Welcome! This document provides context and conventions for AI assistants (Claude, Cursor, Copilot, Antigravity, Devin) working on this codebase.
114
+
115
+ ## Project Summary
116
+ - **Project Name:** ${projectName}
117
+ - **Framework:** [Froot](https://github.com/orbitnorth/froot) (\`frootjs\`)
118
+ - **Template Architecture:** ${templateName} (\`${templateId}\`)
119
+ - **Package Manager:** \`${pkgManager}\`
120
+ - **Docker Support:** ${docker ? 'Yes (Dockerfile + docker-compose.yml)' : 'No'}
121
+
122
+ ## Essential Commands
123
+ \`\`\`bash
124
+ # Start development server with hot-reload
125
+ ${pkgManager} run dev
126
+
127
+ # Run TypeScript compilation check
128
+ ${pkgManager} run build
129
+
130
+ # Start production server
131
+ ${pkgManager} start
132
+ \`\`\`
133
+ ${testSection}${linterSection}${dbSection}
134
+ ${archGuidelines}
135
+ ## Core Froot API Rules & Conventions
136
+
137
+ ### 1. Handler Signatures
138
+ Handlers receive a single Context object \`c\`:
139
+ \`\`\`ts
140
+ import { Froot } from 'frootjs';
141
+
142
+ const app = new Froot();
143
+
144
+ app.get('/users/:id', async (c) => {
145
+ const id = c.req.param('id');
146
+ const role = c.req.query('role');
147
+ return c.json({ id, role });
148
+ });
149
+ \`\`\`
150
+
151
+ ### 2. Request Data Extraction
152
+ - **Path Parameters:** \`c.req.param('paramName')\`
153
+ - **Query Parameters:** \`c.req.query('queryName')\`
154
+ - **JSON Body:** \`await c.req.json()\`
155
+ - **Headers:** \`c.req.header('authorization')\`
156
+ - **Cookies:** \`c.req.cookie('session')\`
157
+
158
+ ### 3. Response Generation
159
+ - **JSON:** \`c.json(data, statusCode?)\`
160
+ - **Plain Text:** \`c.text(string, statusCode?)\`
161
+ - **HTML:** \`c.html(htmlStringOrJSX, statusCode?)\`
162
+ - **Redirect:** \`c.redirect(url, statusCode?)\`
163
+
164
+ ### 4. Middleware Pattern
165
+ Middleware in Froot uses an onion-style async function:
166
+ \`\`\`ts
167
+ import type { MiddlewareHandler } from 'frootjs';
168
+
169
+ export const timingMiddleware: MiddlewareHandler = async (c, next) => {
170
+ const start = performance.now();
171
+ await next();
172
+ const elapsed = (performance.now() - start).toFixed(2);
173
+ c.header('X-Response-Time', \`\${elapsed}ms\`);
174
+ };
175
+ \`\`\`
176
+
177
+ ### 5. CRITICAL: Anti-Patterns to AVOID
178
+ - **DO NOT** use Express-style response methods: \`res.send()\`, \`res.status().json()\` do NOT exist. Return \`c.json()\` instead.
179
+ - **DO NOT** use \`req.body\` synchronously. Always use \`await c.req.json()\`.
180
+ - **DO NOT** pass errors via \`next(err)\`. Either throw an error or handle it via \`app.onError()\`.
181
+ - **DO NOT** import from deprecated packages \`create-froot\`. The framework package is always \`frootjs\`.
182
+
183
+ ### 6. Testing Conventions
184
+ Always use in-memory Web Standards \`app.fetch(request)\` for fast, port-independent tests:
185
+ \`\`\`ts
186
+ const req = new Request('http://localhost/api/health');
187
+ const res = await app.fetch(req);
188
+ const data = await res.json();
189
+ \`\`\`
190
+ `;
191
+ }
192
+ export function generateCursorRules(opts) {
193
+ return `# Froot Framework Rules (.cursorrules)
194
+ # Project: ${opts.projectName} (${opts.templateName})
195
+
196
+ # Framework Conventions:
197
+ - Web framework is frootjs (TypeScript-native, high performance).
198
+ - Handlers always receive (c) context and must return Response or Promise<Response>.
199
+ - Always use c.json(body, status) or c.text(msg, status).
200
+ - Never use Express-like res.send(), res.status(), req.body.
201
+ - For async bodies, use await c.req.json().
202
+ - Route parameters: c.req.param('id').
203
+ - Query parameters: c.req.query('key').
204
+ - Sub-routers: mount using app.route(prefix, subApp).
205
+ - Package manager: ${opts.pkgManager}. Run tests using ${opts.pkgManager} test.
206
+ - Check AGENT.md for full architectural guidelines.
207
+ `;
208
+ }
209
+ export function applyAgentAddon(files, opts) {
210
+ files['AGENT.md'] = generateAgentDoc(opts);
211
+ files['.cursorrules'] = generateCursorRules(opts);
212
+ }
213
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/addons/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,MAAM,UAAU,gBAAgB,CAAC,IAAyB;IACxD,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAEtG,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,SAAS,GAAG;;;;8BAIc,UAAU;0BACd,UAAU;;CAEnC,CAAC;IACA,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,SAAS,GAAG;;;+BAGe,UAAU;uBAClB,UAAU;0BACP,UAAU;CACnC,CAAC;IACA,CAAC;IAED,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,aAAa,GAAG;;oBAEA,UAAU;sBACR,UAAU;;CAE/B,CAAC;IACA,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,aAAa,GAAG;;oBAEA,UAAU;sBACR,UAAU;;CAE/B,CAAC;IACA,CAAC;IAED,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,WAAW,GAAG;;iBAED,UAAU;kBACT,UAAU;;;CAG3B,CAAC;IACA,CAAC;SAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAC9B,WAAW,GAAG;;iBAED,UAAU;;;;CAI1B,CAAC;IACA,CAAC;IAED,IAAI,cAAc,GAAG,EAAE,CAAC;IACxB,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,cAAc,GAAG;;;;;;;CAOpB,CAAC;IACA,CAAC;SAAM,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACpC,cAAc,GAAG;;;;;CAKpB,CAAC;IACA,CAAC;SAAM,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QACtC,cAAc,GAAG;;;;CAIpB,CAAC;IACA,CAAC;SAAM,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QACtC,cAAc,GAAG;;;CAGpB,CAAC;IACA,CAAC;SAAM,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACpC,cAAc,GAAG;;;;;CAKpB,CAAC;IACA,CAAC;SAAM,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QACtC,cAAc,GAAG;;;;CAIpB,CAAC;IACA,CAAC;IAED,OAAO,qBAAqB,WAAW;;;;;sBAKnB,WAAW;;+BAEF,YAAY,OAAO,UAAU;2BACjC,UAAU;wBACb,MAAM,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,IAAI;;;;;EAK7E,UAAU;;;EAGV,UAAU;;;EAGV,UAAU;;EAEV,WAAW,GAAG,aAAa,GAAG,SAAS;EACvC,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDf,CAAC;AACF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAyB;IAC3D,OAAO;aACI,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,YAAY;;;;;;;;;;;qBAW9B,IAAI,CAAC,UAAU,qBAAqB,IAAI,CAAC,UAAU;;CAEvE,CAAC;AACF,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAA6B,EAC7B,IAAyB;IAEzB,KAAK,CAAC,UAAU,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,CAAC,cAAc,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Database & ORM Add-on for create-frootjs
3
+ * Injects Drizzle ORM or Prisma into generated projects with SQLite starters.
4
+ */
5
+ export type DatabaseOption = 'none' | 'drizzle' | 'prisma';
6
+ export interface PackageJsonLike {
7
+ scripts?: Record<string, string>;
8
+ dependencies?: Record<string, string>;
9
+ devDependencies?: Record<string, string>;
10
+ [key: string]: unknown;
11
+ }
12
+ export declare function applyDatabaseAddon(files: Record<string, string>, dbOption: DatabaseOption): void;
13
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/addons/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,QAAQ,EAAE,cAAc,GACvB,IAAI,CAuFN"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Database & ORM Add-on for create-frootjs
3
+ * Injects Drizzle ORM or Prisma into generated projects with SQLite starters.
4
+ */
5
+ export function applyDatabaseAddon(files, dbOption) {
6
+ if (dbOption === 'none')
7
+ return;
8
+ const pkgJsonStr = files['package.json'];
9
+ if (!pkgJsonStr)
10
+ return;
11
+ const pkg = JSON.parse(pkgJsonStr);
12
+ pkg.scripts = pkg.scripts || {};
13
+ pkg.dependencies = pkg.dependencies || {};
14
+ pkg.devDependencies = pkg.devDependencies || {};
15
+ if (dbOption === 'drizzle') {
16
+ pkg.dependencies['drizzle-orm'] = '^0.39.0';
17
+ pkg.dependencies['better-sqlite3'] = '^11.8.0';
18
+ pkg.devDependencies['@types/better-sqlite3'] = '^7.6.12';
19
+ pkg.devDependencies['drizzle-kit'] = '^0.30.0';
20
+ pkg.scripts['db:push'] = 'drizzle-kit push';
21
+ pkg.scripts['db:studio'] = 'drizzle-kit studio';
22
+ files['drizzle.config.ts'] = `import { defineConfig } from 'drizzle-kit';
23
+
24
+ export default defineConfig({
25
+ schema: './src/db/schema.ts',
26
+ out: './drizzle',
27
+ dialect: 'sqlite',
28
+ dbCredentials: {
29
+ url: 'sqlite.db',
30
+ },
31
+ });
32
+ `;
33
+ files['src/db/schema.ts'] = `import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
34
+
35
+ export const users = sqliteTable('users', {
36
+ id: text('id').primaryKey(),
37
+ name: text('name').notNull(),
38
+ email: text('email').notNull().unique(),
39
+ createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
40
+ });
41
+
42
+ export type User = typeof users.$inferSelect;
43
+ export type NewUser = typeof users.$inferInsert;
44
+ `;
45
+ files['src/db/index.ts'] = `import Database from 'better-sqlite3';
46
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
47
+ import * as schema from './schema.js';
48
+
49
+ const sqlite = new Database('sqlite.db');
50
+ export const db = drizzle(sqlite, { schema });
51
+ export * from './schema.js';
52
+ `;
53
+ }
54
+ else if (dbOption === 'prisma') {
55
+ pkg.dependencies['@prisma/client'] = '^6.4.0';
56
+ pkg.devDependencies['prisma'] = '^6.4.0';
57
+ pkg.scripts['db:push'] = 'prisma db push';
58
+ pkg.scripts['db:studio'] = 'prisma studio';
59
+ pkg.scripts['db:generate'] = 'prisma generate';
60
+ files['prisma/schema.prisma'] = `datasource db {
61
+ provider = "sqlite"
62
+ url = "file:./dev.db"
63
+ }
64
+
65
+ generator client {
66
+ provider = "prisma-client-js"
67
+ }
68
+
69
+ model User {
70
+ id String @id @default(cuid())
71
+ name String
72
+ email String @unique
73
+ createdAt DateTime @default(now())
74
+ }
75
+ `;
76
+ files['src/db/index.ts'] = `import { PrismaClient } from '@prisma/client';
77
+
78
+ export const prisma = new PrismaClient();
79
+ export * from '@prisma/client';
80
+ `;
81
+ }
82
+ // Update package.json
83
+ files['package.json'] = JSON.stringify(pkg, null, 2) + '\n';
84
+ }
85
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/addons/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,UAAU,kBAAkB,CAChC,KAA6B,EAC7B,QAAwB;IAExB,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO;IAEhC,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,GAAG,GAAoB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpD,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAChC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IAC1C,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC;IAEhD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;QAC5C,GAAG,CAAC,YAAY,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC;QAC/C,GAAG,CAAC,eAAe,CAAC,uBAAuB,CAAC,GAAG,SAAS,CAAC;QACzD,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;QAE/C,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,kBAAkB,CAAC;QAC5C,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,oBAAoB,CAAC;QAEhD,KAAK,CAAC,mBAAmB,CAAC,GAAG;;;;;;;;;;CAUhC,CAAC;QAEE,KAAK,CAAC,kBAAkB,CAAC,GAAG;;;;;;;;;;;CAW/B,CAAC;QAEE,KAAK,CAAC,iBAAiB,CAAC,GAAG;;;;;;;CAO9B,CAAC;IACA,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,GAAG,CAAC,YAAY,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC;QAC9C,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;QAEzC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC;QAC1C,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,eAAe,CAAC;QAC3C,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;QAE/C,KAAK,CAAC,sBAAsB,CAAC,GAAG;;;;;;;;;;;;;;;CAenC,CAAC;QAEE,KAAK,CAAC,iBAAiB,CAAC,GAAG;;;;CAI9B,CAAC;IACA,CAAC;IAED,sBAAsB;IACtB,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Docker & Containerization Add-on for create-frootjs
3
+ * Generates production-ready multi-stage Dockerfile, docker-compose.yml, and .dockerignore.
4
+ */
5
+ export interface DockerAddonConfig {
6
+ projectName: string;
7
+ pkgManager: 'pnpm' | 'npm' | 'yarn' | 'bun';
8
+ entryPoint: 'dist/server.js' | 'dist/index.js';
9
+ port?: number;
10
+ }
11
+ export declare function applyDockerAddon(files: Record<string, string>, config: DockerAddonConfig): void;
12
+ //# sourceMappingURL=docker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/addons/docker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAC5C,UAAU,EAAE,gBAAgB,GAAG,eAAe,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,MAAM,EAAE,iBAAiB,GACxB,IAAI,CAiEN"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Docker & Containerization Add-on for create-frootjs
3
+ * Generates production-ready multi-stage Dockerfile, docker-compose.yml, and .dockerignore.
4
+ */
5
+ export function applyDockerAddon(files, config) {
6
+ const { projectName, pkgManager, entryPoint, port = 3000 } = config;
7
+ // 1. .dockerignore
8
+ files['.dockerignore'] = `node_modules/
9
+ dist/
10
+ .git/
11
+ .gitignore
12
+ .env
13
+ .env.local
14
+ *.log
15
+ .pnpm-store/
16
+ npm-debug.log*
17
+ yarn-debug.log*
18
+ yarn-error.log*
19
+ `;
20
+ // 2. Multi-stage Dockerfile
21
+ files['Dockerfile'] = `# Stage 1: Build & bundle
22
+ FROM node:22-alpine AS builder
23
+ WORKDIR /app
24
+
25
+ # Enable Corepack for pnpm/yarn
26
+ RUN corepack enable
27
+
28
+ COPY package*.json ./
29
+ ${pkgManager === 'pnpm' ? 'COPY pnpm-lock.yaml ./\nRUN pnpm install --frozen-lockfile' : ''}${pkgManager === 'npm' ? 'COPY package-lock.json* ./\nRUN npm ci' : ''}${pkgManager === 'yarn' ? 'COPY yarn.lock* ./\nRUN yarn install --frozen-lockfile' : ''}${pkgManager === 'bun' ? 'RUN npm install -g bun && bun install' : ''}
30
+
31
+ COPY tsconfig.json ./
32
+ COPY src/ ./src/
33
+ ${files['drizzle.config.ts'] ? 'COPY drizzle.config.ts ./\n' : ''}${files['prisma/schema.prisma'] ? 'COPY prisma/ ./prisma/\nRUN npx prisma generate\n' : ''}
34
+ RUN ${pkgManager === 'bun' ? 'bun' : 'npm'} run build
35
+
36
+ # Stage 2: Lean Production Runtime
37
+ FROM node:22-alpine AS runner
38
+ WORKDIR /app
39
+
40
+ ENV NODE_ENV=production
41
+ ENV PORT=${port}
42
+
43
+ # Run as non-root user
44
+ USER node
45
+
46
+ COPY --from=builder --chown=node:node /app/package*.json ./
47
+ COPY --from=builder --chown=node:node /app/node_modules/ ./node_modules/
48
+ COPY --from=builder --chown=node:node /app/dist/ ./dist/
49
+
50
+ EXPOSE ${port}
51
+
52
+ CMD ["node", "${entryPoint}"]
53
+ `;
54
+ // 3. docker-compose.yml
55
+ files['docker-compose.yml'] = `services:
56
+ ${projectName}:
57
+ build:
58
+ context: .
59
+ dockerfile: Dockerfile
60
+ ports:
61
+ - "${port}:${port}"
62
+ environment:
63
+ - NODE_ENV=production
64
+ - PORT=${port}
65
+ restart: unless-stopped
66
+ `;
67
+ }
68
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/addons/docker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,UAAU,gBAAgB,CAC9B,KAA6B,EAC7B,MAAyB;IAEzB,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAEpE,mBAAmB;IACnB,KAAK,CAAC,eAAe,CAAC,GAAG;;;;;;;;;;;CAW1B,CAAC;IAEA,4BAA4B;IAC5B,KAAK,CAAC,YAAY,CAAC,GAAG;;;;;;;;EAQtB,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,4DAA4D,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,wDAAwD,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,EAAE;;;;EAI9T,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,mDAAmD,CAAC,CAAC,CAAC,EAAE;MACtJ,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;;;;;;;WAO/B,IAAI;;;;;;;;;SASN,IAAI;;gBAEG,UAAU;CACzB,CAAC;IAEA,wBAAwB;IACxB,KAAK,CAAC,oBAAoB,CAAC,GAAG;IAC5B,WAAW;;;;;WAKJ,IAAI,IAAI,IAAI;;;eAGR,IAAI;;CAElB,CAAC;AACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Linter & Code Formatter Add-on for create-frootjs
3
+ * Injects Biome (Rust-based ultra-fast linter) or ESLint + Prettier into generated projects.
4
+ */
5
+ export type LinterOption = 'none' | 'biome' | 'eslint';
6
+ export declare function applyLinterAddon(files: Record<string, string>, linter: LinterOption): void;
7
+ //# sourceMappingURL=linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../../src/addons/linter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AASvD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,MAAM,EAAE,YAAY,GACnB,IAAI,CA8EN"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Linter & Code Formatter Add-on for create-frootjs
3
+ * Injects Biome (Rust-based ultra-fast linter) or ESLint + Prettier into generated projects.
4
+ */
5
+ export function applyLinterAddon(files, linter) {
6
+ if (linter === 'none')
7
+ return;
8
+ const pkgJsonStr = files['package.json'];
9
+ if (!pkgJsonStr)
10
+ return;
11
+ const pkg = JSON.parse(pkgJsonStr);
12
+ pkg.scripts = pkg.scripts || {};
13
+ pkg.devDependencies = pkg.devDependencies || {};
14
+ if (linter === 'biome') {
15
+ pkg.devDependencies['@biomejs/biome'] = '^1.9.4';
16
+ pkg.scripts['lint'] = 'biome lint src/';
17
+ pkg.scripts['format'] = 'biome format --write src/';
18
+ pkg.scripts['check'] = 'biome check src/';
19
+ files['biome.json'] = `{
20
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
21
+ "vcs": {
22
+ "enabled": true,
23
+ "clientKind": "git",
24
+ "useIgnoreFile": true
25
+ },
26
+ "files": {
27
+ "ignoreUnknown": false,
28
+ "ignore": ["node_modules", "dist"]
29
+ },
30
+ "formatter": {
31
+ "enabled": true,
32
+ "indentStyle": "space",
33
+ "indentWidth": 2,
34
+ "lineWidth": 100
35
+ },
36
+ "linter": {
37
+ "enabled": true,
38
+ "rules": {
39
+ "recommended": true
40
+ }
41
+ },
42
+ "javascript": {
43
+ "formatter": {
44
+ "quoteStyle": "single",
45
+ "semicolons": "always"
46
+ }
47
+ }
48
+ }
49
+ `;
50
+ }
51
+ else if (linter === 'eslint') {
52
+ pkg.devDependencies['eslint'] = '^9.21.0';
53
+ pkg.devDependencies['@eslint/js'] = '^9.21.0';
54
+ pkg.devDependencies['typescript-eslint'] = '^8.25.0';
55
+ pkg.devDependencies['prettier'] = '^3.5.0';
56
+ pkg.scripts['lint'] = 'eslint src/';
57
+ pkg.scripts['format'] = 'prettier --write src/';
58
+ files['eslint.config.js'] = `import js from '@eslint/js';
59
+ import tseslint from 'typescript-eslint';
60
+
61
+ export default tseslint.config(
62
+ js.configs.recommended,
63
+ ...tseslint.configs.recommended,
64
+ {
65
+ ignores: ['dist/**', 'node_modules/**'],
66
+ }
67
+ );
68
+ `;
69
+ files['.prettierrc'] = `{
70
+ "semi": true,
71
+ "singleQuote": true,
72
+ "tabWidth": 2,
73
+ "trailingComma": "es5"
74
+ }
75
+ `;
76
+ }
77
+ files['package.json'] = JSON.stringify(pkg, null, 2) + '\n';
78
+ }
79
+ //# sourceMappingURL=linter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter.js","sourceRoot":"","sources":["../../src/addons/linter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,UAAU,gBAAgB,CAC9B,KAA6B,EAC7B,MAAoB;IAEpB,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO;IAE9B,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,GAAG,GAAoB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpD,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAChC,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC;IAEhD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,GAAG,CAAC,eAAe,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC;QACjD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,iBAAiB,CAAC;QACxC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,2BAA2B,CAAC;QACpD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC;QAE1C,KAAK,CAAC,YAAY,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BzB,CAAC;IACA,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;QAC1C,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;QAC9C,GAAG,CAAC,eAAe,CAAC,mBAAmB,CAAC,GAAG,SAAS,CAAC;QACrD,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QAE3C,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;QACpC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,uBAAuB,CAAC;QAEhD,KAAK,CAAC,kBAAkB,CAAC,GAAG;;;;;;;;;;CAU/B,CAAC;QAEE,KAAK,CAAC,aAAa,CAAC,GAAG;;;;;;CAM1B,CAAC;IACA,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Testing Framework Add-on for create-frootjs
3
+ * Injects Vitest or Node:test suite into generated Froot projects.
4
+ */
5
+ export type TestingOption = 'none' | 'vitest' | 'node';
6
+ export interface TestingAddonOptions {
7
+ projectName: string;
8
+ }
9
+ export declare function applyTestingAddon(files: Record<string, string>, testing: TestingOption, options: TestingAddonOptions): void;
10
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/addons/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;CACrB;AASD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,mBAAmB,GAC3B,IAAI,CA4DN"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Testing Framework Add-on for create-frootjs
3
+ * Injects Vitest or Node:test suite into generated Froot projects.
4
+ */
5
+ export function applyTestingAddon(files, testing, options) {
6
+ if (testing === 'none')
7
+ return;
8
+ const pkgJsonStr = files['package.json'];
9
+ if (!pkgJsonStr)
10
+ return;
11
+ const pkg = JSON.parse(pkgJsonStr);
12
+ pkg.scripts = pkg.scripts || {};
13
+ pkg.devDependencies = pkg.devDependencies || {};
14
+ // Resolve where app is exported
15
+ let appImport = '../src/index.js';
16
+ if (files['src/app.ts']) {
17
+ appImport = '../src/app.js';
18
+ }
19
+ else if (files['src/server.ts']) {
20
+ appImport = '../src/server.js';
21
+ }
22
+ if (testing === 'vitest') {
23
+ pkg.devDependencies['vitest'] = '^3.0.0';
24
+ pkg.scripts['test'] = 'vitest run';
25
+ pkg.scripts['test:watch'] = 'vitest';
26
+ files['vitest.config.ts'] = `import { defineConfig } from 'vitest/config';
27
+
28
+ export default defineConfig({
29
+ test: {
30
+ environment: 'node',
31
+ globals: true,
32
+ },
33
+ });
34
+ `;
35
+ files['tests/app.test.ts'] = `import { describe, it, expect } from 'vitest';
36
+ import { app } from '${appImport}';
37
+
38
+ describe('${options.projectName} HTTP tests', () => {
39
+ it('responds with status 200 on GET /', async () => {
40
+ const res = await app.fetch(new Request('http://localhost/'));
41
+ expect(res.status).toBe(200);
42
+ });
43
+ });
44
+ `;
45
+ }
46
+ else if (testing === 'node') {
47
+ pkg.scripts['test'] = 'node --test tests/*.test.ts';
48
+ files['tests/app.test.ts'] = `import { describe, it } from 'node:test';
49
+ import assert from 'node:assert/strict';
50
+ import { app } from '${appImport}';
51
+
52
+ describe('${options.projectName} HTTP tests', () => {
53
+ it('responds with status 200 on GET /', async () => {
54
+ const res = await app.fetch(new Request('http://localhost/'));
55
+ assert.equal(res.status, 200);
56
+ });
57
+ });
58
+ `;
59
+ }
60
+ files['package.json'] = JSON.stringify(pkg, null, 2) + '\n';
61
+ }
62
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/addons/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,MAAM,UAAU,iBAAiB,CAC/B,KAA6B,EAC7B,OAAsB,EACtB,OAA4B;IAE5B,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO;IAE/B,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,GAAG,GAAoB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpD,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAChC,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC;IAEhD,gCAAgC;IAChC,IAAI,SAAS,GAAG,iBAAiB,CAAC;IAClC,IAAI,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;QACxB,SAAS,GAAG,eAAe,CAAC;IAC9B,CAAC;SAAM,IAAI,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QAClC,SAAS,GAAG,kBAAkB,CAAC;IACjC,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;QACzC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;QACnC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;QAErC,KAAK,CAAC,kBAAkB,CAAC,GAAG;;;;;;;;CAQ/B,CAAC;QAEE,KAAK,CAAC,mBAAmB,CAAC,GAAG;uBACV,SAAS;;YAEpB,OAAO,CAAC,WAAW;;;;;;CAM9B,CAAC;IACA,CAAC;SAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAC9B,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,6BAA6B,CAAC;QAEpD,KAAK,CAAC,mBAAmB,CAAC,GAAG;;uBAEV,SAAS;;YAEpB,OAAO,CAAC,WAAW;;;;;;CAM9B,CAAC;IACA,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC9D,CAAC"}
@@ -3,6 +3,9 @@
3
3
  * Writes template files to disk, initializes git, and executes dependency installation with animated spinners.
4
4
  */
5
5
  import { TemplateDefinition } from './templates/index.js';
6
+ import { DatabaseOption } from './addons/database.js';
7
+ import { LinterOption } from './addons/linter.js';
8
+ import { TestingOption } from './addons/testing.js';
6
9
  export interface ScaffoldOptions {
7
10
  targetDir: string;
8
11
  projectName: string;
@@ -10,6 +13,11 @@ export interface ScaffoldOptions {
10
13
  pkgManager: 'pnpm' | 'npm' | 'yarn' | 'bun';
11
14
  gitInit: boolean;
12
15
  installDeps: boolean;
16
+ database?: DatabaseOption;
17
+ docker?: boolean;
18
+ linter?: LinterOption;
19
+ testing?: TestingOption;
20
+ agentRules?: boolean;
13
21
  }
14
22
  export interface ScaffoldResult {
15
23
  targetDir: string;
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK1D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAwDvF"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AAKvE,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAmGvF"}
package/dist/generator.js CHANGED
@@ -7,14 +7,44 @@ import * as path from 'node:path';
7
7
  import { exec } from 'node:child_process';
8
8
  import { promisify } from 'node:util';
9
9
  import { c, Spinner } from './ui.js';
10
+ import { applyDatabaseAddon } from './addons/database.js';
11
+ import { applyDockerAddon } from './addons/docker.js';
12
+ import { applyLinterAddon } from './addons/linter.js';
13
+ import { applyTestingAddon } from './addons/testing.js';
14
+ import { applyAgentAddon } from './addons/agent.js';
10
15
  const execAsync = promisify(exec);
11
16
  export async function scaffoldProject(options) {
12
- const { targetDir, projectName, template, pkgManager, gitInit, installDeps } = options;
17
+ const { targetDir, projectName, template, pkgManager, gitInit, installDeps, database, docker, linter, testing, agentRules = true, } = options;
13
18
  // 1. Ensure target directory exists
14
19
  await fs.mkdir(targetDir, { recursive: true });
15
20
  // 2. Generate files map from template
16
21
  const writeSpinner = new Spinner(`Scaffolding ${template.name} template`).start();
17
22
  const files = template.generate(projectName);
23
+ if (database && database !== 'none') {
24
+ applyDatabaseAddon(files, database);
25
+ }
26
+ if (docker) {
27
+ const entryPoint = template.id === 'minimal' ? 'dist/index.js' : 'dist/server.js';
28
+ applyDockerAddon(files, { projectName, pkgManager, entryPoint });
29
+ }
30
+ if (linter && linter !== 'none') {
31
+ applyLinterAddon(files, linter);
32
+ }
33
+ if (testing && testing !== 'none') {
34
+ applyTestingAddon(files, testing, { projectName });
35
+ }
36
+ if (agentRules) {
37
+ applyAgentAddon(files, {
38
+ projectName,
39
+ templateId: template.id,
40
+ templateName: template.name,
41
+ pkgManager,
42
+ database,
43
+ linter,
44
+ testing,
45
+ docker,
46
+ });
47
+ }
18
48
  const fileKeys = Object.keys(files);
19
49
  // 3. Write each file to destination
20
50
  for (const relativePath of fileKeys) {
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAgB,MAAM,SAAS,CAAC;AAEnD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAkBlC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEvF,oCAAoC;IACpC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,sCAAsC;IACtC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,eAAe,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;IAClF,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEpC,oCAAoC;IACpC,KAAK,MAAM,YAAY,IAAI,QAAQ,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAE,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAElH,wBAAwB;IACxB,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC,CAAC,KAAK,EAAE,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;YAChD,cAAc,GAAG,IAAI,CAAC;YACtB,UAAU,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,UAAU,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QACrF,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;YAC3C,MAAM,GAAG,GAAG,KAAK,IAAI,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;YAC7E,MAAM,SAAS,CAAC,GAAG,GAAG,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;YACtD,aAAa,GAAG,IAAI,CAAC;YACrB,UAAU,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,IAAI,GAAG,UAAU,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAClF,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,UAAU,CAAC,IAAI,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO;QACL,SAAS;QACT,YAAY,EAAE,QAAQ,CAAC,MAAM;QAC7B,cAAc;QACd,aAAa;KACd,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAgB,MAAM,SAAS,CAAC;AACnD,OAAO,EAAkB,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAgB,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAiB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAuBlC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,MAAM,EACJ,SAAS,EACT,WAAW,EACX,QAAQ,EACR,UAAU,EACV,OAAO,EACP,WAAW,EACX,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,UAAU,GAAG,IAAI,GAClB,GAAG,OAAO,CAAC;IAEZ,oCAAoC;IACpC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,sCAAsC;IACtC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,eAAe,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;IAClF,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE7C,IAAI,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACpC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAClF,gBAAgB,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAChC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAClC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,eAAe,CAAC,KAAK,EAAE;YACrB,WAAW;YACX,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,UAAU;YACV,QAAQ;YACR,MAAM;YACN,OAAO;YACP,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEpC,oCAAoC;IACpC,KAAK,MAAM,YAAY,IAAI,QAAQ,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAE,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAElH,wBAAwB;IACxB,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC,CAAC,KAAK,EAAE,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;YAChD,cAAc,GAAG,IAAI,CAAC;YACtB,UAAU,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,UAAU,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QACrF,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;YAC3C,MAAM,GAAG,GAAG,KAAK,IAAI,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;YAC7E,MAAM,SAAS,CAAC,GAAG,GAAG,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;YACtD,aAAa,GAAG,IAAI,CAAC;YACrB,UAAU,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,IAAI,GAAG,UAAU,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAClF,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,UAAU,CAAC,IAAI,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO;QACL,SAAS;QACT,YAAY,EAAE,QAAQ,CAAC,MAAM;QAC7B,cAAc;QACd,aAAa;KACd,CAAC;AACJ,CAAC"}
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import * as fs from 'node:fs';
8
8
  import { printBanner, printStep, printError, printNextSteps, promptText, promptSelect, promptConfirm, c, } from './ui.js';
9
9
  import { TEMPLATES, TEMPLATE_LIST, getTemplate } from './templates/index.js';
10
10
  import { scaffoldProject } from './generator.js';
11
- const VERSION = '1.0.6';
11
+ const VERSION = '1.0.8';
12
12
  function parseCliArgs(argv) {
13
13
  const args = {};
14
14
  const raw = argv.slice(2);
@@ -20,6 +20,9 @@ function parseCliArgs(argv) {
20
20
  else if (item === '--version' || item === '-v') {
21
21
  args.version = true;
22
22
  }
23
+ else if (item === '--schema' || item === '--json-schema' || item === 'schema') {
24
+ args.schema = true;
25
+ }
23
26
  else if (item === '--yes' || item === '-y') {
24
27
  args.yes = true;
25
28
  }
@@ -35,6 +38,39 @@ function parseCliArgs(argv) {
35
38
  else if (item === '--no-install') {
36
39
  args.install = false;
37
40
  }
41
+ else if (item === '--docker') {
42
+ args.docker = true;
43
+ }
44
+ else if (item === '--no-docker') {
45
+ args.docker = false;
46
+ }
47
+ else if (item === '--agent' || item === '--ai') {
48
+ args.agent = true;
49
+ }
50
+ else if (item === '--no-agent' || item === '--no-ai') {
51
+ args.agent = false;
52
+ }
53
+ else if (item === '--biome') {
54
+ args.linter = 'biome';
55
+ }
56
+ else if (item === '--eslint') {
57
+ args.linter = 'eslint';
58
+ }
59
+ else if (item === '--linter') {
60
+ args.linter = raw[++i];
61
+ }
62
+ else if (item.startsWith('--linter=')) {
63
+ args.linter = item.split('=')[1];
64
+ }
65
+ else if (item === '--vitest') {
66
+ args.testing = 'vitest';
67
+ }
68
+ else if (item === '--test' || item === '--testing') {
69
+ args.testing = raw[++i];
70
+ }
71
+ else if (item.startsWith('--testing=') || item.startsWith('--test=')) {
72
+ args.testing = item.split('=')[1];
73
+ }
38
74
  else if (item === '--template' || item === '-t') {
39
75
  args.template = raw[++i];
40
76
  }
@@ -47,6 +83,12 @@ function parseCliArgs(argv) {
47
83
  else if (item.startsWith('--pm=')) {
48
84
  args.pkgManager = item.split('=')[1];
49
85
  }
86
+ else if (item === '--db' || item === '--database') {
87
+ args.db = raw[++i];
88
+ }
89
+ else if (item.startsWith('--db=')) {
90
+ args.db = item.split('=')[1];
91
+ }
50
92
  else if (!item.startsWith('-') && !args.targetDir) {
51
93
  args.targetDir = item;
52
94
  }
@@ -69,6 +111,12 @@ function printUsage() {
69
111
  • fullstack Server-rendered JSX views
70
112
  • minimal Lean single-file starter
71
113
  --pm <manager> Package manager: pnpm | npm | yarn | bun
114
+ --db <orm> Database ORM: none | drizzle | prisma
115
+ --linter <tool> Linter & formatter: none | biome | eslint
116
+ --test <tool> Testing framework: none | vitest | node
117
+ --agent / --no-agent Generate AGENT.md & .cursorrules for AI assistants
118
+ --schema Output machine-readable JSON schema for AI agents
119
+ --docker / --no-docker Generate Docker setup
72
120
  --git / --no-git Initialize a git repository
73
121
  --install / --no-install Automatically install dependencies
74
122
  -y, --yes Accept all defaults non-interactively
@@ -76,6 +124,75 @@ function printUsage() {
76
124
  -h, --help Display help information
77
125
  `);
78
126
  }
127
+ function printAgentSchema() {
128
+ const schema = {
129
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
130
+ name: 'create-frootjs',
131
+ version: VERSION,
132
+ description: 'CLI generator for scaffolding high-performance Froot TypeScript web applications',
133
+ usage: 'npm create frootjs [project-directory] [options]',
134
+ nonInteractiveFlag: '-y or --yes',
135
+ templates: TEMPLATE_LIST.map((t) => ({
136
+ id: t.id,
137
+ name: t.name,
138
+ description: t.description,
139
+ })),
140
+ options: {
141
+ template: {
142
+ flag: '-t, --template <name>',
143
+ choices: ['mvc', 'modular', 'streaming', 'websocket', 'openapi', 'fullstack', 'minimal'],
144
+ default: 'mvc',
145
+ description: 'Architectural pattern of the scaffolded application',
146
+ },
147
+ database: {
148
+ flag: '--db <orm>',
149
+ choices: ['none', 'drizzle', 'prisma'],
150
+ default: 'none',
151
+ description: 'Database ORM integration',
152
+ },
153
+ docker: {
154
+ flag: '--docker / --no-docker',
155
+ type: 'boolean',
156
+ default: false,
157
+ description: 'Generate multi-stage Dockerfile and docker-compose.yml',
158
+ },
159
+ linter: {
160
+ flag: '--linter <tool>',
161
+ choices: ['none', 'biome', 'eslint'],
162
+ default: 'none',
163
+ description: 'Code quality and linting tool',
164
+ },
165
+ testing: {
166
+ flag: '--test <framework>',
167
+ choices: ['none', 'vitest', 'node'],
168
+ default: 'none',
169
+ description: 'Unit testing suite',
170
+ },
171
+ agentRules: {
172
+ flag: '--agent / --no-agent',
173
+ type: 'boolean',
174
+ default: true,
175
+ description: 'Generate AGENT.md and .cursorrules for AI agents and coding assistants',
176
+ },
177
+ packageManager: {
178
+ flag: '--pm <manager>',
179
+ choices: ['pnpm', 'npm', 'yarn', 'bun'],
180
+ default: 'auto-detected',
181
+ description: 'Package manager for dependency installation',
182
+ },
183
+ },
184
+ recipes: {
185
+ enterpriseApi: 'npm create frootjs my-app -t modular --db drizzle --docker --linter biome --test vitest -y',
186
+ mvcCrudApp: 'npm create frootjs my-app -t mvc --db drizzle --linter biome --test vitest -y',
187
+ restApiScalarDocs: 'npm create frootjs my-app -t openapi --db prisma --linter eslint --test node -y',
188
+ realtimeWebSocket: 'npm create frootjs my-app -t websocket --linter biome --test vitest -y',
189
+ aiStreamingSSE: 'npm create frootjs my-app -t streaming --linter biome --test vitest -y',
190
+ fullstackJsx: 'npm create frootjs my-app -t fullstack --linter biome --test vitest -y',
191
+ minimalStarter: 'npm create frootjs my-app -t minimal --docker --test vitest -y',
192
+ },
193
+ };
194
+ console.log(JSON.stringify(schema, null, 2));
195
+ }
79
196
  /** Detect which package manager invoked create-frootjs */
80
197
  function detectCurrentPackageManager() {
81
198
  const userAgent = process.env.npm_config_user_agent || '';
@@ -89,6 +206,10 @@ function detectCurrentPackageManager() {
89
206
  }
90
207
  async function main() {
91
208
  const args = parseCliArgs(process.argv);
209
+ if (args.schema) {
210
+ printAgentSchema();
211
+ return;
212
+ }
92
213
  if (args.version) {
93
214
  console.log(`create-frootjs v${VERSION}`);
94
215
  return;
@@ -106,7 +227,7 @@ async function main() {
106
227
  targetDir = 'froot-app';
107
228
  }
108
229
  else {
109
- printStep(1, 4, 'Directory');
230
+ printStep(1, 7, 'Directory');
110
231
  targetDir = await promptText('Project directory:', 'my-froot-app', (input) => {
111
232
  if (!input.trim())
112
233
  return 'Project name cannot be empty';
@@ -121,7 +242,7 @@ async function main() {
121
242
  if (fs.existsSync(resolvedTarget)) {
122
243
  const existingFiles = fs.readdirSync(resolvedTarget);
123
244
  if (existingFiles.length > 0 && !args.yes) {
124
- printStep(1, 4, 'Directory warning');
245
+ printStep(1, 7, 'Directory warning');
125
246
  const proceed = await promptConfirm(`Directory "${targetDir}" is not empty. Continue?`, false);
126
247
  console.log();
127
248
  if (!proceed) {
@@ -142,7 +263,7 @@ async function main() {
142
263
  selectedTemplate = TEMPLATES['mvc'];
143
264
  }
144
265
  else {
145
- printStep(2, 4, 'Template');
266
+ printStep(2, 7, 'Template');
146
267
  const choice = await promptSelect('Select a template:', TEMPLATE_LIST.map((t) => ({
147
268
  value: t.id,
148
269
  label: t.name,
@@ -152,11 +273,44 @@ async function main() {
152
273
  console.log();
153
274
  }
154
275
  }
155
- // 3. Package Manager Selection
276
+ // 3. Database ORM Selection
277
+ let dbOption = args.db || 'none';
278
+ if (!args.db && !args.yes) {
279
+ printStep(3, 7, 'Database');
280
+ dbOption = await promptSelect('Include database ORM?', [
281
+ { value: 'none', label: 'None', hint: 'In-memory / no database' },
282
+ { value: 'drizzle', label: 'Drizzle', hint: 'Drizzle ORM & SQLite' },
283
+ { value: 'prisma', label: 'Prisma', hint: 'Prisma & SQLite starter' },
284
+ ]);
285
+ console.log();
286
+ }
287
+ // 4. Linter & Formatter Selection
288
+ let linterOption = args.linter || 'none';
289
+ if (!args.linter && !args.yes) {
290
+ printStep(4, 7, 'Linter & Formatter');
291
+ linterOption = await promptSelect('Code quality tooling:', [
292
+ { value: 'none', label: 'None', hint: 'No linter config' },
293
+ { value: 'biome', label: 'Biome', hint: 'Fast Rust linter & formatter' },
294
+ { value: 'eslint', label: 'ESLint', hint: 'ESLint 9 & Prettier' },
295
+ ]);
296
+ console.log();
297
+ }
298
+ // 5. Testing Framework Selection
299
+ let testingOption = args.testing || 'none';
300
+ if (!args.testing && !args.yes) {
301
+ printStep(5, 7, 'Testing');
302
+ testingOption = await promptSelect('Testing framework:', [
303
+ { value: 'vitest', label: 'Vitest', hint: 'Fast modern unit test runner' },
304
+ { value: 'node', label: 'Node:test', hint: 'Native Node.js test runner' },
305
+ { value: 'none', label: 'None', hint: 'No testing setup' },
306
+ ]);
307
+ console.log();
308
+ }
309
+ // 6. Package Manager Selection
156
310
  const detectedPm = detectCurrentPackageManager();
157
311
  let pkgManager = args.pkgManager || detectedPm;
158
312
  if (!args.pkgManager && !args.yes) {
159
- printStep(3, 4, 'Package manager');
313
+ printStep(6, 7, 'Package manager');
160
314
  pkgManager = await promptSelect('Select package manager:', [
161
315
  { value: 'pnpm', label: 'pnpm', hint: 'Fast, disk-efficient' },
162
316
  { value: 'npm', label: 'npm', hint: 'Standard' },
@@ -165,14 +319,18 @@ async function main() {
165
319
  ]);
166
320
  console.log();
167
321
  }
168
- // 4. Git Initialization & Install Preferences
322
+ // 7. Git, Docker & Install Preferences
169
323
  let gitInit = args.git;
324
+ let docker = args.docker;
170
325
  let installDeps = args.install;
171
326
  if (!args.yes) {
172
- printStep(4, 4, 'Preferences');
327
+ printStep(7, 7, 'Preferences');
173
328
  if (gitInit === undefined) {
174
329
  gitInit = await promptConfirm('Initialize git repository?', true);
175
330
  }
331
+ if (docker === undefined) {
332
+ docker = await promptConfirm('Include Docker container setup?', false);
333
+ }
176
334
  if (installDeps === undefined) {
177
335
  installDeps = await promptConfirm(`Install dependencies with ${pkgManager}?`, true);
178
336
  }
@@ -181,10 +339,12 @@ async function main() {
181
339
  else {
182
340
  if (gitInit === undefined)
183
341
  gitInit = true;
342
+ if (docker === undefined)
343
+ docker = false;
184
344
  if (installDeps === undefined)
185
345
  installDeps = true;
186
346
  }
187
- // 5. Scaffold Project
347
+ // 8. Scaffold Project
188
348
  const startTime = performance.now();
189
349
  try {
190
350
  const result = await scaffoldProject({
@@ -194,6 +354,11 @@ async function main() {
194
354
  pkgManager,
195
355
  gitInit: Boolean(gitInit),
196
356
  installDeps: Boolean(installDeps),
357
+ database: dbOption,
358
+ docker: Boolean(docker),
359
+ linter: linterOption,
360
+ testing: testingOption,
361
+ agentRules: args.agent !== false,
197
362
  });
198
363
  const durationMs = Math.round(performance.now() - startTime);
199
364
  // 6. Print stylized next steps card
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EACL,WAAW,EACX,SAAS,EACT,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,aAAa,EACb,CAAC,GACF,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,OAAO,GAAG,OAAO,CAAC;AAmBxB,SAAS,YAAY,CAAC,IAAc;IAClC,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;QAErB,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,eAAe,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC;QACnB,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;aAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACtB,CAAC;aAAM,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACjD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;QACxB,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QACzB,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,CAAyB,CAAC;QACjD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAyB,CAAC;QAC3D,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;QAC1B,CAAC;aAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,CAAC,CAA0B,CAAC;QACnD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAA0B,CAAC;QAC7D,CAAC;aAAM,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClD,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC,CAA6B,CAAC;QACzD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAA6B,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACpD,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,CAAqB,CAAC;QACzC,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAqB,CAAC;QACnD,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CAAC,GAAG,CAAC;IACV,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,KAAK;;;;IAItB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;CAqB3B,CAAC,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,8CAA8C;QACvD,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,kFAAkF;QAC/F,KAAK,EAAE,kDAAkD;QACzD,kBAAkB,EAAE,aAAa;QACjC,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC;QACH,OAAO,EAAE;YACP,QAAQ,EAAE;gBACR,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC;gBACxF,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,qDAAqD;aACnE;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;gBACtC,OAAO,EAAE,MAAM;gBACf,WAAW,EAAE,0BAA0B;aACxC;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,wDAAwD;aACtE;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;gBACpC,OAAO,EAAE,MAAM;gBACf,WAAW,EAAE,+BAA+B;aAC7C;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,oBAAoB;gBAC1B,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;gBACnC,OAAO,EAAE,MAAM;gBACf,WAAW,EAAE,oBAAoB;aAClC;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,sBAAsB;gBAC5B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,wEAAwE;aACtF;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC;gBACvC,OAAO,EAAE,eAAe;gBACxB,WAAW,EAAE,6CAA6C;aAC3D;SACF;QACD,OAAO,EAAE;YACP,aAAa,EAAE,4FAA4F;YAC3G,UAAU,EAAE,+EAA+E;YAC3F,iBAAiB,EAAE,iFAAiF;YACpG,iBAAiB,EAAE,wEAAwE;YAC3F,cAAc,EAAE,wEAAwE;YACxF,YAAY,EAAE,wEAAwE;YACtF,cAAc,EAAE,gEAAgE;SACjF;KACF,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,0DAA0D;AAC1D,SAAS,2BAA2B;IAClC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAC1D,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,gBAAgB,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,UAAU,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,WAAW,CAAC,OAAO,CAAC,CAAC;IAErB,sCAAsC;IACtC,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,WAAW,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;YAC7B,SAAS,GAAG,MAAM,UAAU,CAAC,oBAAoB,EAAE,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC3E,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;oBAAE,OAAO,8BAA8B,CAAC;gBACzD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAElD,gDAAgD;IAChD,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAClC,MAAM,aAAa,GAAG,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QACrD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1C,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,mBAAmB,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,MAAM,aAAa,CACjC,cAAc,SAAS,2BAA2B,EAClD,KAAK,CACN,CAAC;YACF,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,UAAU,CAAC,kBAAkB,CAAC,CAAC;gBAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9E,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvC,UAAU,CAAC,qBAAqB,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAE,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;YAC5B,MAAM,MAAM,GAAG,MAAM,YAAY,CAC/B,oBAAoB,EACpB,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxB,KAAK,EAAE,CAAC,CAAC,EAAE;gBACX,KAAK,EAAE,CAAC,CAAC,IAAI;gBACb,IAAI,EAAE,CAAC,CAAC,WAAW;aACpB,CAAC,CAAC,CACJ,CAAC;YACF,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAE,CAAC;YACxC,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,IAAI,QAAQ,GAAG,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC;IACjC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;QAC5B,QAAQ,GAAG,MAAM,YAAY,CAC3B,uBAAuB,EACvB;YACE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE;YACjE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,sBAAsB,EAAE;YACpE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,yBAAyB,EAAE;SACtE,CACF,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,kCAAkC;IAClC,IAAI,YAAY,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;IACzC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC,CAAC;QACtC,YAAY,GAAG,MAAM,YAAY,CAC/B,uBAAuB,EACvB;YACE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE;YAC1D,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,8BAA8B,EAAE;YACxE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,EAAE;SAClE,CACF,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,iCAAiC;IACjC,IAAI,aAAa,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;IAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QAC3B,aAAa,GAAG,MAAM,YAAY,CAChC,oBAAoB,EACpB;YACE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,8BAA8B,EAAE;YAC1E,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,4BAA4B,EAAE;YACzE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE;SAC3D,CACF,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,+BAA+B;IAC/B,MAAM,UAAU,GAAG,2BAA2B,EAAE,CAAC;IACjD,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC;IAE/C,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACnC,UAAU,GAAG,MAAM,YAAY,CAC7B,yBAAyB,EACzB;YACE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,EAAE;YAC9D,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE;YAChD,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE;YAC1D,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE;SAC3D,CACF,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,uCAAuC;IACvC,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;IACvB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;IAE/B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;QAC/B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,GAAG,MAAM,aAAa,CAAC,4BAA4B,EAAE,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,GAAG,MAAM,aAAa,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,WAAW,GAAG,MAAM,aAAa,CAAC,6BAA6B,UAAU,GAAG,EAAE,IAAI,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;SAAM,CAAC;QACN,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,GAAG,IAAI,CAAC;QAC1C,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,GAAG,KAAK,CAAC;QACzC,IAAI,WAAW,KAAK,SAAS;YAAE,WAAW,GAAG,IAAI,CAAC;IACpD,CAAC;IAED,sBAAsB;IACtB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,SAAS,EAAE,cAAc;YACzB,WAAW;YACX,QAAQ,EAAE,gBAAgB;YAC1B,UAAU;YACV,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;YACzB,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC;YACjC,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;YACvB,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,IAAI,CAAC,KAAK,KAAK,KAAK;SACjC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QAE7D,oCAAoC;QACpC,cAAc,CAAC;YACb,UAAU,EAAE,SAAS;YACrB,UAAU;YACV,YAAY,EAAE,MAAM,CAAC,aAAa;YAClC,IAAI,EAAE,IAAI;YACV,UAAU;SACX,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,UAAU,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1 +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,kBAyT7B,CAAC"}
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,kBAgU7B,CAAC"}
@@ -279,7 +279,14 @@ app.route('/api', authModule);
279
279
  app.route('/api', usersModule);
280
280
  app.route('/api', productsModule);
281
281
 
282
- // Health check
282
+ // Root & Health check
283
+ app.get('/', (c) => {
284
+ return c.json({
285
+ message: 'Welcome to Froot Modular API',
286
+ health: '/health',
287
+ });
288
+ });
289
+
283
290
  app.get('/health', (c) => {
284
291
  return c.json({
285
292
  status: 'ok',
@@ -1 +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,SAAS;IACf,WAAW,EAAE,8BAA8B;IAC3C,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,yBAAyB;oBAC9B,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,GAAG,EAAE,SAAS;oBACd,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BxC;YAEK,oCAAoC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyB3C;YAEK,kCAAkC,EAAE;;;;;;;;;;;;;;;;;CAiBzC;YAEK,iCAAiC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyBxC;YAEK,kCAAkC,EAAE;;;;;;CAMzC;YAEK,oCAAoC,EAAE;;;;;;;;;;;;;;;;;CAiB3C;YAEK,mCAAmC,EAAE;;;;;;;;;;;;;;;;;;;;CAoB1C;YAEK,wCAAwC,EAAE;;;;;;CAM/C;YAEK,0CAA0C,EAAE;;;;;;;;;;;;;;;;;CAiBjD;YAEK,yCAAyC,EAAE;;;;;;;;;;;;;;;;;CAiBhD;YAEK,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BnB;YAEK,eAAe,EAAE;;;;;;;CAOtB;SACI,CAAC;IACJ,CAAC;CACF,CAAC"}
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,SAAS;IACf,WAAW,EAAE,8BAA8B;IAC3C,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,yBAAyB;oBAC9B,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,GAAG,EAAE,SAAS;oBACd,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BxC;YAEK,oCAAoC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyB3C;YAEK,kCAAkC,EAAE;;;;;;;;;;;;;;;;;CAiBzC;YAEK,iCAAiC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;CAyBxC;YAEK,kCAAkC,EAAE;;;;;;CAMzC;YAEK,oCAAoC,EAAE;;;;;;;;;;;;;;;;;CAiB3C;YAEK,mCAAmC,EAAE;;;;;;;;;;;;;;;;;;;;CAoB1C;YAEK,wCAAwC,EAAE;;;;;;CAM/C;YAEK,0CAA0C,EAAE;;;;;;;;;;;;;;;;;CAiBjD;YAEK,yCAAyC,EAAE;;;;;;;;;;;;;;;;;CAiBhD;YAEK,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCnB;YAEK,eAAe,EAAE;;;;;;;CAOtB;SACI,CAAC;IACJ,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "create-frootjs",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Interactive CLI generator for scaffolding high-performance Froot applications",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-frootjs": "./dist/index.js",
8
- "create-froot": "./dist/index.js"
7
+ "create-frootjs": "dist/index.js",
8
+ "create-froot": "dist/index.js"
9
9
  },
10
10
  "main": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",