@cedarjs/cli 6.0.0-canary.2841 → 6.0.0-canary.2842

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.
@@ -0,0 +1,15 @@
1
+ import { terminalLink } from "termi-link";
2
+ import * as setupDatabasePostgres from "./postgres.js";
3
+ const command = "database <command>";
4
+ const description = "Switch your project's database";
5
+ const builder = (yargs) => yargs.command(setupDatabasePostgres).demandCommand().epilogue(
6
+ `Also see the ${terminalLink(
7
+ "CedarJS CLI Reference",
8
+ "https://cedarjs.com/docs/cli-commands#setup"
9
+ )}`
10
+ );
11
+ export {
12
+ builder,
13
+ command,
14
+ description
15
+ };
@@ -0,0 +1,19 @@
1
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
2
+ const command = "postgres";
3
+ const description = "Switch your project from SQLite to PostgreSQL (schema, dependencies, and database adapter)";
4
+ function builder(yargs) {
5
+ return yargs;
6
+ }
7
+ async function handler() {
8
+ recordTelemetryAttributes({
9
+ command: "setup database postgres"
10
+ });
11
+ const { handler: handler2 } = await import("./postgresHandler.js");
12
+ return handler2();
13
+ }
14
+ export {
15
+ builder,
16
+ command,
17
+ description,
18
+ handler
19
+ };
@@ -0,0 +1,194 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import execa from "execa";
4
+ import { Listr } from "listr2";
5
+ import { colors, getPaths, installPackages } from "@cedarjs/cli-helpers";
6
+ import { prettyPrintCedarCommand } from "@cedarjs/cli-helpers/packageManager";
7
+ import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
8
+ import { resolveFile } from "@cedarjs/project-config";
9
+ import { errorTelemetry } from "@cedarjs/telemetry";
10
+ function checkProjectShape(cedarPaths) {
11
+ const schemaPath = path.join(cedarPaths.api.base, "db", "schema.prisma");
12
+ const dbPath = resolveFile(path.join(cedarPaths.api.lib, "db"));
13
+ if (!fs.existsSync(schemaPath)) {
14
+ return blocked(`Could not find ${schemaPath}.`);
15
+ }
16
+ if (!dbPath) {
17
+ return blocked(`No ${path.join(cedarPaths.api.lib, "db")} file found`);
18
+ }
19
+ const schemaContent = fs.readFileSync(schemaPath, "utf-8");
20
+ const hasPgAdapter = fs.readFileSync(dbPath, "utf-8").includes("PrismaPg");
21
+ if (schemaContent.includes('provider = "postgresql"') && hasPgAdapter) {
22
+ return {
23
+ ok: false,
24
+ alreadyConverted: true,
25
+ message: "This project is already configured for PostgreSQL."
26
+ };
27
+ }
28
+ if (!schemaContent.includes('provider = "sqlite"') || hasPgAdapter) {
29
+ return blocked(
30
+ "This command only converts a project that is still on SQLite, with the default adapter in api/src/lib/db.ts (or db.js) untouched. This project doesn't match that shape (a different provider, or a partial previous conversion). Please switch it over to PostgreSQL manually."
31
+ );
32
+ }
33
+ return { ok: true, dbPath };
34
+ }
35
+ function blocked(message) {
36
+ return { ok: false, alreadyConverted: false, message };
37
+ }
38
+ function getSqliteToPostgresTasks({
39
+ dbPath
40
+ }) {
41
+ const cedarPaths = getPaths();
42
+ const schemaPath = path.join(cedarPaths.api.base, "db", "schema.prisma");
43
+ const rootPkgPath = path.join(cedarPaths.base, "package.json");
44
+ const apiPkgPath = path.join(cedarPaths.api.base, "package.json");
45
+ const dbTsTemplatePath = path.join(
46
+ import.meta.dirname,
47
+ "templates",
48
+ "db.ts.template"
49
+ );
50
+ return [
51
+ {
52
+ title: "Removing SQLite dependencies from api/package.json",
53
+ task: () => {
54
+ const pkg = JSON.parse(fs.readFileSync(apiPkgPath, "utf-8"));
55
+ if (pkg.dependencies) {
56
+ delete pkg.dependencies["better-sqlite3"];
57
+ delete pkg.dependencies["@prisma/adapter-better-sqlite3"];
58
+ }
59
+ fs.writeFileSync(apiPkgPath, JSON.stringify(pkg, null, 2) + "\n");
60
+ }
61
+ },
62
+ {
63
+ title: "Removing better-sqlite3 dependenciesMeta",
64
+ task: () => {
65
+ if (!fs.existsSync(rootPkgPath)) {
66
+ return;
67
+ }
68
+ const pkg = JSON.parse(fs.readFileSync(rootPkgPath, "utf-8"));
69
+ if (pkg.dependenciesMeta?.["better-sqlite3"]) {
70
+ delete pkg.dependenciesMeta["better-sqlite3"];
71
+ if (Object.keys(pkg.dependenciesMeta).length === 0) {
72
+ delete pkg.dependenciesMeta;
73
+ }
74
+ fs.writeFileSync(rootPkgPath, JSON.stringify(pkg, null, 2) + "\n");
75
+ }
76
+ }
77
+ },
78
+ {
79
+ title: "Switching Prisma schema to PostgreSQL",
80
+ task: () => {
81
+ const schemaContent = fs.readFileSync(schemaPath, "utf-8");
82
+ fs.writeFileSync(
83
+ schemaPath,
84
+ schemaContent.replace(
85
+ 'provider = "sqlite"',
86
+ 'provider = "postgresql"'
87
+ )
88
+ );
89
+ }
90
+ },
91
+ {
92
+ title: "Updating database adapter",
93
+ task: () => {
94
+ const pgDbTs = fs.readFileSync(dbTsTemplatePath, "utf-8");
95
+ fs.writeFileSync(dbPath, pgDbTs);
96
+ }
97
+ },
98
+ {
99
+ title: "Adding required api packages...",
100
+ task: async () => {
101
+ await addWorkspacePackages("api", ["@prisma/adapter-pg@7.8.0"], {
102
+ cwd: cedarPaths.api.base
103
+ });
104
+ }
105
+ }
106
+ ];
107
+ }
108
+ function readEnvVar(envContent, name) {
109
+ return envContent.match(new RegExp(`^${name}=(.*)$`, "m"))?.[1] || void 0;
110
+ }
111
+ async function handler() {
112
+ const cedarPaths = getPaths();
113
+ const shape = checkProjectShape(cedarPaths);
114
+ if (!shape.ok) {
115
+ if (shape.alreadyConverted) {
116
+ console.log(colors.note(shape.message));
117
+ return;
118
+ }
119
+ console.error(colors.error(shape.message));
120
+ process.exit(1);
121
+ }
122
+ const envPath = path.join(cedarPaths.base, ".env");
123
+ const envContent = fs.existsSync(envPath) ? fs.readFileSync(envPath, "utf-8") : "";
124
+ const databaseUrl = readEnvVar(envContent, "DATABASE_URL");
125
+ const tasks = new Listr(
126
+ [
127
+ ...getSqliteToPostgresTasks({ dbPath: shape.dbPath }),
128
+ installPackages,
129
+ {
130
+ title: "Running Prisma migrations",
131
+ skip: () => {
132
+ if (!databaseUrl) {
133
+ return `No DATABASE_URL found in \`.env\`. Set it to your PostgreSQL connection string, then run \`${prettyPrintCedarCommand(["prisma", "migrate", "dev"])}\``;
134
+ }
135
+ return false;
136
+ },
137
+ task: () => {
138
+ const result = execa.commandSync(
139
+ "yarn cedar prisma migrate dev --name init-postgres",
140
+ {
141
+ cwd: cedarPaths.base,
142
+ stdio: ["inherit", "inherit", "pipe"],
143
+ reject: false
144
+ }
145
+ );
146
+ if (result.exitCode !== 0) {
147
+ throw new Error(
148
+ "Prisma migration failed:\n\n" + result.stderr + `
149
+
150
+ You can try running it manually:
151
+ ${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-postgres"])}`
152
+ );
153
+ }
154
+ }
155
+ }
156
+ ],
157
+ {
158
+ exitOnError: false,
159
+ collectErrors: "minimal"
160
+ }
161
+ );
162
+ try {
163
+ await tasks.run();
164
+ if (tasks.errors.length > 0) {
165
+ for (const error of tasks.errors) {
166
+ if (isErrorWithMessage(error)) {
167
+ errorTelemetry(process.argv, error.message);
168
+ console.error(colors.error(error.message));
169
+ }
170
+ }
171
+ process.exit(1);
172
+ }
173
+ } catch (e) {
174
+ if (isErrorWithMessage(e)) {
175
+ errorTelemetry(process.argv, e.message);
176
+ console.error(colors.error(e.message));
177
+ }
178
+ if (isErrorWithExitCode(e)) {
179
+ process.exit(e.exitCode);
180
+ }
181
+ process.exit(1);
182
+ }
183
+ }
184
+ function isErrorWithMessage(e) {
185
+ return !!e && typeof e === "object" && "message" in e;
186
+ }
187
+ function isErrorWithExitCode(e) {
188
+ return !!e && typeof e === "object" && "exitCode" in e && typeof e.exitCode === "number";
189
+ }
190
+ export {
191
+ checkProjectShape,
192
+ getSqliteToPostgresTasks,
193
+ handler
194
+ };
@@ -3,213 +3,76 @@ import path from "node:path";
3
3
  import execa from "execa";
