percher 0.2.11 → 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/dist/bin/percher.js +7532 -3049
- package/dist/package.json +45 -0
- package/dist/src/ci-env.d.ts +6 -0
- package/dist/src/ci-env.d.ts.map +1 -0
- package/dist/src/ci-env.js +35 -0
- package/dist/src/ci-env.js.map +1 -0
- package/dist/src/cli-utils.d.ts +44 -0
- package/dist/src/cli-utils.d.ts.map +1 -0
- package/dist/src/cli-utils.js +129 -0
- package/dist/src/cli-utils.js.map +1 -0
- package/dist/src/commands/account.d.ts +4 -0
- package/dist/src/commands/account.d.ts.map +1 -0
- package/dist/src/commands/account.js +280 -0
- package/dist/src/commands/account.js.map +1 -0
- package/dist/src/commands/apps.d.ts +13 -0
- package/dist/src/commands/apps.d.ts.map +1 -0
- package/dist/src/commands/apps.js +483 -0
- package/dist/src/commands/apps.js.map +1 -0
- package/dist/src/commands/auth.d.ts +4 -0
- package/dist/src/commands/auth.d.ts.map +1 -0
- package/dist/src/commands/auth.js +21 -0
- package/dist/src/commands/auth.js.map +1 -0
- package/dist/src/commands/data.d.ts +4 -0
- package/dist/src/commands/data.d.ts.map +1 -0
- package/dist/src/commands/data.js +148 -0
- package/dist/src/commands/data.js.map +1 -0
- package/dist/src/commands/deploys.d.ts +4 -0
- package/dist/src/commands/deploys.d.ts.map +1 -0
- package/dist/src/commands/deploys.js +197 -0
- package/dist/src/commands/deploys.js.map +1 -0
- package/dist/src/commands/env.d.ts +4 -0
- package/dist/src/commands/env.d.ts.map +1 -0
- package/dist/src/commands/env.js +66 -0
- package/dist/src/commands/env.js.map +1 -0
- package/dist/src/commands/github.d.ts +4 -0
- package/dist/src/commands/github.d.ts.map +1 -0
- package/dist/src/commands/github.js +93 -0
- package/dist/src/commands/github.js.map +1 -0
- package/dist/src/commands/status.d.ts +4 -0
- package/dist/src/commands/status.d.ts.map +1 -0
- package/dist/src/commands/status.js +53 -0
- package/dist/src/commands/status.js.map +1 -0
- package/dist/src/env-set-input.d.ts +13 -0
- package/dist/src/env-set-input.d.ts.map +1 -0
- package/dist/src/env-set-input.js +59 -0
- package/dist/src/env-set-input.js.map +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +19 -790
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompt-hidden.d.ts +15 -0
- package/dist/src/prompt-hidden.d.ts.map +1 -0
- package/dist/src/prompt-hidden.js +104 -0
- package/dist/src/prompt-hidden.js.map +1 -0
- package/dist/src/telemetry.d.ts +1 -1
- package/dist/src/telemetry.d.ts.map +1 -1
- package/dist/src/telemetry.js +8 -1
- package/dist/src/telemetry.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as core from "@percher/core";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { firstNonFlagAfter, printSuperuserResetResult, writeLine } from "../cli-utils";
|
|
4
|
+
export function registerDataCommands(cli, ctx, argv) {
|
|
5
|
+
cli
|
|
6
|
+
// The trailing `[...rest]` is a variadic absorber that exists only
|
|
7
|
+
// to make cac v7's checkUnusedArgs happy. cac matches commands by
|
|
8
|
+
// first-token equality (see Command.isMatched in cac's source), so
|
|
9
|
+
// both `data` and `data reset-superuser foo` route here. Without
|
|
10
|
+
// [...rest], v7 throws "Unused args" on the extra positionals; v6
|
|
11
|
+
// silently dropped them, which is why the in-action manual dispatch
|
|
12
|
+
// below worked there. The dispatch logic is unchanged across the
|
|
13
|
+
// bump — we only needed [...rest] to silence v7's safety check.
|
|
14
|
+
.command("data [app] [...rest]", "Show app data status and collections")
|
|
15
|
+
.option("--json", "Output as JSON")
|
|
16
|
+
.option("--reveal", "(reset-superuser only) also print the plaintext password once")
|
|
17
|
+
.option("--out <path>", "(export only) Output file (default: ./<app>-pb-<timestamp>.tar.gz)")
|
|
18
|
+
.action(async (app, _rest, options) => {
|
|
19
|
+
// cac matches commands by single first-token equality, so
|
|
20
|
+
// `percher data reset-superuser <app>` would otherwise hit this
|
|
21
|
+
// handler with app="reset-superuser" and silently drop the real
|
|
22
|
+
// app name. Detect the documented subcommand here and dispatch
|
|
23
|
+
// to the reset-superuser handler instead. The separate
|
|
24
|
+
// `data reset-superuser [app]` registration below still exists
|
|
25
|
+
// so `--help` lists the subcommand, but its action body is
|
|
26
|
+
// unreachable in practice via that route.
|
|
27
|
+
if (app === "reset-superuser") {
|
|
28
|
+
// Skip flag tokens when looking for the app name so both orderings
|
|
29
|
+
// work: `... reset-superuser my-app --reveal` AND `... reset-superuser
|
|
30
|
+
// --reveal my-app`. cac would handle this if it parsed multi-token
|
|
31
|
+
// commands natively; since we route manually, we mirror cac's
|
|
32
|
+
// "first non-flag positional" rule here.
|
|
33
|
+
const idx = argv.indexOf("reset-superuser");
|
|
34
|
+
const realApp = idx >= 0 ? firstNonFlagAfter(argv, idx) : undefined;
|
|
35
|
+
const reveal = argv.includes("--reveal");
|
|
36
|
+
const r = await core.resetSuperuser(ctx, { app: realApp, reveal });
|
|
37
|
+
await printSuperuserResetResult(ctx, r);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (app === "export") {
|
|
41
|
+
const idx = argv.indexOf("export");
|
|
42
|
+
const realApp = idx >= 0 ? firstNonFlagAfter(argv, idx) : undefined;
|
|
43
|
+
const outIdx = argv.indexOf("--out");
|
|
44
|
+
const out = outIdx >= 0 ? argv[outIdx + 1] : undefined;
|
|
45
|
+
const result = await core.dataExport(ctx, { app: realApp, out });
|
|
46
|
+
const mb = (result.bytes / 1024 / 1024).toFixed(1);
|
|
47
|
+
await writeLine(ctx, `${pc.green("✓")} Exported ${result.app}`);
|
|
48
|
+
await writeLine(ctx, ` Path: ${result.path}`);
|
|
49
|
+
await writeLine(ctx, ` Size: ${mb} MB`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const result = await core.data(ctx, { app, json: options.json });
|
|
53
|
+
if (options.json) {
|
|
54
|
+
await writeLine(ctx, JSON.stringify(result, null, 2));
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const version = result.version ? ` Version: ${result.version}` : "";
|
|
58
|
+
await writeLine(ctx, `${pc.bold("Data")} Mode: ${result.mode} Status: ${result.status}${version}`);
|
|
59
|
+
await writeLine(ctx, "");
|
|
60
|
+
if (result.collections.length > 0) {
|
|
61
|
+
await writeLine(ctx, pc.bold("Collections"));
|
|
62
|
+
for (const col of result.collections) {
|
|
63
|
+
await writeLine(ctx, ` ${col.name.padEnd(20)} ${pc.dim(col.type)}`);
|
|
64
|
+
}
|
|
65
|
+
await writeLine(ctx, "");
|
|
66
|
+
}
|
|
67
|
+
await writeLine(ctx, `Collections: ${result.stats.collections} Records: ${result.stats.totalRecords}`);
|
|
68
|
+
if (result.adminUrl) {
|
|
69
|
+
await writeLine(ctx, "");
|
|
70
|
+
await writeLine(ctx, `Admin: ${result.adminUrl}`);
|
|
71
|
+
}
|
|
72
|
+
if (result.warning) {
|
|
73
|
+
await writeLine(ctx, "");
|
|
74
|
+
await writeLine(ctx, pc.yellow(`⚠ ${result.warning}`));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
cli
|
|
79
|
+
.command("data reset-superuser [app]", "Reset PocketBase superuser and inject new credentials")
|
|
80
|
+
.option("--reveal", "Also print the plaintext password once (default: hidden)")
|
|
81
|
+
.action(async (app, options) => {
|
|
82
|
+
// Unreachable in practice — handled by the "data [app] [...rest]" action
|
|
83
|
+
// above via the `app === "reset-superuser"` branch (cac only matches the
|
|
84
|
+
// first token). Registered here so `--help` lists the subcommand.
|
|
85
|
+
const result = await core.resetSuperuser(ctx, { app, reveal: options.reveal });
|
|
86
|
+
await printSuperuserResetResult(ctx, result);
|
|
87
|
+
});
|
|
88
|
+
cli
|
|
89
|
+
.command("data export [app]", "Download a snapshot of your app's PocketBase data as a .tar.gz")
|
|
90
|
+
// --out is registered on the parent `data [app] [...rest]` so cac
|
|
91
|
+
// doesn't reject it as unknown when the user runs `data export ... --out`.
|
|
92
|
+
// Don't duplicate it here; this command is unreachable anyway and the
|
|
93
|
+
// duplication just risks drift if the description ever changes.
|
|
94
|
+
.action(async () => {
|
|
95
|
+
// Unreachable in practice — handled by the "data [app] [...rest]" action
|
|
96
|
+
// above via the `app === "export"` branch. Registered here so --help
|
|
97
|
+
// lists the subcommand.
|
|
98
|
+
});
|
|
99
|
+
cli
|
|
100
|
+
.command("backups [app]", "List available backups for an app")
|
|
101
|
+
.action(async (app) => {
|
|
102
|
+
const { backups, skipped } = await core.listBackups(ctx, { app });
|
|
103
|
+
if (backups.length === 0) {
|
|
104
|
+
await writeLine(ctx, `${pc.dim("No backups found.")}`);
|
|
105
|
+
if (skipped.length > 0) {
|
|
106
|
+
await writeLine(ctx, pc.yellow(`(${skipped.length} sidecar(s) skipped — see ops logs)`));
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
for (const b of backups) {
|
|
111
|
+
const components = b.apps[0]?.components.join(", ") ?? "—";
|
|
112
|
+
const size = b.tarball_size_bytes < 1024 * 1024
|
|
113
|
+
? `${Math.round(b.tarball_size_bytes / 1024)} KB`
|
|
114
|
+
: `${(b.tarball_size_bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
115
|
+
await writeLine(ctx, `${pc.green("●")} ${pc.bold(b.backup_id)} ${pc.dim(size.padStart(10))} ${pc.dim(`[${components}]`)}`);
|
|
116
|
+
}
|
|
117
|
+
if (skipped.length > 0) {
|
|
118
|
+
await writeLine(ctx, pc.yellow(`\n${skipped.length} sidecar(s) skipped — older backups predating the manifest schema.`));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
cli
|
|
122
|
+
.command("restore <source> [app]", "Restore an app's data from a backup")
|
|
123
|
+
.option("--components <list>", "Comma-separated: appdata,pocketbase (default: both)")
|
|
124
|
+
.option("--dry-run", "Show what would be restored without doing it")
|
|
125
|
+
.action(async (source, app, options) => {
|
|
126
|
+
const components = options.components
|
|
127
|
+
? options.components
|
|
128
|
+
.split(",")
|
|
129
|
+
.map((c) => c.trim())
|
|
130
|
+
.filter((c) => c === "appdata" || c === "pocketbase")
|
|
131
|
+
: undefined;
|
|
132
|
+
const result = await core.restore(ctx, {
|
|
133
|
+
app,
|
|
134
|
+
source,
|
|
135
|
+
components,
|
|
136
|
+
dryRun: options.dryRun ?? false,
|
|
137
|
+
});
|
|
138
|
+
if ("kind" in result) {
|
|
139
|
+
await writeLine(ctx, `${pc.cyan("dry-run")} would restore ${pc.bold(result.app)} from ${pc.bold(result.resolvedBackup.backup_id)}`);
|
|
140
|
+
await writeLine(ctx, ` components: ${pc.dim(result.components.join(", "))}`);
|
|
141
|
+
await writeLine(ctx, ` sha: ${pc.dim(`${result.resolvedBackup.tarball_sha256.slice(0, 16)}…`)}`);
|
|
142
|
+
await writeLine(ctx, pc.dim("\nRun without --dry-run to actually restore. Expect 30–120s of downtime."));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
await writeLine(ctx, `${pc.green("✓")} restored from ${result.sourceBackupId} (job ${result.id.slice(0, 12)})`);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/commands/data.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploys.d.ts","sourceRoot":"","sources":["../../../src/commands/deploys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAW/B,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsNpF"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as core from "@percher/core";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { SilentExitError, firstNonFlagAfter, formatDeployTimestamp, formatStatus, runDeploysInspect, writeLine, } from "../cli-utils";
|
|
4
|
+
export function registerDeploysCommands(cli, ctx, argv) {
|
|
5
|
+
cli
|
|
6
|
+
// The trailing `[...rest]` is a variadic absorber that exists only
|
|
7
|
+
// to make cac v7's checkUnusedArgs happy. cac matches commands by
|
|
8
|
+
// first-token equality (Command.isMatched in cac's source), so
|
|
9
|
+
// `deploys inspect dep_42` routes here with app="inspect" and the
|
|
10
|
+
// deploy id as an extra positional. v6 silently dropped extras; v7
|
|
11
|
+
// throws "Unused args" without a variadic absorber.
|
|
12
|
+
.command("deploys [app] [...rest]", "List recent deploys (id, status, created, error) for an app")
|
|
13
|
+
.option("--limit <n>", "Number of deploys to show (default: 10, max: 100)")
|
|
14
|
+
// Parent must accept the inspect-subcommand's flags too, since cac
|
|
15
|
+
// matches `deploys inspect ...` here (see in-action dispatch below)
|
|
16
|
+
// and rejects unknown options at parse time.
|
|
17
|
+
.option("--app <name>", "(inspect only) App name (defaults to percher.toml in cwd)")
|
|
18
|
+
.option("--latest-failed", "(inspect only) Resolve to the most recent failed deploy")
|
|
19
|
+
.action(async (app, _rest, options) => {
|
|
20
|
+
// Subcommand collision: `percher deploys inspect <id>` would otherwise
|
|
21
|
+
// hit this handler with app="inspect" because cac matches on first
|
|
22
|
+
// token only. Dispatch the documented form to the inspect handler.
|
|
23
|
+
if (app === "inspect") {
|
|
24
|
+
// Same flag-skip rule as the data reset-superuser dispatch — both
|
|
25
|
+
// `deploys inspect <id> --latest-failed` and `deploys inspect
|
|
26
|
+
// --latest-failed` should work. `--app` consumes the next argv
|
|
27
|
+
// token as its value (e.g. `--app my-app`), so we tell the
|
|
28
|
+
// walker to skip those pairs and not mistake `my-app` for the
|
|
29
|
+
// deploy id.
|
|
30
|
+
const idx = argv.indexOf("inspect");
|
|
31
|
+
const id = idx >= 0 ? firstNonFlagAfter(argv, idx, new Set(["--app"])) : undefined;
|
|
32
|
+
await runDeploysInspect(ctx, {
|
|
33
|
+
id,
|
|
34
|
+
// Forward --app + --latest-failed if the user passed them. Their
|
|
35
|
+
// flag values land in `options` even though we registered them
|
|
36
|
+
// on the sibling command, because cac merges argv flags onto the
|
|
37
|
+
// matched command's options.
|
|
38
|
+
app: options.app,
|
|
39
|
+
latestFailed: Boolean(options.latestFailed),
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
44
|
+
const list = await core.deploysList(ctx, { app, limit });
|
|
45
|
+
if (list.length === 0) {
|
|
46
|
+
await writeLine(ctx, pc.dim("No deploys yet."));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
await writeLine(ctx, `${pc.bold("ID".padEnd(22))} ${pc.bold("STATUS".padEnd(10))} ${pc.bold("CREATED".padEnd(20))} ${pc.bold("ERROR")}`);
|
|
50
|
+
for (const d of list) {
|
|
51
|
+
const id = d.id.padEnd(22);
|
|
52
|
+
const status = d.status.padEnd(10);
|
|
53
|
+
const created = formatDeployTimestamp(d.createdAt).padEnd(20);
|
|
54
|
+
const err = d.errorMessage
|
|
55
|
+
? (d.errorMessage.split("\n")[0]?.slice(0, 60) ?? "—")
|
|
56
|
+
: pc.dim("—");
|
|
57
|
+
const colored = d.status === "live"
|
|
58
|
+
? pc.green(status)
|
|
59
|
+
: d.status === "failed"
|
|
60
|
+
? pc.red(status)
|
|
61
|
+
: pc.yellow(status);
|
|
62
|
+
await writeLine(ctx, `${pc.dim(id)} ${colored} ${pc.dim(created)} ${err}`);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
cli
|
|
66
|
+
.command("deploys inspect [id]", "Inspect a deploy: status, error, build log")
|
|
67
|
+
.option("--app <name>", "App name (defaults to percher.toml in cwd)")
|
|
68
|
+
.option("--latest-failed", "Resolve to the most recent failed deploy")
|
|
69
|
+
.action(async (id, options) => {
|
|
70
|
+
// Unreachable in practice — the parent `deploys [app] [...rest]`
|
|
71
|
+
// action above intercepts `deploys inspect` and dispatches via
|
|
72
|
+
// runDeploysInspect, since cac only matches the first token.
|
|
73
|
+
// Kept registered so cac surfaces the subcommand in `--help`.
|
|
74
|
+
await runDeploysInspect(ctx, { id, app: options.app, latestFailed: options.latestFailed });
|
|
75
|
+
});
|
|
76
|
+
cli
|
|
77
|
+
.command("rollback <sha> [app]", "Roll back to a previous version")
|
|
78
|
+
.action(async (sha, app) => {
|
|
79
|
+
const result = await core.rollback(ctx, { app, commitSha: sha });
|
|
80
|
+
await writeLine(ctx, `${pc.green("✓")} rolled back to ${sha.slice(0, 10)} (status: ${result.status})`);
|
|
81
|
+
});
|
|
82
|
+
cli
|
|
83
|
+
.command("reproduce <deployId>", "Download a deploy's source and reproduce the build locally")
|
|
84
|
+
.option("--app <name>", "App name (defaults to percher.toml app.name)")
|
|
85
|
+
.action(async (deployId, options) => {
|
|
86
|
+
const result = await core.reproduce(ctx, {
|
|
87
|
+
app: options.app,
|
|
88
|
+
deployId,
|
|
89
|
+
});
|
|
90
|
+
if (result.status === "needs_login") {
|
|
91
|
+
await writeLine(ctx, `${pc.red("✗")} Not logged in. Run: percher login`);
|
|
92
|
+
throw new SilentExitError();
|
|
93
|
+
}
|
|
94
|
+
if (result.status === "failed") {
|
|
95
|
+
await writeLine(ctx, `${pc.red("✗")} ${result.error?.title ?? "Reproduce failed"}`);
|
|
96
|
+
if (result.error?.explanation) {
|
|
97
|
+
await writeLine(ctx, ` ${result.error.explanation}`);
|
|
98
|
+
}
|
|
99
|
+
if (result.error?.suggestion) {
|
|
100
|
+
await writeLine(ctx, ` ${pc.dim(result.error.suggestion)}`);
|
|
101
|
+
}
|
|
102
|
+
throw new SilentExitError();
|
|
103
|
+
}
|
|
104
|
+
await writeLine(ctx, `${pc.green("✓")} ${result.summary}`);
|
|
105
|
+
if (result.currentAppEnvKeys && result.currentAppEnvKeys.length > 0) {
|
|
106
|
+
await writeLine(ctx, "");
|
|
107
|
+
await writeLine(ctx, pc.bold("Current app env keys:"));
|
|
108
|
+
for (const k of result.currentAppEnvKeys) {
|
|
109
|
+
await writeLine(ctx, ` ${k}`);
|
|
110
|
+
}
|
|
111
|
+
await writeLine(ctx, pc.dim(" (values not exfiltrated — set them locally before building. Note: this is the CURRENT app env, not a deploy-time snapshot.)"));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
cli
|
|
115
|
+
.command("logs [app]", "Stream application logs")
|
|
116
|
+
.option("--tail <n>", "Return the last N lines and exit", { type: [Number] })
|
|
117
|
+
.option("--no-follow", "Don't stream new lines")
|
|
118
|
+
.option("--build [deployId]", "Show the BUILD log instead of runtime logs (defaults to latest failed deploy)")
|
|
119
|
+
.action(async (app, options) => {
|
|
120
|
+
// --build routes to the same logic as `deploys inspect`. We default
|
|
121
|
+
// to latest-failed when no deploy id is given because that's the
|
|
122
|
+
// common case (debugging the build that just failed).
|
|
123
|
+
if (options.build !== undefined) {
|
|
124
|
+
const deployId = typeof options.build === "string" && options.build.length > 0 ? options.build : undefined;
|
|
125
|
+
const result = await core.deploysInspect(ctx, {
|
|
126
|
+
app,
|
|
127
|
+
id: deployId,
|
|
128
|
+
latestFailed: deployId ? undefined : true,
|
|
129
|
+
});
|
|
130
|
+
const { deploy, buildLog } = result;
|
|
131
|
+
await writeLine(ctx, `${pc.bold("Deploy:")} ${deploy.id}`);
|
|
132
|
+
await writeLine(ctx, `${pc.bold("Status:")} ${formatStatus(deploy.status)}`);
|
|
133
|
+
await writeLine(ctx, `${pc.bold("Created:")} ${formatDeployTimestamp(deploy.createdAt)}`);
|
|
134
|
+
if (deploy.errorMessage) {
|
|
135
|
+
await writeLine(ctx, "");
|
|
136
|
+
await writeLine(ctx, pc.bold(pc.red("Error:")));
|
|
137
|
+
for (const line of deploy.errorMessage.split("\n")) {
|
|
138
|
+
await writeLine(ctx, ` ${line}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (buildLog) {
|
|
142
|
+
await writeLine(ctx, "");
|
|
143
|
+
const lines = buildLog.split("\n");
|
|
144
|
+
const tailN = options.tail ? Number(options.tail) : 200;
|
|
145
|
+
const tail = lines.slice(-tailN);
|
|
146
|
+
const header = lines.length > tail.length
|
|
147
|
+
? `${pc.bold("Build log")} ${pc.dim(`(last ${tail.length} of ${lines.length} lines)`)}`
|
|
148
|
+
: pc.bold("Build log");
|
|
149
|
+
await writeLine(ctx, header);
|
|
150
|
+
for (const line of tail) {
|
|
151
|
+
await writeLine(ctx, ` ${line}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
await writeLine(ctx, pc.dim("(no build log available for this deploy)"));
|
|
156
|
+
}
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
await core.logs(ctx, {
|
|
160
|
+
app,
|
|
161
|
+
tail: options.tail ? Number(options.tail) : undefined,
|
|
162
|
+
follow: options.follow !== false,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
cli
|
|
166
|
+
.command("versions [app]", "List deployed versions for an app")
|
|
167
|
+
.action(async (app) => {
|
|
168
|
+
const list = await core.versions(ctx, { app });
|
|
169
|
+
for (const v of list) {
|
|
170
|
+
await writeLine(ctx, `${v.sha.slice(0, 10)} ${v.timestamp} ${v.message}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
cli
|
|
174
|
+
.command("preview <action> [deployId]", "Manage preview deploys (promote | discard)")
|
|
175
|
+
.option("--app <name>", "App name (overrides percher.toml)")
|
|
176
|
+
.action(async (action, deployId, options) => {
|
|
177
|
+
const appRef = options.app ?? core.readPercherTomlAppName(ctx.cwd);
|
|
178
|
+
if (!appRef)
|
|
179
|
+
throw new Error("App name required. Use --app or run from a project directory.");
|
|
180
|
+
if (action === "promote") {
|
|
181
|
+
if (!deployId)
|
|
182
|
+
throw new Error("Deploy ID required. Usage: percher preview promote <id>");
|
|
183
|
+
const result = await ctx.client.apps.promotePreview(appRef, deployId);
|
|
184
|
+
await writeLine(ctx, `${pc.green("✓")} Preview promoted to live. Status: ${result.status}`);
|
|
185
|
+
}
|
|
186
|
+
else if (action === "discard") {
|
|
187
|
+
if (!deployId)
|
|
188
|
+
throw new Error("Deploy ID required. Usage: percher preview discard <id>");
|
|
189
|
+
await ctx.client.apps.discardPreview(appRef, deployId);
|
|
190
|
+
await writeLine(ctx, `${pc.green("✓")} Preview discarded.`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
throw new Error(`Unknown preview action "${action}". Use promote | discard.`);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=deploys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploys.js","sourceRoot":"","sources":["../../../src/commands/deploys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAI/B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CA2DhE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as core from "@percher/core";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { SilentExitError, writeLine } from "../cli-utils";
|
|
4
|
+
export function registerEnvCommands(cli, ctx) {
|
|
5
|
+
cli
|
|
6
|
+
.command("env <action> [...args]", "Manage env vars (set KEY=VALUE | set KEY --from-stdin | set KEY --from-file <path> | set KEY (prompts) | unset KEY | list)")
|
|
7
|
+
.option("--app <name>", "App name (overrides percher.toml)")
|
|
8
|
+
.option("--from-stdin", "(set) Read value for the single KEY from stdin")
|
|
9
|
+
.option("--from-file <path>", "(set) Read value for the single KEY from file")
|
|
10
|
+
.action(async (action, args, options) => {
|
|
11
|
+
if (action === "set") {
|
|
12
|
+
const { resolveEnvSetInputs, EnvSetInputError } = await import("../env-set-input");
|
|
13
|
+
const { promptHidden } = await import("../prompt-hidden");
|
|
14
|
+
const { readFile } = await import("node:fs/promises");
|
|
15
|
+
try {
|
|
16
|
+
const values = await resolveEnvSetInputs({
|
|
17
|
+
args,
|
|
18
|
+
fromStdin: options.fromStdin,
|
|
19
|
+
fromFile: options.fromFile,
|
|
20
|
+
readStdin: async () => {
|
|
21
|
+
const chunks = [];
|
|
22
|
+
for await (const c of process.stdin)
|
|
23
|
+
chunks.push(c);
|
|
24
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
25
|
+
},
|
|
26
|
+
readFile: async (p) => readFile(p, "utf8"),
|
|
27
|
+
promptHidden,
|
|
28
|
+
});
|
|
29
|
+
await core.envSet(ctx, { app: options.app, values });
|
|
30
|
+
await writeLine(ctx, `${pc.green("✓")} env vars updated (${Object.keys(values).length})`);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
if (err instanceof EnvSetInputError) {
|
|
34
|
+
await writeLine(ctx, `${pc.red("✗")} ${err.message}`);
|
|
35
|
+
throw new SilentExitError();
|
|
36
|
+
}
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else if (action === "unset") {
|
|
41
|
+
const key = args[0];
|
|
42
|
+
if (!key)
|
|
43
|
+
throw new Error("Expected key to unset");
|
|
44
|
+
await core.envUnset(ctx, { app: options.app, key });
|
|
45
|
+
await writeLine(ctx, `${pc.green("✓")} unset ${key}`);
|
|
46
|
+
}
|
|
47
|
+
else if (action === "list") {
|
|
48
|
+
const env = await core.envList(ctx, { app: options.app });
|
|
49
|
+
for (const [k, v] of Object.entries(env)) {
|
|
50
|
+
await writeLine(ctx, `${k}=${v}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error(`Unknown env action "${action}". Use set | unset | list.`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
cli
|
|
58
|
+
.command("generate", "Generate .env.example and TypeScript types from percher.toml")
|
|
59
|
+
.action(async () => {
|
|
60
|
+
const result = await core.generate(ctx);
|
|
61
|
+
for (const f of result.files) {
|
|
62
|
+
await writeLine(ctx, `${pc.green("✓")} ${f}`);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/commands/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/commands/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAkC/B,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CA8GnE"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as core from "@percher/core";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { writeLine } from "../cli-utils";
|
|
4
|
+
async function printWebhookInstructions(ctx, instructions, branch) {
|
|
5
|
+
await writeLine(ctx, pc.bold("Add this webhook in GitHub to enable auto-deploy on push:"));
|
|
6
|
+
await writeLine(ctx, ` URL: ${instructions.settingsUrl}`);
|
|
7
|
+
await writeLine(ctx, "");
|
|
8
|
+
await writeLine(ctx, " Field Value");
|
|
9
|
+
await writeLine(ctx, " ─────────────────────────────────────────────────");
|
|
10
|
+
await writeLine(ctx, ` Payload URL ${instructions.payloadUrl}`);
|
|
11
|
+
await writeLine(ctx, " Content type application/json");
|
|
12
|
+
await writeLine(ctx, ` Secret ${instructions.secret}`);
|
|
13
|
+
await writeLine(ctx, " Which events? Just the push event");
|
|
14
|
+
await writeLine(ctx, "");
|
|
15
|
+
await writeLine(ctx, pc.yellow(" ⚠ Treat this secret like a password — save it now, it won't be shown again."));
|
|
16
|
+
await writeLine(ctx, "");
|
|
17
|
+
await writeLine(ctx, pc.dim(`After adding the webhook, every push to ${branch} will auto-deploy.`));
|
|
18
|
+
}
|
|
19
|
+
export function registerGithubCommands(cli, ctx) {
|
|
20
|
+
// cac matches commands by single first-token equality (Command.isMatched
|
|
21
|
+
// in cac's source compares parsed.args[0] only), so multi-word commands
|
|
22
|
+
// like `github connect <repoUrl>` never match — argv[0] is just "github"
|
|
23
|
+
// and there's no plain `github` command registered. Pre-cac-v7 the
|
|
24
|
+
// result was a silent no-op (action body never ran, exit 0); v7's
|
|
25
|
+
// checkUnusedArgs surfaces the unused tokens as errors. Either way the
|
|
26
|
+
// user gets bad UX.
|
|
27
|
+
//
|
|
28
|
+
// Fix mirrors the data/deploys pattern: register a parent `github
|
|
29
|
+
// [action] ...` that dispatches on the action argument, plus keep the
|
|
30
|
+
// multi-word registrations below for `--help` discoverability (their
|
|
31
|
+
// action bodies are unreachable in practice).
|
|
32
|
+
cli
|
|
33
|
+
.command("github [action] [repoUrl] [...rest]", "GitHub integration: connect | setup-webhook")
|
|
34
|
+
.option("--app <name>", "App name (overrides percher.toml)")
|
|
35
|
+
.option("--branch <branch>", "(connect only) Branch to track (default: main)")
|
|
36
|
+
.action(async (action, repoUrl, _rest, options) => {
|
|
37
|
+
if (action === "connect") {
|
|
38
|
+
if (!repoUrl) {
|
|
39
|
+
throw new Error("repoUrl required. Usage: percher github connect <repoUrl>");
|
|
40
|
+
}
|
|
41
|
+
const result = await core.githubConnect(ctx, {
|
|
42
|
+
app: options.app,
|
|
43
|
+
repoUrl,
|
|
44
|
+
branch: options.branch,
|
|
45
|
+
});
|
|
46
|
+
await writeLine(ctx, `${pc.green("✓")} Connected to ${result.repoUrl} (branch: ${result.branch})`);
|
|
47
|
+
await writeLine(ctx, `${pc.green("✓")} Deploy started: ${result.deployId}`);
|
|
48
|
+
await writeLine(ctx, "");
|
|
49
|
+
if (result.webhookSetupFailed) {
|
|
50
|
+
await writeLine(ctx, pc.yellow(`⚠ Webhook setup failed: ${result.webhookSetupError ?? "unknown error"}`));
|
|
51
|
+
await writeLine(ctx, pc.yellow(" Auto-deploy will NOT work until you re-run webhook setup:"));
|
|
52
|
+
await writeLine(ctx, ` ${pc.bold(`percher github setup-webhook${options.app ? ` --app ${options.app}` : ""}`)}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (result.webhookInstructions) {
|
|
56
|
+
await printWebhookInstructions(ctx, result.webhookInstructions, result.branch);
|
|
57
|
+
}
|
|
58
|
+
await writeLine(ctx, pc.dim(`Track the initial deploy: percher deploys inspect ${result.deployId}`));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (action === "setup-webhook") {
|
|
62
|
+
const result = await core.githubSetupWebhook(ctx, { app: options.app });
|
|
63
|
+
await writeLine(ctx, `${pc.green("✓")} Webhook regenerated for ${result.app}`);
|
|
64
|
+
await writeLine(ctx, "");
|
|
65
|
+
await printWebhookInstructions(ctx, result.webhookInstructions, result.branch);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`Unknown github action "${action ?? ""}". Use: connect <repoUrl> | setup-webhook.`);
|
|
69
|
+
});
|
|
70
|
+
// Help-only registrations. Unreachable in practice (cac single-token
|
|
71
|
+
// matching falls through to the parent `github [action] ...` above),
|
|
72
|
+
// but kept so `percher --help` lists the documented subcommands with
|
|
73
|
+
// their full signatures.
|
|
74
|
+
cli
|
|
75
|
+
// [repoUrl] (optional) rather than <repoUrl> (required) so cac's
|
|
76
|
+
// checkRequiredArgs doesn't throw on this unreachable registration
|
|
77
|
+
// if cac's matching ever shifts to support multi-word commands. The
|
|
78
|
+
// parent `github [action] ...` action's own `if (!repoUrl) throw`
|
|
79
|
+
// guard produces the better user-facing error.
|
|
80
|
+
.command("github connect [repoUrl]", "Connect a Percher app to a GitHub repo: clones it, deploys it, and sets up auto-deploy on push")
|
|
81
|
+
.option("--app <name>", "App name (overrides percher.toml)")
|
|
82
|
+
.option("--branch <branch>", "Branch to track (default: main)")
|
|
83
|
+
.action(async () => {
|
|
84
|
+
// Unreachable — handled by parent `github [action] ...` action.
|
|
85
|
+
});
|
|
86
|
+
cli
|
|
87
|
+
.command("github setup-webhook", "Regenerate the GitHub webhook secret for an app (use after a failed `github connect`)")
|
|
88
|
+
.option("--app <name>", "App name (overrides percher.toml)")
|
|
89
|
+
.action(async () => {
|
|
90
|
+
// Unreachable — handled by parent `github [action] ...` action.
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../../src/commands/github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,KAAK,UAAU,wBAAwB,CACrC,GAAY,EACZ,YAIC,EACD,MAAc;IAEd,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC,CAAC;IAC3F,MAAM,SAAS,CAAC,GAAG,EAAE,YAAY,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACzB,MAAM,SAAS,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;IACjD,MAAM,SAAS,CAAC,GAAG,EAAE,qDAAqD,CAAC,CAAC;IAC5E,MAAM,SAAS,CAAC,GAAG,EAAE,sBAAsB,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC;IACtE,MAAM,SAAS,CAAC,GAAG,EAAE,qCAAqC,CAAC,CAAC;IAC5D,MAAM,SAAS,CAAC,GAAG,EAAE,sBAAsB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,MAAM,SAAS,CAAC,GAAG,EAAE,wCAAwC,CAAC,CAAC;IAC/D,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACzB,MAAM,SAAS,CACb,GAAG,EACH,EAAE,CAAC,MAAM,CAAC,gFAAgF,CAAC,CAC5F,CAAC;IACF,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACzB,MAAM,SAAS,CACb,GAAG,EACH,EAAE,CAAC,GAAG,CAAC,2CAA2C,MAAM,oBAAoB,CAAC,CAC9E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAQ,EAAE,GAAY;IAC3D,yEAAyE;IACzE,wEAAwE;IACxE,yEAAyE;IACzE,mEAAmE;IACnE,kEAAkE;IAClE,uEAAuE;IACvE,oBAAoB;IACpB,EAAE;IACF,kEAAkE;IAClE,sEAAsE;IACtE,qEAAqE;IACrE,8CAA8C;IAC9C,GAAG;SACA,OAAO,CAAC,qCAAqC,EAAE,6CAA6C,CAAC;SAC7F,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC;SAC3D,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CACL,KAAK,EACH,MAA0B,EAC1B,OAA2B,EAC3B,KAAe,EACf,OAA0C,EAC1C,EAAE;QACF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC/E,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;gBAC3C,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,OAAO;gBACP,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YAEH,MAAM,SAAS,CACb,GAAG,EACH,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,MAAM,GAAG,CAC7E,CAAC;YACF,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5E,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAEzB,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC9B,MAAM,SAAS,CACb,GAAG,EACH,EAAE,CAAC,MAAM,CAAC,4BAA4B,MAAM,CAAC,iBAAiB,IAAI,eAAe,EAAE,CAAC,CACrF,CAAC;gBACF,MAAM,SAAS,CACb,GAAG,EACH,EAAE,CAAC,MAAM,CAAC,8DAA8D,CAAC,CAC1E,CAAC;gBACF,MAAM,SAAS,CACb,GAAG,EACH,MAAM,EAAE,CAAC,IAAI,CAAC,+BAA+B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAC7F,CAAC;gBACF,OAAO;YACT,CAAC;YAED,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;gBAC/B,MAAM,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACjF,CAAC;YAED,MAAM,SAAS,CACb,GAAG,EACH,EAAE,CAAC,GAAG,CAAC,qDAAqD,MAAM,CAAC,QAAQ,EAAE,CAAC,CAC/E,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACxE,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/E,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACzB,MAAM,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;QAED,MAAM,IAAI,KAAK,CACb,0BAA0B,MAAM,IAAI,EAAE,4CAA4C,CACnF,CAAC;IACJ,CAAC,CACF,CAAC;IAEJ,qEAAqE;IACrE,qEAAqE;IACrE,qEAAqE;IACrE,yBAAyB;IACzB,GAAG;QACD,iEAAiE;QACjE,mEAAmE;QACnE,oEAAoE;QACpE,kEAAkE;QAClE,+CAA+C;SAC9C,OAAO,CACN,0BAA0B,EAC1B,gGAAgG,CACjG;SACA,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC;SAC3D,MAAM,CAAC,mBAAmB,EAAE,iCAAiC,CAAC;SAC9D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,gEAAgE;IAClE,CAAC,CAAC,CAAC;IACL,GAAG;SACA,OAAO,CACN,sBAAsB,EACtB,uFAAuF,CACxF;SACA,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC;SAC3D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,gEAAgE;IAClE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAC;AAE3D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAI/B,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAcnE"}
|