@buenojs/bueno 0.8.0

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 (120) hide show
  1. package/.env.example +109 -0
  2. package/.github/workflows/ci.yml +31 -0
  3. package/LICENSE +21 -0
  4. package/README.md +892 -0
  5. package/architecture.md +652 -0
  6. package/bun.lock +70 -0
  7. package/dist/cli/index.js +3233 -0
  8. package/dist/index.js +9014 -0
  9. package/package.json +77 -0
  10. package/src/cache/index.ts +795 -0
  11. package/src/cli/ARCHITECTURE.md +837 -0
  12. package/src/cli/bin.ts +10 -0
  13. package/src/cli/commands/build.ts +425 -0
  14. package/src/cli/commands/dev.ts +248 -0
  15. package/src/cli/commands/generate.ts +541 -0
  16. package/src/cli/commands/help.ts +55 -0
  17. package/src/cli/commands/index.ts +112 -0
  18. package/src/cli/commands/migration.ts +355 -0
  19. package/src/cli/commands/new.ts +804 -0
  20. package/src/cli/commands/start.ts +208 -0
  21. package/src/cli/core/args.ts +283 -0
  22. package/src/cli/core/console.ts +349 -0
  23. package/src/cli/core/index.ts +60 -0
  24. package/src/cli/core/prompt.ts +424 -0
  25. package/src/cli/core/spinner.ts +265 -0
  26. package/src/cli/index.ts +135 -0
  27. package/src/cli/templates/deploy.ts +295 -0
  28. package/src/cli/templates/docker.ts +307 -0
  29. package/src/cli/templates/index.ts +24 -0
  30. package/src/cli/utils/fs.ts +428 -0
  31. package/src/cli/utils/index.ts +8 -0
  32. package/src/cli/utils/strings.ts +197 -0
  33. package/src/config/env.ts +408 -0
  34. package/src/config/index.ts +506 -0
  35. package/src/config/loader.ts +329 -0
  36. package/src/config/merge.ts +285 -0
  37. package/src/config/types.ts +320 -0
  38. package/src/config/validation.ts +441 -0
  39. package/src/container/forward-ref.ts +143 -0
  40. package/src/container/index.ts +386 -0
  41. package/src/context/index.ts +360 -0
  42. package/src/database/index.ts +1142 -0
  43. package/src/database/migrations/index.ts +371 -0
  44. package/src/database/schema/index.ts +619 -0
  45. package/src/frontend/api-routes.ts +640 -0
  46. package/src/frontend/bundler.ts +643 -0
  47. package/src/frontend/console-client.ts +419 -0
  48. package/src/frontend/console-stream.ts +587 -0
  49. package/src/frontend/dev-server.ts +846 -0
  50. package/src/frontend/file-router.ts +611 -0
  51. package/src/frontend/frameworks/index.ts +106 -0
  52. package/src/frontend/frameworks/react.ts +85 -0
  53. package/src/frontend/frameworks/solid.ts +104 -0
  54. package/src/frontend/frameworks/svelte.ts +110 -0
  55. package/src/frontend/frameworks/vue.ts +92 -0
  56. package/src/frontend/hmr-client.ts +663 -0
  57. package/src/frontend/hmr.ts +728 -0
  58. package/src/frontend/index.ts +342 -0
  59. package/src/frontend/islands.ts +552 -0
  60. package/src/frontend/isr.ts +555 -0
  61. package/src/frontend/layout.ts +475 -0
  62. package/src/frontend/ssr/react.ts +446 -0
  63. package/src/frontend/ssr/solid.ts +523 -0
  64. package/src/frontend/ssr/svelte.ts +546 -0
  65. package/src/frontend/ssr/vue.ts +504 -0
  66. package/src/frontend/ssr.ts +699 -0
  67. package/src/frontend/types.ts +2274 -0
  68. package/src/health/index.ts +604 -0
  69. package/src/index.ts +410 -0
  70. package/src/lock/index.ts +587 -0
  71. package/src/logger/index.ts +444 -0
  72. package/src/logger/transports/index.ts +969 -0
  73. package/src/metrics/index.ts +494 -0
  74. package/src/middleware/built-in.ts +360 -0
  75. package/src/middleware/index.ts +94 -0
  76. package/src/modules/filters.ts +458 -0
  77. package/src/modules/guards.ts +405 -0
  78. package/src/modules/index.ts +1256 -0
  79. package/src/modules/interceptors.ts +574 -0
  80. package/src/modules/lazy.ts +418 -0
  81. package/src/modules/lifecycle.ts +478 -0
  82. package/src/modules/metadata.ts +90 -0
  83. package/src/modules/pipes.ts +626 -0
  84. package/src/router/index.ts +339 -0
  85. package/src/router/linear.ts +371 -0
  86. package/src/router/regex.ts +292 -0
  87. package/src/router/tree.ts +562 -0
  88. package/src/rpc/index.ts +1263 -0
  89. package/src/security/index.ts +436 -0
  90. package/src/ssg/index.ts +631 -0
  91. package/src/storage/index.ts +456 -0
  92. package/src/telemetry/index.ts +1097 -0
  93. package/src/testing/index.ts +1586 -0
  94. package/src/types/index.ts +236 -0
  95. package/src/types/optional-deps.d.ts +219 -0
  96. package/src/validation/index.ts +276 -0
  97. package/src/websocket/index.ts +1004 -0
  98. package/tests/integration/cli.test.ts +1016 -0
  99. package/tests/integration/fullstack.test.ts +234 -0
  100. package/tests/unit/cache.test.ts +174 -0
  101. package/tests/unit/cli-commands.test.ts +892 -0
  102. package/tests/unit/cli.test.ts +1258 -0
  103. package/tests/unit/container.test.ts +279 -0
  104. package/tests/unit/context.test.ts +221 -0
  105. package/tests/unit/database.test.ts +183 -0
  106. package/tests/unit/linear-router.test.ts +280 -0
  107. package/tests/unit/lock.test.ts +336 -0
  108. package/tests/unit/middleware.test.ts +184 -0
  109. package/tests/unit/modules.test.ts +142 -0
  110. package/tests/unit/pubsub.test.ts +257 -0
  111. package/tests/unit/regex-router.test.ts +265 -0
  112. package/tests/unit/router.test.ts +373 -0
  113. package/tests/unit/rpc.test.ts +1248 -0
  114. package/tests/unit/security.test.ts +174 -0
  115. package/tests/unit/telemetry.test.ts +371 -0
  116. package/tests/unit/test-cache.test.ts +110 -0
  117. package/tests/unit/test-database.test.ts +282 -0
  118. package/tests/unit/tree-router.test.ts +325 -0
  119. package/tests/unit/validation.test.ts +794 -0
  120. package/tsconfig.json +27 -0
