@cedarjs/cli 5.0.0-canary.2490 → 5.0.0-canary.2492

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.
@@ -8,6 +8,7 @@ import { env as envInterpolation } from "string-env-interpolation";
8
8
  import { titleCase } from "title-case";
9
9
  import { colors as c } from "@cedarjs/cli-helpers";
10
10
  import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
11
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
11
12
  import { getPaths } from "../../../lib/index.js";
12
13
  const CONFIG_FILENAME = "deploy.toml";
13
14
  const SYMLINK_FLAGS = "-nsf";
@@ -16,7 +17,7 @@ const LIFECYCLE_HOOKS = ["before", "after"];
16
17
  const DEFAULT_SERVER_CONFIG = {
17
18
  port: 22,
18
19
  branch: "main",
19
- packageManagerCommand: "yarn",
20
+ packageManagerCommand: getPackageManager(),
20
21
  monitorCommand: "pm2",
21
22
  sides: ["api", "web"],
22
23
  keepReleases: 5,
@@ -297,17 +298,20 @@ const deployTasks = (yargs, ssh, serverConfig, serverLifecycle) => {
297
298
  title: `DB Migrations...`,
298
299
  task: async () => {
299
300
  await ssh.exec(cmdPath, serverConfig.packageManagerCommand, [
301
+ "exec",
300
302
  "cedar",
301
303
  "prisma",
302
304
  "migrate",
303
305
  "deploy"
304
306
  ]);
305
307
  await ssh.exec(cmdPath, serverConfig.packageManagerCommand, [
308
+ "exec",
306
309
  "cedar",
307
310
  "prisma",
308
311
  "generate"
309
312
  ]);
310
313
  await ssh.exec(cmdPath, serverConfig.packageManagerCommand, [
314
+ "exec",
311
315
  "cedar",
312
316
  "dataMigrate",
313
317
  "up"
@@ -326,6 +330,7 @@ const deployTasks = (yargs, ssh, serverConfig, serverLifecycle) => {
326
330
  title: `Building ${side}...`,
327
331
  task: async () => {
328
332
  await ssh.exec(cmdPath, serverConfig.packageManagerCommand, [
333
+ "exec",
329
334
  "cedar",
330
335
  "build",
331
336
  side
@@ -6,6 +6,7 @@ import {
6
6
  addWebPackages,
7
7
  colors as c
8
8
  } from "@cedarjs/cli-helpers";
9
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
9
10
  import {
10
11
  getConfigPath,
11
12
  getMigrationsPath,
@@ -265,7 +266,7 @@ async function handler({ force, verbose }) {
265
266
  task: () => {
266
267
  if (!hasRealtimeDependency) {
267
268
  throw new Error(
268
- `@cedarjs/realtime is not installed in your api workspace. Please run ${c.highlight("yarn cedar setup realtime")} first.`
269
+ `@cedarjs/realtime is not installed in your api workspace. Please run ${c.highlight(formatCedarCommand(["setup", "realtime"]))} first.`
269
270
  );
270
271
  }
271
272
  }
@@ -408,7 +409,9 @@ async function handler({ force, verbose }) {
408
409
  ${c.success("\nLive query notifications configured!\n")}
409
410
 
410
411
  Apply the migration to activate Postgres notifications:
411
- ${c.highlight("\n\xA0\xA0yarn cedar prisma migrate dev\n")}
412
+ ${c.highlight(`
413
+ \xA0\xA0${formatCedarCommand(["prisma", "migrate", "dev"])}
414
+ `)}
412
415
 
413
416
  You're then ready to use @live queries to get real-time updates as
414
417
  soon as something in your database changes.
@@ -1,6 +1,7 @@
1
- import execa from "execa";
2
1
  import { Listr } from "listr2";
3
2
  import { colors as c } from "@cedarjs/cli-helpers";
3
+ import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
4
+ import { addRootPackages } from "@cedarjs/cli-helpers/packageManager/packages";
4
5
  import { errorTelemetry } from "@cedarjs/telemetry";
5
6
  import { getPaths } from "../../lib/index.js";
6
7
  import { command, description, EXPERIMENTAL_TOPIC_ID } from "./setupInngest.js";
@@ -10,18 +11,16 @@ const handler = async ({ force }) => {
10
11
  {
11
12
  title: `Adding Inngest setup packages for RedwoodJS ...`,
12
13
  task: async () => {
13
- await execa("yarn", ["add", "-D", "inngest-setup-redwoodjs"], {
14
- cwd: getPaths().base
14
+ await addRootPackages(["inngest-setup-redwoodjs"], {
15
+ cwd: getPaths().base,
16
+ dev: true
15
17
  });
16
18
  }
17
19
  },
18
20
  {
19
21
  task: async () => {
20
- const pluginCommands = ["inngest-setup-redwoodjs", "plugin"];
21
- if (force) {
22
- pluginCommands.push("--force");
23
- }
24
- await execa("yarn", [...pluginCommands], {
22
+ const pluginArgs = force ? ["--force"] : [];
23
+ await runBin("inngest-setup-redwoodjs", ["plugin", ...pluginArgs], {
25
24
  stdout: "inherit",
26
25
  cwd: getPaths().base
27
26
  });
@@ -1,9 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
4
- import execa from "execa";
5
4
  import { Listr } from "listr2";
6
5
  import { addApiPackages, colors as c } from "@cedarjs/cli-helpers";
6
+ import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
7
7
  import {
8
8
  getConfigPath,
9
9
  resolveFile,
@@ -170,9 +170,8 @@ const handler = async ({ force, verbose }) => {
170
170
  {
171
171
  title: "Regenerate the Prisma client...",
172
172
  task: (_ctx, _task) => {
173
- return execa(`yarn cedar prisma generate`, {
173
+ return runBin("cedar", ["prisma", "generate"], {
174
174
  stdio: "inherit",
175
- shell: true,
176
175
  cwd: getPaths().web.base
177
176
  });
178
177
  }
@@ -1,9 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import semver from "semver";
6
5
  import { colors as c } from "@cedarjs/cli-helpers";
6
+ import {
7
+ addRootPackages,
8
+ addWorkspacePackages
9
+ } from "@cedarjs/cli-helpers/packageManager/packages";
7
10
  import { getConfigPath } from "@cedarjs/project-config";
8
11
  import { errorTelemetry } from "@cedarjs/telemetry";
9
12
  import { getPaths, writeFile } from "../../lib/index.js";
@@ -81,26 +84,25 @@ const handler = async (options) => {
81
84
  }
82
85
  }
83
86
  },
84
- // We are using two different yarn commands here which is fine because
85
- // they're operating on different workspaces - web and the root
87
+ // We are using two different package manager commands here which is
88
+ // fine because they're operating on different workspaces - web and the
89
+ // root
86
90
  {
87
91
  title: "Installing eslint-plugin-react-compiler",
88
92
  task: async () => {
89
- await execa("yarn", ["add", "-D", "eslint-plugin-react-compiler"], {
90
- cwd: getPaths().base
93
+ await addRootPackages(["eslint-plugin-react-compiler"], {
94
+ cwd: getPaths().base,
95
+ dev: true
91
96
  });
92
97
  }
93
98
  },
94
99
  {
95
100
  title: "Installing babel-plugin-react-compiler",
96
101
  task: async () => {
97
- await execa(
98
- "yarn",
99
- ["web/", "add", "-D", "babel-plugin-react-compiler"],
100
- {
101
- cwd: getPaths().base
102
- }
103
- );
102
+ await addWorkspacePackages("web", ["babel-plugin-react-compiler"], {
103
+ cwd: getPaths().base,
104
+ dev: true
105
+ });
104
106
  }
105
107
  },
106
108
  {
@@ -2,6 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import ansis from "ansis";
4
4
  import { terminalLink } from "termi-link";
5
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
5
6
  import { getPaths } from "../../lib/index.js";
6
7
  import { isTypeScriptProject, serverFileExists } from "../../lib/project.js";
7
8
  function link(topicId, isTerminal = false) {
@@ -41,7 +42,7 @@ function printTaskEpilogue(command, description, topicId) {
41
42
  const isServerFileSetup = () => {
42
43
  if (!serverFileExists()) {
43
44
  throw new Error(
44
- "CedarJS Realtime requires a serverful environment. Please run `yarn cedarjs setup server-file` first."
45
+ `CedarJS Realtime requires a serverful environment. Please run \`${formatCedarCommand(["setup", "server-file"])}\` first.`
45
46
  );
46
47
  }
47
48
  return true;
@@ -56,7 +57,7 @@ const realtimeExists = () => {
56
57
  const isRealtimeSetup = () => {
57
58
  if (!realtimeExists()) {
58
59
  throw new Error(
59
- "Adding realtime events requires that CedarJS Realtime is setup. Please run `yarn cedar setup realtime` first."
60
+ `Adding realtime events requires that CedarJS Realtime is setup. Please run \`${formatCedarCommand(["setup", "realtime"])}\` first.`
60
61
  );
61
62
  }
62
63
  return true;
@@ -1,11 +1,11 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import execa from "execa";
4
3
  import { terminalLink } from "termi-link";
5
4
  import {
6
5
  recordTelemetryAttributes,
7
6
  standardAuthBuilder
8
7
  } from "@cedarjs/cli-helpers";
8
+ import { addRootPackages } from "@cedarjs/cli-helpers/packageManager/packages";
9
9
  import { getPaths } from "../../../lib/index.js";
10
10
  const command = "auth <provider>";
11
11
  const description = "Set up an auth configuration";
@@ -225,7 +225,8 @@ async function getAuthSetupHandler(module) {
225
225
  if (!versionIsPublished) {
226
226
  version = "canary";
227
227
  }
228
- await execa.command(`yarn add -D ${module}@${version}`, {
228
+ await addRootPackages([`${module}@${version}`], {
229
+ dev: true,
229
230
  stdio: "inherit",
230
231
  cwd: getPaths().base
231
232
  });
@@ -8,6 +8,10 @@ import {
8
8
  isTypeScriptProject,
9
9
  getConfigPath
10
10
  } from "@cedarjs/cli-helpers";
11
+ import {
12
+ formatCedarCommand,
13
+ formatRunBinCommand
14
+ } from "@cedarjs/cli-helpers/packageManager/display";
11
15
  import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
12
16
  import { errorTelemetry } from "@cedarjs/telemetry";
13
17
  import { printSetupNotes } from "../../../../lib/index.js";
@@ -74,20 +78,34 @@ async function getCoherenceConfigFileContent() {
74
78
  if (db === "postgresql") {
75
79
  db = "postgres";
76
80
  }
77
- const apiProdCommand = ["yarn", "cedar", "build", "api", "&&"];
81
+ const apiProdCommandSegments = [formatCedarCommand(["build", "api"]), "&&"];
78
82
  if (serverFileExists()) {
79
- apiProdCommand.push(
80
- "yarn",
81
- "node",
82
- "api/dist/server.js",
83
- "--apiRootPath=/api"
83
+ apiProdCommandSegments.push(
84
+ formatRunBinCommand("node", ["api/dist/server.js", "--apiRootPath=/api"])
84
85
  );
85
86
  } else {
86
- apiProdCommand.push("yarn", "cedar", "serve", "api", "--apiRootPath=/api");
87
+ apiProdCommandSegments.push(
88
+ formatCedarCommand(["serve", "api", "--apiRootPath=/api"])
89
+ );
87
90
  }
91
+ const apiDevCommandSegments = [
92
+ formatCedarCommand(["build", "api"]),
93
+ "&&",
94
+ formatCedarCommand(["dev", "api", "--apiRootPath=/api"])
95
+ ];
96
+ const migrationCommandSegments = [
97
+ formatCedarCommand(["prisma", "migrate", "deploy"]),
98
+ "&&",
99
+ formatCedarCommand(["data-migrate", "up"])
100
+ ];
88
101
  return coherenceFiles.yamlTemplate({
89
102
  db,
90
- apiProdCommand: `[${apiProdCommand.map((cmd) => `"${cmd}"`).join(", ")}]`
103
+ apiProdCommand: `[${apiProdCommandSegments.map((cmd) => `"${cmd}"`).join(", ")}]`,
104
+ apiDevCommand: `[${apiDevCommandSegments.map((cmd) => `"${cmd}"`).join(", ")}]`,
105
+ migrationCommand: `[${migrationCommandSegments.map((cmd) => `"${cmd}"`).join(", ")}]`,
106
+ webProdCommand: `["${formatCedarCommand(["serve", "web"])}"]`,
107
+ webDevCommand: `["${formatCedarCommand(["dev", "web", '--fwd=\\"--allowed-hosts all\\"'])}"]`,
108
+ webBuildCommand: `["${formatCedarCommand(["build", "web", "--no-prerender"])}"]`
91
109
  });
92
110
  }
93
111
  const SUPPORTED_DATABASES = ["mysql", "postgresql"];
@@ -145,14 +163,22 @@ const HOST_REGEXP = /host(\s*)=(\s*)\".+\"/g;
145
163
  const API_URL_REGEXP = /apiUrl(\s*)=(\s*)\".+\"/;
146
164
  const PORT_REGEXP = /port(\s*)=(\s*)(?<port>\d{4})/g;
147
165
  const coherenceFiles = {
148
- yamlTemplate({ db, apiProdCommand }) {
166
+ yamlTemplate({
167
+ db,
168
+ apiProdCommand,
169
+ apiDevCommand,
170
+ migrationCommand,
171
+ webProdCommand,
172
+ webDevCommand,
173
+ webBuildCommand
174
+ }) {
149
175
  return `api:
150
176
  type: backend
151
177
  url_path: "/api"
152
178
  prod:
153
179
  command: ${apiProdCommand}
154
180
  dev:
155
- command: ["yarn", "cedar", "build", "api", "&&", "yarn", "cedar", "dev", "api", "--apiRootPath=/api"]
181
+ command: ${apiDevCommand}
156
182
  local_packages: ["node_modules"]
157
183
 
158
184
  system:
@@ -168,20 +194,20 @@ const coherenceFiles = {
168
194
  ${db === "postgres" ? "adapter: postgresql" : ""}
169
195
 
170
196
  # If you use data migrations, use the following instead:
171
- # migration: ["yarn", "cedar", "prisma", "migrate", "deploy", "&&", "yarn", "cedar", "data-migrate", "up"]
172
- migration: ["yarn", "cedar", "prisma", "migrate", "deploy"]
197
+ # migration: ["${formatCedarCommand(["prisma", "migrate", "deploy"])}", "&&", "${formatCedarCommand(["data-migrate", "up"])}"]
198
+ migration: ${migrationCommand}
173
199
 
174
200
  web:
175
201
  type: frontend
176
202
  assets_path: "web/dist"
177
203
  prod:
178
- command: ["yarn", "cedar", "serve", "web"]
204
+ command: ${webProdCommand}
179
205
  dev:
180
- command: ["yarn", "cedar", "dev", "web", "--fwd=\\"--allowed-hosts all\\""]
206
+ command: ${webDevCommand}
181
207
 
182
208
  # Heads up: Redwood's prerender doesn't work with Coherence yet.
183
209
  # For current status and updates, see https://github.com/redwoodjs/redwood/issues/8333.
184
- build: ["yarn", "cedar", "build", "web", "--no-prerender"]
210
+ build: ${webBuildCommand}
185
211
  local_packages: ["node_modules"]
186
212
 
187
213
  system:
@@ -1,3 +1,4 @@
1
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
1
2
  const ECOSYSTEM = `module.exports = {
2
3
  apps: [
3
4
  {
@@ -32,7 +33,7 @@ host = "server.com"
32
33
  username = "user"
33
34
  agentForward = true
34
35
  sides = ["api","web"]
35
- packageManagerCommand = "yarn"
36
+ packageManagerCommand = "${getPackageManager()}"
36
37
  monitorCommand = "pm2"
37
38
  path = "/var/www/app"
38
39
  processNames = ["serve"]
@@ -4,7 +4,10 @@ import path from "node:path";
4
4
  import execa from "execa";
5
5
  import { Listr } from "listr2";
6
6
  import { writeFile, colors as c } from "@cedarjs/cli-helpers";
7
+ import { dedupe } from "@cedarjs/cli-helpers/packageManager";
8
+ import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
7
9
  import { getConfig, getConfigPath, getPaths } from "@cedarjs/project-config";
10
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
8
11
  import { errorTelemetry } from "@cedarjs/telemetry";
9
12
  async function handler({ force }) {
10
13
  const TEMPLATE_DIR = path.join(import.meta.dirname, "templates");
@@ -40,10 +43,17 @@ async function handler({ force }) {
40
43
  [
41
44
  {
42
45
  title: "Adding the official yarn workspace-tools plugin...",
46
+ // The `yarn plugin` commands only exist in yarn. Docker setup is a
47
+ // yarn-specific workflow (workspace-tools plugin has no npm/pnpm
48
+ // equivalent), so we invoke yarn directly here.
43
49
  task: async (_ctx, task) => {
44
- const { stdout } = await execa.command("yarn plugin runtime --json", {
45
- cwd: getPaths().base
46
- });
50
+ const { stdout } = await execa(
51
+ "yarn",
52
+ ["plugin", "runtime", "--json"],
53
+ {
54
+ cwd: getPaths().base
55
+ }
56
+ );
47
57
  const hasWorkspaceToolsPlugin = stdout.trim().split("\n").map(JSON.parse).some(({ name }) => name === "@yarnpkg/plugin-workspace-tools");
48
58
  if (hasWorkspaceToolsPlugin) {
49
59
  task.skip(
@@ -51,7 +61,7 @@ async function handler({ force }) {
51
61
  );
52
62
  return;
53
63
  }
54
- return execa.command("yarn plugin import workspace-tools", {
64
+ return execa("yarn", ["plugin", "import", "workspace-tools"], {
55
65
  cwd: getPaths().base
56
66
  }).stdout;
57
67
  }
@@ -83,25 +93,26 @@ async function handler({ force }) {
83
93
  }
84
94
  if (!hasApiServerPackage) {
85
95
  const apiServerPackageVersion = await getVersionOfRedwoodPackageToInstall(apiServerPackageName);
86
- await execa.command(
87
- `yarn workspace api add ${apiServerPackageName}@${apiServerPackageVersion}`,
88
- {
89
- cwd: getPaths().base
90
- }
96
+ await addWorkspacePackages(
97
+ "api",
98
+ [`${apiServerPackageName}@${apiServerPackageVersion}`],
99
+ { cwd: getPaths().base }
91
100
  );
92
101
  }
93
102
  if (!hasWebServerPackage) {
94
103
  const webServerPackageVersion = await getVersionOfRedwoodPackageToInstall(webServerPackageName);
95
- await execa.command(
96
- `yarn workspace web add ${webServerPackageName}@${webServerPackageVersion}`,
97
- {
98
- cwd: getPaths().base
99
- }
104
+ await addWorkspacePackages(
105
+ "web",
106
+ [`${webServerPackageName}@${webServerPackageVersion}`],
107
+ { cwd: getPaths().base }
100
108
  );
101
109
  }
102
- return execa.command(`yarn dedupe`, {
103
- cwd: getPaths().base
104
- }).stdout;
110
+ const dedupeCommand = dedupe();
111
+ if (dedupeCommand) {
112
+ await execa(getPackageManager(), [dedupeCommand], {
113
+ cwd: getPaths().base
114
+ });
115
+ }
105
116
  }
106
117
  },
107
118
  {
@@ -1,6 +1,5 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import { format } from "prettier";
6
5
  import {
@@ -8,6 +7,7 @@ import {
8
7
  getPrettierOptions,
9
8
  setTomlSetting
10
9
  } from "@cedarjs/cli-helpers";
10
+ import { runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
11
11
  import { getConfig, getPaths } from "@cedarjs/project-config";
12
12
  import { runTransform } from "../../../../../lib/runTransform.js";
13
13
  const command = "fragments";
@@ -34,7 +34,7 @@ async function handler({ force }) {
34
34
  {
35
35
  title: "Generate possibleTypes.ts",
36
36
  task: () => {
37
- execa.commandSync("yarn cedar generate types", { stdio: "ignore" });
37
+ runBinSync("cedar", ["generate", "types"], { stdio: "ignore" });
38
38
  }
39
39
  },
40
40
  {
@@ -1,9 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import { format } from "prettier";
6
5
  import { getPrettierOptions, setTomlSetting } from "@cedarjs/cli-helpers";
6
+ import { runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
7
7
  import { getConfig, getPaths, resolveFile } from "@cedarjs/project-config";
8
8
  import { runTransform } from "../../../../../lib/runTransform.js";
9
9
  async function handler({ force }) {
@@ -28,7 +28,7 @@ async function handler({ force }) {
28
28
  {
29
29
  title: "Generating Trusted Documents store ...",
30
30
  task: () => {
31
- execa.commandSync("yarn cedar generate types", { stdio: "ignore" });
31
+ runBinSync("cedar", ["generate", "types"], { stdio: "ignore" });
32
32
  }
33
33
  },
34
34
  {
@@ -1,9 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import { terminalLink } from "termi-link";
6
5
  import { colors as c } from "@cedarjs/cli-helpers";
6
+ import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
7
7
  import { errorTelemetry } from "@cedarjs/telemetry";
8
8
  import extendStorybookConfiguration from "../../../lib/configureStorybook.js";
9
9
  import { fileIncludes } from "../../../lib/extendFile.js";
@@ -39,14 +39,15 @@ const handler = async ({ force }) => {
39
39
  {
40
40
  title: "Install i18next, react-i18next and i18next-browser-languagedetector",
41
41
  task: async () => {
42
- await execa("yarn", [
43
- "workspace",
42
+ await addWorkspacePackages(
44
43
  "web",
45
- "add",
46
- "i18next",
47
- "react-i18next",
48
- "i18next-browser-languagedetector"
49
- ]);
44
+ [
45
+ "i18next",
46
+ "react-i18next",
47
+ "i18next-browser-languagedetector"
48
+ ],
49
+ { cwd: rwPaths.base }
50
+ );
50
51
  }
51
52
  }
52
53
  ],
@@ -4,6 +4,7 @@ import prismaInternals from "@prisma/internals";
4
4
  import { Listr } from "listr2";
5
5
  import { terminalLink } from "termi-link";
6
6
  import { addApiPackages, colors as c } from "@cedarjs/cli-helpers";
7
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
7
8
  import { getSchemaPath, getPrismaSchemas } from "@cedarjs/project-config";
8
9
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
9
10
  import { isTypeScriptProject } from "../../../lib/project.js";
@@ -97,10 +98,13 @@ const tasks = async ({ force }) => {
97
98
  ${c.success("\nBackground jobs configured!\n")}
98
99
 
99
100
  ${!modelExists ? "Migrate your database to finish setting up jobs:\n" : ""}
100
- ${!modelExists ? c.highlight("\n\xA0\xA0yarn cedar prisma migrate dev\n") : ""}
101
+ ${!modelExists ? c.highlight(`
102
+ \xA0\xA0${formatCedarCommand(["prisma", "migrate", "dev"])}
103
+ `) : ""}
101
104
 
102
- Generate jobs with: ${c.highlight("yarn cedar g job <name>")}
103
- Execute jobs with: ${c.highlight("yarn cedar jobs work\n")}
105
+ Generate jobs with: ${c.highlight(formatCedarCommand(["g", "job", "<name>"]))}
106
+ Execute jobs with: ${c.highlight(`${formatCedarCommand(["jobs", "work"])}
107
+ `)}
104
108
 
105
109
  Check out the docs for more info:
106
110
  ${terminalLink("", "https://cedarjs.com/docs/background-jobs")}
@@ -1,7 +1,7 @@
1
1
  import enq from "enquirer";
2
- import execa from "execa";
3
2
  import semver from "semver";
4
3
  import { getCompatibilityData } from "@cedarjs/cli-helpers";
4
+ import { dlx } from "@cedarjs/cli-helpers/packageManager/exec";
5
5
  import { getPaths } from "@cedarjs/project-config";
6
6
  async function handler({ npmPackage, force, _: _args }) {
7
7
  const isScoped = npmPackage.startsWith("@");
@@ -106,7 +106,7 @@ async function runPackage(packageName, version, options = []) {
106
106
  const versionString = version === void 0 ? "" : `@${version}`;
107
107
  console.log(`Running ${packageName}${versionString}...`);
108
108
  try {
109
- await execa("yarn", ["dlx", `${packageName}${versionString}`, ...options], {
109
+ await dlx(`${packageName}${versionString}`, options, {
110
110
  stdio: "inherit",
111
111
  cwd: getPaths().base
112
112
  });
@@ -1,9 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import prompts from "prompts";
6
5
  import { addApiPackages, colors as c } from "@cedarjs/cli-helpers";
6
+ import { runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
7
7
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
8
8
  import { projectIsEsm } from "@cedarjs/project-config";
9
9
  import { errorTelemetry } from "@cedarjs/telemetry";
@@ -333,9 +333,9 @@ async function handler(args) {
333
333
  getPaths().api.functions,
334
334
  `graphql.${isTypeScriptProject() ? "ts" : "js"}`
335
335
  );
336
- execa.sync(
337
- "yarn",
338
- ["cedar", "lint", "--fix", graphqlHandlerPath, realtimeLibFilePath],
336
+ runBinSync(
337
+ "cedar",
338
+ ["lint", "--fix", graphqlHandlerPath, realtimeLibFilePath],
339
339
  {
340
340
  cwd: getPaths().base,
341
341
  // Silently ignore errors
@@ -1,7 +1,7 @@
1
1
  import path from "path";
2
- import execa from "execa";
3
2
  import { Listr } from "listr2";
4
3
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
4
+ import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
5
5
  import extendStorybookConfiguration from "../../../../lib/configureStorybook.js";
6
6
  import { extendJSXFile, fileIncludes } from "../../../../lib/extendFile.js";
7
7
  import { getPaths, writeFile } from "../../../../lib/index.js";
@@ -34,7 +34,9 @@ async function handler({ force, install }) {
34
34
  {
35
35
  title: `Install ${packages.join(", ")}`,
36
36
  task: async () => {
37
- await execa("yarn", ["workspace", "web", "add", ...packages]);
37
+ await addWorkspacePackages("web", packages, {
38
+ cwd: rwPaths.base
39
+ });
38
40
  }
39
41
  }
40
42
  ],
@@ -1,8 +1,8 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { addWorkspacePackages } from "@cedarjs/cli-helpers/packageManager/packages";
6
6
  import extendStorybookConfiguration from "../../../../lib/configureStorybook.js";
7
7
  import { extendJSXFile, fileIncludes } from "../../../../lib/extendFile.js";
8
8
  import { getPaths, writeFile } from "../../../../lib/index.js";
@@ -51,14 +51,14 @@ async function handler({ force, install, packages }) {
51
51
  {
52
52
  title: `Install ${installPackages.join(", ")}`,
53
53
  task: async () => {
54
- await execa("yarn", [
55
- "workspace",
56
- "web",
57
- "add",
58
- "-D",
59
- "@emotion/react",
60
- ...installPackages
61
- ]);
54
+ await addWorkspacePackages("web", installPackages, {
55
+ cwd: cedarPaths.base,
56
+ dev: true
57
+ });
58
+ await addWorkspacePackages("web", ["@emotion/react"], {
59
+ cwd: cedarPaths.base,
60
+ dev: true
61
+ });
62
62
  }
63
63
  }
64
64
  ],
@@ -5,6 +5,12 @@ import execa from "execa";
5
5
  import { Listr } from "listr2";
6
6
  import { terminalLink } from "termi-link";
7
7
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
8
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
9
+ import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
10
+ import {
11
+ addRootPackages,
12
+ addWorkspacePackages
13
+ } from "@cedarjs/cli-helpers/packageManager/packages";
8
14
  import { errorTelemetry } from "@cedarjs/telemetry";
9
15
  import { getPaths, usingVSCode } from "../../../../lib/index.js";
10
16
  const tailwindDirectives = [
@@ -19,7 +25,7 @@ const tailwindImportsAndNotes = [
19
25
  "/**",
20
26
  " * START --- SETUP TAILWINDCSS EDIT",
21
27
  " *",
22
- " * `yarn cedar setup ui tailwindcss` placed these directives here",
28
+ ` * \`${formatCedarCommand(["setup", "ui", "tailwindcss"])}\` placed these directives here`,
23
29
  " * to inject Tailwind's styles into your CSS.",
24
30
  " * For more information, see: https://tailwindcss.com/docs/installation",
25
31
  " */",
@@ -93,8 +99,9 @@ const handler = async ({ force, install }) => {
93
99
  {
94
100
  title: `Install ${projectPackages.join(", ")}`,
95
101
  task: async () => {
96
- await execa("yarn", ["add", "-D", ...projectPackages], {
97
- cwd: rwPaths.base
102
+ await addRootPackages(projectPackages, {
103
+ cwd: rwPaths.base,
104
+ dev: true
98
105
  });
99
106
  }
100
107
  }
@@ -112,19 +119,16 @@ const handler = async ({ force, install }) => {
112
119
  {
113
120
  title: `Install ${webWorkspacePackages.join(", ")}`,
114
121
  task: async () => {
115
- await execa(
116
- "yarn",
117
- ["workspace", "web", "add", "-D", ...webWorkspacePackages],
118
- {
119
- cwd: rwPaths.base,
120
- env: {
121
- // For some reason yarn started installing deprecated
122
- // typescript types when installing tailwind. This
123
- // prevents it from happening.
124
- YARN_TS_ENABLE_AUTO_TYPES: "false"
125
- }
126
- }
127
- );
122
+ await addWorkspacePackages("web", webWorkspacePackages, {
123
+ cwd: rwPaths.base,
124
+ env: {
125
+ // For some reason yarn started installing deprecated
126
+ // typescript types when installing tailwind. This
127
+ // prevents it from happening. (yarn-only env var.)
128
+ YARN_TS_ENABLE_AUTO_TYPES: "false"
129
+ },
130
+ dev: true
131
+ });
128
132
  }
129
133
  }
130
134
  ],
@@ -169,7 +173,7 @@ const handler = async ({ force, install }) => {
169
173
  );
170
174
  }
171
175
  }
172
- await execa("yarn", ["tailwindcss", "init", tailwindConfigPath], {
176
+ await runBin("tailwindcss", ["init", tailwindConfigPath], {
173
177
  cwd: rwPaths.web.base
174
178
  });
175
179
  const tailwindConfig = fs.readFileSync(tailwindConfigPath, "utf-8");
@@ -8,6 +8,7 @@ import {
8
8
  getPrettierOptions,
9
9
  colors as c
10
10
  } from "@cedarjs/cli-helpers";
11
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
11
12
  import { errorTelemetry } from "@cedarjs/telemetry";
12
13
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
13
14
  import { isTypeScriptProject } from "../../../lib/project.js";
@@ -124,7 +125,7 @@ const handler = async ({ force }) => {
124
125
 
125
126
  ${c.success("\nUploads and storage configured!\n")}
126
127
 
127
- Remember to add UPLOADS_SECRET to your .env file. You can generate one with ${c.highlight("yarn cedar generate secret")}
128
+ Remember to add UPLOADS_SECRET to your .env file. You can generate one with ${c.highlight(formatCedarCommand(["generate", "secret"]))}
128
129
 
129
130
  Check out the docs for more info:
130
131
  ${terminalLink("", "https://cedarjs.com/docs/uploads")}
@@ -2,6 +2,9 @@ import fs from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import path from "node:path";
4
4
  import execa from "execa";
5
+ import { dedupe } from "@cedarjs/cli-helpers/packageManager";
6
+ import { addRootPackages } from "@cedarjs/cli-helpers/packageManager/packages";
7
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
5
8
  import { getPaths } from "./index.js";
6
9
  async function installModule(name, version = void 0) {
7
10
  if (isModuleInstalled(name)) {
@@ -10,7 +13,8 @@ async function installModule(name, version = void 0) {
10
13
  if (version === void 0) {
11
14
  return installCedarModule(name);
12
15
  } else {
13
- await execa.command(`yarn add -D ${name}@${version}`, {
16
+ await addRootPackages([`${name}@${version}`], {
17
+ dev: true,
14
18
  stdio: "inherit",
15
19
  cwd: getPaths().base
16
20
  });
@@ -44,14 +48,18 @@ async function installCedarModule(module) {
44
48
  if (!versionIsPublished) {
45
49
  version = "canary";
46
50
  }
47
- await execa.command(`yarn add -D ${module}@${version}`, {
48
- stdio: "inherit",
49
- cwd: getPaths().base
50
- });
51
- await execa.command(`yarn dedupe`, {
51
+ await addRootPackages([`${module}@${version}`], {
52
+ dev: true,
52
53
  stdio: "inherit",
53
54
  cwd: getPaths().base
54
55
  });
56
+ const dedupeCommand = dedupe();
57
+ if (dedupeCommand) {
58
+ await execa(getPackageManager(), [dedupeCommand], {
59
+ stdio: "inherit",
60
+ cwd: getPaths().base
61
+ });
62
+ }
55
63
  return true;
56
64
  }
57
65
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "5.0.0-canary.2490",
3
+ "version": "5.0.0-canary.2492",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,17 +33,17 @@
33
33
  "dependencies": {
34
34
  "@babel/parser": "7.29.3",
35
35
  "@babel/preset-typescript": "7.28.5",
36
- "@cedarjs/api-server": "5.0.0-canary.2490",
37
- "@cedarjs/cli-helpers": "5.0.0-canary.2490",
38
- "@cedarjs/fastify-web": "5.0.0-canary.2490",
39
- "@cedarjs/internal": "5.0.0-canary.2490",
40
- "@cedarjs/prerender": "5.0.0-canary.2490",
41
- "@cedarjs/project-config": "5.0.0-canary.2490",
42
- "@cedarjs/structure": "5.0.0-canary.2490",
43
- "@cedarjs/telemetry": "5.0.0-canary.2490",
44
- "@cedarjs/utils": "5.0.0-canary.2490",
45
- "@cedarjs/vite": "5.0.0-canary.2490",
46
- "@cedarjs/web-server": "5.0.0-canary.2490",
36
+ "@cedarjs/api-server": "5.0.0-canary.2492",
37
+ "@cedarjs/cli-helpers": "5.0.0-canary.2492",
38
+ "@cedarjs/fastify-web": "5.0.0-canary.2492",
39
+ "@cedarjs/internal": "5.0.0-canary.2492",
40
+ "@cedarjs/prerender": "5.0.0-canary.2492",
41
+ "@cedarjs/project-config": "5.0.0-canary.2492",
42
+ "@cedarjs/structure": "5.0.0-canary.2492",
43
+ "@cedarjs/telemetry": "5.0.0-canary.2492",
44
+ "@cedarjs/utils": "5.0.0-canary.2492",
45
+ "@cedarjs/vite": "5.0.0-canary.2492",
46
+ "@cedarjs/web-server": "5.0.0-canary.2492",
47
47
  "@listr2/prompt-adapter-enquirer": "4.2.1",
48
48
  "@opentelemetry/api": "1.9.1",
49
49
  "@opentelemetry/core": "1.30.1",