create-frootjs 0.0.0-stage → 1.0.2

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,17 @@
1
+ /**
2
+ * Template definition types for create-frootjs.
3
+ */
4
+ export interface TemplateFileMap {
5
+ [filePath: string]: string;
6
+ }
7
+ export interface TemplateDefinition {
8
+ id: string;
9
+ name: string;
10
+ description: string;
11
+ generate: (projectName: string) => TemplateFileMap;
12
+ }
13
+ /** Common .gitignore for all templates */
14
+ export declare const COMMON_GITIGNORE = "# Dependencies\nnode_modules/\n.pnpm-store/\n\n# Build Output\ndist/\n*.tsbuildinfo\n\n# Logs & Environment\n*.log\n.env\n.env.local\n\n# Editor\n.vscode/\n.idea/\n.DS_Store\n";
15
+ /** Common tsconfig.json for all templates */
16
+ export declare const COMMON_TSCONFIG = "{\n \"compilerOptions\": {\n \"target\": \"ES2024\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"lib\": [\"ES2024\", \"DOM\", \"DOM.Iterable\"],\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true,\n \"noImplicitAny\": true,\n \"strictNullChecks\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"jsx\": \"react-jsx\",\n \"jsxImportSource\": \"frootjs\"\n },\n \"include\": [\"src/**/*\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n";
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/templates/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,eAAe,CAAC;CACpD;AAED,0CAA0C;AAC1C,eAAO,MAAM,gBAAgB,oLAiB5B,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,eAAe,0oBAsB3B,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Template definition types for create-frootjs.
3
+ */
4
+ /** Common .gitignore for all templates */
5
+ export const COMMON_GITIGNORE = `# Dependencies
6
+ node_modules/
7
+ .pnpm-store/
8
+
9
+ # Build Output
10
+ dist/
11
+ *.tsbuildinfo
12
+
13
+ # Logs & Environment
14
+ *.log
15
+ .env
16
+ .env.local
17
+
18
+ # Editor
19
+ .vscode/
20
+ .idea/
21
+ .DS_Store
22
+ `;
23
+ /** Common tsconfig.json for all templates */
24
+ export const COMMON_TSCONFIG = `{
25
+ "compilerOptions": {
26
+ "target": "ES2024",
27
+ "module": "NodeNext",
28
+ "moduleResolution": "NodeNext",
29
+ "lib": ["ES2024", "DOM", "DOM.Iterable"],
30
+ "declaration": true,
31
+ "declarationMap": true,
32
+ "sourceMap": true,
33
+ "outDir": "./dist",
34
+ "rootDir": "./src",
35
+ "strict": true,
36
+ "noImplicitAny": true,
37
+ "strictNullChecks": true,
38
+ "skipLibCheck": true,
39
+ "forceConsistentCasingInFileNames": true,
40
+ "jsx": "react-jsx",
41
+ "jsxImportSource": "frootjs"
42
+ },
43
+ "include": ["src/**/*"],
44
+ "exclude": ["node_modules", "dist"]
45
+ }
46
+ `;
47
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/templates/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;CAiB/B,CAAC;AAEF,6CAA6C;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsB9B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * WebSocket & Real-Time Pub/Sub Template
3
+ * Universal WebSocket handling with rooms, broadcast hub, and an interactive chat client.
4
+ */
5
+ import { TemplateDefinition } from './types.js';
6
+ export declare const websocketTemplate: TemplateDefinition;
7
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/templates/websocket.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAsD,MAAM,YAAY,CAAC;AAEpG,eAAO,MAAM,iBAAiB,EAAE,kBAsM/B,CAAC"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * WebSocket & Real-Time Pub/Sub Template
3
+ * Universal WebSocket handling with rooms, broadcast hub, and an interactive chat client.
4
+ */
5
+ import { COMMON_GITIGNORE, COMMON_TSCONFIG } from './types.js';
6
+ export const websocketTemplate = {
7
+ id: 'websocket',
8
+ name: 'WebSocket & Real-Time Pub/Sub',
9
+ description: 'Cross-runtime WebSockets, pub/sub rooms hub, and interactive browser chat client',
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
+ },
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
+ Froot application built with the **WebSocket & Real-Time Pub/Sub** pattern.
34
+
35
+ ## Features
36
+
37
+ - **Universal WebSockets**: Powered by \`frootjs/ws\` (\`upgradeWebSocket\`)
38
+ - **Pub/Sub Room Hub**: Multi-room broadcast hub with automatic disconnect cleanup (\`createHub\`)
39
+ - **Interactive Chat Client**: Browser interface for connecting, joining rooms, and broadcasting messages
40
+
41
+ ## Getting Started
42
+
43
+ \`\`\`bash
44
+ # 1. Install dependencies
45
+ pnpm install
46
+
47
+ # 2. Run in development mode
48
+ pnpm run dev
49
+
50
+ # 3. Open in browser
51
+ http://localhost:3000
52
+ \`\`\`
53
+ `,
54
+ 'src/server.ts': `import { Froot } from 'frootjs';
55
+ import { cors } from 'frootjs/cors';
56
+ import { upgradeWebSocket, createHub } from 'frootjs/ws';
57
+
58
+ export const app = new Froot();
59
+ const hub = createHub();
60
+
61
+ app.use(cors());
62
+
63
+ // Web UI Chat Client
64
+ app.get('/', (c) => {
65
+ return c.html(\`<!DOCTYPE html>
66
+ <html lang="en">
67
+ <head>
68
+ <meta charset="UTF-8">
69
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
70
+ <title>Froot WebSocket Hub</title>
71
+ <style>
72
+ * { box-sizing: border-box; margin: 0; padding: 0; }
73
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0f172a; color: #f8fafc; padding: 2rem; }
74
+ .container { max-width: 720px; margin: 0 auto; display: flex; flex-direction: column; gap: 1rem; }
75
+ .card { background: #1e293b; border: 1px solid #334155; border-radius: 8px; padding: 1.5rem; }
76
+ h1 { color: #10b981; font-size: 1.75rem; margin-bottom: 0.5rem; }
77
+ .status { display: inline-block; padding: 0.25rem 0.75rem; border-radius: 9999px; font-size: 0.85rem; font-weight: 600; margin-bottom: 1rem; }
78
+ .status.connected { background: #064e3b; color: #34d399; }
79
+ .status.disconnected { background: #7f1d1d; color: #f87171; }
80
+ #messages { height: 280px; overflow-y: auto; background: #0b0f19; border-radius: 6px; padding: 1rem; font-family: monospace; font-size: 0.9rem; display: flex; flex-direction: column; gap: 0.5rem; }
81
+ .msg { padding: 0.4rem 0.8rem; border-radius: 4px; background: #1e293b; }
82
+ .msg.system { color: #38bdf8; font-style: italic; background: transparent; }
83
+ .input-row { display: flex; gap: 0.5rem; margin-top: 1rem; }
84
+ input[type="text"] { flex: 1; padding: 0.75rem; border-radius: 6px; border: 1px solid #334155; background: #0b0f19; color: #fff; font-size: 1rem; outline: none; }
85
+ input[type="text"]:focus { border-color: #10b981; }
86
+ button { background: #10b981; color: #0f172a; border: none; padding: 0.75rem 1.5rem; border-radius: 6px; font-weight: bold; cursor: pointer; }
87
+ button:hover { background: #059669; }
88
+ </style>
89
+ </head>
90
+ <body>
91
+ <div class="container">
92
+ <div>
93
+ <h1>Froot Universal WebSocket Hub</h1>
94
+ <p style="color: #94a3b8;">High-speed bidirectional event broadcasting</p>
95
+ </div>
96
+
97
+ <div class="card">
98
+ <div id="status" class="status disconnected">Connecting...</div>
99
+ <div id="messages"></div>
100
+ <div class="input-row">
101
+ <input type="text" id="chat-input" placeholder="Type a message and press Enter..." />
102
+ <button id="send-btn">Send</button>
103
+ </div>
104
+ </div>
105
+ </div>
106
+
107
+ <script>
108
+ const statusEl = document.getElementById('status');
109
+ const msgBox = document.getElementById('messages');
110
+ const input = document.getElementById('chat-input');
111
+ const sendBtn = document.getElementById('send-btn');
112
+
113
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
114
+ const wsUrl = protocol + '//' + window.location.host + '/ws';
115
+ let ws;
116
+
117
+ function connect() {
118
+ ws = new WebSocket(wsUrl);
119
+ ws.onopen = () => {
120
+ statusEl.className = 'status connected';
121
+ statusEl.textContent = 'Connected to /ws';
122
+ addMessage('System: Connected to live room', true);
123
+ };
124
+ ws.onmessage = (event) => {
125
+ try {
126
+ const payload = JSON.parse(event.data);
127
+ addMessage(payload.user + ': ' + payload.text);
128
+ } catch {
129
+ addMessage(event.data);
130
+ }
131
+ };
132
+ ws.onclose = () => {
133
+ statusEl.className = 'status disconnected';
134
+ statusEl.textContent = 'Disconnected (Reconnecting...)';
135
+ setTimeout(connect, 2000);
136
+ };
137
+ }
138
+
139
+ function addMessage(text, isSystem = false) {
140
+ const div = document.createElement('div');
141
+ div.className = 'msg' + (isSystem ? ' system' : '');
142
+ div.textContent = text;
143
+ msgBox.appendChild(div);
144
+ msgBox.scrollTop = msgBox.scrollHeight;
145
+ }
146
+
147
+ function sendMessage() {
148
+ const val = input.value.trim();
149
+ if (!val || !ws || ws.readyState !== WebSocket.OPEN) return;
150
+ const packet = JSON.stringify({ user: 'Guest-' + Math.floor(Math.random() * 900 + 100), text: val });
151
+ ws.send(packet);
152
+ input.value = '';
153
+ }
154
+
155
+ sendBtn.addEventListener('click', sendMessage);
156
+ input.addEventListener('keydown', (e) => {
157
+ if (e.key === 'Enter') sendMessage();
158
+ });
159
+
160
+ connect();
161
+ </script>
162
+ </body>
163
+ </html>\`);
164
+ });
165
+
166
+ // WebSocket Upgrade Endpoint
167
+ app.get(
168
+ '/ws',
169
+ upgradeWebSocket((c) => {
170
+ const room = c.req.query('room') || 'general';
171
+
172
+ return {
173
+ onOpen(ws) {
174
+ hub.subscribe(ws, room);
175
+ const welcome = JSON.stringify({ user: 'System', text: \`New user joined #\${room}\` });
176
+ hub.publish(room, welcome);
177
+ },
178
+ onMessage(ws, event) {
179
+ hub.publish(room, String(event.data));
180
+ },
181
+ onClose(ws) {
182
+ hub.unsubscribe(ws, room);
183
+ const exit = JSON.stringify({ user: 'System', text: \`A user left #\${room}\` });
184
+ hub.publish(room, exit);
185
+ },
186
+ };
187
+ })
188
+ );
189
+
190
+ const PORT = Number(process.env.PORT) || 3000;
191
+ app.listen(PORT, () => {
192
+ console.log(\`WebSocket server running on http://localhost:\${PORT}\`);
193
+ });
194
+ `,
195
+ };
196
+ },
197
+ };
198
+ //# sourceMappingURL=websocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/templates/websocket.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpG,MAAM,CAAC,MAAM,iBAAiB,GAAuB;IACnD,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,+BAA+B;IACrC,WAAW,EAAE,kFAAkF;IAC/F,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;iBAC7B;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;;;;;;;;;;;;;;;;;;;;;;CAsBlC;YAEK,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4ItB;SACI,CAAC;IACJ,CAAC;CACF,CAAC"}
package/dist/ui.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Terminal UI and interactive prompt utilities for create-frootjs.
3
+ * Zero-dependency implementation with full ANSI color and raw-mode TTY support.
4
+ */
5
+ export declare const c: {
6
+ reset: string;
7
+ bold: string;
8
+ dim: string;
9
+ italic: string;
10
+ underline: string;
11
+ black: string;
12
+ red: string;
13
+ green: string;
14
+ yellow: string;
15
+ blue: string;
16
+ magenta: string;
17
+ cyan: string;
18
+ white: string;
19
+ gray: string;
20
+ emerald: string;
21
+ violet: string;
22
+ amber: string;
23
+ sky: string;
24
+ rose: string;
25
+ };
26
+ /**
27
+ * Print the stylized Froot header banner.
28
+ */
29
+ export declare function printBanner(version?: string): void;
30
+ /**
31
+ * Print a section step indicator.
32
+ */
33
+ export declare function printStep(current: number, total: number, title: string): void;
34
+ /**
35
+ * Print a success message.
36
+ */
37
+ export declare function printSuccess(message: string): void;
38
+ /**
39
+ * Print an info message.
40
+ */
41
+ export declare function printInfo(message: string): void;
42
+ /**
43
+ * Print a warning message.
44
+ */
45
+ export declare function printWarning(message: string): void;
46
+ /**
47
+ * Print an error message.
48
+ */
49
+ export declare function printError(message: string): void;
50
+ /**
51
+ * Text input prompt with a default fallback value.
52
+ */
53
+ export declare function promptText(question: string, defaultValue: string, validate?: (input: string) => string | true): Promise<string>;
54
+ export interface SelectOption<T = string> {
55
+ value: T;
56
+ label: string;
57
+ hint?: string;
58
+ }
59
+ /**
60
+ * Interactive single-select prompt with keyboard arrow navigation.
61
+ */
62
+ export declare function promptSelect<T = string>(question: string, options: SelectOption<T>[]): Promise<T>;
63
+ /**
64
+ * Confirm (yes/no) prompt.
65
+ */
66
+ export declare function promptConfirm(question: string, defaultValue?: boolean): Promise<boolean>;
67
+ export declare function printNextSteps(options: {
68
+ projectDir: string;
69
+ pkgManager: string;
70
+ hasInstalled: boolean;
71
+ port?: number;
72
+ }): void;
73
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;CAwBb,CAAC;AAMF;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,SAAU,GAAG,IAAI,CAQnD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAMD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAC1C,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM;IACtC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,GAAG,MAAM,EAC3C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,GACzB,OAAO,CAAC,CAAC,CAAC,CA0EZ;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,YAAY,UAAO,GAClB,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAkCP"}
package/dist/ui.js ADDED
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Terminal UI and interactive prompt utilities for create-frootjs.
3
+ * Zero-dependency implementation with full ANSI color and raw-mode TTY support.
4
+ */
5
+ import * as readline from 'node:readline';
6
+ // ---------------------------------------------------------------------------
7
+ // ANSI Color & Styling Codes
8
+ // ---------------------------------------------------------------------------
9
+ export const c = {
10
+ reset: '\x1b[0m',
11
+ bold: '\x1b[1m',
12
+ dim: '\x1b[2m',
13
+ italic: '\x1b[3m',
14
+ underline: '\x1b[4m',
15
+ // Foreground colors
16
+ black: '\x1b[30m',
17
+ red: '\x1b[31m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ blue: '\x1b[34m',
21
+ magenta: '\x1b[35m',
22
+ cyan: '\x1b[36m',
23
+ white: '\x1b[37m',
24
+ gray: '\x1b[90m',
25
+ // Bright / 24-bit RGB colors
26
+ emerald: '\x1b[38;2;16;185;129m',
27
+ violet: '\x1b[38;2;168;85;247m',
28
+ amber: '\x1b[38;2;245;158;11m',
29
+ sky: '\x1b[38;2;14;165;233m',
30
+ rose: '\x1b[38;2;244;63;94m',
31
+ };
32
+ // ---------------------------------------------------------------------------
33
+ // Visual Components
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Print the stylized Froot header banner.
37
+ */
38
+ export function printBanner(version = '1.0.1') {
39
+ const line = '─'.repeat(54);
40
+ console.log();
41
+ console.log(` ${c.emerald}╭${line}╮${c.reset}`);
42
+ console.log(` ${c.emerald}│${c.reset} ${c.bold}${c.emerald}F R O O T J S${c.reset} ${c.gray}v${version}${c.reset}${' '.repeat(34 - version.length)}${c.emerald}│${c.reset}`);
43
+ console.log(` ${c.emerald}│${c.reset} ${c.dim}Ultra-fast, TypeScript-native web framework ${c.reset}${c.emerald}│${c.reset}`);
44
+ console.log(` ${c.emerald}╰${line}╯${c.reset}`);
45
+ console.log();
46
+ }
47
+ /**
48
+ * Print a section step indicator.
49
+ */
50
+ export function printStep(current, total, title) {
51
+ console.log(` ${c.emerald}${current}/${total}${c.reset} ${c.bold}${title}${c.reset}`);
52
+ }
53
+ /**
54
+ * Print a success message.
55
+ */
56
+ export function printSuccess(message) {
57
+ console.log(` ${c.green}✔${c.reset} ${message}`);
58
+ }
59
+ /**
60
+ * Print an info message.
61
+ */
62
+ export function printInfo(message) {
63
+ console.log(` ${c.cyan}ℹ${c.reset} ${c.dim}${message}${c.reset}`);
64
+ }
65
+ /**
66
+ * Print a warning message.
67
+ */
68
+ export function printWarning(message) {
69
+ console.log(` ${c.yellow}▲${c.reset} ${c.yellow}${message}${c.reset}`);
70
+ }
71
+ /**
72
+ * Print an error message.
73
+ */
74
+ export function printError(message) {
75
+ console.log(` ${c.red}✖${c.reset} ${c.red}${message}${c.reset}`);
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // Interactive Prompts
79
+ // ---------------------------------------------------------------------------
80
+ /**
81
+ * Text input prompt with a default fallback value.
82
+ */
83
+ export async function promptText(question, defaultValue, validate) {
84
+ const isTTY = process.stdin.isTTY;
85
+ if (!isTTY) {
86
+ return defaultValue;
87
+ }
88
+ const rl = readline.createInterface({
89
+ input: process.stdin,
90
+ output: process.stdout,
91
+ });
92
+ return new Promise((resolve) => {
93
+ const ask = () => {
94
+ rl.question(` ${c.cyan}?${c.reset} ${c.bold}${question}${c.reset} ${c.dim}(${defaultValue})${c.reset} `, (answer) => {
95
+ const value = answer.trim() || defaultValue;
96
+ if (validate) {
97
+ const result = validate(value);
98
+ if (result !== true) {
99
+ console.log(` ${c.red}▲ ${result}${c.reset}`);
100
+ ask();
101
+ return;
102
+ }
103
+ }
104
+ rl.close();
105
+ resolve(value);
106
+ });
107
+ };
108
+ ask();
109
+ });
110
+ }
111
+ /**
112
+ * Interactive single-select prompt with keyboard arrow navigation.
113
+ */
114
+ export async function promptSelect(question, options) {
115
+ const isTTY = process.stdin.isTTY;
116
+ if (!isTTY || options.length === 0) {
117
+ return options[0].value;
118
+ }
119
+ let selectedIndex = 0;
120
+ const stdin = process.stdin;
121
+ const stdout = process.stdout;
122
+ // Hide cursor during selection
123
+ stdout.write('\x1b[?25l');
124
+ const render = (isInitial = false) => {
125
+ if (!isInitial) {
126
+ // Clear previous options lines
127
+ stdout.write(`\x1b[${options.length}A\x1b[0J`);
128
+ }
129
+ for (let i = 0; i < options.length; i++) {
130
+ const opt = options[i];
131
+ const isSelected = i === selectedIndex;
132
+ const pointer = isSelected ? `${c.emerald}❯${c.reset}` : ' ';
133
+ const labelText = isSelected
134
+ ? `${c.bold}${c.emerald}${opt.label}${c.reset}`
135
+ : `${c.dim}${opt.label}${c.reset}`;
136
+ const hintText = opt.hint ? ` ${c.gray}(${opt.hint})${c.reset}` : '';
137
+ stdout.write(` ${pointer} ${labelText}${hintText}\n`);
138
+ }
139
+ };
140
+ console.log(` ${c.cyan}?${c.reset} ${c.bold}${question}${c.reset} ${c.dim}(Use arrows, Enter to select)${c.reset}`);
141
+ render(true);
142
+ return new Promise((resolve) => {
143
+ const wasRaw = stdin.isRaw;
144
+ stdin.setRawMode(true);
145
+ stdin.resume();
146
+ const onData = (data) => {
147
+ const key = data.toString();
148
+ // Ctrl+C
149
+ if (key === '\u0003') {
150
+ stdout.write('\x1b[?25h'); // restore cursor
151
+ process.exit(130);
152
+ }
153
+ // Enter / Return
154
+ if (key === '\r' || key === '\n') {
155
+ stdin.removeListener('data', onData);
156
+ stdin.setRawMode(wasRaw ?? false);
157
+ stdin.pause();
158
+ stdout.write('\x1b[?25h'); // restore cursor
159
+ resolve(options[selectedIndex].value);
160
+ return;
161
+ }
162
+ // Up arrow or 'k'
163
+ if (key === '\u001b[A' || key === 'k') {
164
+ selectedIndex = (selectedIndex - 1 + options.length) % options.length;
165
+ render();
166
+ }
167
+ // Down arrow or 'j'
168
+ if (key === '\u001b[B' || key === 'j') {
169
+ selectedIndex = (selectedIndex + 1) % options.length;
170
+ render();
171
+ }
172
+ };
173
+ stdin.on('data', onData);
174
+ });
175
+ }
176
+ /**
177
+ * Confirm (yes/no) prompt.
178
+ */
179
+ export async function promptConfirm(question, defaultValue = true) {
180
+ const isTTY = process.stdin.isTTY;
181
+ if (!isTTY) {
182
+ return defaultValue;
183
+ }
184
+ const defaultHint = defaultValue ? 'Y/n' : 'y/N';
185
+ const rl = readline.createInterface({
186
+ input: process.stdin,
187
+ output: process.stdout,
188
+ });
189
+ return new Promise((resolve) => {
190
+ rl.question(` ${c.cyan}?${c.reset} ${c.bold}${question}${c.reset} ${c.dim}(${defaultHint})${c.reset} `, (answer) => {
191
+ rl.close();
192
+ const trimmed = answer.trim().toLowerCase();
193
+ if (!trimmed) {
194
+ resolve(defaultValue);
195
+ }
196
+ else {
197
+ resolve(trimmed === 'y' || trimmed === 'yes');
198
+ }
199
+ });
200
+ });
201
+ }
202
+ // ---------------------------------------------------------------------------
203
+ // Post-Generation Next Steps Card
204
+ // ---------------------------------------------------------------------------
205
+ export function printNextSteps(options) {
206
+ const { projectDir, pkgManager, hasInstalled, port = 3000 } = options;
207
+ const isCurrentDir = projectDir === '.' || projectDir === './';
208
+ const commands = [];
209
+ if (!isCurrentDir) {
210
+ commands.push(`cd ${projectDir}`);
211
+ }
212
+ if (!hasInstalled) {
213
+ commands.push(`${pkgManager} install`);
214
+ }
215
+ commands.push(`${pkgManager} run dev`);
216
+ const innerWidth = 54;
217
+ const top = '─'.repeat(innerWidth);
218
+ console.log();
219
+ console.log(` ${c.emerald}╭${top}╮${c.reset}`);
220
+ console.log(` ${c.emerald}│${c.reset} ${c.bold}Project created successfully!${c.reset}${' '.repeat(innerWidth - 30)}${c.emerald}│${c.reset}`);
221
+ console.log(` ${c.emerald}│${c.reset}${' '.repeat(innerWidth)}${c.emerald}│${c.reset}`);
222
+ console.log(` ${c.emerald}│${c.reset} ${c.dim}Next steps:${c.reset}${' '.repeat(innerWidth - 13)}${c.emerald}│${c.reset}`);
223
+ for (const cmd of commands) {
224
+ const formatted = ` ${c.cyan}$ ${cmd}${c.reset}`;
225
+ const visibleLength = cmd.length + 4;
226
+ const padding = Math.max(0, innerWidth - visibleLength);
227
+ console.log(` ${c.emerald}│${c.reset}${formatted}${' '.repeat(padding)}${c.emerald}│${c.reset}`);
228
+ }
229
+ console.log(` ${c.emerald}│${c.reset}${' '.repeat(innerWidth)}${c.emerald}│${c.reset}`);
230
+ const urlMsg = ` ${c.gray}Server starts on http://localhost:${port}${c.reset}`;
231
+ const urlLen = `Server starts on http://localhost:${port}`.length + 2;
232
+ console.log(` ${c.emerald}│${c.reset}${urlMsg}${' '.repeat(Math.max(0, innerWidth - urlLen))}${c.emerald}│${c.reset}`);
233
+ console.log(` ${c.emerald}╰${top}╯${c.reset}`);
234
+ console.log();
235
+ }
236
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,47 @@
1
1
  {
2
2
  "name": "create-frootjs",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.2",
4
+ "description": "Interactive CLI generator for scaffolding high-performance Froot applications",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-frootjs": "dist/index.js",
8
+ "create-froot": "dist/index.js"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "prepublishOnly": "npm run build",
20
+ "start": "node dist/index.js",
21
+ "dev": "node --experimental-strip-types src/index.ts",
22
+ "test": "node --test tests/*.test.ts"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/orbitnorth/froot.git",
27
+ "directory": "packages/create-frootjs"
28
+ },
29
+ "keywords": [
30
+ "froot",
31
+ "frootjs",
32
+ "cli",
33
+ "generator",
34
+ "scaffold",
35
+ "create-froot",
36
+ "create-frootjs",
37
+ "typescript",
38
+ "web",
39
+ "framework"
40
+ ],
41
+ "author": "OrbitNorth LLC",
42
+ "license": "MIT",
43
+ "devDependencies": {
44
+ "@types/node": "^22.10.0",
45
+ "typescript": "^5.8.0"
46
+ }
47
+ }