@cedarjs/cli 2.8.0 → 2.8.1-next.109
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/commands/build/buildHandler.js +7 -3
- package/dist/commands/build.js +2 -1
- package/dist/commands/check.js +2 -4
- package/dist/commands/console.js +2 -2
- package/dist/commands/consoleHandler.js +10 -4
- package/dist/commands/dev/devHandler.js +1 -4
- package/dist/commands/execHandler.js +11 -4
- package/dist/commands/generate/dataMigration/dataMigration.js +1 -2
- package/dist/commands/generate/realtime/realtimeHandler.js +3 -3
- package/dist/commands/generate/service/serviceHandler.js +1 -2
- package/dist/commands/generate.js +8 -1
- package/dist/commands/jobsHandler.js +4 -2
- package/dist/commands/lint.js +2 -2
- package/dist/commands/prerenderHandler.js +65 -35
- package/dist/commands/prismaHandler.js +41 -18
- package/dist/commands/setup/deploy/providers/coherenceHandler.js +3 -3
- package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +4 -12
- package/dist/commands/setup/deploy/providers/renderHandler.js +5 -12
- package/dist/commands/setup/jobs/jobsHandler.js +3 -4
- package/dist/commands/setup/realtime/realtime.js +1 -1
- package/dist/commands/setup/realtime/realtimeHandler.js +20 -1
- package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +1 -1
- package/dist/commands/test/datasourceWarning.js +42 -0
- package/dist/commands/{testHandler.js → test/testHandler.js} +43 -30
- package/dist/commands/{testHandlerEsm.js → test/testHandlerEsm.js} +38 -23
- package/dist/commands/test.js +5 -1
- package/dist/commands/testEsm.js +5 -1
- package/dist/commands/type-checkHandler.js +21 -12
- package/dist/commands/upgrade/upgradeHandler.js +22 -9
- package/dist/lib/background.js +2 -0
- package/dist/lib/generatePrismaClient.js +4 -4
- package/dist/lib/schemaHelpers.js +3 -6
- package/dist/lib/test.js +10 -0
- package/dist/telemetry/resource.js +1 -3
- package/dist/testLib/cells.js +5 -3
- package/package.json +17 -19
|
@@ -4,13 +4,10 @@ import path from "path";
|
|
|
4
4
|
import prismaInternals from "@prisma/internals";
|
|
5
5
|
import { Listr } from "listr2";
|
|
6
6
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
7
|
+
import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
|
|
7
8
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
8
9
|
import c from "../../../../lib/colors.js";
|
|
9
|
-
import {
|
|
10
|
-
getPaths,
|
|
11
|
-
writeFilesTask,
|
|
12
|
-
printSetupNotes
|
|
13
|
-
} from "../../../../lib/index.js";
|
|
10
|
+
import { writeFilesTask, printSetupNotes } from "../../../../lib/index.js";
|
|
14
11
|
import { updateApiURLTask } from "../helpers/index.js";
|
|
15
12
|
import {
|
|
16
13
|
flightcontrolConfig,
|
|
@@ -18,7 +15,7 @@ import {
|
|
|
18
15
|
postgresDatabaseService,
|
|
19
16
|
mysqlDatabaseService
|
|
20
17
|
} from "../templates/flightcontrol.js";
|
|
21
|
-
const {
|
|
18
|
+
const { getConfig } = prismaInternals;
|
|
22
19
|
const getFlightcontrolJson = async (database) => {
|
|
23
20
|
if (database === "none") {
|
|
24
21
|
return {
|
|
@@ -26,12 +23,7 @@ const getFlightcontrolJson = async (database) => {
|
|
|
26
23
|
content: flightcontrolConfig
|
|
27
24
|
};
|
|
28
25
|
}
|
|
29
|
-
|
|
30
|
-
throw new Error("Could not find prisma schema at 'api/db/schema.prisma'");
|
|
31
|
-
}
|
|
32
|
-
const result = await getSchemaWithPath(
|
|
33
|
-
path.join(getPaths().base, "api/db/schema.prisma")
|
|
34
|
-
);
|
|
26
|
+
const result = await getPrismaSchemas();
|
|
35
27
|
const config = await getConfig({ datamodel: result.schemas });
|
|
36
28
|
const detectedDatabase = config.datasources[0].activeProvider;
|
|
37
29
|
if (detectedDatabase === database) {
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import path from "path";
|
|
3
2
|
import prismaInternals from "@prisma/internals";
|
|
4
3
|
import { Listr } from "listr2";
|
|
5
4
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
5
|
+
import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
|
|
6
6
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
7
7
|
import c from "../../../../lib/colors.js";
|
|
8
|
-
import {
|
|
9
|
-
getPaths,
|
|
10
|
-
writeFilesTask,
|
|
11
|
-
printSetupNotes
|
|
12
|
-
} from "../../../../lib/index.js";
|
|
8
|
+
import { writeFilesTask, printSetupNotes } from "../../../../lib/index.js";
|
|
13
9
|
import { addFilesTask, updateApiURLTask } from "../helpers/index.js";
|
|
14
10
|
import {
|
|
15
11
|
POSTGRES_YAML,
|
|
@@ -17,7 +13,7 @@ import {
|
|
|
17
13
|
RENDER_YAML,
|
|
18
14
|
SQLITE_YAML
|
|
19
15
|
} from "../templates/render.js";
|
|
20
|
-
const {
|
|
16
|
+
const { getConfig } = prismaInternals;
|
|
21
17
|
const getRenderYamlContent = async (database) => {
|
|
22
18
|
if (database === "none") {
|
|
23
19
|
return {
|
|
@@ -25,11 +21,8 @@ const getRenderYamlContent = async (database) => {
|
|
|
25
21
|
content: RENDER_YAML("")
|
|
26
22
|
};
|
|
27
23
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
const { schemas } = await getSchemaWithPath("api/db/schema.prisma");
|
|
32
|
-
const config = await getConfig({ datamodel: schemas });
|
|
24
|
+
const result = await getPrismaSchemas();
|
|
25
|
+
const config = await getConfig({ datamodel: result.schemas });
|
|
33
26
|
const detectedDatabase = config.datasources[0].activeProvider;
|
|
34
27
|
if (detectedDatabase === database) {
|
|
35
28
|
switch (database) {
|
|
@@ -3,11 +3,11 @@ import * as path from "node:path";
|
|
|
3
3
|
import prismaInternals from "@prisma/internals";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
5
|
import { addApiPackages } from "@cedarjs/cli-helpers";
|
|
6
|
-
import { getSchemaPath } from "@cedarjs/project-config";
|
|
6
|
+
import { getSchemaPath, getPrismaSchemas } from "@cedarjs/project-config";
|
|
7
7
|
import c from "../../../lib/colors.js";
|
|
8
8
|
import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
|
|
9
9
|
import { isTypeScriptProject } from "../../../lib/project.js";
|
|
10
|
-
const { getDMMF
|
|
10
|
+
const { getDMMF } = prismaInternals;
|
|
11
11
|
const MODEL_SCHEMA = `
|
|
12
12
|
model BackgroundJob {
|
|
13
13
|
id Int @id @default(autoincrement())
|
|
@@ -26,8 +26,7 @@ model BackgroundJob {
|
|
|
26
26
|
}
|
|
27
27
|
`;
|
|
28
28
|
const getModelNames = async () => {
|
|
29
|
-
const
|
|
30
|
-
const { schemas } = await getSchemaWithPath(schemaPath);
|
|
29
|
+
const { schemas } = await getPrismaSchemas();
|
|
31
30
|
const schema = await getDMMF({ datamodel: schemas });
|
|
32
31
|
return schema.datamodel.models.map((model) => model.name);
|
|
33
32
|
};
|
|
@@ -4,7 +4,7 @@ const description = "Setup RedwoodJS Realtime";
|
|
|
4
4
|
function builder(yargs) {
|
|
5
5
|
yargs.option("includeExamples", {
|
|
6
6
|
alias: ["e", "examples"],
|
|
7
|
-
default:
|
|
7
|
+
default: void 0,
|
|
8
8
|
description: "Include examples of how to implement liveQueries and subscriptions",
|
|
9
9
|
type: "boolean"
|
|
10
10
|
}).option("force", {
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
|
+
import prompts from "prompts";
|
|
5
6
|
import { addApiPackages } from "@cedarjs/cli-helpers";
|
|
6
7
|
import { projectIsEsm } from "@cedarjs/project-config";
|
|
7
8
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
@@ -16,13 +17,31 @@ const { version } = JSON.parse(
|
|
|
16
17
|
"utf-8"
|
|
17
18
|
)
|
|
18
19
|
);
|
|
19
|
-
async function
|
|
20
|
+
async function handleExamplesPreference(includeExamples) {
|
|
21
|
+
let incl = includeExamples;
|
|
22
|
+
if (typeof includeExamples === "undefined") {
|
|
23
|
+
const response = await prompts({
|
|
24
|
+
type: "toggle",
|
|
25
|
+
name: "includeExamples",
|
|
26
|
+
message: "Do you want to generate examples?",
|
|
27
|
+
initial: true,
|
|
28
|
+
active: "Yes",
|
|
29
|
+
inactive: "No"
|
|
30
|
+
});
|
|
31
|
+
incl = response.includeExamples;
|
|
32
|
+
}
|
|
33
|
+
return incl;
|
|
34
|
+
}
|
|
35
|
+
async function handler(args) {
|
|
20
36
|
const redwoodPaths = getPaths();
|
|
21
37
|
const ts = isTypeScriptProject();
|
|
22
38
|
const realtimeLibFilePath = path.join(
|
|
23
39
|
redwoodPaths.api.lib,
|
|
24
40
|
`realtime.${isTypeScriptProject() ? "ts" : "js"}`
|
|
25
41
|
);
|
|
42
|
+
const force = args.force || false;
|
|
43
|
+
const verbose = args.verbose || false;
|
|
44
|
+
const includeExamples = await handleExamplesPreference(args.includeExamples);
|
|
26
45
|
const tasks = new Listr(
|
|
27
46
|
[
|
|
28
47
|
addApiPackages(["ioredis@^5", `@cedarjs/realtime@${version}`]),
|
|
@@ -76,7 +76,7 @@ const handler = async ({ force, install }) => {
|
|
|
76
76
|
install
|
|
77
77
|
});
|
|
78
78
|
const rwPaths = getPaths();
|
|
79
|
-
const projectPackages = ["prettier-plugin-tailwindcss@^0.
|
|
79
|
+
const projectPackages = ["prettier-plugin-tailwindcss@^0.7.0"];
|
|
80
80
|
const webWorkspacePackages = [
|
|
81
81
|
"postcss",
|
|
82
82
|
"postcss-loader",
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import Enquirer from "enquirer";
|
|
3
|
+
import { getPaths } from "@cedarjs/project-config";
|
|
4
|
+
async function warnIfNonStandardDatasourceUrl({ force } = {}) {
|
|
5
|
+
const cedarPaths = getPaths();
|
|
6
|
+
if (!fs.existsSync(cedarPaths.api.prismaConfig)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const prismaConfig = await fs.promises.readFile(
|
|
10
|
+
cedarPaths.api.prismaConfig,
|
|
11
|
+
"utf-8"
|
|
12
|
+
);
|
|
13
|
+
const prismaConfigLines = prismaConfig.split("\n");
|
|
14
|
+
for (const line of prismaConfigLines) {
|
|
15
|
+
const envVarName = (line.match(
|
|
16
|
+
/^\s*url: process\.env\.(\w+),?(\s*\/\/.*)?$/
|
|
17
|
+
) ?? line.match(/^\s*url: env\(['"](\w+)['"]\),?(\s*\/\/.*)?$/) ?? line.match(/[{,] url: process\.env\.(\w+)(?:,| })/) ?? line.match(/[{,] url: env\(['"](\w+)['"]\)(?:,| })/))?.[1];
|
|
18
|
+
if (envVarName && envVarName !== "DATABASE_URL") {
|
|
19
|
+
if (force) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.warn(
|
|
23
|
+
`Found a non-standard prisma config datasource url env var: "${envVarName}".
|
|
24
|
+
Cedar will not override this env var, potentially running destructive commands against your production database.`
|
|
25
|
+
);
|
|
26
|
+
const { proceed } = await Enquirer.prompt({
|
|
27
|
+
type: "confirm",
|
|
28
|
+
name: "proceed",
|
|
29
|
+
message: "Are you sure you want to run tests against this database?",
|
|
30
|
+
initial: false
|
|
31
|
+
});
|
|
32
|
+
if (!proceed) {
|
|
33
|
+
console.log("Aborting.");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
warnIfNonStandardDatasourceUrl
|
|
42
|
+
};
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "path";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
5
5
|
import { ensurePosixPath } from "@cedarjs/project-config";
|
|
6
6
|
import { errorTelemetry, timedTelemetry } from "@cedarjs/telemetry";
|
|
7
|
-
import c from "
|
|
8
|
-
import { getPaths } from "
|
|
9
|
-
import * as project from "
|
|
7
|
+
import c from "../../lib/colors.js";
|
|
8
|
+
import { getPaths } from "../../lib/index.js";
|
|
9
|
+
import * as project from "../../lib/project.js";
|
|
10
|
+
import { warnIfNonStandardDatasourceUrl } from "./datasourceWarning.js";
|
|
11
|
+
function hasStringMessage(value) {
|
|
12
|
+
return typeof value === "object" && value !== null && "message" in value && value.message === "string";
|
|
13
|
+
}
|
|
14
|
+
function getExitCode(value) {
|
|
15
|
+
if (!value || typeof value !== "object" || !("exitCode" in value) || typeof value.exitCode !== "number") {
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
18
|
+
return value.exitCode;
|
|
19
|
+
}
|
|
10
20
|
function isInGitRepository() {
|
|
11
21
|
try {
|
|
12
22
|
execa.commandSync("git rev-parse --is-inside-work-tree");
|
|
@@ -24,25 +34,24 @@ function isInMercurialRepository() {
|
|
|
24
34
|
}
|
|
25
35
|
}
|
|
26
36
|
function isJestConfigFile(sides) {
|
|
27
|
-
for (
|
|
37
|
+
for (const side of sides) {
|
|
28
38
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`
|
|
39
|
+
const jestConfigExists = fs.existsSync(path.join(side, "jest.config.js")) || fs.existsSync(path.join(side, "jest.config.ts"));
|
|
40
|
+
if (!jestConfigExists) {
|
|
41
|
+
console.error(
|
|
42
|
+
c.error(
|
|
43
|
+
`
|
|
35
44
|
Error: Missing Jest config file ${side}/jest.config.js
|
|
36
45
|
To add this file, run \`npx @cedarjs/codemods update-jest-config\`
|
|
37
46
|
`
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
throw new Error(`Error: Jest config file not found in ${side} side`);
|
|
42
50
|
}
|
|
43
|
-
} catch (
|
|
44
|
-
|
|
45
|
-
process.
|
|
51
|
+
} catch (error) {
|
|
52
|
+
const message = hasStringMessage(error) ? error.message : `Error: Jest config file not found in ${side} side`;
|
|
53
|
+
errorTelemetry(process.argv, message);
|
|
54
|
+
process.exit(getExitCode(error) ?? 1);
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
}
|
|
@@ -51,6 +60,7 @@ const handler = async ({
|
|
|
51
60
|
watch = true,
|
|
52
61
|
collectCoverage = false,
|
|
53
62
|
dbPush = true,
|
|
63
|
+
force = false,
|
|
54
64
|
...others
|
|
55
65
|
}) => {
|
|
56
66
|
recordTelemetryAttributes({
|
|
@@ -64,21 +74,20 @@ const handler = async ({
|
|
|
64
74
|
if ([
|
|
65
75
|
"collect-coverage",
|
|
66
76
|
"db-push",
|
|
77
|
+
"force",
|
|
67
78
|
"loadEnvFiles",
|
|
68
79
|
"watch",
|
|
69
80
|
"$0",
|
|
70
81
|
"_"
|
|
71
82
|
].includes(flagName)) {
|
|
72
83
|
return [];
|
|
73
|
-
} else {
|
|
74
|
-
const flag = flagName.length > 1 ? `--${flagName}` : `-${flagName}`;
|
|
75
|
-
const flagValue = others[flagName];
|
|
76
|
-
if (Array.isArray(flagValue)) {
|
|
77
|
-
return flagValue.flatMap((val) => [flag, val]);
|
|
78
|
-
} else {
|
|
79
|
-
return [flag, flagValue];
|
|
80
|
-
}
|
|
81
84
|
}
|
|
85
|
+
const flag = flagName.length > 1 ? `--${flagName}` : `-${flagName}`;
|
|
86
|
+
const flagValue = others[flagName];
|
|
87
|
+
if (Array.isArray(flagValue)) {
|
|
88
|
+
return flagValue.flatMap((val) => [flag, val]);
|
|
89
|
+
}
|
|
90
|
+
return [flag, flagValue];
|
|
82
91
|
});
|
|
83
92
|
const sides = filterParams.filter(
|
|
84
93
|
(filterString) => project.workspaces().includes(filterString)
|
|
@@ -113,11 +122,14 @@ const handler = async ({
|
|
|
113
122
|
if (sides.includes("api") && !dbPush) {
|
|
114
123
|
process.env.SKIP_DB_PUSH = "1";
|
|
115
124
|
}
|
|
125
|
+
if (sides.includes("api")) {
|
|
126
|
+
await warnIfNonStandardDatasourceUrl({ force });
|
|
127
|
+
}
|
|
116
128
|
const runCommand = async () => {
|
|
117
129
|
await execa("yarn", ["jest", ...jestArgs], {
|
|
118
130
|
cwd: rwjsPaths.base,
|
|
119
131
|
stdio: "inherit",
|
|
120
|
-
env: { DATABASE_URL }
|
|
132
|
+
env: { ...process.env, DATABASE_URL }
|
|
121
133
|
});
|
|
122
134
|
};
|
|
123
135
|
if (watch) {
|
|
@@ -127,9 +139,10 @@ const handler = async ({
|
|
|
127
139
|
await runCommand();
|
|
128
140
|
});
|
|
129
141
|
}
|
|
130
|
-
} catch (
|
|
131
|
-
|
|
132
|
-
process.
|
|
142
|
+
} catch (error) {
|
|
143
|
+
const message = hasStringMessage(error) ? error.message : "Test command failed";
|
|
144
|
+
errorTelemetry(process.argv, message);
|
|
145
|
+
process.exit(getExitCode(error) ?? 1);
|
|
133
146
|
}
|
|
134
147
|
};
|
|
135
148
|
export {
|
|
@@ -2,11 +2,22 @@ import execa from "execa";
|
|
|
2
2
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
3
3
|
import { ensurePosixPath } from "@cedarjs/project-config";
|
|
4
4
|
import { errorTelemetry, timedTelemetry } from "@cedarjs/telemetry";
|
|
5
|
-
import { getPaths } from "
|
|
6
|
-
import * as project from "
|
|
5
|
+
import { getPaths } from "../../lib/index.js";
|
|
6
|
+
import * as project from "../../lib/project.js";
|
|
7
|
+
import { warnIfNonStandardDatasourceUrl } from "./datasourceWarning.js";
|
|
8
|
+
function hasStringMessage(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && "message" in value && value.message === "string";
|
|
10
|
+
}
|
|
11
|
+
function getExitCode(value) {
|
|
12
|
+
if (!value || typeof value !== "object" || !("exitCode" in value) || typeof value.exitCode !== "number") {
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
15
|
+
return value.exitCode;
|
|
16
|
+
}
|
|
7
17
|
const handler = async ({
|
|
8
18
|
filter: filterParams = [],
|
|
9
19
|
dbPush = true,
|
|
20
|
+
force = false,
|
|
10
21
|
...others
|
|
11
22
|
}) => {
|
|
12
23
|
recordTelemetryAttributes({
|
|
@@ -16,22 +27,20 @@ const handler = async ({
|
|
|
16
27
|
let watch = true;
|
|
17
28
|
const rwjsPaths = getPaths();
|
|
18
29
|
const forwardVitestFlags = Object.keys(others).flatMap((flagName) => {
|
|
19
|
-
if (["db-push", "loadEnvFiles", "$0", "_"].includes(flagName)) {
|
|
30
|
+
if (["db-push", "force", "loadEnvFiles", "$0", "_"].includes(flagName)) {
|
|
20
31
|
return [];
|
|
21
|
-
} else {
|
|
22
|
-
const flag = flagName.length > 1 ? `--${flagName}` : `-${flagName}`;
|
|
23
|
-
const flagValue = others[flagName];
|
|
24
|
-
if (flagName === "watch") {
|
|
25
|
-
watch = flagValue === true;
|
|
26
|
-
} else if (flagName === "run" && flagValue) {
|
|
27
|
-
watch = false;
|
|
28
|
-
}
|
|
29
|
-
if (Array.isArray(flagValue)) {
|
|
30
|
-
return flagValue.flatMap((val) => [flag, val]);
|
|
31
|
-
} else {
|
|
32
|
-
return [flag, flagValue];
|
|
33
|
-
}
|
|
34
32
|
}
|
|
33
|
+
const flag = flagName.length > 1 ? `--${flagName}` : `-${flagName}`;
|
|
34
|
+
const flagValue = others[flagName];
|
|
35
|
+
if (flagName === "watch") {
|
|
36
|
+
watch = flagValue === true;
|
|
37
|
+
} else if (flagName === "run" && flagValue) {
|
|
38
|
+
watch = false;
|
|
39
|
+
}
|
|
40
|
+
if (Array.isArray(flagValue)) {
|
|
41
|
+
return flagValue.flatMap((val) => [flag, val]);
|
|
42
|
+
}
|
|
43
|
+
return [flag, flagValue];
|
|
35
44
|
});
|
|
36
45
|
const sides = filterParams.filter(
|
|
37
46
|
(filterString) => project.workspaces().includes(filterString)
|
|
@@ -49,10 +58,12 @@ const handler = async ({
|
|
|
49
58
|
if (process.env.CI) {
|
|
50
59
|
vitestArgs.push("--run");
|
|
51
60
|
}
|
|
52
|
-
if (!
|
|
53
|
-
|
|
61
|
+
if (!others["config"]) {
|
|
62
|
+
if (!sides.length) {
|
|
63
|
+
project.workspaces().forEach((side) => sides.push(side));
|
|
64
|
+
}
|
|
65
|
+
sides.forEach((side) => vitestArgs.push("--project", side));
|
|
54
66
|
}
|
|
55
|
-
sides.forEach((side) => vitestArgs.push("--project", side));
|
|
56
67
|
try {
|
|
57
68
|
const cacheDirDb = `file:${ensurePosixPath(
|
|
58
69
|
rwjsPaths.generated.base
|
|
@@ -61,11 +72,14 @@ const handler = async ({
|
|
|
61
72
|
if (sides.includes("api") && !dbPush) {
|
|
62
73
|
process.env.SKIP_DB_PUSH = "1";
|
|
63
74
|
}
|
|
75
|
+
if (sides.includes("api")) {
|
|
76
|
+
await warnIfNonStandardDatasourceUrl({ force });
|
|
77
|
+
}
|
|
64
78
|
const runCommand = async () => {
|
|
65
79
|
await execa("yarn", ["vitest", ...vitestArgs], {
|
|
66
80
|
cwd: rwjsPaths.base,
|
|
67
81
|
stdio: "inherit",
|
|
68
|
-
env: { DATABASE_URL }
|
|
82
|
+
env: { ...process.env, DATABASE_URL }
|
|
69
83
|
});
|
|
70
84
|
};
|
|
71
85
|
if (watch) {
|
|
@@ -75,9 +89,10 @@ const handler = async ({
|
|
|
75
89
|
await runCommand();
|
|
76
90
|
});
|
|
77
91
|
}
|
|
78
|
-
} catch (
|
|
79
|
-
|
|
80
|
-
process.
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const message = hasStringMessage(error) ? error.message : "Test command failed";
|
|
94
|
+
errorTelemetry(process.argv, message);
|
|
95
|
+
process.exit(getExitCode(error) ?? 1);
|
|
81
96
|
}
|
|
82
97
|
};
|
|
83
98
|
export {
|
package/dist/commands/test.js
CHANGED
|
@@ -21,6 +21,10 @@ const builder = (yargs) => {
|
|
|
21
21
|
describe: "Syncs the test database with your Prisma schema without requiring a migration. It creates a test database if it doesn't already exist.",
|
|
22
22
|
type: "boolean",
|
|
23
23
|
default: true
|
|
24
|
+
}).option("force", {
|
|
25
|
+
describe: "Run tests without prompting for confirmation, even when a non-standard datasource url env var is detected.",
|
|
26
|
+
type: "boolean",
|
|
27
|
+
default: false
|
|
24
28
|
}).epilogue(
|
|
25
29
|
`For all available flags, run jest cli directly ${c.tip(
|
|
26
30
|
"yarn jest --help"
|
|
@@ -34,7 +38,7 @@ Also see the ${terminalLink(
|
|
|
34
38
|
);
|
|
35
39
|
};
|
|
36
40
|
const handler = async (options) => {
|
|
37
|
-
const { handler: handler2 } = await import("./testHandler.js");
|
|
41
|
+
const { handler: handler2 } = await import("./test/testHandler.js");
|
|
38
42
|
return handler2(options);
|
|
39
43
|
};
|
|
40
44
|
export {
|
package/dist/commands/testEsm.js
CHANGED
|
@@ -18,6 +18,10 @@ const builder = (yargs) => {
|
|
|
18
18
|
describe: "Syncs the test database with your Prisma schema without requiring a migration. It creates a test database if it doesn't already exist.",
|
|
19
19
|
type: "boolean",
|
|
20
20
|
default: true
|
|
21
|
+
}).option("force", {
|
|
22
|
+
describe: "Skip any confirmation prompts and run tests without interruption. Useful in CI or scripted environments.",
|
|
23
|
+
type: "boolean",
|
|
24
|
+
default: false
|
|
21
25
|
}).epilogue(
|
|
22
26
|
`For all available flags, run vitest cli directly ${vitestTip}
|
|
23
27
|
|
|
@@ -26,7 +30,7 @@ Also see the ${cliDocsLink}
|
|
|
26
30
|
);
|
|
27
31
|
};
|
|
28
32
|
const handler = async (options) => {
|
|
29
|
-
const { handler: handler2 } = await import("./testHandlerEsm.js");
|
|
33
|
+
const { handler: handler2 } = await import("./test/testHandlerEsm.js");
|
|
30
34
|
return handler2(options);
|
|
31
35
|
};
|
|
32
36
|
export {
|
|
@@ -1,25 +1,36 @@
|
|
|
1
|
-
import path from "path";
|
|
1
|
+
import path from "node:path";
|
|
2
2
|
import concurrently from "concurrently";
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
5
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
6
6
|
import { generatePrismaClient } from "../lib/generatePrismaClient.js";
|
|
7
7
|
import { getPaths } from "../lib/index.js";
|
|
8
|
-
const
|
|
8
|
+
const isConcurrentlyErrorArray = (value) => {
|
|
9
|
+
return Array.isArray(value);
|
|
10
|
+
};
|
|
11
|
+
const handler = async ({
|
|
12
|
+
sides,
|
|
13
|
+
verbose = false,
|
|
14
|
+
prisma = true,
|
|
15
|
+
generate = true
|
|
16
|
+
}) => {
|
|
17
|
+
const selectedSides = (Array.isArray(sides) ? sides : []).filter(
|
|
18
|
+
(side) => typeof side === "string"
|
|
19
|
+
);
|
|
9
20
|
recordTelemetryAttributes({
|
|
10
21
|
command: "type-check",
|
|
11
|
-
sides: JSON.stringify(
|
|
22
|
+
sides: JSON.stringify(selectedSides),
|
|
12
23
|
verbose,
|
|
13
24
|
prisma,
|
|
14
25
|
generate
|
|
15
26
|
});
|
|
16
27
|
const typeCheck = async () => {
|
|
17
28
|
let conclusiveExitCode = 0;
|
|
18
|
-
const tscForAllSides =
|
|
29
|
+
const tscForAllSides = selectedSides.map((side) => {
|
|
19
30
|
const projectDir = path.join(getPaths().base, side);
|
|
20
31
|
return {
|
|
21
32
|
cwd: projectDir,
|
|
22
|
-
command:
|
|
33
|
+
command: "yarn tsc --noEmit --skipLibCheck"
|
|
23
34
|
};
|
|
24
35
|
});
|
|
25
36
|
const { result } = concurrently(tscForAllSides, {
|
|
@@ -28,18 +39,16 @@ const handler = async ({ sides, verbose, prisma, generate }) => {
|
|
|
28
39
|
});
|
|
29
40
|
try {
|
|
30
41
|
await result;
|
|
31
|
-
} catch (
|
|
32
|
-
if (
|
|
33
|
-
const exitCodes =
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (isConcurrentlyErrorArray(error)) {
|
|
44
|
+
const exitCodes = error.map((entry) => entry.exitCode).filter((exitCode2) => Boolean(exitCode2));
|
|
34
45
|
conclusiveExitCode = Math.max(...exitCodes);
|
|
35
46
|
}
|
|
36
47
|
}
|
|
37
48
|
return conclusiveExitCode;
|
|
38
49
|
};
|
|
39
50
|
if (generate && prisma) {
|
|
40
|
-
await generatePrismaClient({
|
|
41
|
-
verbose
|
|
42
|
-
});
|
|
51
|
+
await generatePrismaClient({ verbose });
|
|
43
52
|
}
|
|
44
53
|
if (generate) {
|
|
45
54
|
await new Listr(
|
|
@@ -53,7 +62,7 @@ const handler = async ({ sides, verbose, prisma, generate }) => {
|
|
|
53
62
|
}
|
|
54
63
|
],
|
|
55
64
|
{
|
|
56
|
-
renderer: verbose
|
|
65
|
+
renderer: verbose ? "verbose" : "default",
|
|
57
66
|
rendererOptions: { collapseSubtasks: false }
|
|
58
67
|
}
|
|
59
68
|
).run();
|
|
@@ -331,6 +331,11 @@ async function updatePackageVersionsFromTemplate(ctx, { dryRun, verbose }) {
|
|
|
331
331
|
title: `Updating ${pkgJsonPath}`,
|
|
332
332
|
task: async (_ctx, task) => {
|
|
333
333
|
const res = await fetch(url);
|
|
334
|
+
if (!res.ok) {
|
|
335
|
+
throw new Error(
|
|
336
|
+
`Failed to fetch template package.json from ${url}: ` + res.statusText
|
|
337
|
+
);
|
|
338
|
+
}
|
|
334
339
|
const text = await res.text();
|
|
335
340
|
const templatePackageJson = JSON.parse(text);
|
|
336
341
|
const localPackageJsonText = fs.readFileSync(pkgJsonPath, "utf-8");
|
|
@@ -380,16 +385,19 @@ async function downloadYarnPatches(ctx, { dryRun, verbose }) {
|
|
|
380
385
|
throw new Error("Failed to upgrade");
|
|
381
386
|
}
|
|
382
387
|
const githubToken = process.env.GH_TOKEN || process.env.GITHUB_TOKEN || process.env.REDWOOD_GITHUB_TOKEN;
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
{
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
Accept: "application/vnd.github+json"
|
|
390
|
-
}
|
|
388
|
+
const url = "https://api.github.com/repos/cedarjs/cedar/git/trees/main?recursive=1";
|
|
389
|
+
const res = await fetch(url, {
|
|
390
|
+
headers: {
|
|
391
|
+
...githubToken && { Authorization: `Bearer ${githubToken}` },
|
|
392
|
+
["X-GitHub-Api-Version"]: "2022-11-28",
|
|
393
|
+
Accept: "application/vnd.github+json"
|
|
391
394
|
}
|
|
392
|
-
);
|
|
395
|
+
});
|
|
396
|
+
if (!res.ok) {
|
|
397
|
+
throw new Error(
|
|
398
|
+
`Failed to fetch list of yarn patches from ${url}: ` + res.statusText
|
|
399
|
+
);
|
|
400
|
+
}
|
|
393
401
|
const json = await res.json();
|
|
394
402
|
const patches = json.tree?.filter(
|
|
395
403
|
(patchInfo) => patchInfo.path.startsWith(
|
|
@@ -409,6 +417,11 @@ async function downloadYarnPatches(ctx, { dryRun, verbose }) {
|
|
|
409
417
|
title: `Downloading ${patch.path}`,
|
|
410
418
|
task: async () => {
|
|
411
419
|
const res2 = await fetch(patch.url);
|
|
420
|
+
if (!res2.ok) {
|
|
421
|
+
throw new Error(
|
|
422
|
+
`Failed to fetch patch metadata from ${patch.url}: ` + res2.statusText
|
|
423
|
+
);
|
|
424
|
+
}
|
|
412
425
|
const patchMeta = await res2.json();
|
|
413
426
|
const patchPath = path.join(
|
|
414
427
|
getPaths().base,
|
package/dist/lib/background.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { resolveGeneratedPrismaClient } from "@cedarjs/project-config";
|
|
4
|
-
import { runCommandTask, getPaths } from "
|
|
4
|
+
import { runCommandTask, getPaths } from "./index.js";
|
|
5
5
|
const generatePrismaCommand = async () => {
|
|
6
6
|
const createdRequire = createRequire(import.meta.url);
|
|
7
7
|
const prismaIndexPath = createdRequire.resolve("prisma/build/index.js");
|
|
@@ -18,10 +18,10 @@ const generatePrismaClient = async ({
|
|
|
18
18
|
verbose = true,
|
|
19
19
|
force = true,
|
|
20
20
|
silent = false
|
|
21
|
-
}) => {
|
|
21
|
+
} = {}) => {
|
|
22
22
|
if (!force) {
|
|
23
|
-
const
|
|
24
|
-
const prismaClientFile = fs.existsSync(
|
|
23
|
+
const { clientPath } = await resolveGeneratedPrismaClient();
|
|
24
|
+
const prismaClientFile = clientPath && fs.existsSync(clientPath) ? fs.readFileSync(clientPath, "utf8") : "";
|
|
25
25
|
if (!prismaClientFile.includes("@prisma/client did not initialize yet.") && prismaClientFile.includes("exports.Prisma.")) {
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import prismaInternals from "@prisma/internals";
|
|
2
|
-
import {
|
|
2
|
+
import { getPrismaSchemas } from "@cedarjs/project-config";
|
|
3
3
|
import { singularize, isPlural } from "@cedarjs/utils/cedarPluralize";
|
|
4
4
|
import { ensureUniquePlural } from "./pluralHelpers.js";
|
|
5
|
-
|
|
6
|
-
const { getConfig, getDMMF, getSchemaWithPath } = prismaInternals;
|
|
5
|
+
const { getConfig, getDMMF } = prismaInternals;
|
|
7
6
|
const schemaMemo = {};
|
|
8
7
|
const getExistingModelName = async (name) => {
|
|
9
8
|
if (!name) {
|
|
@@ -64,9 +63,7 @@ const getEnum = async (name) => {
|
|
|
64
63
|
return model;
|
|
65
64
|
};
|
|
66
65
|
const getDataModel = async () => {
|
|
67
|
-
const
|
|
68
|
-
const schemaPath = await getSchemaPath(prismaConfigPath);
|
|
69
|
-
const result = await getSchemaWithPath(schemaPath);
|
|
66
|
+
const result = await getPrismaSchemas();
|
|
70
67
|
return result.schemas;
|
|
71
68
|
};
|
|
72
69
|
const getSchemaDefinitions = async () => {
|