@capgo/cli 4.6.3 → 4.8.0
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/CHANGELOG.md +14 -0
- package/bun.lockb +0 -0
- package/dist/index.js +143 -69
- package/package.json +2 -2
- package/src/api/app.ts +3 -23
- package/src/app/add.ts +1 -1
- package/src/bundle/upload.ts +24 -13
- package/src/init.ts +35 -31
- package/src/login.ts +4 -0
- package/src/utils.ts +24 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [4.8.0](https://github.com/Cap-go/CLI/compare/v4.7.0...v4.8.0) (2024-05-10)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* auto select package manager and runner ([94f8bef](https://github.com/Cap-go/CLI/commit/94f8bef06efeafbd5cff1979f5ed75de2a523caa))
|
|
11
|
+
|
|
12
|
+
## [4.7.0](https://github.com/Cap-go/CLI/compare/v4.6.3...v4.7.0) (2024-05-10)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* add upload time + correct PM name ([af61757](https://github.com/Cap-go/CLI/commit/af6175751d92070088d4569b892a333a3e1a1063))
|
|
18
|
+
|
|
5
19
|
### [4.6.3](https://github.com/Cap-go/CLI/compare/v4.6.2...v4.6.3) (2024-05-10)
|
|
6
20
|
|
|
7
21
|
|
package/bun.lockb
CHANGED
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -92373,7 +92373,7 @@ var {
|
|
|
92373
92373
|
// package.json
|
|
92374
92374
|
var package_default = {
|
|
92375
92375
|
name: "@capgo/cli",
|
|
92376
|
-
version: "4.
|
|
92376
|
+
version: "4.8.0",
|
|
92377
92377
|
description: "A CLI to upload to capgo servers",
|
|
92378
92378
|
author: "github.com/riderx",
|
|
92379
92379
|
license: "Apache 2.0",
|
|
@@ -92418,7 +92418,7 @@ var package_default = {
|
|
|
92418
92418
|
dependencies: {
|
|
92419
92419
|
"@aws-sdk/client-s3": "^3.563.0",
|
|
92420
92420
|
"@capacitor/cli": "6.0.0",
|
|
92421
|
-
"@capgo/find-package-manager": "0.0.
|
|
92421
|
+
"@capgo/find-package-manager": "^0.0.16",
|
|
92422
92422
|
"@clack/prompts": "^0.7.0",
|
|
92423
92423
|
"@supabase/supabase-js": "^2.42.7",
|
|
92424
92424
|
"@tomasklaen/checksum": "^1.1.0",
|
|
@@ -93536,6 +93536,65 @@ var distribution_default = ky;
|
|
|
93536
93536
|
|
|
93537
93537
|
// src/utils.ts
|
|
93538
93538
|
var import_node_dir = __toESM(require_node_dir());
|
|
93539
|
+
|
|
93540
|
+
// node_modules/@capgo/find-package-manager/main.js
|
|
93541
|
+
var import_fs = require("fs");
|
|
93542
|
+
var findPackageManagerType = (path3 = ".", defaultPackageManager = "unknown") => {
|
|
93543
|
+
const bunPath = `${path3}/bun.lockb`;
|
|
93544
|
+
const pnpmPath = `${path3}/pnpm-lock.yaml`;
|
|
93545
|
+
const yarnPath = `${path3}/yarn.lock`;
|
|
93546
|
+
const npmPath = `${path3}/package-lock.json`;
|
|
93547
|
+
if ((0, import_fs.existsSync)(bunPath)) {
|
|
93548
|
+
return "bun";
|
|
93549
|
+
}
|
|
93550
|
+
if ((0, import_fs.existsSync)(pnpmPath)) {
|
|
93551
|
+
return "pnpm";
|
|
93552
|
+
}
|
|
93553
|
+
if ((0, import_fs.existsSync)(yarnPath)) {
|
|
93554
|
+
return "yarn";
|
|
93555
|
+
}
|
|
93556
|
+
if ((0, import_fs.existsSync)(npmPath)) {
|
|
93557
|
+
return "npm";
|
|
93558
|
+
}
|
|
93559
|
+
return defaultPm;
|
|
93560
|
+
};
|
|
93561
|
+
var findInstallCommand = (packageManagerType = findPackageManagerType(), prefix = false) => {
|
|
93562
|
+
switch (packageManagerType) {
|
|
93563
|
+
case "bun":
|
|
93564
|
+
return prefix ? "bun install" : "install";
|
|
93565
|
+
case "pnpm":
|
|
93566
|
+
return prefix ? "pnpm install" : "install";
|
|
93567
|
+
case "yarn":
|
|
93568
|
+
return prefix ? "yarn install" : "install";
|
|
93569
|
+
case "npm":
|
|
93570
|
+
return prefix ? "npm install" : "install";
|
|
93571
|
+
case "unknown":
|
|
93572
|
+
return prefix ? "unknown unknown" : "unknown";
|
|
93573
|
+
default:
|
|
93574
|
+
return prefix ? "npm install" : "install";
|
|
93575
|
+
}
|
|
93576
|
+
};
|
|
93577
|
+
var findPackageManagerRunner = (path3 = ".", defaultPackageManagerRunner = "npx") => {
|
|
93578
|
+
const bunPath = `${path3}/bun.lockb`;
|
|
93579
|
+
const pnpmPath = `${path3}/pnpm-lock.yaml`;
|
|
93580
|
+
const yarnPath = `${path3}/yarn.lock`;
|
|
93581
|
+
const npmPath = `${path3}/package-lock.json`;
|
|
93582
|
+
if ((0, import_fs.existsSync)(bunPath)) {
|
|
93583
|
+
return "bunx";
|
|
93584
|
+
}
|
|
93585
|
+
if ((0, import_fs.existsSync)(pnpmPath)) {
|
|
93586
|
+
return "pnpm exec";
|
|
93587
|
+
}
|
|
93588
|
+
if ((0, import_fs.existsSync)(yarnPath)) {
|
|
93589
|
+
return "yarn dlx";
|
|
93590
|
+
}
|
|
93591
|
+
if ((0, import_fs.existsSync)(npmPath)) {
|
|
93592
|
+
return "npx";
|
|
93593
|
+
}
|
|
93594
|
+
return defaultPackageManagerRunner;
|
|
93595
|
+
};
|
|
93596
|
+
|
|
93597
|
+
// src/utils.ts
|
|
93539
93598
|
var baseKey = ".capgo_key";
|
|
93540
93599
|
var baseKeyPub = `${baseKey}.pub`;
|
|
93541
93600
|
var defaultHost = "https://capgo.app";
|
|
@@ -93554,7 +93613,7 @@ async function getConfig() {
|
|
|
93554
93613
|
try {
|
|
93555
93614
|
config = await (0, import_config.loadConfig)();
|
|
93556
93615
|
} catch (err) {
|
|
93557
|
-
f2.error(
|
|
93616
|
+
f2.error(`No capacitor config file found, run \`cap init\` first ${formatError(err)}`);
|
|
93558
93617
|
program.error("");
|
|
93559
93618
|
}
|
|
93560
93619
|
return config;
|
|
@@ -93755,7 +93814,7 @@ function findSavedKey(quiet = false) {
|
|
|
93755
93814
|
key2 = (0, import_node_fs4.readFileSync)(keyPath, "utf8").trim();
|
|
93756
93815
|
}
|
|
93757
93816
|
if (!key2) {
|
|
93758
|
-
f2.error(`Cannot find API key in local folder or global, please login first with
|
|
93817
|
+
f2.error(`Cannot find API key in local folder or global, please login first with ${getPMAndCommand().runner} @capacitor/cli login`);
|
|
93759
93818
|
program.error("");
|
|
93760
93819
|
}
|
|
93761
93820
|
return key2;
|
|
@@ -93948,6 +94007,19 @@ function getHumanDate(createdA) {
|
|
|
93948
94007
|
const date = new Date(createdA || "");
|
|
93949
94008
|
return date.toLocaleString();
|
|
93950
94009
|
}
|
|
94010
|
+
var pmFetched = false;
|
|
94011
|
+
var pm = "npm";
|
|
94012
|
+
var pmCommand = "install";
|
|
94013
|
+
var pmRunner = "npx";
|
|
94014
|
+
function getPMAndCommand() {
|
|
94015
|
+
if (pmFetched)
|
|
94016
|
+
return { pm, command: pmCommand, installCommand: `${pm} ${pmCommand}`, runner: pmRunner };
|
|
94017
|
+
pm = findPackageManagerType(".", "npm");
|
|
94018
|
+
pmCommand = findInstallCommand(pm);
|
|
94019
|
+
pmFetched = true;
|
|
94020
|
+
pmRunner = findPackageManagerRunner();
|
|
94021
|
+
return { pm, command: pmCommand, installCommand: `${pm} ${pmCommand}`, runner: pmRunner };
|
|
94022
|
+
}
|
|
93951
94023
|
async function getLocalDepenencies() {
|
|
93952
94024
|
if (!(0, import_node_fs4.existsSync)("./package.json")) {
|
|
93953
94025
|
f2.error("Missing package.json, you need to be in a capacitor project");
|
|
@@ -93973,7 +94045,9 @@ async function getLocalDepenencies() {
|
|
|
93973
94045
|
}
|
|
93974
94046
|
}
|
|
93975
94047
|
if (!(0, import_node_fs4.existsSync)("./node_modules/")) {
|
|
93976
|
-
|
|
94048
|
+
const pm2 = findPackageManagerType(".", "npm");
|
|
94049
|
+
const installCmd = findInstallCommand(pm2);
|
|
94050
|
+
f2.error(`Missing node_modules folder, please run ${pm2} ${installCmd}`);
|
|
93977
94051
|
program.error("");
|
|
93978
94052
|
}
|
|
93979
94053
|
let anyInvalid = false;
|
|
@@ -93981,7 +94055,9 @@ async function getLocalDepenencies() {
|
|
|
93981
94055
|
const dependencyFolderExists = (0, import_node_fs4.existsSync)(`./node_modules/${key2}`);
|
|
93982
94056
|
if (!dependencyFolderExists) {
|
|
93983
94057
|
anyInvalid = true;
|
|
93984
|
-
|
|
94058
|
+
const pm2 = findPackageManagerType(".", "npm");
|
|
94059
|
+
const installCmd = findInstallCommand(pm2);
|
|
94060
|
+
f2.error(`Missing dependency ${key2}, please run ${pm2} ${installCmd}`);
|
|
93985
94061
|
return { name: key2, version: value };
|
|
93986
94062
|
}
|
|
93987
94063
|
let hasNativeFiles = false;
|
|
@@ -94213,30 +94289,6 @@ The app size is ${mbSize} Mb, this may take a while to download for users
|
|
|
94213
94289
|
var import_node_fs11 = require("node:fs");
|
|
94214
94290
|
var import_node_child_process6 = require("node:child_process");
|
|
94215
94291
|
var import_node_process16 = __toESM(require("node:process"));
|
|
94216
|
-
|
|
94217
|
-
// node_modules/@capgo/find-package-manager/main.js
|
|
94218
|
-
var import_fs = require("fs");
|
|
94219
|
-
var findPackageManagerType = (path3 = ".") => {
|
|
94220
|
-
const bunPath = `${path3}/bun.lockb`;
|
|
94221
|
-
const pnpmPath = `${path3}/pnpm-lock.yaml`;
|
|
94222
|
-
const yarnPath = `${path3}/yarn.lock`;
|
|
94223
|
-
const npmPath = `${path3}/package-lock.json`;
|
|
94224
|
-
if ((0, import_fs.existsSync)(bunPath)) {
|
|
94225
|
-
return "bun";
|
|
94226
|
-
}
|
|
94227
|
-
if ((0, import_fs.existsSync)(pnpmPath)) {
|
|
94228
|
-
return "pnpm";
|
|
94229
|
-
}
|
|
94230
|
-
if ((0, import_fs.existsSync)(yarnPath)) {
|
|
94231
|
-
return "yarn";
|
|
94232
|
-
}
|
|
94233
|
-
if ((0, import_fs.existsSync)(npmPath)) {
|
|
94234
|
-
return "npm";
|
|
94235
|
-
}
|
|
94236
|
-
return "unknown";
|
|
94237
|
-
};
|
|
94238
|
-
|
|
94239
|
-
// src/init.ts
|
|
94240
94292
|
var import_semver = __toESM(require_semver4());
|
|
94241
94293
|
|
|
94242
94294
|
// src/app/debug.ts
|
|
@@ -94248,6 +94300,7 @@ async function checkAppExists(supabase, appid) {
|
|
|
94248
94300
|
return !!app2;
|
|
94249
94301
|
}
|
|
94250
94302
|
async function checkAppExistsAndHasPermissionOrgErr(supabase, apikey, appid, requiredPermission) {
|
|
94303
|
+
const pm2 = getPMAndCommand();
|
|
94251
94304
|
const permissions = await isAllowedAppOrg(supabase, apikey, appid);
|
|
94252
94305
|
if (!permissions.okay) {
|
|
94253
94306
|
switch (permissions.error) {
|
|
@@ -94257,7 +94310,7 @@ async function checkAppExistsAndHasPermissionOrgErr(supabase, apikey, appid, req
|
|
|
94257
94310
|
break;
|
|
94258
94311
|
}
|
|
94259
94312
|
case "NO_APP": {
|
|
94260
|
-
f2.error(`App ${appid} does not exist`);
|
|
94313
|
+
f2.error(`App ${appid} does not exist, run first \`${pm2.runner} @capgo/cli app add ${appid}\` to create it`);
|
|
94261
94314
|
program.error("");
|
|
94262
94315
|
break;
|
|
94263
94316
|
}
|
|
@@ -94752,12 +94805,15 @@ async function addChannelCommand(apikey, appId, options) {
|
|
|
94752
94805
|
var import_node_crypto3 = require("node:crypto");
|
|
94753
94806
|
var import_node_fs8 = require("node:fs");
|
|
94754
94807
|
var import_node_process13 = __toESM(require("node:process"));
|
|
94808
|
+
var import_node_perf_hooks = require("node:perf_hooks");
|
|
94755
94809
|
var import_adm_zip2 = __toESM(require_adm_zip());
|
|
94756
94810
|
var import_checksum2 = __toESM(require_dist());
|
|
94757
94811
|
var import_ci_info = __toESM(require_ci_info());
|
|
94758
94812
|
var import_client_s3 = __toESM(require_dist_cjs71());
|
|
94759
94813
|
var alertMb2 = 20;
|
|
94814
|
+
var UPLOAD_TIMEOUT = 12e4;
|
|
94760
94815
|
async function uploadBundle(appid, options, shouldExit = true) {
|
|
94816
|
+
const pm2 = getPMAndCommand();
|
|
94761
94817
|
oe(`Uploading`);
|
|
94762
94818
|
await checkLatest();
|
|
94763
94819
|
let { bundle: bundle2, path: path3, channel: channel2 } = options;
|
|
@@ -94781,7 +94837,7 @@ async function uploadBundle(appid, options, shouldExit = true) {
|
|
|
94781
94837
|
const snag = useLogSnag();
|
|
94782
94838
|
channel2 = channel2 || "dev";
|
|
94783
94839
|
const config = await getConfig();
|
|
94784
|
-
const localS3 = (config
|
|
94840
|
+
const localS3 = (config?.app?.extConfig?.plugins && config?.app?.extConfig?.plugins?.CapacitorUpdater && config?.app?.extConfig?.plugins?.CapacitorUpdater?.localS3) === true;
|
|
94785
94841
|
const checkNotifyAppReady = options.codeCheck;
|
|
94786
94842
|
appid = appid || config?.app?.appId;
|
|
94787
94843
|
const uuid = (0, import_node_crypto3.randomUUID)().split("-")[0];
|
|
@@ -94795,8 +94851,8 @@ async function uploadBundle(appid, options, shouldExit = true) {
|
|
|
94795
94851
|
f2.error(`Missing API key, you need to provide a API key to upload your bundle`);
|
|
94796
94852
|
program.error("");
|
|
94797
94853
|
}
|
|
94798
|
-
if (!appid || !
|
|
94799
|
-
f2.error("Missing argument, you need to provide a appid and a
|
|
94854
|
+
if (!appid || !path3) {
|
|
94855
|
+
f2.error("Missing argument, you need to provide a appid and a path (--path), or be in a capacitor project");
|
|
94800
94856
|
program.error("");
|
|
94801
94857
|
}
|
|
94802
94858
|
if (s3BucketName || s3Region || s3Apikey || s3Apisecret) {
|
|
@@ -94843,7 +94899,7 @@ async function uploadBundle(appid, options, shouldExit = true) {
|
|
|
94843
94899
|
localDependencies = localDependenciesWithChannel;
|
|
94844
94900
|
if (finalCompatibility.find((x3) => x3.localVersion !== x3.remoteVersion)) {
|
|
94845
94901
|
f2.error(`Your bundle is not compatible with the channel ${channel2}`);
|
|
94846
|
-
f2.warn(`You can check compatibility with "
|
|
94902
|
+
f2.warn(`You can check compatibility with "${pm2.runner} @capgo/cli bundle compatibility"`);
|
|
94847
94903
|
if (autoMinUpdateVersion) {
|
|
94848
94904
|
minUpdateVersion = bundle2;
|
|
94849
94905
|
f2.info(`Auto set min-update-version to ${minUpdateVersion}`);
|
|
@@ -95015,9 +95071,10 @@ The app size is ${mbSize} Mb, this may take a while to download for users
|
|
|
95015
95071
|
f2.error(`Cannot get upload url`);
|
|
95016
95072
|
program.error("");
|
|
95017
95073
|
}
|
|
95074
|
+
const startTime = import_node_perf_hooks.performance.now();
|
|
95018
95075
|
try {
|
|
95019
95076
|
await distribution_default.put(url, {
|
|
95020
|
-
timeout: options.timeout ||
|
|
95077
|
+
timeout: options.timeout || UPLOAD_TIMEOUT,
|
|
95021
95078
|
retry: 5,
|
|
95022
95079
|
body: zipped,
|
|
95023
95080
|
headers: !localS3 ? {
|
|
@@ -95027,7 +95084,9 @@ The app size is ${mbSize} Mb, this may take a while to download for users
|
|
|
95027
95084
|
} : void 0
|
|
95028
95085
|
});
|
|
95029
95086
|
} catch (errorUpload) {
|
|
95030
|
-
|
|
95087
|
+
const endTime2 = import_node_perf_hooks.performance.now();
|
|
95088
|
+
const uploadTime2 = ((endTime2 - startTime) / 1e3).toFixed(2);
|
|
95089
|
+
spinner.stop(`Failed to upload bundle ( after ${uploadTime2} seconds)`);
|
|
95031
95090
|
f2.error(`Cannot upload bundle ${formatError(errorUpload)}`);
|
|
95032
95091
|
await deletedFailedVersion(supabase, appid, bundle2);
|
|
95033
95092
|
program.error("");
|
|
@@ -95038,7 +95097,9 @@ The app size is ${mbSize} Mb, this may take a while to download for users
|
|
|
95038
95097
|
f2.error(`Cannot update bundle ${formatError(dbError2)}`);
|
|
95039
95098
|
program.error("");
|
|
95040
95099
|
}
|
|
95041
|
-
|
|
95100
|
+
const endTime = import_node_perf_hooks.performance.now();
|
|
95101
|
+
const uploadTime = ((endTime - startTime) / 1e3).toFixed(2);
|
|
95102
|
+
spinner.stop(`Bundle Uploaded \u{1F4AA} (${uploadTime} seconds)`);
|
|
95042
95103
|
} else if (useS3 && zipped && s3Client) {
|
|
95043
95104
|
const spinner = de();
|
|
95044
95105
|
spinner.start(`Uploading Bundle`);
|
|
@@ -95049,6 +95110,7 @@ The app size is ${mbSize} Mb, this may take a while to download for users
|
|
|
95049
95110
|
Key: fileName,
|
|
95050
95111
|
Body: zipped
|
|
95051
95112
|
});
|
|
95113
|
+
const startTime = import_node_perf_hooks.performance.now();
|
|
95052
95114
|
const response = await s3Client.send(command);
|
|
95053
95115
|
if (response.$metadata.httpStatusCode !== 200) {
|
|
95054
95116
|
f2.error(`Cannot upload to S3`);
|
|
@@ -95061,7 +95123,9 @@ The app size is ${mbSize} Mb, this may take a while to download for users
|
|
|
95061
95123
|
f2.error(`Cannot update bundle ${formatError(dbError2)}`);
|
|
95062
95124
|
program.error("");
|
|
95063
95125
|
}
|
|
95064
|
-
|
|
95126
|
+
const endTime = import_node_perf_hooks.performance.now();
|
|
95127
|
+
const uploadTime = ((endTime - startTime) / 1e3).toFixed(2);
|
|
95128
|
+
spinner.stop(`Bundle Uploaded \u{1F4AA} (${uploadTime} seconds)`);
|
|
95065
95129
|
}
|
|
95066
95130
|
const { data: versionId } = await supabase.rpc("get_app_versions", { apikey: options.apikey, name_version: bundle2, appid }).single();
|
|
95067
95131
|
if (versionId && hasOrganizationPerm(permissions, 3 /* write */)) {
|
|
@@ -95115,7 +95179,8 @@ async function uploadCommand(apikey, options) {
|
|
|
95115
95179
|
}
|
|
95116
95180
|
}
|
|
95117
95181
|
async function uploadDeprecatedCommand(apikey, options) {
|
|
95118
|
-
|
|
95182
|
+
const pm2 = getPMAndCommand();
|
|
95183
|
+
f2.warn(`\u26A0\uFE0F This command is deprecated, use "${pm2.runner} @capgo/cli bundle upload" instead \u26A0\uFE0F`);
|
|
95119
95184
|
try {
|
|
95120
95185
|
await uploadBundle(apikey, options, true);
|
|
95121
95186
|
} catch (error) {
|
|
@@ -95128,6 +95193,10 @@ async function uploadDeprecatedCommand(apikey, options) {
|
|
|
95128
95193
|
var import_node_fs9 = require("node:fs");
|
|
95129
95194
|
var import_node_os3 = require("node:os");
|
|
95130
95195
|
var import_node_process14 = __toESM(require("node:process"));
|
|
95196
|
+
async function doLoginExists() {
|
|
95197
|
+
const userHomeDir = (0, import_node_os3.homedir)();
|
|
95198
|
+
return (0, import_node_fs9.existsSync)(`${userHomeDir}/.capgo`) || (0, import_node_fs9.existsSync)(".capgo");
|
|
95199
|
+
}
|
|
95131
95200
|
async function login(apikey, options, shouldExit = true) {
|
|
95132
95201
|
if (shouldExit)
|
|
95133
95202
|
oe(`Login to Capgo`);
|
|
@@ -95315,7 +95384,7 @@ async function addApp(appId, options, throwErr = true) {
|
|
|
95315
95384
|
f2.error(`App ${appId} already exist`);
|
|
95316
95385
|
program.error("");
|
|
95317
95386
|
} else if (appExist) {
|
|
95318
|
-
return
|
|
95387
|
+
return false;
|
|
95319
95388
|
}
|
|
95320
95389
|
const { error: orgError, data: allOrganizations } = await supabase.rpc("get_orgs_v5");
|
|
95321
95390
|
if (orgError) {
|
|
@@ -95439,27 +95508,29 @@ async function markStep(userId, snag, step) {
|
|
|
95439
95508
|
return markSnag("onboarding-v2", userId, snag, `onboarding-step-${step}`);
|
|
95440
95509
|
}
|
|
95441
95510
|
async function step2(userId, snag, appId, options) {
|
|
95511
|
+
const pm2 = getPMAndCommand();
|
|
95442
95512
|
const doAdd = await se({ message: `Add ${appId} in Capgo?` });
|
|
95443
95513
|
await cancelCommand2(doAdd, userId, snag);
|
|
95444
95514
|
if (doAdd) {
|
|
95445
95515
|
const s = de();
|
|
95446
|
-
s.start(`Running:
|
|
95516
|
+
s.start(`Running: ${pm2.runner} @capgo/cli@latest app add ${appId}`);
|
|
95447
95517
|
const addRes = await addApp(appId, options, false);
|
|
95448
95518
|
if (!addRes)
|
|
95449
95519
|
s.stop(`App already add \u2705`);
|
|
95450
95520
|
else
|
|
95451
95521
|
s.stop(`App add Done \u2705`);
|
|
95452
95522
|
} else {
|
|
95453
|
-
f2.info(`Run yourself "
|
|
95523
|
+
f2.info(`Run yourself "${pm2.runner} @capgo/cli@latest app add ${appId}"`);
|
|
95454
95524
|
}
|
|
95455
95525
|
await markStep(userId, snag, 2);
|
|
95456
95526
|
}
|
|
95457
95527
|
async function step3(userId, snag, apikey, appId) {
|
|
95528
|
+
const pm2 = getPMAndCommand();
|
|
95458
95529
|
const doChannel = await se({ message: `Create default channel ${defaultChannel} for ${appId} in Capgo?` });
|
|
95459
95530
|
await cancelCommand2(doChannel, userId, snag);
|
|
95460
95531
|
if (doChannel) {
|
|
95461
95532
|
const s = de();
|
|
95462
|
-
s.start(`Running:
|
|
95533
|
+
s.start(`Running: ${pm2.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default`);
|
|
95463
95534
|
const addChannelRes = await addChannel(defaultChannel, appId, {
|
|
95464
95535
|
default: true,
|
|
95465
95536
|
apikey
|
|
@@ -95469,13 +95540,14 @@ async function step3(userId, snag, apikey, appId) {
|
|
|
95469
95540
|
else
|
|
95470
95541
|
s.stop(`Channel add Done \u2705`);
|
|
95471
95542
|
} else {
|
|
95472
|
-
f2.info(`Run yourself "
|
|
95543
|
+
f2.info(`Run yourself "${pm2.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`);
|
|
95473
95544
|
}
|
|
95474
95545
|
await markStep(userId, snag, 3);
|
|
95475
95546
|
}
|
|
95476
95547
|
var urlMigrateV6 = "https://capacitorjs.com/docs/updating/6-0";
|
|
95477
95548
|
var urlMigrateV5 = "https://capacitorjs.com/docs/updating/5-0";
|
|
95478
95549
|
async function step4(userId, snag, apikey, appId) {
|
|
95550
|
+
const pm2 = getPMAndCommand();
|
|
95479
95551
|
const doInstall = await se({ message: `Automatic Install "@capgo/capacitor-updater" dependency in ${appId}?` });
|
|
95480
95552
|
await cancelCommand2(doInstall, userId, snag);
|
|
95481
95553
|
if (doInstall) {
|
|
@@ -95499,22 +95571,20 @@ async function step4(userId, snag, apikey, appId) {
|
|
|
95499
95571
|
s.stop(`@capacitor/core version is ${coreVersion}, please update to Capacitor v6: ${urlMigrateV6} to access the best features of Capgo`);
|
|
95500
95572
|
versionToInstall = "^5.0.0";
|
|
95501
95573
|
}
|
|
95502
|
-
|
|
95503
|
-
if (pm === "unknown") {
|
|
95574
|
+
if (pm2.pm === "unknown") {
|
|
95504
95575
|
s.stop("Error");
|
|
95505
|
-
f2.warn(`Cannot reconize package manager, please run \`capgo init\` in a capacitor project with npm, pnpm or yarn`);
|
|
95576
|
+
f2.warn(`Cannot reconize package manager, please run \`capgo init\` in a capacitor project with npm, pnpm, bun or yarn`);
|
|
95506
95577
|
$e(`Bye \u{1F44B}`);
|
|
95507
95578
|
import_node_process16.default.exit();
|
|
95508
95579
|
}
|
|
95509
|
-
const installCmd = pm === "yarn" ? "add" : "install";
|
|
95510
95580
|
if (pack.dependencies["@capgo/capacitor-updater"]) {
|
|
95511
95581
|
s.stop(`Capgo already installed \u2705`);
|
|
95512
95582
|
} else {
|
|
95513
|
-
await (0, import_node_child_process6.execSync)(`${
|
|
95583
|
+
await (0, import_node_child_process6.execSync)(`${pm2.installCommand} @capgo/capacitor-updater@${versionToInstall}`, execOption);
|
|
95514
95584
|
s.stop(`Install Done \u2705`);
|
|
95515
95585
|
}
|
|
95516
95586
|
} else {
|
|
95517
|
-
f2.info(`Run yourself "
|
|
95587
|
+
f2.info(`Run yourself "${pm2.installCommand} @capgo/capacitor-updater@latest"`);
|
|
95518
95588
|
}
|
|
95519
95589
|
await markStep(userId, snag, 4);
|
|
95520
95590
|
}
|
|
@@ -95568,11 +95638,12 @@ ${codeInject};
|
|
|
95568
95638
|
}
|
|
95569
95639
|
}
|
|
95570
95640
|
async function step6(userId, snag, apikey, appId) {
|
|
95641
|
+
const pm2 = getPMAndCommand();
|
|
95571
95642
|
const doEncrypt = await se({ message: `Automatic configure end-to-end encryption in ${appId} updates?` });
|
|
95572
95643
|
await cancelCommand2(doEncrypt, userId, snag);
|
|
95573
95644
|
if (doEncrypt) {
|
|
95574
95645
|
const s = de();
|
|
95575
|
-
s.start(`Running:
|
|
95646
|
+
s.start(`Running: ${pm2.runner} @capgo/cli@latest key create`);
|
|
95576
95647
|
const keyRes = await createKey({ force: true }, false);
|
|
95577
95648
|
if (!keyRes) {
|
|
95578
95649
|
s.stop("Error");
|
|
@@ -95587,13 +95658,14 @@ async function step6(userId, snag, apikey, appId) {
|
|
|
95587
95658
|
await markStep(userId, snag, 6);
|
|
95588
95659
|
}
|
|
95589
95660
|
async function step7(userId, snag, apikey, appId) {
|
|
95590
|
-
const
|
|
95661
|
+
const pm2 = getPMAndCommand();
|
|
95662
|
+
const doBuild = await se({ message: `Automatic build ${appId} with "${pm2.pm} run build" ?` });
|
|
95591
95663
|
await cancelCommand2(doBuild, userId, snag);
|
|
95592
95664
|
if (doBuild) {
|
|
95593
95665
|
const s = de();
|
|
95594
95666
|
const projectType = await findProjectType();
|
|
95595
95667
|
const buildCommand = await findBuildCommandForProjectType(projectType);
|
|
95596
|
-
s.start(`Running:
|
|
95668
|
+
s.start(`Running: ${pm2.pm} run ${buildCommand} && ${pm2.runner} cap sync`);
|
|
95597
95669
|
const pack = JSON.parse((0, import_node_fs11.readFileSync)("package.json").toString());
|
|
95598
95670
|
if (!pack.scripts[buildCommand]) {
|
|
95599
95671
|
s.stop("Error");
|
|
@@ -95601,19 +95673,20 @@ async function step7(userId, snag, apikey, appId) {
|
|
|
95601
95673
|
$e(`Bye \u{1F44B}`);
|
|
95602
95674
|
import_node_process16.default.exit();
|
|
95603
95675
|
}
|
|
95604
|
-
(0, import_node_child_process6.execSync)(
|
|
95676
|
+
(0, import_node_child_process6.execSync)(`${pm2.pm} run ${buildCommand} && ${pm2.runner} cap sync`, execOption);
|
|
95605
95677
|
s.stop(`Build & Sync Done \u2705`);
|
|
95606
95678
|
} else {
|
|
95607
|
-
f2.info(`Build yourself with command:
|
|
95679
|
+
f2.info(`Build yourself with command: ${pm2.pm} run build && ${pm2.runner} cap sync`);
|
|
95608
95680
|
}
|
|
95609
95681
|
await markStep(userId, snag, 7);
|
|
95610
95682
|
}
|
|
95611
95683
|
async function step8(userId, snag, apikey, appId) {
|
|
95684
|
+
const pm2 = getPMAndCommand();
|
|
95612
95685
|
const doBundle = await se({ message: `Automatic upload ${appId} bundle to Capgo?` });
|
|
95613
95686
|
await cancelCommand2(doBundle, userId, snag);
|
|
95614
95687
|
if (doBundle) {
|
|
95615
95688
|
const s = de();
|
|
95616
|
-
s.start(`Running:
|
|
95689
|
+
s.start(`Running: ${pm2.runner} @capgo/cli@latest bundle upload`);
|
|
95617
95690
|
const uploadRes = await uploadBundle(appId, {
|
|
95618
95691
|
channel: defaultChannel,
|
|
95619
95692
|
apikey
|
|
@@ -95627,11 +95700,12 @@ async function step8(userId, snag, apikey, appId) {
|
|
|
95627
95700
|
s.stop(`Upload Done \u2705`);
|
|
95628
95701
|
}
|
|
95629
95702
|
} else {
|
|
95630
|
-
f2.info(`Upload yourself with command:
|
|
95703
|
+
f2.info(`Upload yourself with command: ${pm2.runner} @capgo/cli@latest bundle upload`);
|
|
95631
95704
|
}
|
|
95632
95705
|
await markStep(userId, snag, 8);
|
|
95633
95706
|
}
|
|
95634
95707
|
async function step9(userId, snag) {
|
|
95708
|
+
const pm2 = getPMAndCommand();
|
|
95635
95709
|
const doRun = await se({ message: `Run in device now ?` });
|
|
95636
95710
|
await cancelCommand2(doRun, userId, snag);
|
|
95637
95711
|
if (doRun) {
|
|
@@ -95648,11 +95722,11 @@ async function step9(userId, snag) {
|
|
|
95648
95722
|
}
|
|
95649
95723
|
const platform2 = plaformType;
|
|
95650
95724
|
const s = de();
|
|
95651
|
-
s.start(`Running:
|
|
95652
|
-
await (0, import_node_child_process6.spawnSync)(
|
|
95725
|
+
s.start(`Running: ${pm2.runner} cap run ${platform2}`);
|
|
95726
|
+
await (0, import_node_child_process6.spawnSync)(pm2.runner, ["cap", "run", platform2], { stdio: "inherit" });
|
|
95653
95727
|
s.stop(`Started Done \u2705`);
|
|
95654
95728
|
} else {
|
|
95655
|
-
f2.info(`Run yourself with command:
|
|
95729
|
+
f2.info(`Run yourself with command: ${pm2.runner} cap run <ios|android>`);
|
|
95656
95730
|
}
|
|
95657
95731
|
await markStep(userId, snag, 9);
|
|
95658
95732
|
}
|
|
@@ -95669,20 +95743,20 @@ async function step10(userId, snag, supabase, appId) {
|
|
|
95669
95743
|
}
|
|
95670
95744
|
await markStep(userId, snag, 10);
|
|
95671
95745
|
}
|
|
95672
|
-
async function initApp(
|
|
95746
|
+
async function initApp(apikeyCommand, appId, options) {
|
|
95747
|
+
const pm2 = getPMAndCommand();
|
|
95673
95748
|
oe(`Capgo onboarding \u{1F6EB}`);
|
|
95674
95749
|
await checkLatest();
|
|
95675
95750
|
const snag = useLogSnag();
|
|
95676
95751
|
const config = await getConfig();
|
|
95677
95752
|
appId = appId || config?.app?.appId;
|
|
95678
|
-
apikey =
|
|
95753
|
+
const apikey = apikeyCommand || findSavedKey();
|
|
95679
95754
|
const log = de();
|
|
95680
|
-
|
|
95681
|
-
|
|
95682
|
-
|
|
95683
|
-
log.stop("Login already done \u2705");
|
|
95684
|
-
else
|
|
95755
|
+
if (!doLoginExists() || apikeyCommand) {
|
|
95756
|
+
log.start(`Running: ${pm2.runner} @capgo/cli@latest login ***`);
|
|
95757
|
+
await login(apikey, options, false);
|
|
95685
95758
|
log.stop("Login Done \u2705");
|
|
95759
|
+
}
|
|
95686
95760
|
const supabase = await createSupabaseClient(apikey);
|
|
95687
95761
|
const userId = await verifyUser(supabase, apikey, ["upload", "all", "read", "write"]);
|
|
95688
95762
|
await markStep(userId, snag, 1);
|
|
@@ -95698,7 +95772,7 @@ async function initApp(apikey, appId, options) {
|
|
|
95698
95772
|
await markStep(userId, snag, 0);
|
|
95699
95773
|
f2.info(`Welcome onboard \u2708\uFE0F!`);
|
|
95700
95774
|
f2.info(`Your Capgo update system is setup`);
|
|
95701
|
-
f2.info(`Next time use
|
|
95775
|
+
f2.info(`Next time use \`${pm2.runner} @capgo/cli@latest bundle upload\` to only upload your bundle`);
|
|
95702
95776
|
$e(`Bye \u{1F44B}`);
|
|
95703
95777
|
import_node_process16.default.exit();
|
|
95704
95778
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.0",
|
|
4
4
|
"description": "A CLI to upload to capgo servers",
|
|
5
5
|
"author": "github.com/riderx",
|
|
6
6
|
"license": "Apache 2.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@aws-sdk/client-s3": "^3.563.0",
|
|
47
47
|
"@capacitor/cli": "6.0.0",
|
|
48
|
-
"@capgo/find-package-manager": "0.0.
|
|
48
|
+
"@capgo/find-package-manager": "^0.0.16",
|
|
49
49
|
"@clack/prompts": "^0.7.0",
|
|
50
50
|
"@supabase/supabase-js": "^2.42.7",
|
|
51
51
|
"@tomasklaen/checksum": "^1.1.0",
|
package/src/api/app.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as p from '@clack/prompts'
|
|
|
3
3
|
import { program } from 'commander'
|
|
4
4
|
import type { Database } from '../types/supabase.types'
|
|
5
5
|
import type { OptionsBase } from '../utils'
|
|
6
|
-
import { OrganizationPerm,
|
|
6
|
+
import { OrganizationPerm, getPMAndCommand, isAllowedAppOrg } from '../utils'
|
|
7
7
|
|
|
8
8
|
export async function checkAppExists(supabase: SupabaseClient<Database>, appid: string) {
|
|
9
9
|
const { data: app } = await supabase
|
|
@@ -12,28 +12,8 @@ export async function checkAppExists(supabase: SupabaseClient<Database>, appid:
|
|
|
12
12
|
return !!app
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export async function checkAppExistsAndHasPermissionErr(supabase: SupabaseClient<Database>, apikey: string, appid: string, shouldExist = true) {
|
|
16
|
-
const appExist = await checkAppExists(supabase, appid)
|
|
17
|
-
const perm = await isAllowedApp(supabase, apikey, appid)
|
|
18
|
-
|
|
19
|
-
if (appExist && !shouldExist) {
|
|
20
|
-
p.log.error(`App ${appid} already exist`)
|
|
21
|
-
program.error('')
|
|
22
|
-
}
|
|
23
|
-
if (!appExist && shouldExist) {
|
|
24
|
-
p.log.error(`App ${appid} does not exist`)
|
|
25
|
-
program.error('')
|
|
26
|
-
}
|
|
27
|
-
if (appExist && !perm) {
|
|
28
|
-
p.log.error(`App ${appid} exist and you don't have permission to access it`)
|
|
29
|
-
if (appid === 'io.ionic.starter')
|
|
30
|
-
p.log.info('Modify your appid in your capacitor.config.json file to something unique, this is a default appid for ionic starter app')
|
|
31
|
-
|
|
32
|
-
program.error('')
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
15
|
export async function checkAppExistsAndHasPermissionOrgErr(supabase: SupabaseClient<Database>, apikey: string, appid: string, requiredPermission: OrganizationPerm) {
|
|
16
|
+
const pm = getPMAndCommand()
|
|
37
17
|
const permissions = await isAllowedAppOrg(supabase, apikey, appid)
|
|
38
18
|
if (!permissions.okay) {
|
|
39
19
|
switch (permissions.error) {
|
|
@@ -43,7 +23,7 @@ export async function checkAppExistsAndHasPermissionOrgErr(supabase: SupabaseCli
|
|
|
43
23
|
break
|
|
44
24
|
}
|
|
45
25
|
case 'NO_APP': {
|
|
46
|
-
p.log.error(`App ${appid} does not exist`)
|
|
26
|
+
p.log.error(`App ${appid} does not exist, run first \`${pm.runner} @capgo/cli app add ${appid}\` to create it`)
|
|
47
27
|
program.error('')
|
|
48
28
|
break
|
|
49
29
|
}
|
package/src/app/add.ts
CHANGED
package/src/bundle/upload.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto'
|
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs'
|
|
3
3
|
import process from 'node:process'
|
|
4
4
|
import type { Buffer } from 'node:buffer'
|
|
5
|
+
import { performance } from 'node:perf_hooks'
|
|
5
6
|
import AdmZip from 'adm-zip'
|
|
6
7
|
import { program } from 'commander'
|
|
7
8
|
import * as p from '@clack/prompts'
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
getLocalConfig,
|
|
33
34
|
getLocalDepenencies,
|
|
34
35
|
getOrganizationId,
|
|
36
|
+
getPMAndCommand,
|
|
35
37
|
hasOrganizationPerm,
|
|
36
38
|
regexSemver,
|
|
37
39
|
requireUpdateMetadata,
|
|
@@ -66,7 +68,10 @@ interface Options extends OptionsBase {
|
|
|
66
68
|
timeout?: number
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
const UPLOAD_TIMEOUT = 120000
|
|
72
|
+
|
|
69
73
|
export async function uploadBundle(appid: string, options: Options, shouldExit = true) {
|
|
74
|
+
const pm = getPMAndCommand()
|
|
70
75
|
p.intro(`Uploading`)
|
|
71
76
|
await checkLatest()
|
|
72
77
|
let { bundle, path, channel } = options
|
|
@@ -93,8 +98,8 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
|
|
|
93
98
|
channel = channel || 'dev'
|
|
94
99
|
|
|
95
100
|
const config = await getConfig()
|
|
96
|
-
const localS3: boolean = (config
|
|
97
|
-
&& config
|
|
101
|
+
const localS3: boolean = (config?.app?.extConfig?.plugins && config?.app?.extConfig?.plugins?.CapacitorUpdater
|
|
102
|
+
&& config?.app?.extConfig?.plugins?.CapacitorUpdater?.localS3) === true
|
|
98
103
|
|
|
99
104
|
const checkNotifyAppReady = options.codeCheck
|
|
100
105
|
appid = appid || config?.app?.appId
|
|
@@ -111,8 +116,8 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
|
|
|
111
116
|
p.log.error(`Missing API key, you need to provide a API key to upload your bundle`)
|
|
112
117
|
program.error('')
|
|
113
118
|
}
|
|
114
|
-
if (!appid || !
|
|
115
|
-
p.log.error('Missing argument, you need to provide a appid and a
|
|
119
|
+
if (!appid || !path) {
|
|
120
|
+
p.log.error('Missing argument, you need to provide a appid and a path (--path), or be in a capacitor project')
|
|
116
121
|
program.error('')
|
|
117
122
|
}
|
|
118
123
|
// if one S3 variable is set, check that all are set
|
|
@@ -147,8 +152,6 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
|
|
|
147
152
|
const supabase = await createSupabaseClient(options.apikey)
|
|
148
153
|
const userId = await verifyUser(supabase, options.apikey, ['write', 'all', 'upload'])
|
|
149
154
|
// Check we have app access to this appId
|
|
150
|
-
// await checkAppExistsAndHasPermissionErr(supabase, options.apikey, appid);
|
|
151
|
-
|
|
152
155
|
const permissions = await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appid, OrganizationPerm.upload)
|
|
153
156
|
|
|
154
157
|
// Now if it does exist we will fetch the org id
|
|
@@ -183,7 +186,7 @@ export async function uploadBundle(appid: string, options: Options, shouldExit =
|
|
|
183
186
|
|
|
184
187
|
if (finalCompatibility.find(x => x.localVersion !== x.remoteVersion)) {
|
|
185
188
|
p.log.error(`Your bundle is not compatible with the channel ${channel}`)
|
|
186
|
-
p.log.warn(`You can check compatibility with "
|
|
189
|
+
p.log.warn(`You can check compatibility with "${pm.runner} @capgo/cli bundle compatibility"`)
|
|
187
190
|
|
|
188
191
|
if (autoMinUpdateVersion) {
|
|
189
192
|
minUpdateVersion = bundle
|
|
@@ -384,9 +387,10 @@ It will be also visible in your dashboard\n`)
|
|
|
384
387
|
p.log.error(`Cannot get upload url`)
|
|
385
388
|
program.error('')
|
|
386
389
|
}
|
|
390
|
+
const startTime = performance.now()
|
|
387
391
|
try {
|
|
388
392
|
await ky.put(url, {
|
|
389
|
-
timeout: options.timeout ||
|
|
393
|
+
timeout: options.timeout || UPLOAD_TIMEOUT,
|
|
390
394
|
retry: 5,
|
|
391
395
|
body: zipped,
|
|
392
396
|
headers: (!localS3
|
|
@@ -399,7 +403,9 @@ It will be also visible in your dashboard\n`)
|
|
|
399
403
|
})
|
|
400
404
|
}
|
|
401
405
|
catch (errorUpload) {
|
|
402
|
-
|
|
406
|
+
const endTime = performance.now()
|
|
407
|
+
const uploadTime = ((endTime - startTime) / 1000).toFixed(2)
|
|
408
|
+
spinner.stop(`Failed to upload bundle ( after ${uploadTime} seconds)`)
|
|
403
409
|
p.log.error(`Cannot upload bundle ${formatError(errorUpload)}`)
|
|
404
410
|
// call delete version on path /delete_failed_version to delete the version
|
|
405
411
|
await deletedFailedVersion(supabase, appid, bundle)
|
|
@@ -411,7 +417,9 @@ It will be also visible in your dashboard\n`)
|
|
|
411
417
|
p.log.error(`Cannot update bundle ${formatError(dbError2)}`)
|
|
412
418
|
program.error('')
|
|
413
419
|
}
|
|
414
|
-
|
|
420
|
+
const endTime = performance.now()
|
|
421
|
+
const uploadTime = ((endTime - startTime) / 1000).toFixed(2)
|
|
422
|
+
spinner.stop(`Bundle Uploaded 💪 (${uploadTime} seconds)`)
|
|
415
423
|
}
|
|
416
424
|
else if (useS3 && zipped && s3Client) {
|
|
417
425
|
const spinner = p.spinner()
|
|
@@ -424,7 +432,7 @@ It will be also visible in your dashboard\n`)
|
|
|
424
432
|
Key: fileName,
|
|
425
433
|
Body: zipped,
|
|
426
434
|
})
|
|
427
|
-
|
|
435
|
+
const startTime = performance.now()
|
|
428
436
|
const response = await s3Client.send(command)
|
|
429
437
|
if (response.$metadata.httpStatusCode !== 200) {
|
|
430
438
|
p.log.error(`Cannot upload to S3`)
|
|
@@ -438,7 +446,9 @@ It will be also visible in your dashboard\n`)
|
|
|
438
446
|
p.log.error(`Cannot update bundle ${formatError(dbError2)}`)
|
|
439
447
|
program.error('')
|
|
440
448
|
}
|
|
441
|
-
|
|
449
|
+
const endTime = performance.now()
|
|
450
|
+
const uploadTime = ((endTime - startTime) / 1000).toFixed(2)
|
|
451
|
+
spinner.stop(`Bundle Uploaded 💪 (${uploadTime} seconds)`)
|
|
442
452
|
}
|
|
443
453
|
const { data: versionId } = await supabase
|
|
444
454
|
.rpc('get_app_versions', { apikey: options.apikey, name_version: bundle, appid })
|
|
@@ -501,7 +511,8 @@ export async function uploadCommand(apikey: string, options: Options) {
|
|
|
501
511
|
}
|
|
502
512
|
|
|
503
513
|
export async function uploadDeprecatedCommand(apikey: string, options: Options) {
|
|
504
|
-
|
|
514
|
+
const pm = getPMAndCommand()
|
|
515
|
+
p.log.warn(`⚠️ This command is deprecated, use "${pm.runner} @capgo/cli bundle upload" instead ⚠️`)
|
|
505
516
|
try {
|
|
506
517
|
await uploadBundle(apikey, options, true)
|
|
507
518
|
}
|
package/src/init.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { readFileSync, writeFileSync } from 'node:fs'
|
|
|
2
2
|
import type { ExecSyncOptions } from 'node:child_process'
|
|
3
3
|
import { execSync, spawnSync } from 'node:child_process'
|
|
4
4
|
import process from 'node:process'
|
|
5
|
-
import { findPackageManagerType } from '@capgo/find-package-manager'
|
|
6
5
|
import * as p from '@clack/prompts'
|
|
7
6
|
import type { SupabaseClient } from '@supabase/supabase-js'
|
|
8
7
|
import type LogSnag from 'logsnag'
|
|
@@ -12,11 +11,11 @@ import { markSnag, waitLog } from './app/debug'
|
|
|
12
11
|
import { createKey } from './key'
|
|
13
12
|
import { addChannel } from './channel/add'
|
|
14
13
|
import { uploadBundle } from './bundle/upload'
|
|
15
|
-
import { login } from './login'
|
|
14
|
+
import { doLoginExists, login } from './login'
|
|
16
15
|
import { addApp } from './app/add'
|
|
17
16
|
import { checkLatest } from './api/update'
|
|
18
17
|
import type { Options } from './api/app'
|
|
19
|
-
import { convertAppName, createSupabaseClient, findBuildCommandForProjectType, findMainFile, findMainFileForProjectType, findProjectType, findSavedKey, getConfig, useLogSnag, verifyUser } from './utils'
|
|
18
|
+
import { convertAppName, createSupabaseClient, findBuildCommandForProjectType, findMainFile, findMainFileForProjectType, findProjectType, findSavedKey, getConfig, getPMAndCommand, useLogSnag, verifyUser } from './utils'
|
|
20
19
|
|
|
21
20
|
interface SuperOptions extends Options {
|
|
22
21
|
local: boolean
|
|
@@ -40,11 +39,12 @@ async function markStep(userId: string, snag: LogSnag, step: number | string) {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
async function step2(userId: string, snag: LogSnag, appId: string, options: SuperOptions) {
|
|
42
|
+
const pm = getPMAndCommand()
|
|
43
43
|
const doAdd = await p.confirm({ message: `Add ${appId} in Capgo?` })
|
|
44
44
|
await cancelCommand(doAdd, userId, snag)
|
|
45
45
|
if (doAdd) {
|
|
46
46
|
const s = p.spinner()
|
|
47
|
-
s.start(`Running:
|
|
47
|
+
s.start(`Running: ${pm.runner} @capgo/cli@latest app add ${appId}`)
|
|
48
48
|
const addRes = await addApp(appId, options, false)
|
|
49
49
|
if (!addRes)
|
|
50
50
|
s.stop(`App already add ✅`)
|
|
@@ -52,18 +52,19 @@ async function step2(userId: string, snag: LogSnag, appId: string, options: Supe
|
|
|
52
52
|
s.stop(`App add Done ✅`)
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
|
-
p.log.info(`Run yourself "
|
|
55
|
+
p.log.info(`Run yourself "${pm.runner} @capgo/cli@latest app add ${appId}"`)
|
|
56
56
|
}
|
|
57
57
|
await markStep(userId, snag, 2)
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
async function step3(userId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
61
|
+
const pm = getPMAndCommand()
|
|
61
62
|
const doChannel = await p.confirm({ message: `Create default channel ${defaultChannel} for ${appId} in Capgo?` })
|
|
62
63
|
await cancelCommand(doChannel, userId, snag)
|
|
63
64
|
if (doChannel) {
|
|
64
65
|
const s = p.spinner()
|
|
65
66
|
// create production channel public
|
|
66
|
-
s.start(`Running:
|
|
67
|
+
s.start(`Running: ${pm.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default`)
|
|
67
68
|
const addChannelRes = await addChannel(defaultChannel, appId, {
|
|
68
69
|
default: true,
|
|
69
70
|
apikey,
|
|
@@ -74,7 +75,7 @@ async function step3(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
74
75
|
s.stop(`Channel add Done ✅`)
|
|
75
76
|
}
|
|
76
77
|
else {
|
|
77
|
-
p.log.info(`Run yourself "
|
|
78
|
+
p.log.info(`Run yourself "${pm.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`)
|
|
78
79
|
}
|
|
79
80
|
await markStep(userId, snag, 3)
|
|
80
81
|
}
|
|
@@ -82,6 +83,7 @@ async function step3(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
82
83
|
const urlMigrateV6 = 'https://capacitorjs.com/docs/updating/6-0'
|
|
83
84
|
const urlMigrateV5 = 'https://capacitorjs.com/docs/updating/5-0'
|
|
84
85
|
async function step4(userId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
86
|
+
const pm = getPMAndCommand()
|
|
85
87
|
const doInstall = await p.confirm({ message: `Automatic Install "@capgo/capacitor-updater" dependency in ${appId}?` })
|
|
86
88
|
await cancelCommand(doInstall, userId, snag)
|
|
87
89
|
if (doInstall) {
|
|
@@ -107,27 +109,25 @@ async function step4(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
107
109
|
s.stop(`@capacitor/core version is ${coreVersion}, please update to Capacitor v6: ${urlMigrateV6} to access the best features of Capgo`)
|
|
108
110
|
versionToInstall = '^5.0.0'
|
|
109
111
|
}
|
|
110
|
-
|
|
111
|
-
if (pm === 'unknown') {
|
|
112
|
+
if (pm.pm === 'unknown') {
|
|
112
113
|
s.stop('Error')
|
|
113
|
-
p.log.warn(`Cannot reconize package manager, please run \`capgo init\` in a capacitor project with npm, pnpm or yarn`)
|
|
114
|
+
p.log.warn(`Cannot reconize package manager, please run \`capgo init\` in a capacitor project with npm, pnpm, bun or yarn`)
|
|
114
115
|
p.outro(`Bye 👋`)
|
|
115
116
|
process.exit()
|
|
116
117
|
}
|
|
117
118
|
// // use pm to install capgo
|
|
118
119
|
// // run command pm install @capgo/capacitor-updater@latest
|
|
119
|
-
const installCmd = pm === 'yarn' ? 'add' : 'install'
|
|
120
120
|
// check if capgo is already installed in package.json
|
|
121
121
|
if (pack.dependencies['@capgo/capacitor-updater']) {
|
|
122
122
|
s.stop(`Capgo already installed ✅`)
|
|
123
123
|
}
|
|
124
124
|
else {
|
|
125
|
-
await execSync(`${pm}
|
|
125
|
+
await execSync(`${pm.installCommand} @capgo/capacitor-updater@${versionToInstall}`, execOption as ExecSyncOptions)
|
|
126
126
|
s.stop(`Install Done ✅`)
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
else {
|
|
130
|
-
p.log.info(`Run yourself "
|
|
130
|
+
p.log.info(`Run yourself "${pm.installCommand} @capgo/capacitor-updater@latest"`)
|
|
131
131
|
}
|
|
132
132
|
await markStep(userId, snag, 4)
|
|
133
133
|
}
|
|
@@ -180,11 +180,12 @@ async function step5(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
async function step6(userId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
183
|
+
const pm = getPMAndCommand()
|
|
183
184
|
const doEncrypt = await p.confirm({ message: `Automatic configure end-to-end encryption in ${appId} updates?` })
|
|
184
185
|
await cancelCommand(doEncrypt, userId, snag)
|
|
185
186
|
if (doEncrypt) {
|
|
186
187
|
const s = p.spinner()
|
|
187
|
-
s.start(`Running:
|
|
188
|
+
s.start(`Running: ${pm.runner} @capgo/cli@latest key create`)
|
|
188
189
|
const keyRes = await createKey({ force: true }, false)
|
|
189
190
|
if (!keyRes) {
|
|
190
191
|
s.stop('Error')
|
|
@@ -201,13 +202,14 @@ async function step6(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
201
202
|
}
|
|
202
203
|
|
|
203
204
|
async function step7(userId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
204
|
-
const
|
|
205
|
+
const pm = getPMAndCommand()
|
|
206
|
+
const doBuild = await p.confirm({ message: `Automatic build ${appId} with "${pm.pm} run build" ?` })
|
|
205
207
|
await cancelCommand(doBuild, userId, snag)
|
|
206
208
|
if (doBuild) {
|
|
207
209
|
const s = p.spinner()
|
|
208
210
|
const projectType = await findProjectType()
|
|
209
211
|
const buildCommand = await findBuildCommandForProjectType(projectType)
|
|
210
|
-
s.start(`Running:
|
|
212
|
+
s.start(`Running: ${pm.pm} run ${buildCommand} && ${pm.runner} cap sync`)
|
|
211
213
|
const pack = JSON.parse(readFileSync('package.json').toString())
|
|
212
214
|
// check in script build exist
|
|
213
215
|
if (!pack.scripts[buildCommand]) {
|
|
@@ -216,21 +218,22 @@ async function step7(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
216
218
|
p.outro(`Bye 👋`)
|
|
217
219
|
process.exit()
|
|
218
220
|
}
|
|
219
|
-
execSync(
|
|
221
|
+
execSync(`${pm.pm} run ${buildCommand} && ${pm.runner} cap sync`, execOption as ExecSyncOptions)
|
|
220
222
|
s.stop(`Build & Sync Done ✅`)
|
|
221
223
|
}
|
|
222
224
|
else {
|
|
223
|
-
p.log.info(`Build yourself with command:
|
|
225
|
+
p.log.info(`Build yourself with command: ${pm.pm} run build && ${pm.runner} cap sync`)
|
|
224
226
|
}
|
|
225
227
|
await markStep(userId, snag, 7)
|
|
226
228
|
}
|
|
227
229
|
|
|
228
230
|
async function step8(userId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
231
|
+
const pm = getPMAndCommand()
|
|
229
232
|
const doBundle = await p.confirm({ message: `Automatic upload ${appId} bundle to Capgo?` })
|
|
230
233
|
await cancelCommand(doBundle, userId, snag)
|
|
231
234
|
if (doBundle) {
|
|
232
235
|
const s = p.spinner()
|
|
233
|
-
s.start(`Running:
|
|
236
|
+
s.start(`Running: ${pm.runner} @capgo/cli@latest bundle upload`)
|
|
234
237
|
const uploadRes = await uploadBundle(appId, {
|
|
235
238
|
channel: defaultChannel,
|
|
236
239
|
apikey,
|
|
@@ -246,12 +249,13 @@ async function step8(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
246
249
|
}
|
|
247
250
|
}
|
|
248
251
|
else {
|
|
249
|
-
p.log.info(`Upload yourself with command:
|
|
252
|
+
p.log.info(`Upload yourself with command: ${pm.runner} @capgo/cli@latest bundle upload`)
|
|
250
253
|
}
|
|
251
254
|
await markStep(userId, snag, 8)
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
async function step9(userId: string, snag: LogSnag) {
|
|
258
|
+
const pm = getPMAndCommand()
|
|
255
259
|
const doRun = await p.confirm({ message: `Run in device now ?` })
|
|
256
260
|
await cancelCommand(doRun, userId, snag)
|
|
257
261
|
if (doRun) {
|
|
@@ -269,12 +273,12 @@ async function step9(userId: string, snag: LogSnag) {
|
|
|
269
273
|
|
|
270
274
|
const platform = plaformType as 'ios' | 'android'
|
|
271
275
|
const s = p.spinner()
|
|
272
|
-
s.start(`Running:
|
|
273
|
-
await spawnSync(
|
|
276
|
+
s.start(`Running: ${pm.runner} cap run ${platform}`)
|
|
277
|
+
await spawnSync(pm.runner, ['cap', 'run', platform], { stdio: 'inherit' })
|
|
274
278
|
s.stop(`Started Done ✅`)
|
|
275
279
|
}
|
|
276
280
|
else {
|
|
277
|
-
p.log.info(`Run yourself with command:
|
|
281
|
+
p.log.info(`Run yourself with command: ${pm.runner} cap run <ios|android>`)
|
|
278
282
|
}
|
|
279
283
|
await markStep(userId, snag, 9)
|
|
280
284
|
}
|
|
@@ -294,21 +298,21 @@ async function step10(userId: string, snag: LogSnag, supabase: SupabaseClient<Da
|
|
|
294
298
|
await markStep(userId, snag, 10)
|
|
295
299
|
}
|
|
296
300
|
|
|
297
|
-
export async function initApp(
|
|
301
|
+
export async function initApp(apikeyCommand: string, appId: string, options: SuperOptions) {
|
|
302
|
+
const pm = getPMAndCommand()
|
|
298
303
|
p.intro(`Capgo onboarding 🛫`)
|
|
299
304
|
await checkLatest()
|
|
300
305
|
const snag = useLogSnag()
|
|
301
306
|
const config = await getConfig()
|
|
302
307
|
appId = appId || config?.app?.appId
|
|
303
|
-
apikey =
|
|
308
|
+
const apikey = apikeyCommand || findSavedKey()
|
|
304
309
|
|
|
305
310
|
const log = p.spinner()
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
log.stop('Login already done ✅')
|
|
310
|
-
else
|
|
311
|
+
if (!doLoginExists() || apikeyCommand) {
|
|
312
|
+
log.start(`Running: ${pm.runner} @capgo/cli@latest login ***`)
|
|
313
|
+
await login(apikey, options, false)
|
|
311
314
|
log.stop('Login Done ✅')
|
|
315
|
+
}
|
|
312
316
|
|
|
313
317
|
const supabase = await createSupabaseClient(apikey)
|
|
314
318
|
const userId = await verifyUser(supabase, apikey, ['upload', 'all', 'read', 'write'])
|
|
@@ -327,7 +331,7 @@ export async function initApp(apikey: string, appId: string, options: SuperOptio
|
|
|
327
331
|
await markStep(userId, snag, 0)
|
|
328
332
|
p.log.info(`Welcome onboard ✈️!`)
|
|
329
333
|
p.log.info(`Your Capgo update system is setup`)
|
|
330
|
-
p.log.info(`Next time use
|
|
334
|
+
p.log.info(`Next time use \`${pm.runner} @capgo/cli@latest bundle upload\` to only upload your bundle`)
|
|
331
335
|
p.outro(`Bye 👋`)
|
|
332
336
|
process.exit()
|
|
333
337
|
}
|
package/src/login.ts
CHANGED
|
@@ -9,6 +9,10 @@ import { checkLatest } from './api/update'
|
|
|
9
9
|
interface Options {
|
|
10
10
|
local: boolean
|
|
11
11
|
}
|
|
12
|
+
export async function doLoginExists() {
|
|
13
|
+
const userHomeDir = homedir()
|
|
14
|
+
return existsSync(`${userHomeDir}/.capgo`) || existsSync('.capgo')
|
|
15
|
+
}
|
|
12
16
|
|
|
13
17
|
export async function login(apikey: string, options: Options, shouldExit = true) {
|
|
14
18
|
if (shouldExit)
|
package/src/utils.ts
CHANGED
|
@@ -11,6 +11,8 @@ import { LogSnag } from 'logsnag'
|
|
|
11
11
|
import * as p from '@clack/prompts'
|
|
12
12
|
import ky from 'ky'
|
|
13
13
|
import { promiseFiles } from 'node-dir'
|
|
14
|
+
import type { InstallCommand, PackageManagerRunner, PackageManagerType } from '@capgo/find-package-manager'
|
|
15
|
+
import { findInstallCommand, findPackageManagerRunner, findPackageManagerType } from '@capgo/find-package-manager'
|
|
14
16
|
import type { Database } from './types/supabase.types'
|
|
15
17
|
|
|
16
18
|
export const baseKey = '.capgo_key'
|
|
@@ -38,7 +40,7 @@ export async function getConfig() {
|
|
|
38
40
|
config = await loadConfig()
|
|
39
41
|
}
|
|
40
42
|
catch (err) {
|
|
41
|
-
p.log.error(
|
|
43
|
+
p.log.error(`No capacitor config file found, run \`cap init\` first ${formatError(err)}`)
|
|
42
44
|
program.error('')
|
|
43
45
|
}
|
|
44
46
|
return config
|
|
@@ -305,7 +307,7 @@ export function findSavedKey(quiet = false) {
|
|
|
305
307
|
key = readFileSync(keyPath, 'utf8').trim()
|
|
306
308
|
}
|
|
307
309
|
if (!key) {
|
|
308
|
-
p.log.error(`Cannot find API key in local folder or global, please login first with
|
|
310
|
+
p.log.error(`Cannot find API key in local folder or global, please login first with ${getPMAndCommand().runner} @capacitor/cli login`)
|
|
309
311
|
program.error('')
|
|
310
312
|
}
|
|
311
313
|
return key
|
|
@@ -624,6 +626,20 @@ export function getHumanDate(createdA: string | null) {
|
|
|
624
626
|
return date.toLocaleString()
|
|
625
627
|
}
|
|
626
628
|
|
|
629
|
+
let pmFetched = false
|
|
630
|
+
let pm: PackageManagerType = 'npm'
|
|
631
|
+
let pmCommand: InstallCommand = 'install'
|
|
632
|
+
let pmRunner: PackageManagerRunner = 'npx'
|
|
633
|
+
export function getPMAndCommand() {
|
|
634
|
+
if (pmFetched)
|
|
635
|
+
return { pm, command: pmCommand, installCommand: `${pm} ${pmCommand}`, runner: pmRunner }
|
|
636
|
+
pm = findPackageManagerType('.', 'npm')
|
|
637
|
+
pmCommand = findInstallCommand(pm)
|
|
638
|
+
pmFetched = true
|
|
639
|
+
pmRunner = findPackageManagerRunner()
|
|
640
|
+
return { pm, command: pmCommand, installCommand: `${pm} ${pmCommand}`, runner: pmRunner }
|
|
641
|
+
}
|
|
642
|
+
|
|
627
643
|
export async function getLocalDepenencies() {
|
|
628
644
|
if (!existsSync('./package.json')) {
|
|
629
645
|
p.log.error('Missing package.json, you need to be in a capacitor project')
|
|
@@ -654,7 +670,9 @@ export async function getLocalDepenencies() {
|
|
|
654
670
|
}
|
|
655
671
|
|
|
656
672
|
if (!existsSync('./node_modules/')) {
|
|
657
|
-
|
|
673
|
+
const pm = findPackageManagerType('.', 'npm')
|
|
674
|
+
const installCmd = findInstallCommand(pm)
|
|
675
|
+
p.log.error(`Missing node_modules folder, please run ${pm} ${installCmd}`)
|
|
658
676
|
program.error('')
|
|
659
677
|
}
|
|
660
678
|
|
|
@@ -667,7 +685,9 @@ export async function getLocalDepenencies() {
|
|
|
667
685
|
|
|
668
686
|
if (!dependencyFolderExists) {
|
|
669
687
|
anyInvalid = true
|
|
670
|
-
|
|
688
|
+
const pm = findPackageManagerType('.', 'npm')
|
|
689
|
+
const installCmd = findInstallCommand(pm)
|
|
690
|
+
p.log.error(`Missing dependency ${key}, please run ${pm} ${installCmd}`)
|
|
671
691
|
return { name: key, version: value }
|
|
672
692
|
}
|
|
673
693
|
|