@cedarjs/cli 4.2.1-next.0 → 4.2.1-next.269

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.
Files changed (153) hide show
  1. package/dist/cfw.js +8 -6
  2. package/dist/commands/build/buildHandler.js +43 -42
  3. package/dist/commands/build/buildPackagesTask.js +6 -6
  4. package/dist/commands/build.js +7 -1
  5. package/dist/commands/deploy/baremetal/SshExecutor.js +13 -4
  6. package/dist/commands/deploy/baremetal/baremetalHandler.js +117 -65
  7. package/dist/commands/deploy/baremetal.js +24 -3
  8. package/dist/commands/deploy/flightcontrolHandler.js +16 -14
  9. package/dist/commands/deploy/helpers/deployHandler.js +10 -5
  10. package/dist/commands/deploy/packing/nft.js +1 -2
  11. package/dist/commands/deploy/render.js +1 -1
  12. package/dist/commands/deploy/renderHandler.js +22 -12
  13. package/dist/commands/deploy/serverlessHandler.js +67 -25
  14. package/dist/commands/destroy/component/component.js +2 -3
  15. package/dist/commands/destroy/directive/directive.js +1 -3
  16. package/dist/commands/destroy/directive/directiveHandler.js +2 -4
  17. package/dist/commands/destroy/function/function.js +1 -3
  18. package/dist/commands/destroy/handlerHelpers.js +16 -16
  19. package/dist/commands/destroy/helpers.js +8 -2
  20. package/dist/commands/destroy/layout/layout.js +1 -2
  21. package/dist/commands/destroy/page/pageHandler.js +1 -1
  22. package/dist/commands/destroy/scaffold/scaffoldHandler.js +28 -9
  23. package/dist/commands/destroy/sdl/sdlHandler.js +1 -1
  24. package/dist/commands/dev/devHandler.js +25 -25
  25. package/dist/commands/dev.js +3 -0
  26. package/dist/commands/experimental/live-queries/liveQueriesHandler.js +110 -4
  27. package/dist/commands/experimental/setupInngest.js +1 -1
  28. package/dist/commands/experimental/setupInngestHandler.js +12 -11
  29. package/dist/commands/experimental/setupOpentelemetry.js +1 -1
  30. package/dist/commands/experimental/setupOpentelemetryHandler.js +11 -7
  31. package/dist/commands/experimental/setupReactCompiler.js +1 -1
  32. package/dist/commands/experimental/setupReactCompilerHandler.js +45 -30
  33. package/dist/commands/experimental/setupRscHandler.js +14 -11
  34. package/dist/commands/experimental/setupStreamingSsr.js +1 -1
  35. package/dist/commands/experimental/setupStreamingSsrHandler.js +46 -31
  36. package/dist/commands/experimental/templates/rsc/Document.tsx.template +1 -1
  37. package/dist/commands/experimental/templates/rsc/entry.client.tsx.template +8 -8
  38. package/dist/commands/experimental/templates/streamingSsr/Document.tsx.template +1 -1
  39. package/dist/commands/experimental/templates/streamingSsr/entry.client.tsx.template +6 -6
  40. package/dist/commands/experimental/util.js +3 -2
  41. package/dist/commands/generate/cell/cellHandler.js +22 -21
  42. package/dist/commands/generate/component/componentHandler.js +14 -16
  43. package/dist/commands/generate/dataMigration/dataMigration.js +24 -13
  44. package/dist/commands/generate/dbAuth/dbAuth.js +1 -0
  45. package/dist/commands/generate/dbAuth/dbAuthHandler.js +40 -30
  46. package/dist/commands/generate/directive/directiveHandler.js +12 -14
  47. package/dist/commands/generate/function/function.js +1 -0
  48. package/dist/commands/generate/function/functionHandler.js +12 -17
  49. package/dist/commands/generate/helpers.js +17 -17
  50. package/dist/commands/generate/job/job.js +1 -0
  51. package/dist/commands/generate/job/jobHandler.js +15 -17
  52. package/dist/commands/generate/layout/layoutHandler.js +13 -16
  53. package/dist/commands/generate/model/model.js +1 -0
  54. package/dist/commands/generate/model/modelHandler.js +9 -3
  55. package/dist/commands/generate/ogImage/ogImage.js +1 -0
  56. package/dist/commands/generate/ogImage/ogImageHandler.js +16 -9
  57. package/dist/commands/generate/package/packageHandler.js +32 -49
  58. package/dist/commands/generate/page/pageHandler.js +25 -22
  59. package/dist/commands/generate/realtime/realtime.js +1 -1
  60. package/dist/commands/generate/realtime/realtimeHandler.js +46 -20
  61. package/dist/commands/generate/scaffold/scaffold.js +1 -0
  62. package/dist/commands/generate/scaffold/scaffoldHandler.js +35 -27
  63. package/dist/commands/generate/script/script.js +1 -0
  64. package/dist/commands/generate/script/templates/tsconfig.json.template +14 -0
  65. package/dist/commands/generate/sdl/sdl.js +4 -3
  66. package/dist/commands/generate/sdl/sdlHandler.js +38 -18
  67. package/dist/commands/generate/secret/secret.js +19 -19
  68. package/dist/commands/generate/service/service.js +5 -5
  69. package/dist/commands/generate/service/serviceHandler.js +59 -22
  70. package/dist/commands/generate/yargsCommandHelpers.js +6 -1
  71. package/dist/commands/generate/yargsHandlerHelpers.js +18 -10
  72. package/dist/commands/generate.js +3 -10
  73. package/dist/commands/jobsHandler.js +3 -2
  74. package/dist/commands/prismaHandler.js +10 -9
  75. package/dist/commands/serve.js +84 -137
  76. package/dist/commands/serveApiHandler.js +5 -5
  77. package/dist/commands/serveBothHandler.js +10 -7
  78. package/dist/commands/serveWebHandler.js +2 -2
  79. package/dist/commands/setup/auth/auth.js +12 -6
  80. package/dist/commands/setup/cache/cacheHandler.js +11 -6
  81. package/dist/commands/setup/deploy/deploy.js +4 -3
  82. package/dist/commands/setup/deploy/helpers/helpers.js +5 -1
  83. package/dist/commands/setup/deploy/helpers/index.js +157 -5
  84. package/dist/commands/setup/deploy/providers/baremetalHandler.js +26 -4
  85. package/dist/commands/setup/deploy/providers/coherenceHandler.js +53 -25
  86. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +33 -23
  87. package/dist/commands/setup/deploy/providers/netlify.js +6 -0
  88. package/dist/commands/setup/deploy/providers/netlifyHandler.js +112 -11
  89. package/dist/commands/setup/deploy/providers/renderHandler.js +10 -5
  90. package/dist/commands/setup/deploy/providers/serverlessHandler.js +5 -3
  91. package/dist/commands/setup/deploy/providers/universal-deploy.js +11 -0
  92. package/dist/commands/setup/deploy/providers/universalDeployHandler.js +188 -0
  93. package/dist/commands/setup/deploy/providers/vercel.js +6 -0
  94. package/dist/commands/setup/deploy/providers/vercelHandler.js +113 -12
  95. package/dist/commands/setup/deploy/templates/baremetal.js +3 -2
  96. package/dist/commands/setup/deploy/templates/flightcontrol.js +60 -49
  97. package/dist/commands/setup/deploy/templates/netlify.js +2 -1
  98. package/dist/commands/setup/deploy/templates/netlifyUD.js +31 -0
  99. package/dist/commands/setup/docker/docker.js +1 -1
  100. package/dist/commands/setup/docker/dockerHandler.js +72 -37
  101. package/dist/commands/setup/docker/templates/Dockerfile.npm +119 -0
  102. package/dist/commands/setup/docker/templates/Dockerfile.pnpm +112 -0
  103. package/dist/commands/setup/docker/templates/{Dockerfile → Dockerfile.yarn} +1 -1
  104. package/dist/commands/setup/docker/templates/docker-compose.dev.yml +2 -2
  105. package/dist/commands/setup/generator/generatorHandler.js +4 -3
  106. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +2 -2
  107. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +2 -2
  108. package/dist/commands/setup/i18n/i18nHandler.js +18 -15
  109. package/dist/commands/setup/jobs/jobsHandler.js +10 -5
  110. package/dist/commands/setup/mailer/mailerHandler.js +11 -9
  111. package/dist/commands/setup/package/packageHandler.js +14 -10
  112. package/dist/commands/setup/realtime/realtimeHandler.js +22 -20
  113. package/dist/commands/setup/server-file/serverFileHandler.js +16 -8
  114. package/dist/commands/setup/tsconfig/tsconfigHandler.js +5 -3
  115. package/dist/commands/setup/ui/helpers/helpers.js +5 -1
  116. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +11 -5
  117. package/dist/commands/setup/ui/libraries/mantineHandler.js +21 -13
  118. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +38 -26
  119. package/dist/commands/setup/uploads/uploadsHandler.js +7 -4
  120. package/dist/commands/setup.js +1 -2
  121. package/dist/commands/test/testHandler.js +2 -1
  122. package/dist/commands/test/testHandlerEsm.js +2 -2
  123. package/dist/commands/type-checkHandler.js +4 -6
  124. package/dist/commands/upgrade/upgradeHandler.js +2 -4
  125. package/dist/index.js +10 -4
  126. package/dist/lib/configureStorybook.js +2 -2
  127. package/dist/lib/exec.js +36 -24
  128. package/dist/lib/exit.js +19 -4
  129. package/dist/lib/extendFile.js +22 -12
  130. package/dist/lib/index.js +119 -85
  131. package/dist/lib/merge/algorithms.js +4 -1
  132. package/dist/lib/merge/index.js +76 -41
  133. package/dist/lib/merge/semanticIdentity.js +18 -6
  134. package/dist/lib/merge/strategy.js +86 -36
  135. package/dist/lib/packages.js +23 -13
  136. package/dist/lib/plugin.js +12 -5
  137. package/dist/lib/pluralHelpers.js +1 -1
  138. package/dist/lib/project.js +3 -1
  139. package/dist/lib/rollback.js +7 -7
  140. package/dist/lib/schemaHelpers.js +12 -12
  141. package/dist/lib/test.js +4 -0
  142. package/dist/lib/updateCheck.js +6 -4
  143. package/dist/middleware/checkNodeVersion.js +5 -0
  144. package/dist/plugin.js +18 -12
  145. package/dist/telemetry/exporter.js +12 -5
  146. package/dist/telemetry/index.js +4 -3
  147. package/dist/telemetry/resource.js +9 -5
  148. package/dist/telemetry/send.js +14 -10
  149. package/package.json +15 -13
  150. package/dist/commands/setup/vite/templates/vite.config.ts.template +0 -19
  151. package/dist/commands/setup/vite/vite.js +0 -38
  152. package/dist/commands/setup/vite/viteHandler.js +0 -82
  153. /package/dist/{index.d.js → global.d.js} +0 -0
