@strapi/cloud-cli 4.25.3 → 4.25.4

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
@@ -1,12 +1,12 @@
1
1
  import crypto$1 from "crypto";
2
- import fse from "fs-extra";
2
+ import * as fse from "fs-extra";
3
+ import fse__default from "fs-extra";
3
4
  import * as path from "path";
4
5
  import path__default from "path";
5
6
  import chalk from "chalk";
6
7
  import axios, { AxiosError } from "axios";
7
8
  import * as crypto from "node:crypto";
8
9
  import { env } from "@strapi/utils";
9
- import * as fs from "fs";
10
10
  import * as tar from "tar";
11
11
  import { minimatch } from "minimatch";
12
12
  import inquirer from "inquirer";
@@ -18,7 +18,6 @@ import jwt from "jsonwebtoken";
18
18
  import stringify from "fast-safe-stringify";
19
19
  import ora from "ora";
20
20
  import * as cliProgress from "cli-progress";
21
- import fs$1 from "fs/promises";
22
21
  import pkgUp from "pkg-up";
23
22
  import * as yup from "yup";
24
23
  import _ from "lodash";
@@ -41,23 +40,6 @@ const IGNORED_PATTERNS = [
41
40
  "**/.idea/**",
42
41
  "**/.vscode/**"
43
42
  ];
44
- const getFiles = (dirPath, ignorePatterns = [], arrayOfFiles = [], subfolder = "") => {
45
- const entries = fs.readdirSync(path.join(dirPath, subfolder));
46
- entries.forEach((entry) => {
47
- const entryPathFromRoot = path.join(subfolder, entry);
48
- const entryPath = path.relative(dirPath, entryPathFromRoot);
49
- const isIgnored = isIgnoredFile(dirPath, entryPathFromRoot, ignorePatterns);
50
- if (isIgnored) {
51
- return;
52
- }
53
- if (fs.statSync(entryPath).isDirectory()) {
54
- getFiles(dirPath, ignorePatterns, arrayOfFiles, entryPathFromRoot);
55
- } else {
56
- arrayOfFiles.push(entryPath);
57
- }
58
- });
59
- return arrayOfFiles;
60
- };
61
43
  const isIgnoredFile = (folderPath, file, ignorePatterns) => {
62
44
  ignorePatterns.push(...IGNORED_PATTERNS);
63
45
  const relativeFilePath = path.join(folderPath, file);
@@ -75,16 +57,35 @@ const isIgnoredFile = (folderPath, file, ignorePatterns) => {
75
57
  }
76
58
  return isIgnored;
77
59
  };
