@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 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.6.3",
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.11",
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("No capacitor config file found, run `cap init` first");
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 npx @capacitor/cli login`);
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
- f2.error("Missing node_modules folder, please run npm install");
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
- f2.error(`Missing dependency ${key2}, please run npm install`);
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.app.extConfig.plugins && config.app.extConfig.plugins.CapacitorUpdater && config.app.extConfig.plugins.CapacitorUpdater.localS3) === true;
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 || !bundle2 || !path3) {
94799
- f2.error("Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project");
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 "npx @capgo/cli bundle compatibility"`);
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 || 12e4,
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
- spinner.stop("Failed to upload bundle");
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
- spinner.stop("Bundle Uploaded \u{1F4AA}");
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
- spinner.stop("Bundle Uploaded \u{1F4AA}");
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
- f2.warn('\u26A0\uFE0F This command is deprecated, use "npx @capgo/cli bundle upload" instead \u26A0\uFE0F');
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 true;
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: npx @capgo/cli@latest app add ${appId}`);
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 "npx @capgo/cli@latest app add ${appId}"`);
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: npx @capgo/cli@latest channel add ${defaultChannel} ${appId} --default`);
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 "npx @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`);
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
- const pm = findPackageManagerType();
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)(`${pm} ${installCmd} @capgo/capacitor-updater@${versionToInstall}`, execOption);
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 "npm i @capgo/capacitor-updater@latest"`);
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: npx @capgo/cli@latest key create`);
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 doBuild = await se({ message: `Automatic build ${appId} with "npm run build" ?` });
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: npm run ${buildCommand} && npx cap sync`);
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)(`npm run ${buildCommand} && npx cap sync`, execOption);
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: npm run build && npx cap sync`);
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: npx @capgo/cli@latest bundle upload`);
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: npx @capgo/cli@latest bundle upload`);
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: npx cap run ${platform2}`);
95652
- await (0, import_node_child_process6.spawnSync)("npx", ["cap", "run", platform2], { stdio: "inherit" });
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: npx cap run <ios|android>`);
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(apikey, appId, options) {
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 = apikey || findSavedKey();
95753
+ const apikey = apikeyCommand || findSavedKey();
95679
95754
  const log = de();
95680
- log.start("Running: npx @capgo/cli@latest login ***");
95681
- const loginRes = await login(apikey, options, false);
95682
- if (!loginRes)
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 \`npx @capgo/cli@latest bundle upload\` to only upload your bundle`);
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.6.3",
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.11",
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, isAllowedApp, isAllowedAppOrg } from '../utils'
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
@@ -52,7 +52,7 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
52
52
  program.error('')
53
53
  }
54
54
  else if (appExist) {
55
- return true
55
+ return false
56
56
  }
57
57
 
58
58
  const { error: orgError, data: allOrganizations } = await supabase
@@ -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.app.extConfig.plugins && config.app.extConfig.plugins.CapacitorUpdater
97
- && config.app.extConfig.plugins.CapacitorUpdater.localS3) === true
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 || !bundle || !path) {
115
- p.log.error('Missing argument, you need to provide a appid and a bundle and a path, or be in a capacitor project')
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 "npx @capgo/cli bundle compatibility"`)
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 || 120000,
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
- spinner.stop('Failed to upload bundle')
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
- spinner.stop('Bundle Uploaded 💪')
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
- spinner.stop('Bundle Uploaded 💪')
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
- p.log.warn('⚠️ This command is deprecated, use "npx @capgo/cli bundle upload" instead ⚠️')
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: npx @capgo/cli@latest app add ${appId}`)
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 "npx @capgo/cli@latest app add ${appId}"`)
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: npx @capgo/cli@latest channel add ${defaultChannel} ${appId} --default`)
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 "npx @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`)
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
- const pm = findPackageManagerType()
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} ${installCmd} @capgo/capacitor-updater@${versionToInstall}`, execOption as ExecSyncOptions)
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 "npm i @capgo/capacitor-updater@latest"`)
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: npx @capgo/cli@latest key create`)
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 doBuild = await p.confirm({ message: `Automatic build ${appId} with "npm run build" ?` })
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: npm run ${buildCommand} && npx cap sync`)
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(`npm run ${buildCommand} && npx cap sync`, execOption as ExecSyncOptions)
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: npm run build && npx cap sync`)
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: npx @capgo/cli@latest bundle upload`)
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: npx @capgo/cli@latest bundle upload`)
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: npx cap run ${platform}`)
273
- await spawnSync('npx', ['cap', 'run', platform], { stdio: 'inherit' })
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: npx cap run <ios|android>`)
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(apikey: string, appId: string, options: SuperOptions) {
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 = apikey || findSavedKey()
308
+ const apikey = apikeyCommand || findSavedKey()
304
309
 
305
310
  const log = p.spinner()
306
- log.start('Running: npx @capgo/cli@latest login ***')
307
- const loginRes = await login(apikey, options, false)
308
- if (!loginRes)
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 \`npx @capgo/cli@latest bundle upload\` to only upload your bundle`)
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('No capacitor config file found, run `cap init` first')
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 npx @capacitor/cli login`)
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
- p.log.error('Missing node_modules folder, please run npm install')
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
- p.log.error(`Missing dependency ${key}, please run npm install`)
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