@greatwait/cli 0.1.0-alpha.3 → 0.1.0-alpha.5
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 +1 -1
- package/dist/args.d.ts +2 -2
- package/dist/args.js +33 -16
- package/dist/catalog.d.ts +196 -0
- package/dist/catalog.js +1521 -0
- package/dist/cli.d.ts +11 -2
- package/dist/cli.js +45 -32
- package/dist/commands.d.ts +33 -1
- package/dist/commands.js +207 -148
- package/dist/confirm.d.ts +33 -0
- package/dist/confirm.js +17 -0
- package/dist/exit.d.ts +24 -2
- package/dist/exit.js +44 -2
- package/dist/gw.d.ts +2 -0
- package/dist/gw.js +15 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/journey.d.ts +2 -2
- package/dist/journey.js +20 -4
- package/dist/main.js +6 -16
- package/dist/node-runtime.d.ts +15 -1
- package/dist/node-runtime.js +32 -2
- package/dist/oauth.d.ts +1 -1
- package/dist/oauth.js +16 -16
- package/dist/operate.d.ts +39 -0
- package/dist/operate.js +1558 -0
- package/dist/remediation.d.ts +35 -0
- package/dist/remediation.js +81 -0
- package/dist/runtime.d.ts +21 -1
- package/dist/session.js +5 -5
- package/dist/start.d.ts +15 -0
- package/dist/start.js +26 -0
- package/dist/support.d.ts +129 -0
- package/dist/support.js +261 -0
- package/package.json +6 -5
package/dist/cli.d.ts
CHANGED
|
@@ -9,6 +9,15 @@ import { type CliRuntime } from "./runtime.js";
|
|
|
9
9
|
* lets a test construct one. `main.ts` is the only file that knows there is a
|
|
10
10
|
* process at all.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The overview, rendered from the catalog rather than kept beside it.
|
|
14
|
+
*
|
|
15
|
+
* **It was a string literal, and by the end of this story it would have been
|
|
16
|
+
* wrong.** Thirty-odd commands maintained in a template beside thirty-odd
|
|
17
|
+
* declarations is a list that drifts on the first rename, and the drift is
|
|
18
|
+
* invisible: nothing executes a usage string. Generating it means a command
|
|
19
|
+
* that exists appears here, and one that does not, cannot.
|
|
20
|
+
*/
|
|
21
|
+
declare function usage(programName: string): string;
|
|
13
22
|
export declare function run(runtime: CliRuntime): Promise<number>;
|
|
14
|
-
export {
|
|
23
|
+
export { usage };
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { GreatwaitClientError } from "@greatwait/api-client";
|
|
2
2
|
import { parseArguments } from "./args.js";
|
|
3
|
+
import { COMMAND_CATALOG, commandHelp, overview } from "./catalog.js";
|
|
3
4
|
import { COMMANDS } from "./commands.js";
|
|
4
5
|
import { UnsafeConfigError } from "./config.js";
|
|
5
6
|
import { EXIT_CLASSES, classifyStatus } from "./exit.js";
|
|
6
7
|
import { renderFailure, renderResult } from "./output.js";
|
|
8
|
+
import { remediationFor } from "./remediation.js";
|
|
7
9
|
import { CliError, InterruptedError } from "./runtime.js";
|
|
8
10
|
/**
|
|
9
11
|
* One run of `greatwait`, from argv to an exit code.
|
|
@@ -15,26 +17,25 @@ import { CliError, InterruptedError } from "./runtime.js";
|
|
|
15
17
|
* lets a test construct one. `main.ts` is the only file that knows there is a
|
|
16
18
|
* process at all.
|
|
17
19
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
/**
|
|
21
|
+
* The overview, rendered from the catalog rather than kept beside it.
|
|
22
|
+
*
|
|
23
|
+
* **It was a string literal, and by the end of this story it would have been
|
|
24
|
+
* wrong.** Thirty-odd commands maintained in a template beside thirty-odd
|
|
25
|
+
* declarations is a list that drifts on the first rename, and the drift is
|
|
26
|
+
* invisible: nothing executes a usage string. Generating it means a command
|
|
27
|
+
* that exists appears here, and one that does not, cannot.
|
|
28
|
+
*/
|
|
29
|
+
function usage(programName) {
|
|
30
|
+
return `${programName} — the GreatWait command line
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
greatwait destinations disable <destination>
|
|
29
|
-
greatwait schedules create --endpoint <destination> (--in 30s | --at <instant>) [--data <json>]
|
|
30
|
-
greatwait schedules read <schedule>
|
|
31
|
-
greatwait occurrences wait <schedule> <occurrence>
|
|
32
|
-
greatwait attempts list <schedule> <occurrence>
|
|
32
|
+
${overview()}
|
|
33
33
|
|
|
34
34
|
--json machine-readable output, versioned
|
|
35
|
-
--help this text
|
|
35
|
+
--help this text, or the help for a command that precedes it
|
|
36
36
|
|
|
37
|
-
Run
|
|
37
|
+
Run \`${programName} journey\` for the published first-value sequence.`;
|
|
38
|
+
}
|
|
38
39
|
/**
|
|
39
40
|
* Which command a set of leading words names.
|
|
40
41
|
*
|
|
@@ -71,7 +72,7 @@ function problemOf(error) {
|
|
|
71
72
|
* them, and a client that replaced those with its own wording would be
|
|
72
73
|
* maintaining a second copy of every refusal the service can produce.
|
|
73
74
|
*/
|
|
74
|
-
function classify(error) {
|
|
75
|
+
function classify(error, programName) {
|
|
75
76
|
if (error instanceof InterruptedError) {
|
|
76
77
|
return {
|
|
77
78
|
exit: "interrupted",
|
|
@@ -101,15 +102,17 @@ function classify(error) {
|
|
|
101
102
|
return {
|
|
102
103
|
exit: classifyStatus(error.status, problem?.code),
|
|
103
104
|
human: problem === undefined
|
|
104
|
-
?
|
|
105
|
+
? error.status === 0
|
|
106
|
+
? "The service could not be reached."
|
|
107
|
+
: `The service answered ${String(error.status)}.`
|
|
105
108
|
: `${problem.title} (${problem.code})`,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
// **Every published code, not the two that were spelled out here.** This
|
|
110
|
+
// was a two-branch conditional naming `authentication_required` and
|
|
111
|
+
// `scope_missing`, so a `credential_revoked` — the same 401, and the one
|
|
112
|
+
// that means sign in again — arrived with the right exit number and no
|
|
113
|
+
// idea what to do about it. The record it now reads is exhaustive by
|
|
114
|
+
// type, so the next code the contract publishes cannot arrive silent.
|
|
115
|
+
nextMove: remediationFor(problem, error.retryable, programName),
|
|
113
116
|
problem,
|
|
114
117
|
};
|
|
115
118
|
}
|
|
@@ -125,17 +128,27 @@ function classify(error) {
|
|
|
125
128
|
}
|
|
126
129
|
export async function run(runtime) {
|
|
127
130
|
let json = false;
|
|
128
|
-
let command =
|
|
131
|
+
let command = runtime.programName;
|
|
129
132
|
try {
|
|
130
|
-
const args = parseArguments(runtime.argv, COMMAND_WORDS);
|
|
133
|
+
const args = parseArguments(runtime.argv, COMMAND_WORDS, runtime.programName);
|
|
131
134
|
json = args.booleans.has("--json");
|
|
135
|
+
const selected = select(args.command);
|
|
132
136
|
if (args.booleans.has("--help") || args.command.length === 0) {
|
|
133
|
-
|
|
137
|
+
// **The help for the command that was named, where one was.** `greatwait
|
|
138
|
+
// schedules replace --help` printing the whole overview is the answer to
|
|
139
|
+
// a question nobody asked: somebody who has typed two words wants to know
|
|
140
|
+
// what those two words take, and the alternative is reading a thirty-line
|
|
141
|
+
// list to find the same line they started from.
|
|
142
|
+
const declaration = selected === undefined
|
|
143
|
+
? undefined
|
|
144
|
+
: COMMAND_CATALOG.find((candidate) => candidate.words === selected.key);
|
|
145
|
+
runtime.stdout(`${declaration === undefined
|
|
146
|
+
? usage(runtime.programName)
|
|
147
|
+
: commandHelp(declaration, runtime.programName)}\n`);
|
|
134
148
|
return EXIT_CLASSES.ok;
|
|
135
149
|
}
|
|
136
|
-
const selected = select(args.command);
|
|
137
150
|
if (selected === undefined) {
|
|
138
|
-
throw new CliError(`unknown command ${args.command.join(" ")}`, "usage",
|
|
151
|
+
throw new CliError(`unknown command ${args.command.join(" ")}`, "usage", `Run ${runtime.programName} --help for the list.`);
|
|
139
152
|
}
|
|
140
153
|
command = selected.key;
|
|
141
154
|
const result = await COMMANDS[selected.key](runtime, { ...args, command: selected.rest });
|
|
@@ -156,7 +169,7 @@ export async function run(runtime) {
|
|
|
156
169
|
return EXIT_CLASSES[result.exit ?? "ok"];
|
|
157
170
|
}
|
|
158
171
|
catch (error) {
|
|
159
|
-
const classified = classify(error);
|
|
172
|
+
const classified = classify(error, runtime.programName);
|
|
160
173
|
// **A `--json` failure goes to standard output, and a plain one to standard
|
|
161
174
|
// error.** Found by the staging browser suite, which could not parse a
|
|
162
175
|
// refusal because Node had written a deprecation warning to the same stream
|
|
@@ -188,4 +201,4 @@ export async function run(runtime) {
|
|
|
188
201
|
return EXIT_CLASSES[classified.exit];
|
|
189
202
|
}
|
|
190
203
|
}
|
|
191
|
-
export {
|
|
204
|
+
export { usage };
|
package/dist/commands.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ import { type ParsedArguments } from "./args.js";
|
|
|
2
2
|
import { type StoredCredential } from "./config.js";
|
|
3
3
|
import { type CommandResult } from "./output.js";
|
|
4
4
|
import { type CliRuntime } from "./runtime.js";
|
|
5
|
+
/**
|
|
6
|
+
* The commands, each bounded and each useful on its own.
|
|
7
|
+
*
|
|
8
|
+
* **There is no `greatwait demo`.** The project specification excludes one by
|
|
9
|
+
* name, and the reason is that a single command whose success proves everything
|
|
10
|
+
* teaches nothing: somebody who ran it has watched a callback arrive and still
|
|
11
|
+
* cannot make a second one. Every command here is a step somebody would take
|
|
12
|
+
* again on their own work, and together they are the published first-value
|
|
13
|
+
* journey — which `greatwait journey` renders rather than restates.
|
|
14
|
+
*/
|
|
5
15
|
type Command = (runtime: CliRuntime, args: ParsedArguments) => Promise<CommandResult>;
|
|
6
16
|
interface CredentialContextView {
|
|
7
17
|
readonly environmentKind: string;
|
|
@@ -9,6 +19,28 @@ interface CredentialContextView {
|
|
|
9
19
|
readonly project: string;
|
|
10
20
|
readonly scopes: readonly string[];
|
|
11
21
|
}
|
|
12
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Every implementation, keyed by the words that select it.
|
|
24
|
+
*
|
|
25
|
+
* Not the dispatch table: that is built from the catalog below, so a command
|
|
26
|
+
* cannot be documented without existing and cannot exist without being
|
|
27
|
+
* documented. This half is the functions, and `packages/cli/src/catalog.ts` is
|
|
28
|
+
* what says they are the right set.
|
|
29
|
+
*/
|
|
30
|
+
declare const IMPLEMENTATIONS: Readonly<Record<string, Command>>;
|
|
31
|
+
/**
|
|
32
|
+
* The dispatch table, assembled from the catalog.
|
|
33
|
+
*
|
|
34
|
+
* **A declaration with no function raises here, at import.** The alternative
|
|
35
|
+
* was a test that compared two lists, which is a check the published reference
|
|
36
|
+
* page can still contradict: the page is generated from the catalog, so a
|
|
37
|
+
* command documented and never implemented would ship as a promise the
|
|
38
|
+
* executable does not keep. Raising means the binary does not start.
|
|
39
|
+
*
|
|
40
|
+
* The other direction is a test rather than a raise — an implementation nobody
|
|
41
|
+
* declared is unreachable rather than dangerous, and `commands.test.ts` names
|
|
42
|
+
* it.
|
|
43
|
+
*/
|
|
13
44
|
export declare const COMMANDS: Readonly<Record<string, Command>>;
|
|
45
|
+
export { IMPLEMENTATIONS };
|
|
14
46
|
export type { Command, CredentialContextView, StoredCredential };
|