@strapi/cloud-cli 0.0.0-next.7466630056657c483fb286557dda890490597807 → 0.0.0-next.7f1333f1967e625c57ab16648c057aea08c9dddb

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -20,8 +20,8 @@ import ora from "ora";
20
20
  import * as cliProgress from "cli-progress";
21
21
  import pkgUp from "pkg-up";
22
22
  import * as yup from "yup";
23
- import _ from "lodash";
24
23
  import EventSource from "eventsource";
24
+ import { createCommand } from "commander";
25
25
  const apiConfig = {
26
26
  apiBaseUrl: env("STRAPI_CLI_CLOUD_API", "https://cloud-cli-api.strapi.io"),
27
27
  dashboardBaseUrl: env("STRAPI_CLI_CLOUD_DASHBOARD", "https://cloud.strapi.io")
@@ -134,7 +134,7 @@ async function saveLocalConfig(data) {
134
134
  await fse__default.writeJson(configFilePath, data, { encoding: "utf8", spaces: 2, mode: 384 });
135
135
  }
136
136
  const name = "@strapi/cloud-cli";
137
- const version = "4.25.7";
137
+ const version = "5.0.2-beta.0";
138
138
  const description = "Commands to interact with the Strapi Cloud";
139
139
  const keywords = [
140
140
  "strapi",
@@ -179,14 +179,14 @@ const scripts = {
179
179
  watch: "pack-up watch"
180
180
  };
181
181
  const dependencies = {
182
- "@strapi/utils": "4.25.7",
183
- axios: "1.6.0",
182
+ "@strapi/utils": "workspace:*",
183
+ axios: "1.7.4",
184
184
  chalk: "4.1.2",
185
185
  "cli-progress": "3.12.0",
186
186
  commander: "8.3.0",
187
187
  eventsource: "2.0.2",
188
188
  "fast-safe-stringify": "2.1.1",
189
- "fs-extra": "10.0.0",
189
+ "fs-extra": "11.2.0",
190
190
  inquirer: "8.2.5",
191
191
  jsonwebtoken: "9.0.0",
192
192
  "jwks-rsa": "3.1.0",
@@ -195,7 +195,7 @@ const dependencies = {
195
195
  open: "8.4.0",
196
196
  ora: "5.4.1",
197
197
  "pkg-up": "3.1.0",
198
- tar: "6.1.13",
198
+ tar: "6.2.1",
199
199
  "xdg-app-paths": "8.3.0",
200
200
  yup: "0.32.9"
201
201
  };
@@ -204,8 +204,8 @@ const devDependencies = {
204
204
  "@types/cli-progress": "3.11.5",
205
205
  "@types/eventsource": "1.1.15",
206
206
  "@types/lodash": "^4.14.191",
207
- "eslint-config-custom": "4.25.7",
208
- tsconfig: "4.25.7"
207
+ "eslint-config-custom": "workspace:*",
208
+ tsconfig: "workspace:*"
209
209
  };
210
210
  const engines = {
211
211
  node: ">=18.0.0 <=20.x.x",
@@ -317,7 +317,7 @@ async function cloudApiFactory({ logger }, token) {
317
317
  },
318
318
  async listLinkProjects() {
319
319
  try {
320
- const response = await axiosCloudAPI.get("/projects/linkable");
320
+ const response = await axiosCloudAPI.get("/projects-linkable");
321
321
  if (response.status !== 200) {
322
322
  throw new Error("Error fetching cloud projects from the server.");
323
323
  }
@@ -329,6 +329,20 @@ async function cloudApiFactory({ logger }, token) {
329
329
  throw error;
330
330
  }
331
331
  },
332
+ async getProject({ name: name2 }) {
333
+ try {
334
+ const response = await axiosCloudAPI.get(`/projects/${name2}`);
335
+ if (response.status !== 200) {
336
+ throw new Error("Error fetching project's details.");
337
+ }
338
+ return response;
339
+ } catch (error) {
340
+ logger.debug(
341
+ "🥲 Oops! There was a problem retrieving your project's details. Please try again."
342
+ );
343
+ throw error;
344
+ }
345
+ },
332
346
  track(event, payload = {}) {
333
347
  return axiosCloudAPI.post("/track", {
334
348
  event,
@@ -602,21 +616,24 @@ yup.object({
602
616
  name: yup.string().required(),
603
617
  exports: yup.lazy(
604
618
  (value) => yup.object(
605
- typeof value === "object" ? Object.entries(value).reduce((acc, [key, value2]) => {
606
- if (typeof value2 === "object") {
607
- acc[key] = yup.object({
608
- types: yup.string().optional(),
609
- source: yup.string().required(),
610
- module: yup.string().optional(),
611
- import: yup.string().required(),
612
- require: yup.string().required(),
613
- default: yup.string().required()
614
- }).noUnknown(true);
615
- } else {
616
- acc[key] = yup.string().matches(/^\.\/.*\.json$/).required();
617
- }
618
- return acc;
619
- }, {}) : void 0
619
+ typeof value === "object" ? Object.entries(value).reduce(
620
+ (acc, [key, value2]) => {
621
+ if (typeof value2 === "object") {
622
+ acc[key] = yup.object({
623
+ types: yup.string().optional(),
624
+ source: yup.string().required(),
625
+ module: yup.string().optional(),
626
+ import: yup.string().required(),
627
+ require: yup.string().required(),
628
+ default: yup.string().required()
629
+ }).noUnknown(true);
630
+ } else {
631
+ acc[key] = yup.string().matches(/^\.\/.*\.json$/).required();
632
+ }
633
+ return acc;
634
+ },
635
+ {}
636
+ ) : void 0
620
637
  ).optional()
621
638
  )
622
639
  });
@@ -638,18 +655,6 @@ async function getProjectNameFromPackageJson(ctx) {
638
655
  return "my-strapi-project";
639
656
  }
640
657
  }
641
- function applyDefaultName(newDefaultName, questions, defaultValues) {
642
- const newDefaultValues = _.cloneDeep(defaultValues);
643
- newDefaultValues.name = newDefaultName;
644
- const newQuestions = questions.map((question) => {
645
- const questionCopy = _.cloneDeep(question);
646
- if (questionCopy.name === "name") {
647
- questionCopy.default = newDefaultName;
648
- }
649
- return questionCopy;
650
- });
651
- return { newQuestions, newDefaultValues };
652
- }
653
658
  const trackEvent = async (ctx, cloudApiService, eventName, eventData) => {
654
659
  try {
655
660
  await cloudApiService.track(eventName, eventData);
@@ -813,6 +818,45 @@ async function loginAction(ctx) {
813
818
  await authenticate();
814
819
  return isAuthenticated;
815
820
  }
821
+ function questionDefaultValuesMapper(questionsMap) {
822
+ return (questions) => {
823
+ return questions.map((question) => {
824
+ const questionName = question.name;
825
+ if (questionName in questionsMap) {
826
+ const questionDefault = questionsMap[questionName];
827
+ if (typeof questionDefault === "function") {
828
+ return {
829
+ ...question,
830
+ default: questionDefault(question)
831
+ };
832
+ }
833
+ return {
834
+ ...question,
835
+ default: questionDefault
836
+ };
837
+ }
838
+ return question;
839
+ });
840
+ };
841
+ }
842
+ function getDefaultsFromQuestions(questions) {
843
+ return questions.reduce((acc, question) => {
844
+ if (question.default && question.name) {
845
+ return { ...acc, [question.name]: question.default };
846
+ }
847
+ return acc;
848
+ }, {});
849
+ }
850
+ function getProjectNodeVersionDefault(question) {
851
+ const currentNodeVersion = process.versions.node.split(".")[0];
852
+ if (question.type === "list" && Array.isArray(question.choices)) {
853
+ const choice = question.choices.find((choice2) => choice2.value === currentNodeVersion);
854
+ if (choice) {
855
+ return choice.value;
856
+ }
857
+ }
858
+ return question.default;
859
+ }
816
860
  async function handleError(ctx, error) {
817
861
  const { logger } = ctx;
818
862
  logger.debug(error);
@@ -866,11 +910,16 @@ const action$4 = async (ctx) => {
866
910
  }
867
911
  const cloudApi = await cloudApiFactory(ctx, token);
868
912
  const { data: config } = await cloudApi.config();
869
- const { newQuestions: questions, newDefaultValues: defaultValues } = applyDefaultName(
870
- await getProjectNameFromPackageJson(ctx),
871
- config.projectCreation.questions,
872
- config.projectCreation.defaults
873
- );
913
+ const projectName = await getProjectNameFromPackageJson(ctx);
914
+ const defaultAnswersMapper = questionDefaultValuesMapper({
915
+ name: projectName,
916
+ nodeVersion: getProjectNodeVersionDefault
917
+ });
918
+ const questions = defaultAnswersMapper(config.projectCreation.questions);
919
+ const defaultValues = {
920
+ ...config.projectCreation.defaults,
921
+ ...getDefaultsFromQuestions(questions)
922
+ };
874
923
  const projectAnswersDefaulted = defaults(defaultValues);
875
924
  const projectAnswers = await inquirer.prompt(questions);
876
925
  const projectInput = projectAnswersDefaulted(projectAnswers);
@@ -1047,17 +1096,7 @@ async function upload(ctx, project, token, maxProjectFileSize) {
1047
1096
  return data.build_id;
1048
1097
  } catch (e) {
1049
1098
  progressBar.stop();
1050
- if (e instanceof AxiosError && e.response?.data) {
1051
- if (e.response.status === 404) {
1052
- ctx.logger.warn(
1053
- `The project does not exist. Please link your local project to a Strapi Cloud project using the link command.`
1054
- );
1055
- } else {
1056
- ctx.logger.error(e.response.data);
1057
- }
1058
- } else {
1059
- ctx.logger.error("An error occurred while deploying the project. Please try again later.");
1060
- }
1099
+ ctx.logger.error("An error occurred while deploying the project. Please try again later.");
1061
1100
  ctx.logger.debug(e);
1062
1101
  } finally {
1063
1102
  await fse__default.remove(tarFilePath);
@@ -1104,7 +1143,39 @@ const action$3 = async (ctx) => {
1104
1143
  if (!project) {
1105
1144
  return;
1106
1145
  }
1107
- const cloudApiService = await cloudApiFactory(ctx);
1146
+ const cloudApiService = await cloudApiFactory(ctx, token);
1147
+ try {
1148
+ const {
1149
+ data: { data: projectData, metadata }
1150
+ } = await cloudApiService.getProject({ name: project.name });
1151
+ const isProjectSuspended = projectData.suspendedAt;
1152
+ if (isProjectSuspended) {
1153
+ ctx.logger.log(
1154
+ "\n Oops! This project has been suspended. \n\n Please reactivate it from the dashboard to continue deploying: "
1155
+ );
1156
+ ctx.logger.log(chalk.underline(`${metadata.dashboardUrls.project}`));
1157
+ return;
1158
+ }
1159
+ } catch (e) {
1160
+ if (e instanceof AxiosError && e.response?.data) {
1161
+ if (e.response.status === 404) {
1162
+ ctx.logger.warn(
1163
+ `The project associated with this folder does not exist in Strapi Cloud.
1164
+ Please link your local project to an existing Strapi Cloud project using the ${chalk.cyan(
1165
+ "link"
1166
+ )} command before deploying.`
1167
+ );
1168
+ } else {
1169
+ ctx.logger.error(e.response.data);
1170
+ }
1171
+ } else {
1172
+ ctx.logger.error(
1173
+ "An error occurred while retrieving the project's information. Please try again later."
1174
+ );
1175
+ }
1176
+ ctx.logger.debug(e);
1177
+ return;
1178
+ }
1108
1179
  await trackEvent(ctx, cloudApiService, "willDeployWithCLI", {
1109
1180
  projectInternalName: project.name
1110
1181
  });
@@ -1113,7 +1184,7 @@ const action$3 = async (ctx) => {
1113
1184
  const cliConfig2 = await getConfig({ ctx, cloudApiService });
1114
1185
  if (!cliConfig2) {
1115
1186
  ctx.logger.error(
1116
- "An error occurred while retrieving data from Strapi Cloud. Please try check your network or again later."
1187
+ "An error occurred while retrieving data from Strapi Cloud. Please check your network or try again later."
1117
1188
  );
1118
1189
  return;
1119
1190
  }
@@ -1173,8 +1244,8 @@ const runAction = (name2, action2) => (...args) => {
1173
1244
  process.exit(1);
1174
1245
  });
1175
1246
  };
1176
- const command$5 = ({ command: command2, ctx }) => {
1177
- command2.command("cloud:deploy").alias("deploy").description("Deploy a Strapi Cloud project").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("deploy", action$3)(ctx));
1247
+ const command$5 = ({ ctx }) => {
1248
+ return createCommand("cloud:deploy").alias("deploy").description("Deploy a Strapi Cloud project").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("deploy", action$3)(ctx));
1178
1249
  };
1179
1250
  const deployProject = {
1180
1251
  name: "deploy-project",
@@ -1328,8 +1399,8 @@ const link = {
1328
1399
  action: action$2,
1329
1400
  command: command$4
1330
1401
  };
1331
- const command$3 = ({ command: command2, ctx }) => {
1332
- command2.command("cloud:login").alias("login").description("Strapi Cloud Login").addHelpText(
1402
+ const command$3 = ({ ctx }) => {
1403
+ return createCommand("cloud:login").alias("login").description("Strapi Cloud Login").addHelpText(
1333
1404
  "after",
1334
1405
  "\nAfter running this command, you will be prompted to enter your authentication information."
1335
1406
  ).option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("login", loginAction)(ctx));
@@ -1373,8 +1444,8 @@ const action$1 = async (ctx) => {
1373
1444
  }
1374
1445
  await trackEvent(ctx, cloudApiService, "didLogout", { loginMethod: "cli" });
1375
1446
  };
1376
- const command$2 = ({ command: command2, ctx }) => {
1377
- command2.command("cloud:logout").alias("logout").description("Strapi Cloud Logout").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("logout", action$1)(ctx));
1447
+ const command$2 = ({ ctx }) => {
1448
+ return createCommand("cloud:logout").alias("logout").description("Strapi Cloud Logout").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("logout", action$1)(ctx));
1378
1449
  };
1379
1450
  const logout = {
1380
1451
  name: "logout",
@@ -1382,8 +1453,8 @@ const logout = {
1382
1453
  action: action$1,
1383
1454
  command: command$2
1384
1455
  };
1385
- const command$1 = ({ command: command2, ctx }) => {
1386
- command2.command("cloud:create-project").description("Create a Strapi Cloud project").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("cloud:create-project", action$4)(ctx));
1456
+ const command$1 = ({ ctx }) => {
1457
+ return createCommand("cloud:create-project").description("Create a Strapi Cloud project").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("cloud:create-project", action$4)(ctx));
1387
1458
  };
1388
1459
  const createProject = {
1389
1460
  name: "create-project",
@@ -1444,7 +1515,10 @@ async function buildStrapiCloudCommands({
1444
1515
  await initCloudCLIConfig();
1445
1516
  for (const cloudCommand of cloudCommands) {
1446
1517
  try {
1447
- await cloudCommand.command({ command: command2, ctx, argv });
1518
+ const subCommand = await cloudCommand.command({ command: command2, ctx, argv });
1519
+ if (subCommand) {
1520
+ command2.addCommand(subCommand);
1521
+ }
1448
1522
  } catch (e) {
1449
1523
  console.error(`Failed to load command ${cloudCommand.name}`, e);
1450
1524
  }