@strapi/cloud-cli 0.0.0-experimental.f77206734629a2b88793a7a8abca40388843c656 → 0.0.0-next.48485bcb4aa83c14d6d2cb99cbd47676d0d31b97

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/LICENSE CHANGED
@@ -2,7 +2,21 @@ Copyright (c) 2015-present Strapi Solutions SAS
2
2
 
3
3
  Portions of the Strapi software are licensed as follows:
4
4
 
5
- * All software that resides under an "ee/" directory (the “EE Software”), if that directory exists, is licensed under the license defined in "ee/LICENSE".
5
+ * All software that resides under an "ee/" directory (the “EE Software”), if that directory exists, is licensed under the license defined below.
6
+
7
+ Enterprise License
8
+
9
+ If you or the company you represent has entered into a written agreement referencing the Enterprise Edition of the Strapi source code available at
10
+ https://github.com/strapi/strapi, then such agreement applies to your use of the Enterprise Edition of the Strapi Software. If you or the company you
11
+ represent is using the Enterprise Edition of the Strapi Software in connection with a subscription to our cloud offering, then the agreement you have
12
+ agreed to with respect to our cloud offering and the licenses included in such agreement apply to your use of the Enterprise Edition of the Strapi Software.
13
+ Otherwise, the Strapi Enterprise Software License Agreement (found here https://strapi.io/enterprise-terms) applies to your use of the Enterprise Edition of the Strapi Software.
14
+
15
+ BY ACCESSING OR USING THE ENTERPRISE EDITION OF THE STRAPI SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE RELEVANT REFERENCED AGREEMENT.
16
+ IF YOU ARE NOT AUTHORIZED TO ACCEPT THESE TERMS ON BEHALF OF THE COMPANY YOU REPRESENT OR IF YOU DO NOT AGREE TO ALL OF THE RELEVANT TERMS AND CONDITIONS REFERENCED AND YOU
17
+ HAVE NOT OTHERWISE EXECUTED A WRITTEN AGREEMENT WITH STRAPI, YOU ARE NOT AUTHORIZED TO ACCESS OR USE OR ALLOW ANY USER TO ACCESS OR USE ANY PART OF
18
+ THE ENTERPRISE EDITION OF THE STRAPI SOFTWARE. YOUR ACCESS RIGHTS ARE CONDITIONAL ON YOUR CONSENT TO THE RELEVANT REFERENCED TERMS TO THE EXCLUSION OF ALL OTHER TERMS;
19
+ IF THE RELEVANT REFERENCED TERMS ARE CONSIDERED AN OFFER BY YOU, ACCEPTANCE IS EXPRESSLY LIMITED TO THE RELEVANT REFERENCED TERMS.
6
20
 
7
21
  * All software outside of the above-mentioned directories or restrictions above is available under the "MIT Expat" license as set forth below.
8
22
 
@@ -18,5 +32,6 @@ furnished to do so, subject to the following conditions:
18
32
  The above copyright notice and this permission notice shall be included in all
19
33
  copies or substantial portions of the Software.
20
34
 
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
- SOFTWARE.
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
37
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/dist/bin.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const commander = require("commander");
4
- const axios = require("axios");
5
- const fs = require("fs");
6
- const os = require("os");
4
+ require("axios");
5
+ require("fs-extra");
6
+ require("os");
7
7
  const utils = require("@strapi/utils");
8
- const path = require("path");
9
- const XDGAppPaths = require("xdg-app-paths");
8
+ require("path");
9
+ require("xdg-app-paths");
10
10
  require("jwks-rsa");
11
11
  require("jsonwebtoken");
12
12
  const chalk = require("chalk");
@@ -33,215 +33,14 @@ function _interopNamespace(e) {
33
33
  n.default = e;
34
34
  return Object.freeze(n);
35
35
  }
36
- const axios__default = /* @__PURE__ */ _interopDefault(axios);
37
- const fs__namespace = /* @__PURE__ */ _interopNamespace(fs);
38
- const os__default = /* @__PURE__ */ _interopDefault(os);
39
- const path__default = /* @__PURE__ */ _interopDefault(path);
40
- const XDGAppPaths__default = /* @__PURE__ */ _interopDefault(XDGAppPaths);
41
36
  const chalk__default = /* @__PURE__ */ _interopDefault(chalk);
42
37
  const stringify__default = /* @__PURE__ */ _interopDefault(stringify);
43
38
  const ora__default = /* @__PURE__ */ _interopDefault(ora);
44
39
  const cliProgress__namespace = /* @__PURE__ */ _interopNamespace(cliProgress);
45
- const apiConfig = {
46
- apiBaseUrl: utils.env("STRAPI_CLI_CLOUD_API", "https://cli.cloud.strapi.io")
47
- };
48
- const APP_FOLDER_NAME = "com.strapi.cli";
49
- const CONFIG_FILENAME = "config.json";
50
- function checkDirectoryExists(directoryPath) {
51
- try {
52
- return fs__namespace.default.lstatSync(directoryPath).isDirectory();
53
- } catch (e) {
54
- return false;
55
- }
56
- }
57
- function getConfigPath() {
58
- const configDirs = XDGAppPaths__default.default(APP_FOLDER_NAME).configDirs();
59
- const configPath = configDirs.find(checkDirectoryExists);
60
- if (!configPath) {
61
- fs__namespace.default.mkdirSync(configDirs[0], { recursive: true });
62
- return configDirs[0];
63
- }
64
- return configPath;
65
- }
66
- function getLocalConfig() {
67
- const configPath = getConfigPath();
68
- const configFilePath = path__default.default.join(configPath, CONFIG_FILENAME);
69
- if (!fs__namespace.default.existsSync(configFilePath)) {
70
- return {};
71
- }
72
- try {
73
- return JSON.parse(fs__namespace.default.readFileSync(configFilePath, "utf8"));
74
- } catch (e) {
75
- return {};
76
- }
77
- }
78
- const name = "@strapi/cloud-cli";
79
- const version = "4.24.3";
80
- const description = "Commands to interact with the Strapi Cloud";
81
- const keywords = [
82
- "strapi",
83
- "cloud",
84
- "cli"
85
- ];
86
- const homepage = "https://strapi.io";
87
- const bugs = {
88
- url: "https://github.com/strapi/strapi/issues"
89
- };
90
- const repository = {
91
- type: "git",
92
- url: "git://github.com/strapi/strapi.git"
93
- };
94
- const license = "SEE LICENSE IN LICENSE";
95
- const author = {
96
- name: "Strapi Solutions SAS",
97
- email: "hi@strapi.io",
98
- url: "https://strapi.io"
99
- };
100
- const maintainers = [
101
- {
102
- name: "Strapi Solutions SAS",
103
- email: "hi@strapi.io",
104
- url: "https://strapi.io"
105
- }
106
- ];
107
- const main = "./dist/index.js";
108
- const module$1 = "./dist/index.mjs";
109
- const source = "./src/index.ts";
110
- const types = "./dist/src/index.d.ts";
111
- const bin = "./bin/index.js";
112
- const files = [
113
- "./dist",
114
- "./bin"
115
- ];
116
- const scripts = {
117
- build: "pack-up build",
118
- clean: "run -T rimraf ./dist",
119
- lint: "run -T eslint .",
120
- watch: "pack-up watch"
121
- };
122
- const dependencies = {
123
- "@strapi/utils": "4.24.3",
124
- axios: "1.6.0",
125
- chalk: "4.1.2",
126
- "cli-progress": "3.12.0",
127
- commander: "8.3.0",
128
- eventsource: "2.0.2",
129
- "fast-safe-stringify": "2.1.1",
130
- inquirer: "8.2.5",
131
- jsonwebtoken: "9.0.0",
132
- "jwks-rsa": "3.1.0",
133
- lodash: "4.17.21",
134
- minimatch: "9.0.3",
135
- open: "8.4.0",
136
- ora: "5.4.1",
137
- "pkg-up": "3.1.0",
138
- tar: "6.1.13",
139
- "xdg-app-paths": "8.3.0",
140
- yup: "0.32.9"
141
- };
142
- const devDependencies = {
143
- "@strapi/pack-up": "4.23.0",
144
- "@types/cli-progress": "3.11.5",
145
- "@types/eventsource": "1.1.15",
146
- "@types/lodash": "^4.14.191",
147
- "eslint-config-custom": "4.24.3",
148
- tsconfig: "4.24.3"
149
- };
150
- const engines = {
151
- node: ">=18.0.0 <=20.x.x",
152
- npm: ">=6.0.0"
153
- };
154
- const packageJson = {
155
- name,
156
- version,
157
- description,
158
- keywords,
159
- homepage,
160
- bugs,
161
- repository,
162
- license,
163
- author,
164
- maintainers,
165
- main,
166
- module: module$1,
167
- source,
168
- types,
169
- bin,
170
- files,
171
- scripts,
172
- dependencies,
173
- devDependencies,
174
- engines
175
- };
176
- const VERSION = "v1";
177
- function cloudApiFactory(token) {
178
- const localConfig = getLocalConfig();
179
- const customHeaders = {
180
- "x-device-id": localConfig.deviceId,
181
- "x-app-version": packageJson.version,
182
- "x-os-name": os__default.default.type(),
183
- "x-os-version": os__default.default.version(),
184
- "x-language": Intl.DateTimeFormat().resolvedOptions().locale,
185
- "x-node-version": process.versions.node
186
- };
187
- const axiosCloudAPI = axios__default.default.create({
188
- baseURL: `${apiConfig.apiBaseUrl}/${VERSION}`,
189
- headers: {
190
- "Content-Type": "application/json",
191
- ...customHeaders
192
- }
193
- });
194
- if (token) {
195
- axiosCloudAPI.defaults.headers.Authorization = `Bearer ${token}`;
196
- }
197
- return {
198
- deploy({ filePath, project }, { onUploadProgress }) {
199
- return axiosCloudAPI.post(
200
- `/deploy/${project.name}`,
201
- { file: fs__namespace.createReadStream(filePath) },
202
- {
203
- headers: {
204
- "Content-Type": "multipart/form-data"
205
- },
206
- onUploadProgress
207
- }
208
- );
209
- },
210
- async createProject({ name: name2, nodeVersion, region, plan }) {
211
- const response = await axiosCloudAPI.post("/project", {
212
- projectName: name2,
213
- region,
214
- nodeVersion,
215
- plan
216
- });
217
- return {
218
- data: {
219
- id: response.data.id,
220
- name: response.data.name,
221
- nodeVersion: response.data.nodeVersion,
222
- region: response.data.region
223
- },
224
- status: response.status
225
- };
226
- },
227
- getUserInfo() {
228
- return axiosCloudAPI.get("/user");
229
- },
230
- config() {
231
- return axiosCloudAPI.get("/config");
232
- },
233
- listProjects() {
234
- return axiosCloudAPI.get("/projects");
235
- },
236
- track(event, payload = {}) {
237
- return axiosCloudAPI.post("/track", {
238
- event,
239
- payload
240
- });
241
- }
242
- };
243
- }
244
- cloudApiFactory();
40
+ ({
41
+ apiBaseUrl: utils.env("STRAPI_CLI_CLOUD_API", "https://cloud-cli-api.strapi.io"),
42
+ dashboardBaseUrl: utils.env("STRAPI_CLI_CLOUD_DASHBOARD", "https://cloud.strapi.io")
43
+ });
245
44
  const stringifyArg = (arg) => {
246
45
  return typeof arg === "object" ? stringify__default.default(arg) : arg;
247
46
  };
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sources":["../src/config/api.ts","../src/config/local.ts","../src/services/cli-api.ts","../src/services/token.ts","../src/services/logger.ts","../src/bin.ts"],"sourcesContent":["import { env } from '@strapi/utils';\n\nexport const apiConfig = {\n apiBaseUrl: env('STRAPI_CLI_CLOUD_API', 'https://cli.cloud.strapi.io'),\n};\n","import path from 'path';\nimport os from 'os';\nimport fs from 'fs';\nimport XDGAppPaths from 'xdg-app-paths';\n\nconst APP_FOLDER_NAME = 'com.strapi.cli';\n\nexport const CONFIG_FILENAME = 'config.json';\n\nexport type LocalConfig = {\n token?: string;\n deviceId?: string;\n};\n\nfunction checkDirectoryExists(directoryPath: string) {\n try {\n return fs.lstatSync(directoryPath).isDirectory();\n } catch (e) {\n return false;\n }\n}\n\n// Determine storage path based on the operating system\nexport function getTmpStoragePath() {\n const storagePath = path.join(os.tmpdir(), APP_FOLDER_NAME);\n if (!checkDirectoryExists(storagePath)) {\n fs.mkdirSync(storagePath, { recursive: true });\n }\n return storagePath;\n}\n\nfunction getConfigPath() {\n const configDirs = XDGAppPaths(APP_FOLDER_NAME).configDirs();\n const configPath = configDirs.find(checkDirectoryExists);\n\n if (!configPath) {\n fs.mkdirSync(configDirs[0], { recursive: true });\n return configDirs[0];\n }\n return configPath;\n}\n\nexport function getLocalConfig(): LocalConfig {\n const configPath = getConfigPath();\n const configFilePath = path.join(configPath, CONFIG_FILENAME);\n if (!fs.existsSync(configFilePath)) {\n return {};\n }\n try {\n return JSON.parse(fs.readFileSync(configFilePath, 'utf8'));\n } catch (e) {\n return {};\n }\n}\n\nexport function saveLocalConfig(data: LocalConfig) {\n const configPath = getConfigPath();\n const configFilePath = path.join(configPath, CONFIG_FILENAME);\n fs.writeFileSync(configFilePath, JSON.stringify(data), { encoding: 'utf8', mode: 0o600 });\n}\n","import axios, { type AxiosResponse } from 'axios';\nimport * as fs from 'fs';\nimport os from 'os';\nimport { apiConfig } from '../config/api';\nimport type { CloudCliConfig } from '../types';\nimport { getLocalConfig } from '../config/local';\n\nimport packageJson from '../../package.json';\n\nexport const VERSION = 'v1';\n\nexport type ProjectInfos = {\n name: string;\n nodeVersion: string;\n region: string;\n plan?: string;\n url?: string;\n};\nexport type ProjectInput = Omit<ProjectInfos, 'id'>;\n\nexport type DeployResponse = {\n build_id: string;\n image: string;\n};\n\nexport type TrackPayload = Record<string, unknown>;\n\nexport interface CloudApiService {\n deploy(\n deployInput: {\n filePath: string;\n project: { name: string };\n },\n {\n onUploadProgress,\n }: {\n onUploadProgress: (progressEvent: { loaded: number; total?: number }) => void;\n }\n ): Promise<AxiosResponse<DeployResponse>>;\n\n createProject(projectInput: ProjectInput): Promise<{\n data: ProjectInfos;\n status: number;\n }>;\n\n getUserInfo(): Promise<AxiosResponse>;\n\n config(): Promise<AxiosResponse<CloudCliConfig>>;\n\n listProjects(): Promise<AxiosResponse<ProjectInfos[]>>;\n\n track(event: string, payload?: TrackPayload): Promise<AxiosResponse<void>>;\n}\n\nexport function cloudApiFactory(token?: string): CloudApiService {\n const localConfig = getLocalConfig();\n const customHeaders = {\n 'x-device-id': localConfig.deviceId,\n 'x-app-version': packageJson.version,\n 'x-os-name': os.type(),\n 'x-os-version': os.version(),\n 'x-language': Intl.DateTimeFormat().resolvedOptions().locale,\n 'x-node-version': process.versions.node,\n };\n const axiosCloudAPI = axios.create({\n baseURL: `${apiConfig.apiBaseUrl}/${VERSION}`,\n headers: {\n 'Content-Type': 'application/json',\n ...customHeaders,\n },\n });\n\n if (token) {\n axiosCloudAPI.defaults.headers.Authorization = `Bearer ${token}`;\n }\n\n return {\n deploy({ filePath, project }, { onUploadProgress }) {\n return axiosCloudAPI.post(\n `/deploy/${project.name}`,\n { file: fs.createReadStream(filePath) },\n {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n onUploadProgress,\n }\n );\n },\n\n async createProject({ name, nodeVersion, region, plan }) {\n const response = await axiosCloudAPI.post('/project', {\n projectName: name,\n region,\n nodeVersion,\n plan,\n });\n\n return {\n data: {\n id: response.data.id,\n name: response.data.name,\n nodeVersion: response.data.nodeVersion,\n region: response.data.region,\n },\n status: response.status,\n };\n },\n\n getUserInfo() {\n return axiosCloudAPI.get('/user');\n },\n\n config(): Promise<AxiosResponse<CloudCliConfig>> {\n return axiosCloudAPI.get('/config');\n },\n\n listProjects() {\n return axiosCloudAPI.get<ProjectInfos[]>('/projects');\n },\n\n track(event, payload = {}) {\n return axiosCloudAPI.post<void>('/track', {\n event,\n payload,\n });\n },\n };\n}\n","import jwksClient, { type JwksClient, type SigningKey } from 'jwks-rsa';\nimport type { JwtHeader, VerifyErrors } from 'jsonwebtoken';\nimport jwt from 'jsonwebtoken';\nimport { getLocalConfig, saveLocalConfig } from '../config/local';\nimport type { CloudCliConfig, CLIContext } from '../types';\nimport { cloudApiFactory } from './cli-api';\n\nconst cloudApiService = cloudApiFactory();\n\nlet cliConfig: CloudCliConfig;\n\ninterface DecodedToken {\n [key: string]: any;\n}\n\nexport function tokenServiceFactory({ logger }: { logger: CLIContext['logger'] }) {\n function saveToken(str: string) {\n const appConfig = getLocalConfig();\n\n if (!appConfig) {\n logger.error('There was a problem saving your token. Please try again.');\n return;\n }\n\n appConfig.token = str;\n\n try {\n saveLocalConfig(appConfig);\n } catch (error: Error | unknown) {\n logger.debug(error);\n logger.error('There was a problem saving your token. Please try again.');\n }\n }\n\n async function retrieveToken() {\n const appConfig = getLocalConfig();\n if (appConfig.token) {\n // check if token is still valid\n if (await isTokenValid(appConfig.token)) {\n return appConfig.token;\n }\n }\n return undefined;\n }\n\n async function validateToken(idToken: string, jwksUrl: string): Promise<void> {\n const client: JwksClient = jwksClient({\n jwksUri: jwksUrl,\n });\n\n // Get the Key from the JWKS using the token header's Key ID (kid)\n const getKey = (header: JwtHeader, callback: (err: Error | null, key?: string) => void) => {\n client.getSigningKey(header.kid, (err: Error | null, key?: SigningKey) => {\n if (err) {\n callback(err);\n } else if (key) {\n const publicKey = 'publicKey' in key ? key.publicKey : key.rsaPublicKey;\n callback(null, publicKey);\n } else {\n callback(new Error('Key not found'));\n }\n });\n };\n\n // Decode the JWT token to get the header and payload\n const decodedToken = jwt.decode(idToken, { complete: true }) as DecodedToken;\n if (!decodedToken) {\n if (typeof idToken === 'undefined' || idToken === '') {\n logger.warn('You need to be logged in to use this feature. Please log in and try again.');\n } else {\n logger.error(\n 'There seems to be a problem with your login information. Please try logging in again.'\n );\n }\n }\n\n // Verify the JWT token signature using the JWKS Key\n return new Promise<void>((resolve, reject) => {\n jwt.verify(idToken, getKey, (err: VerifyErrors | null) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n }\n\n async function isTokenValid(token: string) {\n try {\n const config = await cloudApiService.config();\n\n cliConfig = config.data;\n if (token) {\n await validateToken(token, cliConfig.jwksUrl);\n return true;\n }\n return false;\n } catch (error) {\n logger.debug(error);\n return false;\n }\n }\n\n function eraseToken() {\n const appConfig = getLocalConfig();\n if (!appConfig) {\n return;\n }\n\n delete appConfig.token;\n\n try {\n saveLocalConfig(appConfig);\n } catch (error: Error | unknown) {\n logger.debug(error);\n logger.error(\n 'There was an issue removing your login information. Please try logging out again.'\n );\n }\n }\n\n async function getValidToken() {\n const token = await retrieveToken();\n if (!token) {\n logger.log('No token found. Please login first.');\n return null;\n }\n\n if (!(await isTokenValid(token))) {\n logger.log('Unable to proceed: Token is expired or not valid. Please login again.');\n return null;\n }\n return token;\n }\n\n return {\n saveToken,\n retrieveToken,\n validateToken,\n isTokenValid,\n eraseToken,\n getValidToken,\n };\n}\n","import chalk from 'chalk';\nimport stringify from 'fast-safe-stringify';\n\nimport ora from 'ora';\nimport * as cliProgress from 'cli-progress';\n\nexport interface LoggerOptions {\n silent?: boolean;\n debug?: boolean;\n timestamp?: boolean;\n}\n\nexport interface Logger {\n warnings: number;\n errors: number;\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n success: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n log: (...args: unknown[]) => void;\n spinner: (text: string) => Pick<ora.Ora, 'succeed' | 'fail' | 'start' | 'text' | 'isSpinning'>;\n progressBar: (\n totalSize: number,\n text: string\n ) => Pick<cliProgress.SingleBar, 'start' | 'stop' | 'update'>;\n}\n\nconst stringifyArg = (arg: unknown) => {\n return typeof arg === 'object' ? stringify(arg) : arg;\n};\n\nconst createLogger = (options: LoggerOptions = {}): Logger => {\n const { silent = false, debug = false, timestamp = true } = options;\n\n const state = { errors: 0, warning: 0 };\n\n return {\n get warnings() {\n return state.warning;\n },\n\n get errors() {\n return state.errors;\n },\n\n async debug(...args) {\n if (silent || !debug) {\n return;\n }\n\n console.log(\n chalk.cyan(`[DEBUG]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n info(...args) {\n if (silent) {\n return;\n }\n\n console.info(\n chalk.blue(`[INFO]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n log(...args) {\n if (silent) {\n return;\n }\n\n console.info(\n chalk.blue(`${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n success(...args) {\n if (silent) {\n return;\n }\n\n console.info(\n chalk.green(`[SUCCESS]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n warn(...args) {\n state.warning += 1;\n\n if (silent) {\n return;\n }\n\n console.warn(\n chalk.yellow(`[WARN]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n error(...args) {\n state.errors += 1;\n\n if (silent) {\n return;\n }\n\n console.error(\n chalk.red(`[ERROR]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n // @ts-expect-error – returning a subpart of ora is fine because the types tell us what is what.\n spinner(text: string) {\n if (silent) {\n return {\n succeed() {\n return this;\n },\n fail() {\n return this;\n },\n start() {\n return this;\n },\n text: '',\n isSpinning: false,\n };\n }\n\n return ora(text);\n },\n\n progressBar(totalSize: number, text: string) {\n if (silent) {\n return {\n start() {\n return this;\n },\n stop() {\n return this;\n },\n update() {\n return this;\n },\n };\n }\n\n const progressBar = new cliProgress.SingleBar({\n format: `${text ? `${text} |` : ''}${chalk.green('{bar}')}| {percentage}%`,\n barCompleteChar: '\\u2588',\n barIncompleteChar: '\\u2591',\n hideCursor: true,\n forceRedraw: true,\n });\n\n progressBar.start(totalSize, 0);\n\n return progressBar;\n },\n };\n};\n\nexport { createLogger };\n","import { Command } from 'commander';\nimport { createLogger } from './services';\nimport { CLIContext } from './types';\nimport { buildStrapiCloudCommands } from './index';\n\nfunction loadStrapiCloudCommand(argv = process.argv, command = new Command()) {\n // Initial program setup\n command.storeOptionsAsProperties(false).allowUnknownOption(true);\n\n // Help command\n command.helpOption('-h, --help', 'Display help for command');\n command.addHelpCommand('help [command]', 'Display help for command');\n\n const cwd = process.cwd();\n\n const hasDebug = argv.includes('--debug');\n const hasSilent = argv.includes('--silent');\n\n const logger = createLogger({ debug: hasDebug, silent: hasSilent, timestamp: false });\n\n const ctx = {\n cwd,\n logger,\n } satisfies CLIContext;\n\n buildStrapiCloudCommands({ command, ctx, argv });\n}\n\nfunction runStrapiCloudCommand(argv = process.argv, command = new Command()) {\n loadStrapiCloudCommand(argv, command);\n command.parse(argv);\n}\n\nexport { runStrapiCloudCommand };\n"],"names":["env","fs","XDGAppPaths","path","os","axios","name","stringify","chalk","ora","cliProgress","Command","buildStrapiCloudCommands"],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sources":["../src/config/api.ts","../src/services/logger.ts","../src/bin.ts"],"sourcesContent":["import { env } from '@strapi/utils';\n\nexport const apiConfig = {\n apiBaseUrl: env('STRAPI_CLI_CLOUD_API', 'https://cloud-cli-api.strapi.io'),\n dashboardBaseUrl: env('STRAPI_CLI_CLOUD_DASHBOARD', 'https://cloud.strapi.io'),\n};\n","import chalk from 'chalk';\nimport stringify from 'fast-safe-stringify';\n\nimport ora from 'ora';\nimport * as cliProgress from 'cli-progress';\n\nexport interface LoggerOptions {\n silent?: boolean;\n debug?: boolean;\n timestamp?: boolean;\n}\n\nexport interface Logger {\n warnings: number;\n errors: number;\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n success: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n log: (...args: unknown[]) => void;\n spinner: (text: string) => Pick<ora.Ora, 'succeed' | 'fail' | 'start' | 'text' | 'isSpinning'>;\n progressBar: (\n totalSize: number,\n text: string\n ) => Pick<cliProgress.SingleBar, 'start' | 'stop' | 'update'>;\n}\n\nconst stringifyArg = (arg: unknown) => {\n return typeof arg === 'object' ? stringify(arg) : arg;\n};\n\nconst createLogger = (options: LoggerOptions = {}): Logger => {\n const { silent = false, debug = false, timestamp = true } = options;\n\n const state = { errors: 0, warning: 0 };\n\n return {\n get warnings() {\n return state.warning;\n },\n\n get errors() {\n return state.errors;\n },\n\n async debug(...args) {\n if (silent || !debug) {\n return;\n }\n\n console.log(\n chalk.cyan(`[DEBUG]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n info(...args) {\n if (silent) {\n return;\n }\n\n console.info(\n chalk.blue(`[INFO]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n log(...args) {\n if (silent) {\n return;\n }\n\n console.info(\n chalk.blue(`${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n success(...args) {\n if (silent) {\n return;\n }\n\n console.info(\n chalk.green(`[SUCCESS]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n warn(...args) {\n state.warning += 1;\n\n if (silent) {\n return;\n }\n\n console.warn(\n chalk.yellow(`[WARN]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n error(...args) {\n state.errors += 1;\n\n if (silent) {\n return;\n }\n\n console.error(\n chalk.red(`[ERROR]${timestamp ? `\\t[${new Date().toISOString()}]` : ''}`),\n ...args.map(stringifyArg)\n );\n },\n\n // @ts-expect-error – returning a subpart of ora is fine because the types tell us what is what.\n spinner(text: string) {\n if (silent) {\n return {\n succeed() {\n return this;\n },\n fail() {\n return this;\n },\n start() {\n return this;\n },\n text: '',\n isSpinning: false,\n };\n }\n\n return ora(text);\n },\n\n progressBar(totalSize: number, text: string) {\n if (silent) {\n return {\n start() {\n return this;\n },\n stop() {\n return this;\n },\n update() {\n return this;\n },\n };\n }\n\n const progressBar = new cliProgress.SingleBar({\n format: `${text ? `${text} |` : ''}${chalk.green('{bar}')}| {percentage}%`,\n barCompleteChar: '\\u2588',\n barIncompleteChar: '\\u2591',\n hideCursor: true,\n forceRedraw: true,\n });\n\n progressBar.start(totalSize, 0);\n\n return progressBar;\n },\n };\n};\n\nexport { createLogger };\n","import { Command } from 'commander';\nimport { createLogger } from './services';\nimport { CLIContext } from './types';\nimport { buildStrapiCloudCommands } from './index';\n\nfunction loadStrapiCloudCommand(argv = process.argv, command = new Command()) {\n // Initial program setup\n command.storeOptionsAsProperties(false).allowUnknownOption(true);\n\n // Help command\n command.helpOption('-h, --help', 'Display help for command');\n command.addHelpCommand('help [command]', 'Display help for command');\n\n const cwd = process.cwd();\n\n const hasDebug = argv.includes('--debug');\n const hasSilent = argv.includes('--silent');\n\n const logger = createLogger({ debug: hasDebug, silent: hasSilent, timestamp: false });\n\n const ctx = {\n cwd,\n logger,\n } satisfies CLIContext;\n\n buildStrapiCloudCommands({ command, ctx, argv });\n}\n\nfunction runStrapiCloudCommand(argv = process.argv, command = new Command()) {\n loadStrapiCloudCommand(argv, command);\n command.parse(argv);\n}\n\nexport { runStrapiCloudCommand };\n"],"names":["env","stringify","chalk","ora","cliProgress","Command","buildStrapiCloudCommands"],"mappings":"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"}