@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.js CHANGED
@@ -29,7 +29,6 @@ const chalk = require("chalk");
29
29
  const axios = require("axios");
30
30
  const crypto = require("node:crypto");
31
31
  const utils = require("@strapi/utils");
32
- const fs = require("fs");
33
32
  const tar = require("tar");
34
33
  const minimatch = require("minimatch");
35
34
  const inquirer = require("inquirer");
@@ -41,7 +40,6 @@ const jwt = require("jsonwebtoken");
41
40
  const stringify = require("fast-safe-stringify");
42
41
  const ora = require("ora");
43
42
  const cliProgress = require("cli-progress");
44
- const fs$1 = require("fs/promises");
45
43
  const pkgUp = require("pkg-up");
46
44
  const yup = require("yup");
47
45
  const _ = require("lodash");
@@ -66,12 +64,11 @@ function _interopNamespace(e) {
66
64
  return Object.freeze(n);
67
65
  }
68
66
  const crypto__default = /* @__PURE__ */ _interopDefault(crypto$1);
69
- const fse__default = /* @__PURE__ */ _interopDefault(fse);
67
+ const fse__namespace = /* @__PURE__ */ _interopNamespace(fse);
70
68
  const path__namespace = /* @__PURE__ */ _interopNamespace(path);
71
69
  const chalk__default = /* @__PURE__ */ _interopDefault(chalk);
72
70
  const axios__default = /* @__PURE__ */ _interopDefault(axios);
73
71
  const crypto__namespace = /* @__PURE__ */ _interopNamespace(crypto);
74
- const fs__namespace = /* @__PURE__ */ _interopNamespace(fs);
75
72
  const tar__namespace = /* @__PURE__ */ _interopNamespace(tar);
76
73
  const inquirer__default = /* @__PURE__ */ _interopDefault(inquirer);
77
74
  const os__default = /* @__PURE__ */ _interopDefault(os);
@@ -81,7 +78,6 @@ const jwt__default = /* @__PURE__ */ _interopDefault(jwt);
81
78
  const stringify__default = /* @__PURE__ */ _interopDefault(stringify);
82
79
  const ora__default = /* @__PURE__ */ _interopDefault(ora);
83
80
  const cliProgress__namespace = /* @__PURE__ */ _interopNamespace(cliProgress);
84
- const fs__default = /* @__PURE__ */ _interopDefault(fs$1);
85
81
  const pkgUp__default = /* @__PURE__ */ _interopDefault(pkgUp);
86
82
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
87
83
  const ___default = /* @__PURE__ */ _interopDefault(_);
@@ -104,23 +100,6 @@ const IGNORED_PATTERNS = [
104
100
  "**/.idea/**",
105
101
  "**/.vscode/**"
106
102
  ];
107
- const getFiles = (dirPath, ignorePatterns = [], arrayOfFiles = [], subfolder = "") => {
108
- const entries = fs__namespace.readdirSync(path__namespace.join(dirPath, subfolder));
109
- entries.forEach((entry) => {
110
- const entryPathFromRoot = path__namespace.join(subfolder, entry);
111
- const entryPath = path__namespace.relative(dirPath, entryPathFromRoot);
112
- const isIgnored = isIgnoredFile(dirPath, entryPathFromRoot, ignorePatterns);
113
- if (isIgnored) {
114
- return;
115
- }
116
- if (fs__namespace.statSync(entryPath).isDirectory()) {
117
- getFiles(dirPath, ignorePatterns, arrayOfFiles, entryPathFromRoot);
118
- } else {
119
- arrayOfFiles.push(entryPath);
120
- }
121
- });
122
- return arrayOfFiles;
123
- };
124
103
  const isIgnoredFile = (folderPath, file, ignorePatterns) => {
125
104
  ignorePatterns.push(...IGNORED_PATTERNS);
126
105
  const relativeFilePath = path__namespace.join(folderPath, file);
@@ -138,16 +117,35 @@ const isIgnoredFile = (folderPath, file, ignorePatterns) => {
138
117
  }
139
118
  return isIgnored;
140
119
  };
