@capuchoo/cli 0.2.1 → 0.4.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/README.md +233 -26
- package/dist/base-command.d.ts +1 -1
- package/dist/base-command.js +1 -1
- package/dist/cli/prompts.d.ts +43 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +137 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/commands/app/delete.d.ts +20 -0
- package/dist/commands/app/delete.d.ts.map +1 -0
- package/dist/commands/app/delete.js +71 -0
- package/dist/commands/app/delete.js.map +1 -0
- package/dist/commands/app/list.d.ts +9 -0
- package/dist/commands/app/list.d.ts.map +1 -0
- package/dist/commands/app/list.js +40 -0
- package/dist/commands/app/list.js.map +1 -0
- package/dist/commands/auth/login.d.ts.map +1 -1
- package/dist/commands/auth/login.js +10 -13
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/auth/logout.js +2 -2
- package/dist/commands/auth/logout.js.map +1 -1
- package/dist/commands/auth/whoami.d.ts.map +1 -1
- package/dist/commands/auth/whoami.js +14 -2
- package/dist/commands/auth/whoami.js.map +1 -1
- package/dist/commands/channel/create.d.ts +25 -0
- package/dist/commands/channel/create.d.ts.map +1 -0
- package/dist/commands/channel/create.js +96 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/delete.d.ts +19 -0
- package/dist/commands/channel/delete.d.ts.map +1 -0
- package/dist/commands/channel/delete.js +66 -0
- package/dist/commands/channel/delete.js.map +1 -0
- package/dist/commands/channel/list.js +1 -1
- package/dist/commands/channel/list.js.map +1 -1
- package/dist/commands/doctor.d.ts +28 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +278 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +151 -58
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/org/create.d.ts +19 -0
- package/dist/commands/org/create.d.ts.map +1 -0
- package/dist/commands/org/create.js +45 -0
- package/dist/commands/org/create.js.map +1 -0
- package/dist/commands/org/list.d.ts +9 -0
- package/dist/commands/org/list.d.ts.map +1 -0
- package/dist/commands/org/list.js +41 -0
- package/dist/commands/org/list.js.map +1 -0
- package/dist/commands/setup.d.ts +16 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +168 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/deploy/execute.d.ts.map +1 -1
- package/dist/deploy/execute.js +43 -30
- package/dist/deploy/execute.js.map +1 -1
- package/dist/pipeline/build.js +1 -1
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/capacitor-support.d.ts +53 -0
- package/dist/pipeline/capacitor-support.d.ts.map +1 -0
- package/dist/pipeline/capacitor-support.js +95 -0
- package/dist/pipeline/capacitor-support.js.map +1 -0
- package/dist/pipeline/deploy.js +1 -1
- package/dist/pipeline/deploy.js.map +1 -1
- package/dist/pipeline/flavour.js +1 -1
- package/dist/pipeline/flavour.js.map +1 -1
- package/dist/services/cloud.d.ts +22 -2
- package/dist/services/cloud.d.ts.map +1 -1
- package/dist/services/cloud.js +26 -3
- package/dist/services/cloud.js.map +1 -1
- package/dist/utils/config.d.ts +1 -1
- package/dist/utils/config.js +3 -3
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/http.d.ts +2 -0
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/http.js +4 -0
- package/dist/utils/http.js.map +1 -1
- package/oclif.manifest.json +352 -5
- package/package.json +13 -6
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { confirm, isInteractive, log } from "../../cli/prompts.js";
|
|
5
|
+
import { CloudClient } from "../../services/cloud.js";
|
|
6
|
+
import { readProjectConfig, resolveCredentials } from "../../utils/config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Deleting an app takes its channels, bundles and update history with it, and
|
|
9
|
+
* every installed copy stops receiving updates. So the identifier is required
|
|
10
|
+
* as an argument rather than read from project.json - deleting whatever
|
|
11
|
+
* directory you happen to be standing in is too easy a mistake - and the
|
|
12
|
+
* confirmation asks for nothing less than the bundle id.
|
|
13
|
+
*/
|
|
14
|
+
export default class AppDelete extends BaseCommand {
|
|
15
|
+
static description = "Delete an app, its channels and its bundles";
|
|
16
|
+
static examples = ["<%= config.bin %> app delete com.company.app"];
|
|
17
|
+
static args = {
|
|
18
|
+
appId: Args.string({ description: "Bundle identifier of the app to delete" }),
|
|
19
|
+
};
|
|
20
|
+
static flags = {
|
|
21
|
+
yes: Flags.boolean({
|
|
22
|
+
char: "y",
|
|
23
|
+
default: false,
|
|
24
|
+
description: "Skip the confirmation (scripts and CI)",
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
const { args, flags } = await this.parse(AppDelete);
|
|
29
|
+
const credentials = resolveCredentials();
|
|
30
|
+
if (!credentials) {
|
|
31
|
+
this.error(`Not authenticated. Run ${chalk.cyan("capuchoo auth login")}.`);
|
|
32
|
+
}
|
|
33
|
+
const wanted = args.appId?.trim();
|
|
34
|
+
if (!wanted) {
|
|
35
|
+
this.error("Which app? Pass its bundle identifier, e.g. capuchoo app delete com.company.app.");
|
|
36
|
+
}
|
|
37
|
+
const cloud = new CloudClient(credentials.endpoint, credentials.apiKey);
|
|
38
|
+
const apps = await cloud.apps();
|
|
39
|
+
const app = apps.find((candidate) => candidate.app_id === wanted || candidate.id === wanted);
|
|
40
|
+
if (!app) {
|
|
41
|
+
this.error(`No app called "${wanted}" on this account. ` +
|
|
42
|
+
`Available: ${apps.map((candidate) => candidate.app_id).join(", ") || "none"}.`);
|
|
43
|
+
}
|
|
44
|
+
const channels = await cloud.channels(app.id).catch(() => []);
|
|
45
|
+
const serving = channels.filter((channel) => channel.current_version_id);
|
|
46
|
+
log.warn(`${app.name} has ${channels.length} channel(s)` +
|
|
47
|
+
(serving.length > 0 ? `, ${serving.length} of them serving a bundle right now` : "") +
|
|
48
|
+
". Deleting it takes them and the update history with it, and installed " +
|
|
49
|
+
"copies stop receiving updates.");
|
|
50
|
+
if (readProjectConfig(process.cwd())?.cloudAppId === app.id) {
|
|
51
|
+
log.warn("This is the app the current directory is linked to.");
|
|
52
|
+
}
|
|
53
|
+
if (!flags.yes && !isInteractive()) {
|
|
54
|
+
this.error(`Refusing to delete ${app.app_id} unattended. Pass --yes.`);
|
|
55
|
+
}
|
|
56
|
+
const proceed = flags.yes ||
|
|
57
|
+
(await confirm(`Delete ${app.name} (${app.app_id}) for good?`, {
|
|
58
|
+
default: false,
|
|
59
|
+
flag: "--yes",
|
|
60
|
+
}));
|
|
61
|
+
if (!proceed) {
|
|
62
|
+
this.log(chalk.dim(" Nothing was deleted."));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
await cloud.deleteApp(app.id);
|
|
66
|
+
this.log("");
|
|
67
|
+
this.log(` ${chalk.green("Deleted")} ${app.name} ${chalk.dim(app.app_id)}`);
|
|
68
|
+
this.log(chalk.dim(" .capuchoo/project.json still points at it - remove it or re-run init.") + "\n");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/commands/app/delete.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class AppList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
};
|
|
7
|
+
run(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,OAAgB,WAAW,SAA0C;IAErE,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkC3B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { CloudClient } from "../../services/cloud.js";
|
|
5
|
+
import { readProjectConfig, resolveCredentials } from "../../utils/config.js";
|
|
6
|
+
export default class AppList extends BaseCommand {
|
|
7
|
+
static description = "List the apps this account can reach";
|
|
8
|
+
static flags = {
|
|
9
|
+
json: Flags.boolean({ default: false, description: "Machine-readable output" }),
|
|
10
|
+
};
|
|
11
|
+
async run() {
|
|
12
|
+
const { flags } = await this.parse(AppList);
|
|
13
|
+
const credentials = resolveCredentials();
|
|
14
|
+
if (!credentials) {
|
|
15
|
+
this.error(`Not authenticated. Run ${chalk.cyan("capuchoo auth login")}.`);
|
|
16
|
+
}
|
|
17
|
+
const cloud = new CloudClient(credentials.endpoint, credentials.apiKey);
|
|
18
|
+
const apps = await cloud.apps();
|
|
19
|
+
if (flags.json) {
|
|
20
|
+
this.log(JSON.stringify(apps, null, 2));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (apps.length === 0) {
|
|
24
|
+
this.log("");
|
|
25
|
+
this.log(chalk.yellow(" No apps yet."));
|
|
26
|
+
this.log(chalk.dim(" Register one with: capuchoo init --create") + "\n");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Marking the linked one turns this into an answer to "which app am I about
|
|
30
|
+
// to deploy to", which is the reason to run it from a project directory.
|
|
31
|
+
const linked = readProjectConfig(process.cwd())?.cloudAppId;
|
|
32
|
+
this.log("");
|
|
33
|
+
for (const app of apps) {
|
|
34
|
+
const marker = app.id === linked ? chalk.green(" <- this directory") : "";
|
|
35
|
+
this.log(` ${app.name.padEnd(24)} ${chalk.dim(app.app_id)}${marker}`);
|
|
36
|
+
}
|
|
37
|
+
this.log("");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,MAAM,CAAU,WAAW,GAAG,sCAAsC,CAAC;IAErE,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;KAChF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE5C,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEhC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,UAAU,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,SAA+C;IAE1E,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;MAMnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAK1B;;;;;;OAMG;WACU,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiDrF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { askSecret, askText } from "../../cli/prompts.js";
|
|
2
2
|
import { Flags } from "@oclif/core";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import ora from "ora";
|
|
@@ -7,7 +7,7 @@ import { readGlobalConfig, updateGlobalConfig } from "../../utils/config.js";
|
|
|
7
7
|
import { BaseCommand } from "../../base-command.js";
|
|
8
8
|
const DEFAULT_ENDPOINT = "https://capuchoo-back.onrender.com";
|
|
9
9
|
export default class AuthLogin extends BaseCommand {
|
|
10
|
-
static description = "Store an API key for the
|
|
10
|
+
static description = "Store an API key for the Capuchoo backend";
|
|
11
11
|
static examples = [
|
|
12
12
|
"<%= config.bin %> auth login",
|
|
13
13
|
"<%= config.bin %> auth login --endpoint https://capucho.internal --api-key cap_...",
|
|
@@ -33,23 +33,20 @@ export default class AuthLogin extends BaseCommand {
|
|
|
33
33
|
static async performLogin(flagEndpoint, flagApiKey) {
|
|
34
34
|
const existing = readGlobalConfig();
|
|
35
35
|
const endpoint = (flagEndpoint ??
|
|
36
|
-
(await
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
validate: (value) => /^https?:\/\/.+/.test(value.trim())
|
|
36
|
+
(await askText("Backend URL", {
|
|
37
|
+
initial: existing.endpoint ?? DEFAULT_ENDPOINT,
|
|
38
|
+
flag: "--endpoint",
|
|
39
|
+
validate: (value) => /^https?:\/\/.+/.test(value.trim()) ? undefined : "Must start with http:// or https://",
|
|
40
40
|
})))
|
|
41
41
|
.trim()
|
|
42
42
|
.replace(/\/+$/, "");
|
|
43
43
|
let apiKey = flagApiKey;
|
|
44
44
|
if (!apiKey) {
|
|
45
45
|
process.stderr.write(chalk.dim(`\n Create a key under Settings > API Keys at ${endpoint}\n\n`));
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// business enforcing - a rotated prefix would have locked users out.
|
|
51
|
-
validate: (value) => value.trim().length >= 16 || "That key looks too short",
|
|
52
|
-
});
|
|
46
|
+
// Only a length check. The previous version required the key to start with
|
|
47
|
+
// "cap_", which is a server-side format decision the CLI has no business
|
|
48
|
+
// enforcing - a rotated prefix would have locked users out.
|
|
49
|
+
apiKey = await askSecret("API key");
|
|
53
50
|
}
|
|
54
51
|
apiKey = apiKey.trim();
|
|
55
52
|
const spinner = ora({ text: "Verifying", stream: process.stderr }).start();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,8 +14,8 @@ export default class AuthLogout extends BaseCommand {
|
|
|
14
14
|
writeGlobalConfig({ endpoint: config.endpoint });
|
|
15
15
|
this.log(chalk.green("Signed out. The stored API key has been removed."));
|
|
16
16
|
}
|
|
17
|
-
if (process.env.
|
|
18
|
-
this.log(chalk.yellow("!
|
|
17
|
+
if (process.env.CAPUCHOO_API_KEY) {
|
|
18
|
+
this.log(chalk.yellow("! CAPUCHOO_API_KEY is set in this environment and still takes precedence."));
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../src/commands/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,MAAM,CAAU,WAAW,GAAG,2BAA2B,CAAC;IAE1D,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAElC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,wEAAwE;YACxE,+DAA+D;YAC/D,iBAAiB,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../src/commands/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,MAAM,CAAU,WAAW,GAAG,2BAA2B,CAAC;IAE1D,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAElC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,wEAAwE;YACxE,+DAA+D;YAC/D,iBAAiB,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,MAAM,CAAC,2EAA2E,CAAC,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/whoami.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,WAAW,SACiD;IAE5E,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/whoami.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,WAAW,SACiD;IAE5E,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuG3B"}
|
|
@@ -44,6 +44,7 @@ export default class AuthWhoami extends BaseCommand {
|
|
|
44
44
|
user: profile.user,
|
|
45
45
|
organizations: profile.organizations,
|
|
46
46
|
apps: profile.apps,
|
|
47
|
+
credential: profile.credential ?? null,
|
|
47
48
|
}, null, 2));
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
@@ -51,7 +52,7 @@ export default class AuthWhoami extends BaseCommand {
|
|
|
51
52
|
this.log(` ${chalk.bold("account")} ${chalk.green(profile.user.email)}`);
|
|
52
53
|
this.log(` ${chalk.bold("endpoint")} ${credentials.endpoint}`);
|
|
53
54
|
this.log(` ${chalk.bold("source")} ${credentials.source === "environment"
|
|
54
|
-
? "
|
|
55
|
+
? "CAPUCHOO_ENDPOINT / CAPUCHOO_API_KEY"
|
|
55
56
|
: "~/.capuchoo/config.json"}`);
|
|
56
57
|
if (profile.organizations.length > 0) {
|
|
57
58
|
this.log("");
|
|
@@ -63,8 +64,19 @@ export default class AuthWhoami extends BaseCommand {
|
|
|
63
64
|
if (profile.apps.length > 0) {
|
|
64
65
|
this.log("");
|
|
65
66
|
this.log(chalk.bold(" apps"));
|
|
67
|
+
// These are the apps the *account* owns. An app-scoped key can publish to
|
|
68
|
+
// exactly one of them, so listing all of them unqualified is how "capuchoo
|
|
69
|
+
// app list shows one app but whoami shows three" happens.
|
|
70
|
+
const scope = profile.credential?.app_id;
|
|
66
71
|
for (const app of profile.apps) {
|
|
67
|
-
|
|
72
|
+
const note = scope && app.id !== scope ? chalk.dim(" - this key cannot publish to it") : "";
|
|
73
|
+
this.log(` ${app.name} ${chalk.dim(app.app_id)}${note}`);
|
|
74
|
+
}
|
|
75
|
+
if (scope) {
|
|
76
|
+
const scoped = profile.apps.find((app) => app.id === scope);
|
|
77
|
+
this.log("");
|
|
78
|
+
this.log(chalk.dim(` This key is restricted to ${scoped ? scoped.app_id : scope}. ` +
|
|
79
|
+
"Use an unscoped key to work across apps."));
|
|
68
80
|
}
|
|
69
81
|
}
|
|
70
82
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../../src/commands/auth/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,MAAM,CAAU,WAAW,GACzB,yEAAyE,CAAC;IAE5E,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;KAChF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;QAEzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5D,OAAO;YACT,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;YACxD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,yEAAyE;QACzE,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;QAErC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,IAAI,CAAC,KAAK,CACR,8BAA8B,WAAW,CAAC,QAAQ,wBAAwB;gBACxE,OAAO,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAC9C,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,SAAS,CACZ;gBACE,aAAa,EAAE,IAAI;gBACnB,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,gBAAgB,EAAE,WAAW,CAAC,MAAM;gBACpC,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,IAAI,EAAE,OAAO,CAAC,IAAI;
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../../src/commands/auth/whoami.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creating a channel used to be dashboard-only, which broke the CLI story: a
|
|
4
|
+
* deploy needs a channel, so setting an app up meant CLI, then browser, then
|
|
5
|
+
* CLI again. Nothing about it needed a UI.
|
|
6
|
+
*
|
|
7
|
+
* The environment is asked for rather than derived. A channel named `prod` on
|
|
8
|
+
* the staging environment serves staging bundles to production devices and
|
|
9
|
+
* nothing errors - which is how all three of Lowmaro's channels ended up on
|
|
10
|
+
* staging - so the name never silently decides it.
|
|
11
|
+
*/
|
|
12
|
+
export default class ChannelCreate extends BaseCommand {
|
|
13
|
+
static description: string;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
static args: {
|
|
16
|
+
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
17
|
+
};
|
|
18
|
+
static flags: {
|
|
19
|
+
environment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
};
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/create.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,WAAW,SAAmC;IAE9D,OAAgB,QAAQ,WAItB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;;;MAYnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuE3B"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ENVIRONMENTS, environmentMismatchWarning, suggestEnvironment } from "@capuchoo/core";
|
|
2
|
+
import { Args, Flags } from "@oclif/core";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { BaseCommand } from "../../base-command.js";
|
|
5
|
+
import { confirm, isInteractive, log, selectOne } from "../../cli/prompts.js";
|
|
6
|
+
import { CloudClient } from "../../services/cloud.js";
|
|
7
|
+
import { requireProjectConfig, resolveCredentials } from "../../utils/config.js";
|
|
8
|
+
/**
|
|
9
|
+
* Creating a channel used to be dashboard-only, which broke the CLI story: a
|
|
10
|
+
* deploy needs a channel, so setting an app up meant CLI, then browser, then
|
|
11
|
+
* CLI again. Nothing about it needed a UI.
|
|
12
|
+
*
|
|
13
|
+
* The environment is asked for rather than derived. A channel named `prod` on
|
|
14
|
+
* the staging environment serves staging bundles to production devices and
|
|
15
|
+
* nothing errors - which is how all three of Lowmaro's channels ended up on
|
|
16
|
+
* staging - so the name never silently decides it.
|
|
17
|
+
*/
|
|
18
|
+
export default class ChannelCreate extends BaseCommand {
|
|
19
|
+
static description = "Create a channel for this app";
|
|
20
|
+
static examples = [
|
|
21
|
+
"<%= config.bin %> channel create staging",
|
|
22
|
+
"<%= config.bin %> channel create beta --environment staging",
|
|
23
|
+
"<%= config.bin %> channel create prod --environment prod --yes",
|
|
24
|
+
];
|
|
25
|
+
static args = {
|
|
26
|
+
name: Args.string({ description: "Name of the channel, e.g. staging" }),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
environment: Flags.string({
|
|
30
|
+
char: "e",
|
|
31
|
+
options: [...ENVIRONMENTS],
|
|
32
|
+
description: "Which build flavour this channel serves",
|
|
33
|
+
}),
|
|
34
|
+
yes: Flags.boolean({
|
|
35
|
+
char: "y",
|
|
36
|
+
default: false,
|
|
37
|
+
description: "Accept the environment even when it disagrees with the name",
|
|
38
|
+
}),
|
|
39
|
+
json: Flags.boolean({ default: false, description: "Machine-readable output" }),
|
|
40
|
+
};
|
|
41
|
+
async run() {
|
|
42
|
+
const { args, flags } = await this.parse(ChannelCreate);
|
|
43
|
+
const project = requireProjectConfig(process.cwd());
|
|
44
|
+
const credentials = resolveCredentials();
|
|
45
|
+
if (!credentials) {
|
|
46
|
+
this.error(`Not authenticated. Run ${chalk.cyan("capuchoo auth login")}.`);
|
|
47
|
+
}
|
|
48
|
+
const cloud = new CloudClient(credentials.endpoint, credentials.apiKey);
|
|
49
|
+
const name = args.name?.trim();
|
|
50
|
+
if (!name) {
|
|
51
|
+
this.error("Which channel? Pass a name, e.g. capuchoo channel create staging.");
|
|
52
|
+
}
|
|
53
|
+
// A duplicate name is a 409 from the server; catching it here names the
|
|
54
|
+
// existing channel's environment, which is usually what the user wanted.
|
|
55
|
+
const existing = await cloud.channels(project.cloudAppId).catch(() => []);
|
|
56
|
+
const clash = existing.find((channel) => channel.name === name);
|
|
57
|
+
if (clash) {
|
|
58
|
+
this.error(`${project.appName} already has a channel called "${name}" ` +
|
|
59
|
+
`on the ${clash.environment} environment.`);
|
|
60
|
+
}
|
|
61
|
+
const suggested = suggestEnvironment(name);
|
|
62
|
+
const environment = flags.environment ??
|
|
63
|
+
(suggested && !isInteractive()
|
|
64
|
+
? suggested
|
|
65
|
+
: await selectOne(`Which flavour should "${name}" serve?`, ENVIRONMENTS.map((value) => ({
|
|
66
|
+
value,
|
|
67
|
+
label: value,
|
|
68
|
+
...(value === suggested ? { hint: "matches the name" } : {}),
|
|
69
|
+
})), "--environment"));
|
|
70
|
+
// Deliberate mismatches are legitimate - a prod app pointed at a staging
|
|
71
|
+
// channel for beta testing - so this confirms rather than refuses.
|
|
72
|
+
const warning = environmentMismatchWarning(name, environment);
|
|
73
|
+
if (warning) {
|
|
74
|
+
log.warn(warning);
|
|
75
|
+
const proceed = await confirm("Create it anyway?", {
|
|
76
|
+
...(flags.yes ? { default: true } : {}),
|
|
77
|
+
flag: "--yes",
|
|
78
|
+
});
|
|
79
|
+
if (!proceed)
|
|
80
|
+
this.error("Cancelled. Nothing was created.");
|
|
81
|
+
}
|
|
82
|
+
const channel = await cloud.createChannel({
|
|
83
|
+
app_id: project.cloudAppId,
|
|
84
|
+
name,
|
|
85
|
+
environment: environment,
|
|
86
|
+
});
|
|
87
|
+
if (flags.json) {
|
|
88
|
+
this.log(JSON.stringify(channel, null, 2));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.log("");
|
|
92
|
+
this.log(` ${chalk.green("Created")} ${channel.name} ${chalk.dim(`(${environment})`)}`);
|
|
93
|
+
this.log(chalk.dim(` Deploy to it with: capuchoo deploy ota --channel ${channel.name}`) + "\n");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/channel/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
/**
|
|
3
|
+
* Deleting a channel is not recoverable and devices are pointed at it by name,
|
|
4
|
+
* so this confirms by default and says what is currently on it first. A channel
|
|
5
|
+
* serving a bundle is the dangerous case: devices asking for it stop getting
|
|
6
|
+
* updates the moment it disappears.
|
|
7
|
+
*/
|
|
8
|
+
export default class ChannelDelete extends BaseCommand {
|
|
9
|
+
static description: string;
|
|
10
|
+
static examples: string[];
|
|
11
|
+
static args: {
|
|
12
|
+
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
13
|
+
};
|
|
14
|
+
static flags: {
|
|
15
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/delete.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,WAAW,SAAuC;IAElE,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqD3B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { confirm, isInteractive, log } from "../../cli/prompts.js";
|
|
5
|
+
import { CloudClient } from "../../services/cloud.js";
|
|
6
|
+
import { requireProjectConfig, resolveCredentials } from "../../utils/config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Deleting a channel is not recoverable and devices are pointed at it by name,
|
|
9
|
+
* so this confirms by default and says what is currently on it first. A channel
|
|
10
|
+
* serving a bundle is the dangerous case: devices asking for it stop getting
|
|
11
|
+
* updates the moment it disappears.
|
|
12
|
+
*/
|
|
13
|
+
export default class ChannelDelete extends BaseCommand {
|
|
14
|
+
static description = "Delete one of this app's channels";
|
|
15
|
+
static examples = [
|
|
16
|
+
"<%= config.bin %> channel delete beta",
|
|
17
|
+
"<%= config.bin %> channel delete beta --yes",
|
|
18
|
+
];
|
|
19
|
+
static args = {
|
|
20
|
+
name: Args.string({ description: "Name of the channel to delete" }),
|
|
21
|
+
};
|
|
22
|
+
static flags = {
|
|
23
|
+
yes: Flags.boolean({ char: "y", default: false, description: "Skip the confirmation" }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { args, flags } = await this.parse(ChannelDelete);
|
|
27
|
+
const project = requireProjectConfig(process.cwd());
|
|
28
|
+
const credentials = resolveCredentials();
|
|
29
|
+
if (!credentials) {
|
|
30
|
+
this.error(`Not authenticated. Run ${chalk.cyan("capuchoo auth login")}.`);
|
|
31
|
+
}
|
|
32
|
+
const name = args.name?.trim();
|
|
33
|
+
if (!name) {
|
|
34
|
+
this.error("Which channel? Pass a name, e.g. capuchoo channel delete beta.");
|
|
35
|
+
}
|
|
36
|
+
const cloud = new CloudClient(credentials.endpoint, credentials.apiKey);
|
|
37
|
+
const channels = await cloud.channels(project.cloudAppId);
|
|
38
|
+
const channel = channels.find((candidate) => candidate.name === name);
|
|
39
|
+
if (!channel) {
|
|
40
|
+
const available = channels.map((c) => c.name).join(", ") || "none";
|
|
41
|
+
this.error(`${project.appName} has no channel called "${name}". Available: ${available}.`);
|
|
42
|
+
}
|
|
43
|
+
if (channel.current_version_id) {
|
|
44
|
+
log.warn(`"${channel.name}" is serving a bundle right now. Devices on it will stop ` +
|
|
45
|
+
"receiving updates.");
|
|
46
|
+
}
|
|
47
|
+
// Exiting 0 without deleting anything reads as success in a script, so a
|
|
48
|
+
// non-interactive run without --yes is an error rather than a quiet no-op.
|
|
49
|
+
if (!flags.yes && !isInteractive()) {
|
|
50
|
+
this.error(`Refusing to delete "${channel.name}" unattended. Pass --yes.`);
|
|
51
|
+
}
|
|
52
|
+
const proceed = flags.yes ||
|
|
53
|
+
(await confirm(`Delete "${channel.name}" (${channel.environment}) from ${project.appName}?`, {
|
|
54
|
+
default: false,
|
|
55
|
+
flag: "--yes",
|
|
56
|
+
}));
|
|
57
|
+
if (!proceed) {
|
|
58
|
+
this.log(chalk.dim(" Nothing was deleted."));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
await cloud.deleteChannel(channel.id, project.cloudAppId);
|
|
62
|
+
this.log("");
|
|
63
|
+
this.log(` ${chalk.green("Deleted")} ${channel.name}\n`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/commands/channel/delete.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ export default class ChannelList extends BaseCommand {
|
|
|
24
24
|
if (channels.length === 0) {
|
|
25
25
|
this.log("");
|
|
26
26
|
this.log(chalk.yellow(` ${project.appName} has no channels yet.`));
|
|
27
|
-
this.log(chalk.dim(" Create one
|
|
27
|
+
this.log(chalk.dim(" Create one with: capuchoo channel create staging"));
|
|
28
28
|
this.log("");
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/channel/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,MAAM,CAAU,WAAW,GAAG,8CAA8C,CAAC;IAE7E,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;KAChF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAEpD,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE1D,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/channel/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,MAAM,CAAU,WAAW,GAAG,8CAA8C,CAAC;IAE7E,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;KAChF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAEpD,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE1D,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;YAC1E,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEb,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,mEAAmE;YACnE,0EAA0E;YAC1E,gCAAgC;YAChC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW;gBACrC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC;gBACvC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;YAEnD,IAAI,CAAC,GAAG,CACN,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,WAAW,GAAG;gBAC5C,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CACnD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
/**
|
|
3
|
+
* Explains why a deploy will not work, before you run one.
|
|
4
|
+
*
|
|
5
|
+
* Every check here corresponds to something that has silently failed in this
|
|
6
|
+
* project: an endpoint pointing at a retired backend, a channel whose
|
|
7
|
+
* environment disagreed with its name, a channel serving nothing because the
|
|
8
|
+
* upload never moved its pointer, an app whose flavour env file did not exist.
|
|
9
|
+
* Each finding names the fix, because a diagnosis you cannot act on is just bad
|
|
10
|
+
* news.
|
|
11
|
+
*/
|
|
12
|
+
export default class Doctor extends BaseCommand {
|
|
13
|
+
static description: string;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Looks for the two calls that decide whether updates work at all.
|
|
18
|
+
*
|
|
19
|
+
* Textual, not semantic: this is a hint, not a compiler. Worth doing anyway -
|
|
20
|
+
* a missing `notifyAppReady()` rolls back working bundles ten seconds after
|
|
21
|
+
* they install, and that is invisible until it happens on a device.
|
|
22
|
+
*/
|
|
23
|
+
private checkRuntimeWiring;
|
|
24
|
+
/** Shallow-ish walk: enough to find an import, cheap enough to run always. */
|
|
25
|
+
private sourceFiles;
|
|
26
|
+
private report;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAcjD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAAsE;IAEjG,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA4L1B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IA6D1B,8EAA8E;IAC9E,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,MAAM;CA0Bf"}
|