@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
|
@@ -29,7 +29,9 @@ function checkWorkspacePackageEntryPoints(cedarPaths) {
|
|
|
29
29
|
if (!fs.existsSync(pkgJsonPath)) {
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
|
-
const pkgJson = JSON.parse(
|
|
32
|
+
const pkgJson = JSON.parse(
|
|
33
|
+
fs.readFileSync(pkgJsonPath, "utf8")
|
|
34
|
+
);
|
|
33
35
|
const pkgName = pkgJson.name || entry.name;
|
|
34
36
|
const pkgDir = path.join(packagesDir, entry.name);
|
|
35
37
|
const entryFiles = /* @__PURE__ */ new Set();
|
|
@@ -82,7 +84,9 @@ const handler = async ({
|
|
|
82
84
|
const prerenderRoutes = prerender && workspace.includes("web") ? detectPrerenderRoutes() : [];
|
|
83
85
|
const shouldGeneratePrismaClient = prisma && prismaSchemaExists && (workspace.includes("api") || prerenderRoutes.length > 0);
|
|
84
86
|
const packageJsonPath = path.join(cedarPaths.base, "package.json");
|
|
85
|
-
const packageJson = JSON.parse(
|
|
87
|
+
const packageJson = JSON.parse(
|
|
88
|
+
fs.readFileSync(packageJsonPath, "utf8")
|
|
89
|
+
);
|
|
86
90
|
const packageJsonWorkspaces = packageJson.workspaces;
|
|
87
91
|
const nonApiWebWorkspaces = Array.isArray(packageJsonWorkspaces) && packageJsonWorkspaces.length > 2 ? workspace.filter((w) => w !== "api" && w !== "web") : [];
|
|
88
92
|
const gqlFeaturesTaskTitle = `Generating types needed for ${[
|
|
@@ -176,7 +180,7 @@ Run ` + c.info("yarn cedar build") + " (without specifying a workspace) to build
|
|
|
176
180
|
}
|
|
177
181
|
}
|
|
178
182
|
}
|
|
179
|
-
].filter(Boolean);
|
|
183
|
+
].filter((t) => Boolean(t));
|
|
180
184
|
const triggerPrerender = async () => {
|
|
181
185
|
console.log("Starting prerendering...");
|
|
182
186
|
if (prerenderRoutes.length === 0) {
|
package/dist/commands/build.js
CHANGED
|
@@ -9,7 +9,8 @@ const builder = (yargs) => {
|
|
|
9
9
|
yargs.positional("workspace", {
|
|
10
10
|
default: ["api", "web", "packages/*"],
|
|
11
11
|
description: "What workspace(s) to build. Valid values are: web, api, packages/*, <package-name>",
|
|
12
|
-
type: "
|
|
12
|
+
type: "string",
|
|
13
|
+
array: true
|
|
13
14
|
}).option("verbose", {
|
|
14
15
|
alias: "v",
|
|
15
16
|
default: false,
|
package/dist/commands/check.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
2
2
|
import c from "../lib/colors.js";
|
|
3
|
-
import { getPaths } from "../lib/index.js";
|
|
4
3
|
const command = "check";
|
|
5
4
|
const aliases = ["diagnostics"];
|
|
6
5
|
const description = "Get structural diagnostics for a Redwood project (experimental)";
|
|
7
6
|
const handler = async () => {
|
|
8
7
|
recordTelemetryAttributes({ command: "check" });
|
|
9
|
-
const { printDiagnostics, DiagnosticSeverity } =
|
|
10
|
-
|
|
11
|
-
printDiagnostics(getPaths().base, {
|
|
8
|
+
const { printDiagnostics, DiagnosticSeverity } = await import("@cedarjs/structure");
|
|
9
|
+
printDiagnostics({
|
|
12
10
|
getSeverityLabel: (severity) => {
|
|
13
11
|
if (severity === DiagnosticSeverity.Error) {
|
|
14
12
|
return c.error("error");
|
package/dist/commands/console.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const command = "console";
|
|
2
2
|
const aliases = ["c"];
|
|
3
3
|
const description = "Launch an interactive Redwood shell (experimental)";
|
|
4
|
-
const handler = async (
|
|
4
|
+
const handler = async () => {
|
|
5
5
|
const { handler: handler2 } = await import("./consoleHandler.js");
|
|
6
|
-
return handler2(
|
|
6
|
+
return handler2();
|
|
7
7
|
};
|
|
8
8
|
export {
|
|
9
9
|
aliases,
|
|
@@ -6,6 +6,9 @@ import { registerApiSideBabelHook } from "@cedarjs/babel-config";
|
|
|
6
6
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
7
7
|
import { getPaths } from "../lib/index.js";
|
|
8
8
|
const paths = getPaths();
|
|
9
|
+
function isREPLServerWithHistory(replServer) {
|
|
10
|
+
return "history" in replServer && "lines" in replServer;
|
|
11
|
+
}
|
|
9
12
|
const loadPrismaClient = (replContext) => {
|
|
10
13
|
const createdRequire = createRequire(import.meta.url);
|
|
11
14
|
const { db } = createdRequire(path.join(paths.api.lib, "db"));
|
|
@@ -14,16 +17,19 @@ const loadPrismaClient = (replContext) => {
|
|
|
14
17
|
};
|
|
15
18
|
const consoleHistoryFile = path.join(paths.generated.base, "console_history");
|
|
16
19
|
const persistConsoleHistory = (r) => {
|
|
20
|
+
const lines = isREPLServerWithHistory(r) ? r.lines : [];
|
|
17
21
|
fs.appendFileSync(
|
|
18
22
|
consoleHistoryFile,
|
|
19
|
-
|
|
23
|
+
lines.filter((line) => line.trim()).join("\n") + "\n",
|
|
20
24
|
"utf8"
|
|
21
25
|
);
|
|
22
26
|
};
|
|
23
27
|
const loadConsoleHistory = async (r) => {
|
|
24
28
|
try {
|
|
25
29
|
const history = await fs.promises.readFile(consoleHistoryFile, "utf8");
|
|
26
|
-
|
|
30
|
+
if (isREPLServerWithHistory(r)) {
|
|
31
|
+
history.split("\n").reverse().map((line) => r.history.push(line));
|
|
32
|
+
}
|
|
27
33
|
} catch {
|
|
28
34
|
}
|
|
29
35
|
};
|
|
@@ -53,8 +59,8 @@ const handler = (_options) => {
|
|
|
53
59
|
} else {
|
|
54
60
|
try {
|
|
55
61
|
callback(null, await Promise.resolve(result));
|
|
56
|
-
} catch (
|
|
57
|
-
callback(
|
|
62
|
+
} catch (err2) {
|
|
63
|
+
callback(err2 instanceof Error ? err2 : new Error(String(err2)), null);
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
});
|
|
@@ -83,10 +83,7 @@ const handler = async ({
|
|
|
83
83
|
}
|
|
84
84
|
if (workspace.includes("api")) {
|
|
85
85
|
try {
|
|
86
|
-
await generatePrismaClient({
|
|
87
|
-
verbose: false,
|
|
88
|
-
force: false
|
|
89
|
-
});
|
|
86
|
+
await generatePrismaClient({ verbose: false, force: false });
|
|
90
87
|
} catch (e) {
|
|
91
88
|
const message = getErrorMessage(e);
|
|
92
89
|
errorTelemetry(process.argv, `Error generating prisma client: ${message}`);
|
|
@@ -36,14 +36,21 @@ const printAvailableScriptsToConsole = () => {
|
|
|
36
36
|
const handler = async (args) => {
|
|
37
37
|
recordTelemetryAttributes({
|
|
38
38
|
command: "exec",
|
|
39
|
-
prisma: args.prisma,
|
|
40
|
-
list: args.list
|
|
39
|
+
prisma: !!args.prisma,
|
|
40
|
+
list: !!args.list
|
|
41
41
|
});
|
|
42
42
|
const { name, prisma, list, ...scriptArgs } = args;
|
|
43
43
|
if (list || !name) {
|
|
44
44
|
printAvailableScriptsToConsole();
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
+
if (Array.isArray(scriptArgs._)) {
|
|
48
|
+
scriptArgs._ = scriptArgs._.slice(1);
|
|
49
|
+
}
|
|
50
|
+
delete scriptArgs.$0;
|
|
51
|
+
delete scriptArgs.l;
|
|
52
|
+
delete scriptArgs.s;
|
|
53
|
+
delete scriptArgs.silent;
|
|
47
54
|
const scriptPath = resolveScriptPath(name);
|
|
48
55
|
if (!scriptPath) {
|
|
49
56
|
console.error(
|
|
@@ -57,11 +64,11 @@ No script called \`${name}\` in the ./scripts folder.
|
|
|
57
64
|
const scriptTasks = [
|
|
58
65
|
{
|
|
59
66
|
title: "Generating Prisma client",
|
|
60
|
-
enabled: () =>
|
|
67
|
+
enabled: () => !!prisma,
|
|
61
68
|
task: () => generatePrismaClient({
|
|
62
69
|
force: false,
|
|
63
70
|
verbose: !args.silent,
|
|
64
|
-
silent: args.silent
|
|
71
|
+
silent: !!args.silent
|
|
65
72
|
})
|
|
66
73
|
},
|
|
67
74
|
{
|
|
@@ -3,7 +3,6 @@ import { paramCase } from "change-case";
|
|
|
3
3
|
import { Listr } from "listr2";
|
|
4
4
|
import { terminalLink } from "termi-link";
|
|
5
5
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
6
|
-
import { dbReexportsPrismaClient } from "@cedarjs/internal/dist/project";
|
|
7
6
|
import { getDataMigrationsPath } from "@cedarjs/project-config";
|
|
8
7
|
import c from "../../../lib/colors.js";
|
|
9
8
|
import {
|
|
@@ -44,7 +43,7 @@ const files = async ({ name, typescript }) => {
|
|
|
44
43
|
getPaths().api.prismaConfig
|
|
45
44
|
);
|
|
46
45
|
const outputPath = path.join(dataMigrationsPath, outputFilename);
|
|
47
|
-
const prismaImportSource =
|
|
46
|
+
const prismaImportSource = "src/lib/db";
|
|
48
47
|
return {
|
|
49
48
|
[outputPath]: await generateTemplate(TEMPLATE_PATHS[extension], {
|
|
50
49
|
name,
|
|
@@ -2,7 +2,7 @@ import path from "path";
|
|
|
2
2
|
import camelcase from "camelcase";
|
|
3
3
|
import { Listr } from "listr2";
|
|
4
4
|
import pascalcase from "pascalcase";
|
|
5
|
-
import pluralize
|
|
5
|
+
import pluralize from "pluralize";
|
|
6
6
|
import prompts from "prompts";
|
|
7
7
|
import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
|
|
8
8
|
import { projectIsEsm } from "@cedarjs/project-config";
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { isTypeScriptProject } from "../../../lib/project.js";
|
|
18
18
|
import { isRealtimeSetup, isServerFileSetup } from "../../experimental/util.js";
|
|
19
19
|
const templateVariables = (name) => {
|
|
20
|
-
name = singular(name.toLowerCase());
|
|
20
|
+
name = pluralize.singular(name.toLowerCase());
|
|
21
21
|
return {
|
|
22
22
|
name,
|
|
23
23
|
collectionName: pluralize(name),
|
|
@@ -38,7 +38,7 @@ const templateVariables = (name) => {
|
|
|
38
38
|
async function handler({ name, type, force, verbose, silent }) {
|
|
39
39
|
const redwoodPaths = getPaths();
|
|
40
40
|
const ts = isTypeScriptProject();
|
|
41
|
-
name = singular(name.toLowerCase());
|
|
41
|
+
name = pluralize.singular(name.toLowerCase());
|
|
42
42
|
let functionType = type;
|
|
43
43
|
if (!functionType) {
|
|
44
44
|
const response = await prompts({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import camelcase from "camelcase";
|
|
3
|
-
import { dbReexportsPrismaClient } from "@cedarjs/internal/dist/project";
|
|
4
3
|
import { pluralize, singularize } from "@cedarjs/utils/cedarPluralize";
|
|
5
4
|
import { transformTSToJS } from "../../../lib/index.js";
|
|
6
5
|
import { getSchema, verifyModelName } from "../../../lib/schemaHelpers.js";
|
|
@@ -223,7 +222,7 @@ const files = async ({
|
|
|
223
222
|
const componentName = camelcase(pluralize(name));
|
|
224
223
|
const model = name;
|
|
225
224
|
const idName = await getIdName(model);
|
|
226
|
-
const prismaImportSource =
|
|
225
|
+
const prismaImportSource = "src/lib/db";
|
|
227
226
|
const modelRelations = relations || relationsForModel(await getSchema(model));
|
|
228
227
|
const serviceFile = await templateForFile({
|
|
229
228
|
name,
|
|
@@ -22,12 +22,19 @@ import * as generateService from "./generate/service/service.js";
|
|
|
22
22
|
const command = "generate <type>";
|
|
23
23
|
const aliases = ["g"];
|
|
24
24
|
const description = "Generate boilerplate code and type definitions";
|
|
25
|
+
const getExitCode = (error) => {
|
|
26
|
+
if (typeof error !== "object" || error === null) {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
const exitCode = Reflect.get(error, "exitCode");
|
|
30
|
+
return typeof exitCode === "number" ? exitCode : void 0;
|
|
31
|
+
};
|
|
25
32
|
const builder = (yargs) => yargs.command("types", "Generate supplementary code", {}, () => {
|
|
26
33
|
recordTelemetryAttributes({ command: "generate types" });
|
|
27
34
|
try {
|
|
28
35
|
execa.sync("yarn", ["rw-gen"], { stdio: "inherit" });
|
|
29
36
|
} catch (error) {
|
|
30
|
-
process.exitCode = error
|
|
37
|
+
process.exitCode = getExitCode(error) ?? 1;
|
|
31
38
|
}
|
|
32
39
|
}).command(generateCell).command(generateComponent).command(generateDataMigration).command(generateDbAuth).command(generateDirective).command(generateFunction).command(generateJob).command(generateLayout).command(generateModel).command(generateOgImage).command(generatePackage).command(generatePage).command(generateRealtime).command(generateScaffold).command(generateScript).command(generateSdl).command(generateSecret).command(generateService).demandCommand().epilogue(
|
|
33
40
|
`Also see the ${terminalLink(
|
|
@@ -6,10 +6,12 @@ const handler = async ({
|
|
|
6
6
|
commands: _commands,
|
|
7
7
|
...options
|
|
8
8
|
}) => {
|
|
9
|
-
const
|
|
9
|
+
const positionalArgs = Array.isArray(_) ? [..._] : [];
|
|
10
|
+
const commandArg = positionalArgs.pop();
|
|
11
|
+
const args = [commandArg == null ? "" : String(commandArg)];
|
|
10
12
|
for (const [name, value] of Object.entries(options)) {
|
|
11
13
|
args.push(name.length > 1 ? `--${name}` : `-${name}`);
|
|
12
|
-
args.push(value);
|
|
14
|
+
args.push(String(value));
|
|
13
15
|
}
|
|
14
16
|
let command = `yarn rw-jobs ${args.join(" ")}`;
|
|
15
17
|
const originalLogLevel = process.env.LOG_LEVEL;
|
package/dist/commands/lint.js
CHANGED
|
@@ -3,7 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { terminalLink } from "termi-link";
|
|
5
5
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
6
|
-
import { getPaths, getConfig } from "
|
|
6
|
+
import { getPaths, getConfig } from "@cedarjs/project-config";
|
|
7
7
|
function detectLegacyEslintConfig() {
|
|
8
8
|
const projectRoot = getPaths().base;
|
|
9
9
|
const legacyConfigFiles = [
|
|
@@ -88,7 +88,7 @@ const handler = async ({
|
|
|
88
88
|
recordTelemetryAttributes({ command: "lint", fix, format });
|
|
89
89
|
const config = getConfig();
|
|
90
90
|
const legacyConfigFiles = detectLegacyEslintConfig();
|
|
91
|
-
if (legacyConfigFiles.length > 0 && config.eslintLegacyConfigWarning) {
|
|
91
|
+
if (legacyConfigFiles.length > 0 && config instanceof Object && "eslintLegacyConfigWarning" in config && config.eslintLegacyConfigWarning) {
|
|
92
92
|
showLegacyEslintDeprecationWarning(legacyConfigFiles);
|
|
93
93
|
}
|
|
94
94
|
try {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "path";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
import { Listr } from "listr2";
|
|
4
4
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
5
5
|
import { getConfig, getPaths, projectIsEsm } from "@cedarjs/project-config";
|
|
@@ -9,12 +9,33 @@ import { runScriptFunction } from "../lib/exec.js";
|
|
|
9
9
|
import { configureBabel } from "../lib/execBabel.js";
|
|
10
10
|
class PathParamError extends Error {
|
|
11
11
|
}
|
|
12
|
+
const hasPath = (route) => {
|
|
13
|
+
return typeof route.path === "string" && route.path.length > 0;
|
|
14
|
+
};
|
|
15
|
+
const normalizeRoute = (route) => {
|
|
16
|
+
const normalizedPath = route.path;
|
|
17
|
+
const normalizedName = typeof route.name === "string" ? route.name : normalizedPath;
|
|
18
|
+
const normalizedRoutePath = typeof route.routePath === "string" ? route.routePath : normalizedPath;
|
|
19
|
+
const normalizedFilePath = typeof route.filePath === "string" ? route.filePath : "";
|
|
20
|
+
return {
|
|
21
|
+
...route,
|
|
22
|
+
name: normalizedName,
|
|
23
|
+
path: normalizedPath,
|
|
24
|
+
routePath: normalizedRoutePath,
|
|
25
|
+
filePath: normalizedFilePath
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const getErrorMessage = (error) => {
|
|
29
|
+
return error instanceof Error ? error.message : String(error);
|
|
30
|
+
};
|
|
31
|
+
const getErrorStack = (error) => {
|
|
32
|
+
return error instanceof Error ? error.stack ?? error.message : String(error);
|
|
33
|
+
};
|
|
12
34
|
const mapRouterPathToHtml = (routerPath) => {
|
|
13
35
|
if (routerPath === "/") {
|
|
14
36
|
return "web/dist/index.html";
|
|
15
|
-
} else {
|
|
16
|
-
return `web/dist${routerPath}.html`;
|
|
17
37
|
}
|
|
38
|
+
return `web/dist${routerPath}.html`;
|
|
18
39
|
};
|
|
19
40
|
function getRouteHooksFilePath(routeFilePath) {
|
|
20
41
|
const routeHooksFilePathTs = routeFilePath.replace(
|
|
@@ -49,28 +70,32 @@ async function expandRouteParameters(route) {
|
|
|
49
70
|
filePath: route.filePath
|
|
50
71
|
}
|
|
51
72
|
});
|
|
52
|
-
if (routeParameters) {
|
|
73
|
+
if (Array.isArray(routeParameters)) {
|
|
53
74
|
return routeParameters.map((pathParamValues) => {
|
|
54
75
|
let newPath = route.path;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
if (typeof pathParamValues === "object" && pathParamValues !== null && !Array.isArray(pathParamValues)) {
|
|
77
|
+
Object.entries(pathParamValues).forEach(
|
|
78
|
+
([paramName, paramValue]) => {
|
|
79
|
+
newPath = newPath.replace(
|
|
80
|
+
new RegExp(`{${paramName}:?[^}]*}`),
|
|
81
|
+
String(paramValue)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
59
84
|
);
|
|
60
|
-
}
|
|
85
|
+
}
|
|
61
86
|
return { ...route, path: newPath };
|
|
62
87
|
});
|
|
63
88
|
}
|
|
64
|
-
} catch (
|
|
65
|
-
console.error(c.error(
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error(c.error(getErrorStack(error)));
|
|
66
91
|
return [route];
|
|
67
92
|
}
|
|
68
93
|
return [route];
|
|
69
94
|
}
|
|
70
95
|
const getTasks = async (dryrun, routerPathFilter = null) => {
|
|
71
96
|
const detector = projectIsEsm() ? await import("@cedarjs/prerender/detection") : await import("@cedarjs/prerender/cjs/detection");
|
|
72
|
-
const
|
|
73
|
-
const
|
|
97
|
+
const detectedRoutes = detector.detectPrerenderRoutes();
|
|
98
|
+
const prerenderRoutes = detectedRoutes.filter(hasPath).map(normalizeRoute);
|
|
74
99
|
if (prerenderRoutes.length === 0) {
|
|
75
100
|
console.log("\nSkipping prerender...");
|
|
76
101
|
console.log(
|
|
@@ -80,6 +105,7 @@ const getTasks = async (dryrun, routerPathFilter = null) => {
|
|
|
80
105
|
);
|
|
81
106
|
return [];
|
|
82
107
|
}
|
|
108
|
+
const indexHtmlPath = path.join(getPaths().web.dist, "index.html");
|
|
83
109
|
if (!fs.existsSync(indexHtmlPath)) {
|
|
84
110
|
console.error(
|
|
85
111
|
"You must run `yarn cedar build web` before trying to prerender."
|
|
@@ -125,7 +151,7 @@ const getTasks = async (dryrun, routerPathFilter = null) => {
|
|
|
125
151
|
}
|
|
126
152
|
];
|
|
127
153
|
}
|
|
128
|
-
return routesToPrerender.
|
|
154
|
+
return routesToPrerender.flatMap((routeToPrerender) => {
|
|
129
155
|
if (routerPathFilter && routeToPrerender.path !== routerPathFilter) {
|
|
130
156
|
return [];
|
|
131
157
|
}
|
|
@@ -160,12 +186,6 @@ const diagnosticCheck = () => {
|
|
|
160
186
|
path.join(getPaths().web.base, "node_modules/react-dom")
|
|
161
187
|
)
|
|
162
188
|
},
|
|
163
|
-
{
|
|
164
|
-
message: "Duplicate core-js version found in web/node_modules",
|
|
165
|
-
failure: fs.existsSync(
|
|
166
|
-
path.join(getPaths().web.base, "node_modules/core-js")
|
|
167
|
-
)
|
|
168
|
-
},
|
|
169
189
|
{
|
|
170
190
|
message: "Duplicate @cedarjs/web version found in web/node_modules",
|
|
171
191
|
failure: fs.existsSync(
|
|
@@ -174,7 +194,7 @@ const diagnosticCheck = () => {
|
|
|
174
194
|
}
|
|
175
195
|
];
|
|
176
196
|
console.log("Running diagnostic checks");
|
|
177
|
-
if (checks.some((
|
|
197
|
+
if (checks.some((check) => check.failure)) {
|
|
178
198
|
console.error(c.error("node_modules are being duplicated in `./web` \n"));
|
|
179
199
|
console.log("\u26A0\uFE0F Issues found: ");
|
|
180
200
|
console.log("-".repeat(50));
|
|
@@ -196,8 +216,11 @@ const diagnosticCheck = () => {
|
|
|
196
216
|
console.log("\u2714 Diagnostics checks passed \n");
|
|
197
217
|
}
|
|
198
218
|
};
|
|
219
|
+
const hasUnexpandedPathParams = (routePath) => {
|
|
220
|
+
return /\{.*}/.test(routePath);
|
|
221
|
+
};
|
|
199
222
|
const prerenderRoute = async (prerenderer, queryCache, routeToPrerender, dryrun, outputHtmlPath) => {
|
|
200
|
-
if (
|
|
223
|
+
if (hasUnexpandedPathParams(routeToPrerender.path)) {
|
|
201
224
|
throw new PathParamError(
|
|
202
225
|
`Could not retrieve route parameters for ${routeToPrerender.path}`
|
|
203
226
|
);
|
|
@@ -207,25 +230,31 @@ const prerenderRoute = async (prerenderer, queryCache, routeToPrerender, dryrun,
|
|
|
207
230
|
queryCache,
|
|
208
231
|
renderPath: routeToPrerender.path
|
|
209
232
|
});
|
|
210
|
-
if (!dryrun) {
|
|
233
|
+
if (!dryrun && typeof prerenderedHtml === "string") {
|
|
211
234
|
prerenderer.writePrerenderedHtmlFile(outputHtmlPath, prerenderedHtml);
|
|
212
235
|
}
|
|
213
|
-
} catch (
|
|
236
|
+
} catch (error) {
|
|
214
237
|
console.log();
|
|
215
238
|
console.log(
|
|
216
239
|
c.warning("You can use `yarn cedar prerender --dry-run` to debug")
|
|
217
240
|
);
|
|
218
241
|
console.log();
|
|
219
|
-
|
|
220
|
-
|
|
242
|
+
const sep = c.info("-".repeat(10));
|
|
243
|
+
console.log(`${sep} Error rendering path "${routeToPrerender.path}" ${sep}`);
|
|
244
|
+
errorTelemetry(
|
|
245
|
+
process.argv,
|
|
246
|
+
`Error prerendering: ${getErrorMessage(error)}`
|
|
221
247
|
);
|
|
222
|
-
|
|
223
|
-
console.error(c.error(e.stack));
|
|
248
|
+
console.error(c.error(getErrorStack(error)));
|
|
224
249
|
console.log();
|
|
225
250
|
throw new Error(`Failed to render "${routeToPrerender.filePath}"`);
|
|
226
251
|
}
|
|
227
252
|
};
|
|
228
|
-
const handler = async ({
|
|
253
|
+
const handler = async ({
|
|
254
|
+
path: routerPath,
|
|
255
|
+
dryRun = false,
|
|
256
|
+
verbose = false
|
|
257
|
+
}) => {
|
|
229
258
|
if (getConfig().experimental?.streamingSsr?.enabled) {
|
|
230
259
|
console.log(
|
|
231
260
|
c.warning(
|
|
@@ -239,7 +268,7 @@ const handler = async ({ path: routerPath, dryRun, verbose }) => {
|
|
|
239
268
|
dryRun,
|
|
240
269
|
verbose
|
|
241
270
|
});
|
|
242
|
-
const listrTasks = await getTasks(dryRun, routerPath);
|
|
271
|
+
const listrTasks = await getTasks(dryRun, routerPath ?? null);
|
|
243
272
|
const tasks = new Listr(listrTasks, {
|
|
244
273
|
renderer: verbose ? "verbose" : "default",
|
|
245
274
|
rendererOptions: { collapseSubtasks: false },
|
|
@@ -250,11 +279,11 @@ const handler = async ({ path: routerPath, dryRun, verbose }) => {
|
|
|
250
279
|
console.log(c.info("::: Dry run, not writing changes :::"));
|
|
251
280
|
}
|
|
252
281
|
await tasks.run();
|
|
253
|
-
} catch (
|
|
282
|
+
} catch (error) {
|
|
254
283
|
console.log();
|
|
255
|
-
|
|
284
|
+
diagnosticCheck();
|
|
256
285
|
console.log(c.warning("Tips:"));
|
|
257
|
-
if (
|
|
286
|
+
if (error instanceof PathParamError) {
|
|
258
287
|
console.log(
|
|
259
288
|
c.info(
|
|
260
289
|
"- You most likely need to add or update a *.routeHooks.{js,ts} file next to the Page you're trying to prerender"
|
|
@@ -263,7 +292,7 @@ const handler = async ({ path: routerPath, dryRun, verbose }) => {
|
|
|
263
292
|
} else {
|
|
264
293
|
console.log(
|
|
265
294
|
c.info(
|
|
266
|
-
|
|
295
|
+
"- This could mean that a library you're using does not support SSR."
|
|
267
296
|
)
|
|
268
297
|
);
|
|
269
298
|
console.log(
|
|
@@ -283,5 +312,6 @@ const handler = async ({ path: routerPath, dryRun, verbose }) => {
|
|
|
283
312
|
};
|
|
284
313
|
export {
|
|
285
314
|
getTasks,
|
|
286
|
-
handler
|
|
315
|
+
handler,
|
|
316
|
+
hasUnexpandedPathParams
|
|
287
317
|
};
|
|
@@ -1,58 +1,81 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "path";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
import boxen from "boxen";
|
|
4
4
|
import execa from "execa";
|
|
5
5
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
6
6
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
7
7
|
import c from "../lib/colors.js";
|
|
8
8
|
import { getPaths } from "../lib/index.js";
|
|
9
|
-
const
|
|
9
|
+
const getErrorMessage = (error) => {
|
|
10
|
+
return error instanceof Error ? error.message : String(error);
|
|
11
|
+
};
|
|
12
|
+
function getExitCode(value) {
|
|
13
|
+
if (!value || typeof value !== "object" || !("exitCode" in value) || typeof value.exitCode !== "number") {
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
return value.exitCode;
|
|
17
|
+
}
|
|
18
|
+
const handler = async ({
|
|
19
|
+
_: _positionals,
|
|
20
|
+
$0: _binName,
|
|
21
|
+
commands = [],
|
|
22
|
+
...options
|
|
23
|
+
}) => {
|
|
10
24
|
recordTelemetryAttributes({
|
|
11
25
|
command: "prisma"
|
|
12
26
|
});
|
|
13
|
-
const
|
|
14
|
-
const
|
|
27
|
+
const cedarPaths = getPaths();
|
|
28
|
+
const args = [...Array.isArray(commands) ? commands : []].filter(
|
|
29
|
+
(value) => typeof value === "string"
|
|
30
|
+
);
|
|
31
|
+
const helpIndex = args.indexOf("help");
|
|
15
32
|
if (helpIndex !== -1) {
|
|
16
33
|
options.help = true;
|
|
17
|
-
|
|
34
|
+
args.splice(helpIndex, 1);
|
|
18
35
|
}
|
|
19
36
|
const hasHelpOption = options.help || options.h;
|
|
20
37
|
if (!hasHelpOption) {
|
|
21
|
-
if (!fs.existsSync(
|
|
38
|
+
if (!fs.existsSync(cedarPaths.api.prismaConfig)) {
|
|
22
39
|
console.error();
|
|
23
40
|
console.error(c.error("No Prisma config file found."));
|
|
24
|
-
console.error(`Cedar searched here '${
|
|
41
|
+
console.error(`Cedar searched here '${cedarPaths.api.prismaConfig}'`);
|
|
25
42
|
console.error();
|
|
26
43
|
process.exit(1);
|
|
27
44
|
}
|
|
28
|
-
options.config = `${
|
|
45
|
+
options.config = `${cedarPaths.api.prismaConfig}`;
|
|
29
46
|
}
|
|
30
|
-
const args = commands;
|
|
31
47
|
for (const [name, value] of Object.entries(options)) {
|
|
32
48
|
args.push(name.length > 1 ? `--${name}` : `-${name}`);
|
|
33
49
|
if (typeof value === "string") {
|
|
34
|
-
value.split(" ").length > 1
|
|
50
|
+
if (value.split(" ").length > 1) {
|
|
51
|
+
args.push(`"${value}"`);
|
|
52
|
+
} else {
|
|
53
|
+
args.push(value);
|
|
54
|
+
}
|
|
35
55
|
} else if (typeof value === "number") {
|
|
36
|
-
args.push(value);
|
|
56
|
+
args.push(String(value));
|
|
37
57
|
}
|
|
38
58
|
}
|
|
39
59
|
console.log();
|
|
40
60
|
console.log(c.note("Running Prisma CLI..."));
|
|
41
|
-
console.log(c.underline(
|
|
61
|
+
console.log(c.underline(`$ yarn prisma ${args.join(" ")}`));
|
|
42
62
|
console.log();
|
|
43
63
|
try {
|
|
44
|
-
const prismaBin = path.join(
|
|
64
|
+
const prismaBin = path.join(cedarPaths.base, "node_modules/.bin/prisma");
|
|
45
65
|
execa.sync(prismaBin, args, {
|
|
46
|
-
cwd:
|
|
66
|
+
cwd: cedarPaths.base,
|
|
47
67
|
stdio: "inherit",
|
|
48
68
|
cleanup: true
|
|
49
69
|
});
|
|
50
|
-
if (hasHelpOption ||
|
|
70
|
+
if (hasHelpOption || args.length === 0) {
|
|
51
71
|
printWrapInfo();
|
|
52
72
|
}
|
|
53
|
-
} catch (
|
|
54
|
-
errorTelemetry(
|
|
55
|
-
|
|
73
|
+
} catch (error) {
|
|
74
|
+
errorTelemetry(
|
|
75
|
+
process.argv,
|
|
76
|
+
`Error generating prisma client: ${getErrorMessage(error)}`
|
|
77
|
+
);
|
|
78
|
+
process.exit(getExitCode(error) ?? 1);
|
|
56
79
|
}
|
|
57
80
|
};
|
|
58
81
|
const printWrapInfo = () => {
|
|
@@ -5,15 +5,15 @@ import { Listr } from "listr2";
|
|
|
5
5
|
import * as toml from "smol-toml";
|
|
6
6
|
import {
|
|
7
7
|
colors as c,
|
|
8
|
-
getPaths,
|
|
9
8
|
isTypeScriptProject,
|
|
10
9
|
getConfigPath
|
|
11
10
|
} from "@cedarjs/cli-helpers";
|
|
11
|
+
import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
|
|
12
12
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
13
13
|
import { printSetupNotes } from "../../../../lib/index.js";
|
|
14
14
|
import { serverFileExists } from "../../../../lib/project.js";
|
|
15
15
|
import { addFilesTask } from "../helpers/index.js";
|
|
16
|
-
const {
|
|
16
|
+
const { getConfig } = prismaInternals;
|
|
17
17
|
const cedarPaths = getPaths();
|
|
18
18
|
const EXTENSION = isTypeScriptProject ? "ts" : "js";
|
|
19
19
|
async function handler({ force }) {
|
|
@@ -58,7 +58,7 @@ async function getAddCoherenceFilesTask(force) {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
async function getCoherenceConfigFileContent() {
|
|
61
|
-
const result = await
|
|
61
|
+
const result = await getPrismaSchemas();
|
|
62
62
|
const prismaConfig = await getConfig({ datamodel: result.schemas });
|
|
63
63
|
let db = prismaConfig.datasources[0].activeProvider;
|
|
64
64
|
if (!SUPPORTED_DATABASES.includes(db)) {
|