@capgo/cli 4.8.1 → 4.8.2
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 +2 -0
- package/dist/index.js +91 -101
- package/package.json +1 -1
- package/src/app/add.ts +12 -42
- package/src/app/debug.ts +13 -11
- package/src/init.ts +53 -48
- package/src/utils.ts +44 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
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.2](https://github.com/Cap-go/CLI/compare/v4.8.1...v4.8.2) (2024-05-11)
|
|
6
|
+
|
|
5
7
|
### [4.8.1](https://github.com/Cap-go/CLI/compare/v4.8.0...v4.8.1) (2024-05-11)
|
|
6
8
|
|
|
7
9
|
## [4.8.0](https://github.com/Cap-go/CLI/compare/v4.7.0...v4.8.0) (2024-05-10)
|
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.8.
|
|
92376
|
+
version: "4.8.2",
|
|
92377
92377
|
description: "A CLI to upload to capgo servers",
|
|
92378
92378
|
author: "github.com/riderx",
|
|
92379
92379
|
license: "Apache 2.0",
|
|
@@ -94031,11 +94031,38 @@ async function updateOrCreateChannel(supabase, update) {
|
|
|
94031
94031
|
}
|
|
94032
94032
|
function useLogSnag() {
|
|
94033
94033
|
const logsnag = new import_logsnag.LogSnag({
|
|
94034
|
-
token: "c124f5e9d0ce5bdd14bbb48f815d5583",
|
|
94035
|
-
project: "capgo"
|
|
94034
|
+
token: import_node_process8.default.env.CAPGO_LOGSNAG ?? "c124f5e9d0ce5bdd14bbb48f815d5583",
|
|
94035
|
+
project: import_node_process8.default.env.CAPGO_LOGSNAG_PROJECT ?? "capgo"
|
|
94036
94036
|
});
|
|
94037
94037
|
return logsnag;
|
|
94038
94038
|
}
|
|
94039
|
+
async function getOrganization(supabase, roles) {
|
|
94040
|
+
const { error: orgError, data: allOrganizations } = await supabase.rpc("get_orgs_v5");
|
|
94041
|
+
if (orgError) {
|
|
94042
|
+
f2.error("Cannot get the list of organizations - exiting");
|
|
94043
|
+
f2.error(`Error ${JSON.stringify(orgError)}`);
|
|
94044
|
+
program.error("");
|
|
94045
|
+
}
|
|
94046
|
+
const adminOrgs = allOrganizations.filter((org) => !!roles.find((role) => role === org.role));
|
|
94047
|
+
if (adminOrgs.length === 0) {
|
|
94048
|
+
f2.error(`Could not get organization with roles: ${roles.join(" or ")} because the user does not have any org`);
|
|
94049
|
+
program.error("");
|
|
94050
|
+
}
|
|
94051
|
+
const organizationUidRaw = adminOrgs.length > 1 ? await ie({
|
|
94052
|
+
message: "Please pick the organization that you want to insert to",
|
|
94053
|
+
options: adminOrgs.map((org) => {
|
|
94054
|
+
return { value: org.gid, label: org.name };
|
|
94055
|
+
})
|
|
94056
|
+
}) : adminOrgs[0].gid;
|
|
94057
|
+
if (eD(organizationUidRaw)) {
|
|
94058
|
+
f2.error("Canceled organization selection, exiting");
|
|
94059
|
+
program.error("");
|
|
94060
|
+
}
|
|
94061
|
+
const organizationUid = organizationUidRaw;
|
|
94062
|
+
const organization = allOrganizations.find((org) => org.gid === organizationUid);
|
|
94063
|
+
f2.info(`Using the organization "${organization.name}" as the app owner`);
|
|
94064
|
+
return organization;
|
|
94065
|
+
}
|
|
94039
94066
|
var convertAppName = (appName) => appName.replace(/\./g, "--");
|
|
94040
94067
|
async function verifyUser(supabase, apikey, keymod = ["all"]) {
|
|
94041
94068
|
await checkKey(supabase, apikey, keymod);
|
|
@@ -94401,18 +94428,18 @@ function wait2(ms) {
|
|
|
94401
94428
|
setTimeout(resolve2, ms);
|
|
94402
94429
|
});
|
|
94403
94430
|
}
|
|
94404
|
-
async function markSnag(channel2,
|
|
94431
|
+
async function markSnag(channel2, orgId, snag, event, icon = "\u2705") {
|
|
94405
94432
|
await snag.track({
|
|
94406
94433
|
channel: channel2,
|
|
94407
94434
|
event,
|
|
94408
94435
|
icon,
|
|
94409
|
-
user_id:
|
|
94436
|
+
user_id: orgId,
|
|
94410
94437
|
notify: false
|
|
94411
94438
|
}).catch();
|
|
94412
94439
|
}
|
|
94413
|
-
async function cancelCommand(channel2, command,
|
|
94440
|
+
async function cancelCommand(channel2, command, orgId, snag) {
|
|
94414
94441
|
if (eD(command)) {
|
|
94415
|
-
await markSnag(channel2,
|
|
94442
|
+
await markSnag(channel2, orgId, snag, "canceled", "\u{1F937}");
|
|
94416
94443
|
import_node_process10.default.exit();
|
|
94417
94444
|
}
|
|
94418
94445
|
}
|
|
@@ -94428,13 +94455,13 @@ async function getStats(supabase, query) {
|
|
|
94428
94455
|
}
|
|
94429
94456
|
return null;
|
|
94430
94457
|
}
|
|
94431
|
-
async function waitLog(channel2, supabase, appId, snag,
|
|
94458
|
+
async function waitLog(channel2, supabase, appId, snag, orgId, deviceId) {
|
|
94432
94459
|
let loop = true;
|
|
94433
94460
|
let now = (/* @__PURE__ */ new Date()).toISOString();
|
|
94434
94461
|
const appIdUrl = convertAppName(appId);
|
|
94435
94462
|
const config = await getLocalConfig();
|
|
94436
94463
|
const baseUrl = `${config.hostWeb}/app/p/${appIdUrl}`;
|
|
94437
|
-
await markSnag(channel2,
|
|
94464
|
+
await markSnag(channel2, orgId, snag, "Use waitlog");
|
|
94438
94465
|
const query = {
|
|
94439
94466
|
appId,
|
|
94440
94467
|
devicesId: deviceId ? [deviceId] : void 0,
|
|
@@ -94452,12 +94479,12 @@ async function waitLog(channel2, supabase, appId, snag, userId, deviceId) {
|
|
|
94452
94479
|
f2.info(`Log from Device: ${data.device_id}`);
|
|
94453
94480
|
if (data.action === "get") {
|
|
94454
94481
|
f2.info("Update Sent your your device, wait until event download complete");
|
|
94455
|
-
await markSnag(channel2,
|
|
94482
|
+
await markSnag(channel2, orgId, snag, "done");
|
|
94456
94483
|
} else if (data.action.startsWith("download_")) {
|
|
94457
94484
|
const action = data.action.split("_")[1];
|
|
94458
94485
|
if (action === "complete") {
|
|
94459
94486
|
f2.info("Your bundle has been downloaded on your device, background the app now and open it again to see the update");
|
|
94460
|
-
await markSnag(channel2,
|
|
94487
|
+
await markSnag(channel2, orgId, snag, "downloaded");
|
|
94461
94488
|
} else if (action === "fail") {
|
|
94462
94489
|
f2.error("Your bundle has failed to download on your device.");
|
|
94463
94490
|
f2.error("Please check if you have network connection and try again");
|
|
@@ -94467,7 +94494,7 @@ async function waitLog(channel2, supabase, appId, snag, userId, deviceId) {
|
|
|
94467
94494
|
} else if (data.action === "set") {
|
|
94468
94495
|
f2.info("Your bundle has been set on your device \u2764\uFE0F");
|
|
94469
94496
|
loop = false;
|
|
94470
|
-
await markSnag(channel2,
|
|
94497
|
+
await markSnag(channel2, orgId, snag, "set");
|
|
94471
94498
|
return Promise.resolve(data);
|
|
94472
94499
|
} else if (data.action === "NoChannelOrOverride") {
|
|
94473
94500
|
f2.error(`No default channel or override (channel/device) found, please create it here ${baseUrl}`);
|
|
@@ -94535,12 +94562,13 @@ async function debugApp(appId, options) {
|
|
|
94535
94562
|
const userId = await verifyUser(supabase, options.apikey);
|
|
94536
94563
|
f2.info(`Getting active bundle in Capgo`);
|
|
94537
94564
|
await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, 4 /* admin */);
|
|
94565
|
+
const orgId = await getOrganizationId(supabase, appId);
|
|
94538
94566
|
const doRun = await se({ message: `Automatic check if update working in device ?` });
|
|
94539
94567
|
await cancelCommand("debug", doRun, userId, snag);
|
|
94540
94568
|
if (doRun) {
|
|
94541
94569
|
f2.info(`Wait logs sent to Capgo from ${appId} device, Put the app in background and open it again.`);
|
|
94542
94570
|
f2.info("Waiting...");
|
|
94543
|
-
await waitLog("debug", supabase, appId, snag,
|
|
94571
|
+
await waitLog("debug", supabase, appId, snag, orgId, deviceId);
|
|
94544
94572
|
$e(`Done \u2705`);
|
|
94545
94573
|
} else {
|
|
94546
94574
|
$e(`Canceled \u274C`);
|
|
@@ -95426,13 +95454,15 @@ var src_default = new Mime_default(standard_default, other_default)._freeze();
|
|
|
95426
95454
|
|
|
95427
95455
|
// src/app/add.ts
|
|
95428
95456
|
async function addApp(appId, options, throwErr = true) {
|
|
95457
|
+
await addAppInternal(appId, options, void 0, throwErr);
|
|
95458
|
+
}
|
|
95459
|
+
async function addAppInternal(appId, options, organization, throwErr = true) {
|
|
95429
95460
|
if (throwErr)
|
|
95430
95461
|
oe(`Adding`);
|
|
95431
95462
|
await checkLatest();
|
|
95432
95463
|
options.apikey = options.apikey || findSavedKey();
|
|
95433
95464
|
const config = await getConfig();
|
|
95434
95465
|
appId = appId || config?.app?.appId;
|
|
95435
|
-
const snag = useLogSnag();
|
|
95436
95466
|
if (!options.apikey) {
|
|
95437
95467
|
f2.error(`Missing API key, you need to provide a API key to upload your bundle`);
|
|
95438
95468
|
program.error("");
|
|
@@ -95446,7 +95476,7 @@ async function addApp(appId, options, throwErr = true) {
|
|
|
95446
95476
|
program.error("");
|
|
95447
95477
|
}
|
|
95448
95478
|
const supabase = await createSupabaseClient(options.apikey);
|
|
95449
|
-
|
|
95479
|
+
const userId = await verifyUser(supabase, options.apikey, ["write", "all"]);
|
|
95450
95480
|
const appExist = await checkAppExists(supabase, appId);
|
|
95451
95481
|
if (throwErr && appExist) {
|
|
95452
95482
|
f2.error(`App ${appId} already exist`);
|
|
@@ -95454,27 +95484,9 @@ async function addApp(appId, options, throwErr = true) {
|
|
|
95454
95484
|
} else if (appExist) {
|
|
95455
95485
|
return false;
|
|
95456
95486
|
}
|
|
95457
|
-
|
|
95458
|
-
|
|
95459
|
-
|
|
95460
|
-
f2.error(`Error ${JSON.stringify(orgError)}`);
|
|
95461
|
-
program.error("");
|
|
95462
|
-
}
|
|
95463
|
-
const adminOrgs = allOrganizations.filter((org) => org.role === "admin" || org.role === "super_admin");
|
|
95464
|
-
const organizationUidRaw = adminOrgs.length > 1 ? await ie({
|
|
95465
|
-
message: "Please pick the organization that you want to insert to",
|
|
95466
|
-
options: adminOrgs.map((org) => {
|
|
95467
|
-
return { value: org.gid, label: org.name };
|
|
95468
|
-
})
|
|
95469
|
-
}) : adminOrgs[0].gid;
|
|
95470
|
-
if (eD(organizationUidRaw)) {
|
|
95471
|
-
f2.error("Canceled organization selection, exiting");
|
|
95472
|
-
program.error("");
|
|
95473
|
-
}
|
|
95474
|
-
const organizationUid = organizationUidRaw;
|
|
95475
|
-
const organization = allOrganizations.find((org) => org.gid === organizationUid);
|
|
95476
|
-
userId = organization.created_by;
|
|
95477
|
-
f2.info(`Using the organization "${organization.name}" as the app owner`);
|
|
95487
|
+
if (!organization)
|
|
95488
|
+
organization = await getOrganization(supabase, ["admin", "super_admin"]);
|
|
95489
|
+
const organizationUid = organization.gid;
|
|
95478
95490
|
await checkPlanValid(supabase, organizationUid, options.apikey, void 0, false);
|
|
95479
95491
|
let { name, icon } = options;
|
|
95480
95492
|
appId = appId || config?.app?.appId;
|
|
@@ -95539,16 +95551,6 @@ async function addApp(appId, options, throwErr = true) {
|
|
|
95539
95551
|
f2.error(`Could not add app ${formatError(dbVersionError)}`);
|
|
95540
95552
|
program.error("");
|
|
95541
95553
|
}
|
|
95542
|
-
await snag.track({
|
|
95543
|
-
channel: "app",
|
|
95544
|
-
event: "App Added",
|
|
95545
|
-
icon: "\u{1F389}",
|
|
95546
|
-
user_id: userId,
|
|
95547
|
-
tags: {
|
|
95548
|
-
"app-id": appId
|
|
95549
|
-
},
|
|
95550
|
-
notify: false
|
|
95551
|
-
}).catch();
|
|
95552
95554
|
f2.success(`App ${appId} added to Capgo. ${throwErr ? "You can upload a bundle now" : ""}`);
|
|
95553
95555
|
if (throwErr) {
|
|
95554
95556
|
$e(`Done \u2705`);
|
|
@@ -95566,23 +95568,23 @@ var codeInject = "CapacitorUpdater.notifyAppReady()";
|
|
|
95566
95568
|
var regexImport = /import.*from.*/g;
|
|
95567
95569
|
var defaultChannel = "production";
|
|
95568
95570
|
var execOption = { stdio: "pipe" };
|
|
95569
|
-
async function cancelCommand2(command,
|
|
95571
|
+
async function cancelCommand2(command, orgId, snag) {
|
|
95570
95572
|
if (eD(command)) {
|
|
95571
|
-
await markSnag("onboarding-v2",
|
|
95573
|
+
await markSnag("onboarding-v2", orgId, snag, "canceled", "\u{1F937}");
|
|
95572
95574
|
import_node_process16.default.exit();
|
|
95573
95575
|
}
|
|
95574
95576
|
}
|
|
95575
|
-
async function markStep(
|
|
95576
|
-
return markSnag("onboarding-v2",
|
|
95577
|
+
async function markStep(orgId, snag, step) {
|
|
95578
|
+
return markSnag("onboarding-v2", orgId, snag, `onboarding-step-${step}`);
|
|
95577
95579
|
}
|
|
95578
|
-
async function step2(
|
|
95580
|
+
async function step2(organization, snag, appId, options) {
|
|
95579
95581
|
const pm2 = getPMAndCommand();
|
|
95580
95582
|
const doAdd = await se({ message: `Add ${appId} in Capgo?` });
|
|
95581
|
-
await cancelCommand2(doAdd,
|
|
95583
|
+
await cancelCommand2(doAdd, organization.gid, snag);
|
|
95582
95584
|
if (doAdd) {
|
|
95583
95585
|
const s = de();
|
|
95584
95586
|
s.start(`Running: ${pm2.runner} @capgo/cli@latest app add ${appId}`);
|
|
95585
|
-
const addRes = await
|
|
95587
|
+
const addRes = await addAppInternal(appId, options, organization, false);
|
|
95586
95588
|
if (!addRes)
|
|
95587
95589
|
s.stop(`App already add \u2705`);
|
|
95588
95590
|
else
|
|
@@ -95590,12 +95592,12 @@ async function step2(userId, snag, appId, options) {
|
|
|
95590
95592
|
} else {
|
|
95591
95593
|
f2.info(`Run yourself "${pm2.runner} @capgo/cli@latest app add ${appId}"`);
|
|
95592
95594
|
}
|
|
95593
|
-
await markStep(
|
|
95595
|
+
await markStep(organization.gid, snag, 2);
|
|
95594
95596
|
}
|
|
95595
|
-
async function step3(
|
|
95597
|
+
async function step3(orgId, snag, apikey, appId) {
|
|
95596
95598
|
const pm2 = getPMAndCommand();
|
|
95597
95599
|
const doChannel = await se({ message: `Create default channel ${defaultChannel} for ${appId} in Capgo?` });
|
|
95598
|
-
await cancelCommand2(doChannel,
|
|
95600
|
+
await cancelCommand2(doChannel, orgId, snag);
|
|
95599
95601
|
if (doChannel) {
|
|
95600
95602
|
const s = de();
|
|
95601
95603
|
s.start(`Running: ${pm2.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default`);
|
|
@@ -95610,14 +95612,14 @@ async function step3(userId, snag, apikey, appId) {
|
|
|
95610
95612
|
} else {
|
|
95611
95613
|
f2.info(`Run yourself "${pm2.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`);
|
|
95612
95614
|
}
|
|
95613
|
-
await markStep(
|
|
95615
|
+
await markStep(orgId, snag, 3);
|
|
95614
95616
|
}
|
|
95615
95617
|
var urlMigrateV6 = "https://capacitorjs.com/docs/updating/6-0";
|
|
95616
95618
|
var urlMigrateV5 = "https://capacitorjs.com/docs/updating/5-0";
|
|
95617
|
-
async function step4(
|
|
95619
|
+
async function step4(orgId, snag, apikey, appId) {
|
|
95618
95620
|
const pm2 = getPMAndCommand();
|
|
95619
95621
|
const doInstall = await se({ message: `Automatic Install "@capgo/capacitor-updater" dependency in ${appId}?` });
|
|
95620
|
-
await cancelCommand2(doInstall,
|
|
95622
|
+
await cancelCommand2(doInstall, orgId, snag);
|
|
95621
95623
|
if (doInstall) {
|
|
95622
95624
|
const s = de();
|
|
95623
95625
|
s.start(`Checking if @capgo/capacitor-updater is installed`);
|
|
@@ -95654,11 +95656,11 @@ async function step4(userId, snag, apikey, appId) {
|
|
|
95654
95656
|
} else {
|
|
95655
95657
|
f2.info(`Run yourself "${pm2.installCommand} @capgo/capacitor-updater@latest"`);
|
|
95656
95658
|
}
|
|
95657
|
-
await markStep(
|
|
95659
|
+
await markStep(orgId, snag, 4);
|
|
95658
95660
|
}
|
|
95659
|
-
async function step5(
|
|
95661
|
+
async function step5(orgId, snag, apikey, appId) {
|
|
95660
95662
|
const doAddCode = await se({ message: `Automatic Add "${codeInject}" code and import in ${appId}?` });
|
|
95661
|
-
await cancelCommand2(doAddCode,
|
|
95663
|
+
await cancelCommand2(doAddCode, orgId, snag);
|
|
95662
95664
|
if (doAddCode) {
|
|
95663
95665
|
const s = de();
|
|
95664
95666
|
s.start(`Adding @capacitor-updater to your main file`);
|
|
@@ -95695,7 +95697,7 @@ ${codeInject};
|
|
|
95695
95697
|
(0, import_node_fs11.writeFileSync)(mainFilePath, newMainFileContent);
|
|
95696
95698
|
s.stop(`Code added to ${mainFilePath} \u2705`);
|
|
95697
95699
|
}
|
|
95698
|
-
await markStep(
|
|
95700
|
+
await markStep(orgId, snag, 5);
|
|
95699
95701
|
} else {
|
|
95700
95702
|
f2.info(`Add to your main file the following code:
|
|
95701
95703
|
|
|
@@ -95705,10 +95707,10 @@ ${codeInject};
|
|
|
95705
95707
|
`);
|
|
95706
95708
|
}
|
|
95707
95709
|
}
|
|
95708
|
-
async function step6(
|
|
95710
|
+
async function step6(orgId, snag, apikey, appId) {
|
|
95709
95711
|
const pm2 = getPMAndCommand();
|
|
95710
95712
|
const doEncrypt = await se({ message: `Automatic configure end-to-end encryption in ${appId} updates?` });
|
|
95711
|
-
await cancelCommand2(doEncrypt,
|
|
95713
|
+
await cancelCommand2(doEncrypt, orgId, snag);
|
|
95712
95714
|
if (doEncrypt) {
|
|
95713
95715
|
const s = de();
|
|
95714
95716
|
s.start(`Running: ${pm2.runner} @capgo/cli@latest key create`);
|
|
@@ -95721,14 +95723,14 @@ async function step6(userId, snag, apikey, appId) {
|
|
|
95721
95723
|
} else {
|
|
95722
95724
|
s.stop(`key created \u{1F511}`);
|
|
95723
95725
|
}
|
|
95724
|
-
markSnag("onboarding-v2",
|
|
95726
|
+
markSnag("onboarding-v2", orgId, snag, "Use encryption");
|
|
95725
95727
|
}
|
|
95726
|
-
await markStep(
|
|
95728
|
+
await markStep(orgId, snag, 6);
|
|
95727
95729
|
}
|
|
95728
|
-
async function step7(
|
|
95730
|
+
async function step7(orgId, snag, apikey, appId) {
|
|
95729
95731
|
const pm2 = getPMAndCommand();
|
|
95730
95732
|
const doBuild = await se({ message: `Automatic build ${appId} with "${pm2.pm} run build" ?` });
|
|
95731
|
-
await cancelCommand2(doBuild,
|
|
95733
|
+
await cancelCommand2(doBuild, orgId, snag);
|
|
95732
95734
|
if (doBuild) {
|
|
95733
95735
|
const s = de();
|
|
95734
95736
|
const projectType = await findProjectType();
|
|
@@ -95746,12 +95748,12 @@ async function step7(userId, snag, apikey, appId) {
|
|
|
95746
95748
|
} else {
|
|
95747
95749
|
f2.info(`Build yourself with command: ${pm2.pm} run build && ${pm2.runner} cap sync`);
|
|
95748
95750
|
}
|
|
95749
|
-
await markStep(
|
|
95751
|
+
await markStep(orgId, snag, 7);
|
|
95750
95752
|
}
|
|
95751
|
-
async function step8(
|
|
95753
|
+
async function step8(orgId, snag, apikey, appId) {
|
|
95752
95754
|
const pm2 = getPMAndCommand();
|
|
95753
95755
|
const doBundle = await se({ message: `Automatic upload ${appId} bundle to Capgo?` });
|
|
95754
|
-
await cancelCommand2(doBundle,
|
|
95756
|
+
await cancelCommand2(doBundle, orgId, snag);
|
|
95755
95757
|
if (doBundle) {
|
|
95756
95758
|
const s = de();
|
|
95757
95759
|
s.start(`Running: ${pm2.runner} @capgo/cli@latest bundle upload`);
|
|
@@ -95770,12 +95772,12 @@ async function step8(userId, snag, apikey, appId) {
|
|
|
95770
95772
|
} else {
|
|
95771
95773
|
f2.info(`Upload yourself with command: ${pm2.runner} @capgo/cli@latest bundle upload`);
|
|
95772
95774
|
}
|
|
95773
|
-
await markStep(
|
|
95775
|
+
await markStep(orgId, snag, 8);
|
|
95774
95776
|
}
|
|
95775
|
-
async function step9(
|
|
95777
|
+
async function step9(orgId, snag) {
|
|
95776
95778
|
const pm2 = getPMAndCommand();
|
|
95777
95779
|
const doRun = await se({ message: `Run in device now ?` });
|
|
95778
|
-
await cancelCommand2(doRun,
|
|
95780
|
+
await cancelCommand2(doRun, orgId, snag);
|
|
95779
95781
|
if (doRun) {
|
|
95780
95782
|
const plaformType = await ie({
|
|
95781
95783
|
message: "Pick a platform to run your app",
|
|
@@ -95796,20 +95798,7 @@ async function step9(userId, snag) {
|
|
|
95796
95798
|
} else {
|
|
95797
95799
|
f2.info(`Run yourself with command: ${pm2.runner} cap run <ios|android>`);
|
|
95798
95800
|
}
|
|
95799
|
-
await markStep(
|
|
95800
|
-
}
|
|
95801
|
-
async function step10(userId, snag, supabase, appId) {
|
|
95802
|
-
const doRun = await se({ message: `Automatic check if update working in device ?` });
|
|
95803
|
-
await cancelCommand2(doRun, userId, snag);
|
|
95804
|
-
if (doRun) {
|
|
95805
|
-
f2.info(`Wait logs sent to Capgo from ${appId} device, Put the app in background and open it again.`);
|
|
95806
|
-
f2.info("Waiting...");
|
|
95807
|
-
await waitLog("onboarding-v2", supabase, appId, snag, userId);
|
|
95808
|
-
} else {
|
|
95809
|
-
const appIdUrl = convertAppName(appId);
|
|
95810
|
-
f2.info(`Check logs in https://web.capgo.app/app/p/${appIdUrl}/logs to see if update works.`);
|
|
95811
|
-
}
|
|
95812
|
-
await markStep(userId, snag, 10);
|
|
95801
|
+
await markStep(orgId, snag, 9);
|
|
95813
95802
|
}
|
|
95814
95803
|
async function initApp(apikeyCommand, appId, options) {
|
|
95815
95804
|
const pm2 = getPMAndCommand();
|
|
@@ -95826,18 +95815,19 @@ async function initApp(apikeyCommand, appId, options) {
|
|
|
95826
95815
|
log.stop("Login Done \u2705");
|
|
95827
95816
|
}
|
|
95828
95817
|
const supabase = await createSupabaseClient(apikey);
|
|
95829
|
-
|
|
95830
|
-
await
|
|
95831
|
-
|
|
95832
|
-
await
|
|
95833
|
-
await
|
|
95834
|
-
await
|
|
95835
|
-
await
|
|
95836
|
-
await
|
|
95837
|
-
await
|
|
95838
|
-
await
|
|
95839
|
-
await
|
|
95840
|
-
await
|
|
95818
|
+
await verifyUser(supabase, apikey, ["upload", "all", "read", "write"]);
|
|
95819
|
+
const organization = await getOrganization(supabase, ["admin", "super_admin"]);
|
|
95820
|
+
const orgId = organization.gid;
|
|
95821
|
+
await markStep(orgId, snag, 1);
|
|
95822
|
+
await step2(organization, snag, appId, options);
|
|
95823
|
+
await step3(orgId, snag, apikey, appId);
|
|
95824
|
+
await step4(orgId, snag, apikey, appId);
|
|
95825
|
+
await step5(orgId, snag, apikey, appId);
|
|
95826
|
+
await step6(orgId, snag, apikey, appId);
|
|
95827
|
+
await step7(orgId, snag, apikey, appId);
|
|
95828
|
+
await step8(orgId, snag, apikey, appId);
|
|
95829
|
+
await step9(orgId, snag);
|
|
95830
|
+
await markStep(orgId, snag, 0);
|
|
95841
95831
|
f2.info(`Welcome onboard \u2708\uFE0F!`);
|
|
95842
95832
|
f2.info(`Your Capgo update system is setup`);
|
|
95843
95833
|
f2.info(`Next time use \`${pm2.runner} @capgo/cli@latest bundle upload\` to only upload your bundle`);
|
package/package.json
CHANGED
package/src/app/add.ts
CHANGED
|
@@ -7,17 +7,24 @@ import * as p from '@clack/prompts'
|
|
|
7
7
|
import { checkLatest } from '../api/update'
|
|
8
8
|
import type { Options } from '../api/app'
|
|
9
9
|
import { checkAppExists, newIconPath } from '../api/app'
|
|
10
|
+
import type {
|
|
11
|
+
Organization,
|
|
12
|
+
} from '../utils'
|
|
10
13
|
import {
|
|
11
14
|
checkPlanValid,
|
|
12
15
|
createSupabaseClient,
|
|
13
16
|
findSavedKey,
|
|
14
17
|
formatError,
|
|
15
18
|
getConfig,
|
|
16
|
-
|
|
19
|
+
getOrganization,
|
|
17
20
|
verifyUser,
|
|
18
21
|
} from '../utils'
|
|
19
22
|
|
|
20
23
|
export async function addApp(appId: string, options: Options, throwErr = true) {
|
|
24
|
+
await addAppInternal(appId, options, undefined, throwErr)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function addAppInternal(appId: string, options: Options, organization?: Organization, throwErr = true) {
|
|
21
28
|
if (throwErr)
|
|
22
29
|
p.intro(`Adding`)
|
|
23
30
|
|
|
@@ -25,7 +32,6 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
|
|
|
25
32
|
options.apikey = options.apikey || findSavedKey()
|
|
26
33
|
const config = await getConfig()
|
|
27
34
|
appId = appId || config?.app?.appId
|
|
28
|
-
const snag = useLogSnag()
|
|
29
35
|
|
|
30
36
|
if (!options.apikey) {
|
|
31
37
|
p.log.error(`Missing API key, you need to provide a API key to upload your bundle`)
|
|
@@ -43,7 +49,7 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
|
|
|
43
49
|
|
|
44
50
|
const supabase = await createSupabaseClient(options.apikey)
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
const userId = await verifyUser(supabase, options.apikey, ['write', 'all'])
|
|
47
53
|
|
|
48
54
|
// Check we have app access to this appId
|
|
49
55
|
const appExist = await checkAppExists(supabase, appId)
|
|
@@ -55,36 +61,10 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
|
|
|
55
61
|
return false
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (orgError) {
|
|
62
|
-
p.log.error('Cannot get the list of organizations - exiting')
|
|
63
|
-
p.log.error(`Error ${JSON.stringify(orgError)}`)
|
|
64
|
-
program.error('')
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const adminOrgs = allOrganizations.filter(org => org.role === 'admin' || org.role === 'super_admin')
|
|
68
|
-
|
|
69
|
-
const organizationUidRaw = (adminOrgs.length > 1)
|
|
70
|
-
? await p.select({
|
|
71
|
-
message: 'Please pick the organization that you want to insert to',
|
|
72
|
-
options: adminOrgs.map((org) => {
|
|
73
|
-
return { value: org.gid, label: org.name }
|
|
74
|
-
}),
|
|
75
|
-
})
|
|
76
|
-
: adminOrgs[0].gid
|
|
77
|
-
|
|
78
|
-
if (p.isCancel(organizationUidRaw)) {
|
|
79
|
-
p.log.error('Canceled organization selection, exiting')
|
|
80
|
-
program.error('')
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const organizationUid = organizationUidRaw as string
|
|
84
|
-
const organization = allOrganizations.find(org => org.gid === organizationUid)!
|
|
85
|
-
userId = organization.created_by
|
|
64
|
+
if (!organization)
|
|
65
|
+
organization = await getOrganization(supabase, ['admin', 'super_admin'])
|
|
86
66
|
|
|
87
|
-
|
|
67
|
+
const organizationUid = organization.gid
|
|
88
68
|
|
|
89
69
|
await checkPlanValid(supabase, organizationUid, options.apikey, undefined, false)
|
|
90
70
|
|
|
@@ -168,16 +148,6 @@ export async function addApp(appId: string, options: Options, throwErr = true) {
|
|
|
168
148
|
p.log.error(`Could not add app ${formatError(dbVersionError)}`)
|
|
169
149
|
program.error('')
|
|
170
150
|
}
|
|
171
|
-
await snag.track({
|
|
172
|
-
channel: 'app',
|
|
173
|
-
event: 'App Added',
|
|
174
|
-
icon: '🎉',
|
|
175
|
-
user_id: userId,
|
|
176
|
-
tags: {
|
|
177
|
-
'app-id': appId,
|
|
178
|
-
},
|
|
179
|
-
notify: false,
|
|
180
|
-
}).catch()
|
|
181
151
|
p.log.success(`App ${appId} added to Capgo. ${throwErr ? 'You can upload a bundle now' : ''}`)
|
|
182
152
|
if (throwErr) {
|
|
183
153
|
p.outro(`Done ✅`)
|
package/src/app/debug.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type LogSnag from 'logsnag'
|
|
|
6
6
|
import type { Database } from '../types/supabase.types'
|
|
7
7
|
import { checkAppExistsAndHasPermissionOrgErr } from '../api/app'
|
|
8
8
|
import { checkLatest } from '../api/update'
|
|
9
|
-
import { OrganizationPerm, convertAppName, createSupabaseClient, findSavedKey, formatError, getConfig, getLocalConfig, useLogSnag, verifyUser } from '../utils'
|
|
9
|
+
import { OrganizationPerm, convertAppName, createSupabaseClient, findSavedKey, formatError, getConfig, getLocalConfig, getOrganizationId, useLogSnag, verifyUser } from '../utils'
|
|
10
10
|
|
|
11
11
|
function wait(ms: number) {
|
|
12
12
|
return new Promise((resolve) => {
|
|
@@ -19,19 +19,19 @@ export interface OptionsBaseDebug {
|
|
|
19
19
|
device?: string
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export async function markSnag(channel: string,
|
|
22
|
+
export async function markSnag(channel: string, orgId: string, snag: LogSnag, event: string, icon = '✅') {
|
|
23
23
|
await snag.track({
|
|
24
24
|
channel,
|
|
25
25
|
event,
|
|
26
26
|
icon,
|
|
27
|
-
user_id:
|
|
27
|
+
user_id: orgId,
|
|
28
28
|
notify: false,
|
|
29
29
|
}).catch()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export async function cancelCommand(channel: string, command: boolean | symbol,
|
|
32
|
+
export async function cancelCommand(channel: string, command: boolean | symbol, orgId: string, snag: LogSnag) {
|
|
33
33
|
if (p.isCancel(command)) {
|
|
34
|
-
await markSnag(channel,
|
|
34
|
+
await markSnag(channel, orgId, snag, 'canceled', '🤷')
|
|
35
35
|
process.exit()
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -65,13 +65,13 @@ export async function getStats(supabase: SupabaseClient<Database>, query: QueryS
|
|
|
65
65
|
return null
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
export async function waitLog(channel: string, supabase: SupabaseClient<Database>, appId: string, snag: LogSnag,
|
|
68
|
+
export async function waitLog(channel: string, supabase: SupabaseClient<Database>, appId: string, snag: LogSnag, orgId: string, deviceId?: string) {
|
|
69
69
|
let loop = true
|
|
70
70
|
let now = new Date().toISOString()
|
|
71
71
|
const appIdUrl = convertAppName(appId)
|
|
72
72
|
const config = await getLocalConfig()
|
|
73
73
|
const baseUrl = `${config.hostWeb}/app/p/${appIdUrl}`
|
|
74
|
-
await markSnag(channel,
|
|
74
|
+
await markSnag(channel, orgId, snag, 'Use waitlog')
|
|
75
75
|
const query: QueryStats = {
|
|
76
76
|
appId,
|
|
77
77
|
devicesId: deviceId ? [deviceId] : undefined,
|
|
@@ -90,13 +90,13 @@ export async function waitLog(channel: string, supabase: SupabaseClient<Database
|
|
|
90
90
|
p.log.info(`Log from Device: ${data.device_id}`)
|
|
91
91
|
if (data.action === 'get') {
|
|
92
92
|
p.log.info('Update Sent your your device, wait until event download complete')
|
|
93
|
-
await markSnag(channel,
|
|
93
|
+
await markSnag(channel, orgId, snag, 'done')
|
|
94
94
|
}
|
|
95
95
|
else if (data.action.startsWith('download_')) {
|
|
96
96
|
const action = data.action.split('_')[1]
|
|
97
97
|
if (action === 'complete') {
|
|
98
98
|
p.log.info('Your bundle has been downloaded on your device, background the app now and open it again to see the update')
|
|
99
|
-
await markSnag(channel,
|
|
99
|
+
await markSnag(channel, orgId, snag, 'downloaded')
|
|
100
100
|
}
|
|
101
101
|
else if (action === 'fail') {
|
|
102
102
|
p.log.error('Your bundle has failed to download on your device.')
|
|
@@ -109,7 +109,7 @@ export async function waitLog(channel: string, supabase: SupabaseClient<Database
|
|
|
109
109
|
else if (data.action === 'set') {
|
|
110
110
|
p.log.info('Your bundle has been set on your device ❤️')
|
|
111
111
|
loop = false
|
|
112
|
-
await markSnag(channel,
|
|
112
|
+
await markSnag(channel, orgId, snag, 'set')
|
|
113
113
|
return Promise.resolve(data)
|
|
114
114
|
}
|
|
115
115
|
else if (data.action === 'NoChannelOrOverride') {
|
|
@@ -202,12 +202,14 @@ export async function debugApp(appId: string, options: OptionsBaseDebug) {
|
|
|
202
202
|
// Check we have app access to this appId
|
|
203
203
|
await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.admin)
|
|
204
204
|
|
|
205
|
+
const orgId = await getOrganizationId(supabase, appId)
|
|
206
|
+
|
|
205
207
|
const doRun = await p.confirm({ message: `Automatic check if update working in device ?` })
|
|
206
208
|
await cancelCommand('debug', doRun, userId, snag)
|
|
207
209
|
if (doRun) {
|
|
208
210
|
p.log.info(`Wait logs sent to Capgo from ${appId} device, Put the app in background and open it again.`)
|
|
209
211
|
p.log.info('Waiting...')
|
|
210
|
-
await waitLog('debug', supabase, appId, snag,
|
|
212
|
+
await waitLog('debug', supabase, appId, snag, orgId, deviceId)
|
|
211
213
|
p.outro(`Done ✅`)
|
|
212
214
|
}
|
|
213
215
|
else {
|
package/src/init.ts
CHANGED
|
@@ -12,10 +12,11 @@ import { createKey } from './key'
|
|
|
12
12
|
import { addChannel } from './channel/add'
|
|
13
13
|
import { uploadBundle } from './bundle/upload'
|
|
14
14
|
import { doLoginExists, login } from './login'
|
|
15
|
-
import {
|
|
15
|
+
import { addAppInternal } from './app/add'
|
|
16
16
|
import { checkLatest } from './api/update'
|
|
17
17
|
import type { Options } from './api/app'
|
|
18
|
-
import {
|
|
18
|
+
import type { Organization } from './utils'
|
|
19
|
+
import { convertAppName, createSupabaseClient, findBuildCommandForProjectType, findMainFile, findMainFileForProjectType, findProjectType, findSavedKey, getConfig, getOrganization, getPMAndCommand, useLogSnag, verifyUser } from './utils'
|
|
19
20
|
|
|
20
21
|
interface SuperOptions extends Options {
|
|
21
22
|
local: boolean
|
|
@@ -27,25 +28,25 @@ const regexImport = /import.*from.*/g
|
|
|
27
28
|
const defaultChannel = 'production'
|
|
28
29
|
const execOption = { stdio: 'pipe' }
|
|
29
30
|
|
|
30
|
-
async function cancelCommand(command: boolean | symbol,
|
|
31
|
+
async function cancelCommand(command: boolean | symbol, orgId: string, snag: LogSnag) {
|
|
31
32
|
if (p.isCancel(command)) {
|
|
32
|
-
await markSnag('onboarding-v2',
|
|
33
|
+
await markSnag('onboarding-v2', orgId, snag, 'canceled', '🤷')
|
|
33
34
|
process.exit()
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
async function markStep(
|
|
38
|
-
return markSnag('onboarding-v2',
|
|
38
|
+
async function markStep(orgId: string, snag: LogSnag, step: number | string) {
|
|
39
|
+
return markSnag('onboarding-v2', orgId, snag, `onboarding-step-${step}`)
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
async function step2(
|
|
42
|
+
async function step2(organization: Organization, snag: LogSnag, appId: string, options: SuperOptions) {
|
|
42
43
|
const pm = getPMAndCommand()
|
|
43
44
|
const doAdd = await p.confirm({ message: `Add ${appId} in Capgo?` })
|
|
44
|
-
await cancelCommand(doAdd,
|
|
45
|
+
await cancelCommand(doAdd, organization.gid, snag)
|
|
45
46
|
if (doAdd) {
|
|
46
47
|
const s = p.spinner()
|
|
47
48
|
s.start(`Running: ${pm.runner} @capgo/cli@latest app add ${appId}`)
|
|
48
|
-
const addRes = await
|
|
49
|
+
const addRes = await addAppInternal(appId, options, organization, false)
|
|
49
50
|
if (!addRes)
|
|
50
51
|
s.stop(`App already add ✅`)
|
|
51
52
|
else
|
|
@@ -54,13 +55,13 @@ async function step2(userId: string, snag: LogSnag, appId: string, options: Supe
|
|
|
54
55
|
else {
|
|
55
56
|
p.log.info(`Run yourself "${pm.runner} @capgo/cli@latest app add ${appId}"`)
|
|
56
57
|
}
|
|
57
|
-
await markStep(
|
|
58
|
+
await markStep(organization.gid, snag, 2)
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
async function step3(
|
|
61
|
+
async function step3(orgId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
61
62
|
const pm = getPMAndCommand()
|
|
62
63
|
const doChannel = await p.confirm({ message: `Create default channel ${defaultChannel} for ${appId} in Capgo?` })
|
|
63
|
-
await cancelCommand(doChannel,
|
|
64
|
+
await cancelCommand(doChannel, orgId, snag)
|
|
64
65
|
if (doChannel) {
|
|
65
66
|
const s = p.spinner()
|
|
66
67
|
// create production channel public
|
|
@@ -77,15 +78,15 @@ async function step3(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
77
78
|
else {
|
|
78
79
|
p.log.info(`Run yourself "${pm.runner} @capgo/cli@latest channel add ${defaultChannel} ${appId} --default"`)
|
|
79
80
|
}
|
|
80
|
-
await markStep(
|
|
81
|
+
await markStep(orgId, snag, 3)
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
const urlMigrateV6 = 'https://capacitorjs.com/docs/updating/6-0'
|
|
84
85
|
const urlMigrateV5 = 'https://capacitorjs.com/docs/updating/5-0'
|
|
85
|
-
async function step4(
|
|
86
|
+
async function step4(orgId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
86
87
|
const pm = getPMAndCommand()
|
|
87
88
|
const doInstall = await p.confirm({ message: `Automatic Install "@capgo/capacitor-updater" dependency in ${appId}?` })
|
|
88
|
-
await cancelCommand(doInstall,
|
|
89
|
+
await cancelCommand(doInstall, orgId, snag)
|
|
89
90
|
if (doInstall) {
|
|
90
91
|
const s = p.spinner()
|
|
91
92
|
s.start(`Checking if @capgo/capacitor-updater is installed`)
|
|
@@ -129,12 +130,12 @@ async function step4(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
129
130
|
else {
|
|
130
131
|
p.log.info(`Run yourself "${pm.installCommand} @capgo/capacitor-updater@latest"`)
|
|
131
132
|
}
|
|
132
|
-
await markStep(
|
|
133
|
+
await markStep(orgId, snag, 4)
|
|
133
134
|
}
|
|
134
135
|
|
|
135
|
-
async function step5(
|
|
136
|
+
async function step5(orgId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
136
137
|
const doAddCode = await p.confirm({ message: `Automatic Add "${codeInject}" code and import in ${appId}?` })
|
|
137
|
-
await cancelCommand(doAddCode,
|
|
138
|
+
await cancelCommand(doAddCode, orgId, snag)
|
|
138
139
|
if (doAddCode) {
|
|
139
140
|
const s = p.spinner()
|
|
140
141
|
s.start(`Adding @capacitor-updater to your main file`)
|
|
@@ -172,17 +173,17 @@ async function step5(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
172
173
|
writeFileSync(mainFilePath, newMainFileContent)
|
|
173
174
|
s.stop(`Code added to ${mainFilePath} ✅`)
|
|
174
175
|
}
|
|
175
|
-
await markStep(
|
|
176
|
+
await markStep(orgId, snag, 5)
|
|
176
177
|
}
|
|
177
178
|
else {
|
|
178
179
|
p.log.info(`Add to your main file the following code:\n\n${importInject};\n\n${codeInject};\n`)
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
async function step6(
|
|
183
|
+
async function step6(orgId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
183
184
|
const pm = getPMAndCommand()
|
|
184
185
|
const doEncrypt = await p.confirm({ message: `Automatic configure end-to-end encryption in ${appId} updates?` })
|
|
185
|
-
await cancelCommand(doEncrypt,
|
|
186
|
+
await cancelCommand(doEncrypt, orgId, snag)
|
|
186
187
|
if (doEncrypt) {
|
|
187
188
|
const s = p.spinner()
|
|
188
189
|
s.start(`Running: ${pm.runner} @capgo/cli@latest key create`)
|
|
@@ -196,15 +197,15 @@ async function step6(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
196
197
|
else {
|
|
197
198
|
s.stop(`key created 🔑`)
|
|
198
199
|
}
|
|
199
|
-
markSnag('onboarding-v2',
|
|
200
|
+
markSnag('onboarding-v2', orgId, snag, 'Use encryption')
|
|
200
201
|
}
|
|
201
|
-
await markStep(
|
|
202
|
+
await markStep(orgId, snag, 6)
|
|
202
203
|
}
|
|
203
204
|
|
|
204
|
-
async function step7(
|
|
205
|
+
async function step7(orgId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
205
206
|
const pm = getPMAndCommand()
|
|
206
207
|
const doBuild = await p.confirm({ message: `Automatic build ${appId} with "${pm.pm} run build" ?` })
|
|
207
|
-
await cancelCommand(doBuild,
|
|
208
|
+
await cancelCommand(doBuild, orgId, snag)
|
|
208
209
|
if (doBuild) {
|
|
209
210
|
const s = p.spinner()
|
|
210
211
|
const projectType = await findProjectType()
|
|
@@ -224,13 +225,13 @@ async function step7(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
224
225
|
else {
|
|
225
226
|
p.log.info(`Build yourself with command: ${pm.pm} run build && ${pm.runner} cap sync`)
|
|
226
227
|
}
|
|
227
|
-
await markStep(
|
|
228
|
+
await markStep(orgId, snag, 7)
|
|
228
229
|
}
|
|
229
230
|
|
|
230
|
-
async function step8(
|
|
231
|
+
async function step8(orgId: string, snag: LogSnag, apikey: string, appId: string) {
|
|
231
232
|
const pm = getPMAndCommand()
|
|
232
233
|
const doBundle = await p.confirm({ message: `Automatic upload ${appId} bundle to Capgo?` })
|
|
233
|
-
await cancelCommand(doBundle,
|
|
234
|
+
await cancelCommand(doBundle, orgId, snag)
|
|
234
235
|
if (doBundle) {
|
|
235
236
|
const s = p.spinner()
|
|
236
237
|
s.start(`Running: ${pm.runner} @capgo/cli@latest bundle upload`)
|
|
@@ -251,13 +252,13 @@ async function step8(userId: string, snag: LogSnag, apikey: string, appId: strin
|
|
|
251
252
|
else {
|
|
252
253
|
p.log.info(`Upload yourself with command: ${pm.runner} @capgo/cli@latest bundle upload`)
|
|
253
254
|
}
|
|
254
|
-
await markStep(
|
|
255
|
+
await markStep(orgId, snag, 8)
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
async function step9(
|
|
258
|
+
async function step9(orgId: string, snag: LogSnag) {
|
|
258
259
|
const pm = getPMAndCommand()
|
|
259
260
|
const doRun = await p.confirm({ message: `Run in device now ?` })
|
|
260
|
-
await cancelCommand(doRun,
|
|
261
|
+
await cancelCommand(doRun, orgId, snag)
|
|
261
262
|
if (doRun) {
|
|
262
263
|
const plaformType = await p.select({
|
|
263
264
|
message: 'Pick a platform to run your app',
|
|
@@ -280,22 +281,22 @@ async function step9(userId: string, snag: LogSnag) {
|
|
|
280
281
|
else {
|
|
281
282
|
p.log.info(`Run yourself with command: ${pm.runner} cap run <ios|android>`)
|
|
282
283
|
}
|
|
283
|
-
await markStep(
|
|
284
|
+
await markStep(orgId, snag, 9)
|
|
284
285
|
}
|
|
285
286
|
|
|
286
|
-
async function
|
|
287
|
+
async function _step10(orgId: string, snag: LogSnag, supabase: SupabaseClient<Database>, appId: string) {
|
|
287
288
|
const doRun = await p.confirm({ message: `Automatic check if update working in device ?` })
|
|
288
|
-
await cancelCommand(doRun,
|
|
289
|
+
await cancelCommand(doRun, orgId, snag)
|
|
289
290
|
if (doRun) {
|
|
290
291
|
p.log.info(`Wait logs sent to Capgo from ${appId} device, Put the app in background and open it again.`)
|
|
291
292
|
p.log.info('Waiting...')
|
|
292
|
-
await waitLog('onboarding-v2', supabase, appId, snag,
|
|
293
|
+
await waitLog('onboarding-v2', supabase, appId, snag, orgId)
|
|
293
294
|
}
|
|
294
295
|
else {
|
|
295
296
|
const appIdUrl = convertAppName(appId)
|
|
296
297
|
p.log.info(`Check logs in https://web.capgo.app/app/p/${appIdUrl}/logs to see if update works.`)
|
|
297
298
|
}
|
|
298
|
-
await markStep(
|
|
299
|
+
await markStep(orgId, snag, 10)
|
|
299
300
|
}
|
|
300
301
|
|
|
301
302
|
export async function initApp(apikeyCommand: string, appId: string, options: SuperOptions) {
|
|
@@ -315,20 +316,24 @@ export async function initApp(apikeyCommand: string, appId: string, options: Sup
|
|
|
315
316
|
}
|
|
316
317
|
|
|
317
318
|
const supabase = await createSupabaseClient(apikey)
|
|
318
|
-
|
|
319
|
-
await markStep(userId, snag, 1)
|
|
319
|
+
await verifyUser(supabase, apikey, ['upload', 'all', 'read', 'write'])
|
|
320
320
|
|
|
321
|
-
await
|
|
322
|
-
|
|
323
|
-
await step4(userId, snag, apikey, appId)
|
|
324
|
-
await step5(userId, snag, apikey, appId)
|
|
325
|
-
await step6(userId, snag, apikey, appId)
|
|
326
|
-
await step7(userId, snag, apikey, appId)
|
|
327
|
-
await step8(userId, snag, apikey, appId)
|
|
328
|
-
await step9(userId, snag)
|
|
329
|
-
await step10(userId, snag, supabase, appId)
|
|
321
|
+
const organization = await getOrganization(supabase, ['admin', 'super_admin'])
|
|
322
|
+
const orgId = organization.gid
|
|
330
323
|
|
|
331
|
-
await markStep(
|
|
324
|
+
await markStep(orgId, snag, 1)
|
|
325
|
+
|
|
326
|
+
await step2(organization, snag, appId, options)
|
|
327
|
+
await step3(orgId, snag, apikey, appId)
|
|
328
|
+
await step4(orgId, snag, apikey, appId)
|
|
329
|
+
await step5(orgId, snag, apikey, appId)
|
|
330
|
+
await step6(orgId, snag, apikey, appId)
|
|
331
|
+
await step7(orgId, snag, apikey, appId)
|
|
332
|
+
await step8(orgId, snag, apikey, appId)
|
|
333
|
+
await step9(orgId, snag)
|
|
334
|
+
// await step10(orgId, snag, supabase, appId)
|
|
335
|
+
|
|
336
|
+
await markStep(orgId, snag, 0)
|
|
332
337
|
p.log.info(`Welcome onboard ✈️!`)
|
|
333
338
|
p.log.info(`Your Capgo update system is setup`)
|
|
334
339
|
p.log.info(`Next time use \`${pm.runner} @capgo/cli@latest bundle upload\` to only upload your bundle`)
|
package/src/utils.ts
CHANGED
|
@@ -22,6 +22,10 @@ export const defaultHost = 'https://capgo.app'
|
|
|
22
22
|
export const defaultApiHost = 'https://api.capgo.app'
|
|
23
23
|
export const defaultHostWeb = 'https://web.capgo.app'
|
|
24
24
|
|
|
25
|
+
export type ArrayElement<ArrayType extends readonly unknown[]> =
|
|
26
|
+
ArrayType extends readonly (infer ElementType)[] ? ElementType : never
|
|
27
|
+
export type Organization = ArrayElement<Database['public']['Functions']['get_orgs_v5']['Returns']>
|
|
28
|
+
|
|
25
29
|
export const regexSemver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
|
|
26
30
|
export const formatError = (error: any) => error ? `\n${prettyjson.render(error)}` : ''
|
|
27
31
|
|
|
@@ -653,12 +657,50 @@ export async function updateOrCreateChannel(supabase: SupabaseClient<Database>,
|
|
|
653
657
|
|
|
654
658
|
export function useLogSnag(): LogSnag {
|
|
655
659
|
const logsnag = new LogSnag({
|
|
656
|
-
token: 'c124f5e9d0ce5bdd14bbb48f815d5583',
|
|
657
|
-
project: 'capgo',
|
|
660
|
+
token: process.env.CAPGO_LOGSNAG ?? 'c124f5e9d0ce5bdd14bbb48f815d5583',
|
|
661
|
+
project: process.env.CAPGO_LOGSNAG_PROJECT ?? 'capgo',
|
|
658
662
|
})
|
|
659
663
|
return logsnag
|
|
660
664
|
}
|
|
661
665
|
|
|
666
|
+
export async function getOrganization(supabase: SupabaseClient<Database>, roles: string[]): Promise<Organization> {
|
|
667
|
+
const { error: orgError, data: allOrganizations } = await supabase
|
|
668
|
+
.rpc('get_orgs_v5')
|
|
669
|
+
|
|
670
|
+
if (orgError) {
|
|
671
|
+
p.log.error('Cannot get the list of organizations - exiting')
|
|
672
|
+
p.log.error(`Error ${JSON.stringify(orgError)}`)
|
|
673
|
+
program.error('')
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
const adminOrgs = allOrganizations.filter(org => !!roles.find(role => role === org.role))
|
|
677
|
+
|
|
678
|
+
if (adminOrgs.length === 0) {
|
|
679
|
+
p.log.error(`Could not get organization with roles: ${roles.join(' or ')} because the user does not have any org`)
|
|
680
|
+
program.error('')
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
const organizationUidRaw = (adminOrgs.length > 1)
|
|
684
|
+
? await p.select({
|
|
685
|
+
message: 'Please pick the organization that you want to insert to',
|
|
686
|
+
options: adminOrgs.map((org) => {
|
|
687
|
+
return { value: org.gid, label: org.name }
|
|
688
|
+
}),
|
|
689
|
+
})
|
|
690
|
+
: adminOrgs[0].gid
|
|
691
|
+
|
|
692
|
+
if (p.isCancel(organizationUidRaw)) {
|
|
693
|
+
p.log.error('Canceled organization selection, exiting')
|
|
694
|
+
program.error('')
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const organizationUid = organizationUidRaw as string
|
|
698
|
+
const organization = allOrganizations.find(org => org.gid === organizationUid)!
|
|
699
|
+
|
|
700
|
+
p.log.info(`Using the organization "${organization.name}" as the app owner`)
|
|
701
|
+
return organization
|
|
702
|
+
}
|
|
703
|
+
|
|
662
704
|
export const convertAppName = (appName: string) => appName.replace(/\./g, '--')
|
|
663
705
|
|
|
664
706
|
export async function verifyUser(supabase: SupabaseClient<Database>, apikey: string, keymod: Database['public']['Enums']['key_mode'][] = ['all']) {
|