@strapi/cloud-cli 4.25.3 → 4.25.5
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 +304 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +305 -96
- package/dist/index.mjs.map +1 -1
- package/dist/src/deploy-project/action.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/link/action.d.ts +4 -0
- package/dist/src/link/action.d.ts.map +1 -0
- package/dist/src/link/command.d.ts +7 -0
- package/dist/src/link/command.d.ts.map +1 -0
- package/dist/src/link/index.d.ts +7 -0
- package/dist/src/link/index.d.ts.map +1 -0
- package/dist/src/list-projects/action.d.ts +4 -0
- package/dist/src/list-projects/action.d.ts.map +1 -0
- package/dist/src/list-projects/command.d.ts +7 -0
- package/dist/src/list-projects/command.d.ts.map +1 -0
- package/dist/src/list-projects/index.d.ts +7 -0
- package/dist/src/list-projects/index.d.ts.map +1 -0
- package/dist/src/login/action.d.ts.map +1 -1
- package/dist/src/logout/action.d.ts.map +1 -1
- package/dist/src/services/build-logs.d.ts.map +1 -1
- package/dist/src/services/cli-api.d.ts +19 -7
- package/dist/src/services/cli-api.d.ts.map +1 -1
- package/dist/src/services/strapi-info-save.d.ts +1 -1
- package/dist/src/services/strapi-info-save.d.ts.map +1 -1
- package/dist/src/types.d.ts +1 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/analytics.d.ts +4 -0
- package/dist/src/utils/analytics.d.ts.map +1 -0
- package/dist/src/utils/compress-files.d.ts.map +1 -1
- package/dist/src/utils/pkg.d.ts.map +1 -1
- package/package.json +5 -5
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
|
|
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
|
|
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
|
-
|
|
140
|
+
const pathExist = await fse__namespace.pathExists(gitignorePath);
|
|
141
|
+
if (!pathExist)
|
|
144
142
|
return [];
|
|
145
|
-
const gitignoreContent =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
184
|
+
await fse__namespace.default.ensureFile(configFilePath);
|
|
187
185
|
try {
|
|
188
|
-
return await
|
|
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
|
|
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.
|
|
197
|
+
const version = "4.25.4";
|
|
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.
|
|
242
|
+
"@strapi/utils": "4.25.4",
|
|
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.
|
|
270
|
-
tsconfig: "4.25.
|
|
267
|
+
"eslint-config-custom": "4.25.4",
|
|
268
|
+
tsconfig: "4.25.4"
|
|
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:
|
|
321
|
+
{ file: fse__namespace.default.createReadStream(filePath) },
|
|
324
322
|
{
|
|
325
323
|
headers: {
|
|
326
324
|
"Content-Type": "multipart/form-data"
|
|
@@ -363,8 +361,33 @@ async function cloudApiFactory({ logger }, token) {
|
|
|
363
361
|
throw error;
|
|
364
362
|
}
|
|
365
363
|
},
|
|
366
|
-
listProjects() {
|
|
367
|
-
|
|
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
|
+
}
|
|
377
|
+
},
|
|
378
|
+
async listLinkProjects() {
|
|
379
|
+
try {
|
|
380
|
+
const response = await axiosCloudAPI.get("/projects/linkable");
|
|
381
|
+
if (response.status !== 200) {
|
|
382
|
+
throw new Error("Error fetching cloud projects from the server.");
|
|
383
|
+
}
|
|
384
|
+
return response;
|
|
385
|
+
} catch (error) {
|
|
386
|
+
logger.debug(
|
|
387
|
+
"🥲 Oops! Couldn't retrieve your project's list from the server. Please try again."
|
|
388
|
+
);
|
|
389
|
+
throw error;
|
|
390
|
+
}
|
|
368
391
|
},
|
|
369
392
|
track(event, payload = {}) {
|
|
370
393
|
return axiosCloudAPI.post("/track", {
|
|
@@ -379,18 +402,18 @@ async function save(data, { directoryPath } = {}) {
|
|
|
379
402
|
const alreadyInFileData = await retrieve({ directoryPath });
|
|
380
403
|
const storedData = { ...alreadyInFileData, ...data };
|
|
381
404
|
const pathToFile = path__namespace.default.join(directoryPath || process.cwd(), LOCAL_SAVE_FILENAME);
|
|
382
|
-
await
|
|
383
|
-
await
|
|
405
|
+
await fse__namespace.default.ensureDir(path__namespace.default.dirname(pathToFile));
|
|
406
|
+
await fse__namespace.default.writeJson(pathToFile, storedData, { encoding: "utf8" });
|
|
384
407
|
}
|
|
385
408
|
async function retrieve({
|
|
386
409
|
directoryPath
|
|
387
410
|
} = {}) {
|
|
388
411
|
const pathToFile = path__namespace.default.join(directoryPath || process.cwd(), LOCAL_SAVE_FILENAME);
|
|
389
|
-
const pathExists = await
|
|
412
|
+
const pathExists = await fse__namespace.default.pathExists(pathToFile);
|
|
390
413
|
if (!pathExists) {
|
|
391
414
|
return {};
|
|
392
415
|
}
|
|
393
|
-
return
|
|
416
|
+
return fse__namespace.default.readJSON(pathToFile, { encoding: "utf8" });
|
|
394
417
|
}
|
|
395
418
|
const strapiInfoSave = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
396
419
|
__proto__: null,
|
|
@@ -662,7 +685,7 @@ const loadPkg = async ({ cwd, logger }) => {
|
|
|
662
685
|
if (!pkgPath) {
|
|
663
686
|
throw new Error("Could not find a package.json in the current directory");
|
|
664
687
|
}
|
|
665
|
-
const buffer = await
|
|
688
|
+
const buffer = await fse__namespace.readFile(pkgPath);
|
|
666
689
|
const pkg = JSON.parse(buffer.toString());
|
|
667
690
|
logger.debug("Loaded package.json:", os__default.default.EOL, pkg);
|
|
668
691
|
return pkg;
|
|
@@ -687,6 +710,13 @@ function applyDefaultName(newDefaultName, questions, defaultValues) {
|
|
|
687
710
|
});
|
|
688
711
|
return { newQuestions, newDefaultValues };
|
|
689
712
|
}
|
|
713
|
+
const trackEvent = async (ctx, cloudApiService, eventName, eventData) => {
|
|
714
|
+
try {
|
|
715
|
+
await cloudApiService.track(eventName, eventData);
|
|
716
|
+
} catch (e) {
|
|
717
|
+
ctx.logger.debug(`Failed to track ${eventName}`, e);
|
|
718
|
+
}
|
|
719
|
+
};
|
|
690
720
|
const openModule$1 = import("open");
|
|
691
721
|
async function promptLogin(ctx) {
|
|
692
722
|
const response = await inquirer__default.default.prompt([
|
|
@@ -707,13 +737,6 @@ async function loginAction(ctx) {
|
|
|
707
737
|
const tokenService = await tokenServiceFactory(ctx);
|
|
708
738
|
const existingToken = await tokenService.retrieveToken();
|
|
709
739
|
const cloudApiService = await cloudApiFactory(ctx, existingToken || void 0);
|
|
710
|
-
const trackFailedLogin = async () => {
|
|
711
|
-
try {
|
|
712
|
-
await cloudApiService.track("didNotLogin", { loginMethod: "cli" });
|
|
713
|
-
} catch (e) {
|
|
714
|
-
logger.debug("Failed to track failed login", e);
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
740
|
if (existingToken) {
|
|
718
741
|
const isTokenValid = await tokenService.isTokenValid(existingToken);
|
|
719
742
|
if (isTokenValid) {
|
|
@@ -745,11 +768,7 @@ async function loginAction(ctx) {
|
|
|
745
768
|
logger.debug(e);
|
|
746
769
|
return false;
|
|
747
770
|
}
|
|
748
|
-
|
|
749
|
-
await cloudApiService.track("willLoginAttempt", {});
|
|
750
|
-
} catch (e) {
|
|
751
|
-
logger.debug("Failed to track login attempt", e);
|
|
752
|
-
}
|
|
771
|
+
await trackEvent(ctx, cloudApiService, "willLoginAttempt", {});
|
|
753
772
|
logger.debug("🔐 Creating device authentication request...", {
|
|
754
773
|
client_id: cliConfig2.clientId,
|
|
755
774
|
scope: cliConfig2.scope,
|
|
@@ -829,13 +848,13 @@ async function loginAction(ctx) {
|
|
|
829
848
|
"There seems to be a problem with your login information. Please try logging in again."
|
|
830
849
|
);
|
|
831
850
|
spinnerFail();
|
|
832
|
-
await
|
|
851
|
+
await trackEvent(ctx, cloudApiService, "didNotLogin", { loginMethod: "cli" });
|
|
833
852
|
return false;
|
|
834
853
|
}
|
|
835
854
|
if (e.response?.data.error && !["authorization_pending", "slow_down"].includes(e.response.data.error)) {
|
|
836
855
|
logger.debug(e);
|
|
837
856
|
spinnerFail();
|
|
838
|
-
await
|
|
857
|
+
await trackEvent(ctx, cloudApiService, "didNotLogin", { loginMethod: "cli" });
|
|
839
858
|
return false;
|
|
840
859
|
}
|
|
841
860
|
await new Promise((resolve) => {
|
|
@@ -849,11 +868,7 @@ async function loginAction(ctx) {
|
|
|
849
868
|
"To access your dashboard, please copy and paste the following URL into your web browser:"
|
|
850
869
|
);
|
|
851
870
|
logger.log(chalk__default.default.underline(`${apiConfig.dashboardBaseUrl}/projects`));
|
|
852
|
-
|
|
853
|
-
await cloudApiService.track("didLogin", { loginMethod: "cli" });
|
|
854
|
-
} catch (e) {
|
|
855
|
-
logger.debug("Failed to track login", e);
|
|
856
|
-
}
|
|
871
|
+
await trackEvent(ctx, cloudApiService, "didLogin", { loginMethod: "cli" });
|
|
857
872
|
};
|
|
858
873
|
await authenticate();
|
|
859
874
|
return isAuthenticated;
|
|
@@ -902,7 +917,7 @@ async function createProject$1(ctx, cloudApi, projectInput) {
|
|
|
902
917
|
throw e;
|
|
903
918
|
}
|
|
904
919
|
}
|
|
905
|
-
const action$
|
|
920
|
+
const action$4 = async (ctx) => {
|
|
906
921
|
const { logger } = ctx;
|
|
907
922
|
const { getValidToken, eraseToken } = await tokenServiceFactory(ctx);
|
|
908
923
|
const token = await getValidToken(ctx, promptLogin);
|
|
@@ -1017,6 +1032,7 @@ const buildLogsServiceFactory = ({ logger }) => {
|
|
|
1017
1032
|
if (retries > MAX_RETRIES) {
|
|
1018
1033
|
spinner.fail("We were unable to connect to the server to get build logs at this time.");
|
|
1019
1034
|
es.close();
|
|
1035
|
+
clearExistingTimeout();
|
|
1020
1036
|
reject(new Error("Max retries reached"));
|
|
1021
1037
|
}
|
|
1022
1038
|
};
|
|
@@ -1059,13 +1075,13 @@ async function upload(ctx, project, token, maxProjectFileSize) {
|
|
|
1059
1075
|
process.exit(1);
|
|
1060
1076
|
}
|
|
1061
1077
|
const tarFilePath = path__namespace.default.resolve(storagePath, compressedFilename);
|
|
1062
|
-
const fileStats = await
|
|
1078
|
+
const fileStats = await fse__namespace.default.stat(tarFilePath);
|
|
1063
1079
|
if (fileStats.size > maxProjectFileSize) {
|
|
1064
1080
|
ctx.logger.log(
|
|
1065
1081
|
"Unable to proceed: Your project is too big to be transferred, please use a git repo instead."
|
|
1066
1082
|
);
|
|
1067
1083
|
try {
|
|
1068
|
-
await
|
|
1084
|
+
await fse__namespace.default.remove(tarFilePath);
|
|
1069
1085
|
} catch (e) {
|
|
1070
1086
|
ctx.logger.log("Unable to remove file: ", tarFilePath);
|
|
1071
1087
|
ctx.logger.debug(e);
|
|
@@ -1104,7 +1120,7 @@ async function upload(ctx, project, token, maxProjectFileSize) {
|
|
|
1104
1120
|
}
|
|
1105
1121
|
ctx.logger.debug(e);
|
|
1106
1122
|
} finally {
|
|
1107
|
-
await
|
|
1123
|
+
await fse__namespace.default.remove(tarFilePath);
|
|
1108
1124
|
}
|
|
1109
1125
|
process.exit(0);
|
|
1110
1126
|
} catch (e) {
|
|
@@ -1117,7 +1133,7 @@ async function getProject(ctx) {
|
|
|
1117
1133
|
const { project } = await retrieve();
|
|
1118
1134
|
if (!project) {
|
|
1119
1135
|
try {
|
|
1120
|
-
return await action$
|
|
1136
|
+
return await action$4(ctx);
|
|
1121
1137
|
} catch (e) {
|
|
1122
1138
|
ctx.logger.error("An error occurred while deploying the project. Please try again later.");
|
|
1123
1139
|
ctx.logger.debug(e);
|
|
@@ -1126,7 +1142,19 @@ async function getProject(ctx) {
|
|
|
1126
1142
|
}
|
|
1127
1143
|
return project;
|
|
1128
1144
|
}
|
|
1129
|
-
|
|
1145
|
+
async function getConfig({
|
|
1146
|
+
ctx,
|
|
1147
|
+
cloudApiService
|
|
1148
|
+
}) {
|
|
1149
|
+
try {
|
|
1150
|
+
const { data: cliConfig2 } = await cloudApiService.config();
|
|
1151
|
+
return cliConfig2;
|
|
1152
|
+
} catch (e) {
|
|
1153
|
+
ctx.logger.debug("Failed to get cli config", e);
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
const action$3 = async (ctx) => {
|
|
1130
1158
|
const { getValidToken } = await tokenServiceFactory(ctx);
|
|
1131
1159
|
const token = await getValidToken(ctx, promptLogin);
|
|
1132
1160
|
if (!token) {
|
|
@@ -1137,14 +1165,18 @@ const action$1 = async (ctx) => {
|
|
|
1137
1165
|
return;
|
|
1138
1166
|
}
|
|
1139
1167
|
const cloudApiService = await cloudApiFactory(ctx);
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
}
|
|
1143
|
-
ctx.logger.debug("Failed to track willDeploy", e);
|
|
1144
|
-
}
|
|
1168
|
+
await trackEvent(ctx, cloudApiService, "willDeployWithCLI", {
|
|
1169
|
+
projectInternalName: project.name
|
|
1170
|
+
});
|
|
1145
1171
|
const notificationService = notificationServiceFactory(ctx);
|
|
1146
1172
|
const buildLogsService = buildLogsServiceFactory(ctx);
|
|
1147
|
-
const
|
|
1173
|
+
const cliConfig2 = await getConfig({ ctx, cloudApiService });
|
|
1174
|
+
if (!cliConfig2) {
|
|
1175
|
+
ctx.logger.error(
|
|
1176
|
+
"An error occurred while retrieving data from Strapi Cloud. Please try check your network or again later."
|
|
1177
|
+
);
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1148
1180
|
let maxSize = parseInt(cliConfig2.maxProjectFileSize, 10);
|
|
1149
1181
|
if (Number.isNaN(maxSize)) {
|
|
1150
1182
|
ctx.logger.debug(
|
|
@@ -1166,10 +1198,11 @@ const action$1 = async (ctx) => {
|
|
|
1166
1198
|
chalk__default.default.underline(`${apiConfig.dashboardBaseUrl}/projects/${project.name}/deployments`)
|
|
1167
1199
|
);
|
|
1168
1200
|
} catch (e) {
|
|
1201
|
+
ctx.logger.debug(e);
|
|
1169
1202
|
if (e instanceof Error) {
|
|
1170
1203
|
ctx.logger.error(e.message);
|
|
1171
1204
|
} else {
|
|
1172
|
-
|
|
1205
|
+
ctx.logger.error("An error occurred while deploying the project. Please try again later.");
|
|
1173
1206
|
}
|
|
1174
1207
|
}
|
|
1175
1208
|
};
|
|
@@ -1200,16 +1233,162 @@ const runAction = (name2, action2) => (...args) => {
|
|
|
1200
1233
|
process.exit(1);
|
|
1201
1234
|
});
|
|
1202
1235
|
};
|
|
1203
|
-
const command$
|
|
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$
|
|
1236
|
+
const command$5 = ({ command: command2, ctx }) => {
|
|
1237
|
+
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));
|
|
1205
1238
|
};
|
|
1206
1239
|
const deployProject = {
|
|
1207
1240
|
name: "deploy-project",
|
|
1208
1241
|
description: "Deploy a Strapi Cloud project",
|
|
1209
|
-
action: action$
|
|
1210
|
-
command: command$
|
|
1242
|
+
action: action$3,
|
|
1243
|
+
command: command$5
|
|
1211
1244
|
};
|
|
1212
|
-
const
|
|
1245
|
+
const QUIT_OPTION = "Quit";
|
|
1246
|
+
async function getExistingConfig(ctx) {
|
|
1247
|
+
try {
|
|
1248
|
+
return await retrieve();
|
|
1249
|
+
} catch (e) {
|
|
1250
|
+
ctx.logger.debug("Failed to get project config", e);
|
|
1251
|
+
ctx.logger.error("An error occurred while retrieving config data from your local project.");
|
|
1252
|
+
return null;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
async function promptForRelink(ctx, cloudApiService, existingConfig) {
|
|
1256
|
+
if (existingConfig && existingConfig.project) {
|
|
1257
|
+
const { shouldRelink } = await inquirer__default.default.prompt([
|
|
1258
|
+
{
|
|
1259
|
+
type: "confirm",
|
|
1260
|
+
name: "shouldRelink",
|
|
1261
|
+
message: `A project named ${chalk__default.default.cyan(
|
|
1262
|
+
existingConfig.project.displayName ? existingConfig.project.displayName : existingConfig.project.name
|
|
1263
|
+
)} is already linked to this local folder. Do you want to update the link?`,
|
|
1264
|
+
default: false
|
|
1265
|
+
}
|
|
1266
|
+
]);
|
|
1267
|
+
if (!shouldRelink) {
|
|
1268
|
+
await trackEvent(ctx, cloudApiService, "didNotLinkProject", {
|
|
1269
|
+
currentProjectName: existingConfig.project?.name
|
|
1270
|
+
});
|
|
1271
|
+
return false;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
return true;
|
|
1275
|
+
}
|
|
1276
|
+
async function getProjectsList(ctx, cloudApiService, existingConfig) {
|
|
1277
|
+
const spinner = ctx.logger.spinner("Fetching your projects...\n").start();
|
|
1278
|
+
try {
|
|
1279
|
+
const {
|
|
1280
|
+
data: { data: projectList }
|
|
1281
|
+
} = await cloudApiService.listLinkProjects();
|
|
1282
|
+
spinner.succeed();
|
|
1283
|
+
if (!Array.isArray(projectList)) {
|
|
1284
|
+
ctx.logger.log("We couldn't find any projects available for linking in Strapi Cloud");
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1287
|
+
const projects = projectList.filter(
|
|
1288
|
+
(project) => !(project.isMaintainer || project.name === existingConfig?.project?.name)
|
|
1289
|
+
).map((project) => {
|
|
1290
|
+
return {
|
|
1291
|
+
name: project.displayName,
|
|
1292
|
+
value: { name: project.name, displayName: project.displayName }
|
|
1293
|
+
};
|
|
1294
|
+
});
|
|
1295
|
+
if (projects.length === 0) {
|
|
1296
|
+
ctx.logger.log("We couldn't find any projects available for linking in Strapi Cloud");
|
|
1297
|
+
return null;
|
|
1298
|
+
}
|
|
1299
|
+
return projects;
|
|
1300
|
+
} catch (e) {
|
|
1301
|
+
spinner.fail("An error occurred while fetching your projects from Strapi Cloud.");
|
|
1302
|
+
ctx.logger.debug("Failed to list projects", e);
|
|
1303
|
+
return null;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
async function getUserSelection(ctx, projects) {
|
|
1307
|
+
const { logger } = ctx;
|
|
1308
|
+
try {
|
|
1309
|
+
const answer = await inquirer__default.default.prompt([
|
|
1310
|
+
{
|
|
1311
|
+
type: "list",
|
|
1312
|
+
name: "linkProject",
|
|
1313
|
+
message: "Which project do you want to link?",
|
|
1314
|
+
choices: [...projects, { name: chalk__default.default.grey(`(${QUIT_OPTION})`), value: null }]
|
|
1315
|
+
}
|
|
1316
|
+
]);
|
|
1317
|
+
if (!answer.linkProject) {
|
|
1318
|
+
return null;
|
|
1319
|
+
}
|
|
1320
|
+
return answer;
|
|
1321
|
+
} catch (e) {
|
|
1322
|
+
logger.debug("Failed to get user input", e);
|
|
1323
|
+
logger.error("An error occurred while trying to get your input.");
|
|
1324
|
+
return null;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
const action$2 = async (ctx) => {
|
|
1328
|
+
const { getValidToken } = await tokenServiceFactory(ctx);
|
|
1329
|
+
const token = await getValidToken(ctx, promptLogin);
|
|
1330
|
+
const { logger } = ctx;
|
|
1331
|
+
if (!token) {
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1334
|
+
const cloudApiService = await cloudApiFactory(ctx, token);
|
|
1335
|
+
const existingConfig = await getExistingConfig(ctx);
|
|
1336
|
+
const shouldRelink = await promptForRelink(ctx, cloudApiService, existingConfig);
|
|
1337
|
+
if (!shouldRelink) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
await trackEvent(ctx, cloudApiService, "willLinkProject", {});
|
|
1341
|
+
const projects = await getProjectsList(
|
|
1342
|
+
ctx,
|
|
1343
|
+
cloudApiService,
|
|
1344
|
+
existingConfig
|
|
1345
|
+
);
|
|
1346
|
+
if (!projects) {
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
const answer = await getUserSelection(ctx, projects);
|
|
1350
|
+
if (!answer) {
|
|
1351
|
+
return;
|
|
1352
|
+
}
|
|
1353
|
+
try {
|
|
1354
|
+
const { confirmAction } = await inquirer__default.default.prompt([
|
|
1355
|
+
{
|
|
1356
|
+
type: "confirm",
|
|
1357
|
+
name: "confirmAction",
|
|
1358
|
+
message: "Warning: Once linked, deploying from CLI will replace the existing project and its data. Confirm to proceed:",
|
|
1359
|
+
default: false
|
|
1360
|
+
}
|
|
1361
|
+
]);
|
|
1362
|
+
if (!confirmAction) {
|
|
1363
|
+
await trackEvent(ctx, cloudApiService, "didNotLinkProject", {
|
|
1364
|
+
cancelledProjectName: answer.linkProject.name,
|
|
1365
|
+
currentProjectName: existingConfig ? existingConfig.project?.name : null
|
|
1366
|
+
});
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
await save({ project: answer.linkProject });
|
|
1370
|
+
logger.log(`Project ${chalk__default.default.cyan(answer.linkProject.displayName)} linked successfully.`);
|
|
1371
|
+
await trackEvent(ctx, cloudApiService, "didLinkProject", {
|
|
1372
|
+
projectInternalName: answer.linkProject
|
|
1373
|
+
});
|
|
1374
|
+
} catch (e) {
|
|
1375
|
+
logger.debug("Failed to link project", e);
|
|
1376
|
+
logger.error("An error occurred while linking the project.");
|
|
1377
|
+
await trackEvent(ctx, cloudApiService, "didNotLinkProject", {
|
|
1378
|
+
projectInternalName: answer.linkProject
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
};
|
|
1382
|
+
const command$4 = ({ command: command2, ctx }) => {
|
|
1383
|
+
command2.command("cloud:link").alias("link").description("Link a local directory to a Strapi Cloud project").option("-d, --debug", "Enable debugging mode with verbose logs").option("-s, --silent", "Don't log anything").action(() => runAction("link", action$2)(ctx));
|
|
1384
|
+
};
|
|
1385
|
+
const link = {
|
|
1386
|
+
name: "link-project",
|
|
1387
|
+
description: "Link a local directory to a Strapi Cloud project",
|
|
1388
|
+
action: action$2,
|
|
1389
|
+
command: command$4
|
|
1390
|
+
};
|
|
1391
|
+
const command$3 = ({ command: command2, ctx }) => {
|
|
1213
1392
|
command2.command("cloud:login").alias("login").description("Strapi Cloud Login").addHelpText(
|
|
1214
1393
|
"after",
|
|
1215
1394
|
"\nAfter running this command, you will be prompted to enter your authentication information."
|
|
@@ -1219,10 +1398,10 @@ const login = {
|
|
|
1219
1398
|
name: "login",
|
|
1220
1399
|
description: "Strapi Cloud Login",
|
|
1221
1400
|
action: loginAction,
|
|
1222
|
-
command: command$
|
|
1401
|
+
command: command$3
|
|
1223
1402
|
};
|
|
1224
1403
|
const openModule = import("open");
|
|
1225
|
-
const action = async (ctx) => {
|
|
1404
|
+
const action$1 = async (ctx) => {
|
|
1226
1405
|
const { logger } = ctx;
|
|
1227
1406
|
const { retrieveToken, eraseToken } = await tokenServiceFactory(ctx);
|
|
1228
1407
|
const token = await retrieveToken();
|
|
@@ -1252,37 +1431,64 @@ const action = async (ctx) => {
|
|
|
1252
1431
|
logger.error("🥲 Oops! Something went wrong while logging you out. Please try again.");
|
|
1253
1432
|
logger.debug(e);
|
|
1254
1433
|
}
|
|
1255
|
-
|
|
1256
|
-
await cloudApiService.track("didLogout", { loginMethod: "cli" });
|
|
1257
|
-
} catch (e) {
|
|
1258
|
-
logger.debug("Failed to track logout event", e);
|
|
1259
|
-
}
|
|
1434
|
+
await trackEvent(ctx, cloudApiService, "didLogout", { loginMethod: "cli" });
|
|
1260
1435
|
};
|
|
1261
|
-
const command$
|
|
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));
|
|
1436
|
+
const command$2 = ({ command: command2, ctx }) => {
|
|
1437
|
+
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
1438
|
};
|
|
1264
1439
|
const logout = {
|
|
1265
1440
|
name: "logout",
|
|
1266
1441
|
description: "Strapi Cloud Logout",
|
|
1267
|
-
action,
|
|
1268
|
-
command: command$
|
|
1442
|
+
action: action$1,
|
|
1443
|
+
command: command$2
|
|
1269
1444
|
};
|
|
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$
|
|
1445
|
+
const command$1 = ({ command: command2, ctx }) => {
|
|
1446
|
+
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));
|
|
1272
1447
|
};
|
|
1273
1448
|
const createProject = {
|
|
1274
1449
|
name: "create-project",
|
|
1275
1450
|
description: "Create a new project",
|
|
1276
|
-
action: action$
|
|
1451
|
+
action: action$4,
|
|
1452
|
+
command: command$1
|
|
1453
|
+
};
|
|
1454
|
+
const action = async (ctx) => {
|
|
1455
|
+
const { getValidToken } = await tokenServiceFactory(ctx);
|
|
1456
|
+
const token = await getValidToken(ctx, promptLogin);
|
|
1457
|
+
const { logger } = ctx;
|
|
1458
|
+
if (!token) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
const cloudApiService = await cloudApiFactory(ctx, token);
|
|
1462
|
+
const spinner = logger.spinner("Fetching your projects...").start();
|
|
1463
|
+
try {
|
|
1464
|
+
const {
|
|
1465
|
+
data: { data: projectList }
|
|
1466
|
+
} = await cloudApiService.listProjects();
|
|
1467
|
+
spinner.succeed();
|
|
1468
|
+
logger.log(projectList);
|
|
1469
|
+
} catch (e) {
|
|
1470
|
+
ctx.logger.debug("Failed to list projects", e);
|
|
1471
|
+
spinner.fail("An error occurred while fetching your projects from Strapi Cloud.");
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
const command = ({ command: command2, ctx }) => {
|
|
1475
|
+
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("projects", action)(ctx));
|
|
1476
|
+
};
|
|
1477
|
+
const listProjects = {
|
|
1478
|
+
name: "list-projects",
|
|
1479
|
+
description: "List Strapi Cloud projects",
|
|
1480
|
+
action,
|
|
1277
1481
|
command
|
|
1278
1482
|
};
|
|
1279
1483
|
const cli = {
|
|
1280
1484
|
deployProject,
|
|
1485
|
+
link,
|
|
1281
1486
|
login,
|
|
1282
1487
|
logout,
|
|
1283
|
-
createProject
|
|
1488
|
+
createProject,
|
|
1489
|
+
listProjects
|
|
1284
1490
|
};
|
|
1285
|
-
const cloudCommands = [deployProject, login, logout];
|
|
1491
|
+
const cloudCommands = [deployProject, link, login, logout, listProjects];
|
|
1286
1492
|
async function initCloudCLIConfig() {
|
|
1287
1493
|
const localConfig = await getLocalConfig();
|
|
1288
1494
|
if (!localConfig.deviceId) {
|