@buenojs/bueno 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +264 -17
- package/dist/cli/{index.js → bin.js} +413 -332
- package/dist/container/index.js +273 -0
- package/dist/context/index.js +219 -0
- package/dist/database/index.js +493 -0
- package/dist/frontend/index.js +7697 -0
- package/dist/graphql/index.js +2156 -0
- package/dist/health/index.js +364 -0
- package/dist/i18n/index.js +345 -0
- package/dist/index.js +9694 -5047
- package/dist/jobs/index.js +819 -0
- package/dist/lock/index.js +367 -0
- package/dist/logger/index.js +281 -0
- package/dist/metrics/index.js +289 -0
- package/dist/middleware/index.js +77 -0
- package/dist/migrations/index.js +571 -0
- package/dist/modules/index.js +3411 -0
- package/dist/notification/index.js +484 -0
- package/dist/observability/index.js +331 -0
- package/dist/openapi/index.js +795 -0
- package/dist/orm/index.js +1356 -0
- package/dist/router/index.js +886 -0
- package/dist/rpc/index.js +691 -0
- package/dist/schema/index.js +400 -0
- package/dist/telemetry/index.js +595 -0
- package/dist/template/index.js +640 -0
- package/dist/templates/index.js +640 -0
- package/dist/testing/index.js +1111 -0
- package/dist/types/index.js +60 -0
- package/llms.txt +231 -0
- package/package.json +125 -27
- package/src/cache/index.ts +2 -1
- package/src/cli/ARCHITECTURE.md +3 -3
- package/src/cli/bin.ts +2 -2
- package/src/cli/commands/build.ts +183 -165
- package/src/cli/commands/dev.ts +96 -89
- package/src/cli/commands/generate.ts +142 -111
- package/src/cli/commands/help.ts +20 -16
- package/src/cli/commands/index.ts +3 -6
- package/src/cli/commands/migration.ts +124 -105
- package/src/cli/commands/new.ts +294 -232
- package/src/cli/commands/start.ts +81 -79
- package/src/cli/core/args.ts +68 -50
- package/src/cli/core/console.ts +89 -95
- package/src/cli/core/index.ts +4 -4
- package/src/cli/core/prompt.ts +65 -62
- package/src/cli/core/spinner.ts +23 -20
- package/src/cli/index.ts +46 -38
- package/src/cli/templates/database/index.ts +37 -18
- package/src/cli/templates/database/mysql.ts +3 -3
- package/src/cli/templates/database/none.ts +2 -2
- package/src/cli/templates/database/postgresql.ts +3 -3
- package/src/cli/templates/database/sqlite.ts +3 -3
- package/src/cli/templates/deploy.ts +29 -26
- package/src/cli/templates/docker.ts +41 -30
- package/src/cli/templates/frontend/index.ts +33 -15
- package/src/cli/templates/frontend/none.ts +2 -2
- package/src/cli/templates/frontend/react.ts +18 -18
- package/src/cli/templates/frontend/solid.ts +15 -15
- package/src/cli/templates/frontend/svelte.ts +17 -17
- package/src/cli/templates/frontend/vue.ts +15 -15
- package/src/cli/templates/generators/index.ts +29 -29
- package/src/cli/templates/generators/types.ts +21 -21
- package/src/cli/templates/index.ts +6 -6
- package/src/cli/templates/project/api.ts +37 -36
- package/src/cli/templates/project/default.ts +25 -25
- package/src/cli/templates/project/fullstack.ts +28 -26
- package/src/cli/templates/project/index.ts +55 -16
- package/src/cli/templates/project/minimal.ts +17 -12
- package/src/cli/templates/project/types.ts +10 -5
- package/src/cli/templates/project/website.ts +15 -15
- package/src/cli/utils/fs.ts +55 -41
- package/src/cli/utils/index.ts +3 -3
- package/src/cli/utils/strings.ts +47 -33
- package/src/cli/utils/version.ts +14 -8
- package/src/config/env-validation.ts +100 -0
- package/src/config/env.ts +169 -41
- package/src/config/index.ts +28 -20
- package/src/config/loader.ts +25 -16
- package/src/config/merge.ts +21 -10
- package/src/config/types.ts +566 -25
- package/src/config/validation.ts +215 -7
- package/src/container/forward-ref.ts +22 -22
- package/src/container/index.ts +34 -12
- package/src/context/index.ts +11 -1
- package/src/database/index.ts +7 -190
- package/src/database/orm/builder.ts +457 -0
- package/src/database/orm/casts/index.ts +130 -0
- package/src/database/orm/casts/types.ts +25 -0
- package/src/database/orm/compiler.ts +304 -0
- package/src/database/orm/hooks/index.ts +114 -0
- package/src/database/orm/index.ts +61 -0
- package/src/database/orm/model-registry.ts +59 -0
- package/src/database/orm/model.ts +821 -0
- package/src/database/orm/relationships/base.ts +146 -0
- package/src/database/orm/relationships/belongs-to-many.ts +179 -0
- package/src/database/orm/relationships/belongs-to.ts +56 -0
- package/src/database/orm/relationships/has-many.ts +45 -0
- package/src/database/orm/relationships/has-one.ts +41 -0
- package/src/database/orm/relationships/index.ts +11 -0
- package/src/database/orm/scopes/index.ts +55 -0
- package/src/events/__tests__/event-system.test.ts +235 -0
- package/src/events/config.ts +238 -0
- package/src/events/example-usage.ts +185 -0
- package/src/events/index.ts +278 -0
- package/src/events/manager.ts +385 -0
- package/src/events/registry.ts +182 -0
- package/src/events/types.ts +124 -0
- package/src/frontend/api-routes.ts +65 -23
- package/src/frontend/bundler.ts +76 -34
- package/src/frontend/console-client.ts +2 -2
- package/src/frontend/console-stream.ts +94 -38
- package/src/frontend/dev-server.ts +94 -46
- package/src/frontend/file-router.ts +61 -19
- package/src/frontend/frameworks/index.ts +37 -10
- package/src/frontend/frameworks/react.ts +10 -8
- package/src/frontend/frameworks/solid.ts +11 -9
- package/src/frontend/frameworks/svelte.ts +15 -9
- package/src/frontend/frameworks/vue.ts +13 -11
- package/src/frontend/hmr-client.ts +12 -10
- package/src/frontend/hmr.ts +146 -103
- package/src/frontend/index.ts +14 -5
- package/src/frontend/islands.ts +41 -22
- package/src/frontend/isr.ts +59 -37
- package/src/frontend/layout.ts +36 -21
- package/src/frontend/ssr/react.ts +74 -27
- package/src/frontend/ssr/solid.ts +54 -20
- package/src/frontend/ssr/svelte.ts +48 -14
- package/src/frontend/ssr/vue.ts +50 -18
- package/src/frontend/ssr.ts +83 -39
- package/src/frontend/types.ts +91 -56
- package/src/graphql/built-in-engine.ts +598 -0
- package/src/graphql/context-builder.ts +110 -0
- package/src/graphql/decorators.ts +358 -0
- package/src/graphql/execution-pipeline.ts +227 -0
- package/src/graphql/graphql-module.ts +563 -0
- package/src/graphql/index.ts +101 -0
- package/src/graphql/metadata.ts +237 -0
- package/src/graphql/schema-builder.ts +319 -0
- package/src/graphql/subscription-handler.ts +283 -0
- package/src/graphql/types.ts +324 -0
- package/src/health/index.ts +21 -9
- package/src/i18n/engine.ts +305 -0
- package/src/i18n/index.ts +38 -0
- package/src/i18n/loader.ts +218 -0
- package/src/i18n/middleware.ts +164 -0
- package/src/i18n/negotiator.ts +162 -0
- package/src/i18n/types.ts +158 -0
- package/src/index.ts +182 -27
- package/src/jobs/drivers/memory.ts +315 -0
- package/src/jobs/drivers/redis.ts +459 -0
- package/src/jobs/index.ts +30 -0
- package/src/jobs/queue.ts +281 -0
- package/src/jobs/types.ts +295 -0
- package/src/jobs/worker.ts +380 -0
- package/src/logger/index.ts +1 -3
- package/src/logger/transports/index.ts +62 -22
- package/src/metrics/index.ts +25 -16
- package/src/migrations/index.ts +9 -0
- package/src/modules/filters.ts +13 -17
- package/src/modules/guards.ts +49 -26
- package/src/modules/index.ts +457 -299
- package/src/modules/interceptors.ts +58 -20
- package/src/modules/lazy.ts +11 -19
- package/src/modules/lifecycle.ts +15 -7
- package/src/modules/metadata.ts +15 -5
- package/src/modules/pipes.ts +94 -72
- package/src/notification/channels/base.ts +68 -0
- package/src/notification/channels/email.ts +105 -0
- package/src/notification/channels/push.ts +104 -0
- package/src/notification/channels/sms.ts +105 -0
- package/src/notification/channels/whatsapp.ts +104 -0
- package/src/notification/index.ts +48 -0
- package/src/notification/service.ts +354 -0
- package/src/notification/types.ts +344 -0
- package/src/observability/__tests__/observability.test.ts +483 -0
- package/src/observability/breadcrumbs.ts +114 -0
- package/src/observability/index.ts +136 -0
- package/src/observability/interceptor.ts +85 -0
- package/src/observability/service.ts +303 -0
- package/src/observability/trace.ts +37 -0
- package/src/observability/types.ts +196 -0
- package/src/openapi/__tests__/decorators.test.ts +335 -0
- package/src/openapi/__tests__/document-builder.test.ts +285 -0
- package/src/openapi/__tests__/route-scanner.test.ts +334 -0
- package/src/openapi/__tests__/schema-generator.test.ts +275 -0
- package/src/openapi/decorators.ts +328 -0
- package/src/openapi/document-builder.ts +274 -0
- package/src/openapi/index.ts +112 -0
- package/src/openapi/metadata.ts +112 -0
- package/src/openapi/route-scanner.ts +289 -0
- package/src/openapi/schema-generator.ts +256 -0
- package/src/openapi/swagger-module.ts +166 -0
- package/src/openapi/types.ts +398 -0
- package/src/orm/index.ts +10 -0
- package/src/rpc/index.ts +3 -1
- package/src/schema/index.ts +9 -0
- package/src/security/index.ts +15 -6
- package/src/ssg/index.ts +9 -8
- package/src/telemetry/index.ts +76 -22
- package/src/template/index.ts +7 -0
- package/src/templates/engine.ts +224 -0
- package/src/templates/index.ts +9 -0
- package/src/templates/loader.ts +331 -0
- package/src/templates/renderers/markdown.ts +212 -0
- package/src/templates/renderers/simple.ts +269 -0
- package/src/templates/types.ts +154 -0
- package/src/testing/index.ts +100 -27
- package/src/types/optional-deps.d.ts +347 -187
- package/src/validation/index.ts +92 -2
- package/src/validation/schemas.ts +536 -0
- package/tests/integration/cli.test.ts +19 -19
- package/tests/integration/fullstack.test.ts +4 -4
- package/tests/unit/cli.test.ts +1 -1
- package/tests/unit/database.test.ts +2 -72
- package/tests/unit/env-validation.test.ts +166 -0
- package/tests/unit/events.test.ts +910 -0
- package/tests/unit/graphql.test.ts +991 -0
- package/tests/unit/i18n.test.ts +455 -0
- package/tests/unit/jobs.test.ts +493 -0
- package/tests/unit/notification.test.ts +988 -0
- package/tests/unit/observability.test.ts +453 -0
- package/tests/unit/orm/builder.test.ts +323 -0
- package/tests/unit/orm/casts.test.ts +179 -0
- package/tests/unit/orm/compiler.test.ts +220 -0
- package/tests/unit/orm/eager-loading.test.ts +285 -0
- package/tests/unit/orm/hooks.test.ts +191 -0
- package/tests/unit/orm/model.test.ts +373 -0
- package/tests/unit/orm/relationships.test.ts +303 -0
- package/tests/unit/orm/scopes.test.ts +74 -0
- package/tests/unit/templates-simple.test.ts +53 -0
- package/tests/unit/templates.test.ts +454 -0
- package/tests/unit/validation.test.ts +18 -24
- package/tsconfig.json +11 -3
package/src/cli/commands/new.ts
CHANGED
|
@@ -4,54 +4,54 @@
|
|
|
4
4
|
* Create a new Bueno project
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { defineCommand } from './index';
|
|
8
|
-
import { getOption, hasFlag, getOptionValues, type ParsedArgs } from '../core/args';
|
|
9
|
-
import { cliConsole, colors, printTable } from '../core/console';
|
|
10
|
-
import { prompt, select, isInteractive } from '../core/prompt';
|
|
11
|
-
import { spinner, runTasks, type TaskOptions } from '../core/spinner';
|
|
12
7
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
8
|
+
type ParsedArgs,
|
|
9
|
+
getOption,
|
|
10
|
+
getOptionValues,
|
|
11
|
+
hasFlag,
|
|
12
|
+
} from "../core/args";
|
|
13
|
+
import { cliConsole, colors, printTable } from "../core/console";
|
|
14
|
+
import { isInteractive, prompt, select } from "../core/prompt";
|
|
15
|
+
import { type TaskOptions, runTasks, spinner } from "../core/spinner";
|
|
16
|
+
import { CLIError, CLIErrorType } from "../index";
|
|
21
17
|
import {
|
|
22
18
|
type DeployPlatform,
|
|
23
|
-
getDeployTemplate,
|
|
24
19
|
getDeployFilename,
|
|
25
20
|
getDeployPlatformName,
|
|
26
|
-
|
|
21
|
+
getDeployTemplate,
|
|
22
|
+
} from "../templates";
|
|
27
23
|
import {
|
|
28
|
-
type ProjectTemplate,
|
|
29
|
-
type ProjectConfig,
|
|
30
|
-
type FrontendFramework,
|
|
31
24
|
type DatabaseDriver,
|
|
32
|
-
|
|
25
|
+
type FrontendFramework,
|
|
26
|
+
type ProjectConfig,
|
|
27
|
+
type ProjectTemplate,
|
|
33
28
|
getDatabaseOptions,
|
|
34
29
|
getFrontendOptions,
|
|
35
|
-
|
|
30
|
+
getTemplateOptions,
|
|
31
|
+
} from "../templates";
|
|
32
|
+
import { createDirectory, fileExists, joinPaths, writeFile } from "../utils/fs";
|
|
33
|
+
import { kebabCase } from "../utils/strings";
|
|
34
|
+
import { getBuenoDependency } from "../utils/version";
|
|
35
|
+
import { defineCommand } from "./index";
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Validate project name
|
|
39
39
|
*/
|
|
40
40
|
function validateProjectName(name: string): boolean | string {
|
|
41
41
|
if (!name || name.length === 0) {
|
|
42
|
-
return
|
|
42
|
+
return "Project name is required";
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
|
|
46
|
-
return
|
|
46
|
+
return "Project name can only contain letters, numbers, hyphens, and underscores";
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
if (name.startsWith(
|
|
50
|
-
return
|
|
49
|
+
if (name.startsWith("-") || name.startsWith("_")) {
|
|
50
|
+
return "Project name cannot start with a hyphen or underscore";
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (name.length > 100) {
|
|
54
|
-
return
|
|
54
|
+
return "Project name is too long (max 100 characters)";
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
return true;
|
|
@@ -60,36 +60,43 @@ function validateProjectName(name: string): boolean | string {
|
|
|
60
60
|
/**
|
|
61
61
|
* Get package.json template
|
|
62
62
|
*/
|
|
63
|
-
function getPackageJsonTemplate(
|
|
63
|
+
function getPackageJsonTemplate(
|
|
64
|
+
config: ProjectConfig,
|
|
65
|
+
template: {
|
|
66
|
+
dependencies?: Record<string, string>;
|
|
67
|
+
devDependencies?: Record<string, string>;
|
|
68
|
+
scripts?: Record<string, string>;
|
|
69
|
+
},
|
|
70
|
+
): string {
|
|
64
71
|
const dependencies: Record<string, string> = {
|
|
65
72
|
...getBuenoDependency(),
|
|
66
73
|
...(template.dependencies || {}),
|
|
67
74
|
};
|
|
68
|
-
|
|
75
|
+
|
|
69
76
|
// If using link, don't add @buenojs/bueno to dependencies
|
|
70
77
|
if (config.link) {
|
|
71
|
-
delete dependencies[
|
|
78
|
+
delete dependencies["@buenojs/bueno"];
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
const devDependencies: Record<string, string> = {
|
|
75
|
-
|
|
76
|
-
typescript:
|
|
82
|
+
"@types/bun": "latest",
|
|
83
|
+
typescript: "^5.3.0",
|
|
77
84
|
...(template.devDependencies || {}),
|
|
78
85
|
};
|
|
79
86
|
|
|
80
87
|
const scripts: Record<string, string> = {
|
|
81
|
-
dev:
|
|
82
|
-
build:
|
|
83
|
-
start:
|
|
84
|
-
test:
|
|
88
|
+
dev: "bun run --watch server/main.ts",
|
|
89
|
+
build: "bun build ./server/main.ts --outdir ./dist --target bun",
|
|
90
|
+
start: "bun run dist/main.js",
|
|
91
|
+
test: "bun test",
|
|
85
92
|
...(template.scripts || {}),
|
|
86
93
|
};
|
|
87
94
|
|
|
88
95
|
return JSON.stringify(
|
|
89
96
|
{
|
|
90
97
|
name: kebabCase(config.name),
|
|
91
|
-
version:
|
|
92
|
-
type:
|
|
98
|
+
version: "0.1.0",
|
|
99
|
+
type: "module",
|
|
93
100
|
scripts,
|
|
94
101
|
dependencies,
|
|
95
102
|
devDependencies,
|
|
@@ -106,20 +113,20 @@ function getTsConfigTemplate(): string {
|
|
|
106
113
|
return JSON.stringify(
|
|
107
114
|
{
|
|
108
115
|
compilerOptions: {
|
|
109
|
-
target:
|
|
110
|
-
module:
|
|
111
|
-
moduleResolution:
|
|
116
|
+
target: "ESNext",
|
|
117
|
+
module: "ESNext",
|
|
118
|
+
moduleResolution: "bundler",
|
|
112
119
|
strict: true,
|
|
113
120
|
skipLibCheck: true,
|
|
114
121
|
esModuleInterop: true,
|
|
115
122
|
allowSyntheticDefaultImports: true,
|
|
116
|
-
jsx:
|
|
123
|
+
jsx: "react-jsx",
|
|
117
124
|
paths: {
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
"@buenojs/bueno": ["./node_modules/@buenojs/bueno/dist/index.d.ts"],
|
|
126
|
+
},
|
|
120
127
|
},
|
|
121
|
-
include: [
|
|
122
|
-
exclude: [
|
|
128
|
+
include: ["server/**/*", "client/**/*"],
|
|
129
|
+
exclude: ["node_modules", "dist"],
|
|
123
130
|
},
|
|
124
131
|
null,
|
|
125
132
|
2,
|
|
@@ -130,7 +137,7 @@ function getTsConfigTemplate(): string {
|
|
|
130
137
|
* Get .env.example template
|
|
131
138
|
*/
|
|
132
139
|
function getEnvExampleTemplate(config: ProjectConfig): string {
|
|
133
|
-
if (config.database ===
|
|
140
|
+
if (config.database === "none" || config.database === "sqlite") {
|
|
134
141
|
return `# Bueno Environment Variables
|
|
135
142
|
NODE_ENV=development
|
|
136
143
|
`;
|
|
@@ -186,11 +193,11 @@ coverage/
|
|
|
186
193
|
*/
|
|
187
194
|
function getReadmeTemplate(config: ProjectConfig): string {
|
|
188
195
|
const templateDescriptions: Record<ProjectTemplate, string> = {
|
|
189
|
-
default:
|
|
190
|
-
minimal:
|
|
191
|
-
fullstack:
|
|
192
|
-
api:
|
|
193
|
-
website:
|
|
196
|
+
default: "Standard project with modules and database",
|
|
197
|
+
minimal: "Bare minimum project structure",
|
|
198
|
+
fullstack: "Full-stack project with SSR and frontend",
|
|
199
|
+
api: "API-only project without frontend",
|
|
200
|
+
website: "Static website with SSG",
|
|
194
201
|
};
|
|
195
202
|
|
|
196
203
|
return `# ${config.name}
|
|
@@ -236,13 +243,13 @@ bun run start
|
|
|
236
243
|
* Get bueno.config.ts template
|
|
237
244
|
*/
|
|
238
245
|
function getConfigTemplate(config: ProjectConfig): string {
|
|
239
|
-
let dbConfig =
|
|
240
|
-
|
|
241
|
-
if (config.database ===
|
|
246
|
+
let dbConfig = "undefined";
|
|
247
|
+
|
|
248
|
+
if (config.database === "sqlite") {
|
|
242
249
|
dbConfig = `{ url: 'sqlite:./data.db' }`;
|
|
243
|
-
} else if (config.database ===
|
|
250
|
+
} else if (config.database === "postgresql") {
|
|
244
251
|
dbConfig = `{ url: process.env.DATABASE_URL ?? 'postgresql://localhost/${kebabCase(config.name)}' }`;
|
|
245
|
-
} else if (config.database ===
|
|
252
|
+
} else if (config.database === "mysql") {
|
|
246
253
|
dbConfig = `{ url: process.env.DATABASE_URL ?? 'mysql://localhost/${kebabCase(config.name)}' }`;
|
|
247
254
|
}
|
|
248
255
|
|
|
@@ -254,7 +261,7 @@ export default defineConfig({
|
|
|
254
261
|
host: 'localhost',
|
|
255
262
|
},
|
|
256
263
|
|
|
257
|
-
${config.database !==
|
|
264
|
+
${config.database !== "none" ? `database: ${dbConfig},` : ""}
|
|
258
265
|
|
|
259
266
|
logger: {
|
|
260
267
|
level: 'info',
|
|
@@ -276,26 +283,44 @@ export default defineConfig({
|
|
|
276
283
|
async function createProjectFiles(
|
|
277
284
|
projectPath: string,
|
|
278
285
|
config: ProjectConfig,
|
|
279
|
-
templateResult: {
|
|
286
|
+
templateResult: {
|
|
287
|
+
files: { path: string; content: string }[];
|
|
288
|
+
directories: string[];
|
|
289
|
+
dependencies?: Record<string, string>;
|
|
290
|
+
devDependencies?: Record<string, string>;
|
|
291
|
+
scripts?: Record<string, string>;
|
|
292
|
+
},
|
|
280
293
|
): Promise<void> {
|
|
281
294
|
const tasks: TaskOptions[] = [];
|
|
282
295
|
|
|
283
296
|
// Create directories
|
|
284
297
|
tasks.push({
|
|
285
|
-
text:
|
|
298
|
+
text: "Creating project structure",
|
|
286
299
|
task: async () => {
|
|
287
300
|
// Base directories
|
|
288
|
-
await createDirectory(joinPaths(projectPath,
|
|
289
|
-
await createDirectory(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
await createDirectory(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
await createDirectory(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
301
|
+
await createDirectory(joinPaths(projectPath, "server", "modules", "app"));
|
|
302
|
+
await createDirectory(
|
|
303
|
+
joinPaths(projectPath, "server", "common", "middleware"),
|
|
304
|
+
);
|
|
305
|
+
await createDirectory(
|
|
306
|
+
joinPaths(projectPath, "server", "common", "guards"),
|
|
307
|
+
);
|
|
308
|
+
await createDirectory(
|
|
309
|
+
joinPaths(projectPath, "server", "common", "interceptors"),
|
|
310
|
+
);
|
|
311
|
+
await createDirectory(
|
|
312
|
+
joinPaths(projectPath, "server", "common", "pipes"),
|
|
313
|
+
);
|
|
314
|
+
await createDirectory(
|
|
315
|
+
joinPaths(projectPath, "server", "common", "filters"),
|
|
316
|
+
);
|
|
317
|
+
await createDirectory(
|
|
318
|
+
joinPaths(projectPath, "server", "database", "migrations"),
|
|
319
|
+
);
|
|
320
|
+
await createDirectory(joinPaths(projectPath, "server", "config"));
|
|
321
|
+
await createDirectory(joinPaths(projectPath, "tests", "unit"));
|
|
322
|
+
await createDirectory(joinPaths(projectPath, "tests", "integration"));
|
|
323
|
+
|
|
299
324
|
// Template-specific directories
|
|
300
325
|
for (const dir of templateResult.directories) {
|
|
301
326
|
await createDirectory(joinPaths(projectPath, dir));
|
|
@@ -305,10 +330,10 @@ async function createProjectFiles(
|
|
|
305
330
|
|
|
306
331
|
// Create package.json
|
|
307
332
|
tasks.push({
|
|
308
|
-
text:
|
|
333
|
+
text: "Creating package.json",
|
|
309
334
|
task: async () => {
|
|
310
335
|
await writeFile(
|
|
311
|
-
joinPaths(projectPath,
|
|
336
|
+
joinPaths(projectPath, "package.json"),
|
|
312
337
|
getPackageJsonTemplate(config, templateResult),
|
|
313
338
|
);
|
|
314
339
|
},
|
|
@@ -316,10 +341,10 @@ async function createProjectFiles(
|
|
|
316
341
|
|
|
317
342
|
// Create tsconfig.json
|
|
318
343
|
tasks.push({
|
|
319
|
-
text:
|
|
344
|
+
text: "Creating tsconfig.json",
|
|
320
345
|
task: async () => {
|
|
321
346
|
await writeFile(
|
|
322
|
-
joinPaths(projectPath,
|
|
347
|
+
joinPaths(projectPath, "tsconfig.json"),
|
|
323
348
|
getTsConfigTemplate(),
|
|
324
349
|
);
|
|
325
350
|
},
|
|
@@ -330,21 +355,18 @@ async function createProjectFiles(
|
|
|
330
355
|
tasks.push({
|
|
331
356
|
text: `Creating ${file.path}`,
|
|
332
357
|
task: async () => {
|
|
333
|
-
await writeFile(
|
|
334
|
-
joinPaths(projectPath, file.path),
|
|
335
|
-
file.content,
|
|
336
|
-
);
|
|
358
|
+
await writeFile(joinPaths(projectPath, file.path), file.content);
|
|
337
359
|
},
|
|
338
360
|
});
|
|
339
361
|
}
|
|
340
362
|
|
|
341
363
|
// Create bueno.config.ts (not for website template)
|
|
342
|
-
if (config.template !==
|
|
364
|
+
if (config.template !== "website") {
|
|
343
365
|
tasks.push({
|
|
344
|
-
text:
|
|
366
|
+
text: "Creating bueno.config.ts",
|
|
345
367
|
task: async () => {
|
|
346
368
|
await writeFile(
|
|
347
|
-
joinPaths(projectPath,
|
|
369
|
+
joinPaths(projectPath, "bueno.config.ts"),
|
|
348
370
|
getConfigTemplate(config),
|
|
349
371
|
);
|
|
350
372
|
},
|
|
@@ -353,10 +375,10 @@ async function createProjectFiles(
|
|
|
353
375
|
|
|
354
376
|
// Create .env.example
|
|
355
377
|
tasks.push({
|
|
356
|
-
text:
|
|
378
|
+
text: "Creating .env.example",
|
|
357
379
|
task: async () => {
|
|
358
380
|
await writeFile(
|
|
359
|
-
joinPaths(projectPath,
|
|
381
|
+
joinPaths(projectPath, ".env.example"),
|
|
360
382
|
getEnvExampleTemplate(config),
|
|
361
383
|
);
|
|
362
384
|
},
|
|
@@ -364,10 +386,10 @@ async function createProjectFiles(
|
|
|
364
386
|
|
|
365
387
|
// Create .gitignore
|
|
366
388
|
tasks.push({
|
|
367
|
-
text:
|
|
389
|
+
text: "Creating .gitignore",
|
|
368
390
|
task: async () => {
|
|
369
391
|
await writeFile(
|
|
370
|
-
joinPaths(projectPath,
|
|
392
|
+
joinPaths(projectPath, ".gitignore"),
|
|
371
393
|
getGitignoreTemplate(),
|
|
372
394
|
);
|
|
373
395
|
},
|
|
@@ -375,53 +397,62 @@ async function createProjectFiles(
|
|
|
375
397
|
|
|
376
398
|
// Create README.md
|
|
377
399
|
tasks.push({
|
|
378
|
-
text:
|
|
400
|
+
text: "Creating README.md",
|
|
379
401
|
task: async () => {
|
|
380
402
|
await writeFile(
|
|
381
|
-
joinPaths(projectPath,
|
|
403
|
+
joinPaths(projectPath, "README.md"),
|
|
382
404
|
getReadmeTemplate(config),
|
|
383
405
|
);
|
|
384
406
|
},
|
|
385
407
|
});
|
|
386
408
|
|
|
387
409
|
// Create Docker files if enabled
|
|
388
|
-
if (config.docker && config.template !==
|
|
410
|
+
if (config.docker && config.template !== "website") {
|
|
389
411
|
tasks.push({
|
|
390
|
-
text:
|
|
412
|
+
text: "Creating Dockerfile",
|
|
391
413
|
task: async () => {
|
|
392
414
|
await writeFile(
|
|
393
|
-
joinPaths(projectPath,
|
|
394
|
-
getDockerfileTemplate(
|
|
415
|
+
joinPaths(projectPath, "Dockerfile"),
|
|
416
|
+
getDockerfileTemplate(
|
|
417
|
+
config.name,
|
|
418
|
+
config.database === "none" ? undefined : config.database,
|
|
419
|
+
),
|
|
395
420
|
);
|
|
396
421
|
},
|
|
397
422
|
});
|
|
398
423
|
|
|
399
424
|
tasks.push({
|
|
400
|
-
text:
|
|
425
|
+
text: "Creating .dockerignore",
|
|
401
426
|
task: async () => {
|
|
402
427
|
await writeFile(
|
|
403
|
-
joinPaths(projectPath,
|
|
428
|
+
joinPaths(projectPath, ".dockerignore"),
|
|
404
429
|
getDockerignoreTemplate(),
|
|
405
430
|
);
|
|
406
431
|
},
|
|
407
432
|
});
|
|
408
433
|
|
|
409
434
|
tasks.push({
|
|
410
|
-
text:
|
|
435
|
+
text: "Creating docker-compose.yml",
|
|
411
436
|
task: async () => {
|
|
412
437
|
await writeFile(
|
|
413
|
-
joinPaths(projectPath,
|
|
414
|
-
getDockerComposeTemplate(
|
|
438
|
+
joinPaths(projectPath, "docker-compose.yml"),
|
|
439
|
+
getDockerComposeTemplate(
|
|
440
|
+
config.name,
|
|
441
|
+
config.database === "none" ? undefined : config.database,
|
|
442
|
+
),
|
|
415
443
|
);
|
|
416
444
|
},
|
|
417
445
|
});
|
|
418
446
|
|
|
419
447
|
tasks.push({
|
|
420
|
-
text:
|
|
448
|
+
text: "Creating .env.docker",
|
|
421
449
|
task: async () => {
|
|
422
450
|
await writeFile(
|
|
423
|
-
joinPaths(projectPath,
|
|
424
|
-
getDockerEnvTemplate(
|
|
451
|
+
joinPaths(projectPath, ".env.docker"),
|
|
452
|
+
getDockerEnvTemplate(
|
|
453
|
+
config.name,
|
|
454
|
+
config.database === "none" ? undefined : config.database,
|
|
455
|
+
),
|
|
425
456
|
);
|
|
426
457
|
},
|
|
427
458
|
});
|
|
@@ -435,7 +466,11 @@ async function createProjectFiles(
|
|
|
435
466
|
task: async () => {
|
|
436
467
|
await writeFile(
|
|
437
468
|
joinPaths(projectPath, filename),
|
|
438
|
-
getDeployTemplate(
|
|
469
|
+
getDeployTemplate(
|
|
470
|
+
platform,
|
|
471
|
+
config.name,
|
|
472
|
+
config.database === "none" ? "sqlite" : config.database,
|
|
473
|
+
),
|
|
439
474
|
);
|
|
440
475
|
},
|
|
441
476
|
});
|
|
@@ -446,11 +481,11 @@ async function createProjectFiles(
|
|
|
446
481
|
|
|
447
482
|
// Import docker templates
|
|
448
483
|
import {
|
|
449
|
-
getDockerfileTemplate,
|
|
450
|
-
getDockerignoreTemplate,
|
|
451
484
|
getDockerComposeTemplate,
|
|
452
485
|
getDockerEnvTemplate,
|
|
453
|
-
|
|
486
|
+
getDockerfileTemplate,
|
|
487
|
+
getDockerignoreTemplate,
|
|
488
|
+
} from "../templates";
|
|
454
489
|
|
|
455
490
|
/**
|
|
456
491
|
* Handle new command
|
|
@@ -458,18 +493,18 @@ import {
|
|
|
458
493
|
async function handleNew(args: ParsedArgs): Promise<void> {
|
|
459
494
|
// Get project name
|
|
460
495
|
let name = args.positionals[0];
|
|
461
|
-
const useDefaults = hasFlag(args,
|
|
496
|
+
const useDefaults = hasFlag(args, "yes") || hasFlag(args, "y");
|
|
462
497
|
|
|
463
498
|
// Interactive prompts if no name provided
|
|
464
499
|
if (!name && isInteractive()) {
|
|
465
|
-
name = await prompt(
|
|
500
|
+
name = await prompt("Project name:", {
|
|
466
501
|
validate: validateProjectName,
|
|
467
502
|
});
|
|
468
503
|
}
|
|
469
504
|
|
|
470
505
|
if (!name) {
|
|
471
506
|
throw new CLIError(
|
|
472
|
-
|
|
507
|
+
"Project name is required. Usage: bueno new <project-name>",
|
|
473
508
|
CLIErrorType.INVALID_ARGS,
|
|
474
509
|
);
|
|
475
510
|
}
|
|
@@ -480,37 +515,37 @@ async function handleNew(args: ParsedArgs): Promise<void> {
|
|
|
480
515
|
}
|
|
481
516
|
|
|
482
517
|
// Get options
|
|
483
|
-
let template = getOption(args,
|
|
484
|
-
name:
|
|
485
|
-
alias:
|
|
486
|
-
type:
|
|
487
|
-
description:
|
|
518
|
+
let template = getOption(args, "template", {
|
|
519
|
+
name: "template",
|
|
520
|
+
alias: "t",
|
|
521
|
+
type: "string",
|
|
522
|
+
description: "",
|
|
488
523
|
}) as ProjectTemplate;
|
|
489
524
|
|
|
490
|
-
let framework = getOption(args,
|
|
491
|
-
name:
|
|
492
|
-
alias:
|
|
493
|
-
type:
|
|
494
|
-
description:
|
|
525
|
+
let framework = getOption(args, "framework", {
|
|
526
|
+
name: "framework",
|
|
527
|
+
alias: "f",
|
|
528
|
+
type: "string",
|
|
529
|
+
description: "",
|
|
495
530
|
}) as FrontendFramework;
|
|
496
531
|
|
|
497
|
-
let database = getOption(args,
|
|
498
|
-
name:
|
|
499
|
-
alias:
|
|
500
|
-
type:
|
|
501
|
-
description:
|
|
532
|
+
let database = getOption(args, "database", {
|
|
533
|
+
name: "database",
|
|
534
|
+
alias: "d",
|
|
535
|
+
type: "string",
|
|
536
|
+
description: "",
|
|
502
537
|
}) as DatabaseDriver;
|
|
503
538
|
|
|
504
|
-
const skipInstall = hasFlag(args,
|
|
505
|
-
const skipGit = hasFlag(args,
|
|
506
|
-
const docker = hasFlag(args,
|
|
507
|
-
const link = hasFlag(args,
|
|
508
|
-
|
|
539
|
+
const skipInstall = hasFlag(args, "skip-install");
|
|
540
|
+
const skipGit = hasFlag(args, "skip-git");
|
|
541
|
+
const docker = hasFlag(args, "docker");
|
|
542
|
+
const link = hasFlag(args, "link");
|
|
543
|
+
|
|
509
544
|
// Get deployment platforms (can be specified multiple times)
|
|
510
|
-
const deployPlatforms = getOptionValues(args,
|
|
511
|
-
const validPlatforms: DeployPlatform[] = [
|
|
545
|
+
const deployPlatforms = getOptionValues(args, "deploy");
|
|
546
|
+
const validPlatforms: DeployPlatform[] = ["render", "fly", "railway"];
|
|
512
547
|
const deploy: DeployPlatform[] = [];
|
|
513
|
-
|
|
548
|
+
|
|
514
549
|
for (const platform of deployPlatforms) {
|
|
515
550
|
if (validPlatforms.includes(platform as DeployPlatform)) {
|
|
516
551
|
if (!deploy.includes(platform as DeployPlatform)) {
|
|
@@ -518,7 +553,7 @@ async function handleNew(args: ParsedArgs): Promise<void> {
|
|
|
518
553
|
}
|
|
519
554
|
} else {
|
|
520
555
|
throw new CLIError(
|
|
521
|
-
`Invalid deployment platform: ${platform}. Valid options are: ${validPlatforms.join(
|
|
556
|
+
`Invalid deployment platform: ${platform}. Valid options are: ${validPlatforms.join(", ")}`,
|
|
522
557
|
CLIErrorType.INVALID_ARGS,
|
|
523
558
|
);
|
|
524
559
|
}
|
|
@@ -528,44 +563,44 @@ async function handleNew(args: ParsedArgs): Promise<void> {
|
|
|
528
563
|
if (!useDefaults && isInteractive()) {
|
|
529
564
|
if (!template) {
|
|
530
565
|
template = await select<ProjectTemplate>(
|
|
531
|
-
|
|
566
|
+
"Select a template:",
|
|
532
567
|
getTemplateOptions(),
|
|
533
|
-
{ default:
|
|
568
|
+
{ default: "default" },
|
|
534
569
|
);
|
|
535
570
|
}
|
|
536
571
|
|
|
537
572
|
// Only ask for framework if template supports it
|
|
538
|
-
if ((template ===
|
|
573
|
+
if ((template === "fullstack" || template === "default") && !framework) {
|
|
539
574
|
framework = await select<FrontendFramework>(
|
|
540
|
-
|
|
575
|
+
"Select a frontend framework:",
|
|
541
576
|
getFrontendOptions(),
|
|
542
|
-
{ default:
|
|
577
|
+
{ default: "react" },
|
|
543
578
|
);
|
|
544
579
|
}
|
|
545
580
|
|
|
546
581
|
// Website template doesn't need database or frontend selection
|
|
547
|
-
if (template !==
|
|
582
|
+
if (template !== "website" && !database) {
|
|
548
583
|
database = await select<DatabaseDriver>(
|
|
549
|
-
|
|
584
|
+
"Select a database:",
|
|
550
585
|
getDatabaseOptions(),
|
|
551
|
-
{ default:
|
|
586
|
+
{ default: "sqlite" },
|
|
552
587
|
);
|
|
553
588
|
}
|
|
554
589
|
}
|
|
555
590
|
|
|
556
591
|
// Set defaults
|
|
557
|
-
template = template ||
|
|
558
|
-
framework = framework ||
|
|
559
|
-
database = database ||
|
|
592
|
+
template = template || "default";
|
|
593
|
+
framework = framework || "react";
|
|
594
|
+
database = database || "sqlite";
|
|
560
595
|
|
|
561
596
|
// For website template, override database and framework
|
|
562
|
-
const isWebsite = template ===
|
|
597
|
+
const isWebsite = template === "website";
|
|
563
598
|
|
|
564
599
|
const config: ProjectConfig = {
|
|
565
600
|
name,
|
|
566
601
|
template,
|
|
567
|
-
framework: isWebsite ?
|
|
568
|
-
database: isWebsite ?
|
|
602
|
+
framework: isWebsite ? "none" : framework,
|
|
603
|
+
database: isWebsite ? "none" : database,
|
|
569
604
|
skipInstall,
|
|
570
605
|
skipGit,
|
|
571
606
|
docker,
|
|
@@ -586,71 +621,90 @@ async function handleNew(args: ParsedArgs): Promise<void> {
|
|
|
586
621
|
cliConsole.header(`Creating a new Bueno project: ${colors.cyan(name)}`);
|
|
587
622
|
|
|
588
623
|
const rows = [
|
|
589
|
-
[
|
|
590
|
-
[
|
|
591
|
-
[
|
|
592
|
-
[
|
|
593
|
-
[
|
|
594
|
-
|
|
595
|
-
|
|
624
|
+
["Template", template],
|
|
625
|
+
["Framework", isWebsite ? "N/A (Static Site)" : framework],
|
|
626
|
+
["Database", isWebsite ? "N/A" : database],
|
|
627
|
+
["Docker", docker ? colors.green("Yes") : colors.red("No")],
|
|
628
|
+
[
|
|
629
|
+
"Deploy",
|
|
630
|
+
deploy.length > 0
|
|
631
|
+
? colors.green(deploy.map(getDeployPlatformName).join(", "))
|
|
632
|
+
: colors.red("None"),
|
|
633
|
+
],
|
|
634
|
+
[
|
|
635
|
+
"Install dependencies",
|
|
636
|
+
skipInstall ? colors.red("No") : colors.green("Yes"),
|
|
637
|
+
],
|
|
638
|
+
[
|
|
639
|
+
"Use local package",
|
|
640
|
+
link ? colors.green("Yes (bun link)") : colors.red("No"),
|
|
641
|
+
],
|
|
596
642
|
];
|
|
597
643
|
|
|
598
|
-
printTable([
|
|
599
|
-
cliConsole.log(
|
|
644
|
+
printTable(["Setting", "Value"], rows);
|
|
645
|
+
cliConsole.log("");
|
|
600
646
|
|
|
601
647
|
// Get the appropriate template function
|
|
602
|
-
const { getProjectTemplate } = await import(
|
|
648
|
+
const { getProjectTemplate } = await import("../templates");
|
|
603
649
|
const templateFn = getProjectTemplate(template);
|
|
604
650
|
const templateResult = templateFn(config);
|
|
605
651
|
|
|
606
652
|
// Create project
|
|
607
|
-
cliConsole.subheader(
|
|
653
|
+
cliConsole.subheader("Creating project files...");
|
|
608
654
|
await createProjectFiles(projectPath, config, templateResult);
|
|
609
655
|
|
|
610
656
|
// Install dependencies
|
|
611
657
|
if (!skipInstall) {
|
|
612
|
-
cliConsole.subheader(
|
|
613
|
-
const installSpinner = spinner(
|
|
658
|
+
cliConsole.subheader("Installing dependencies...");
|
|
659
|
+
const installSpinner = spinner("Running bun install...");
|
|
614
660
|
|
|
615
661
|
try {
|
|
616
|
-
const proc = Bun.spawn([
|
|
662
|
+
const proc = Bun.spawn(["bun", "install"], {
|
|
617
663
|
cwd: projectPath,
|
|
618
|
-
stdout:
|
|
619
|
-
stderr:
|
|
664
|
+
stdout: "pipe",
|
|
665
|
+
stderr: "pipe",
|
|
620
666
|
});
|
|
621
667
|
|
|
622
668
|
const exitCode = await proc.exited;
|
|
623
669
|
|
|
624
670
|
if (exitCode === 0) {
|
|
625
|
-
installSpinner.success(
|
|
671
|
+
installSpinner.success("Dependencies installed");
|
|
626
672
|
} else {
|
|
627
|
-
installSpinner.warn(
|
|
673
|
+
installSpinner.warn(
|
|
674
|
+
"Failed to install dependencies. Run `bun install` manually.",
|
|
675
|
+
);
|
|
628
676
|
}
|
|
629
677
|
} catch {
|
|
630
|
-
installSpinner.warn(
|
|
678
|
+
installSpinner.warn(
|
|
679
|
+
"Failed to install dependencies. Run `bun install` manually.",
|
|
680
|
+
);
|
|
631
681
|
}
|
|
632
|
-
|
|
682
|
+
|
|
633
683
|
// Link local @buenojs/bueno if --link flag is set
|
|
634
684
|
if (link) {
|
|
635
|
-
cliConsole.subheader(
|
|
636
|
-
const linkSpinner = spinner(
|
|
685
|
+
cliConsole.subheader("Linking local @buenojs/bueno...");
|
|
686
|
+
const linkSpinner = spinner("Running bun link @buenojs/bueno...");
|
|
637
687
|
|
|
638
688
|
try {
|
|
639
|
-
const proc = Bun.spawn([
|
|
689
|
+
const proc = Bun.spawn(["bun", "link", "@buenojs/bueno"], {
|
|
640
690
|
cwd: projectPath,
|
|
641
|
-
stdout:
|
|
642
|
-
stderr:
|
|
691
|
+
stdout: "pipe",
|
|
692
|
+
stderr: "pipe",
|
|
643
693
|
});
|
|
644
694
|
|
|
645
695
|
const exitCode = await proc.exited;
|
|
646
696
|
|
|
647
697
|
if (exitCode === 0) {
|
|
648
|
-
linkSpinner.success(
|
|
698
|
+
linkSpinner.success("Local @buenojs/bueno linked successfully");
|
|
649
699
|
} else {
|
|
650
|
-
linkSpinner.warn(
|
|
700
|
+
linkSpinner.warn(
|
|
701
|
+
"Failed to link @buenojs/bueno. Make sure you have run `bun link` in the bueno directory first.",
|
|
702
|
+
);
|
|
651
703
|
}
|
|
652
704
|
} catch {
|
|
653
|
-
linkSpinner.warn(
|
|
705
|
+
linkSpinner.warn(
|
|
706
|
+
"Failed to link @buenojs/bueno. Make sure you have run `bun link` in the bueno directory first.",
|
|
707
|
+
);
|
|
654
708
|
}
|
|
655
709
|
}
|
|
656
710
|
}
|
|
@@ -659,113 +713,121 @@ async function handleNew(args: ParsedArgs): Promise<void> {
|
|
|
659
713
|
// Users can run `git init` manually if needed
|
|
660
714
|
|
|
661
715
|
// Show success message
|
|
662
|
-
cliConsole.log(
|
|
716
|
+
cliConsole.log("");
|
|
663
717
|
cliConsole.success(`Project created successfully!`);
|
|
664
|
-
cliConsole.log(
|
|
665
|
-
cliConsole.log(
|
|
718
|
+
cliConsole.log("");
|
|
719
|
+
cliConsole.log("Next steps:");
|
|
666
720
|
cliConsole.log(` ${colors.cyan(`cd ${kebabCase(name)}`)}`);
|
|
667
|
-
|
|
721
|
+
|
|
668
722
|
if (isWebsite) {
|
|
669
|
-
cliConsole.log(
|
|
670
|
-
|
|
723
|
+
cliConsole.log(
|
|
724
|
+
` ${colors.cyan("bun run dev")} - Start development server`,
|
|
725
|
+
);
|
|
726
|
+
cliConsole.log(` ${colors.cyan("bun run build")} - Build static site`);
|
|
671
727
|
} else {
|
|
672
|
-
cliConsole.log(` ${colors.cyan(
|
|
728
|
+
cliConsole.log(` ${colors.cyan("bun run dev")}`);
|
|
673
729
|
}
|
|
674
|
-
|
|
675
|
-
cliConsole.log(
|
|
676
|
-
cliConsole.log(
|
|
730
|
+
|
|
731
|
+
cliConsole.log("");
|
|
732
|
+
cliConsole.log(
|
|
733
|
+
`Documentation: ${colors.dim("https://github.com/sivaraj/bueno")}`,
|
|
734
|
+
);
|
|
677
735
|
}
|
|
678
736
|
|
|
679
737
|
// Import the template function getter dynamically
|
|
680
738
|
async function importTemplateFn(template: ProjectTemplate) {
|
|
681
|
-
const { getProjectTemplate } = await import(
|
|
739
|
+
const { getProjectTemplate } = await import("../templates");
|
|
682
740
|
return getProjectTemplate(template);
|
|
683
741
|
}
|
|
684
742
|
|
|
685
743
|
// Register the command
|
|
686
744
|
defineCommand(
|
|
687
745
|
{
|
|
688
|
-
name:
|
|
689
|
-
description:
|
|
746
|
+
name: "new",
|
|
747
|
+
description: "Create a new Bueno project",
|
|
690
748
|
positionals: [
|
|
691
749
|
{
|
|
692
|
-
name:
|
|
750
|
+
name: "name",
|
|
693
751
|
required: false,
|
|
694
|
-
description:
|
|
752
|
+
description: "Project name",
|
|
695
753
|
},
|
|
696
754
|
],
|
|
697
755
|
options: [
|
|
698
756
|
{
|
|
699
|
-
name:
|
|
700
|
-
alias:
|
|
701
|
-
type:
|
|
702
|
-
description:
|
|
757
|
+
name: "template",
|
|
758
|
+
alias: "t",
|
|
759
|
+
type: "string",
|
|
760
|
+
description:
|
|
761
|
+
"Project template (default, minimal, fullstack, api, website)",
|
|
703
762
|
},
|
|
704
763
|
{
|
|
705
|
-
name:
|
|
706
|
-
alias:
|
|
707
|
-
type:
|
|
708
|
-
description:
|
|
764
|
+
name: "framework",
|
|
765
|
+
alias: "f",
|
|
766
|
+
type: "string",
|
|
767
|
+
description: "Frontend framework (react, vue, svelte, solid, none)",
|
|
709
768
|
},
|
|
710
769
|
{
|
|
711
|
-
name:
|
|
712
|
-
alias:
|
|
713
|
-
type:
|
|
714
|
-
description:
|
|
770
|
+
name: "database",
|
|
771
|
+
alias: "d",
|
|
772
|
+
type: "string",
|
|
773
|
+
description: "Database driver (sqlite, postgresql, mysql, none)",
|
|
715
774
|
},
|
|
716
775
|
{
|
|
717
|
-
name:
|
|
718
|
-
type:
|
|
776
|
+
name: "skip-install",
|
|
777
|
+
type: "boolean",
|
|
719
778
|
default: false,
|
|
720
|
-
description:
|
|
779
|
+
description: "Skip dependency installation",
|
|
721
780
|
},
|
|
722
781
|
{
|
|
723
|
-
name:
|
|
724
|
-
type:
|
|
782
|
+
name: "skip-git",
|
|
783
|
+
type: "boolean",
|
|
725
784
|
default: false,
|
|
726
|
-
description:
|
|
785
|
+
description:
|
|
786
|
+
"Skip git initialization (deprecated - git init is no longer automatic)",
|
|
727
787
|
},
|
|
728
788
|
{
|
|
729
|
-
name:
|
|
730
|
-
type:
|
|
789
|
+
name: "docker",
|
|
790
|
+
type: "boolean",
|
|
731
791
|
default: false,
|
|
732
|
-
description:
|
|
792
|
+
description:
|
|
793
|
+
"Include Docker configuration (Dockerfile, docker-compose.yml)",
|
|
733
794
|
},
|
|
734
795
|
{
|
|
735
|
-
name:
|
|
736
|
-
type:
|
|
796
|
+
name: "link",
|
|
797
|
+
type: "boolean",
|
|
737
798
|
default: false,
|
|
738
|
-
description:
|
|
799
|
+
description: "Use local @buenojs/bueno via bun link (for development)",
|
|
739
800
|
},
|
|
740
801
|
{
|
|
741
|
-
name:
|
|
742
|
-
type:
|
|
743
|
-
description:
|
|
802
|
+
name: "deploy",
|
|
803
|
+
type: "string",
|
|
804
|
+
description:
|
|
805
|
+
"Deployment platform configuration (render, fly, railway). Can be specified multiple times.",
|
|
744
806
|
},
|
|
745
807
|
{
|
|
746
|
-
name:
|
|
747
|
-
alias:
|
|
748
|
-
type:
|
|
808
|
+
name: "yes",
|
|
809
|
+
alias: "y",
|
|
810
|
+
type: "boolean",
|
|
749
811
|
default: false,
|
|
750
|
-
description:
|
|
812
|
+
description: "Use default options without prompts",
|
|
751
813
|
},
|
|
752
814
|
],
|
|
753
815
|
examples: [
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
816
|
+
"bueno new my-app",
|
|
817
|
+
"bueno new my-api --template api",
|
|
818
|
+
"bueno new my-fullstack --template fullstack --framework react",
|
|
819
|
+
"bueno new my-project --database postgresql",
|
|
820
|
+
"bueno new my-website --template website",
|
|
821
|
+
"bueno new my-app --docker",
|
|
822
|
+
"bueno new my-app --docker --database postgresql",
|
|
823
|
+
"bueno new my-app --deploy render",
|
|
824
|
+
"bueno new my-app --deploy fly",
|
|
825
|
+
"bueno new my-app --deploy render --deploy fly",
|
|
826
|
+
"bueno new my-app --docker --deploy render",
|
|
827
|
+
"bueno new my-app --docker --database postgresql --deploy render",
|
|
828
|
+
"bueno new my-app -y",
|
|
829
|
+
"bueno new my-app --link",
|
|
768
830
|
],
|
|
769
831
|
},
|
|
770
832
|
handleNew,
|
|
771
|
-
);
|
|
833
|
+
);
|