@webjsdev/cli 0.10.28 → 0.10.29

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/bin/webjs.js CHANGED
@@ -147,6 +147,12 @@ async function main() {
147
147
  // down on exit so a watcher cannot outlive the server.
148
148
  const { readAppTasks } = await import('../lib/app-tasks.js');
149
149
  const devTasks = readAppTasks(process.cwd());
150
+ // Load `.env` BEFORE the before-steps (same as `start`, L188), so a
151
+ // `dev.before` `webjs db migrate` sees DATABASE_URL from `.env`. Without
152
+ // this a Postgres dev migrate runs with no connection string and fails
153
+ // (sqlite survives via its `?? 'db/dev.db'` config fallback). The watch
154
+ // child / inline server load `.env` again later (idempotent).
155
+ loadAppEnv(process.cwd());
150
156
  await runPhaseBeforeSteps('dev', devTasks.dev.before, process.cwd());
151
157
  const killTasks = await startDevParallelTasks(devTasks.dev.parallel, process.cwd());
152
158
  process.on('SIGINT', () => { killTasks(); process.exit(0); });
package/lib/create.js CHANGED
@@ -314,9 +314,9 @@ export async function scaffoldApp(name, cwd, opts = {}) {
314
314
  },
315
315
  scripts: {
316
316
  // No `predev` / `prestart` hooks (#550): the `webjs` block below holds
317
- // the start orchestration (`webjs db migrate`), run INSIDE `webjs start`,
318
- // so `npm run start` (a thin alias) behaves identically. Drizzle has no
319
- // codegen, so there is no dev `before` step.
317
+ // the dev + start orchestration (`webjs db migrate`), run INSIDE `webjs
318
+ // dev` / `webjs start`, so `npm run dev` / `start` (thin aliases) behave
319
+ // identically. Both apply pending migrations before serving (#725).
320
320
  //
321
321
  // Bun runtime (#541): the long-running server scripts (`dev` / `start`)
322
322
  // are prefixed `bun --bun` so the app SERVES on Bun. The `--bun` overrides
@@ -386,16 +386,16 @@ export async function scaffoldApp(name, cwd, opts = {}) {
386
386
  // into components/ui/ (they import @webjsdev/core, not the kit), and the
387
387
  // CLI resolves @webjsdev/ui from its own install.
388
388
  },
389
- // Start task orchestration (#550). `webjs start` reads `start.before` and
390
- // runs it in-process, so `npm run start` (a thin alias above) behaves
391
- // identically. Drizzle has no codegen, so there is no dev `before` step;
392
- // production applies pending migrations via `webjs db migrate`. The scaffold
389
+ // Dev + start task orchestration (#550). `webjs dev` / `webjs start` read
390
+ // `before` and run it in-process, so `npm run dev` / `start` (thin aliases
391
+ // above) behave identically. Both apply pending migrations via `webjs db
392
+ // migrate` (idempotent, a no-op when the db is current), so a freshly
393
+ // generated migration is applied without a manual step (#725). The scaffold
393
394
  // uses the Tailwind browser runtime (no CSS build step), so there is no dev
394
395
  // `parallel` watcher here; an app that adds the Tailwind CLI puts its
395
396
  // `--watch` command under `webjs.dev.parallel`.
396
397
  webjs: {
397
- // Drizzle has no codegen, so there is no dev `before` step. Production
398
- // applies pending migrations at boot via `webjs db migrate` (drizzle-kit).
398
+ dev: { before: ['webjs db migrate'] },
399
399
  start: { before: ['webjs db migrate'] },
400
400
  },
401
401
  }, null, 2) + '\n');
@@ -1388,13 +1388,22 @@ For AI agents, read this before editing scaffolded files:
1388
1388
  // Single copy-paste line so the user can move from "scaffold done"
1389
1389
  // to "dev server up" in one command. The full-stack and saas
1390
1390
  // templates ship with @webjsdev/ui already initialised; the api
1391
- // template has no UI but may add one later. Saas needs a one-time
1392
- // generate + migrate before the first run (the example User model wants
1393
- // its table to exist). Drizzle splits Prisma's `migrate dev` into
1394
- // `db:generate` (schema to SQL) then `db:migrate` (apply).
1391
+ // template has no UI but may add one later.
1395
1392
  const installSegment = installed ? '' : `${pm} install && `;