@@ -0,0 +1,349 @@
1
+ /**
2
+ * Console Output Utilities for Bueno CLI
3
+ *
4
+ * Provides colored output, formatted tables, and progress indicators
5
+ * using ANSI escape codes without external dependencies
6
+ */
7
+
8
+ // ANSI color codes
9
+ const COLORS = {
10
+ reset: '\x1b[0m',
11
+ bold: '\x1b[1m',
12
+ dim: '\x1b[2m',
13
+ italic: '\x1b[3m',
14
+ underline: '\x1b[4m',
15
+
16
+ // Foreground colors
17
+ black: '\x1b[30m',
18
+ red: '\x1b[31m',
19
+ green: '\x1b[32m',
20
+ yellow: '\x1b[33m',
21
+ blue: '\x1b[34m',
22
+ magenta: '\x1b[35m',
23
+ cyan: '\x1b[36m',
24
+ white: '\x1b[37m',
25
+
26
+ // Bright foreground colors
27
+ brightRed: '\x1b[91m',
28
+ brightGreen: '\x1b[92m',
29
+ brightYellow: '\x1b[93m',
30
+ brightBlue: '\x1b[94m',
31
+ brightMagenta: '\x1b[95m',
32
+ brightCyan: '\x1b[96m',
33
+ brightWhite: '\x1b[97m',
34
+
35
+ // Background colors
36
+ bgBlack: '\x1b[40m',
37
+ bgRed: '\x1b[41m',
38
+ bgGreen: '\x1b[42m',
39
+ bgYellow: '\x1b[43m',
40
+ bgBlue: '\x1b[44m',
41
+ bgMagenta: '\x1b[45m',
42
+ bgCyan: '\x1b[46m',
43
+ bgWhite: '\x1b[47m',
44
+ } as const;
45
+
46
+ // Check if colors should be disabled
47
+ let colorEnabled = !process.env.NO_COLOR && process.env.BUENO_NO_COLOR !== 'true' && process.stdout.isTTY;
48
+
49
+ /**
50
+ * Enable or disable colored output
51
+ */
52
+ export function setColorEnabled(enabled: boolean): void {
53
+ colorEnabled = enabled;
54
+ }
55
+
56
+ /**
57
+ * Check if colors are enabled
58
+ */
59
+ export function isColorEnabled(): boolean {
60
+ return colorEnabled;
61
+ }
62
+
63
+ /**
64
+ * Apply color to text
65
+ */
66
+ function colorize(text: string, color: keyof typeof COLORS): string {
67
+ if (!colorEnabled) return text;
68
+ return `${COLORS[color]}${text}${COLORS.reset}`;
69
+ }
70
+
71
+ /**
72
+ * Color helper functions
73
+ */
74
+ export const colors = {
75
+ red: (text: string) => colorize(text, 'red'),
76
+ green: (text: string) => colorize(text, 'green'),
77
+ yellow: (text: string) => colorize(text, 'yellow'),
78
+ blue: (text: string) => colorize(text, 'blue'),
79
+ magenta: (text: string) => colorize(text, 'magenta'),
80
+ cyan: (text: string) => colorize(text, 'cyan'),
81
+ white: (text: string) => colorize(text, 'white'),
82
+ brightRed: (text: string) => colorize(text, 'brightRed'),
83
+ brightGreen: (text: string) => colorize(text, 'brightGreen'),
84
+ brightYellow: (text: string) => colorize(text, 'brightYellow'),
85
+ brightBlue: (text: string) => colorize(text, 'brightBlue'),
86
+ brightCyan: (text: string) => colorize(text, 'brightCyan'),
87
+ dim: (text: string) => colorize(text, 'dim'),
88
+ bold: (text: string) => colorize(text, 'bold'),
89
+ underline: (text: string) => colorize(text, 'underline'),
90
+ italic: (text: string) => colorize(text, 'italic'),
91
+ };
92
+
93
+ /**
94
+ * Console output helpers
95
+ */
96
+ export const cliConsole = {
97
+ /**
98
+ * Log a message
99
+ */
100
+ log(message: string, ...args: unknown[]): void {
101
+ globalThis.console.log(message, ...args);
102
+ },
103
+
104
+ /**
105
+ * Log an info message
106
+ */
107
+ info(message: string, ...args: unknown[]): void {
108
+ globalThis.console.log(colors.cyan('ℹ'), message, ...args);
109
+ },
110
+
111
+ /**
112
+ * Log a success message
113
+ */
114
+ success(message: string, ...args: unknown[]): void {
115
+ globalThis.console.log(colors.green('✓'), message, ...args);
116
+ },
117
+
118
+ /**
119
+ * Log a warning message
120
+ */
121
+ warn(message: string, ...args: unknown[]): void {
122
+ globalThis.console.log(colors.yellow('⚠'), message, ...args);
123
+ },
124
+
125
+ /**
126
+ * Log an error message
127
+ */
128
+ error(message: string, ...args: unknown[]): void {
129
+ globalThis.console.error(colors.red('✗'), message, ...args);
130
+ },
131
+
132
+ /**
133
+ * Log a debug message (only in verbose mode)
134
+ */
135
+ debug(message: string, ...args: unknown[]): void {
136
+ if (process.env.BUENO_VERBOSE === 'true') {
137
+ globalThis.console.log(colors.dim('⋯'), colors.dim(message), ...args);
138
+ }
139
+ },
140
+
141
+ /**
142
+ * Log a header/title
143
+ */
144
+ header(title: string): void {
145
+ globalThis.console.log();
146
+ globalThis.console.log(colors.bold(colors.cyan(title)));
147
+ globalThis.console.log();
148
+ },
149
+
150
+ /**
151
+ * Log a subheader
152
+ */
153
+ subheader(title: string): void {
154
+ globalThis.console.log();
155
+ globalThis.console.log(colors.bold(title));
156
+ },
157
+
158
+ /**
159
+ * Log a newline
160
+ */
161
+ newline(): void {
162
+ globalThis.console.log();
163
+ },
164
+
165
+ /**
166
+ * Clear the console
167
+ */
168
+ clear(): void {
169
+ process.stdout.write('\x1b[2J\x1b[0f');
170
+ },
171
+ };
172
+
173
+ /**
174
+ * Format a table
175
+ */
176
+ export function formatTable(
177
+ headers: string[],
178
+ rows: string[][],
179
+ options: { padding?: number } = {},
180
+ ): string {
181
+ const padding = options.padding ?? 2;
182
+ const widths: number[] = headers.map((h, i) => {
183
+ const maxRowWidth = Math.max(...rows.map((r) => r[i]?.length ?? 0));
184
+ return Math.max(h.length, maxRowWidth);
185
+ });
186
+
187
+ const pad = ' '.repeat(padding);
188
+
189
+ // Header
190
+ const headerLine = headers
191
+ .map((h, i) => h.padEnd(widths[i] ?? 0))
192
+ .join(pad);
193
+
194
+ // Separator
195
+ const separator = widths
196
+ .map((w) => '─'.repeat(w))
197
+ .join(pad);
198
+
199
+ // Rows
200
+ const rowLines = rows.map((row) =>
201
+ row
202
+ .map((cell, i) => (cell ?? '').padEnd(widths[i] ?? 0))
203
+ .join(pad)
204
+ );
205
+
206
+ return [
207
+ colors.bold(headerLine),
208
+ colors.dim(separator),
209
+ ...rowLines,
210
+ ].join('\n');
211
+ }
212
+
213
+ /**
214
+ * Print a table to console
215
+ */
216
+ export function printTable(
217
+ headers: string[],
218
+ rows: string[][],
219
+ options?: { padding?: number },
220
+ ): void {
221
+ globalThis.console.log(formatTable(headers, rows, options));
222
+ }
223
+
224
+ /**
225
+ * Format a list
226
+ */
227
+ export function formatList(
228
+ items: string[],
229
+ options: { bullet?: string; indent?: number } = {},
230
+ ): string {
231
+ const bullet = options.bullet ?? '•';
232
+ const indent = ' '.repeat(options.indent ?? 2);
233
+
234
+ return items.map((item) => `${indent}${colors.cyan(bullet)} ${item}`).join('\n');
235
+ }
236
+
237
+ /**
238
+ * Print a list to console
239
+ */
240
+ export function printList(
241
+ items: string[],
242
+ options?: { bullet?: string; indent?: number },
243
+ ): void {
244
+ globalThis.console.log(formatList(items, options));
245
+ }
246
+
247
+ /**
248
+ * Format a tree structure
249
+ */
250
+ export interface TreeNode {
251
+ label: string;
252
+ children?: TreeNode[];
253
+ }
254
+
255
+ export function formatTree(
256
+ node: TreeNode,
257
+ prefix = '',
258
+ isLast = true,
259
+ ): string {
260
+ const connector = isLast ? '└── ' : '├── ';
261
+ const childPrefix = isLast ? ' ' : '│ ';
262
+
263
+ let result = prefix + connector + node.label + '\n';
264
+
265
+ if (node.children) {
266
+ for (let i = 0; i < node.children.length; i++) {
267
+ const child = node.children[i];
268
+ if (child) {
269
+ result += formatTree(
270
+ child,
271
+ prefix + childPrefix,
272
+ i === node.children.length - 1,
273
+ );
274
+ }
275
+ }
276
+ }
277
+
278
+ return result;
279
+ }
280
+
281
+ /**
282
+ * Print a tree to console
283
+ */
284
+ export function printTree(node: TreeNode): void {
285
+ globalThis.console.log(node.label);
286
+ if (node.children) {
287
+ for (let i = 0; i < node.children.length; i++) {
288
+ const child = node.children[i];
289
+ if (child) {
290
+ globalThis.console.log(
291
+ formatTree(child, '', i === node.children.length - 1),
292
+ );
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Format file size
300
+ */
301
+ export function formatSize(bytes: number): string {
302
+ const units = ['B', 'KB', 'MB', 'GB'];
303
+ let size = bytes;
304
+ let unitIndex = 0;
305
+
306
+ while (size >= 1024 && unitIndex < units.length - 1) {
307
+ size /= 1024;
308
+ unitIndex++;
309
+ }
310
+
311
+ return `${size.toFixed(1)} ${units[unitIndex]}`;
312
+ }
313
+
314
+ /**
315
+ * Format duration
316
+ */
317
+ export function formatDuration(ms: number): string {
318
+ if (ms < 1000) return `${ms}ms`;
319
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
320
+ return `${(ms / 60000).toFixed(1)}m`;
321
+ }
322
+
323
+ /**
324
+ * Format a relative file path
325
+ */
326
+ export function formatPath(path: string, baseDir?: string): string {
327
+ if (baseDir && path.startsWith(baseDir)) {
328
+ return '.' + path.slice(baseDir.length);
329
+ }
330
+ return path;
331
+ }
332
+
333
+ /**
334
+ * Highlight code
335
+ */
336
+ export function highlightCode(code: string): string {
337
+ // Simple syntax highlighting for TypeScript
338
+ return code
339
+ .replace(/\b(import|export|from|const|let|var|function|class|interface|type|async|await|return|if|else|for|while|switch|case|break|continue|new|this|extends|implements)\b/g,
340
+ (match) => colors.magenta(match))
341
+ .replace(/\b(string|number|boolean|void|any|unknown|never|null|undefined|true|false)\b/g,
342
+ (match) => colors.yellow(match))
343
+ .replace(/'([^']*)'|"([^"]*)"|`([^`]*)`/g,
344
+ (match) => colors.green(match))
345
+ .replace(/\/\/.*$/gm,
346
+ (match) => colors.dim(match))
347
+ .replace(/\/\*[\s\S]*?\*\//g,
348
+ (match) => colors.dim(match));
349
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Core CLI Utilities
3
+ *
4
+ * Re-exports all core CLI utilities for convenient importing
5
+ */
6
+
7
+ export {
8
+ parseArgs,
9
+ getOption,
10
+ hasFlag,
11
+ hasOption,
12
+ generateHelpText,
13
+ generateGlobalHelpText,
14
+ type ParsedArgs,
15
+ type OptionDefinition,
16
+ type CommandDefinition,
17
+ } from './args';
18
+
19
+ export {
20
+ setColorEnabled,
21
+ isColorEnabled,
22
+ colors,
23
+ cliConsole,
24
+ formatTable,
25
+ printTable,
26
+ formatList,
27
+ printList,
28
+ formatTree,
29
+ printTree,
30
+ formatSize,
31
+ formatDuration,
32
+ formatPath,
33
+ highlightCode,
34
+ type TreeNode,
35
+ } from './console';
36
+
37
+ export {
38
+ isInteractive,
39
+ prompt,
40
+ confirm,
41
+ select,
42
+ multiSelect,
43
+ number,
44
+ password,
45
+ type PromptOptions,
46
+ type SelectOptions,
47
+ type ConfirmOptions,
48
+ type MultiSelectOptions,
49
+ } from './prompt';
50
+
51
+ export {
52
+ Spinner,
53
+ spinner,
54
+ ProgressBar,
55
+ progressBar,
56
+ runTasks,
57
+ type SpinnerOptions,
58
+ type ProgressBarOptions,
59
+ type TaskOptions,
60
+ } from './spinner';