@cedarjs/cli 5.0.0-canary.2564 → 5.0.0-canary.2565

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.
@@ -69,7 +69,6 @@ function getPostInstallWebauthnMessage(isDbAuthSetup2) {
69
69
  ].filter(Boolean).join("\n");
70
70
  }
71
71
  const files = async ({
72
- _tests,
73
72
  typescript,
74
73
  skipForgot,
75
74
  skipLogin,
@@ -79,7 +78,7 @@ const files = async ({
79
78
  usernameLabel,
80
79
  passwordLabel
81
80
  }) => {
82
- const files2 = [];
81
+ const filesList = [];
83
82
  usernameLabel = usernameLabel || "username";
84
83
  passwordLabel = passwordLabel || "password";
85
84
  const templateVars = {
@@ -91,7 +90,7 @@ const files = async ({
91
90
  passwordTitleCase: titleCase(passwordLabel)
92
91
  };
93
92
  if (!skipForgot) {
94
- files2.push(
93
+ filesList.push(
95
94
  await templateForComponentFile({
96
95
  name: "ForgotPassword",
97
96
  suffix: "Page",
@@ -104,7 +103,7 @@ const files = async ({
104
103
  );
105
104
  }
106
105
  if (!skipLogin) {
107
- files2.push(
106
+ filesList.push(
108
107
  await templateForComponentFile({
109
108
  name: "Login",
110
109
  suffix: "Page",
@@ -117,7 +116,7 @@ const files = async ({
117
116
  );
118
117
  }
119
118
  if (!skipReset) {
120
- files2.push(
119
+ filesList.push(
121
120
  await templateForComponentFile({
122
121
  name: "ResetPassword",
123
122
  suffix: "Page",
@@ -130,7 +129,7 @@ const files = async ({
130
129
  );
131
130
  }
132
131
  if (!skipSignup) {
133
- files2.push(
132
+ filesList.push(
134
133
  await templateForComponentFile({
135
134
  name: "Signup",
136
135
  suffix: "Page",
@@ -142,7 +141,7 @@ const files = async ({
142
141
  })
143
142
  );
144
143
  }
145
- if (files2.length === 0) {
144
+ if (filesList.length === 0) {
146
145
  console.info(c.error("\nNo files to generate.\n"));
147
146
  process.exit(0);
148
147
  }
@@ -155,25 +154,27 @@ const files = async ({
155
154
  ),
156
155
  { name: "scaffold" }
157
156
  );
158
- files2.push([scaffoldOutputPath, scaffoldTemplate]);
157
+ filesList.push([scaffoldOutputPath, scaffoldTemplate]);
159
158
  }
160
- return files2.reduce(async (accP, [outputPath, content]) => {
161
- const acc = await accP;
162
- let template = content;
163
- if (outputPath.match(/\.[jt]sx?/) && !typescript) {
164
- template = await transformTSToJS(outputPath, content);
165
- }
166
- return {
167
- [outputPath]: template,
168
- ...acc
169
- };
170
- }, Promise.resolve({}));
159
+ return filesList.reduce(
160
+ async (accP, [outputPath, content]) => {
161
+ const acc = await accP;
162
+ let template = content;
163
+ if (outputPath.match(/\.[jt]sx?/) && !typescript) {
164
+ template = await transformTSToJS(outputPath, content);
165
+ }
166
+ return {
167
+ [outputPath]: template,
168
+ ...acc
169
+ };
170
+ },
171
+ Promise.resolve({})
172
+ );
171
173
  };
172
174
  const tasks = ({
173
175
  enquirer,
174
176
  listr2,
175
177
  force,
176
- tests,
177
178
  typescript,
178
179
  skipForgot,
179
180
  skipLogin,
@@ -284,7 +285,6 @@ const tasks = ({
284
285
  title: "Creating pages...",
285
286
  task: async () => {
286
287
  const filesObj = await files({
287
- tests,
288
288
  typescript,
289
289
  skipForgot,
290
290
  skipLogin,
@@ -322,7 +322,7 @@ const tasks = ({
322
322
  }
323
323
  ],
324
324
  {
325
- silentRendererCondition: () => listr2?.silentRendererCondition,
325
+ silentRendererCondition: () => listr2?.silentRendererCondition ?? false,
326
326
  rendererOptions: { collapseSubtasks: false },
327
327
  ctx: { enquirer },
328
328
  exitOnError: true
@@ -336,7 +336,7 @@ const handler = async (yargs) => {
336
336
  skipLogin: yargs.skipLogin,
337
337
  skipReset: yargs.skipReset,
338
338
  skipSignup: yargs.skipSignup,
339
- webauthn: yargs.webauthn,
339
+ webauthn: yargs.webauthn ?? void 0,
340
340
  force: yargs.force,
341
341
  rollback: yargs.rollback
342
342
  });
@@ -348,10 +348,11 @@ const handler = async (yargs) => {
348
348
  await t.run();
349
349
  console.log("");
350
350
  console.log(
351
- yargs.webauthn || t.ctx.webauthn ? getPostInstallWebauthnMessage(isDbAuthSetup()) : getPostInstallMessage(isDbAuthSetup())
351
+ yargs.webauthn || t.ctx?.webauthn ? getPostInstallWebauthnMessage(isDbAuthSetup()) : getPostInstallMessage(isDbAuthSetup())
352
352
  );
353
353
  } catch (e) {
354
- console.log(c.error(e.message));
354
+ const msg = e instanceof Error ? e.message : String(e);
355
+ console.log(c.error(msg));
355
356
  }
356
357
  };
357
358
  function isDbAuthSetup() {
@@ -365,7 +366,7 @@ function isDbAuthSetup() {
365
366
  "auth." + webAuthExtension
366
367
  );
367
368
  return /^import (.*) from ['"]@cedarjs\/auth-dbauth-web['"]/m.test(
368
- fs.readFileSync(webAuthPath)
369
+ fs.readFileSync(webAuthPath, "utf-8")
369
370
  );
370
371
  }
371
372
  return false;
@@ -63,7 +63,7 @@ async function updateTsconfig(task) {
63
63
  "Failed to parse tsconfig: " + JSON.stringify(error, null, 2)
64
64
  );
65
65
  }
66
- if (!tsconfig?.compilerOptions || typeof tsconfig.compilerOptions.module === "undefined") {
66
+ if (tsconfig.compilerOptions?.module === void 0) {
67
67
  continue;
68
68
  }
69
69
  const currentModule = typeof tsconfig.compilerOptions.module === "string" ? tsconfig.compilerOptions.module.toLowerCase() : String(tsconfig.compilerOptions.module).toLowerCase();
@@ -129,10 +129,8 @@ async function addDependencyToPackageJson(task, packageJsonPath, packageName) {
129
129
  const packageJson = JSON.parse(
130
130
  await fs.promises.readFile(packageJsonPath, "utf8")
131
131
  );
132
- if (!packageJson.dependencies) {
133
- packageJson.dependencies = {};
134
- }
135
- if (packageJson.dependencies[packageName]) {
132
+ packageJson.dependencies ??= {};
133
+ if (packageJson?.dependencies[packageName]) {
136
134
  task.skip("Dependency already exists");
137
135
  return;
138
136
  }
@@ -203,7 +201,7 @@ function updateWorkspaceTsconfigReferences(task, folderName, targetWorkspaces) {
203
201
  readFile: (p) => {
204
202
  try {
205
203
  return fs.readFileSync(p, "utf8");
206
- } catch (e) {
204
+ } catch {
207
205
  return ts.sys.readFile(p);
208
206
  }
209
207
  },
@@ -216,21 +214,21 @@ function updateWorkspaceTsconfigReferences(task, folderName, targetWorkspaces) {
216
214
  },
217
215
  path.dirname(ws.tsconfigPath)
218
216
  );
219
- if (configParseResult.errors && configParseResult.errors.length) {
217
+ if (configParseResult.errors?.length) {
220
218
  console.error("Parse errors:", configParseResult.errors);
221
219
  }
222
220
  if (!Array.isArray(tsconfig.references)) {
223
221
  tsconfig.references = [];
224
222
  }
225
- const packageDir2 = ws.packageDir || path.join(getPaths().base, "packages", folderName);
226
- 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("/");
227
225
  const references = tsconfig.references;
228
- if (references.some((ref) => ref && ref.path === referencePath)) {
226
+ if (references.some((ref) => ref?.path === referencePath)) {
229
227
  subtask.skip("tsconfig already up to date");
230
228
  return;
231
229
  }
232
230
  const newReferences = references.concat([{ path: referencePath }]);
233
- let text = await fs.promises.readFile(ws.tsconfigPath, "utf8");
231
+ const text = await fs.promises.readFile(ws.tsconfigPath, "utf8");
234
232
  const edits = modify(text, ["references"], newReferences, {
235
233
  formattingOptions: { insertSpaces: true, tabSize: 2 }
236
234
  });
@@ -250,11 +248,15 @@ async function installAndBuild(folderName) {
250
248
  await installPackages({ stdio: "inherit", cwd: getPaths().base });
251
249
  await runScript("build", [], { stdio: "inherit", cwd: packagePath });
252
250
  }
253
- const handler = async ({ name, force, ...rest }) => {
251
+ const handler = async ({
252
+ name,
253
+ force,
254
+ ...rest
255
+ }) => {
254
256
  recordTelemetryAttributes({
255
257
  command: "generate package",
256
258
  force,
257
- rollback: rest.rollback
259
+ rollback: typeof rest.rollback === "boolean" ? rest.rollback : void 0
258
260
  });
259
261
  if (name.replaceAll("/", "").length < name.length - 1) {
260
262
  throw new Error(
@@ -275,7 +277,6 @@ const handler = async ({ name, force, ...rest }) => {
275
277
  }
276
278
  let packageFiles = {};
277
279
  const tasks = new Listr(
278
- /** @type {import('listr2').ListrTask<ListrContext>[]} */
279
280
  [
280
281
  {
281
282
  title: "Parsing package name...",
@@ -307,7 +308,7 @@ const handler = async ({ name, force, ...rest }) => {
307
308
  return;
308
309
  }
309
310
  } catch (e) {
310
- throw new Error(e.message);
311
+ throw new Error(e instanceof Error ? e.message : String(e));
311
312
  }
312
313
  const prompt = task.prompt(ListrEnquirerPromptAdapter);
313
314
  const response = await prompt.run({
@@ -423,9 +424,11 @@ const handler = async ({ name, force, ...rest }) => {
423
424
  }
424
425
  await tasks.run();
425
426
  } catch (e) {
426
- errorTelemetry(process.argv, e.message);
427
- console.error(c.error(e.message));
428
- 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);
429
432
  }
430
433
  };
431
434
  export {
@@ -198,7 +198,7 @@ async function getAuthSetupHandler(module) {
198
198
  } else {
199
199
  customRequire = require;
200
200
  }
201
- } catch (error) {
201
+ } catch {
202
202
  customRequire = require;
203
203
  }
204
204
  const packageJsonPath = customRequire.resolve("@cedarjs/cli/package.json");
@@ -216,9 +216,14 @@ async function getAuthSetupHandler(module) {
216
216
  if (packument.error) {
217
217
  throw new Error(packument.error);
218
218
  }
219
- } catch (error) {
219
+ } catch (e) {
220
220
  throw new Error(
221
- `Couldn't fetch packument for ${module}: ${error.message}`
221
+ `Couldn't fetch packument for ${module}: ${e instanceof Error ? e.message : String(e)}`
222
+ );
223
+ }
224
+ if (!packument.versions || typeof packument.versions !== "object" || Array.isArray(packument.versions)) {
225
+ throw new Error(
226
+ `Couldn't fetch packument for ${module}: invalid versions field`
222
227
  );
223
228
  }
224
229
  const versionIsPublished = Object.keys(packument.versions).includes(version);
@@ -255,7 +260,7 @@ function isInstalled(module) {
255
260
  return possiblePaths.some((modulePath) => {
256
261
  return fs.existsSync(path.join(modulePath, "package.json"));
257
262
  });
258
- } catch (error) {
263
+ } catch {
259
264
  return false;
260
265
  }
261
266
  }
@@ -41,9 +41,10 @@ const preRequisiteCheckTask = (preRequisites) => {
41
41
  task: async () => {
42
42
  try {
43
43
  await execa(...preReq.command);
44
- } catch (error) {
45
- error.message = error.message + "\n" + preReq.errorMessage;
46
- throw error;
44
+ } catch (e) {
45
+ const baseMsg = e instanceof Error ? e.message : String(e);
46
+ const err = new Error(baseMsg + "\n" + preReq.errorMessage);
47
+ throw err;
47
48
  }
48
49
  }
49
50
  };
@@ -59,7 +60,7 @@ const addFilesTask = ({
59
60
  return {
60
61
  title: `${title}...`,
61
62
  task: () => {
62
- let fileNameToContentMap = {};
63
+ const fileNameToContentMap = {};
63
64
  files.forEach((fileData) => {
64
65
  fileNameToContentMap[fileData.path] = fileData.content;
65
66
  });
@@ -105,7 +106,7 @@ function resolveConfigObject(arg) {
105
106
  }
106
107
  if (t.isBlockStatement(arg.body)) {
107
108
  const returnStmt = arg.body.body.find((s) => t.isReturnStatement(s));
108
- if (returnStmt && t.isObjectExpression(returnStmt.argument)) {
109
+ if (t.isObjectExpression(returnStmt?.argument)) {
109
110
  return returnStmt.argument;
110
111
  }
111
112
  }
@@ -113,8 +114,8 @@ function resolveConfigObject(arg) {
113
114
  }
114
115
  if (t.isFunctionExpression(arg)) {
115
116
  if (t.isBlockStatement(arg.body)) {
116
- const returnStmt = arg.body.body.find((s) => t.isReturnStatement(s));
117
- if (returnStmt && t.isObjectExpression(returnStmt.argument)) {
117
+ const returnStmt = arg.body.body.find(t.isReturnStatement);
118
+ if (t.isObjectExpression(returnStmt?.argument)) {
118
119
  return returnStmt.argument;
119
120
  }
120
121
  }
@@ -122,7 +123,10 @@ function resolveConfigObject(arg) {
122
123
  }
123
124
  return null;
124
125
  }
125
- function insertPluginsBeforeCedar({ content, pluginCodes }) {
126
+ function insertPluginsBeforeCedar({
127
+ content,
128
+ pluginCodes
129
+ }) {
126
130
  const ast = recast.parse(content, {
127
131
  parser: {
128
132
  parse(source) {
@@ -133,54 +137,63 @@ function insertPluginsBeforeCedar({ content, pluginCodes }) {
133
137
  }
134
138
  }
135
139
  });
136
- const defaultExport = ast.program.body.find(
137
- (node) => t.isExportDefaultDeclaration(node) && t.isCallExpression(node.declaration) && t.isIdentifier(node.declaration.callee) && node.declaration.callee.name === "defineConfig"
138
- );
140
+ const defaultExport = ast.program.body.find(t.isExportDefaultDeclaration);
139
141
  if (!defaultExport) {
140
142
  return null;
141
143
  }
142
- const configArg = resolveConfigObject(defaultExport.declaration.arguments[0]);
144
+ const declaration = defaultExport.declaration;
145
+ const configArg = resolveConfigObject(declaration.arguments[0]);
143
146
  if (!configArg) {
144
147
  return null;
145
148
  }
146
- const pluginsProp = configArg.properties.find(
147
- (prop) => t.isObjectProperty(prop) && t.isIdentifier(prop.key) && prop.key.name === "plugins" && t.isArrayExpression(prop.value)
148
- );
149
- if (!pluginsProp) {
149
+ const pluginsProp = configArg.properties.find(t.isObjectProperty);
150
+ if (!t.isArrayExpression(pluginsProp?.value)) {
150
151
  return null;
151
152
  }
152
- const elements = pluginsProp.value.elements;
153
+ const arrayExpr = pluginsProp.value;
154
+ const elements = arrayExpr.elements;
153
155
  const cedarIndex = elements.findIndex(
154
156
  (el) => t.isCallExpression(el) && t.isIdentifier(el.callee) && el.callee.name === "cedar"
155
157
  );
156
158
  if (cedarIndex === -1) {
157
159
  return null;
158
160
  }
159
- const cedarNode = elements[cedarIndex];
160
- const arrayNode = pluginsProp.value;
161
- const isInline = cedarNode.loc.start.line === arrayNode.loc.start.line;
161
+ const cedarElement = elements[cedarIndex];
162
+ if (!cedarElement || !t.isCallExpression(cedarElement)) {
163
+ return null;
164
+ }
165
+ const cedarNode = cedarElement;
166
+ if (!cedarNode.loc || !arrayExpr.loc || !pluginsProp.loc) {
167
+ return null;
168
+ }
169
+ const isInline = cedarNode.loc.start.line === arrayExpr.loc.start.line;
162
170
  if (isInline) {
163
171
  const startPos = posToIndex(
164
172
  content,
165
- arrayNode.loc.start.line,
166
- arrayNode.loc.start.column
173
+ arrayExpr.loc.start.line,
174
+ arrayExpr.loc.start.column
167
175
  );
168
176
  const endPos = posToIndex(
169
177
  content,
170
- arrayNode.loc.end.line,
171
- arrayNode.loc.end.column
178
+ arrayExpr.loc.end.line,
179
+ arrayExpr.loc.end.column
172
180
  );
173
181
  const precedingText = content.slice(0, startPos);
174
182
  const followingText = content.slice(endPos);
175
- const existingCodes = elements.map(
176
- (el) => content.slice(
177
- posToIndex(content, el.loc.start.line, el.loc.start.column),
178
- posToIndex(content, el.loc.end.line, el.loc.end.column)
179
- )
180
- );
183
+ const existingCodes = elements.flatMap((el) => {
184
+ if (!el?.loc) {
185
+ return [];
186
+ }
187
+ return [
188
+ content.slice(
189
+ posToIndex(content, el.loc.start.line, el.loc.start.column),
190
+ posToIndex(content, el.loc.end.line, el.loc.end.column)
191
+ )
192
+ ];
193
+ });
181
194
  const lines2 = content.split("\n");
182
195
  const pluginsLine = pluginsProp.loc.start.line;
183
- const pluginsIndent = lines2[pluginsLine - 1].match(/^\s*/)[0];
196
+ const pluginsIndent = (lines2[pluginsLine - 1].match(/^\s*/) ?? [""])[0];
184
197
  const elemIndent = pluginsIndent + " ";
185
198
  const allCodes = [...existingCodes];
186
199
  allCodes.splice(cedarIndex, 0, ...pluginCodes);
@@ -194,7 +207,7 @@ function insertPluginsBeforeCedar({ content, pluginCodes }) {
194
207
  const cedarLine = cedarNode.loc.start.line;
195
208
  const insertPos = posToIndex(content, cedarLine, 0);
196
209
  const lines = content.split("\n");
197
- const indent = lines[cedarLine - 1].match(/^\s*/)[0];
210
+ const indent = (lines[cedarLine - 1].match(/^\s*/) ?? [""])[0];
198
211
  const insertion = pluginCodes.map((code) => `${indent}${code},
199
212
  `).join("");
200
213
  return content.slice(0, insertPos) + insertion + content.slice(insertPos);
@@ -206,6 +219,7 @@ const addToGitIgnoreTask = ({ paths }) => {
206
219
  if (!fs.existsSync(path.resolve(getPaths().base, ".gitignore"))) {
207
220
  return "No gitignore present, skipping.";
208
221
  }
222
+ return void 0;
209
223
  },
210
224
  task: async (_ctx, task) => {
211
225
  const gitIgnore = path.resolve(getPaths().base, ".gitignore");
@@ -224,6 +238,7 @@ const addToDotEnvTask = ({ lines }) => {
224
238
  if (!fs.existsSync(path.resolve(getPaths().base, ".env"))) {
225
239
  return "No .env present, skipping.";
226
240
  }
241
+ return void 0;
227
242
  },
228
243
  task: async (_ctx, task) => {
229
244
  const env = path.resolve(getPaths().base, ".env");
@@ -38,9 +38,11 @@ async function handler({ force }) {
38
38
  );
39
39
  await tasks.run();
40
40
  } catch (e) {
41
- errorTelemetry(process.argv, e.message);
42
- console.error(c.error(e.message));
43
- process.exit(e?.exitCode || 1);
41
+ const message = e instanceof Error ? e.message : String(e);
42
+ errorTelemetry(process.argv, message);
43
+ console.error(c.error(message));
44
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
45
+ process.exit(exitCode);
44
46
  }
45
47
  }
46
48
  async function getAddCoherenceFilesTask(force) {
@@ -50,11 +52,11 @@ async function getAddCoherenceFilesTask(force) {
50
52
  content: coherenceFiles.healthCheck
51
53
  }
52
54
  ];
53
- const coherenceConfigFile = {
54
- path: path.join(cedarPaths.base, "coherence.yml")
55
- };
56
- coherenceConfigFile.content = await getCoherenceConfigFileContent();
57
- files.push(coherenceConfigFile);
55
+ const coherenceConfigContent = await getCoherenceConfigFileContent();
56
+ files.push({
57
+ path: path.join(cedarPaths.base, "coherence.yml"),
58
+ content: coherenceConfigContent
59
+ });
58
60
  return addFilesTask({
59
61
  title: `Adding coherence.yml and health.${EXTENSION}`,
60
62
  files,
@@ -135,13 +137,13 @@ function updateConfigTomlTask() {
135
137
  }
136
138
  configContent = configContent.replaceAll(
137
139
  HOST_REGEXP,
138
- (match, spaceBeforeAssign, spaceAfterAssign) => ["host", spaceBeforeAssign, "=", spaceAfterAssign, '"0.0.0.0"'].join(
140
+ (_match, spaceBeforeAssign, spaceAfterAssign) => ["host", spaceBeforeAssign, "=", spaceAfterAssign, '"0.0.0.0"'].join(
139
141
  ""
140
142
  )
141
143
  );
142
144
  configContent = configContent.replace(
143
145
  API_URL_REGEXP,
144
- (match, spaceBeforeAssign, spaceAfterAssign) => ["apiUrl", spaceBeforeAssign, "=", spaceAfterAssign, '"/api"'].join(
146
+ (_match, spaceBeforeAssign, spaceAfterAssign) => ["apiUrl", spaceBeforeAssign, "=", spaceAfterAssign, '"/api"'].join(
145
147
  ""
146
148
  )
147
149
  );
@@ -48,18 +48,20 @@ const getFlightcontrolJson = async (database) => {
48
48
  {
49
49
  ...flightcontrolConfig.environments[0],
50
50
  services: [
51
- ...flightcontrolConfig.environments[0].services.map((service) => {
52
- if (service.id === "cedar-api") {
53
- return {
54
- ...service,
55
- envVariables: {
56
- ...service.envVariables,
57
- ...databaseEnvVariables
58
- }
59
- };
51
+ ...flightcontrolConfig.environments[0].services.map(
52
+ (service) => {
53
+ if (service.id === "cedar-api") {
54
+ return {
55
+ ...service,
56
+ envVariables: {
57
+ ...service.envVariables,
58
+ ...databaseEnvVariables
59
+ }
60
+ };
61
+ }
62
+ return service;
60
63
  }
61
- return service;
62
- }),
64
+ ),
63
65
  dbService
64
66
  ]
65
67
  }
@@ -79,7 +81,7 @@ const getFlightcontrolJson = async (database) => {
79
81
  const updateGraphQLFunction = () => {
80
82
  return {
81
83
  title: "Adding CORS config to createGraphQLHandler...",
82
- task: (_ctx) => {
84
+ task: () => {
83
85
  const graphqlTsPath = path.join(
84
86
  getPaths().base,
85
87
  "api/src/functions/graphql.ts"
@@ -127,7 +129,7 @@ const updateGraphQLFunction = () => {
127
129
  const updateDbAuth = () => {
128
130
  return {
129
131
  title: "Updating dbAuth cookie config (if used)...",
130
- task: (_ctx) => {
132
+ task: () => {
131
133
  const authTsPath = path.join(getPaths().base, "api/src/functions/auth.ts");
132
134
  const authJsPath = path.join(getPaths().base, "api/src/functions/auth.js");
133
135
  let authFnPath;
@@ -176,7 +178,7 @@ const updateDbAuth = () => {
176
178
  const updateApp = () => {
177
179
  return {
178
180
  title: "Updating App.jsx fetch config...",
179
- task: (_ctx) => {
181
+ task: () => {
180
182
  const appTsPath = path.join(getPaths().base, "web/src/App.tsx");
181
183
  const appJsPath = path.join(getPaths().base, "web/src/App.jsx");
182
184
  let appPath;
@@ -234,8 +236,9 @@ const addToDotEnvDefaultTask = () => {
234
236
  CEDAR_API_URL=${getUserApiUrl()}
235
237
  `;
236
238
  }
239
+ return void 0;
237
240
  },
238
- task: async (_ctx) => {
241
+ task: async () => {
239
242
  const env = path.resolve(getPaths().base, ".env.defaults");
240
243
  const apiUrl = getUserApiUrl();
241
244
  const line = `
@@ -252,7 +255,10 @@ const notes = [
252
255
  "Check out the deployment docs at https://app.flightcontrol.dev/docs for detailed instructions\n",
253
256
  "NOTE: If you are using yarn v1, remove the installCommand's from flightcontrol.json"
254
257
  ];
255
- const handler = async ({ force, database }) => {
258
+ const handler = async ({
259
+ force,
260
+ database
261
+ }) => {
256
262
  recordTelemetryAttributes({
257
263
  command: "setup deploy flightcontrol",
258
264
  force,
@@ -264,7 +270,7 @@ const handler = async ({ force, database }) => {
264
270
  title: "Adding flightcontrol.json",
265
271
  task: async () => {
266
272
  const fileData = await getFlightcontrolJson(database);
267
- let files = {};
273
+ const files = {};
268
274
  files[fileData.path] = JSON.stringify(fileData.content, null, 2);
269
275
  return writeFilesTask(files, { overwriteExisting: force });
270
276
  }
@@ -281,9 +287,11 @@ const handler = async ({ force, database }) => {
281
287
  try {
282
288
  await tasks.run();
283
289
  } catch (e) {
284
- errorTelemetry(process.argv, e.message);
285
- console.error(c.error(e.message));
286
- process.exit(e?.exitCode || 1);
290
+ const message = e instanceof Error ? e.message : String(e);
291
+ errorTelemetry(process.argv, message);
292
+ console.error(c.error(message));
293
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
294
+ process.exit(exitCode);
287
295
  }
288
296
  };
289
297
  export {
@@ -53,7 +53,7 @@ async function handler({ force }) {
53
53
  ...pm === "yarn" ? [
54
54
  {
55
55
  title: "Adding the official yarn workspace-tools plugin...",
56
- task: async (_ctx, task) => {
56
+ task: async (_, task) => {
57
57
  const { stdout } = await execa(
58
58
  "yarn",
59
59
  ["plugin", "runtime", "--json"],
@@ -61,7 +61,7 @@ async function handler({ force }) {
61
61
  cwd: getPaths().base
62
62
  }
63
63
  );
64
- const hasWorkspaceToolsPlugin = stdout.trim().split("\n").map(JSON.parse).some(
64
+ const hasWorkspaceToolsPlugin = stdout.trim().split("\n").map((line) => JSON.parse(line)).some(
65
65
  ({ name }) => name === "@yarnpkg/plugin-workspace-tools"
66
66
  );
67
67
  if (hasWorkspaceToolsPlugin) {
@@ -80,7 +80,7 @@ async function handler({ force }) {
80
80
  title: "Adding @cedarjs/api-server and @cedarjs/web-server...",
81
81
  task: async (_ctx, task) => {
82
82
  const apiServerPackageName = "@cedarjs/api-server";
83
- const { dependencies: apiDependencies } = JSON.parse(
83
+ const { dependencies: apiDependencies = {} } = JSON.parse(
84
84
  fs.readFileSync(
85
85
  path.join(getPaths().api.base, "package.json"),
86
86
  "utf-8"
@@ -88,7 +88,7 @@ async function handler({ force }) {
88
88
  );
89
89
  const hasApiServerPackage = Object.keys(apiDependencies).includes(apiServerPackageName);
90
90
  const webServerPackageName = "@cedarjs/web-server";
91
- const { dependencies: webDependencies } = JSON.parse(
91
+ const { dependencies: webDependencies = {} } = JSON.parse(
92
92
  fs.readFileSync(
93
93
  path.join(getPaths().web.base, "package.json"),
94
94
  "utf-8"
@@ -264,9 +264,11 @@ async function handler({ force }) {
264
264
  ].join("\n")
265
265
  );
266
266
  } catch (e) {
267
- errorTelemetry(process.argv, e.message);
268
- console.error(c.error(e.message));
269
- process.exit(e?.exitCode || 1);
267
+ const msg = e instanceof Error ? e.message : String(e);
268
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
269
+ errorTelemetry(process.argv, msg);
270
+ console.error(c.error(msg));
271
+ process.exit(exitCode);
270
272
  }
271
273
  }
272
274
  async function getVersionOfRedwoodPackageToInstall(module) {
@@ -274,9 +276,21 @@ async function getVersionOfRedwoodPackageToInstall(module) {
274
276
  const packageJsonPath = createdRequire.resolve("@cedarjs/cli/package.json", {
275
277
  paths: [getPaths().base]
276
278
  });
277
- let { version } = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
279
+ let { version = "" } = JSON.parse(
280
+ fs.readFileSync(packageJsonPath, "utf8")
281
+ );
278
282
  const packumentP = await fetch(`https://registry.npmjs.org/${module}`);
279
283
  const packument = await packumentP.json();
284
+ if (packument.error) {
285
+ throw new Error(
286
+ `Couldn't fetch packument for ${module}: ${packument.error}`
287
+ );
288
+ }
289
+ if (!packument.versions || typeof packument.versions !== "object" || Array.isArray(packument.versions)) {
290
+ throw new Error(
291
+ `Couldn't fetch packument for ${module}: invalid versions field`
292
+ );
293
+ }
280
294
  if (version.includes("+")) {
281
295
  version = version.split("+")[0];
282
296
  }
@@ -3,7 +3,11 @@ import semver from "semver";
3
3
  import { getCompatibilityData } from "@cedarjs/cli-helpers";
4
4
  import { dlx } from "@cedarjs/cli-helpers/packageManager/exec";
5
5
  import { getPaths } from "@cedarjs/project-config";
6
- async function handler({ npmPackage, force, _: _args }) {
6
+ async function handler({
7
+ npmPackage,
8
+ force,
9
+ _: _args
10
+ }) {
7
11
  const isScoped = npmPackage.startsWith("@");
8
12
  const packageName = (isScoped ? "@" : "") + npmPackage.split("@")[isScoped ? 1 : 0];
9
13
  const packageVersion = npmPackage.split("@")[isScoped ? 2 : 1] ?? "latest";
@@ -24,9 +28,9 @@ async function handler({ npmPackage, force, _: _args }) {
24
28
  let compatibilityData;
25
29
  try {
26
30
  compatibilityData = await getCompatibilityData(packageName, packageVersion);
27
- } catch (error) {
31
+ } catch (e) {
28
32
  console.log("The following error occurred while checking compatibility:");
29
- const errorMessage = error.message ?? error;
33
+ const errorMessage = e instanceof Error ? e.message : String(e);
30
34
  console.log(errorMessage);
31
35
  if (errorMessage.includes("does not have a tag") || errorMessage.includes("does not have a version")) {
32
36
  process.exit(1);
@@ -110,8 +114,8 @@ async function runPackage(packageName, version, options = []) {
110
114
  stdio: "inherit",
111
115
  cwd: getPaths().base
112
116
  });
113
- } catch (error) {
114
- process.exitCode = error.exitCode ?? 1;
117
+ } catch (e) {
118
+ process.exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
115
119
  }
116
120
  }
117
121
  async function promptWithChoices(message, choices) {
@@ -122,9 +126,9 @@ async function promptWithChoices(message, choices) {
122
126
  choices
123
127
  });
124
128
  return await prompt.run();
125
- } catch (error) {
126
- if (error) {
127
- throw error;
129
+ } catch (e) {
130
+ if (e) {
131
+ throw e;
128
132
  }
129
133
  }
130
134
  return null;
@@ -74,7 +74,10 @@ async function recommendExtensionsToInstall() {
74
74
  });
75
75
  }
76
76
  }
77
- const handler = async ({ force, install }) => {
77
+ const handler = async ({
78
+ force,
79
+ install
80
+ }) => {
78
81
  recordTelemetryAttributes({
79
82
  command: "setup ui tailwindcss",
80
83
  force,
@@ -238,7 +241,7 @@ const handler = async ({ force, install }) => {
238
241
  rwPaths.base,
239
242
  ".vscode/extensions.json"
240
243
  );
241
- let originalExtensionsJson = { recommendations: [] };
244
+ let originalExtensionsJson = {};
242
245
  if (fs.existsSync(VS_CODE_EXTENSIONS_PATH)) {
243
246
  const originalExtensionsFile = fs.readFileSync(
244
247
  VS_CODE_EXTENSIONS_PATH,
@@ -249,7 +252,7 @@ const handler = async ({ force, install }) => {
249
252
  const newExtensionsJson = {
250
253
  ...originalExtensionsJson,
251
254
  recommendations: [
252
- ...originalExtensionsJson.recommendations,
255
+ ...originalExtensionsJson.recommendations ?? [],
253
256
  ...recommendedVSCodeExtensions
254
257
  ]
255
258
  };
@@ -284,7 +287,10 @@ const handler = async ({ force, install }) => {
284
287
  const originalSettingsJson = JSON.parse(
285
288
  originalSettingsFile || "{}"
286
289
  );
287
- const originalTwClassAttributesJson = originalSettingsJson["tailwindCSS.classAttributes"] || [];
290
+ const existingAttributes = originalSettingsJson["tailwindCSS.classAttributes"];
291
+ const originalTwClassAttributesJson = Array.isArray(
292
+ existingAttributes
293
+ ) ? existingAttributes : [];
288
294
  const mergedClassAttributes = Array.from(
289
295
  /* @__PURE__ */ new Set([...classAttributes, ...originalTwClassAttributesJson])
290
296
  );
@@ -346,7 +352,7 @@ const handler = async ({ force, install }) => {
346
352
  const pluginsMatch = newPrettierConfig.match(
347
353
  /plugins: \[[\sa-z\(\)'\-,]*]/
348
354
  );
349
- const matched = pluginsMatch && pluginsMatch[0];
355
+ const matched = pluginsMatch != null ? pluginsMatch[0] : void 0;
350
356
  if (matched && (matched.includes("'prettier-plugin-tailwindcss'") || matched.includes('"prettier-plugin-tailwindcss"'))) {
351
357
  task.skip(
352
358
  "tailwindcss-plugin-prettier already required in plugins"
@@ -374,9 +380,11 @@ const handler = async ({ force, install }) => {
374
380
  await tasks.run();
375
381
  await recommendExtensionsToInstall();
376
382
  } catch (e) {
377
- errorTelemetry(process.argv, e.message);
378
- console.error(c.error(e.message));
379
- process.exit(e?.exitCode || 1);
383
+ const msg = e instanceof Error ? e.message : String(e);
384
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
385
+ errorTelemetry(process.argv, msg);
386
+ console.error(c.error(msg));
387
+ process.exit(exitCode);
380
388
  }
381
389
  };
382
390
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "5.0.0-canary.2564",
3
+ "version": "5.0.0-canary.2565",
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.7",
35
35
  "@babel/preset-typescript": "7.29.7",
36
- "@cedarjs/api-server": "5.0.0-canary.2564",
37
- "@cedarjs/cli-helpers": "5.0.0-canary.2564",
38
- "@cedarjs/fastify-web": "5.0.0-canary.2564",
39
- "@cedarjs/internal": "5.0.0-canary.2564",
40
- "@cedarjs/prerender": "5.0.0-canary.2564",
41
- "@cedarjs/project-config": "5.0.0-canary.2564",
42
- "@cedarjs/structure": "5.0.0-canary.2564",
43
- "@cedarjs/telemetry": "5.0.0-canary.2564",
44
- "@cedarjs/utils": "5.0.0-canary.2564",
45
- "@cedarjs/vite": "5.0.0-canary.2564",
46
- "@cedarjs/web-server": "5.0.0-canary.2564",
36
+ "@cedarjs/api-server": "5.0.0-canary.2565",
37
+ "@cedarjs/cli-helpers": "5.0.0-canary.2565",
38
+ "@cedarjs/fastify-web": "5.0.0-canary.2565",
39
+ "@cedarjs/internal": "5.0.0-canary.2565",
40
+ "@cedarjs/prerender": "5.0.0-canary.2565",
41
+ "@cedarjs/project-config": "5.0.0-canary.2565",
42
+ "@cedarjs/structure": "5.0.0-canary.2565",
43
+ "@cedarjs/telemetry": "5.0.0-canary.2565",
44
+ "@cedarjs/utils": "5.0.0-canary.2565",
45
+ "@cedarjs/vite": "5.0.0-canary.2565",
46
+ "@cedarjs/web-server": "5.0.0-canary.2565",
47
47
  "@listr2/prompt-adapter-enquirer": "4.2.1",
48
48
  "@opentelemetry/api": "1.9.1",
49
49
  "@opentelemetry/core": "1.30.1",