78
- const readGitignore = (folderPath) => {
60
+ const getFiles = async (dirPath, ignorePatterns = [], subfolder = "") => {
61
+ const arrayOfFiles = [];
62
+ const entries = await fse.readdir(path.join(dirPath, subfolder));
63
+ for (const entry of entries) {
64
+ const entryPathFromRoot = path.join(subfolder, entry);
65
+ const entryPath = path.relative(dirPath, entryPathFromRoot);
66
+ const isIgnored = isIgnoredFile(dirPath, entryPathFromRoot, ignorePatterns);
67
+ if (!isIgnored) {
68
+ if (fse.statSync(entryPath).isDirectory()) {
69
+ const subFiles = await getFiles(dirPath, ignorePatterns, entryPathFromRoot);
70
+ arrayOfFiles.push(...subFiles);
71
+ } else {
72
+ arrayOfFiles.push(entryPath);
73
+ }
74
+ }
75
+ }
76
+ return arrayOfFiles;
77
+ };
78
+ const readGitignore = async (folderPath) => {
79
79
  const gitignorePath = path.resolve(folderPath, ".gitignore");
80
- if (!fs.existsSync(gitignorePath))
80
+ const pathExist = await fse.pathExists(gitignorePath);
81
+ if (!pathExist)
81
82
  return [];
82
- const gitignoreContent = fs.readFileSync(gitignorePath, "utf8");
83
+ const gitignoreContent = await fse.readFile(gitignorePath, "utf8");
83
84
  return gitignoreContent.split(/\r?\n/).filter((line) => Boolean(line.trim()) && !line.startsWith("#"));
84
85
  };
85
86
  const compressFilesToTar = async (storagePath, folderToCompress, filename) => {
86
- const ignorePatterns = readGitignore(folderToCompress);
87
- const filesToCompress = getFiles(folderToCompress, ignorePatterns);
87
+ const ignorePatterns = await readGitignore(folderToCompress);
88
+ const filesToCompress = await getFiles(folderToCompress, ignorePatterns);
88
89
  return tar.c(
89
90
  {
90
91
  gzip: true,
@@ -97,7 +98,7 @@ const APP_FOLDER_NAME = "com.strapi.cli";
97
98
  const CONFIG_FILENAME = "config.json";
98
99
  async function checkDirectoryExists(directoryPath) {
99
100
  try {
100
- const fsStat = await fse.lstat(directoryPath);
101
+ const fsStat = await fse__default.lstat(directoryPath);
101
102
  return fsStat.isDirectory();
102
103
  } catch (e) {
103
104
  return false;
@@ -105,14 +106,14 @@ async function checkDirectoryExists(directoryPath) {
105
106
  }
106
107
  async function getTmpStoragePath() {
107
108
  const storagePath = path__default.join(os.tmpdir(), APP_FOLDER_NAME);
108
- await fse.ensureDir(storagePath);
109
+ await fse__default.ensureDir(storagePath);
109
110
  return storagePath;
110
111
  }
111
112
  async function getConfigPath() {
112
113
  const configDirs = XDGAppPaths(APP_FOLDER_NAME).configDirs();
113
114
  const configPath = configDirs.find(checkDirectoryExists);
114
115
  if (!configPath) {
115
- await fse.ensureDir(configDirs[0]);
116
+ await fse__default.ensureDir(configDirs[0]);
116
117
  return configDirs[0];
117
118
  }
118
119
  return configPath;
@@ -120,9 +121,9 @@ async function getConfigPath() {
120
121
  async function getLocalConfig() {
121
122
  const configPath = await getConfigPath();
122
123
  const configFilePath = path__default.join(configPath, CONFIG_FILENAME);
123
- await fse.ensureFile(configFilePath);
124
+ await fse__default.ensureFile(configFilePath);
124
125
  try {
125
- return await fse.readJSON(configFilePath, { encoding: "utf8", throws: true });
126
+ return await fse__default.readJSON(configFilePath, { encoding: "utf8", throws: true });
126
127
  } catch (e) {
127
128
  return {};
128
129
  }
@@ -130,10 +131,10 @@ async function getLocalConfig() {
130
131
  async function saveLocalConfig(data) {
131
132
  const configPath = await getConfigPath();
132
133
  const configFilePath = path__default.join(configPath, CONFIG_FILENAME);
133
- await fse.writeJson(configFilePath, data, { encoding: "utf8", spaces: 2, mode: 384 });
134
+ await fse__default.writeJson(configFilePath, data, { encoding: "utf8", spaces: 2, mode: 384 });
134
135
  }
135
136
  const name = "@strapi/cloud-cli";
136
- const version = "4.25.2";
137
+ const version = "4.25.3";
137
138
  const description = "Commands to interact with the Strapi Cloud";
138
139
  const keywords = [
139
140
  "strapi",
@@ -178,7 +179,7 @@ const scripts = {
178
179
  watch: "pack-up watch"
179
180
  };
180
181
  const dependencies = {
181
- "@strapi/utils": "4.25.2",
182
+ "@strapi/utils": "4.25.3",
182
183
  axios: "1.6.0",
183
184
  chalk: "4.1.2",
184
185
  "cli-progress": "3.12.0",
@@ -203,8 +204,8 @@ const devDependencies = {
203
204
  "@types/cli-progress": "3.11.5",
204
205
  "@types/eventsource": "1.1.15",
205
206
  "@types/lodash": "^4.14.191",
206
- "eslint-config-custom": "4.25.2",
207
- tsconfig: "4.25.2"
207
+ "eslint-config-custom": "4.25.3",
208
+ tsconfig: "4.25.3"
208
209
  };
209
210
  const engines = {
210
211
  node: ">=18.0.0 <=20.x.x",
@@ -257,7 +258,7 @@ async function cloudApiFactory({ logger }, token) {
257
258
  deploy({ filePath, project }, { onUploadProgress }) {
258
259
  return axiosCloudAPI.post(
259
260
  `/deploy/${project.name}`,
260
- { file: fse.createReadStream(filePath) },
261
+ { file: fse__default.createReadStream(filePath) },
261
262
  {
262
263
  headers: {
263
264
  "Content-Type": "multipart/form-data"
@@ -300,8 +301,19 @@ async function cloudApiFactory({ logger }, token) {
300
301
  throw error;
301
302
  }
302
303
  },
303
- listProjects() {
304
- return axiosCloudAPI.get("/projects");
304
+ async listProjects() {
305
+ try {
306
+ const response = await axiosCloudAPI.get("/projects");
307
+ if (response.status !== 200) {
308
+ throw new Error("Error fetching cloud projects from the server.");
309
+ }
310
+ return response;
311
+ } catch (error) {
312
+ logger.debug(
313
+ "🥲 Oops! Couldn't retrieve your project's list from the server. Please try again."
314
+ );
315
+ throw error;
316
+ }
305
317
  },
306
318
  track(event, payload = {}) {
307
319
  return axiosCloudAPI.post("/track", {
@@ -316,18 +328,18 @@ async function save(data, { directoryPath } = {}) {
316
328
  const alreadyInFileData = await retrieve({ directoryPath });
317
329
  const storedData = { ...alreadyInFileData, ...data };
318
330
  const pathToFile = path__default.join(directoryPath || process.cwd(), LOCAL_SAVE_FILENAME);
319
- await fse.ensureDir(path__default.dirname(pathToFile));
320
- await fse.writeJson(pathToFile, storedData, { encoding: "utf8" });
331
+ await fse__default.ensureDir(path__default.dirname(pathToFile));
332
+ await fse__default.writeJson(pathToFile, storedData, { encoding: "utf8" });
321
333
  }
322
334
  async function retrieve({
323
335
  directoryPath
324
336
  } = {}) {
325
337
  const pathToFile = path__default.join(directoryPath || process.cwd(), LOCAL_SAVE_FILENAME);
326
- const pathExists = await fse.pathExists(pathToFile);
338
+ const pathExists = await fse__default.pathExists(pathToFile);
327
339
  if (!pathExists) {
328
340
  return {};
329
341
  }
330
- return fse.readJSON(pathToFile, { encoding: "utf8" });
342
+ return fse__default.readJSON(pathToFile, { encoding: "utf8" });
331
343
  }
332
344
  const strapiInfoSave = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
333
345
  __proto__: null,
@@ -599,7 +611,7 @@ const loadPkg = async ({ cwd, logger }) => {
599
611
  if (!pkgPath) {
600
612
  throw new Error("Could not find a package.json in the current directory");
601
613
  }
602
- const buffer = await fs$1.readFile(pkgPath);
614
+ const buffer = await fse.readFile(pkgPath);
603
615
  const pkg = JSON.parse(buffer.toString());
604
616
  logger.debug("Loaded package.json:", os.EOL, pkg);
605
617
  return pkg;
@@ -839,7 +851,7 @@ async function createProject$1(ctx, cloudApi, projectInput) {
839
851
  throw e;
840
852
  }
841
853
  }
842
- const action$2 = async (ctx) => {
854
+ const action$3 = async (ctx) => {
843
855
  const { logger } = ctx;
844
856
  const { getValidToken, eraseToken } = await tokenServiceFactory(ctx);
845
857
  const token = await getValidToken(ctx, promptLogin);
@@ -996,13 +1008,13 @@ async function upload(ctx, project, token, maxProjectFileSize) {
996
1008
  process.exit(1);
997
1009
  }
998
1010
  const tarFilePath = path__default.resolve(storagePath, compressedFilename);
999
- const fileStats = await fse.stat(tarFilePath);
1011
+ const fileStats = await fse__default.stat(tarFilePath);
1000
1012
  if (fileStats.size > maxProjectFileSize) {
1001
1013
  ctx.logger.log(
1002
1014
  "Unable to proceed: Your project is too big to be transferred, please use a git repo instead."
1003
1015
  );
1004
1016
  try {
1005
- await fse.remove(tarFilePath);
1017
+ await fse__default.remove(tarFilePath);
1006
1018
  } catch (e) {
1007
1019
  ctx.logger.log("Unable to remove file: ", tarFilePath);
1008
1020
  ctx.logger.debug(e);
@@ -1041,7 +1053,7 @@ async function upload(ctx, project, token, maxProjectFileSize) {
1041
1053
  }
1042
1054
  ctx.logger.debug(e);
1043
1055
  } finally {
1044
- await fse.remove(tarFilePath);
1056
+ await fse__default.remove(tarFilePath);
1045
1057
  }
1046
1058
  process.exit(0);
1047
1059
  } catch (e) {
@@ -1054,7 +1066,7 @@ async function getProject(ctx) {
1054
1066
  const { project } = await retrieve();
1055
1067
  if (!project) {
1056
1068
  try {
1057
- return await action$2(ctx);
1069
+ return await action$3(ctx);
1058
1070
  } catch (e) {
1059
1071
  ctx.logger.error("An error occurred while deploying the project. Please try again later.");
1060
1072
  ctx.logger.debug(e);
@@ -1063,7 +1075,7 @@ async function getProject(ctx) {
1063
1075
  }
1064
1076
  return project;
1065
1077
  }
1066
- const action$1 = async (ctx) => {
1078
+ const action$2 = async (ctx) => {
1067
1079
  const { getValidToken } = await tokenServiceFactory(ctx);
1068
1080
  const token = await getValidToken(ctx, promptLogin);
1069
1081
  if (!token) {
@@ -1137,16 +1149,16 @@ const runAction = (name2, action2) => (...args) => {
1137
1149
  process.exit(1);
1138
1150
  });
1139
1151
  };
1140
- const command$3 = ({ command: command2, ctx }) => {
1141
- 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$1)(ctx));
1152
+ const command$4 = ({ command: command2, ctx }) => {
1153
+ 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$2)(ctx));
1142
1154
  };
1143
1155
  const deployProject = {
1144
1156
  name: "deploy-project",
1145
1157
  description: "Deploy a Strapi Cloud project",
1146
- action: action$1,
1147
- command: command$3
1158
+ action: action$2,
1159
+ command: command$4
1148
1160
  };
1149
- const command$2 = ({ command: command2, ctx }) => {
1161
+ const command$3 = ({ command: command2, ctx }) => {
1150
1162
  command2.command("cloud:login").alias("login").description("Strapi Cloud Login").addHelpText(
1151
1163
  "after",
1152
1164
  "\nAfter running this command, you will be prompted to enter your authentication information."
@@ -1156,10 +1168,10 @@ const login = {
1156
1168
  name: "login",
1157
1169
  description: "Strapi Cloud Login",
1158
1170
  action: loginAction,
1159
- command: command$2
1171
+ command: command$3
1160
1172
  };
1161
1173
  const openModule = import("open");
1162
- const action = async (ctx) => {
1174
+ const action$1 = async (ctx) => {
1163
1175
  const { logger } = ctx;
1164
1176
  const { retrieveToken, eraseToken } = await tokenServiceFactory(ctx);
1165
1177
  const token = await retrieveToken();
@@ -1195,31 +1207,61 @@ const action = async (ctx) => {
1195
1207
  logger.debug("Failed to track logout event", e);
1196
1208
  }
1197
1209
  };
1198
- const command$1 = ({ command: command2, ctx }) => {
1199
- 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)(ctx));
1210
+ const command$2 = ({ command: command2, ctx }) => {
1211
+ 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));
1200
1212
  };
1201
1213
  const logout = {
1202
1214
  name: "logout",
1203
1215
  description: "Strapi Cloud Logout",
1204
- action,
1205
- command: command$1
1216
+ action: action$1,
1217
+ command: command$2
1206
1218
  };
1207
- const command = ({ command: command2, ctx }) => {
1208
- 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$2)(ctx));
1219
+ const command$1 = ({ command: command2, ctx }) => {
1220
+ 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$3)(ctx));
1209
1221
  };
1210
1222
  const createProject = {
1211
1223
  name: "create-project",
1212
1224
  description: "Create a new project",
1213
- action: action$2,
1225
+ action: action$3,
1226
+ command: command$1
1227
+ };
1228
+ const action = async (ctx) => {
1229
+ const { getValidToken } = await tokenServiceFactory(ctx);
1230
+ const token = await getValidToken(ctx, promptLogin);
1231
+ const { logger } = ctx;
1232
+ if (!token) {
1233
+ return;
1234
+ }
1235
+ const cloudApiService = await cloudApiFactory(ctx, token);
1236
+ const spinner = logger.spinner("Fetching your projects...").start();
1237
+ try {
1238
+ const {
1239
+ data: { data: projectList }
1240
+ } = await cloudApiService.listProjects();
1241
+ spinner.succeed();
1242
+ logger.log(projectList);
1243
+ } catch (e) {
1244
+ ctx.logger.debug("Failed to list projects", e);
1245
+ spinner.fail("An error occurred while fetching your projects from Strapi Cloud.");
1246
+ }
1247
+ };
1248
+ const command = ({ command: command2, ctx }) => {
1249
+ command2.command("cloud:projects").alias("projects").description("List Strapi Cloud projects").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("listProjects", action)(ctx));
1250
+ };
1251
+ const listProjects = {
1252
+ name: "list-projects",
1253
+ description: "List Strapi Cloud projects",
1254
+ action,
1214
1255
  command
1215
1256
  };
1216
1257
  const cli = {
1217
1258
  deployProject,
1218
1259
  login,
1219
1260
  logout,
1220
- createProject
1261
+ createProject,
1262
+ listProjects
1221
1263
  };
1222
- const cloudCommands = [deployProject, login, logout];
1264
+ const cloudCommands = [deployProject, login, logout, listProjects];
1223
1265
  async function initCloudCLIConfig() {
1224
1266
  const localConfig = await getLocalConfig();
1225
1267
  if (!localConfig.deviceId) {