1396
- const dbSegment = isSaas ? `${pm} run db:generate && ${pm} run db:migrate && ` : '';
1393
+ // The saas example queries the users table on its first request (auth), so it
1394
+ // needs a migration authored first: `db:generate` writes it and the
1395
+ // `webjs.dev.before` migrate applies it on `run dev` (Drizzle splits Prisma's
1396
+ // `migrate dev` into generate-then-migrate). The full-stack / api examples do
1397
+ // not query the db on first paint, so they boot with just `run dev`; once you
1398
+ // add a db route, `db:generate` then `run dev` is the loop (dev auto-migrates).
1399
+ const dbSegment = isSaas ? `${pm} run db:generate && ` : '';
1397
1400
  const runCommand = `cd ${name} && ${installSegment}${dbSegment}${pm} run dev`;
1401
+ // Postgres needs a reachable DATABASE_URL before any migrate (sqlite uses a
1402
+ // local file with no .env). Point it at a running database; `dev` / `start`
1403
+ // then apply pending migrations via webjs.*.before.
1404
+ const pgNote = dialect === 'postgres'
1405
+ ? `\nPostgres: copy .env.example to .env and set DATABASE_URL to a running database before \`${pm} run dev\`.\n`
1406
+ : '';
1398
1407
  // Use `npx webjsdev ui ...` here, not `npx webjs ui ...`. The bare
1399
1408
  // `webjs` npm name is owned by an unrelated package; `npx webjs
1400
1409
  // <cmd>` would fetch THAT package instead of ours when run outside
@@ -1410,7 +1419,7 @@ For AI agents, read this before editing scaffolded files:
1410
1419
  Next steps:
1411
1420
  ${runCommand}
1412
1421
  # → http://localhost:8080
1413
-
1422
+ ${pgNote}
1414
1423
  Optional:
1415
1424
  ${uiNote}
1416
1425
  `);
@@ -186,9 +186,10 @@ export async function writeSaasFiles(appDir, opts = {}) {
186
186
  // ALWAYS once the app modules import: auth() only reads a cookie, no DB
187
187
  // query. This is the headline security assertion and it is REAL.
188
188
  // The signup, login, and protected-route flow writes + reads a user, so it
189
- // needs the DB migrated (`npm run db:generate` then `npm run db:migrate`).
190
- // Until the users table exists those flows error, so the suite skips with a
191
- // clear message instead of crashing. After DB setup it runs for real.
189
+ // needs the migrated users table (`npm run db:generate`, then `npm run dev`
190
+ // applies it via webjs.dev.before). Until then those flows error, so the
191
+ // suite probes readiness and skips with a clear message instead of crashing,
192
+ // then runs for real once the db is set up.
192
193
  await mkdir(join(appDir, 'test', 'auth'), { recursive: true });
193
194
  // The generated comments reference `npm run db:*` setup; bun-ify them so a
194
195
  // bun-flavored saas app reads `bun run db:*` (#541; db is Node tooling, so a
@@ -205,12 +206,11 @@ export async function writeSaasFiles(appDir, opts = {}) {
205
206
  "const appDir = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');",
206
207
  "",
207
208
  "// The auth pages + dashboard middleware query the users table via Drizzle.",
208
- "// Until `npm run db:generate` + `npm run db:migrate` have created it, a",
209
- "// request hitting those modules 500s. We detect that at the RESPONSE level",
209
+ "// Until `npm run db:generate` has authored the migration (then `npm run dev`",
210
+ "// applies it via webjs.dev.before, or `npm run db:migrate` directly), a",
211
+ "// request hitting those modules 500s; we detect that at the RESPONSE level",
210
212
  "// (a 5xx on the dashboard) and SKIP with a clear message rather than report",
211
- "// a misleading failure. After you run",
212
- "// npm install && npm run db:generate && npm run db:migrate",
213
- "// every assertion below runs for real.",
213
+ "// a misleading failure. After the db is set up every assertion runs for real.",
214
214
  "process.env.DATABASE_URL ||= 'file:./dev.db';",
215
215
  "process.env.AUTH_SECRET ||= 'test-secret-at-least-32-characters-long!!';",
216
216
  "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjsdev/cli",
3
- "version": "0.10.28",
3
+ "version": "0.10.29",
4
4
  "type": "module",
5
5
  "description": "webjs CLI - dev, start, create, db",
6
6
  "bin": {
@@ -329,7 +329,7 @@ db/
329
329
  columns.server.ts column helpers (dialect-specific; the only file to swap for Postgres)
330
330
  connection.server.ts opens the driver, exports the \`db\` singleton (import \`db\` from here)
331
331
  seed.server.ts optional seed (run via \`webjs db seed\`)
332
- dev.db SQLite file (gitignored); run \`npm run db:migrate\` to create
332
+ dev.db SQLite file (gitignored); created when migrations apply (\`dev\`/\`start\` run \`webjs db migrate\`)
333
333
  migrations/ generated migration SQL (committed)
334
334
  drizzle.config.ts drizzle-kit config (root; SQLite by default, --db postgres to switch)
335
335
  public/ static assets, served at /public/*
@@ -387,13 +387,16 @@ lives in the `webjs` block of `package.json` and runs INSIDE
387
387
 
388
388
  ```jsonc