141
- const readGitignore = (folderPath) => {
120
+ const getFiles = async (dirPath, ignorePatterns = [], subfolder = "") => {
121
+ const arrayOfFiles = [];
122
+ const entries = await fse__namespace.readdir(path__namespace.join(dirPath, subfolder));
123
+ for (const entry of entries) {
124
+ const entryPathFromRoot = path__namespace.join(subfolder, entry);
125
+ const entryPath = path__namespace.relative(dirPath, entryPathFromRoot);
126
+ const isIgnored = isIgnoredFile(dirPath, entryPathFromRoot, ignorePatterns);
127
+ if (!isIgnored) {
128
+ if (fse__namespace.statSync(entryPath).isDirectory()) {
129
+ const subFiles = await getFiles(dirPath, ignorePatterns, entryPathFromRoot);
130
+ arrayOfFiles.push(...subFiles);
131
+ } else {
132
+ arrayOfFiles.push(entryPath);
133
+ }
134
+ }
135
+ }
136
+ return arrayOfFiles;
137
+ };
138
+ const readGitignore = async (folderPath) => {
142
139
  const gitignorePath = path__namespace.resolve(folderPath, ".gitignore");
143
- if (!fs__namespace.existsSync(gitignorePath))
140
+ const pathExist = await fse__namespace.pathExists(gitignorePath);
141
+ if (!pathExist)
144
142
  return [];
145
- const gitignoreContent = fs__namespace.readFileSync(gitignorePath, "utf8");
143
+ const gitignoreContent = await fse__namespace.readFile(gitignorePath, "utf8");
146
144
  return gitignoreContent.split(/\r?\n/).filter((line) => Boolean(line.trim()) && !line.startsWith("#"));
147
145
  };
148
146
  const compressFilesToTar = async (storagePath, folderToCompress, filename) => {
149
- const ignorePatterns = readGitignore(folderToCompress);
150
- const filesToCompress = getFiles(folderToCompress, ignorePatterns);
147
+ const ignorePatterns = await readGitignore(folderToCompress);
148
+ const filesToCompress = await getFiles(folderToCompress, ignorePatterns);
151
149
  return tar__namespace.c(
152
150
  {
153
151
  gzip: true,
@@ -160,7 +158,7 @@ const APP_FOLDER_NAME = "com.strapi.cli";
160
158
  const CONFIG_FILENAME = "config.json";
161
159
  async function checkDirectoryExists(directoryPath) {
162
160
  try {
163
- const fsStat = await fse__default.default.lstat(directoryPath);
161
+ const fsStat = await fse__namespace.default.lstat(directoryPath);
164
162
  return fsStat.isDirectory();
165
163
  } catch (e) {
166
164
  return false;
@@ -168,14 +166,14 @@ async function checkDirectoryExists(directoryPath) {
168
166
  }
169
167
  async function getTmpStoragePath() {
170
168
  const storagePath = path__namespace.default.join(os__default.default.tmpdir(), APP_FOLDER_NAME);
171
- await fse__default.default.ensureDir(storagePath);
169
+ await fse__namespace.default.ensureDir(storagePath);
172
170
  return storagePath;
173
171
  }
174
172
  async function getConfigPath() {
175
173
  const configDirs = XDGAppPaths__default.default(APP_FOLDER_NAME).configDirs();
176
174
  const configPath = configDirs.find(checkDirectoryExists);
177
175
  if (!configPath) {
178
- await fse__default.default.ensureDir(configDirs[0]);
176
+ await fse__namespace.default.ensureDir(configDirs[0]);
179
177
  return configDirs[0];
180
178
  }
181
179
  return configPath;
@@ -183,9 +181,9 @@ async function getConfigPath() {
183
181
  async function getLocalConfig() {
184
182
  const configPath = await getConfigPath();
185
183
  const configFilePath = path__namespace.default.join(configPath, CONFIG_FILENAME);
186
- await fse__default.default.ensureFile(configFilePath);
184
+ await fse__namespace.default.ensureFile(configFilePath);
187
185
  try {
188
- return await fse__default.default.readJSON(configFilePath, { encoding: "utf8", throws: true });
186
+ return await fse__namespace.default.readJSON(configFilePath, { encoding: "utf8", throws: true });
189
187
  } catch (e) {
190
188
  return {};
191
189
  }
@@ -193,10 +191,10 @@ async function getLocalConfig() {
193
191
  async function saveLocalConfig(data) {
194
192
  const configPath = await getConfigPath();
195
193
  const configFilePath = path__namespace.default.join(configPath, CONFIG_FILENAME);
196
- await fse__default.default.writeJson(configFilePath, data, { encoding: "utf8", spaces: 2, mode: 384 });
194
+ await fse__namespace.default.writeJson(configFilePath, data, { encoding: "utf8", spaces: 2, mode: 384 });
197
195
  }
198
196
  const name = "@strapi/cloud-cli";
199
- const version = "4.25.2";
197
+ const version = "4.25.3";
200
198
  const description = "Commands to interact with the Strapi Cloud";
201
199
  const keywords = [
202
200
  "strapi",
@@ -241,7 +239,7 @@ const scripts = {
241
239
  watch: "pack-up watch"
242
240
  };
243
241
  const dependencies = {
244
- "@strapi/utils": "4.25.2",
242
+ "@strapi/utils": "4.25.3",
245
243
  axios: "1.6.0",
246
244
  chalk: "4.1.2",
247
245
  "cli-progress": "3.12.0",
@@ -266,8 +264,8 @@ const devDependencies = {
266
264
  "@types/cli-progress": "3.11.5",
267
265
  "@types/eventsource": "1.1.15",
268
266
  "@types/lodash": "^4.14.191",
269
- "eslint-config-custom": "4.25.2",
270
- tsconfig: "4.25.2"
267
+ "eslint-config-custom": "4.25.3",
268
+ tsconfig: "4.25.3"
271
269
  };
272
270
  const engines = {
273
271
  node: ">=18.0.0 <=20.x.x",
@@ -320,7 +318,7 @@ async function cloudApiFactory({ logger }, token) {
320
318
  deploy({ filePath, project }, { onUploadProgress }) {
321
319
  return axiosCloudAPI.post(
322
320
  `/deploy/${project.name}`,
323
- { file: fse__default.default.createReadStream(filePath) },
321
+ { file: fse__namespace.default.createReadStream(filePath) },
324
322
  {
325
323
  headers: {
326
324
  "Content-Type": "multipart/form-data"
@@ -363,8 +361,19 @@ async function cloudApiFactory({ logger }, token) {
363
361
  throw error;
364
362
  }
365
363
  },
366
- listProjects() {
367
- return axiosCloudAPI.get("/projects");
364
+ async listProjects() {
365
+ try {
366
+ const response = await axiosCloudAPI.get("/projects");
367
+ if (response.status !== 200) {
368
+ throw new Error("Error fetching cloud projects from the server.");
369
+ }
370
+ return response;
371
+ } catch (error) {
372
+ logger.debug(
373
+ "🥲 Oops! Couldn't retrieve your project's list from the server. Please try again."
374
+ );
375
+ throw error;
376
+ }
368
377
  },
369
378
  track(event, payload = {}) {
370
379
  return axiosCloudAPI.post("/track", {
@@ -379,18 +388,18 @@ async function save(data, { directoryPath } = {}) {
379
388
  const alreadyInFileData = await retrieve({ directoryPath });
380
389
  const storedData = { ...alreadyInFileData, ...data };
381
390
  const pathToFile = path__namespace.default.join(directoryPath || process.cwd(), LOCAL_SAVE_FILENAME);
382
- await fse__default.default.ensureDir(path__namespace.default.dirname(pathToFile));
383
- await fse__default.default.writeJson(pathToFile, storedData, { encoding: "utf8" });
391
+ await fse__namespace.default.ensureDir(path__namespace.default.dirname(pathToFile));
392
+ await fse__namespace.default.writeJson(pathToFile, storedData, { encoding: "utf8" });
384
393
  }
385
394
  async function retrieve({
386
395
  directoryPath
387
396
  } = {}) {
388
397
  const pathToFile = path__namespace.default.join(directoryPath || process.cwd(), LOCAL_SAVE_FILENAME);
389
- const pathExists = await fse__default.default.pathExists(pathToFile);
398
+ const pathExists = await fse__namespace.default.pathExists(pathToFile);
390
399
  if (!pathExists) {
391
400
  return {};
392
401
  }
393
- return fse__default.default.readJSON(pathToFile, { encoding: "utf8" });
402
+ return fse__namespace.default.readJSON(pathToFile, { encoding: "utf8" });
394
403
  }
395
404
  const strapiInfoSave = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
396
405
  __proto__: null,
@@ -662,7 +671,7 @@ const loadPkg = async ({ cwd, logger }) => {
662
671
  if (!pkgPath) {
663
672
  throw new Error("Could not find a package.json in the current directory");
664
673
  }
665
- const buffer = await fs__default.default.readFile(pkgPath);
674
+ const buffer = await fse__namespace.readFile(pkgPath);
666
675
  const pkg = JSON.parse(buffer.toString());
667
676
  logger.debug("Loaded package.json:", os__default.default.EOL, pkg);
668
677
  return pkg;
@@ -902,7 +911,7 @@ async function createProject$1(ctx, cloudApi, projectInput) {
902
911
  throw e;
903
912
  }
904
913
  }
905
- const action$2 = async (ctx) => {
914
+ const action$3 = async (ctx) => {
906
915
  const { logger } = ctx;
907
916
  const { getValidToken, eraseToken } = await tokenServiceFactory(ctx);
908
917
  const token = await getValidToken(ctx, promptLogin);
@@ -1059,13 +1068,13 @@ async function upload(ctx, project, token, maxProjectFileSize) {
1059
1068
  process.exit(1);
1060
1069
  }
1061
1070
  const tarFilePath = path__namespace.default.resolve(storagePath, compressedFilename);
1062
- const fileStats = await fse__default.default.stat(tarFilePath);
1071
+ const fileStats = await fse__namespace.default.stat(tarFilePath);
1063
1072
  if (fileStats.size > maxProjectFileSize) {
1064
1073
  ctx.logger.log(
1065
1074
  "Unable to proceed: Your project is too big to be transferred, please use a git repo instead."
1066
1075
  );
1067
1076
  try {
1068
- await fse__default.default.remove(tarFilePath);
1077
+ await fse__namespace.default.remove(tarFilePath);
1069
1078
  } catch (e) {
1070
1079
  ctx.logger.log("Unable to remove file: ", tarFilePath);
1071
1080
  ctx.logger.debug(e);
@@ -1104,7 +1113,7 @@ async function upload(ctx, project, token, maxProjectFileSize) {
1104
1113
  }
1105
1114
  ctx.logger.debug(e);
1106
1115
  } finally {
1107
- await fse__default.default.remove(tarFilePath);
1116
+ await fse__namespace.default.remove(tarFilePath);
1108
1117
  }
1109
1118
  process.exit(0);
1110
1119
  } catch (e) {
@@ -1117,7 +1126,7 @@ async function getProject(ctx) {
1117
1126
  const { project } = await retrieve();
1118
1127
  if (!project) {
1119
1128
  try {
1120
- return await action$2(ctx);
1129
+ return await action$3(ctx);
1121
1130
  } catch (e) {
1122
1131
  ctx.logger.error("An error occurred while deploying the project. Please try again later.");
1123
1132
  ctx.logger.debug(e);
@@ -1126,7 +1135,7 @@ async function getProject(ctx) {
1126
1135
  }
1127
1136
  return project;
1128
1137
  }
1129
- const action$1 = async (ctx) => {
1138
+ const action$2 = async (ctx) => {
1130
1139
  const { getValidToken } = await tokenServiceFactory(ctx);
1131
1140
  const token = await getValidToken(ctx, promptLogin);
1132
1141
  if (!token) {
@@ -1200,16 +1209,16 @@ const runAction = (name2, action2) => (...args) => {
1200
1209
  process.exit(1);
1201
1210
  });
1202
1211
  };
1203
- const command$3 = ({ command: command2, ctx }) => {
1204
- 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));
1212
+ const command$4 = ({ command: command2, ctx }) => {
1213
+ 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));
1205
1214
  };
1206
1215
  const deployProject = {
1207
1216
  name: "deploy-project",
1208
1217
  description: "Deploy a Strapi Cloud project",
1209
- action: action$1,
1210
- command: command$3
1218
+ action: action$2,
1219
+ command: command$4
1211
1220
  };
1212
- const command$2 = ({ command: command2, ctx }) => {
1221
+ const command$3 = ({ command: command2, ctx }) => {
1213
1222
  command2.command("cloud:login").alias("login").description("Strapi Cloud Login").addHelpText(
1214
1223
  "after",
1215
1224
  "\nAfter running this command, you will be prompted to enter your authentication information."
@@ -1219,10 +1228,10 @@ const login = {
1219
1228
  name: "login",
1220
1229
  description: "Strapi Cloud Login",
1221
1230
  action: loginAction,
1222
- command: command$2
1231
+ command: command$3
1223
1232
  };
1224
1233
  const openModule = import("open");
1225
- const action = async (ctx) => {
1234
+ const action$1 = async (ctx) => {
1226
1235
  const { logger } = ctx;
1227
1236
  const { retrieveToken, eraseToken } = await tokenServiceFactory(ctx);
1228
1237
  const token = await retrieveToken();
@@ -1258,31 +1267,61 @@ const action = async (ctx) => {
1258
1267
  logger.debug("Failed to track logout event", e);
1259
1268
  }
1260
1269
  };
1261
- const command$1 = ({ command: command2, ctx }) => {
1262
- 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));
1270
+ const command$2 = ({ command: command2, ctx }) => {
1271
+ 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));
1263
1272
  };
1264
1273
  const logout = {
1265
1274
  name: "logout",
1266
1275
  description: "Strapi Cloud Logout",
1267
- action,
1268
- command: command$1
1276
+ action: action$1,
1277
+ command: command$2
1269
1278
  };
1270
- const command = ({ command: command2, ctx }) => {
1271
- 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));
1279
+ const command$1 = ({ command: command2, ctx }) => {
1280
+ 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));
1272
1281
  };
1273
1282
  const createProject = {
1274
1283
  name: "create-project",
1275
1284
  description: "Create a new project",
1276
- action: action$2,
1285
+ action: action$3,
1286
+ command: command$1
1287
+ };
1288
+ const action = async (ctx) => {
1289
+ const { getValidToken } = await tokenServiceFactory(ctx);
1290
+ const token = await getValidToken(ctx, promptLogin);
1291
+ const { logger } = ctx;
1292
+ if (!token) {
1293
+ return;
1294
+ }
1295
+ const cloudApiService = await cloudApiFactory(ctx, token);
1296
+ const spinner = logger.spinner("Fetching your projects...").start();
1297
+ try {
1298
+ const {
1299
+ data: { data: projectList }
1300
+ } = await cloudApiService.listProjects();
1301
+ spinner.succeed();
1302
+ logger.log(projectList);
1303
+ } catch (e) {
1304
+ ctx.logger.debug("Failed to list projects", e);
1305
+ spinner.fail("An error occurred while fetching your projects from Strapi Cloud.");
1306
+ }
1307
+ };
1308
+ const command = ({ command: command2, ctx }) => {
1309
+ 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));
1310
+ };
1311
+ const listProjects = {
1312
+ name: "list-projects",
1313
+ description: "List Strapi Cloud projects",
1314
+ action,
1277
1315
  command
1278
1316
  };
1279
1317
  const cli = {
1280
1318
  deployProject,
1281
1319
  login,
1282
1320
  logout,
1283
- createProject
1321
+ createProject,
1322
+ listProjects
1284
1323
  };
1285
- const cloudCommands = [deployProject, login, logout];
1324
+ const cloudCommands = [deployProject, login, logout, listProjects];
1286
1325
  async function initCloudCLIConfig() {
1287
1326
  const localConfig = await getLocalConfig();
1288
1327
  if (!localConfig.deviceId) {