4
4
  import { Listr } from "listr2";
5
5
  import { colors, getPaths, installPackages } from "@cedarjs/cli-helpers";
6
- import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
6
+ import { prettyPrintCedarCommand } from "@cedarjs/cli-helpers/packageManager";
7
7
  import { errorTelemetry } from "@cedarjs/telemetry";
8
- const cedarPaths = getPaths();
8
+ import {
9
+ checkProjectShape,
10
+ getSqliteToPostgresTasks
11
+ } from "../database/postgresHandler.js";
9
12
  async function handler({ force }) {
10
- const schemaPath = path.join(cedarPaths.api.base, "db", "schema.prisma");
11
- const dbTsPath = path.join(cedarPaths.api.src, "lib", "db.ts");
12
- const prismaConfigPathCjs = path.join(
13
- cedarPaths.api.base,
14
- "prisma.config.cjs"
15
- );
16
- const prismaConfigPathMts = path.join(
17
- cedarPaths.api.base,
18
- "prisma.config.mts"
19
- );
13
+ const cedarPaths = getPaths();
14
+ const shape = checkProjectShape(cedarPaths);
15
+ if (!shape.ok) {
16
+ if (shape.alreadyConverted) {
17
+ console.log(colors.note(shape.message));
18
+ return;
19
+ }
20
+ console.error(colors.error(shape.message));
21
+ process.exit(1);
22
+ }
20
23
  const envPath = path.join(cedarPaths.base, ".env");
21
- const rootPkgPath = path.join(cedarPaths.base, "package.json");
22
- const apiPkgPath = path.join(cedarPaths.api.base, "package.json");
23
- const dbTsTemplatePath = path.join(
24
- import.meta.dirname,
25
- "templates",
26
- "db.ts.template"
27
- );
28
- let hasDirectDatabaseUrl = false;
24
+ let hasExistingDatabaseUrl = false;
29
25
  if (fs.existsSync(envPath)) {
30
- hasDirectDatabaseUrl = /^DATABASE_URL=/m.test(
26
+ hasExistingDatabaseUrl = /^DATABASE_URL=/m.test(
31
27
  fs.readFileSync(envPath, "utf-8")
32
28
  );
33
29
  }
30
+ const skipProvisioning = hasExistingDatabaseUrl && !force;
34
31
  const notes = [];
32
+ if (skipProvisioning) {
33
+ notes.push(
34
+ colors.note(
35
+ "DATABASE_URL is already set in .env. Use --force to overwrite."
36
+ )
37
+ );
38
+ }
35
39
  const tasks = new Listr(
36
40
  [
41
+ ...getSqliteToPostgresTasks({ dbPath: shape.dbPath }),
37
42
  {
38
- title: "Checking current database configuration",
39
- task: (ctx) => {
40
- const schemaContent = fs.readFileSync(schemaPath, "utf-8");
41
- ctx.schemaContent = schemaContent;
42
- ctx.isSqlite = schemaContent.includes('provider = "sqlite"');
43
- ctx.isPostgres = schemaContent.includes('provider = "postgresql"');
44
- if (fs.existsSync(dbTsPath)) {
45
- ctx.dbTsContent = fs.readFileSync(dbTsPath, "utf-8");
46
- ctx.isNeon = ctx.dbTsContent.includes("PrismaPg");
47
- } else {
48
- ctx.isNeon = false;
49
- }
50
- if (!ctx.isSqlite && !ctx.isPostgres) {
51
- ctx.unsupportedProvider = true;
52
- notes.push(
53
- colors.note(
54
- "setup neon only supports migrating from SQLite to PostgreSQL. Your project uses a different database provider."
55
- )
56
- );
57
- return;
58
- }
59
- if (!ctx.isPostgres) {
60
- ctx.hasSqliteUsageOutsideDb = hasSqliteUsageOutsideDb(
61
- cedarPaths.api.src,
62
- dbTsPath
63
- );
64
- }
65
- if (hasDirectDatabaseUrl && !force) {
66
- ctx.skipWithNote = true;
67
- notes.push(
68
- colors.note(
69
- "DATABASE_URL is already set in .env. Use --force to overwrite."
70
- )
71
- );
72
- }
73
- }
74
- },
75
- {
76
- title: "Removing SQLite dependencies from api/package.json",
77
- skip: (ctx) => {
78
- if (ctx.unsupportedProvider) {
79
- return "Unsupported database provider";
80
- }
81
- if (ctx.isPostgres) {
82
- return "Already configured for PostgreSQL";
83
- }
84
- if (ctx.hasSqliteUsageOutsideDb) {
85
- return "SQLite is in use outside db.ts \u2014 keeping packages";
86
- }
87
- return false;
88
- },
89
- task: () => {
90
- const pkg = JSON.parse(fs.readFileSync(apiPkgPath, "utf-8"));
91
- if (pkg.dependencies) {
92
- delete pkg.dependencies["better-sqlite3"];
93
- delete pkg.dependencies["@prisma/adapter-better-sqlite3"];
94
- }
95
- fs.writeFileSync(apiPkgPath, JSON.stringify(pkg, null, 2) + "\n");
96
- }
97
- },
98
- {
99
- title: "Removing better-sqlite3 dependenciesMeta",
100
- skip: (ctx) => {
101
- if (ctx.unsupportedProvider) {
102
- return "Unsupported database provider";
103
- }
104
- if (ctx.isPostgres) {
105
- return "Already configured for PostgreSQL";
106
- }
107
- if (ctx.hasSqliteUsageOutsideDb) {
108
- return "SQLite is in use outside db.ts so we're keeping it installed";
109
- }
110
- return false;
111
- },
112
- task: () => {
113
- if (!fs.existsSync(rootPkgPath)) {
114
- return;
115
- }
116
- const pkg = JSON.parse(fs.readFileSync(rootPkgPath, "utf-8"));
117
- if (pkg.dependenciesMeta?.["better-sqlite3"]) {
118
- delete pkg.dependenciesMeta["better-sqlite3"];
119
- if (Object.keys(pkg.dependenciesMeta).length === 0) {
120
- delete pkg.dependenciesMeta;
121
- }
122
- fs.writeFileSync(rootPkgPath, JSON.stringify(pkg, null, 2) + "\n");
123
- }
124
- }
125
- },
126
- {
127
- title: "Switching Prisma schema to PostgreSQL",
128
- skip: (ctx) => {
129
- if (ctx.unsupportedProvider) {
130
- return "Unsupported database provider";
131
- }
132
- if (ctx.isPostgres) {
133
- return "Schema is already configured for PostgreSQL";
134
- }
135
- return false;
136
- },
137
- task: (ctx) => {
138
- const updated = ctx.schemaContent.replace(
139
- 'provider = "sqlite"',
140
- 'provider = "postgresql"'
43
+ title: "Setting DIRECT_DATABASE_URL in Prisma config",
44
+ skip: () => skipProvisioning,
45
+ task: (ctx, task) => {
46
+ const prismaConfigPathCjs = path.join(
47
+ cedarPaths.api.base,
48
+ "prisma.config.cjs"
49
+ );
50
+ const prismaConfigPathMts = path.join(
51
+ cedarPaths.api.base,
52
+ "prisma.config.mts"
141
53
  );
142
- fs.writeFileSync(schemaPath, updated);
143
- }
144
- },
145
- {
146
- title: "Updating database adapter",
147
- skip: (ctx) => {
148
- if (ctx.unsupportedProvider) {
149
- return "Unsupported database provider";
150
- }
151
- if (ctx.isNeon) {
152
- return "Database adapter is already configured for Neon (PrismaPg)";
153
- }
154
- if (ctx.skipWithNote) {
155
- return "DATABASE_URL already configured \u2014 skipping adapter update";
156
- }
157
- return false;
158
- },
159
- task: () => {
160
- const neonDbTs = fs.readFileSync(dbTsTemplatePath, "utf-8");
161
- fs.writeFileSync(dbTsPath, neonDbTs);
162
- }
163
- },
164
- {
165
- title: "Updating Prisma config",
166
- skip: (ctx) => {
167
- if (ctx.unsupportedProvider) {
168
- return "Unsupported database provider";
169
- }
170
- if (ctx.isNeon) {
171
- return "Prisma config is already configured for Neon";
172
- }
173
- if (ctx.skipWithNote) {
174
- return "DATABASE_URL already configured \u2014 skipping config update";
175
- }
176
- return false;
177
- },
178
- task: () => {
179
- if (!fs.existsSync(prismaConfigPathCjs) && !fs.existsSync(prismaConfigPathMts)) {
180
- throw new Error(
181
- "No Prisma config file found. Expected prisma.config.cjs or prisma.config.mts in the api directory."
182
- );
183
- }
184
54
  const configPath = fs.existsSync(prismaConfigPathCjs) ? prismaConfigPathCjs : prismaConfigPathMts;
185
55
  const configContent = fs.readFileSync(configPath, "utf-8");
186
- const updated = configContent.replace(
187
- /env\(["']DATABASE_URL["']\)/,
188
- "env('DIRECT_DATABASE_URL')"
56
+ const datasourceUrlRegex = /(\burl\s*:\s*)env\(["'][^"']*?["']\)/;
57
+ if (!datasourceUrlRegex.test(configContent)) {
58
+ ctx.directDatabaseUrlNotSet = true;
59
+ task.skip(
60
+ "Could not set DIRECT_DATABASE_URL. Please manually set datasource.url in " + configPath
61
+ );
62
+ return;
63
+ }
64
+ fs.writeFileSync(
65
+ configPath,
66
+ configContent.replace(
67
+ datasourceUrlRegex,
68
+ "$1env('DIRECT_DATABASE_URL')"
69
+ )
189
70
  );
190
- fs.writeFileSync(configPath, updated);
191
- }
192
- },
193
- {
194
- title: "Adding required api packages...",
195
- skip: (ctx) => ctx.unsupportedProvider,
196
- task: async () => {
197
- await addWorkspacePackages("api", ["@prisma/adapter-pg@7.8.0"], {
198
- cwd: cedarPaths.api.base
199
- });
200
71
  }
201
72
  },
202
73
  {
203
74
  title: "Provisioning Neon database",
204
- skip: (ctx) => {
205
- if (ctx.unsupportedProvider) {
206
- return true;
207
- }
208
- if (hasDirectDatabaseUrl && !force) {
209
- return true;
210
- }
211
- return false;
212
- },
75
+ skip: () => skipProvisioning,
213
76
  task: async (ctx) => {
214
77
  const res = await fetch("https://neon.new/api/v1/database", {
215
78
  method: "POST",
@@ -239,20 +102,52 @@ async function handler({ force }) {
239
102
  ctx.neonClaimExpiry = new Date(data.expires_at).toUTCString();
240
103
  }
241
104
  },
105
+ installPackages,
242
106
  {
243
- title: "Writing database connection to .env",
107
+ title: "Running Prisma migrations",
244
108
  skip: (ctx) => {
245
- if (ctx.unsupportedProvider) {
109
+ if (skipProvisioning) {
246
110
  return true;
247
111
  }
248
- if (hasDirectDatabaseUrl && !force) {
249
- return true;
250
- }
251
- if (!ctx.databaseUrl) {
252
- return "No database URL to write (Neon provisioning skipped)";
112
+ if (ctx.directDatabaseUrlNotSet) {
113
+ return `Skipping migrations \u2014 could not confirm prisma.config is reading DIRECT_DATABASE_URL, so migrations could target the wrong database. Fix datasource.url, then run \`${prettyPrintCedarCommand(["prisma", "migrate", "dev"])}\` manually.`;
253
114
  }
254
115
  return false;
255
116
  },
117
+ task: (ctx) => {
118
+ const result = execa.commandSync(
119
+ "yarn cedar prisma migrate dev --name init-neon",
120
+ {
121
+ cwd: cedarPaths.base,
122
+ stdio: ["inherit", "inherit", "pipe"],
123
+ reject: false,
124
+ env: {
125
+ ...process.env,
126
+ DIRECT_DATABASE_URL: ctx.databaseUrlDirect
127
+ }
128
+ }
129
+ );
130
+ if (result.exitCode !== 0) {
131
+ throw new Error(
132
+ "Prisma migration failed:\n\n" + result.stderr + `
133
+
134
+ You can try running it manually:
135
+ ${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}`
136
+ );
137
+ }
138
+ }
139
+ },
140
+ {
141
+ title: "Writing database connection to .env",
142
+ // Deliberately runs after migrations, not before — with
143
+ // `exitOnError: true`, a migration failure stops the list here and
144
+ // this task never runs. That means a project whose migrations
145
+ // failed never has DATABASE_URL/DIRECT_DATABASE_URL written to
146
+ // .env, so it's never left pointing at a Neon database it doesn't
147
+ // know it needs to claim. Provisioning that database anyway (and
148
+ // letting it expire unclaimed) is fine — it's exactly as if the
149
+ // command were re-run from scratch, which is safe.
150
+ skip: () => skipProvisioning,
256
151
  task: (ctx) => {
257
152
  let envContent = "";
258
153
  if (fs.existsSync(envPath)) {
@@ -275,49 +170,10 @@ async function handler({ force }) {
275
170
  fs.writeFileSync(envPath, envContent);
276
171
  }
277
172
  },
278
- installPackages,
279
- {
280
- title: "Running Prisma migrations",
281
- skip: (ctx) => {
282
- if (ctx.unsupportedProvider) {
283
- return true;
284
- }
285
- if (ctx.skipWithNote) {
286
- return "DATABASE_URL already configured \u2014 skipping migration";
287
- }
288
- if (!ctx.databaseUrl) {
289
- return "No database provisioned \u2014 skipping migration";
290
- }
291
- return false;
292
- },
293
- task: (ctx) => {
294
- const result = execa.commandSync(
295
- "yarn cedar prisma migrate dev --name init-neon",
296
- {
297
- cwd: cedarPaths.base,
298
- stdio: ["inherit", "inherit", "pipe"],
299
- reject: false,
300
- env: {
301
- ...process.env,
302
- DIRECT_DATABASE_URL: ctx.databaseUrlDirect
303
- }
304
- }
305
- );
306
- if (result.exitCode !== 0) {
307
- throw new Error(
308
- "Prisma migration failed:\n\n" + result.stderr + "\n\nYou can try running it manually:\n yarn cedar prisma migrate dev --name init-neon"
309
- );
310
- }
311
- }
312
- },
313
173
  {
314
174
  title: "One more thing...",
315
175
  task: (ctx, task) => {
316
- if (ctx.unsupportedProvider) {
317
- task.output = "Skipped \u2014 unsupported database provider";
318
- return;
319
- }
320
- if (ctx.skipWithNote) {
176
+ if (skipProvisioning) {
321
177
  task.output = "Skipped \u2014 DATABASE_URL already configured";
322
178
  return;
323
179
  }
@@ -336,7 +192,11 @@ async function handler({ force }) {
336
192
  }
337
193
  ],
338
194
  {
339
- exitOnError: false
195
+ // Migrations run before .env is written (see above) specifically so
196
+ // that a failure here — the one step that shouldn't be allowed to
197
+ // continue — stops the whole list via the default exitOnError
198
+ // behavior, rather than needing every later task to know to skip.
199
+ exitOnError: true
340
200
  }
341
201
  );
342
202
  try {
@@ -362,24 +222,6 @@ function isErrorWithMessage(e) {
362
222
  function isErrorWithExitCode(e) {
363
223
  return !!e && typeof e === "object" && "exitCode" in e && typeof e.exitCode === "number";
364
224
  }
365
- function hasSqliteUsageOutsideDb(srcPath, dbTsPath) {
366
- const sqlitePattern = /better-sqlite3|@prisma\/adapter-better-sqlite3/;
367
- const files = fs.globSync("**/*.{ts,tsx,js,jsx}", { cwd: srcPath });
368
- for (const file of files) {
369
- const fullPath = path.join(srcPath, file);
370
- if (fullPath === dbTsPath) {
371
- continue;
372
- }
373
- try {
374
- const content = fs.readFileSync(fullPath, "utf-8");
375
- if (sqlitePattern.test(content)) {
376
- return true;
377
- }
378
- } catch {
379
- }
380
- }
381
- return false;
382
- }
383
225
  export {
384
226
  handler
385
227
  };
@@ -2,6 +2,7 @@ import { terminalLink } from "termi-link";
2
2
  import { detectCedarVersion } from "../middleware/detectProjectCedarVersion.js";
3
3
  import * as setupAuth from "./setup/auth/auth.js";
4
4
  import * as setupCache from "./setup/cache/cache.js";
5
+ import * as setupDatabase from "./setup/database/database.js";
5
6
  import * as setupDeploy from "./setup/deploy/deploy.js";
6
7
  import * as setupDocker from "./setup/docker/docker.js";
7
8
  import * as setupGenerator from "./setup/generator/generator.js";
@@ -20,7 +21,7 @@ import * as setupUi from "./setup/ui/ui.js";
20
21
  import * as setupUploads from "./setup/uploads/uploads.js";
21
22
  const command = "setup <command>";
22
23
  const description = "Initialize project config and install packages";
23
- const builder = (yargs) => yargs.command(setupAuth).command(setupCache).command(setupDeploy).command(setupDocker).command(setupGenerator).command(setupGraphql).command(setupI18n).command(setupJobs).command(setupMailer).command(setupMiddleware).command(setupMonitoring).command(setupNeon).command(setupPackage).command(setupRealtime).command(setupServerFile).command(setupTsconfig).command(setupUi).command(setupUploads).demandCommand().middleware(detectCedarVersion).epilogue(
24
+ const builder = (yargs) => yargs.command(setupAuth).command(setupCache).command(setupDatabase).command(setupDeploy).command(setupDocker).command(setupGenerator).command(setupGraphql).command(setupI18n).command(setupJobs).command(setupMailer).command(setupMiddleware).command(setupMonitoring).command(setupNeon).command(setupPackage).command(setupRealtime).command(setupServerFile).command(setupTsconfig).command(setupUi).command(setupUploads).demandCommand().middleware(detectCedarVersion).epilogue(
24
25
  `Also see the ${terminalLink(
25
26
  "CedarJS CLI Reference",
26
27
  "https://cedarjs.com/docs/cli-commands#setup"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "6.0.0-canary.2841",
3
+ "version": "6.0.0-canary.2842",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,17 +36,17 @@
36
36
  "@babel/preset-typescript": "7.29.7",
37
37
  "@babel/traverse": "7.29.7",
38
38
  "@babel/types": "7.29.7",
39
- "@cedarjs/api-server": "6.0.0-canary.2841",
40
- "@cedarjs/babel-config": "6.0.0-canary.2841",
41
- "@cedarjs/cli-helpers": "6.0.0-canary.2841",
42
- "@cedarjs/internal": "6.0.0-canary.2841",
43
- "@cedarjs/prerender": "6.0.0-canary.2841",
44
- "@cedarjs/project-config": "6.0.0-canary.2841",
45
- "@cedarjs/structure": "6.0.0-canary.2841",
46
- "@cedarjs/telemetry": "6.0.0-canary.2841",
47
- "@cedarjs/utils": "6.0.0-canary.2841",
48
- "@cedarjs/vite": "6.0.0-canary.2841",
49
- "@cedarjs/web-server": "6.0.0-canary.2841",
39
+ "@cedarjs/api-server": "6.0.0-canary.2842",
40
+ "@cedarjs/babel-config": "6.0.0-canary.2842",
41
+ "@cedarjs/cli-helpers": "6.0.0-canary.2842",
42
+ "@cedarjs/internal": "6.0.0-canary.2842",
43
+ "@cedarjs/prerender": "6.0.0-canary.2842",
44
+ "@cedarjs/project-config": "6.0.0-canary.2842",
45
+ "@cedarjs/structure": "6.0.0-canary.2842",
46
+ "@cedarjs/telemetry": "6.0.0-canary.2842",
47
+ "@cedarjs/utils": "6.0.0-canary.2842",
48
+ "@cedarjs/vite": "6.0.0-canary.2842",
49
+ "@cedarjs/web-server": "6.0.0-canary.2842",
50
50
  "@listr2/prompt-adapter-enquirer": "4.3.0",
51
51
  "@opentelemetry/api": "1.9.1",
52
52
  "@opentelemetry/core": "1.30.1",
@@ -94,7 +94,7 @@
94
94
  "yargs": "17.7.3"
95
95
  },
96
96
  "devDependencies": {
97
- "@cedarjs/framework-tools": "6.0.0-canary.2841",
97
+ "@cedarjs/framework-tools": "6.0.0-canary.2842",
98
98
  "@prisma/dmmf": "7.8.0",
99
99
  "@types/archiver": "^7.0.0",
100
100
  "memfs": "4.64.0",