389
389
  "webjs": {
390
+ "dev": { "before": ["webjs db migrate"] },
390
391
  "start": { "before": ["webjs db migrate"] }
391
392
  }
392
393
  ```
393
394
 
394
- Drizzle has no codegen, so there is no dev `before` step. An app that
395
- adds the Tailwind CLI puts its `--watch` command under
396
- `webjs.dev.parallel` and it runs alongside the server, torn down on exit.
395
+ Both `dev` and `start` apply pending migrations via `webjs db migrate`
396
+ (idempotent, a no-op when the db is current), so a freshly generated
397
+ migration is applied without a manual step. An app that adds the Tailwind
398
+ CLI puts its `--watch` command under `webjs.dev.parallel` and it runs
399
+ alongside the server, torn down on exit.
397
400
  `before` steps run to completion first; a failed `webjs db migrate`
398
401
  aborts the boot with a clear message rather than serving a stale schema.
399
402
 
@@ -457,7 +460,7 @@ Scripts (all wrap `drizzle-kit`):
457
460
  - `npm run db:push`: `webjs db push` (push the schema straight to the dev DB)
458
461
  - `npm run db:studio`: `webjs db studio` (visual DB browser)
459
462
  - `npm run db:seed`: `webjs db seed` (run `db/seed.server.ts`)
460
- - `webjs.start.before` runs `webjs db migrate` inside `webjs start` (idempotent; replaces the old `prestart` hook). No dev `before` step (no codegen).
463
+ - `webjs.dev.before` and `webjs.start.before` both run `webjs db migrate` inside `webjs dev` / `webjs start` (idempotent; replaces the old `prestart` hook), so after you `db:generate` a migration it is applied on the next boot with no manual `db:migrate` step.
461
464
 
462
465
  Always import `db` from `db/connection.server.ts` (the globalThis-cached
463
466
  singleton avoids opening a new connection on every dev-server reload), and
@@ -268,11 +268,12 @@ docs". That is the agent's default behavior in a webjs project.
268
268
 
269
269
  Every webjs app uses **Drizzle + SQLite** for persistence by default. The
270
270
  scaffold ships the `db/` folder (`schema.server.ts`, `columns.server.ts`,
271
- `connection.server.ts`), the `webjs.start.before` step that runs
272
- `webjs db migrate` inside `webjs start` (#550), and the
271
+ `connection.server.ts`), the `webjs.dev.before` + `webjs.start.before` steps
272
+ that run `webjs db migrate` inside `webjs dev` / `webjs start` (#550), and the
273
273
  `npm run db:generate` / `db:migrate` / `db:push` / `db:studio` / `db:seed`
274
- scripts (which route through `webjs db` to drizzle-kit). Drizzle has no
275
- codegen, so there is no dev `before` step.
274
+ scripts (which route through `webjs db` to drizzle-kit). The loop after a
275
+ schema change is `db:generate` (authors the migration) then `webjs dev` (the
276
+ `dev.before` step applies it); `db:generate` is never auto-run on boot.
276
277
 
277
278
  **AI agents: these rules are absolute.**
278
279