create-basalt 1.9.0 → 1.11.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.
- package/README.md +192 -21
- package/dist/args.d.ts +1 -1
- package/dist/args.js +16 -2
- package/dist/bin-template.d.ts +28 -0
- package/dist/bin-template.js +291 -0
- package/dist/cli.js +46 -6
- package/dist/dev-entry.d.ts +23 -0
- package/dist/dev-entry.js +49 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.js +53 -28
- package/dist/latest-versions.d.ts +31 -2
- package/dist/latest-versions.js +91 -51
- package/dist/project/add.d.ts +66 -0
- package/dist/project/add.js +322 -0
- package/dist/project/context.d.ts +53 -0
- package/dist/project/context.js +112 -0
- package/dist/project/doctor.d.ts +50 -0
- package/dist/project/doctor.js +460 -0
- package/dist/project/manifest.d.ts +36 -0
- package/dist/project/manifest.js +81 -0
- package/dist/project/package-json.d.ts +57 -0
- package/dist/project/package-json.js +161 -0
- package/dist/project/run.d.ts +55 -0
- package/dist/project/run.js +477 -0
- package/dist/project/semver.d.ts +29 -0
- package/dist/project/semver.js +132 -0
- package/dist/project/term.d.ts +24 -0
- package/dist/project/term.js +39 -0
- package/dist/project/update.d.ts +101 -0
- package/dist/project/update.js +325 -0
- package/dist/templates.d.ts +31 -5
- package/dist/templates.js +102 -58
- package/dist/versions.js +6 -5
- package/dist/wizard.js +3 -3
- package/package.json +8 -8
package/dist/templates.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { THIRD_PARTY_VERSIONS } from './latest-versions.js';
|
|
2
2
|
import { SCAFFOLD_VERSIONS } from './versions.js';
|
|
3
|
+
export { basaltBin } from './bin-template.js';
|
|
3
4
|
export { SCAFFOLD_VERSIONS } from './versions.js';
|
|
4
5
|
export { THIRD_PARTY_VERSIONS } from './latest-versions.js';
|
|
5
6
|
/**
|
|
@@ -28,6 +29,10 @@ export const thirdPartyVersionOf = (pkg) => {
|
|
|
28
29
|
}
|
|
29
30
|
return range;
|
|
30
31
|
};
|
|
32
|
+
/** The root `basalt` script of an app without `--cli`: create-basalt's project commands. */
|
|
33
|
+
export const BASALT_PROJECT_SCRIPT = 'create-basalt --project';
|
|
34
|
+
/** The root `dev:web` script of a `--ui` app (web/ is a pnpm workspace member). */
|
|
35
|
+
export const webDevScript = (options) => `pnpm --filter ${options.name}-web dev`;
|
|
31
36
|
/** True when the scaffold binds users to the tenant they act on (tenancy + auth). */
|
|
32
37
|
export const enforcesMembership = (options) => options.tenancy && options.auth;
|
|
33
38
|
export function packageJson(options) {
|
|
@@ -76,6 +81,9 @@ export function packageJson(options) {
|
|
|
76
81
|
}
|
|
77
82
|
const devDependencies = {
|
|
78
83
|
'@basaltkit/testing': versionOf('@basaltkit/testing'),
|
|
84
|
+
// The project commands (\`pnpm basalt update | add | doctor | info\`) — dev
|
|
85
|
+
// tooling with no dependencies of its own, never imported by the app.
|
|
86
|
+
'create-basalt': versionOf('create-basalt'),
|
|
79
87
|
};
|
|
80
88
|
for (const pkg of ['@types/node', 'pino-pretty', 'tsx', 'typescript', 'vitest']) {
|
|
81
89
|
devDependencies[pkg] = thirdPartyVersionOf(pkg);
|
|
@@ -107,7 +115,11 @@ export function packageJson(options) {
|
|
|
107
115
|
start: 'tsx src/server.ts',
|
|
108
116
|
test: 'vitest run',
|
|
109
117
|
typecheck: 'tsc --noEmit',
|
|
110
|
-
|
|
118
|
+
// With --cli, bin/basalt.ts serves the generators AND hands the project
|
|
119
|
+
// commands to create-basalt; without it, \`pnpm basalt update\` goes to
|
|
120
|
+
// create-basalt directly (\`create-basalt add cli\` swaps the script).
|
|
121
|
+
basalt: options.cli ? 'tsx bin/basalt.ts' : BASALT_PROJECT_SCRIPT,
|
|
122
|
+
...(options.ui ? { 'dev:web': webDevScript(options) } : {}),
|
|
111
123
|
...(options.prisma
|
|
112
124
|
? {
|
|
113
125
|
// Generate right after install so `pnpm typecheck` has the client
|
|
@@ -210,10 +222,19 @@ export function envPrefix(name) {
|
|
|
210
222
|
base = base.slice(start, end);
|
|
211
223
|
return base === '' || /^\d/.test(base) ? `APP_${base}` : base;
|
|
212
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* The opening lines of `.env.example`. Up to create-basalt 1.10 they read
|
|
227
|
+
* {@link LEGACY_ENV_EXAMPLE_LEAD} ("nothing loads this file"); `update`
|
|
228
|
+
* swaps that for this one in existing apps.
|
|
229
|
+
*/
|
|
230
|
+
export const ENV_EXAMPLE_LEAD = `# Development: copy this file to .env — \`pnpm dev\` and \`pnpm basalt\` load it
|
|
231
|
+
# automatically (a new app already has one). \`pnpm start\` (production) does
|
|
232
|
+
# NOT: there the variables come from the environment (or \`node --env-file\`).`;
|
|
233
|
+
export const LEGACY_ENV_EXAMPLE_LEAD = `# Nothing loads this file for you: copy it to .env and start with
|
|
234
|
+
# \`node --env-file=.env\` / \`tsx --env-file=.env\`, or export the variables.`;
|
|
213
235
|
export function envExample(options) {
|
|
214
236
|
const prefix = envPrefix(options.name);
|
|
215
|
-
return
|
|
216
|
-
# \`node --env-file=.env\` / \`tsx --env-file=.env\`, or export the variables.
|
|
237
|
+
return `${ENV_EXAMPLE_LEAD}
|
|
217
238
|
# --env-file NEVER overrides a variable already exported in your shell: if
|
|
218
239
|
# another project exported PORT or DATABASE_URL, an app reading the generic
|
|
219
240
|
# name would silently use THAT one. That is why src/env.ts reads app-prefixed
|
|
@@ -240,6 +261,20 @@ ${prefix}_DATABASE_URL=postgres://postgres:postgres@localhost:5432/${databaseNam
|
|
|
240
261
|
# ${prefix}_DATABASE_URL=postgres://user:pass@localhost:5432/${options.name.replace(/^@[^/]+\//, '')}
|
|
241
262
|
`}`;
|
|
242
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* The `.env` a new app starts with (git-ignored, never in the manifest): the
|
|
266
|
+
* values of `.env.example` for local development plus — with auth — a freshly
|
|
267
|
+
* generated APP_SECRET, so `pnpm dev` works without a copy step.
|
|
268
|
+
*/
|
|
269
|
+
export function devEnvFile(options, appSecret) {
|
|
270
|
+
const prefix = envPrefix(options.name);
|
|
271
|
+
const example = envExample(options);
|
|
272
|
+
const body = example.slice(example.indexOf(`${prefix}_PORT=`));
|
|
273
|
+
return `# Local development settings, generated by create-basalt from .env.example.
|
|
274
|
+
# Git-ignored: never commit it. \`pnpm dev\` and \`pnpm basalt\` load it (a
|
|
275
|
+
# variable exported in your shell wins); \`pnpm start\` (production) does not.
|
|
276
|
+
${body.replace(`# ${prefix}_APP_SECRET=\n`, `${prefix}_APP_SECRET=${appSecret}\n`)}`;
|
|
277
|
+
}
|
|
243
278
|
/** A PostgreSQL-safe database name derived from the project name. */
|
|
244
279
|
export function databaseName(name) {
|
|
245
280
|
return name.replace(/^@[^/]+\//, '').replace(/[^a-zA-Z0-9]+/g, '_').toLowerCase();
|
|
@@ -514,45 +549,31 @@ for (const signal of ['SIGINT', 'SIGTERM'] as const) {
|
|
|
514
549
|
`;
|
|
515
550
|
}
|
|
516
551
|
/**
|
|
517
|
-
* `pnpm dev` entrypoint.
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
* NODE_ENV
|
|
552
|
+
* `pnpm dev` entrypoint. Loads `.env` (when present) with `node --env-file`
|
|
553
|
+
* semantics — an exported variable wins, the file only fills in what is
|
|
554
|
+
* missing — and opts into NODE_ENV=development (dev secret defaults, pretty
|
|
555
|
+
* logs) unless NODE_ENV is already set, then starts the server. Kept out of
|
|
556
|
+
* server.ts on purpose: `pnpm start` runs server.ts directly, where nothing
|
|
557
|
+
* loads `.env` (production configuration comes from the real environment) and
|
|
558
|
+
* an unset NODE_ENV counts as production, so secrets are required (fail-closed).
|
|
521
559
|
*/
|
|
522
560
|
export function devTs() {
|
|
523
561
|
return `// Development entrypoint (\`pnpm dev\`). \`pnpm start\` runs server.ts directly,
|
|
524
562
|
// where an unset NODE_ENV counts as production: secrets are then required.
|
|
563
|
+
import { existsSync } from 'node:fs'
|
|
564
|
+
import { fileURLToPath } from 'node:url'
|
|
565
|
+
|
|
566
|
+
// Development loads .env (when present) like \`node --env-file=.env\`: a variable
|
|
567
|
+
// already exported in your shell still wins, the file only fills in what is
|
|
568
|
+
// missing. \`pnpm start\` (production) never loads it — there the configuration
|
|
569
|
+
// comes from the real environment.
|
|
570
|
+
const envFile = fileURLToPath(new URL('../.env', import.meta.url))
|
|
571
|
+
if (existsSync(envFile)) process.loadEnvFile(envFile)
|
|
572
|
+
|
|
525
573
|
process.env['NODE_ENV'] ??= 'development'
|
|
526
574
|
await import('./server.js')
|
|
527
575
|
`;
|
|
528
576
|
}
|
|
529
|
-
export function basaltBin() {
|
|
530
|
-
return `#!/usr/bin/env node
|
|
531
|
-
import { runCli } from '@basaltkit/cli'
|
|
532
|
-
import { generatorCommands } from '@basaltkit/generator'
|
|
533
|
-
import { prismaSyncCommand } from '@basaltkit/prisma'
|
|
534
|
-
|
|
535
|
-
// Dev tooling: opt into development defaults unless NODE_ENV is already set
|
|
536
|
-
// (imported dynamically below so env.ts is evaluated after this line).
|
|
537
|
-
process.env['NODE_ENV'] ??= 'development'
|
|
538
|
-
const { buildApp } = await import('../src/app.js')
|
|
539
|
-
|
|
540
|
-
// The 'basalt' CLI: boots the app WITH the dev/CLI commands, runs one, shuts down.
|
|
541
|
-
// The dev tools (@basaltkit/generator; add @basaltkit/ai for ai:*) are imported
|
|
542
|
-
// ONLY here — the runtime server (src/server.ts) never loads them, so the SaaS
|
|
543
|
-
// runs without the codegen/AI layer.
|
|
544
|
-
// pnpm basalt dev — dev server: route table + watch (--worker for a queue worker)
|
|
545
|
-
// pnpm basalt list — show available commands
|
|
546
|
-
// pnpm basalt routes — list registered HTTP routes
|
|
547
|
-
// pnpm basalt make:resource Project — generate a full resource vertical
|
|
548
|
-
// pnpm basalt make:service Project — generate a single artifact (schema/service/…)
|
|
549
|
-
const app = buildApp({
|
|
550
|
-
logLevel: 'silent',
|
|
551
|
-
commands: [...generatorCommands(), prismaSyncCommand()],
|
|
552
|
-
})
|
|
553
|
-
process.exit(await runCli({ app }))
|
|
554
|
-
`;
|
|
555
|
-
}
|
|
556
577
|
/**
|
|
557
578
|
* The models each `@basaltkit/<domain>-prisma` package needs, copied VERBATIM
|
|
558
579
|
* from that package's reference `prisma/schema.prisma` — the same blocks
|
|
@@ -807,9 +828,9 @@ export function prismaConfigTs(options) {
|
|
|
807
828
|
return `import { loadEnvFile } from 'node:process'
|
|
808
829
|
import { defineConfig } from 'prisma/config'
|
|
809
830
|
|
|
810
|
-
// Prisma loads no .env for you
|
|
811
|
-
// mirrors \`node --env-file=.env\`: a variable already
|
|
812
|
-
// still wins, the file only fills in what is missing.
|
|
831
|
+
// Prisma loads no .env for you. Like the app's dev entrypoints (src/dev.ts,
|
|
832
|
+
// bin/basalt.ts) this mirrors \`node --env-file=.env\`: a variable already
|
|
833
|
+
// exported in your shell still wins, the file only fills in what is missing.
|
|
813
834
|
try {
|
|
814
835
|
loadEnvFile('.env')
|
|
815
836
|
} catch {
|
|
@@ -962,7 +983,7 @@ Included: ${features.join(' · ')}.
|
|
|
962
983
|
\`\`\`bash
|
|
963
984
|
pnpm install${options.prisma
|
|
964
985
|
? `
|
|
965
|
-
#
|
|
986
|
+
# start PostgreSQL — .env points ${envPrefix(options.name)}_DATABASE_URL at localhost:5432 — then
|
|
966
987
|
pnpm db:migrate # create the tables${options.tenancy ? ` (runs the seed too)` : ''}`
|
|
967
988
|
: ''}
|
|
968
989
|
pnpm dev # API on http://localhost:3000
|
|
@@ -1020,16 +1041,18 @@ scaffold with \`--cli\` — \`pnpm basalt prisma:sync\` does the merge for you.)
|
|
|
1020
1041
|
: ''}
|
|
1021
1042
|
## Environment
|
|
1022
1043
|
|
|
1023
|
-
\`src/env.ts\` validates \`process.env
|
|
1024
|
-
|
|
1025
|
-
|
|
1044
|
+
\`src/env.ts\` validates \`process.env\`. For development, ${options.cli ? '`pnpm dev` and `pnpm basalt` load' : '`pnpm dev` loads'} \`.env\`
|
|
1045
|
+
automatically — create-basalt wrote one for you: git-ignored, with local
|
|
1046
|
+
values${options.auth ? ' and a generated secret' : ''}. \`.env.example\` is its committed template.
|
|
1047
|
+
\`pnpm start\` (production, \`src/server.ts\`) loads **nothing**: there the
|
|
1048
|
+
variables come from the real environment (or \`node --env-file=.env\`).
|
|
1026
1049
|
|
|
1027
1050
|
The variables are **app-prefixed**: \`${envPrefix(options.name)}_PORT\`,
|
|
1028
1051
|
\`${envPrefix(options.name)}_HOST\`, \`${envPrefix(options.name)}_LOG_LEVEL\`${options.auth ? `, \`${envPrefix(options.name)}_APP_SECRET\`` : ''}${options.prisma ? `, \`${envPrefix(options.name)}_DATABASE_URL\`` : ''}. \`NODE_ENV\` is never prefixed.
|
|
1029
1052
|
|
|
1030
|
-
Why:
|
|
1031
|
-
shell where another project exported \`DATABASE_URL\`
|
|
1032
|
-
the generic name boots against THAT value and only fails on the first request
|
|
1053
|
+
Why: **loading \`.env\` (like \`--env-file\`) never overrides a variable that is
|
|
1054
|
+
already exported.** In a shell where another project exported \`DATABASE_URL\`
|
|
1055
|
+
(or \`PORT\`), an app reading the generic name boots against THAT value and only fails on the first request
|
|
1033
1056
|
that touches it. \`src/env.ts\` therefore passes \`prefix: '${envPrefix(options.name)}'\` to
|
|
1034
1057
|
\`defineEnv\`: each variable is read as \`${envPrefix(options.name)}_<NAME>\` first and
|
|
1035
1058
|
**falls back** to the bare \`<NAME>\`, so a deployment that already exports the
|
|
@@ -1044,8 +1067,24 @@ database and \`DATABASE_URL\` is read as \`${envPrefix(options.name)}_DATABASE_U
|
|
|
1044
1067
|
To drop the fallback entirely (prefixed names only), write
|
|
1045
1068
|
\`prefix: { value: '${envPrefix(options.name)}', fallback: false }\`. When in doubt about what
|
|
1046
1069
|
your shell exports: \`env | grep DATABASE_URL\`.
|
|
1047
|
-
|
|
1048
|
-
|
|
1070
|
+
|
|
1071
|
+
## Keeping it up to date
|
|
1072
|
+
|
|
1073
|
+
\`\`\`bash
|
|
1074
|
+
pnpm basalt update # dependencies → latest (framework always; third-party within its major)
|
|
1075
|
+
pnpm basalt update --dry # preview the table, write nothing
|
|
1076
|
+
pnpm basalt add ui # add a feature later: ui, cli, mcp
|
|
1077
|
+
pnpm basalt doctor # Node, package manager, versions, env and Prisma checks
|
|
1078
|
+
\`\`\`
|
|
1079
|
+
|
|
1080
|
+
\`.basalt/project.json\` records what create-basalt generated (options and file
|
|
1081
|
+
hashes) — commit it: \`add\` and \`update\` use it to tell untouched template
|
|
1082
|
+
files from the ones you edited.
|
|
1083
|
+
${options.cli ? readmeCliSection(options) : ''}${options.ui ? readmeUiSection(options) : ''}${options.mcp ? readmeMcpSection(options) : ''}`;
|
|
1084
|
+
}
|
|
1085
|
+
/** README section for the \`basalt\` CLI (also appended by \`create-basalt add cli\`). */
|
|
1086
|
+
export function readmeCliSection(_options) {
|
|
1087
|
+
return `
|
|
1049
1088
|
## The \`basalt\` CLI
|
|
1050
1089
|
|
|
1051
1090
|
\`\`\`bash
|
|
@@ -1069,21 +1108,25 @@ node_modules/.bin/tsx bin/basalt.ts make:resource Project
|
|
|
1069
1108
|
|
|
1070
1109
|
or set \`verifyDepsBeforeRun: warn\` in \`pnpm-workspace.yaml\` (a conscious
|
|
1071
1110
|
choice: you then run \`pnpm install\` yourself after dependency changes).
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1111
|
+
`;
|
|
1112
|
+
}
|
|
1113
|
+
/** README section for the web/ frontend (also appended by \`create-basalt add ui\`). */
|
|
1114
|
+
export function readmeUiSection(options) {
|
|
1115
|
+
return `
|
|
1075
1116
|
## Web UI
|
|
1076
1117
|
|
|
1077
1118
|
\`\`\`bash
|
|
1078
|
-
pnpm dev
|
|
1079
|
-
pnpm
|
|
1119
|
+
pnpm dev # terminal 1 — API on :3000
|
|
1120
|
+
pnpm dev:web # terminal 2 — UI on http://localhost:5180 (pnpm --filter ${options.name}-web dev)
|
|
1080
1121
|
\`\`\`
|
|
1081
1122
|
|
|
1082
1123
|
Open <http://localhost:5180>. The Vite dev server proxies \`/api\` to the API,
|
|
1083
1124
|
so there is no CORS to configure${options.auth ? '. Register, then sign in' : ''}.
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1125
|
+
`;
|
|
1126
|
+
}
|
|
1127
|
+
/** README section for the MCP server (also appended by \`create-basalt add mcp\`). */
|
|
1128
|
+
export function readmeMcpSection(_options) {
|
|
1129
|
+
return `
|
|
1087
1130
|
## MCP server
|
|
1088
1131
|
|
|
1089
1132
|
Read-only routes marked with \`meta.mcp\` in \`src/routes.ts\` (the overview and
|
|
@@ -1109,8 +1152,7 @@ app's runtime) with MCP clients such as Claude Code and Claude Desktop. It expos
|
|
|
1109
1152
|
\`basalt_make\` (preview by default, writes confined to this project) plus workflow
|
|
1110
1153
|
prompts. Claude Code picks up \`.mcp.json\` automatically; for Claude Desktop add the
|
|
1111
1154
|
same server to its config with \`--cwd=<absolute project path>\`.
|
|
1112
|
-
|
|
1113
|
-
: ''}`;
|
|
1155
|
+
`;
|
|
1114
1156
|
}
|
|
1115
1157
|
/**
|
|
1116
1158
|
* A Claude Code / generic MCP client config that registers the dev-only
|
|
@@ -1183,10 +1225,12 @@ export function pnpmWorkspaceYaml(options) {
|
|
|
1183
1225
|
: ''}allowBuilds:
|
|
1184
1226
|
esbuild: true
|
|
1185
1227
|
msgpackr-extract: false
|
|
1186
|
-
# @basaltkit/* releases in lockstep, often within hours — exclude the scope
|
|
1187
|
-
#
|
|
1228
|
+
# @basaltkit/* releases in lockstep, often within hours — exclude the scope (and
|
|
1229
|
+
# create-basalt, which serves \`pnpm basalt update\`) from pnpm's minimumReleaseAge
|
|
1230
|
+
# policy so an update is never blocked on a fresh release.
|
|
1188
1231
|
minimumReleaseAgeExclude:
|
|
1189
1232
|
- '@basaltkit/*'
|
|
1233
|
+
- create-basalt
|
|
1190
1234
|
# To let specific versions of ONE package bypass the policy, write ONE entry
|
|
1191
1235
|
# with a \`||\` union. pnpm evaluates this list first match wins by package
|
|
1192
1236
|
# name, so a second '<name>@<version>' entry for the same package is ignored:
|
package/dist/versions.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
export const SCAFFOLD_VERSIONS = {
|
|
5
5
|
'@basaltkit/admin': '^2.0.0',
|
|
6
6
|
'@basaltkit/admin-shadcn': '^1.1.0',
|
|
7
|
-
'@basaltkit/ai-mcp': '^0.
|
|
8
|
-
'@basaltkit/auth': '^4.
|
|
7
|
+
'@basaltkit/ai-mcp': '^0.3.0',
|
|
8
|
+
'@basaltkit/auth': '^4.1.0',
|
|
9
9
|
'@basaltkit/auth-prisma': '^2.0.0',
|
|
10
|
-
'@basaltkit/cli': '^1.
|
|
10
|
+
'@basaltkit/cli': '^1.3.0',
|
|
11
11
|
'@basaltkit/config': '^1.1.0',
|
|
12
12
|
'@basaltkit/core': '^1.5.0',
|
|
13
13
|
'@basaltkit/env': '^3.1.0',
|
|
@@ -15,14 +15,15 @@ export const SCAFFOLD_VERSIONS = {
|
|
|
15
15
|
'@basaltkit/fastify': '^2.5.0',
|
|
16
16
|
'@basaltkit/generator': '^1.5.0',
|
|
17
17
|
'@basaltkit/logger': '^1.3.0',
|
|
18
|
-
'@basaltkit/mcp': '^
|
|
18
|
+
'@basaltkit/mcp': '^5.0.0',
|
|
19
19
|
'@basaltkit/prisma': '^3.0.0',
|
|
20
20
|
'@basaltkit/sdk': '^2.1.0',
|
|
21
21
|
'@basaltkit/subscriptions': '^5.0.0',
|
|
22
22
|
'@basaltkit/subscriptions-prisma': '^3.0.0',
|
|
23
23
|
'@basaltkit/teams': '^4.0.0',
|
|
24
24
|
'@basaltkit/teams-prisma': '^1.1.0',
|
|
25
|
-
'@basaltkit/tenancy': '^3.
|
|
25
|
+
'@basaltkit/tenancy': '^3.1.0',
|
|
26
26
|
'@basaltkit/tenancy-prisma': '^2.0.0',
|
|
27
27
|
'@basaltkit/testing': '^2.0.0',
|
|
28
|
+
'create-basalt': '^1.11.0',
|
|
28
29
|
};
|
package/dist/wizard.js
CHANGED
|
@@ -11,9 +11,9 @@ export const FEATURES = [
|
|
|
11
11
|
];
|
|
12
12
|
export const PRESETS = [
|
|
13
13
|
{ value: 'saas', label: 'SaaS starter', hint: 'tenancy + auth + billing + database + CLI', features: ['tenancy', 'auth', 'billing', 'prisma', 'cli'] },
|
|
14
|
-
{ value: 'api', label: 'API only', hint: 'auth + MCP, no tenancy or UI', features: ['auth', 'mcp'] },
|
|
14
|
+
{ value: 'api', label: 'API only', hint: 'auth + MCP + CLI, no tenancy or UI', features: ['auth', 'mcp', 'cli'] },
|
|
15
15
|
{ value: 'full', label: 'Full stack', hint: 'everything + web UI', features: ['tenancy', 'auth', 'billing', 'prisma', 'ui', 'cli', 'mcp'] },
|
|
16
|
-
{ value: 'minimal', label: 'Minimal', hint: '
|
|
16
|
+
{ value: 'minimal', label: 'Minimal', hint: 'just the CLI, add the rest later', features: ['cli'] },
|
|
17
17
|
{ value: 'custom', label: 'Custom', hint: 'pick features yourself', features: null },
|
|
18
18
|
];
|
|
19
19
|
const PACKAGE_MANAGERS = [
|
|
@@ -59,7 +59,7 @@ export async function runWizard(prompter, options = {}) {
|
|
|
59
59
|
(await prompter.multiselect({
|
|
60
60
|
message: 'Select features',
|
|
61
61
|
choices: FEATURES,
|
|
62
|
-
initial: ['tenancy', 'auth'],
|
|
62
|
+
initial: ['tenancy', 'auth', 'cli'],
|
|
63
63
|
})));
|
|
64
64
|
let pm = await prompter.select({
|
|
65
65
|
message: 'Package manager',
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-basalt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22.5.0"
|
|
6
6
|
},
|
|
7
|
-
"description": "Scaffold a production-shaped Basalt SaaS app
|
|
7
|
+
"description": "Scaffold a production-shaped Basalt SaaS app (npm create basalt my-saas [--billing] [--ui] [--cli] [--install] [--git]) — then keep it current: create-basalt update | add | doctor | info",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"sideEffects": false,
|
|
@@ -30,26 +30,26 @@
|
|
|
30
30
|
"typescript": "^7.0.2",
|
|
31
31
|
"vitest": "^5.0.1",
|
|
32
32
|
"zod": "^4.6.5",
|
|
33
|
-
"@basaltkit/auth": "^4.
|
|
33
|
+
"@basaltkit/auth": "^4.1.0",
|
|
34
34
|
"@basaltkit/auth-prisma": "^2.0.0",
|
|
35
|
-
"@basaltkit/cli": "^1.2.5",
|
|
36
35
|
"@basaltkit/config": "^1.1.2",
|
|
36
|
+
"@basaltkit/cli": "^1.3.0",
|
|
37
37
|
"@basaltkit/core": "^1.5.0",
|
|
38
38
|
"@basaltkit/env": "^3.1.1",
|
|
39
39
|
"@basaltkit/events": "^1.3.0",
|
|
40
40
|
"@basaltkit/fastify": "^2.5.0",
|
|
41
41
|
"@basaltkit/generator": "^1.5.0",
|
|
42
42
|
"@basaltkit/logger": "^1.3.0",
|
|
43
|
-
"@basaltkit/mcp": "^
|
|
43
|
+
"@basaltkit/mcp": "^5.0.0",
|
|
44
44
|
"@basaltkit/prisma": "^3.0.0",
|
|
45
45
|
"@basaltkit/subscriptions": "^5.0.0",
|
|
46
46
|
"@basaltkit/subscriptions-prisma": "^3.0.0",
|
|
47
47
|
"@basaltkit/teams": "^4.0.0",
|
|
48
48
|
"@basaltkit/teams-prisma": "^1.1.0",
|
|
49
|
-
"@basaltkit/tenancy": "^3.
|
|
50
|
-
"@basaltkit/
|
|
49
|
+
"@basaltkit/tenancy": "^3.1.0",
|
|
50
|
+
"@basaltkit/tsconfig": "^0.24.0",
|
|
51
51
|
"@basaltkit/testing": "^2.0.3",
|
|
52
|
-
"@basaltkit/
|
|
52
|
+
"@basaltkit/tenancy-prisma": "^2.0.0"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|