@cedarjs/cli 5.0.7-next.338 → 5.0.7
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 +10 -7
- package/dist/cfw.js +1 -3
- package/dist/commands/build/buildHandler.js +6 -14
- package/dist/commands/console.js +3 -5
- package/dist/commands/consoleHandler.js +75 -0
- package/dist/commands/dev/devHandler.js +4 -71
- package/dist/commands/dev.js +4 -7
- package/dist/commands/execHandler.js +0 -12
- package/dist/commands/experimental/setupOpentelemetryHandler.js +1 -1
- package/dist/commands/generate/helpers.js +0 -16
- package/dist/commands/generate/job/jobHandler.js +7 -5
- package/dist/commands/generate/package/filesTask.js +0 -12
- package/dist/commands/generate/package/packageHandler.js +11 -18
- package/dist/commands/generate/package/templates/test.ts.template +2 -2
- package/dist/commands/generate/scaffold/scaffoldHandler.js +19 -138
- package/dist/commands/generate/script/templates/script.ts.template +4 -9
- package/dist/commands/generate/sdl/sdlHandler.js +44 -113
- package/dist/commands/generate/sdl/templates/sdl.js.template +1 -2
- package/dist/commands/generate/sdl/templates/sdl.ts.template +1 -2
- package/dist/commands/generate/service/serviceHandler.js +6 -17
- package/dist/commands/generate/yargsHandlerHelpers.js +6 -0
- package/dist/commands/lint.js +61 -1
- package/dist/commands/prismaHandler.js +7 -4
- package/dist/commands/serve.js +24 -23
- package/dist/commands/serveBothHandler.js +4 -4
- package/dist/commands/setup/auth/auth.js +1 -1
- package/dist/commands/setup/deploy/helpers/index.js +39 -9
- package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +5 -17
- package/dist/commands/setup/deploy/providers/renderHandler.js +21 -27
- package/dist/commands/setup/deploy/templates/render.js +16 -29
- package/dist/commands/setup/docker/templates/Dockerfile.yarn +5 -2
- package/dist/commands/setup/docker/templates/docker-compose.dev.yml +1 -1
- package/dist/commands/setup/docker/templates/docker-compose.prod.yml +5 -2
- package/dist/commands/setup/graphql/features/fragments/appGqlConfigTransform.js +3 -6
- package/dist/commands/setup/monitoring/sentry/sentryHandler.js +4 -9
- package/dist/commands/setup/neon/neon.js +3 -13
- package/dist/commands/setup/neon/neonHandler.js +258 -141
- package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +1 -3
- package/dist/commands/setup/ui/libraries/mantineHandler.js +1 -3
- package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +1 -0
- package/dist/commands/setup/uploads/uploadsHandler.js +5 -6
- package/dist/commands/setup.js +1 -2
- package/dist/commands/test/testHandlerEsm.js +1 -1
- package/dist/commands/upgrade/preUpgradeScripts.js +9 -9
- package/dist/commands/upgrade/upgradeHandler.js +32 -42
- package/dist/lib/background.js +1 -20
- package/dist/lib/exec.js +8 -5
- package/dist/lib/extendFile.js +1 -1
- package/dist/lib/index.js +6 -22
- package/dist/lib/updateCheck.js +6 -34
- package/dist/telemetry/resource.js +8 -3
- package/package.json +27 -26
- package/dist/commands/generate/package/templates/vitest.config.ts.template +0 -9
- package/dist/commands/generate/sdl/stubFiles.js +0 -132
- package/dist/commands/setup/database/database.js +0 -15
- package/dist/commands/setup/database/postgres.js +0 -19
- package/dist/commands/setup/database/postgresHandler.js +0 -194
- /package/dist/commands/setup/{database → neon}/templates/db.ts.template +0 -0
|
@@ -7,25 +7,15 @@ function builder(yargs) {
|
|
|
7
7
|
default: false,
|
|
8
8
|
description: "Overwrite existing DATABASE_URL in .env",
|
|
9
9
|
type: "boolean"
|
|
10
|
-
}).option("migrations", {
|
|
11
|
-
description: "Run Prisma migrations after setup. Omit to be prompted. Use --no-migrations to skip.",
|
|
12
|
-
type: "boolean"
|
|
13
|
-
}).option("verbose", {
|
|
14
|
-
alias: "v",
|
|
15
|
-
default: false,
|
|
16
|
-
description: "Show full output from migration commands (stderr visible in terminal)",
|
|
17
|
-
type: "boolean"
|
|
18
10
|
});
|
|
19
11
|
}
|
|
20
|
-
async function handler({ force
|
|
12
|
+
async function handler({ force }) {
|
|
21
13
|
recordTelemetryAttributes({
|
|
22
14
|
command: "setup neon",
|
|
23
|
-
force
|
|
24
|
-
migrations,
|
|
25
|
-
verbose
|
|
15
|
+
force
|
|
26
16
|
});
|
|
27
17
|
const { handler: handler2 } = await import("./neonHandler.js");
|
|
28
|
-
return handler2({ force
|
|
18
|
+
return handler2({ force });
|
|
29
19
|
}
|
|
30
20
|
export {
|
|
31
21
|
builder,
|
|
@@ -2,116 +2,214 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
|
-
import prompts from "prompts";
|
|
6
5
|
import { colors, getPaths, installPackages } from "@cedarjs/cli-helpers";
|
|
7
|
-
import {
|
|
6
|
+
import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
|
|
8
7
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const url = new URL(value);
|
|
24
|
-
return (url.protocol === "postgres:" || url.protocol === "postgresql:") && !!url.hostname;
|
|
25
|
-
} catch {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async function handler({ force, migrations, verbose }) {
|
|
30
|
-
const cedarPaths = getPaths();
|
|
31
|
-
const shape = checkProjectShape(cedarPaths);
|
|
32
|
-
if (!shape.ok) {
|
|
33
|
-
if (shape.alreadyConverted) {
|
|
34
|
-
console.log(colors.note(shape.message));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
console.error(colors.error(shape.message));
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
8
|
+
const cedarPaths = getPaths();
|
|
9
|
+
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
|
+
);
|
|
40
20
|
const envPath = path.join(cedarPaths.base, ".env");
|
|
41
|
-
|
|
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;
|
|
42
29
|
if (fs.existsSync(envPath)) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
const skipProvisioning = hasExistingDatabaseUrl && !force;
|
|
47
|
-
const notes = [];
|
|
48
|
-
if (skipProvisioning) {
|
|
49
|
-
notes.push(
|
|
50
|
-
colors.note(
|
|
51
|
-
"DATABASE_URL is already set in .env. Use --force to overwrite."
|
|
52
|
-
)
|
|
30
|
+
hasDirectDatabaseUrl = /^DATABASE_URL=/m.test(
|
|
31
|
+
fs.readFileSync(envPath, "utf-8")
|
|
53
32
|
);
|
|
54
33
|
}
|
|
55
|
-
|
|
56
|
-
if (!skipProvisioning && runMigrations === void 0) {
|
|
57
|
-
if (!process.stdin.isTTY) {
|
|
58
|
-
const error = new Error(
|
|
59
|
-
"Cannot prompt for confirmation in a non-interactive terminal. Please pass --migrations or --no-migrations explicitly."
|
|
60
|
-
);
|
|
61
|
-
errorTelemetry(process.argv, error.message);
|
|
62
|
-
console.error(colors.error(error.message));
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
const response = await prompts({
|
|
66
|
-
type: "toggle",
|
|
67
|
-
name: "runMigrations",
|
|
68
|
-
message: "Run Prisma migrations now?",
|
|
69
|
-
initial: true,
|
|
70
|
-
active: "Yes",
|
|
71
|
-
inactive: "No"
|
|
72
|
-
});
|
|
73
|
-
if (response.runMigrations === void 0) {
|
|
74
|
-
process.exit(0);
|
|
75
|
-
}
|
|
76
|
-
runMigrations = response.runMigrations;
|
|
77
|
-
}
|
|
34
|
+
const notes = [];
|
|
78
35
|
const tasks = new Listr(
|
|
79
36
|
[
|
|
80
|
-
...getSqliteToPostgresTasks({ dbPath: shape.dbPath }),
|
|
81
37
|
{
|
|
82
|
-
title: "
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
+
)
|
|
100
56
|
);
|
|
101
57
|
return;
|
|
102
58
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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"'
|
|
141
|
+
);
|
|
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
|
+
const configPath = fs.existsSync(prismaConfigPathCjs) ? prismaConfigPathCjs : prismaConfigPathMts;
|
|
185
|
+
const configContent = fs.readFileSync(configPath, "utf-8");
|
|
186
|
+
const updated = configContent.replace(
|
|
187
|
+
/env\(["']DATABASE_URL["']\)/,
|
|
188
|
+
"env('DIRECT_DATABASE_URL')"
|
|
109
189
|
);
|
|
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
|
+
});
|
|
110
200
|
}
|
|
111
201
|
},
|
|
112
202
|
{
|
|
113
203
|
title: "Provisioning Neon database",
|
|
114
|
-
skip: () =>
|
|
204
|
+
skip: (ctx) => {
|
|
205
|
+
if (ctx.unsupportedProvider) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (hasDirectDatabaseUrl && !force) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
212
|
+
},
|
|
115
213
|
task: async (ctx) => {
|
|
116
214
|
const res = await fetch("https://neon.new/api/v1/database", {
|
|
117
215
|
method: "POST",
|
|
@@ -141,18 +239,54 @@ async function handler({ force, migrations, verbose }) {
|
|
|
141
239
|
ctx.neonClaimExpiry = new Date(data.expires_at).toUTCString();
|
|
142
240
|
}
|
|
143
241
|
},
|
|
242
|
+
{
|
|
243
|
+
title: "Writing database connection to .env",
|
|
244
|
+
skip: (ctx) => {
|
|
245
|
+
if (ctx.unsupportedProvider) {
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
if (hasDirectDatabaseUrl && !force) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
if (!ctx.databaseUrl) {
|
|
252
|
+
return "No database URL to write (Neon provisioning skipped)";
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
255
|
+
},
|
|
256
|
+
task: (ctx) => {
|
|
257
|
+
let envContent = "";
|
|
258
|
+
if (fs.existsSync(envPath)) {
|
|
259
|
+
envContent = fs.readFileSync(envPath, "utf-8");
|
|
260
|
+
if (force) {
|
|
261
|
+
const lines = envContent.split("\n");
|
|
262
|
+
const filtered = lines.filter(
|
|
263
|
+
(line) => !line.startsWith("DATABASE_URL=") && !line.startsWith("DIRECT_DATABASE_URL=")
|
|
264
|
+
);
|
|
265
|
+
envContent = filtered.join("\n").trimEnd();
|
|
266
|
+
}
|
|
267
|
+
if (envContent && !envContent.endsWith("\n")) {
|
|
268
|
+
envContent += "\n";
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
envContent += `DATABASE_URL=${ctx.databaseUrl}
|
|
272
|
+
`;
|
|
273
|
+
envContent += `DIRECT_DATABASE_URL=${ctx.databaseUrlDirect}
|
|
274
|
+
`;
|
|
275
|
+
fs.writeFileSync(envPath, envContent);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
144
278
|
installPackages,
|
|
145
279
|
{
|
|
146
280
|
title: "Running Prisma migrations",
|
|
147
281
|
skip: (ctx) => {
|
|
148
|
-
if (
|
|
282
|
+
if (ctx.unsupportedProvider) {
|
|
149
283
|
return true;
|
|
150
284
|
}
|
|
151
|
-
if (
|
|
152
|
-
return
|
|
285
|
+
if (ctx.skipWithNote) {
|
|
286
|
+
return "DATABASE_URL already configured \u2014 skipping migration";
|
|
153
287
|
}
|
|
154
|
-
if (ctx.
|
|
155
|
-
return
|
|
288
|
+
if (!ctx.databaseUrl) {
|
|
289
|
+
return "No database provisioned \u2014 skipping migration";
|
|
156
290
|
}
|
|
157
291
|
return false;
|
|
158
292
|
},
|
|
@@ -161,7 +295,7 @@ async function handler({ force, migrations, verbose }) {
|
|
|
161
295
|
"yarn cedar prisma migrate dev --name init-neon",
|
|
162
296
|
{
|
|
163
297
|
cwd: cedarPaths.base,
|
|
164
|
-
stdio:
|
|
298
|
+
stdio: ["inherit", "inherit", "pipe"],
|
|
165
299
|
reject: false,
|
|
166
300
|
env: {
|
|
167
301
|
...process.env,
|
|
@@ -171,50 +305,19 @@ async function handler({ force, migrations, verbose }) {
|
|
|
171
305
|
);
|
|
172
306
|
if (result.exitCode !== 0) {
|
|
173
307
|
throw new Error(
|
|
174
|
-
|
|
175
|
-
${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}` : "Prisma migration failed:\n\n" + result.stderr + `
|
|
176
|
-
|
|
177
|
-
You can try running it manually:
|
|
178
|
-
${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}`
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
title: "Writing database connection to .env",
|
|
185
|
-
// Deliberately runs after migrations, not before — with
|
|
186
|
-
// `exitOnError: true`, a migration failure stops the list here and
|
|
187
|
-
// this task never runs. That means a project whose migrations
|
|
188
|
-
// failed never has DATABASE_URL/DIRECT_DATABASE_URL written to
|
|
189
|
-
// .env, so it's never left pointing at a Neon database it doesn't
|
|
190
|
-
// know it needs to claim. Provisioning that database anyway (and
|
|
191
|
-
// letting it expire unclaimed) is fine — it's exactly as if the
|
|
192
|
-
// command were re-run from scratch, which is safe.
|
|
193
|
-
skip: () => skipProvisioning,
|
|
194
|
-
task: (ctx) => {
|
|
195
|
-
let envContent = "";
|
|
196
|
-
if (fs.existsSync(envPath)) {
|
|
197
|
-
envContent = fs.readFileSync(envPath, "utf-8");
|
|
198
|
-
const lines = envContent.split("\n");
|
|
199
|
-
const filtered = lines.filter(
|
|
200
|
-
(line) => !line.startsWith("DATABASE_URL=") && !line.startsWith("DIRECT_DATABASE_URL=")
|
|
308
|
+
"Prisma migration failed:\n\n" + result.stderr + "\n\nYou can try running it manually:\n yarn cedar prisma migrate dev --name init-neon"
|
|
201
309
|
);
|
|
202
|
-
envContent = filtered.join("\n").trimEnd();
|
|
203
|
-
if (envContent && !envContent.endsWith("\n")) {
|
|
204
|
-
envContent += "\n";
|
|
205
|
-
}
|
|
206
310
|
}
|
|
207
|
-
envContent += `DATABASE_URL=${ctx.databaseUrl}
|
|
208
|
-
`;
|
|
209
|
-
envContent += `DIRECT_DATABASE_URL=${ctx.databaseUrlDirect}
|
|
210
|
-
`;
|
|
211
|
-
fs.writeFileSync(envPath, envContent);
|
|
212
311
|
}
|
|
213
312
|
},
|
|
214
313
|
{
|
|
215
314
|
title: "One more thing...",
|
|
216
315
|
task: (ctx, task) => {
|
|
217
|
-
if (
|
|
316
|
+
if (ctx.unsupportedProvider) {
|
|
317
|
+
task.output = "Skipped \u2014 unsupported database provider";
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (ctx.skipWithNote) {
|
|
218
321
|
task.output = "Skipped \u2014 DATABASE_URL already configured";
|
|
219
322
|
return;
|
|
220
323
|
}
|
|
@@ -233,11 +336,7 @@ You can try running it manually:
|
|
|
233
336
|
}
|
|
234
337
|
],
|
|
235
338
|
{
|
|
236
|
-
|
|
237
|
-
// that a failure here — the one step that shouldn't be allowed to
|
|
238
|
-
// continue — stops the whole list via the default exitOnError
|
|
239
|
-
// behavior, rather than needing every later task to know to skip.
|
|
240
|
-
exitOnError: true
|
|
339
|
+
exitOnError: false
|
|
241
340
|
}
|
|
242
341
|
);
|
|
243
342
|
try {
|
|
@@ -263,6 +362,24 @@ function isErrorWithMessage(e) {
|
|
|
263
362
|
function isErrorWithExitCode(e) {
|
|
264
363
|
return !!e && typeof e === "object" && "exitCode" in e && typeof e.exitCode === "number";
|
|
265
364
|
}
|
|
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
|
+
}
|
|
266
383
|
export {
|
|
267
384
|
handler
|
|
268
385
|
};
|
|
@@ -54,9 +54,7 @@ async function handler({
|
|
|
54
54
|
insertComponent: {
|
|
55
55
|
name: "ChakraProvider",
|
|
56
56
|
props: { theme: "extendedTheme" },
|
|
57
|
-
|
|
58
|
-
// deprecated RedwoodProvider) may still use RedwoodProvider.
|
|
59
|
-
within: "CedarProvider|RedwoodProvider",
|
|
57
|
+
within: "RedwoodProvider",
|
|
60
58
|
insertBefore: "<ColorModeScript />"
|
|
61
59
|
},
|
|
62
60
|
imports: [
|
|
@@ -77,9 +77,7 @@ async function handler({
|
|
|
77
77
|
insertComponent: {
|
|
78
78
|
name: "MantineProvider",
|
|
79
79
|
props: { theme: "theme" },
|
|
80
|
-
|
|
81
|
-
// deprecated RedwoodProvider) may still use RedwoodProvider.
|
|
82
|
-
within: "CedarProvider|RedwoodProvider"
|
|
80
|
+
within: "RedwoodProvider"
|
|
83
81
|
},
|
|
84
82
|
imports: [
|
|
85
83
|
"import { MantineProvider } from '@mantine/core'",
|
|
@@ -15,10 +15,9 @@ import { isTypeScriptProject } from "../../../lib/project.js";
|
|
|
15
15
|
import { runTransform } from "../../../lib/runTransform.js";
|
|
16
16
|
const handler = async ({ force }) => {
|
|
17
17
|
const projectIsTypescript = isTypeScriptProject();
|
|
18
|
-
const
|
|
19
|
-
with: { type: "json" }
|
|
20
|
-
});
|
|
21
|
-
const cedarVersion = packageJson.default.devDependencies["@cedarjs/core"] ?? "latest";
|
|
18
|
+
const redwoodVersion = await import(path.join(getPaths().base, "package.json"), {
|
|
19
|
+
with: { type: "json " }
|
|
20
|
+
}).default.devDependencies["@cedarjs/core"] ?? "latest";
|
|
22
21
|
const tasks = new Listr(
|
|
23
22
|
[
|
|
24
23
|
{
|
|
@@ -66,7 +65,7 @@ const handler = async ({ force }) => {
|
|
|
66
65
|
}
|
|
67
66
|
},
|
|
68
67
|
{
|
|
69
|
-
...addApiPackages([`@cedarjs/storage@${
|
|
68
|
+
...addApiPackages([`@cedarjs/storage@${redwoodVersion}`]),
|
|
70
69
|
title: "Adding dependencies to your api side..."
|
|
71
70
|
},
|
|
72
71
|
{
|
|
@@ -83,7 +82,7 @@ const handler = async ({ force }) => {
|
|
|
83
82
|
if (transformResult.error) {
|
|
84
83
|
if (transformResult.error === "RW_CODEMOD_ERR_OLD_FORMAT") {
|
|
85
84
|
throw new Error(
|
|
86
|
-
"It looks like your src/lib/db file is using the old format. Please update it as per the v8 upgrade guide: https://cedarjs.com/docs/
|
|
85
|
+
"It looks like your src/lib/db file is using the old format. Please update it as per the v8 upgrade guide: https://cedarjs.com/docs/upgrade-guides/v8#database-file-structure-change. And run again. \n\nYou can also manually modify your api/src/lib/db to include the prisma extension: https://cedarjs.com/docs/uploads/#attaching-the-prisma-extension"
|
|
87
86
|
);
|
|
88
87
|
}
|
|
89
88
|
throw new Error(
|
package/dist/commands/setup.js
CHANGED
|
@@ -2,7 +2,6 @@ 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";
|
|
6
5
|
import * as setupDeploy from "./setup/deploy/deploy.js";
|
|
7
6
|
import * as setupDocker from "./setup/docker/docker.js";
|
|
8
7
|
import * as setupGenerator from "./setup/generator/generator.js";
|
|
@@ -21,7 +20,7 @@ import * as setupUi from "./setup/ui/ui.js";
|
|
|
21
20
|
import * as setupUploads from "./setup/uploads/uploads.js";
|
|
22
21
|
const command = "setup <command>";
|
|
23
22
|
const description = "Initialize project config and install packages";
|
|
24
|
-
const builder = (yargs) => yargs.command(setupAuth).command(setupCache).command(
|
|
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(
|
|
25
24
|
`Also see the ${terminalLink(
|
|
26
25
|
"CedarJS CLI Reference",
|
|
27
26
|
"https://cedarjs.com/docs/cli-commands#setup"
|
|
@@ -59,10 +59,10 @@ const handler = async ({
|
|
|
59
59
|
vitestArgs.push("--run");
|
|
60
60
|
}
|
|
61
61
|
if (!others["config"]) {
|
|
62
|
-
sides.forEach((side) => vitestArgs.push("--project", side));
|
|
63
62
|
if (!sides.length) {
|
|
64
63
|
project.workspaces().forEach((side) => sides.push(side));
|
|
65
64
|
}
|
|
65
|
+
sides.forEach((side) => vitestArgs.push("--project", side));
|
|
66
66
|
}
|
|
67
67
|
try {
|
|
68
68
|
const cacheDirDb = `file:${ensurePosixPath(
|
|
@@ -4,7 +4,6 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import execa from "execa";
|
|
6
6
|
import semver from "semver";
|
|
7
|
-
const MAIN_BRANCH_PRERELEASE_TAGS = ["canary"];
|
|
8
7
|
function isExecaError(e) {
|
|
9
8
|
return e instanceof Error && ("stdout" in e || "stderr" in e || "exitCode" in e);
|
|
10
9
|
}
|
|
@@ -34,15 +33,8 @@ async function runPreUpgradeScripts(ctx, task, { verbose, force }) {
|
|
|
34
33
|
if (!Array.isArray(manifest) || manifest.length === 0) {
|
|
35
34
|
return;
|
|
36
35
|
}
|
|
37
|
-
const prereleaseTag = parsed?.prerelease[0];
|
|
38
|
-
const isMainBranchPrerelease = typeof prereleaseTag === "string" && MAIN_BRANCH_PRERELEASE_TAGS.includes(prereleaseTag);
|
|
39
36
|
const checkLevels = [];
|
|
40
|
-
if (parsed &&
|
|
41
|
-
checkLevels.push({
|
|
42
|
-
id: "tag",
|
|
43
|
-
candidates: [`${prereleaseTag}.ts`, `${prereleaseTag}/index.ts`]
|
|
44
|
-
});
|
|
45
|
-
} else if (parsed) {
|
|
37
|
+
if (parsed && !parsed.prerelease.length) {
|
|
46
38
|
checkLevels.push({
|
|
47
39
|
id: "exact",
|
|
48
40
|
candidates: [`${version}.ts`, `${version}/index.ts`]
|
|
@@ -58,6 +50,14 @@ async function runPreUpgradeScripts(ctx, task, { verbose, force }) {
|
|
|
58
50
|
id: "minor",
|
|
59
51
|
candidates: [`${parsed.major}.x.ts`, `${parsed.major}.x/index.ts`]
|
|
60
52
|
});
|
|
53
|
+
} else if (parsed && parsed.prerelease.length > 0) {
|
|
54
|
+
checkLevels.push({
|
|
55
|
+
id: "tag",
|
|
56
|
+
candidates: [
|
|
57
|
+
`${parsed.prerelease[0]}.ts`,
|
|
58
|
+
`${parsed.prerelease[0]}/index.ts`
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
61
|
}
|
|
62
62
|
const scriptsToRun = [];
|
|
63
63
|
for (const level of checkLevels) {
|