@devdogsuga/backstage 0.1.10 → 0.1.11
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/{catalog-CaTnrGVr.js → catalog-BLgY4knB.js} +87 -48
- package/dist/{cli-DjIwbjnx.js → cli-B7W_-WdD.js} +3 -3
- package/dist/{cli-feRmGaGi.js → cli-B8Lshscc.js} +28 -22
- package/dist/client-DCRfKvpP.js +2 -0
- package/dist/{client-NuoKMQmV.js → client-Djo8fRdS.js} +4 -4
- package/dist/{commands-C8pXvbv1.js → commands-3HvxDq-2.js} +4 -4
- package/dist/{commands-KY-9X1Rh.js → commands-B25Vafxz.js} +4 -4
- package/dist/{commands-jJcS7D2a.js → commands-BAh2_Nds.js} +2 -3
- package/dist/{commands-35rBJ1R0.js → commands-C3_hAcZS.js} +2 -2
- package/dist/{commands-BF5eptEi.js → commands-C6w8jm6a.js} +4 -4
- package/dist/{commands-CD1v_-6y.js → commands-D-Vvufb0.js} +5 -5
- package/dist/{commands-DQYH_m6i.js → commands-DILvdMc2.js} +3 -3
- package/dist/{commands-Ye0G_5bZ.js → commands-DfWNSPra.js} +3 -3
- package/dist/{dry-run-CFCZUpjb.js → dry-run-OzO0jUhK.js} +1 -1
- package/dist/launch.js +6 -6
- package/dist/{meetings-Du5asTAj.js → meetings-BAX4Sils.js} +2 -2
- package/dist/{peers-u1zxe-Ub.js → peers-DE07w6nT.js} +1 -1
- package/dist/{read-B8DSwYfB.js → read-Dd388anq.js} +2 -2
- package/dist/{telemetry-Be_lbB5c.js → telemetry-RNK5Wu74.js} +156 -9
- package/dist/telemetry.js +1 -1
- package/dist/{ui-Bb69ZfVv.js → ui-RFZyr6k_.js} +1 -1
- package/dist/{vault-DFV0zjbT.js → vault-BpYSYcuT.js} +1 -1
- package/package.json +5 -5
- package/dist/args-Cjr_Iqts.js +0 -66
- package/dist/client-A6pJcxSE.js +0 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { A as YES, D as DRY_RUN, O as JSON_FLAG, j as createCatalog, k as SCOPES, v as noteRan, w as findRepoRoot } from "./telemetry-
|
|
2
|
-
import { n as isDryRun } from "./dry-run-
|
|
3
|
-
import { o as unwrap } from "./ui-
|
|
4
|
-
import { n as positionals } from "./args-Cjr_Iqts.js";
|
|
1
|
+
import { A as YES, D as DRY_RUN, N as positionals, O as JSON_FLAG, j as createCatalog, k as SCOPES, v as noteRan, w as findRepoRoot } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { n as isDryRun } from "./dry-run-OzO0jUhK.js";
|
|
3
|
+
import { o as unwrap } from "./ui-RFZyr6k_.js";
|
|
5
4
|
import { t as EXPORTS } from "./queries-D3mTchag.js";
|
|
6
5
|
import { r as qrCatalogOptions } from "./options-DCaqm8BI.js";
|
|
7
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -80,15 +79,28 @@ function scopedBody(commands) {
|
|
|
80
79
|
open = command.scope;
|
|
81
80
|
lines.push(`${INDENT}${SCOPES[open].help}:`);
|
|
82
81
|
}
|
|
83
|
-
lines.push(`${INDENT.repeat(2)}${command.name.padEnd(width)} ${command
|
|
82
|
+
lines.push(`${INDENT.repeat(2)}${command.name.padEnd(width)} ${describe(command)}`);
|
|
84
83
|
}
|
|
85
84
|
return lines;
|
|
86
85
|
}
|
|
87
86
|
function optionRows(options) {
|
|
88
87
|
return options.map((option) => [optionLabel(option), option.summary]);
|
|
89
88
|
}
|
|
89
|
+
/** A command's summary as a list prints it, with what else it answers to. */
|
|
90
|
+
function describe(command) {
|
|
91
|
+
const aliases = (command.aliases ?? []).map((alias) => alias.name);
|
|
92
|
+
const also = aliases.length > 0 ? ` (also: ${aliases.join(", ")})` : "";
|
|
93
|
+
const deprecated = command.deprecated ? " (deprecated)" : "";
|
|
94
|
+
return `${command.summary}${also}${deprecated}`;
|
|
95
|
+
}
|
|
90
96
|
function childRows(children) {
|
|
91
|
-
return children.map((child) => [child.name, child
|
|
97
|
+
return children.map((child) => [child.name, describe(child)]);
|
|
98
|
+
}
|
|
99
|
+
/** `cron` is `jobs --kind sync`, for a command page's alias line. */
|
|
100
|
+
function aliasLine(node) {
|
|
101
|
+
const aliases = node.aliases ?? [];
|
|
102
|
+
if (aliases.length === 0) return void 0;
|
|
103
|
+
return `Also typed as ${aliases.map((alias) => alias.implies?.length ? `${alias.name} (${node.name} … ${alias.implies.join(" ")})` : alias.name).join(", ")}.`;
|
|
92
104
|
}
|
|
93
105
|
/** `pnpm devtools --help`: the groups, and nothing below them. */
|
|
94
106
|
function renderRoot(catalog) {
|
|
@@ -123,6 +135,8 @@ function renderCommand(catalog, path, node) {
|
|
|
123
135
|
"",
|
|
124
136
|
node.summary
|
|
125
137
|
];
|
|
138
|
+
const also = aliasLine(node);
|
|
139
|
+
if (also) lines.push("", also);
|
|
126
140
|
if (node.deprecated) lines.push("", `Deprecated. ${node.deprecated}`);
|
|
127
141
|
if (children.length > 0) lines.push("", "Subcommands:", ...scopedBody(children));
|
|
128
142
|
if (options.length > 0) lines.push("", "Options:", ...columns(optionRows(options)));
|
|
@@ -139,8 +153,9 @@ function renderCommand(catalog, path, node) {
|
|
|
139
153
|
function renderHelp(catalog, path = []) {
|
|
140
154
|
if (path.length === 0) return renderRoot(catalog);
|
|
141
155
|
const node = catalog.findCommand(path);
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
const canonical = catalog.canonicalPath(path);
|
|
157
|
+
if (!node || !canonical) return renderRoot(catalog);
|
|
158
|
+
return renderCommand(catalog, canonical, node);
|
|
144
159
|
}
|
|
145
160
|
/**
|
|
146
161
|
* The command names in `argv` that precede any flag.
|
|
@@ -177,7 +192,8 @@ function commandList(catalog) {
|
|
|
177
192
|
path: path.join(" "),
|
|
178
193
|
summary: node.summary,
|
|
179
194
|
surface: cliOnly ? "cli-only" : "interactive",
|
|
180
|
-
...node.deprecated ? { deprecated: node.deprecated } : {}
|
|
195
|
+
...node.deprecated ? { deprecated: node.deprecated } : {},
|
|
196
|
+
...node.aliases?.length ? { aliases: node.aliases.map((alias) => alias.name) } : {}
|
|
181
197
|
});
|
|
182
198
|
visit(node.subcommands ?? [], path, cliOnly);
|
|
183
199
|
}
|
|
@@ -606,7 +622,7 @@ function describeEnvironment(env) {
|
|
|
606
622
|
* A command's inputs arrive from two places that never meet: the wizard walks
|
|
607
623
|
* `commands.ts` and gathers the *declared* options into the argv it dispatches
|
|
608
624
|
* (see `menu.ts`), while a runner resolves anything it prompts for *itself* —
|
|
609
|
-
* `
|
|
625
|
+
* `jobs run` picking a tier, `env init` picking projects — deep inside its
|
|
610
626
|
* own call stack, where the dispatched argv is long out of reach. Threading a
|
|
611
627
|
* return value back up through every runner would touch each one's signature;
|
|
612
628
|
* a recorder every layer can reach touches only the layers that actually
|
|
@@ -662,13 +678,22 @@ function recordResolved(...fragment) {
|
|
|
662
678
|
interactive = true;
|
|
663
679
|
}
|
|
664
680
|
/**
|
|
681
|
+
* One argv token as a POSIX shell reads it back. A cron expression is the case
|
|
682
|
+
* that forced this: `--cron 0 0 * * *` pasted unquoted is three stray words
|
|
683
|
+
* and two globs.
|
|
684
|
+
*/
|
|
685
|
+
function shellQuote(token) {
|
|
686
|
+
if (/^[\w@%+=:,./-]+$/.test(token)) return token;
|
|
687
|
+
return `'${token.replaceAll("'", `'\\''`)}'`;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
665
690
|
* The command to print, or `null` when there is nothing worth printing —
|
|
666
691
|
* either no invocation ran, or the user typed a complete command and answered
|
|
667
692
|
* no prompts, so echoing it back would be noise.
|
|
668
693
|
*/
|
|
669
694
|
function reproducibleCommand() {
|
|
670
695
|
if (argv === null || !interactive || argv.length === 0) return null;
|
|
671
|
-
return `pnpm devtools ${[...enteredTier ? ["--tier", enteredTier] : [], ...argv].join(" ")}`;
|
|
696
|
+
return `pnpm devtools ${[...enteredTier ? ["--tier", enteredTier] : [], ...argv].map(shellQuote).join(" ")}`;
|
|
672
697
|
}
|
|
673
698
|
//#endregion
|
|
674
699
|
//#region ../cli-core/src/menu.ts
|
|
@@ -688,6 +713,16 @@ function reproducibleCommand() {
|
|
|
688
713
|
*
|
|
689
714
|
* Walking the catalog means an interactive command added there is in the
|
|
690
715
|
* menu the same day, with its options. Commands marked `cli-only` do not appear here.
|
|
716
|
+
*
|
|
717
|
+
* ## One flat first screen
|
|
718
|
+
*
|
|
719
|
+
* The first screen lists every top-level command, in the catalog's order,
|
|
720
|
+
* under its `title`: "Restart local Supabase" rather than `restart-stack`.
|
|
721
|
+
* There used to be a screen of groups above it, which put a door between the
|
|
722
|
+
* reader and every command and named the doors after how the CLI is built
|
|
723
|
+
* rather than what the reader came to do. The command's real name rides in
|
|
724
|
+
* the hint (`restart-stack · …`), so a walk still teaches what to type next
|
|
725
|
+
* time. Aliases are never drawn: the menu builds an argv for a real command.
|
|
691
726
|
*/
|
|
692
727
|
/** Chosen when a submenu should return to the screen above it. */
|
|
693
728
|
const BACK = Symbol("back");
|
|
@@ -712,39 +747,38 @@ function hintFor(node) {
|
|
|
712
747
|
const said = node.hint ?? node.summary;
|
|
713
748
|
return node.scope ? `${SCOPES[node.scope].menu} · ${said}` : said;
|
|
714
749
|
}
|
|
715
|
-
|
|
716
|
-
|
|
750
|
+
/**
|
|
751
|
+
* One command's entry on a screen: its title, with its real name leading the
|
|
752
|
+
* hint so the reader learns what to type. A command with no title is labelled
|
|
753
|
+
* by its name, which then has no reason to appear twice.
|
|
754
|
+
*/
|
|
755
|
+
function entryFor(node) {
|
|
756
|
+
return node.title ? {
|
|
757
|
+
label: node.title,
|
|
758
|
+
hint: `${node.name} · ${hintFor(node)}`
|
|
759
|
+
} : {
|
|
760
|
+
label: node.name,
|
|
761
|
+
hint: hintFor(node)
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
async function pickTopLevel(catalog, env) {
|
|
717
765
|
return unwrap(await select({
|
|
718
766
|
message: "What would you like to do?",
|
|
719
|
-
options: [...
|
|
720
|
-
value:
|
|
721
|
-
|
|
722
|
-
hint: offered(group.commands, env).map((command) => command.name).join(", ")
|
|
767
|
+
options: [...offered(catalog.topLevel, env).map((command) => ({
|
|
768
|
+
value: command,
|
|
769
|
+
...entryFor(command)
|
|
723
770
|
})), {
|
|
724
771
|
value: null,
|
|
725
772
|
label: "Quit"
|
|
726
773
|
}]
|
|
727
774
|
}));
|
|
728
775
|
}
|
|
729
|
-
async function pickCommand(group, env) {
|
|
730
|
-
const commands = offered(group.commands, env);
|
|
731
|
-
if (commands.length === 1) return commands[0];
|
|
732
|
-
return unwrap(await select({
|
|
733
|
-
message: `${group.title}:`,
|
|
734
|
-
options: [...commands.map((command) => ({
|
|
735
|
-
value: command,
|
|
736
|
-
label: command.name,
|
|
737
|
-
hint: hintFor(command)
|
|
738
|
-
})), BACK_OPTION]
|
|
739
|
-
}));
|
|
740
|
-
}
|
|
741
776
|
async function pickSubcommand(node, env) {
|
|
742
777
|
return unwrap(await select({
|
|
743
|
-
message: `${node.name}:`,
|
|
778
|
+
message: `${node.title ?? node.name}:`,
|
|
744
779
|
options: [...offered(node.subcommands ?? [], env).map((child) => ({
|
|
745
780
|
value: child,
|
|
746
|
-
|
|
747
|
-
hint: hintFor(child)
|
|
781
|
+
...entryFor(child)
|
|
748
782
|
})), BACK_OPTION]
|
|
749
783
|
}));
|
|
750
784
|
}
|
|
@@ -790,7 +824,7 @@ async function askOptions(node) {
|
|
|
790
824
|
* that leaf's options.
|
|
791
825
|
*
|
|
792
826
|
* Shared by both entries into a walk: the top-of-tree loop below, which calls
|
|
793
|
-
* this once a
|
|
827
|
+
* this once a top-level command is chosen, and a resumed walk
|
|
794
828
|
* (`walk`'s `startPath` branch), which calls it directly on a node the caller
|
|
795
829
|
* already picked by argv. `while` rather than a single step because the tree
|
|
796
830
|
* is two deep today and this does not care. The condition counts the OFFERED
|
|
@@ -798,7 +832,7 @@ async function askOptions(node) {
|
|
|
798
832
|
* hidden is treated as the leaf it has become instead of opening a screen
|
|
799
833
|
* holding only "Back".
|
|
800
834
|
*/
|
|
801
|
-
async function descendFrom(start, pathNames, env) {
|
|
835
|
+
async function descendFrom(start, pathNames, env, carried = []) {
|
|
802
836
|
let node = start;
|
|
803
837
|
const path = [...pathNames];
|
|
804
838
|
while (offered(node.subcommands ?? [], env).length > 0) {
|
|
@@ -809,7 +843,11 @@ async function descendFrom(start, pathNames, env) {
|
|
|
809
843
|
}
|
|
810
844
|
return {
|
|
811
845
|
node,
|
|
812
|
-
argv: [
|
|
846
|
+
argv: [
|
|
847
|
+
...path,
|
|
848
|
+
...await askOptions(node),
|
|
849
|
+
...carried
|
|
850
|
+
]
|
|
813
851
|
};
|
|
814
852
|
}
|
|
815
853
|
/**
|
|
@@ -817,24 +855,24 @@ async function descendFrom(start, pathNames, env) {
|
|
|
817
855
|
* a known group.
|
|
818
856
|
*
|
|
819
857
|
* `startPath`, when given, is a path to a group node from `bareGroupStartPath`
|
|
820
|
-
* — `["
|
|
821
|
-
* There is no
|
|
822
|
-
* by typing `
|
|
858
|
+
* — `["jobs"]` for `devtools jobs` — and lands here instead of at the first
|
|
859
|
+
* screen. There is no screen above a resumed node (the caller already named
|
|
860
|
+
* it by typing `jobs`), so BACK on its first subcommand screen has nowhere to
|
|
823
861
|
* return to but out, unlike BACK from the top of the tree, which returns to
|
|
824
|
-
* `
|
|
862
|
+
* the first screen. `startFlags` are the flags typed beside it, carried onto
|
|
863
|
+
* the end of the argv the walk builds.
|
|
825
864
|
*/
|
|
826
|
-
async function walk(catalog, env, startPath) {
|
|
865
|
+
async function walk(catalog, env, startPath, startFlags = []) {
|
|
827
866
|
if (startPath) {
|
|
828
867
|
const start = catalog.findCommand(startPath);
|
|
829
|
-
|
|
830
|
-
|
|
868
|
+
const path = catalog.canonicalPath(startPath);
|
|
869
|
+
if (!start || !path) return null;
|
|
870
|
+
const chosen = await descendFrom(start, path, env, startFlags);
|
|
831
871
|
return chosen === BACK ? null : chosen;
|
|
832
872
|
}
|
|
833
873
|
for (;;) {
|
|
834
|
-
const
|
|
835
|
-
if (!
|
|
836
|
-
const first = await pickCommand(group, env);
|
|
837
|
-
if (first === BACK) continue;
|
|
874
|
+
const first = await pickTopLevel(catalog, env);
|
|
875
|
+
if (!first) return null;
|
|
838
876
|
const chosen = await descendFrom(first, [first.name], env);
|
|
839
877
|
if (chosen === BACK) continue;
|
|
840
878
|
return chosen;
|
|
@@ -865,7 +903,8 @@ function bareGroupStartPath(catalog, argv) {
|
|
|
865
903
|
* from the command line.
|
|
866
904
|
*
|
|
867
905
|
* `options.startPath`, from `bareGroupStartPath`, skips straight to that
|
|
868
|
-
* node's subcommand screen — see `walk`'s `startPath` branch
|
|
906
|
+
* node's subcommand screen — see `walk`'s `startPath` branch — and
|
|
907
|
+
* `options.startFlags` (from `bareGroupStartFlags`) rides along to the end.
|
|
869
908
|
*
|
|
870
909
|
* The deploy tier is NOT asked here any more. `src/launch.ts` resolves it
|
|
871
910
|
* before `cli.ts` — and therefore this module — is even imported, and
|
|
@@ -887,7 +926,7 @@ function bareGroupStartPath(catalog, argv) {
|
|
|
887
926
|
*/
|
|
888
927
|
async function runMenu(catalog, dispatch, env = probeEnvironment(), options = {}) {
|
|
889
928
|
note(describeEnvironment(env), "This machine");
|
|
890
|
-
const chosen = await walk(catalog, env, options.startPath);
|
|
929
|
+
const chosen = await walk(catalog, env, options.startPath, options.startFlags);
|
|
891
930
|
if (!chosen) return null;
|
|
892
931
|
beginInvocation(chosen.argv, true);
|
|
893
932
|
const enteredTier = process.env.DEPLOY_ENV ?? "development";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as discoverRepoRoot, p as isNonInteractive } from "./telemetry-
|
|
1
|
+
import { C as discoverRepoRoot, p as isNonInteractive } from "./telemetry-RNK5Wu74.js";
|
|
2
2
|
import { t as nonEmpty } from "./connection-D3XsOE3S.js";
|
|
3
|
-
import { a as explainError, i as explain, o as unwrap, t as UsageError } from "./ui-
|
|
3
|
+
import { a as explainError, i as explain, o as unwrap, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
4
4
|
import { t as EnvDocument } from "./document-DumoZXoO.js";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
import { confirm, log, text } from "@clack/prompts";
|
|
@@ -31,7 +31,7 @@ async function readProductionKey(key) {
|
|
|
31
31
|
const value = nonEmpty(EnvDocument.parse(text).get(key));
|
|
32
32
|
if (value) return value;
|
|
33
33
|
} catch {}
|
|
34
|
-
const { listSecrets, projectIdFor } = await import("./client-
|
|
34
|
+
const { listSecrets, projectIdFor } = await import("./client-DCRfKvpP.js");
|
|
35
35
|
const secrets = await listSecrets(await projectIdFor(PRODUCTION_PROJECT));
|
|
36
36
|
return nonEmpty(secrets.find((s) => s.key === key)?.value);
|
|
37
37
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { C as discoverRepoRoot, T as cliName, b as ownPackageDir, c as reportDevtoolsError, f as isNoEnv, l as reportDevtoolsFailure, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive, w as findRepoRoot, x as ownVersion } from "./telemetry-
|
|
2
|
-
import { a as recordEnteredTier, f as helpPath, i as beginInvocation, l as dbPush, m as renderHelp, n as bareGroupStartPath, o as recordResolved, p as renderCommandList, r as runMenu, s as reproducibleCommand, t as catalog, u as dbPushDryRun } from "./catalog-
|
|
3
|
-
import { a as repoPeerUrl, n as loadEnv, r as loadEnvLoad, t as getEnvSync } from "./peers-
|
|
1
|
+
import { C as discoverRepoRoot, M as flagValue, N as positionals, T as cliName, b as ownPackageDir, c as reportDevtoolsError, f as isNoEnv, l as reportDevtoolsFailure, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive, w as findRepoRoot, x as ownVersion } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { a as recordEnteredTier, f as helpPath, i as beginInvocation, l as dbPush, m as renderHelp, n as bareGroupStartPath, o as recordResolved, p as renderCommandList, r as runMenu, s as reproducibleCommand, t as catalog, u as dbPushDryRun } from "./catalog-BLgY4knB.js";
|
|
3
|
+
import { a as repoPeerUrl, n as loadEnv, r as loadEnvLoad, t as getEnvSync } from "./peers-DE07w6nT.js";
|
|
4
4
|
import { t as nonEmpty } from "./connection-D3XsOE3S.js";
|
|
5
|
-
import { a as wouldRunLine, n as isDryRun, t as dryRunKind } from "./dry-run-
|
|
6
|
-
import { a as explainError, i as explain, n as bail, o as unwrap, r as errorMessage } from "./ui-
|
|
7
|
-
import { n as positionals, t as flagValue } from "./args-Cjr_Iqts.js";
|
|
5
|
+
import { a as wouldRunLine, n as isDryRun, t as dryRunKind } from "./dry-run-OzO0jUhK.js";
|
|
6
|
+
import { a as explainError, i as explain, n as bail, o as unwrap, r as errorMessage } from "./ui-RFZyr6k_.js";
|
|
8
7
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
9
8
|
import { t as EnvDocument } from "./document-DumoZXoO.js";
|
|
10
|
-
import { a as listSecrets$1, c as updateSecret, i as createSecret, o as projectIdFor, r as byKey, s as setExplicitAccessToken } from "./client-
|
|
9
|
+
import { a as listSecrets$1, c as updateSecret, i as createSecret, o as projectIdFor, r as byKey, s as setExplicitAccessToken } from "./client-Djo8fRdS.js";
|
|
11
10
|
import { register } from "node:module";
|
|
12
11
|
import { pathToFileURL } from "node:url";
|
|
13
12
|
import { appendFileSync, existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
@@ -24,17 +23,24 @@ import { randomBytes } from "node:crypto";
|
|
|
24
23
|
/**
|
|
25
24
|
* Groups all paths by their parent prefix to build per-parent completion lists.
|
|
26
25
|
*
|
|
27
|
-
* e.g. ["env", "pull"] contributes "pull" to the group keyed "env".
|
|
26
|
+
* e.g. ["env", "pull"] contributes "pull" to the group keyed "env". Aliases
|
|
27
|
+
* complete too, after the name they stand for, and the children under an
|
|
28
|
+
* alias are its command's: `cron <TAB>` offers what `jobs <TAB>` does.
|
|
28
29
|
*/
|
|
29
30
|
function buildGroups(catalog) {
|
|
30
31
|
const groups = /* @__PURE__ */ new Map();
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
const visit = (nodes, parents) => {
|
|
33
|
+
for (const node of nodes) {
|
|
34
|
+
const names = [node.name, ...(node.aliases ?? []).map((a) => a.name)];
|
|
35
|
+
for (const parent of parents) {
|
|
36
|
+
const existing = groups.get(parent) ?? [];
|
|
37
|
+
existing.push(...names);
|
|
38
|
+
groups.set(parent, existing);
|
|
39
|
+
}
|
|
40
|
+
visit(node.subcommands ?? [], parents.flatMap((parent) => names.map((name) => parent ? `${parent} ${name}` : name)));
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
visit(catalog.topLevel, [""]);
|
|
38
44
|
return groups;
|
|
39
45
|
}
|
|
40
46
|
function generateBash(catalog) {
|
|
@@ -985,7 +991,7 @@ function toPath(location) {
|
|
|
985
991
|
}
|
|
986
992
|
}
|
|
987
993
|
/**
|
|
988
|
-
* `GET /cron/config-reconcile`, authenticated. Unlike `devtools
|
|
994
|
+
* `GET /cron/config-reconcile`, authenticated. Unlike `devtools jobs run`
|
|
989
995
|
* (which only checks the HTTP status), this reads the JSON body: the route
|
|
990
996
|
* answers 200 even when the reconcile itself failed
|
|
991
997
|
* (`{ success: false, reason: … }`, see
|
|
@@ -5380,12 +5386,12 @@ const HANDLERS = {
|
|
|
5380
5386
|
},
|
|
5381
5387
|
completions: handleCompletions,
|
|
5382
5388
|
github: handleGithub,
|
|
5383
|
-
graphics: async (rest) => (await import("./commands-
|
|
5384
|
-
qr: async (rest) => (await import("./commands-
|
|
5385
|
-
newsletter: async (rest) => (await import("./commands-
|
|
5386
|
-
creds: async (rest) => (await import("./commands-
|
|
5387
|
-
import: async (rest) => (await import("./commands-
|
|
5388
|
-
export: async (rest) => (await import("./commands-
|
|
5389
|
+
graphics: async (rest) => (await import("./commands-BAh2_Nds.js")).handleGraphics(rest),
|
|
5390
|
+
qr: async (rest) => (await import("./commands-DILvdMc2.js")).handleQr(rest),
|
|
5391
|
+
newsletter: async (rest) => (await import("./commands-C3_hAcZS.js")).handleNewsletter(rest),
|
|
5392
|
+
creds: async (rest) => (await import("./commands-C6w8jm6a.js")).handleCreds(rest),
|
|
5393
|
+
import: async (rest) => (await import("./commands-DfWNSPra.js")).handleImport(rest),
|
|
5394
|
+
export: async (rest) => (await import("./commands-3HvxDq-2.js")).handleExport(rest)
|
|
5389
5395
|
};
|
|
5390
5396
|
/**
|
|
5391
5397
|
* Names that were commands of the contributor CLI, refused with where they
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { w as findRepoRoot } from "./telemetry-
|
|
2
|
-
import { n as loadEnv } from "./peers-
|
|
3
|
-
import { o as unwrap } from "./ui-
|
|
1
|
+
import { w as findRepoRoot } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { n as loadEnv } from "./peers-DE07w6nT.js";
|
|
3
|
+
import { o as unwrap } from "./ui-RFZyr6k_.js";
|
|
4
4
|
import { t as EnvDocument } from "./document-DumoZXoO.js";
|
|
5
|
-
import { a as readTokenFromVault, o as saveTokenToVault, t as VAULT_ITEM_NAME } from "./vault-
|
|
5
|
+
import { a as readTokenFromVault, o as saveTokenToVault, t as VAULT_ITEM_NAME } from "./vault-BpYSYcuT.js";
|
|
6
6
|
import { dirname, join, resolve } from "node:path";
|
|
7
7
|
import { log, password, select, text } from "@clack/prompts";
|
|
8
8
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as isDryRun } from "./dry-run-
|
|
2
|
-
import { o as unwrap, r as errorMessage, t as UsageError } from "./ui-
|
|
1
|
+
import { n as isDryRun } from "./dry-run-OzO0jUhK.js";
|
|
2
|
+
import { o as unwrap, r as errorMessage, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
3
3
|
import { i as exportParams, n as EXPORT_KINDS, r as auditFilters, t as EXPORTS } from "./queries-D3mTchag.js";
|
|
4
4
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
5
|
-
import { c as ProductionError, d as requireProductionKey, i as plural, l as connect, o as reportFailure, r as expandHome, s as say, t as canPrompt, u as dbError } from "./cli-
|
|
6
|
-
import { i as parseBound, n as findMeetingsWith, r as pickMeeting, t as describeMeeting } from "./meetings-
|
|
5
|
+
import { c as ProductionError, d as requireProductionKey, i as plural, l as connect, o as reportFailure, r as expandHome, s as say, t as canPrompt, u as dbError } from "./cli-B7W_-WdD.js";
|
|
6
|
+
import { i as parseBound, n as findMeetingsWith, r as pickMeeting, t as describeMeeting } from "./meetings-BAX4Sils.js";
|
|
7
7
|
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
8
8
|
import { basename, dirname, join } from "node:path";
|
|
9
9
|
import { autocomplete, confirm, multiselect, text } from "@clack/prompts";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as isDryRun } from "./dry-run-
|
|
2
|
-
import { r as errorMessage, t as UsageError } from "./ui-
|
|
1
|
+
import { n as isDryRun } from "./dry-run-OzO0jUhK.js";
|
|
2
|
+
import { r as errorMessage, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
3
3
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
4
|
-
import { a as readInputFile, d as requireProductionKey, f as withConnection, i as plural, n as confirmWrite, o as reportFailure, s as say, t as canPrompt } from "./cli-
|
|
5
|
-
import { a as createAccounts, i as createAccountFor, n as accountFinder, o as readAccounts, t as parseCsv } from "./read-
|
|
4
|
+
import { a as readInputFile, d as requireProductionKey, f as withConnection, i as plural, n as confirmWrite, o as reportFailure, s as say, t as canPrompt } from "./cli-B7W_-WdD.js";
|
|
5
|
+
import { a as createAccounts, i as createAccountFor, n as accountFinder, o as readAccounts, t as parseCsv } from "./read-Dd388anq.js";
|
|
6
6
|
import { parseArgs } from "node:util";
|
|
7
7
|
//#region src/involvement/csv.ts
|
|
8
8
|
/**
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { p as isNonInteractive } from "./telemetry-
|
|
2
|
-
import { a as explainError, o as unwrap, r as errorMessage, t as UsageError } from "./ui-
|
|
3
|
-
import { n as positionals } from "./args-Cjr_Iqts.js";
|
|
1
|
+
import { N as positionals, p as isNonInteractive } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { a as explainError, o as unwrap, r as errorMessage, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
4
3
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
5
4
|
import { dirname, relative, resolve } from "node:path";
|
|
6
5
|
import { autocompleteMultiselect, log, multiselect, note } from "@clack/prompts";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as isNonInteractive } from "./telemetry-
|
|
2
|
-
import { a as explainError, o as unwrap, r as errorMessage, t as UsageError } from "./ui-
|
|
1
|
+
import { p as isNonInteractive } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { a as explainError, o as unwrap, r as errorMessage, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
3
3
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { confirm, log, multiselect, spinner, text } from "@clack/prompts";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { C as discoverRepoRoot, p as isNonInteractive } from "./telemetry-
|
|
1
|
+
import { C as discoverRepoRoot, p as isNonInteractive } from "./telemetry-RNK5Wu74.js";
|
|
2
2
|
import { t as nonEmpty } from "./connection-D3XsOE3S.js";
|
|
3
|
-
import { a as explainError, i as explain, o as unwrap, r as errorMessage, t as UsageError } from "./ui-
|
|
3
|
+
import { a as explainError, i as explain, o as unwrap, r as errorMessage, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
4
4
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
5
5
|
import { t as EnvDocument } from "./document-DumoZXoO.js";
|
|
6
|
-
import { i as readPasswordFromVault, n as bwArgs, r as openVault, s as bwCommand } from "./vault-
|
|
6
|
+
import { i as readPasswordFromVault, n as bwArgs, r as openVault, s as bwCommand } from "./vault-BpYSYcuT.js";
|
|
7
7
|
import { resolve } from "node:path";
|
|
8
8
|
import { confirm, log, multiselect, note, password, select, text } from "@clack/prompts";
|
|
9
9
|
import { readFile } from "node:fs/promises";
|
|
@@ -632,7 +632,7 @@ async function readCheckoutDbUrl() {
|
|
|
632
632
|
}
|
|
633
633
|
}
|
|
634
634
|
async function readSecretsManagerDbUrl() {
|
|
635
|
-
const { listSecrets, projectIdFor } = await import("./client-
|
|
635
|
+
const { listSecrets, projectIdFor } = await import("./client-DCRfKvpP.js");
|
|
636
636
|
const secrets = await listSecrets(await projectIdFor(PRODUCTION_PROJECT));
|
|
637
637
|
return nonEmpty(secrets.find((s) => s.key === "DB_URL")?.value);
|
|
638
638
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as isDryRun } from "./dry-run-
|
|
2
|
-
import { o as unwrap, r as errorMessage, t as UsageError } from "./ui-
|
|
1
|
+
import { n as isDryRun } from "./dry-run-OzO0jUhK.js";
|
|
2
|
+
import { o as unwrap, r as errorMessage, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
3
3
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
4
|
-
import { a as readInputFile, c as ProductionError, d as requireProductionKey, f as withConnection, i as plural, l as connect, n as confirmWrite, o as reportFailure, s as say, t as canPrompt } from "./cli-
|
|
5
|
-
import { a as createAccounts, i as createAccountFor, n as accountFinder, r as accountsWith, t as parseCsv } from "./read-
|
|
6
|
-
import { n as findMeetingsWith, r as pickMeeting, t as describeMeeting } from "./meetings-
|
|
4
|
+
import { a as readInputFile, c as ProductionError, d as requireProductionKey, f as withConnection, i as plural, l as connect, n as confirmWrite, o as reportFailure, s as say, t as canPrompt } from "./cli-B7W_-WdD.js";
|
|
5
|
+
import { a as createAccounts, i as createAccountFor, n as accountFinder, r as accountsWith, t as parseCsv } from "./read-Dd388anq.js";
|
|
6
|
+
import { n as findMeetingsWith, r as pickMeeting, t as describeMeeting } from "./meetings-BAX4Sils.js";
|
|
7
7
|
import { text } from "@clack/prompts";
|
|
8
8
|
import { parseArgs } from "node:util";
|
|
9
9
|
//#region src/attendance/plan.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { p as isNonInteractive } from "./telemetry-
|
|
2
|
-
import { n as isDryRun } from "./dry-run-
|
|
3
|
-
import { a as explainError, o as unwrap, t as UsageError } from "./ui-
|
|
1
|
+
import { p as isNonInteractive } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { n as isDryRun } from "./dry-run-OzO0jUhK.js";
|
|
3
|
+
import { a as explainError, o as unwrap, t as UsageError } from "./ui-RFZyr6k_.js";
|
|
4
4
|
import { i as qrParseOptions, n as QR_FLAGS, t as QR_EXTRA_FLAGS } from "./options-DCaqm8BI.js";
|
|
5
5
|
import { t as DONE } from "./dispatch-D048O65I.js";
|
|
6
6
|
import { dirname, extname, relative, resolve } from "node:path";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { i as explain } from "./ui-
|
|
1
|
+
import { i as explain } from "./ui-RFZyr6k_.js";
|
|
2
2
|
//#region src/import/commands.ts
|
|
3
3
|
const handleImport = async (rest) => {
|
|
4
4
|
const [what, ...args] = rest;
|
|
5
|
-
if (what === "involvement") return (await import("./commands-
|
|
6
|
-
if (what === "attendance") return (await import("./commands-
|
|
5
|
+
if (what === "involvement") return (await import("./commands-B25Vafxz.js")).handleInvolvement(args);
|
|
6
|
+
if (what === "attendance") return (await import("./commands-D-Vvufb0.js")).handleAttendance(args);
|
|
7
7
|
explain(what ? `Unknown import "${what}". Try involvement or attendance.` : "Name the import: involvement or attendance.", "");
|
|
8
8
|
process.exitCode = 1;
|
|
9
9
|
return null;
|
package/dist/launch.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { C as discoverRepoRoot, E as setCliName, S as RepoNotFoundError, T as cliName, _ as installFailureLog, d as hasYes, g as stripTierFlag, h as stripNoEnvFlag, m as setNoEnv, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive, s as lastSentryEventId } from "./telemetry-
|
|
2
|
-
import { c as setMenuEnvHook, d as formatCommand, f as helpPath, n as bareGroupStartPath, t as catalog } from "./catalog-
|
|
3
|
-
import { i as loadEnvSession, r as loadEnvLoad } from "./peers-
|
|
1
|
+
import { C as discoverRepoRoot, E as setCliName, S as RepoNotFoundError, T as cliName, _ as installFailureLog, d as hasYes, g as stripTierFlag, h as stripNoEnvFlag, m as setNoEnv, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive, s as lastSentryEventId } from "./telemetry-RNK5Wu74.js";
|
|
2
|
+
import { c as setMenuEnvHook, d as formatCommand, f as helpPath, n as bareGroupStartPath, t as catalog } from "./catalog-BLgY4knB.js";
|
|
3
|
+
import { i as loadEnvSession, r as loadEnvLoad } from "./peers-DE07w6nT.js";
|
|
4
4
|
import { t as nonEmpty } from "./connection-D3XsOE3S.js";
|
|
5
|
-
import { i as setDryRun, n as isDryRun, r as resolveDryRun } from "./dry-run-
|
|
6
|
-
import { o as unwrap, r as errorMessage } from "./ui-
|
|
5
|
+
import { i as setDryRun, n as isDryRun, r as resolveDryRun } from "./dry-run-OzO0jUhK.js";
|
|
6
|
+
import { o as unwrap, r as errorMessage } from "./ui-RFZyr6k_.js";
|
|
7
7
|
import { confirm } from "@clack/prompts";
|
|
8
8
|
//#region ../cli-core/src/pipes.ts
|
|
9
9
|
/**
|
|
@@ -322,7 +322,7 @@ async function launchWith(argv, options) {
|
|
|
322
322
|
*/
|
|
323
323
|
async function launch(argv) {
|
|
324
324
|
await launchWith(argv, { dispatch: async (args) => {
|
|
325
|
-
const { main } = await import("./cli-
|
|
325
|
+
const { main } = await import("./cli-B8Lshscc.js");
|
|
326
326
|
await main(args);
|
|
327
327
|
} });
|
|
328
328
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as UsageError } from "./ui-
|
|
2
|
-
import "./cli-
|
|
1
|
+
import { t as UsageError } from "./ui-RFZyr6k_.js";
|
|
2
|
+
import "./cli-B7W_-WdD.js";
|
|
3
3
|
//#region src/production/time.ts
|
|
4
4
|
/**
|
|
5
5
|
* Dates as officers type them. Meetings happen in Athens, so a bare
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as RepoNotFoundError, w as findRepoRoot } from "./telemetry-
|
|
1
|
+
import { S as RepoNotFoundError, w as findRepoRoot } from "./telemetry-RNK5Wu74.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as errorMessage } from "./ui-
|
|
2
|
-
import { c as ProductionError, f as withConnection } from "./cli-
|
|
1
|
+
import { r as errorMessage } from "./ui-RFZyr6k_.js";
|
|
2
|
+
import { c as ProductionError, f as withConnection } from "./cli-B7W_-WdD.js";
|
|
3
3
|
//#region src/production/accounts.ts
|
|
4
4
|
/**
|
|
5
5
|
* Production accounts: reading them, finding one by email, and creating the
|
|
@@ -4,8 +4,103 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { homedir, platform, release } from "node:os";
|
|
5
5
|
import * as Sentry from "@sentry/node";
|
|
6
6
|
import { buildSentryOptions } from "@devdogsuga/telemetry";
|
|
7
|
+
//#region ../cli-core/src/args.ts
|
|
8
|
+
/**
|
|
9
|
+
* Positional arguments, with flag values excluded.
|
|
10
|
+
*
|
|
11
|
+
* Its own module because of one bug it prevents. The first positional is the
|
|
12
|
+
* subcommand, and `pull`, `push` and `audit` do very different things to live
|
|
13
|
+
* credentials. A naive `filter((a) => !a.startsWith("--"))` reads a flag's
|
|
14
|
+
* VALUE as a positional, so `env --file notes.env audit` fails loudly:
|
|
15
|
+
* `notes.env` is not a subcommand and the command refuses. The quiet version
|
|
16
|
+
* is the one that matters:
|
|
17
|
+
*
|
|
18
|
+
* env --file push audit
|
|
19
|
+
*
|
|
20
|
+
* which runs `push`, writing to Bitwarden and GitHub, when the caller asked
|
|
21
|
+
* for `audit`, which writes nothing at all.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Flags that consume the token after them.
|
|
25
|
+
*/
|
|
26
|
+
const VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
27
|
+
"--access-token",
|
|
28
|
+
"--format",
|
|
29
|
+
"--out",
|
|
30
|
+
"--version",
|
|
31
|
+
"--app",
|
|
32
|
+
"--apps",
|
|
33
|
+
"--base-url",
|
|
34
|
+
"--file",
|
|
35
|
+
"--source",
|
|
36
|
+
"--target",
|
|
37
|
+
"--tier",
|
|
38
|
+
"--cron",
|
|
39
|
+
"--kind",
|
|
40
|
+
"--workflow",
|
|
41
|
+
"--params",
|
|
42
|
+
"--port",
|
|
43
|
+
"--preview-url",
|
|
44
|
+
"--db-url",
|
|
45
|
+
"--user",
|
|
46
|
+
"--filter",
|
|
47
|
+
"--shell"
|
|
48
|
+
]);
|
|
49
|
+
function positionals(argv) {
|
|
50
|
+
const found = [];
|
|
51
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
52
|
+
const arg = argv[i];
|
|
53
|
+
if (!arg.startsWith("-")) {
|
|
54
|
+
found.push(arg);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const next = argv[i + 1];
|
|
58
|
+
if (VALUE_FLAGS.has(arg) && next !== void 0 && !next.startsWith("-")) i += 1;
|
|
59
|
+
}
|
|
60
|
+
return found;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The value after `flag`, or `undefined` when the flag is absent or is
|
|
64
|
+
* followed by another flag instead of a value.
|
|
65
|
+
*/
|
|
66
|
+
function flagValue(rest, flag) {
|
|
67
|
+
const index = rest.indexOf(flag);
|
|
68
|
+
if (index === -1) return void 0;
|
|
69
|
+
const value = rest[index + 1];
|
|
70
|
+
return value && !value.startsWith("--") ? value : void 0;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
7
73
|
//#region ../cli-core/src/catalog.ts
|
|
8
74
|
/**
|
|
75
|
+
* The command catalog: types, shared option shapes and the lookups over a
|
|
76
|
+
* composed tree.
|
|
77
|
+
*
|
|
78
|
+
* A CLI's command tree is data. Each domain declares its own commands in its
|
|
79
|
+
* `catalog.ts` (names, summaries and option shapes, nothing that runs), the
|
|
80
|
+
* CLI's `src/catalog.ts` composes those into groups, and `createCatalog`
|
|
81
|
+
* wraps the result. Three readers consume it:
|
|
82
|
+
*
|
|
83
|
+
* * `help.ts` renders it, one level at a time.
|
|
84
|
+
* * `menu.ts` walks its interactive commands and options without a second
|
|
85
|
+
* list to keep in step.
|
|
86
|
+
* * `completions.ts` enumerates it, and contributor documentation uses the
|
|
87
|
+
* same group and command vocabulary.
|
|
88
|
+
*
|
|
89
|
+
* It is deliberately inert: no imports of anything that runs (`args.ts` is
|
|
90
|
+
* data too), so the launcher can read it (for `envFree`) before the session's
|
|
91
|
+
* environment is entered.
|
|
92
|
+
* The CLI's dispatcher owns the handlers, and the wizard turns a walk of this
|
|
93
|
+
* tree into an argv and hands it to that same dispatcher, which keeps menu and
|
|
94
|
+
* CLI behavior aligned by construction rather than by review.
|
|
95
|
+
*
|
|
96
|
+
* ## What a summary is for
|
|
97
|
+
*
|
|
98
|
+
* Every `summary` is one line and is the ONLY thing `--help` prints for a
|
|
99
|
+
* command at the level above it. Rationale, target tables, credential lookup
|
|
100
|
+
* order and deploy internals live in `docs/`, not here: `--help` is a map, and
|
|
101
|
+
* a map that reprints the territory is the thing this replaced.
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
9
104
|
* How each scope reads, in the two places that draw it.
|
|
10
105
|
*
|
|
11
106
|
* `menu` sits inline in a hint, so it is one word. `help` heads a block of
|
|
@@ -51,22 +146,54 @@ const YES = {
|
|
|
51
146
|
flag: "--yes",
|
|
52
147
|
summary: "Skip the confirmations."
|
|
53
148
|
};
|
|
54
|
-
|
|
149
|
+
/** The node a typed token names among `nodes`, by its name or an alias. */
|
|
150
|
+
function named(nodes, token) {
|
|
151
|
+
for (const node of nodes) {
|
|
152
|
+
if (node.name === token) return { node };
|
|
153
|
+
const alias = node.aliases?.find((candidate) => candidate.name === token);
|
|
154
|
+
if (alias) return {
|
|
155
|
+
node,
|
|
156
|
+
alias
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** Each step of a path, resolved through aliases; `null` at the first miss. */
|
|
161
|
+
function resolve$1(roots, path) {
|
|
55
162
|
let nodes = roots;
|
|
56
|
-
|
|
57
|
-
for (const
|
|
58
|
-
const
|
|
59
|
-
if (!
|
|
60
|
-
|
|
61
|
-
nodes =
|
|
163
|
+
const steps = [];
|
|
164
|
+
for (const token of path) {
|
|
165
|
+
const step = named(nodes, token);
|
|
166
|
+
if (!step) return null;
|
|
167
|
+
steps.push(step);
|
|
168
|
+
nodes = step.node.subcommands ?? [];
|
|
169
|
+
}
|
|
170
|
+
return steps;
|
|
171
|
+
}
|
|
172
|
+
function walk(roots, path) {
|
|
173
|
+
return resolve$1(roots, path)?.at(-1)?.node ?? null;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Refuses a tree where one token could name two siblings. An alias that
|
|
177
|
+
* shadowed another command would make which one runs depend on declaration
|
|
178
|
+
* order, the kind of thing nobody finds until it has run the wrong one.
|
|
179
|
+
*/
|
|
180
|
+
function assertUnambiguous(nodes, prefix) {
|
|
181
|
+
const seen = /* @__PURE__ */ new Set();
|
|
182
|
+
for (const node of nodes) {
|
|
183
|
+
for (const token of [node.name, ...(node.aliases ?? []).map((a) => a.name)]) {
|
|
184
|
+
if (seen.has(token)) throw new Error(`Command tree: "${[...prefix, token].join(" ")}" names two commands.`);
|
|
185
|
+
seen.add(token);
|
|
186
|
+
}
|
|
187
|
+
assertUnambiguous(node.subcommands ?? [], [...prefix, node.name]);
|
|
62
188
|
}
|
|
63
|
-
return found;
|
|
64
189
|
}
|
|
65
190
|
function createCatalog(trees) {
|
|
66
191
|
const groups = trees.groups;
|
|
67
192
|
const ciGroups = trees.ciGroups ?? [];
|
|
68
193
|
const topLevel = groups.flatMap((group) => group.commands);
|
|
69
194
|
const ciTopLevel = ciGroups.flatMap((group) => group.commands);
|
|
195
|
+
assertUnambiguous(topLevel, []);
|
|
196
|
+
assertUnambiguous(ciTopLevel, []);
|
|
70
197
|
const subcommandNames = (path) => (walk(topLevel, path)?.subcommands ?? []).map((node) => node.name);
|
|
71
198
|
return {
|
|
72
199
|
usage: trees.usage,
|
|
@@ -78,6 +205,26 @@ function createCatalog(trees) {
|
|
|
78
205
|
findCommand: (path) => walk(topLevel, path),
|
|
79
206
|
findCiCommand: (path) => walk(ciTopLevel, path),
|
|
80
207
|
groupOf: (name) => groups.find((group) => group.commands.some((command) => command.name === name)),
|
|
208
|
+
canonicalPath: (path) => resolve$1(topLevel, path)?.map((step) => step.node.name) ?? null,
|
|
209
|
+
canonicalArgv: (argv) => {
|
|
210
|
+
const out = [...argv];
|
|
211
|
+
const implied = [];
|
|
212
|
+
let nodes = topLevel;
|
|
213
|
+
for (let i = 0; i < out.length; i += 1) {
|
|
214
|
+
const arg = out[i];
|
|
215
|
+
if (arg.startsWith("-")) {
|
|
216
|
+
const next = out[i + 1];
|
|
217
|
+
if (VALUE_FLAGS.has(arg) && next !== void 0 && !next.startsWith("-")) i += 1;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const step = named(nodes, arg);
|
|
221
|
+
if (!step) break;
|
|
222
|
+
out[i] = step.node.name;
|
|
223
|
+
implied.push(...step.alias?.implies ?? []);
|
|
224
|
+
nodes = step.node.subcommands ?? [];
|
|
225
|
+
}
|
|
226
|
+
return [...out, ...implied];
|
|
227
|
+
},
|
|
81
228
|
subcommandNames,
|
|
82
229
|
subcommandCiNames: (path) => (walk(ciTopLevel, path)?.subcommands ?? []).map((node) => node.name),
|
|
83
230
|
subcommandList: (path) => {
|
|
@@ -606,4 +753,4 @@ async function captureDevtoolsDeprecation(message, fingerprint, tags) {
|
|
|
606
753
|
await Sentry.flush(1e3);
|
|
607
754
|
}
|
|
608
755
|
//#endregion
|
|
609
|
-
export { YES as A, discoverRepoRoot as C, DRY_RUN as D, setCliName as E, JSON_FLAG as O, RepoNotFoundError as S, cliName as T, installFailureLog as _, hasRealCaller as a, ownPackageDir as b, reportDevtoolsError as c, hasYes as d, isNoEnv as f, stripTierFlag as g, stripNoEnvFlag as h, devtoolsTelemetryEnabled as i, createCatalog as j, SCOPES as k, reportDevtoolsFailure as l, setNoEnv as m, captureDevtoolsError as n, initDevtoolsTelemetry as o, isNonInteractive as p, devtoolsEnvironment as r, lastSentryEventId as s, captureDevtoolsDeprecation as t, resolveDevtoolsDsn as u, noteRan as v, findRepoRoot as w, ownVersion as x, suppressFailureLog as y };
|
|
756
|
+
export { YES as A, discoverRepoRoot as C, DRY_RUN as D, setCliName as E, flagValue as M, positionals as N, JSON_FLAG as O, RepoNotFoundError as S, cliName as T, installFailureLog as _, hasRealCaller as a, ownPackageDir as b, reportDevtoolsError as c, hasYes as d, isNoEnv as f, stripTierFlag as g, stripNoEnvFlag as h, devtoolsTelemetryEnabled as i, createCatalog as j, SCOPES as k, reportDevtoolsFailure as l, setNoEnv as m, captureDevtoolsError as n, initDevtoolsTelemetry as o, isNonInteractive as p, devtoolsEnvironment as r, lastSentryEventId as s, captureDevtoolsDeprecation as t, resolveDevtoolsDsn as u, noteRan as v, findRepoRoot as w, ownVersion as x, suppressFailureLog as y };
|
package/dist/telemetry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as hasRealCaller, c as reportDevtoolsError, i as devtoolsTelemetryEnabled, l as reportDevtoolsFailure, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, s as lastSentryEventId, t as captureDevtoolsDeprecation, u as resolveDevtoolsDsn } from "./telemetry-
|
|
1
|
+
import { a as hasRealCaller, c as reportDevtoolsError, i as devtoolsTelemetryEnabled, l as reportDevtoolsFailure, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, s as lastSentryEventId, t as captureDevtoolsDeprecation, u as resolveDevtoolsDsn } from "./telemetry-RNK5Wu74.js";
|
|
2
2
|
export { captureDevtoolsDeprecation, captureDevtoolsError, devtoolsEnvironment, devtoolsTelemetryEnabled, hasRealCaller, initDevtoolsTelemetry, lastSentryEventId, reportDevtoolsError, reportDevtoolsFailure, resolveDevtoolsDsn };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as reportDevtoolsError, p as isNonInteractive, y as suppressFailureLog } from "./telemetry-
|
|
1
|
+
import { c as reportDevtoolsError, p as isNonInteractive, y as suppressFailureLog } from "./telemetry-RNK5Wu74.js";
|
|
2
2
|
import { cancel, isCancel, log, note } from "@clack/prompts";
|
|
3
3
|
//#region ../cli-core/src/ui.ts
|
|
4
4
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devdogsuga/backstage",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Officer and production CLI for DevDogsUGA: deploys, env sync with Bitwarden and GitHub, the migration planner role, club graphics and QR codes, GitHub rulesets and settings, and the newsletter. Ships built JS; run it anywhere with `pnpm dlx @devdogsuga/backstage` (no checkout needed to start; commands that read a checkout say so).",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"typescript": "^6.0.3",
|
|
42
42
|
"zod": "4.4.3",
|
|
43
43
|
"@devdogsuga/brand": "0.1.6",
|
|
44
|
-
"@devdogsuga/telemetry": "0.1.4",
|
|
45
44
|
"@devdogsuga/events": "0.1.7",
|
|
46
|
-
"@devdogsuga/newsletter": "0.1.
|
|
45
|
+
"@devdogsuga/newsletter": "0.1.13",
|
|
46
|
+
"@devdogsuga/telemetry": "0.1.4"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@devdogsuga/db": "*",
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
"tsdown": "^0.23.0",
|
|
66
66
|
"vitest": "^4.1.11",
|
|
67
67
|
"@devdogsuga/cli-core": "0.0.0",
|
|
68
|
-
"@devdogsuga/config": "0.1.2",
|
|
69
68
|
"@devdogsuga/db": "0.1.3",
|
|
70
|
-
"@devdogsuga/env": "0.1.5"
|
|
69
|
+
"@devdogsuga/env": "0.1.5",
|
|
70
|
+
"@devdogsuga/config": "0.1.2"
|
|
71
71
|
},
|
|
72
72
|
"scripts": {
|
|
73
73
|
"build": "tsdown && node scripts/write-build-info.mjs && node ../../scripts/check-bundle-imports.mjs",
|
package/dist/args-Cjr_Iqts.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
//#region ../cli-core/src/args.ts
|
|
2
|
-
/**
|
|
3
|
-
* Positional arguments, with flag values excluded.
|
|
4
|
-
*
|
|
5
|
-
* Its own module because of one bug it prevents. The first positional is the
|
|
6
|
-
* subcommand, and `pull`, `push` and `audit` do very different things to live
|
|
7
|
-
* credentials. A naive `filter((a) => !a.startsWith("--"))` reads a flag's
|
|
8
|
-
* VALUE as a positional, so `env --file notes.env audit` fails loudly:
|
|
9
|
-
* `notes.env` is not a subcommand and the command refuses. The quiet version
|
|
10
|
-
* is the one that matters:
|
|
11
|
-
*
|
|
12
|
-
* env --file push audit
|
|
13
|
-
*
|
|
14
|
-
* which runs `push`, writing to Bitwarden and GitHub, when the caller asked
|
|
15
|
-
* for `audit`, which writes nothing at all.
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* Flags that consume the token after them.
|
|
19
|
-
*/
|
|
20
|
-
const VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
21
|
-
"--access-token",
|
|
22
|
-
"--format",
|
|
23
|
-
"--out",
|
|
24
|
-
"--version",
|
|
25
|
-
"--app",
|
|
26
|
-
"--apps",
|
|
27
|
-
"--base-url",
|
|
28
|
-
"--file",
|
|
29
|
-
"--source",
|
|
30
|
-
"--target",
|
|
31
|
-
"--tier",
|
|
32
|
-
"--cron",
|
|
33
|
-
"--workflow",
|
|
34
|
-
"--params",
|
|
35
|
-
"--port",
|
|
36
|
-
"--preview-url",
|
|
37
|
-
"--db-url",
|
|
38
|
-
"--user",
|
|
39
|
-
"--filter",
|
|
40
|
-
"--shell"
|
|
41
|
-
]);
|
|
42
|
-
function positionals(argv) {
|
|
43
|
-
const found = [];
|
|
44
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
45
|
-
const arg = argv[i];
|
|
46
|
-
if (!arg.startsWith("-")) {
|
|
47
|
-
found.push(arg);
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
const next = argv[i + 1];
|
|
51
|
-
if (VALUE_FLAGS.has(arg) && next !== void 0 && !next.startsWith("-")) i += 1;
|
|
52
|
-
}
|
|
53
|
-
return found;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* The value after `flag`, or `undefined` when the flag is absent or is
|
|
57
|
-
* followed by another flag instead of a value.
|
|
58
|
-
*/
|
|
59
|
-
function flagValue(rest, flag) {
|
|
60
|
-
const index = rest.indexOf(flag);
|
|
61
|
-
if (index === -1) return void 0;
|
|
62
|
-
const value = rest[index + 1];
|
|
63
|
-
return value && !value.startsWith("--") ? value : void 0;
|
|
64
|
-
}
|
|
65
|
-
//#endregion
|
|
66
|
-
export { positionals as n, flagValue as t };
|
package/dist/client-A6pJcxSE.js
DELETED