create-basalt 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +22 -7
- package/dist/index.d.ts +18 -0
- package/dist/index.js +16 -0
- package/dist/templates.js +6 -3
- package/dist/wizard.js +2 -2
- package/package.json +16 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { stdin, stdout } from 'node:process';
|
|
4
|
-
import { createProject, detectPackageManager, runWizard, ttyPrompter, TargetNotEmptyError, WizardCancelledError, } from './index.js';
|
|
4
|
+
import { createProject, detectPackageManager, resolveRunDefaults, runWizard, ttyPrompter, TargetNotEmptyError, WizardCancelledError, } from './index.js';
|
|
5
5
|
const USAGE = `Usage: npm create basalt <name> [options]
|
|
6
6
|
|
|
7
7
|
Options:
|
|
@@ -12,8 +12,12 @@ Options:
|
|
|
12
12
|
--ui Scaffold a web/ frontend (React + shadcn + SDK)
|
|
13
13
|
--cli Scaffold the 'basalt' CLI (code generators + commands)
|
|
14
14
|
--mcp Expose read-only routes as MCP tools at /mcp
|
|
15
|
-
--install Install dependencies
|
|
15
|
+
--install Install dependencies (default: yes in an interactive
|
|
16
|
+
terminal, skipped in CI/non-TTY; --no-install to opt out)
|
|
17
|
+
--no-install Never install dependencies
|
|
16
18
|
--git Initialize a git repository with a first commit
|
|
19
|
+
(same default rule as --install; --no-git to opt out)
|
|
20
|
+
--no-git Never initialize a git repository
|
|
17
21
|
--pm=<manager> Package manager: pnpm | npm | yarn | bun (default: auto-detect)
|
|
18
22
|
-y, --yes Skip prompts and accept defaults
|
|
19
23
|
-h, --help Show this help
|
|
@@ -28,8 +32,6 @@ function parseArgs(argv) {
|
|
|
28
32
|
ui: false,
|
|
29
33
|
cli: false,
|
|
30
34
|
mcp: false,
|
|
31
|
-
install: false,
|
|
32
|
-
git: false,
|
|
33
35
|
yes: false,
|
|
34
36
|
};
|
|
35
37
|
for (const token of argv) {
|
|
@@ -47,8 +49,12 @@ function parseArgs(argv) {
|
|
|
47
49
|
flags.mcp = true;
|
|
48
50
|
else if (token === '--install')
|
|
49
51
|
flags.install = true;
|
|
52
|
+
else if (token === '--no-install')
|
|
53
|
+
flags.install = false;
|
|
50
54
|
else if (token === '--git')
|
|
51
55
|
flags.git = true;
|
|
56
|
+
else if (token === '--no-git')
|
|
57
|
+
flags.git = false;
|
|
52
58
|
else if (token === '-y' || token === '--yes')
|
|
53
59
|
flags.yes = true;
|
|
54
60
|
else if (token.startsWith('--dir='))
|
|
@@ -131,21 +137,30 @@ try {
|
|
|
131
137
|
console.log(`\nCreated ${result.options.name} in ${result.dir}\n`);
|
|
132
138
|
for (const file of result.files)
|
|
133
139
|
console.log(` ${file}`);
|
|
134
|
-
|
|
140
|
+
const run_ = resolveRunDefaults({
|
|
141
|
+
install: flags.install,
|
|
142
|
+
git: flags.git,
|
|
143
|
+
isTTY: Boolean(stdin.isTTY),
|
|
144
|
+
ci: Boolean(process.env['CI']),
|
|
145
|
+
});
|
|
146
|
+
if (flags.install === undefined && !run_.interactive) {
|
|
147
|
+
console.log('\nSkipping dependency install (CI/non-interactive) — pass --install to force it.');
|
|
148
|
+
}
|
|
149
|
+
if (run_.git) {
|
|
135
150
|
console.log('\nInitializing git repository…');
|
|
136
151
|
const ok = (await run('git', ['init', '-q'], result.dir)) &&
|
|
137
152
|
(await run('git', ['add', '-A'], result.dir)) &&
|
|
138
153
|
(await run('git', ['commit', '-q', '-m', 'Initial commit from create-basalt'], result.dir));
|
|
139
154
|
console.log(ok ? ' git repository initialized.' : ' (skipped — git unavailable or already a repo)');
|
|
140
155
|
}
|
|
141
|
-
if (
|
|
156
|
+
if (run_.install) {
|
|
142
157
|
console.log(`\nInstalling dependencies with ${pm}…`);
|
|
143
158
|
const ok = await run(pm, ['install'], result.dir);
|
|
144
159
|
if (!ok)
|
|
145
160
|
console.log(` (install failed — run "${pm} install" yourself)`);
|
|
146
161
|
}
|
|
147
162
|
const steps = [`cd ${result.dir}`];
|
|
148
|
-
if (!
|
|
163
|
+
if (!run_.install)
|
|
149
164
|
steps.push(`${pm} install`);
|
|
150
165
|
steps.push(`${pm} run dev${flags.ui ? ' # API on :3000' : ''}`);
|
|
151
166
|
// `web` is wired as a pnpm workspace member (pnpm-workspace.yaml), so its dev
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,24 @@ export type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';
|
|
|
28
28
|
* `npm_config_user_agent` env var npm/pnpm/yarn/bun all set. Falls back to npm.
|
|
29
29
|
*/
|
|
30
30
|
export declare function detectPackageManager(userAgent?: string | undefined): PackageManager;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve whether to install dependencies / init git when the flag was not
|
|
33
|
+
* given explicitly (D1, ecosystem review 2026-08): interactive terminals
|
|
34
|
+
* default to YES — `npm create basalt my-app` should end in a runnable app —
|
|
35
|
+
* while CI and non-TTY runs default to NO, so automation never gets a
|
|
36
|
+
* surprise install. An explicit `--install`/`--no-install` (or git flag)
|
|
37
|
+
* always wins over the environment.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveRunDefaults(input: {
|
|
40
|
+
install?: boolean | undefined;
|
|
41
|
+
git?: boolean | undefined;
|
|
42
|
+
isTTY: boolean;
|
|
43
|
+
ci: boolean;
|
|
44
|
+
}): {
|
|
45
|
+
install: boolean;
|
|
46
|
+
git: boolean;
|
|
47
|
+
interactive: boolean;
|
|
48
|
+
};
|
|
31
49
|
/** Generates a ready-to-run Basalt app. Does not install dependencies. */
|
|
32
50
|
export declare function createProject(input: CreateProjectInput): Promise<CreateProjectResult>;
|
|
33
51
|
export { runWizard, validateProjectName, PRESETS, FEATURES, type WizardResult, type WizardOptions, type FeatureKey } from './wizard.js';
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,22 @@ export function detectPackageManager(userAgent = process.env['npm_config_user_ag
|
|
|
18
18
|
return name;
|
|
19
19
|
return 'npm';
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve whether to install dependencies / init git when the flag was not
|
|
23
|
+
* given explicitly (D1, ecosystem review 2026-08): interactive terminals
|
|
24
|
+
* default to YES — `npm create basalt my-app` should end in a runnable app —
|
|
25
|
+
* while CI and non-TTY runs default to NO, so automation never gets a
|
|
26
|
+
* surprise install. An explicit `--install`/`--no-install` (or git flag)
|
|
27
|
+
* always wins over the environment.
|
|
28
|
+
*/
|
|
29
|
+
export function resolveRunDefaults(input) {
|
|
30
|
+
const interactive = input.isTTY && !input.ci;
|
|
31
|
+
return {
|
|
32
|
+
interactive,
|
|
33
|
+
install: input.install ?? interactive,
|
|
34
|
+
git: input.git ?? interactive,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
21
37
|
/** Generates a ready-to-run Basalt app. Does not install dependencies. */
|
|
22
38
|
export async function createProject(input) {
|
|
23
39
|
const options = {
|
package/dist/templates.js
CHANGED
|
@@ -95,12 +95,15 @@ export function tsconfigJson() {
|
|
|
95
95
|
}
|
|
96
96
|
export function envTs(options) {
|
|
97
97
|
return `import { defineEnv${options.auth ? ', secret' : ''} } from '@basaltkit/env'
|
|
98
|
+
import { LOG_LEVELS } from '@basaltkit/logger'
|
|
98
99
|
import { z } from 'zod'
|
|
99
100
|
|
|
100
101
|
export const env = defineEnv({
|
|
101
102
|
PORT: z.coerce.number().default(3000),
|
|
102
103
|
HOST: z.string().default('0.0.0.0'),
|
|
103
|
-
|
|
104
|
+
// Typed against the logger's LogLevel union — a free-form string here fails
|
|
105
|
+
// \`pnpm typecheck\` where loggerPlugin({ level }) consumes it.
|
|
106
|
+
LOG_LEVEL: z.enum(LOG_LEVELS).default('info'),
|
|
104
107
|
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),${options.auth
|
|
105
108
|
? `
|
|
106
109
|
// Signs JWTs and sessions. secret() is fail-closed: required in production
|
|
@@ -123,7 +126,7 @@ export function appTs(options) {
|
|
|
123
126
|
`import { configPlugin } from '@basaltkit/config'`,
|
|
124
127
|
`import { eventsPlugin } from '@basaltkit/events'`,
|
|
125
128
|
`import { fastifyPlugin, securityPlugin } from '@basaltkit/fastify'`,
|
|
126
|
-
`import { loggerPlugin } from '@basaltkit/logger'`,
|
|
129
|
+
`import { loggerPlugin, type LogLevel } from '@basaltkit/logger'`,
|
|
127
130
|
];
|
|
128
131
|
const plugins = [
|
|
129
132
|
`configPlugin({ app: { name: '${options.name}' } })`,
|
|
@@ -197,7 +200,7 @@ export function appTs(options) {
|
|
|
197
200
|
import { appRoutes } from './routes.js'
|
|
198
201
|
|
|
199
202
|
export interface BuildAppOptions {
|
|
200
|
-
logLevel?:
|
|
203
|
+
logLevel?: LogLevel
|
|
201
204
|
pretty?: boolean${commandsField}
|
|
202
205
|
}
|
|
203
206
|
|
package/dist/wizard.js
CHANGED
|
@@ -70,8 +70,8 @@ export async function runWizard(prompter, options = {}) {
|
|
|
70
70
|
prompter.note(` Note: the Web UI is a pnpm workspace — using pnpm instead of ${pm}.`);
|
|
71
71
|
pm = 'pnpm';
|
|
72
72
|
}
|
|
73
|
-
const install = await prompter.confirm({ message: 'Install dependencies now?', initial:
|
|
74
|
-
const git = await prompter.confirm({ message: 'Initialize a git repository?', initial:
|
|
73
|
+
const install = await prompter.confirm({ message: 'Install dependencies now?', initial: true });
|
|
74
|
+
const git = await prompter.confirm({ message: 'Initialize a git repository?', initial: true });
|
|
75
75
|
const enabled = FEATURES.filter((f) => featureSet.has(f.value)).map((f) => f.label);
|
|
76
76
|
prompter.note(`\n Summary\n` +
|
|
77
77
|
` name ${name}\n` +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-basalt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Scaffold a production-shaped Basalt SaaS app: npm create basalt my-saas [--billing] [--ui] [--cli] [--install] [--git]",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,21 @@
|
|
|
20
20
|
"@types/node": "^26.3.0",
|
|
21
21
|
"typescript": "^7.0.2",
|
|
22
22
|
"vitest": "^4.1.11",
|
|
23
|
+
"zod": "^4.0.0",
|
|
24
|
+
"@basaltkit/auth": "^1.6.3",
|
|
25
|
+
"@basaltkit/config": "^1.1.1",
|
|
26
|
+
"@basaltkit/cli": "^1.2.1",
|
|
27
|
+
"@basaltkit/env": "^1.0.1",
|
|
28
|
+
"@basaltkit/core": "^1.3.0",
|
|
29
|
+
"@basaltkit/fastify": "^1.7.0",
|
|
30
|
+
"@basaltkit/generator": "^1.2.0",
|
|
31
|
+
"@basaltkit/events": "^1.0.1",
|
|
32
|
+
"@basaltkit/logger": "^1.2.1",
|
|
33
|
+
"@basaltkit/mcp": "^1.0.3",
|
|
34
|
+
"@basaltkit/subscriptions": "^2.7.0",
|
|
35
|
+
"@basaltkit/tenancy": "^1.4.0",
|
|
36
|
+
"@basaltkit/prisma": "^1.4.2",
|
|
37
|
+
"@basaltkit/testing": "^1.1.0",
|
|
23
38
|
"@basaltkit/tsconfig": "^0.24.0"
|
|
24
39
|
},
|
|
25
40
|
"publishConfig": {
|