@@ -2,14 +2,17 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
4
4
  import { paramCase, camelCase } from "change-case";
5
- import execa from "execa";
6
5
  import { modify, applyEdits } from "jsonc-parser";
7
6
  import { Listr } from "listr2";
8
7
  import { terminalLink } from "termi-link";
9
8
  import ts from "typescript";
10
9
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
11
10
  import { workspacePackageSpecifier } from "@cedarjs/cli-helpers/packageManager";
11
+ import { runScript, runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
12
+ import { installPackages } from "@cedarjs/cli-helpers/packageManager/packages";
13
+ import { addWorkspaceDir } from "@cedarjs/cli-helpers/packageManager/workspaces";
12
14
  import { getConfig } from "@cedarjs/project-config";
15
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
13
16
  import { errorTelemetry } from "@cedarjs/telemetry";
14
17
  import { getPaths, writeFilesTask } from "../../../lib/index.js";
15
18
  import { prepareForRollback } from "../../../lib/rollback.js";
@@ -60,7 +63,7 @@ async function updateTsconfig(task) {
60
63
  "Failed to parse tsconfig: " + JSON.stringify(error, null, 2)
61
64
  );
62
65
  }
63
- if (!tsconfig?.compilerOptions || typeof tsconfig.compilerOptions.module === "undefined") {
66
+ if (tsconfig.compilerOptions?.module === void 0) {
64
67
  continue;
65
68
  }
66
69
  const currentModule = typeof tsconfig.compilerOptions.module === "string" ? tsconfig.compilerOptions.module.toLowerCase() : String(tsconfig.compilerOptions.module).toLowerCase();
@@ -126,10 +129,8 @@ async function addDependencyToPackageJson(task, packageJsonPath, packageName) {
126
129
  const packageJson = JSON.parse(
127
130
  await fs.promises.readFile(packageJsonPath, "utf8")
128
131
  );
129
- if (!packageJson.dependencies) {
130
- packageJson.dependencies = {};
131
- }
132
- if (packageJson.dependencies[packageName]) {
132
+ packageJson.dependencies ??= {};
133
+ if (packageJson?.dependencies[packageName]) {
133
134
  task.skip("Dependency already exists");
134
135
  return;
135
136
  }
@@ -200,7 +201,7 @@ function updateWorkspaceTsconfigReferences(task, folderName, targetWorkspaces) {
200
201
  readFile: (p) => {
201
202
  try {
202
203
  return fs.readFileSync(p, "utf8");
203
- } catch (e) {
204
+ } catch {
204
205
  return ts.sys.readFile(p);
205
206
  }
206
207
  },
@@ -213,21 +214,21 @@ function updateWorkspaceTsconfigReferences(task, folderName, targetWorkspaces) {
213
214
  },
214
215
  path.dirname(ws.tsconfigPath)
215
216
  );
216
- if (configParseResult.errors && configParseResult.errors.length) {
217
+ if (configParseResult.errors?.length) {
217
218
  console.error("Parse errors:", configParseResult.errors);
218
219
  }
219
220
  if (!Array.isArray(tsconfig.references)) {
220
221
  tsconfig.references = [];
221
222
  }
222
- const packageDir2 = ws.packageDir || path.join(getPaths().base, "packages", folderName);
223
- const referencePath = path.relative(path.dirname(ws.tsconfigPath), packageDir2).split(path.sep).join("/");
223
+ const wsPackageDir = ws.packageDir || path.join(getPaths().base, "packages", folderName);
224
+ const referencePath = path.relative(path.dirname(ws.tsconfigPath), wsPackageDir).split(path.sep).join("/");
224
225
  const references = tsconfig.references;
225
- if (references.some((ref) => ref && ref.path === referencePath)) {
226
+ if (references.some((ref) => ref?.path === referencePath)) {
226
227
  subtask.skip("tsconfig already up to date");
227
228
  return;
228
229
  }
229
230
  const newReferences = references.concat([{ path: referencePath }]);
230
- let text = await fs.promises.readFile(ws.tsconfigPath, "utf8");
231
+ const text = await fs.promises.readFile(ws.tsconfigPath, "utf8");
231
232
  const edits = modify(text, ["references"], newReferences, {
232
233
  formattingOptions: { insertSpaces: true, tabSize: 2 }
233
234
  });
@@ -244,14 +245,18 @@ function updateWorkspaceTsconfigReferences(task, folderName, targetWorkspaces) {
244
245
  }
245
246
  async function installAndBuild(folderName) {
246
247
  const packagePath = path.join("packages", folderName);
247
- await execa("yarn", ["install"], { stdio: "inherit", cwd: getPaths().base });
248
- await execa("yarn", ["build"], { stdio: "inherit", cwd: packagePath });
248
+ await installPackages({ stdio: "inherit", cwd: getPaths().base });
249
+ await runScript("build", [], { stdio: "inherit", cwd: packagePath });
249
250
  }
250
- const handler = async ({ name, force, ...rest }) => {
251
+ const handler = async ({
252
+ name,
253
+ force,
254
+ ...rest
255
+ }) => {
251
256
  recordTelemetryAttributes({
252
257
  command: "generate package",
253
258
  force,
254
- rollback: rest.rollback
259
+ rollback: typeof rest.rollback === "boolean" ? rest.rollback : void 0
255
260
  });
256
261
  if (name.replaceAll("/", "").length < name.length - 1) {
257
262
  throw new Error(
@@ -272,7 +277,6 @@ const handler = async ({ name, force, ...rest }) => {
272
277
  }
273
278
  let packageFiles = {};
274
279
  const tasks = new Listr(
275
- /** @type {import('listr2').ListrTask<ListrContext>[]} */
276
280
  [
277
281
  {
278
282
  title: "Parsing package name...",
@@ -282,34 +286,12 @@ const handler = async ({ name, force, ...rest }) => {
282
286
  },
283
287
  {
284
288
  title: "Updating workspace config...",
285
- task: async (ctx, task) => {
286
- const rootPackageJsonPath = path.join(getPaths().base, "package.json");
287
- const packageJson = JSON.parse(
288
- await fs.promises.readFile(rootPackageJsonPath, "utf8")
289
- );
290
- if (!Array.isArray(packageJson.workspaces)) {
291
- throw new Error(
292
- "Invalid workspace config in " + rootPackageJsonPath
293
- );
294
- }
289
+ task: (ctx, task) => {
290
+ const pm = getPackageManager();
295
291
  const packagePath = `packages/${ctx.nameVariants.folderName}`;
296
- const hasWildcardPackagesWorkspace = packageJson.workspaces.includes("packages/*");
297
- const hasNamedPackagesWorkspace = packageJson.workspaces.includes(packagePath);
298
- const hasOtherNamedPackages = packageJson.workspaces.some(
299
- (workspace) => workspace.startsWith("packages/") && workspace !== packagePath
300
- );
301
- if (hasWildcardPackagesWorkspace || hasNamedPackagesWorkspace) {
292
+ const result = addWorkspaceDir(getPaths().base, packagePath, pm);
293
+ if (result === "exists") {
302
294
  task.skip("Workspaces already configured");
303
- } else {
304
- if (hasOtherNamedPackages) {
305
- packageJson.workspaces.push(packagePath);
306
- } else {
307
- packageJson.workspaces.push("packages/*");
308
- }
309
- await fs.promises.writeFile(
310
- rootPackageJsonPath,
311
- JSON.stringify(packageJson, null, 2)
312
- );
313
295
  }
314
296
  }
315
297
  },
@@ -326,7 +308,7 @@ const handler = async ({ name, force, ...rest }) => {
326
308
  return;
327
309
  }
328
310
  } catch (e) {
329
- throw new Error(e.message);
311
+ throw new Error(e instanceof Error ? e.message : String(e));
330
312
  }
331
313
  const prompt = task.prompt(ListrEnquirerPromptAdapter);
332
314
  const response = await prompt.run({
@@ -425,8 +407,7 @@ const handler = async ({ name, force, ...rest }) => {
425
407
  {
426
408
  title: "Cleaning up...",
427
409
  task: () => {
428
- execa.sync("yarn", [
429
- "eslint",
410
+ runBinSync("eslint", [
430
411
  "--fix",
431
412
  "--config",
432
413
  `${getPaths().base}/node_modules/@cedarjs/eslint-config/index.js`,
@@ -443,9 +424,11 @@ const handler = async ({ name, force, ...rest }) => {
443
424
  }
444
425
  await tasks.run();
445
426
  } catch (e) {
446
- errorTelemetry(process.argv, e.message);
447
- console.error(c.error(e.message));
448
- process.exit(e?.exitCode || 1);
427
+ const msg = e instanceof Error ? e.message : String(e);
428
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
429
+ errorTelemetry(process.argv, msg);
430
+ console.error(c.error(msg));
431
+ process.exit(exitCode);
449
432
  }
450
433
  };
451
434
  export {
@@ -8,7 +8,7 @@ import { getConfig } from "@cedarjs/project-config";
8
8
  import { errorTelemetry } from "@cedarjs/telemetry";
9
9
  import {
10
10
  addRoutesToRouterTask,
11
- transformTSToJS,
11
+ transformTSToJSMap,
12
12
  writeFilesTask
13
13
  } from "../../../lib/index.js";
14
14
  import {
@@ -23,8 +23,8 @@ import {
23
23
  } from "../helpers.js";
24
24
  import { templateForComponentFile } from "../yargsHandlerHelpers.js";
25
25
  const COMPONENT_SUFFIX = "Page";
26
- const REDWOOD_WEB_PATH_NAME = "pages";
27
- const mapRouteParamTypeToDefaultValue = (paramType) => {
26
+ const CEDAR_WEB_PATH_NAME = "pages";
27
+ function mapRouteParamTypeToDefaultValue(paramType) {
28
28
  switch (paramType) {
29
29
  case "Int":
30
30
  return 42;
@@ -35,7 +35,7 @@ const mapRouteParamTypeToDefaultValue = (paramType) => {
35
35
  default:
36
36
  return "42";
37
37
  }
38
- };
38
+ }
39
39
  const paramVariants = (path) => {
40
40
  const param = path?.match(/(\{[\w:]+\})/)?.[1];
41
41
  const paramName = param?.replace(/:[^}]+/, "").slice(1, -1);
@@ -62,13 +62,19 @@ const paramVariants = (path) => {
62
62
  paramType: mapRouteParamTypeToTsType(routeParamType)
63
63
  };
64
64
  };
65
- const files = async ({ name, tests, stories, typescript, ...rest }) => {
65
+ const files = async ({
66
+ name,
67
+ tests,
68
+ stories,
69
+ typescript = false,
70
+ ...rest
71
+ }) => {
66
72
  const extension = typescript ? ".tsx" : ".jsx";
67
73
  const pageFile = await templateForComponentFile({
68
74
  name,
69
75
  suffix: COMPONENT_SUFFIX,
70
76
  extension,
71
- webPathSection: REDWOOD_WEB_PATH_NAME,
77
+ webPathSection: CEDAR_WEB_PATH_NAME,
72
78
  generator: "page",
73
79
  templatePath: "page.tsx.template",
74
80
  templateVars: {
@@ -80,7 +86,7 @@ const files = async ({ name, tests, stories, typescript, ...rest }) => {
80
86
  name,
81
87
  suffix: COMPONENT_SUFFIX,
82
88
  extension: `.test${extension}`,
83
- webPathSection: REDWOOD_WEB_PATH_NAME,
89
+ webPathSection: CEDAR_WEB_PATH_NAME,
84
90
  generator: "page",
85
91
  templatePath: "test.tsx.template",
86
92
  templateVars: rest
@@ -89,7 +95,7 @@ const files = async ({ name, tests, stories, typescript, ...rest }) => {
89
95
  name,
90
96
  suffix: COMPONENT_SUFFIX,
91
97
  extension: `.stories${extension}`,
92
- webPathSection: REDWOOD_WEB_PATH_NAME,
98
+ webPathSection: CEDAR_WEB_PATH_NAME,
93
99
  generator: "page",
94
100
  templatePath: rest.paramName !== "" ? "stories.tsx.parameters.template" : "stories.tsx.template",
95
101
  templateVars: rest
@@ -101,16 +107,12 @@ const files = async ({ name, tests, stories, typescript, ...rest }) => {
101
107
  if (stories) {
102
108
  files2.push(storiesFile);
103
109
  }
104
- return files2.reduce(async (accP, [outputPath, content]) => {
105
- const acc = await accP;
106
- const template = typescript ? content : await transformTSToJS(outputPath, content);
107
- return {
108
- [outputPath]: template,
109
- ...acc
110
- };
111
- }, Promise.resolve({}));
110
+ return transformTSToJSMap(files2, typescript);
112
111
  };
113
- const routes = ({ name, path }) => {
112
+ const routes = ({
113
+ name,
114
+ path
115
+ }) => {
114
116
  return [
115
117
  `<Route path="${path}" page={${pascalcase(name)}Page} name="${camelcase(
116
118
  name
@@ -159,7 +161,6 @@ const handler = async ({
159
161
  path = pathName(path, pageName);
160
162
  const f = await files({
161
163
  name: pageName,
162
- path,
163
164
  tests,
164
165
  stories,
165
166
  typescript,
@@ -191,7 +192,7 @@ const handler = async ({
191
192
  },
192
193
  {
193
194
  title: "One more thing...",
194
- task: (ctx, task) => {
195
+ task: (_ctx, task) => {
195
196
  task.title = `One more thing...
196
197
 
197
198
  ${c.warning("Page created! A note about <Metadata>:")}
@@ -213,9 +214,11 @@ const handler = async ({
213
214
  }
214
215
  await tasks.run();
215
216
  } catch (e) {
216
- errorTelemetry(process.argv, e.message);
217
- console.error(c.error(e.message));
218
- process.exit(e?.exitCode || 1);
217
+ const message = e instanceof Error ? e.message : String(e);
218
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
219
+ errorTelemetry(process.argv, message);
220
+ console.error(c.error(message));
221
+ process.exit(exitCode);
219
222
  }
220
223
  };
221
224
  export {
@@ -2,7 +2,7 @@ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
2
2
  const command = "realtime <name>";
3
3
  const description = "Generate a subscription or live query used with RedwoodJS Realtime";
4
4
  function builder(yargs) {
5
- yargs.positional("name", {
5
+ return yargs.positional("name", {
6
6
  type: "string",
7
7
  description: "Name of the realtime event to setup. This should be a type or model name like: Widget, Sprocket, etc.",
8
8
  demandOption: true
@@ -35,8 +35,14 @@ const templateVariables = (name) => {
35
35
  subscriptionServiceResolver: `publishTo${pascalcase(name)}Channel`
36
36
  };
37
37
  };
38
- async function handler({ name, type, force, verbose, silent }) {
39
- const redwoodPaths = getPaths();
38
+ async function handler({
39
+ name,
40
+ type,
41
+ force,
42
+ verbose,
43
+ silent
44
+ }) {
45
+ const cedarPaths = getPaths();
40
46
  const ts = isTypeScriptProject();
41
47
  name = pluralize.singular(name.toLowerCase());
42
48
  let functionType = type;
@@ -60,12 +66,13 @@ async function handler({ name, type, force, verbose, silent }) {
60
66
  });
61
67
  functionType = response.functionType;
62
68
  }
63
- const tasks = new Listr(
64
- [
69
+ function buildTaskData() {
70
+ return [
65
71
  {
66
72
  title: "Checking for realtime environment prerequisites ...",
67
73
  task: () => {
68
- isServerFileSetup() && isRealtimeSetup();
74
+ isServerFileSetup();
75
+ isRealtimeSetup();
69
76
  }
70
77
  },
71
78
  {
@@ -80,7 +87,7 @@ async function handler({ name, type, force, verbose, silent }) {
80
87
  `blank.sdl.ts.template`
81
88
  );
82
89
  const sdlFile = path.join(
83
- redwoodPaths.api.graphql,
90
+ cedarPaths.api.graphql,
84
91
  `${name}.sdl.${isTypeScriptProject() ? "ts" : "js"}`
85
92
  );
86
93
  const sdlContent = ts ? exampleSdlTemplateContent : await transformTSToJS(sdlFile, exampleSdlTemplateContent);
@@ -92,7 +99,7 @@ async function handler({ name, type, force, verbose, silent }) {
92
99
  `blank.service.ts.template`
93
100
  );
94
101
  const serviceFile = path.join(
95
- redwoodPaths.api.services,
102
+ cedarPaths.api.services,
96
103
  `${name}`,
97
104
  `${name}.${isTypeScriptProject() ? "ts" : "js"}`
98
105
  );
@@ -105,7 +112,7 @@ async function handler({ name, type, force, verbose, silent }) {
105
112
  `blank.ts.template`
106
113
  );
107
114
  const exampleFile = path.join(
108
- redwoodPaths.api.subscriptions,
115
+ cedarPaths.api.subscriptions,
109
116
  `${name}`,
110
117
  `${name}.${isTypeScriptProject() ? "ts" : "js"}`
111
118
  );
@@ -156,7 +163,7 @@ async function handler({ name, type, force, verbose, silent }) {
156
163
  `blank.sdl.ts.template`
157
164
  );
158
165
  const sdlFile = path.join(
159
- redwoodPaths.api.graphql,
166
+ cedarPaths.api.graphql,
160
167
  `${name}.sdl.${isTypeScriptProject() ? "ts" : "js"}`
161
168
  );
162
169
  const sdlContent = ts ? exampleSdlTemplateContent : await transformTSToJS(sdlFile, exampleSdlTemplateContent);
@@ -168,7 +175,7 @@ async function handler({ name, type, force, verbose, silent }) {
168
175
  "blank.service.ts.template"
169
176
  );
170
177
  const serviceFile = path.join(
171
- redwoodPaths.api.services,
178
+ cedarPaths.api.services,
172
179
  `${name}`,
173
180
  `${name}.${isTypeScriptProject() ? "ts" : "js"}`
174
181
  );
@@ -200,18 +207,37 @@ async function handler({ name, type, force, verbose, silent }) {
200
207
  );
201
208
  }
202
209
  }
203
- ],
204
- {
205
- rendererOptions: { collapseSubtasks: false, persistentOutput: true },
206
- renderer: silent ? "silent" : verbose ? "verbose" : "default"
207
- }
208
- );
210
+ ];
211
+ }
209
212
  try {
210
- await tasks.run();
213
+ if (silent) {
214
+ await new Listr(buildTaskData(), {
215
+ exitOnError: true,
216
+ renderer: "silent"
217
+ }).run();
218
+ } else if (verbose) {
219
+ await new Listr(buildTaskData(), {
220
+ exitOnError: true,
221
+ renderer: "verbose"
222
+ }).run();
223
+ } else {
224
+ await new Listr(
225
+ buildTaskData().map((t) => ({
226
+ ...t,
227
+ rendererOptions: { persistentOutput: true }
228
+ })),
229
+ {
230
+ exitOnError: true,
231
+ rendererOptions: { collapseSubtasks: false }
232
+ }
233
+ ).run();
234
+ }
211
235
  } catch (e) {
212
- errorTelemetry(process.argv, e.message);
213
- console.error(c.error(e.message));
214
- process.exit(e?.exitCode || 1);
236
+ const message = e instanceof Error ? e.message : String(e);
237
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
238
+ errorTelemetry(process.argv, message);
239
+ console.error(c.error(message));
240
+ process.exit(exitCode);
215
241
  }
216
242
  }
217
243
  export {
@@ -28,6 +28,7 @@ const builder = (yargs) => {
28
28
  Object.entries(getYargsDefaults()).forEach(([option, config]) => {
29
29
  yargs.option(option, config);
30
30
  });
31
+ return yargs;
31
32
  };
32
33
  const handler = createHandler("scaffold");
33
34
  export {
@@ -2,11 +2,14 @@ import fs from "node:fs";
2
2
  import path from "path";
3
3
  import camelcase from "camelcase";
4
4
  import { paramCase } from "change-case";
5
- import execa from "execa";
6
5
  import humanize from "humanize-string";
7
6
  import { Listr } from "listr2";
8
7
  import pascalcase from "pascalcase";
9
8
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
9
+ import {
10
+ addWorkspacePackages,
11
+ removeWorkspacePackages
12
+ } from "@cedarjs/cli-helpers/packageManager/packages";
10
13
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
11
14
  import { getConfig } from "@cedarjs/project-config";
12
15
  import { pluralize, singularize } from "@cedarjs/utils/cedarPluralize";
@@ -47,7 +50,7 @@ const getIdName = (model) => {
47
50
  };
48
51
  const isAutoGeneratedColumnForScaffold = (column) => {
49
52
  const autoGeneratedFunctions = ["now", "autoincrement"];
50
- const columnDefaultFunction = typeof column.default === "object" && "name" in column.default ? column.default?.name : "";
53
+ const columnDefaultFunction = typeof column.default === "object" && column.default !== null && "name" in column.default ? column.default.name : "";
51
54
  return column.isId || column.isUpdatedAt || column.name === "createdAt" || autoGeneratedFunctions.includes(columnDefaultFunction);
52
55
  };
53
56
  const getImportComponentNames = (name, scaffoldPath, nestScaffoldByModel = true) => {
@@ -146,7 +149,7 @@ const files = async ({
146
149
  };
147
150
  };
148
151
  const assetFiles = async (name, tailwind) => {
149
- let fileList = {};
152
+ const fileList = {};
150
153
  const assets = fs.readdirSync(
151
154
  customOrDefaultTemplatePath({
152
155
  side: "web",
@@ -268,17 +271,19 @@ const modelRelatedVariables = (model) => {
268
271
  listDisplayFunction: "truncate"
269
272
  }
270
273
  };
271
- const relations = relationsForModel(model).map((relation) => relation);
274
+ const relations = relationsForModel(model)?.map((relation) => relation);
272
275
  const columns = model.fields.filter((field) => field.kind !== "object").map((column) => {
273
276
  let validation;
274
- if (componentMetadata[column.type]?.validation) {
275
- validation = componentMetadata[column.type]?.validation(
276
- column?.isRequired
277
- );
277
+ const meta = componentMetadata[column.type];
278
+ const validationDef = meta?.validation;
279
+ if (typeof validationDef === "function") {
280
+ validation = validationDef(column.isRequired);
281
+ } else if (validationDef !== void 0) {
282
+ validation = column.isRequired ? validationDef : null;
278
283
  } else {
279
- validation = column?.isRequired ? componentMetadata.default.validation : null;
284
+ validation = column.isRequired ? componentMetadata.default.validation : null;
280
285
  }
281
- const isRelationalField = column.name.endsWith("Id") && relations.some((relation) => column.name.includes(relation));
286
+ const isRelationalField = column.name.endsWith("Id") && relations?.some((relation) => column.name.includes(relation));
282
287
  const isRequired = column.isRequired;
283
288
  const isEnum = column.kind === "enum";
284
289
  const isList = column.isList;
@@ -305,7 +310,9 @@ const modelRelatedVariables = (model) => {
305
310
  );
306
311
  const fieldsToImport = Object.keys(
307
312
  editableColumns.reduce((accumulator, column) => {
308
- accumulator[column.component] = true;
313
+ if (column.component) {
314
+ accumulator[column.component] = true;
315
+ }
309
316
  return accumulator;
310
317
  }, {})
311
318
  );
@@ -323,7 +330,7 @@ const modelRelatedVariables = (model) => {
323
330
  };
324
331
  };
325
332
  const layoutFiles = async (name, force, generateTypescript, templateStrings) => {
326
- let fileList = {};
333
+ const fileList = {};
327
334
  const layouts = fs.readdirSync(
328
335
  customOrDefaultTemplatePath({
329
336
  side: "web",
@@ -366,7 +373,7 @@ const pageFiles = async (name, pascalScaffoldPath = "", generateTypescript, nest
366
373
  const idType = getIdType(model);
367
374
  const idTsType = mapPrismaScalarToPagePropTsType(idType);
368
375
  const idName = getIdName(model);
369
- let fileList = {};
376
+ const fileList = {};
370
377
  const pages = fs.readdirSync(
371
378
  customOrDefaultTemplatePath({
372
379
  side: "web",
@@ -408,9 +415,9 @@ const componentFiles = async (name, pascalScaffoldPath = "", generateTypescript,
408
415
  const model = await getSchema(singularName);
409
416
  const idType = getIdType(model);
410
417
  const idName = getIdName(model);
411
- const pascalIdName = pascalcase(idName);
418
+ const pascalIdName = pascalcase(idName ?? "");
412
419
  const intForeignKeys = intForeignKeysForModel(model);
413
- let fileList = {};
420
+ const fileList = {};
414
421
  const components = fs.readdirSync(
415
422
  customOrDefaultTemplatePath({
416
423
  side: "web",
@@ -500,18 +507,18 @@ const addHelperPackages = async (task) => {
500
507
  if (packageJson.default.dependencies["humanize-string"]) {
501
508
  return task.skip("Skipping. Already installed");
502
509
  }
503
- await execa("yarn", ["workspace", "web", "add", "humanize-string@2.1.0"]);
510
+ await addWorkspacePackages("web", ["humanize-string@2.1.0"]);
504
511
  addFunctionToRollback(async () => {
505
- await execa("yarn", ["workspace", "web", "remove", "humanize-string"]);
512
+ await removeWorkspacePackages("web", ["humanize-string"]);
506
513
  });
507
514
  };
508
515
  const addSetImport = (task) => {
509
516
  const routesPath = getPaths().web.routes;
510
517
  const routesContent = readFile(routesPath).toString();
511
- const [redwoodRouterImport, importStart, spacing, importContent, importEnd] = routesContent.match(
518
+ const [cedarRouterImport, importStart, spacing, importContent, importEnd] = routesContent.match(
512
519
  /(import {)(\s*)([^]*)(} from ['"]@cedarjs\/router['"])/
513
520
  ) || [];
514
- if (!redwoodRouterImport) {
521
+ if (!cedarRouterImport) {
515
522
  task.skip(
516
523
  "Couldn't add Set import from @cedarjs/router to Routes.{jsx,tsx}"
517
524
  );
@@ -522,21 +529,21 @@ const addSetImport = (task) => {
522
529
  return "Skipping Set import";
523
530
  }
524
531
  const newRoutesContent = routesContent.replace(
525
- redwoodRouterImport,
532
+ cedarRouterImport,
526
533
  importStart + spacing + PACKAGE_SET + `,` + spacing + importContent + importEnd
527
534
  );
528
535
  writeFile(routesPath, newRoutesContent, { overwriteExisting: true });
529
536
  return "Added Set import to Routes.{jsx,tsx}";
530
537
  };
531
- const addScaffoldSetToRouter = async (model, path2) => {
532
- const templateNames = getTemplateStrings(model, path2);
538
+ const addScaffoldSetToRouter = async (model, scaffoldPath) => {
539
+ const templateNames = getTemplateStrings(model, scaffoldPath);
533
540
  const nameVars = nameVariants(model);
534
541
  const title = nameVars.pluralPascalName;
535
542
  const titleTo = templateNames.pluralRouteName;
536
543
  const buttonLabel = `New ${nameVars.singularPascalName}`;
537
544
  const buttonTo = templateNames.newRouteName;
538
545
  return addRoutesToRouterTask(
539
- await routes({ model, path: path2 }),
546
+ await routes({ model, path: scaffoldPath }),
540
547
  "ScaffoldLayout",
541
548
  { title, titleTo, buttonLabel, buttonTo }
542
549
  );
@@ -548,7 +555,7 @@ const tasks = ({
548
555
  force,
549
556
  tests,
550
557
  typescript,
551
- javascript,
558
+ javascript: _javascript,
552
559
  tailwind
553
560
  }) => {
554
561
  return new Listr(
@@ -562,7 +569,6 @@ const tasks = ({
562
569
  path: path2,
563
570
  tests,
564
571
  typescript,
565
- javascript,
566
572
  tailwind,
567
573
  force
568
574
  });
@@ -645,8 +651,10 @@ const handler = async ({
645
651
  }
646
652
  await t.run();
647
653
  } catch (e) {
648
- console.log(c.error(e.message));
649
- process.exit(e?.existCode || 1);
654
+ const message = e instanceof Error ? e.message : String(e);
655
+ const exitCode = e instanceof Error && "exitCode" in e ? e.exitCode ?? 1 : 1;
656
+ console.log(c.error(message));
657
+ process.exit(exitCode);
650
658
  }
651
659
  };
652
660
  const splitPathAndModel = (pathSlashModel) => {
@@ -19,6 +19,7 @@ const builder = (yargs) => {
19
19
  Object.entries(getYargsDefaults()).forEach(([option, config]) => {
20
20
  yargs.option(option, config);
21
21
  });
22
+ return yargs;
22
23
  };
23
24
  const handler = createHandler("script");
24
25
  export {
@@ -4,6 +4,12 @@
4
4
  "allowJs": true,
5
5
  "esModuleInterop": true,
6
6
  "baseUrl": "./",
7
+ "rootDirs": [
8
+ "../api/src",
9
+ "../.cedar/types/mirror/api/src",
10
+ "../web/src",
11
+ "../.cedar/types/mirror/web/src"
12
+ ],
7
13
  "paths": {
8
14
  "$api/*": [
9
15
  "../api/*",
@@ -11,6 +17,14 @@
11
17
  "api/*": [
12
18
  "../api/*",
13
19
  ],
20
+ "$api/src/*": [
21
+ "../api/src/*",
22
+ "../.cedar/types/mirror/api/src/*"
23
+ ],
24
+ "api/src/*": [
25
+ "../api/src/*",
26
+ "../.cedar/types/mirror/api/src/*"
27
+ ],
14
28
  "$web/*": [
15
29
  "../web/*",
16
30
  ],