@prospera/eprospera-cli 0.1.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +140 -0
- package/bin/eprospera.js +3 -0
- package/cli.ocs.yaml +406 -0
- package/dist/bundle/eprospera.mjs +28349 -0
- package/dist/completions/eprospera.bash +7 -0
- package/dist/completions/eprospera.fish +2 -0
- package/dist/completions/eprospera.ps1 +7 -0
- package/dist/completions/eprospera.zsh +4 -0
- package/dist/src/api/client.d.ts +29 -0
- package/dist/src/api/client.js +131 -0
- package/dist/src/api/errors.d.ts +11 -0
- package/dist/src/api/errors.js +125 -0
- package/dist/src/api/generated.d.ts +1159 -0
- package/dist/src/api/generated.js +6 -0
- package/dist/src/commands/application/create.d.ts +5 -0
- package/dist/src/commands/application/create.js +62 -0
- package/dist/src/commands/application/get.d.ts +2 -0
- package/dist/src/commands/application/get.js +11 -0
- package/dist/src/commands/application/list.d.ts +2 -0
- package/dist/src/commands/application/list.js +8 -0
- package/dist/src/commands/application/pay.d.ts +5 -0
- package/dist/src/commands/application/pay.js +27 -0
- package/dist/src/commands/application/watch.d.ts +7 -0
- package/dist/src/commands/application/watch.js +42 -0
- package/dist/src/commands/auth/login.d.ts +7 -0
- package/dist/src/commands/auth/login.js +60 -0
- package/dist/src/commands/auth/logout.d.ts +2 -0
- package/dist/src/commands/auth/logout.js +14 -0
- package/dist/src/commands/auth/whoami.d.ts +2 -0
- package/dist/src/commands/auth/whoami.js +19 -0
- package/dist/src/commands/completion.d.ts +3 -0
- package/dist/src/commands/completion.js +80 -0
- package/dist/src/commands/config/get.d.ts +2 -0
- package/dist/src/commands/config/get.js +9 -0
- package/dist/src/commands/config/list.d.ts +2 -0
- package/dist/src/commands/config/list.js +7 -0
- package/dist/src/commands/config/set.d.ts +2 -0
- package/dist/src/commands/config/set.js +9 -0
- package/dist/src/commands/config/unset.d.ts +2 -0
- package/dist/src/commands/config/unset.js +9 -0
- package/dist/src/commands/entity/documents.d.ts +2 -0
- package/dist/src/commands/entity/documents.js +11 -0
- package/dist/src/commands/entity/get.d.ts +2 -0
- package/dist/src/commands/entity/get.js +11 -0
- package/dist/src/commands/entity/search.d.ts +2 -0
- package/dist/src/commands/entity/search.js +17 -0
- package/dist/src/commands/entity/verify.d.ts +2 -0
- package/dist/src/commands/entity/verify.js +9 -0
- package/dist/src/commands/files.d.ts +2 -0
- package/dist/src/commands/files.js +24 -0
- package/dist/src/commands/me/id-verification.d.ts +2 -0
- package/dist/src/commands/me/id-verification.js +8 -0
- package/dist/src/commands/me/profile.d.ts +2 -0
- package/dist/src/commands/me/profile.js +8 -0
- package/dist/src/commands/me/residency.d.ts +2 -0
- package/dist/src/commands/me/residency.js +8 -0
- package/dist/src/commands/runtime.d.ts +56 -0
- package/dist/src/commands/runtime.js +101 -0
- package/dist/src/commands/schema.d.ts +2 -0
- package/dist/src/commands/schema.js +13 -0
- package/dist/src/config/store.d.ts +14 -0
- package/dist/src/config/store.js +99 -0
- package/dist/src/credentials/resolve.d.ts +15 -0
- package/dist/src/credentials/resolve.js +63 -0
- package/dist/src/credentials/store.d.ts +22 -0
- package/dist/src/credentials/store.js +184 -0
- package/dist/src/credentials/types.d.ts +15 -0
- package/dist/src/credentials/types.js +5 -0
- package/dist/src/errors.d.ts +39 -0
- package/dist/src/errors.js +38 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +244 -0
- package/dist/src/output/format.d.ts +27 -0
- package/dist/src/output/format.js +126 -0
- package/dist/src/output/table.d.ts +5 -0
- package/dist/src/output/table.js +124 -0
- package/dist/src/output/tty.d.ts +26 -0
- package/dist/src/output/tty.js +41 -0
- package/dist/src/polling/watch.d.ts +19 -0
- package/dist/src/polling/watch.js +86 -0
- package/dist/src/prompts/confirm.d.ts +2 -0
- package/dist/src/prompts/confirm.js +19 -0
- package/dist/src/scopes/check.d.ts +17 -0
- package/dist/src/scopes/check.js +64 -0
- package/dist/src/scopes/map.d.ts +81 -0
- package/dist/src/scopes/map.js +76 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +35 -0
- package/package.json +70 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { Command, CommanderError } from "commander";
|
|
4
|
+
import { runApplicationCreate } from "./commands/application/create.js";
|
|
5
|
+
import { runApplicationGet } from "./commands/application/get.js";
|
|
6
|
+
import { runApplicationList } from "./commands/application/list.js";
|
|
7
|
+
import { runApplicationPay } from "./commands/application/pay.js";
|
|
8
|
+
import { runApplicationWatch } from "./commands/application/watch.js";
|
|
9
|
+
import { runAuthLogin } from "./commands/auth/login.js";
|
|
10
|
+
import { runAuthLogout } from "./commands/auth/logout.js";
|
|
11
|
+
import { runAuthWhoami } from "./commands/auth/whoami.js";
|
|
12
|
+
import { runCompletion } from "./commands/completion.js";
|
|
13
|
+
import { runConfigGet } from "./commands/config/get.js";
|
|
14
|
+
import { runConfigList } from "./commands/config/list.js";
|
|
15
|
+
import { runConfigSet } from "./commands/config/set.js";
|
|
16
|
+
import { runConfigUnset } from "./commands/config/unset.js";
|
|
17
|
+
import { runEntityDocuments } from "./commands/entity/documents.js";
|
|
18
|
+
import { runEntityGet } from "./commands/entity/get.js";
|
|
19
|
+
import { runEntitySearch } from "./commands/entity/search.js";
|
|
20
|
+
import { runEntityVerify } from "./commands/entity/verify.js";
|
|
21
|
+
import { runMeIdVerification } from "./commands/me/id-verification.js";
|
|
22
|
+
import { runMeProfile } from "./commands/me/profile.js";
|
|
23
|
+
import { runMeResidency } from "./commands/me/residency.js";
|
|
24
|
+
import { runSchema } from "./commands/schema.js";
|
|
25
|
+
import { ExitCodes, ExitError } from "./errors.js";
|
|
26
|
+
import { printError } from "./output/format.js";
|
|
27
|
+
import { VERSION } from "./version.js";
|
|
28
|
+
export function createProgram(deps = {}) {
|
|
29
|
+
const program = new Command();
|
|
30
|
+
const stdout = deps.streams?.stdout ?? process.stdout;
|
|
31
|
+
const stderr = deps.streams?.stderr ?? process.stderr;
|
|
32
|
+
program
|
|
33
|
+
.name("eprospera")
|
|
34
|
+
.description("Command-line wrapper over the e-Prospera public API.")
|
|
35
|
+
.version(VERSION)
|
|
36
|
+
.showHelpAfterError()
|
|
37
|
+
.exitOverride()
|
|
38
|
+
.configureOutput({
|
|
39
|
+
writeOut: (value) => stdout.write(value),
|
|
40
|
+
writeErr: (value) => stderr.write(value),
|
|
41
|
+
})
|
|
42
|
+
.option("--json", "Pretty-print JSON to stdout and suppress incidental output.")
|
|
43
|
+
.option("--raw", "Print compact single-line JSON to stdout.")
|
|
44
|
+
.option("--fields <keys>", "Restrict output keys for read commands.")
|
|
45
|
+
.option("--quiet", "Suppress incidental human output.")
|
|
46
|
+
.option("-y, --yes", "Skip confirmation prompts.")
|
|
47
|
+
.option("--api-key <value>", "Use this bearer token instead of environment or stored credentials.")
|
|
48
|
+
.option("--dry-run", "Validate locally and print the request that would be sent.")
|
|
49
|
+
.option("--no-auto-json", "Disable automatic JSON output when stdout is not a TTY.")
|
|
50
|
+
.option("--skip-scope-check", "Skip cached local Agent Key scope preflight.");
|
|
51
|
+
const entity = program
|
|
52
|
+
.command("entity")
|
|
53
|
+
.description("Verify, search, inspect, and fetch documents.");
|
|
54
|
+
entity
|
|
55
|
+
.command("verify")
|
|
56
|
+
.argument("<rpn>")
|
|
57
|
+
.action(function (rpn) {
|
|
58
|
+
return runApplicationSafe(() => runEntityVerify(rpn, globals(this), deps));
|
|
59
|
+
});
|
|
60
|
+
entity
|
|
61
|
+
.command("search")
|
|
62
|
+
.argument("<query>")
|
|
63
|
+
.action(function (query) {
|
|
64
|
+
return runApplicationSafe(() => runEntitySearch(query, globals(this), deps));
|
|
65
|
+
});
|
|
66
|
+
entity
|
|
67
|
+
.command("get")
|
|
68
|
+
.argument("<id>")
|
|
69
|
+
.action(function (id) {
|
|
70
|
+
return runApplicationSafe(() => runEntityGet(id, globals(this), deps));
|
|
71
|
+
});
|
|
72
|
+
entity
|
|
73
|
+
.command("documents")
|
|
74
|
+
.argument("<id>")
|
|
75
|
+
.action(function (id) {
|
|
76
|
+
return runApplicationSafe(() => runEntityDocuments(id, globals(this), deps));
|
|
77
|
+
});
|
|
78
|
+
const application = program
|
|
79
|
+
.command("application")
|
|
80
|
+
.description("Create, pay, list, inspect, and watch applications.");
|
|
81
|
+
application.command("list").action(function () {
|
|
82
|
+
return runApplicationSafe(() => runApplicationList(globals(this), deps));
|
|
83
|
+
});
|
|
84
|
+
application
|
|
85
|
+
.command("create")
|
|
86
|
+
.requiredOption("--file <path>", "Read the application request body from a JSON file.")
|
|
87
|
+
.action(function () {
|
|
88
|
+
return runApplicationSafe(() => runApplicationCreate(this.opts(), globals(this), deps));
|
|
89
|
+
});
|
|
90
|
+
application
|
|
91
|
+
.command("get")
|
|
92
|
+
.argument("<id>")
|
|
93
|
+
.action(function (id) {
|
|
94
|
+
return runApplicationSafe(() => runApplicationGet(id, globals(this), deps));
|
|
95
|
+
});
|
|
96
|
+
application
|
|
97
|
+
.command("pay")
|
|
98
|
+
.argument("<id>")
|
|
99
|
+
.requiredOption("--coupon <code>", "Coupon code to apply.")
|
|
100
|
+
.action(function (id) {
|
|
101
|
+
return runApplicationSafe(() => runApplicationPay(id, this.opts(), globals(this), deps));
|
|
102
|
+
});
|
|
103
|
+
application
|
|
104
|
+
.command("watch")
|
|
105
|
+
.argument("<id>")
|
|
106
|
+
.option("--timeout <duration>", "Hard polling timeout.")
|
|
107
|
+
.option("--initial-interval <duration>", "Polling interval before backoff.")
|
|
108
|
+
.option("--max-interval <duration>", "Maximum polling interval after backoff.")
|
|
109
|
+
.action(function (id) {
|
|
110
|
+
return runApplicationSafe(() => runApplicationWatch(id, this.opts(), globals(this), deps));
|
|
111
|
+
});
|
|
112
|
+
const me = program.command("me").description("Read profile data for the credential owner.");
|
|
113
|
+
me.command("profile").action(function () {
|
|
114
|
+
return runApplicationSafe(() => runMeProfile(globals(this), deps));
|
|
115
|
+
});
|
|
116
|
+
me.command("residency").action(function () {
|
|
117
|
+
return runApplicationSafe(() => runMeResidency(globals(this), deps));
|
|
118
|
+
});
|
|
119
|
+
me.command("id-verification").action(function () {
|
|
120
|
+
return runApplicationSafe(() => runMeIdVerification(globals(this), deps));
|
|
121
|
+
});
|
|
122
|
+
const auth = program
|
|
123
|
+
.command("auth")
|
|
124
|
+
.description("Log in, inspect, and remove local credentials.");
|
|
125
|
+
auth
|
|
126
|
+
.command("login")
|
|
127
|
+
.option("--agent-key", "Prompt for an ak- Agent Key and validate it.")
|
|
128
|
+
.option("--standard-key", "Prompt for an sk- standard API key.")
|
|
129
|
+
.option("--scopes <csv>", "Comma-separated Agent Key scopes to cache.")
|
|
130
|
+
.action(function () {
|
|
131
|
+
return runApplicationSafe(() => runAuthLogin(this.opts(), globals(this), deps));
|
|
132
|
+
});
|
|
133
|
+
auth.command("whoami").action(function () {
|
|
134
|
+
return runApplicationSafe(() => runAuthWhoami(globals(this), deps));
|
|
135
|
+
});
|
|
136
|
+
auth.command("logout").action(function () {
|
|
137
|
+
return runApplicationSafe(() => runAuthLogout(globals(this), deps));
|
|
138
|
+
});
|
|
139
|
+
const config = program.command("config").description("Read and write local CLI configuration.");
|
|
140
|
+
config
|
|
141
|
+
.command("get")
|
|
142
|
+
.argument("<key>")
|
|
143
|
+
.action(function (key) {
|
|
144
|
+
return runApplicationSafe(() => runConfigGet(key, globals(this), deps));
|
|
145
|
+
});
|
|
146
|
+
config
|
|
147
|
+
.command("set")
|
|
148
|
+
.argument("<key>")
|
|
149
|
+
.argument("<value>")
|
|
150
|
+
.action(function (key, value) {
|
|
151
|
+
return runApplicationSafe(() => runConfigSet(key, value, globals(this), deps));
|
|
152
|
+
});
|
|
153
|
+
config.command("list").action(function () {
|
|
154
|
+
return runApplicationSafe(() => runConfigList(globals(this), deps));
|
|
155
|
+
});
|
|
156
|
+
config
|
|
157
|
+
.command("unset")
|
|
158
|
+
.argument("<key>")
|
|
159
|
+
.action(function (key) {
|
|
160
|
+
return runApplicationSafe(() => runConfigUnset(key, globals(this), deps));
|
|
161
|
+
});
|
|
162
|
+
const completion = program
|
|
163
|
+
.command("completion")
|
|
164
|
+
.description("Generate shell completion scripts.");
|
|
165
|
+
for (const shell of ["bash", "zsh", "fish"]) {
|
|
166
|
+
completion.command(shell).action(function () {
|
|
167
|
+
return runApplicationSafe(() => runCompletion(shell, globals(this), deps));
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
completion.command("powershell").action(function () {
|
|
171
|
+
return runApplicationSafe(() => runCompletion("powershell", globals(this), deps));
|
|
172
|
+
});
|
|
173
|
+
program
|
|
174
|
+
.command("schema")
|
|
175
|
+
.description("Print this OpenCLI document to stdout.")
|
|
176
|
+
.action(function () {
|
|
177
|
+
return runApplicationSafe(() => runSchema(globals(this), deps));
|
|
178
|
+
});
|
|
179
|
+
return program;
|
|
180
|
+
}
|
|
181
|
+
export async function runCli(argv = process.argv, deps = {}) {
|
|
182
|
+
const program = createProgram(deps);
|
|
183
|
+
try {
|
|
184
|
+
await program.parseAsync([...argv], { from: "node" });
|
|
185
|
+
return ExitCodes.Success;
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
if (error instanceof CommanderError && error.exitCode === ExitCodes.Success) {
|
|
189
|
+
return ExitCodes.Success;
|
|
190
|
+
}
|
|
191
|
+
const globalsFromArgv = argvGlobals(argv);
|
|
192
|
+
if (error instanceof CommanderError) {
|
|
193
|
+
const result = printError(new ExitError({
|
|
194
|
+
code: "INVALID_USAGE",
|
|
195
|
+
message: error.message,
|
|
196
|
+
exitCode: ExitCodes.Usage,
|
|
197
|
+
cause: error,
|
|
198
|
+
}), {
|
|
199
|
+
json: globalsFromArgv.json,
|
|
200
|
+
raw: globalsFromArgv.raw,
|
|
201
|
+
noAutoJson: globalsFromArgv.autoJson === false,
|
|
202
|
+
streams: deps.streams,
|
|
203
|
+
env: deps.env,
|
|
204
|
+
});
|
|
205
|
+
return result.exitCode;
|
|
206
|
+
}
|
|
207
|
+
const result = printError(error, {
|
|
208
|
+
json: globalsFromArgv.json,
|
|
209
|
+
raw: globalsFromArgv.raw,
|
|
210
|
+
noAutoJson: globalsFromArgv.autoJson === false,
|
|
211
|
+
streams: deps.streams,
|
|
212
|
+
env: deps.env,
|
|
213
|
+
});
|
|
214
|
+
return result.exitCode;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function globals(command) {
|
|
218
|
+
const opts = command.optsWithGlobals();
|
|
219
|
+
return {
|
|
220
|
+
json: opts.json,
|
|
221
|
+
raw: opts.raw,
|
|
222
|
+
fields: opts.fields,
|
|
223
|
+
quiet: opts.quiet,
|
|
224
|
+
yes: opts.yes,
|
|
225
|
+
apiKey: opts.apiKey,
|
|
226
|
+
dryRun: opts.dryRun,
|
|
227
|
+
autoJson: opts.autoJson,
|
|
228
|
+
skipScopeCheck: opts.skipScopeCheck,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function argvGlobals(argv) {
|
|
232
|
+
return {
|
|
233
|
+
json: argv.includes("--json"),
|
|
234
|
+
raw: argv.includes("--raw"),
|
|
235
|
+
autoJson: argv.includes("--no-auto-json") ? false : undefined,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
async function runApplicationSafe(action) {
|
|
239
|
+
await action();
|
|
240
|
+
}
|
|
241
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
242
|
+
process.exitCode = await runCli();
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ExitCode } from "../errors.js";
|
|
2
|
+
import { type TablePreset } from "./table.js";
|
|
3
|
+
import { type OutputMode, type OutputModeOptions, type TerminalLike } from "./tty.js";
|
|
4
|
+
export type OutputWriter = TerminalLike & {
|
|
5
|
+
write(chunk: string): unknown;
|
|
6
|
+
};
|
|
7
|
+
export type OutputStreams = {
|
|
8
|
+
stdin?: TerminalLike;
|
|
9
|
+
stdout?: OutputWriter;
|
|
10
|
+
stderr?: OutputWriter;
|
|
11
|
+
};
|
|
12
|
+
export type PrintOptions = OutputModeOptions & {
|
|
13
|
+
quiet?: boolean;
|
|
14
|
+
fields?: string | readonly string[];
|
|
15
|
+
table?: TablePreset;
|
|
16
|
+
schema?: unknown;
|
|
17
|
+
env?: NodeJS.ProcessEnv;
|
|
18
|
+
streams?: OutputStreams;
|
|
19
|
+
human?: (data: unknown) => string;
|
|
20
|
+
};
|
|
21
|
+
export type PrintErrorResult = {
|
|
22
|
+
exitCode: ExitCode;
|
|
23
|
+
};
|
|
24
|
+
export declare function print(data: unknown, options?: PrintOptions): OutputMode;
|
|
25
|
+
export declare function printError(error: unknown, options?: PrintOptions): PrintErrorResult;
|
|
26
|
+
export declare function parseFields(fields: string | readonly string[] | undefined): string[];
|
|
27
|
+
export declare function selectFields(data: unknown, fields: readonly string[]): unknown;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { ExitCodes, ExitError } from "../errors.js";
|
|
2
|
+
import { renderTable } from "./table.js";
|
|
3
|
+
import { resolveOutputMode, terminalCapabilities, } from "./tty.js";
|
|
4
|
+
export function print(data, options = {}) {
|
|
5
|
+
const streams = resolveStreams(options.streams);
|
|
6
|
+
const mode = resolveOutputMode(options, streams);
|
|
7
|
+
const selected = selectFields(data, parseFields(options.fields));
|
|
8
|
+
if (mode === "json") {
|
|
9
|
+
writeLine(streams.stdout, JSON.stringify(selected ?? null, null, 2));
|
|
10
|
+
return mode;
|
|
11
|
+
}
|
|
12
|
+
if (mode === "raw") {
|
|
13
|
+
writeLine(streams.stdout, JSON.stringify(selected ?? null));
|
|
14
|
+
return mode;
|
|
15
|
+
}
|
|
16
|
+
const capabilities = terminalCapabilities({ ...options, mode }, streams);
|
|
17
|
+
const rendered = options.human?.(selected) ??
|
|
18
|
+
renderTable(selected, options.table, {
|
|
19
|
+
color: capabilities.color,
|
|
20
|
+
});
|
|
21
|
+
writeLine(streams.stdout, rendered);
|
|
22
|
+
return mode;
|
|
23
|
+
}
|
|
24
|
+
export function printError(error, options = {}) {
|
|
25
|
+
const streams = resolveStreams(options.streams);
|
|
26
|
+
const mode = resolveOutputMode(options, streams);
|
|
27
|
+
const { envelope, exitCode } = errorEnvelope(error);
|
|
28
|
+
if (mode === "json") {
|
|
29
|
+
writeLine(streams.stdout, JSON.stringify(envelope, null, 2));
|
|
30
|
+
return { exitCode };
|
|
31
|
+
}
|
|
32
|
+
if (mode === "raw") {
|
|
33
|
+
writeLine(streams.stdout, JSON.stringify(envelope));
|
|
34
|
+
return { exitCode };
|
|
35
|
+
}
|
|
36
|
+
const capabilities = terminalCapabilities({ ...options, mode }, streams);
|
|
37
|
+
const prefix = capabilities.color ? "\u001b[31mError:\u001b[39m" : "Error:";
|
|
38
|
+
writeLine(streams.stderr, `${prefix} ${envelope.error.message}`);
|
|
39
|
+
return { exitCode };
|
|
40
|
+
}
|
|
41
|
+
export function parseFields(fields) {
|
|
42
|
+
if (!fields) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
const rawFields = typeof fields === "string" ? [fields] : fields;
|
|
46
|
+
const parsed = rawFields.flatMap((field) => field.split(",").map((part) => part.trim()));
|
|
47
|
+
return [...new Set(parsed.filter((field) => field.length > 0))];
|
|
48
|
+
}
|
|
49
|
+
export function selectFields(data, fields) {
|
|
50
|
+
if (fields.length === 0) {
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(data)) {
|
|
54
|
+
return data.map((item) => selectObjectFields(item, fields));
|
|
55
|
+
}
|
|
56
|
+
return selectObjectFields(data, fields);
|
|
57
|
+
}
|
|
58
|
+
function selectObjectFields(data, fields) {
|
|
59
|
+
if (!isRecord(data)) {
|
|
60
|
+
return data;
|
|
61
|
+
}
|
|
62
|
+
const output = {};
|
|
63
|
+
for (const field of fields) {
|
|
64
|
+
const path = field.split(".").filter((part) => part.length > 0);
|
|
65
|
+
const value = readPath(data, path);
|
|
66
|
+
if (value !== undefined) {
|
|
67
|
+
writePath(output, path, value);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return output;
|
|
71
|
+
}
|
|
72
|
+
function readPath(data, path) {
|
|
73
|
+
let current = data;
|
|
74
|
+
for (const part of path) {
|
|
75
|
+
if (!isRecord(current) || !(part in current)) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
current = current[part];
|
|
79
|
+
}
|
|
80
|
+
return current;
|
|
81
|
+
}
|
|
82
|
+
function writePath(output, path, value) {
|
|
83
|
+
let current = output;
|
|
84
|
+
for (const [index, part] of path.entries()) {
|
|
85
|
+
if (index === path.length - 1) {
|
|
86
|
+
current[part] = value;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const next = current[part];
|
|
90
|
+
if (!isRecord(next)) {
|
|
91
|
+
current[part] = {};
|
|
92
|
+
}
|
|
93
|
+
current = current[part];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function errorEnvelope(error) {
|
|
97
|
+
if (error instanceof ExitError) {
|
|
98
|
+
return {
|
|
99
|
+
envelope: error.toEnvelope(),
|
|
100
|
+
exitCode: error.exitCode,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
envelope: {
|
|
105
|
+
error: {
|
|
106
|
+
code: "UNEXPECTED_ERROR",
|
|
107
|
+
message: error instanceof Error ? error.message : "Unexpected error.",
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
exitCode: ExitCodes.Generic,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function resolveStreams(streams) {
|
|
114
|
+
return {
|
|
115
|
+
stdin: streams?.stdin ?? process.stdin,
|
|
116
|
+
stdout: streams?.stdout ?? process.stdout,
|
|
117
|
+
stderr: streams?.stderr ?? process.stderr,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function writeLine(writer, value) {
|
|
121
|
+
writer.write(value.endsWith("\n") ? value : `${value}\n`);
|
|
122
|
+
}
|
|
123
|
+
function isRecord(value) {
|
|
124
|
+
return typeof value === "object" && value !== null;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import Table from "cli-table3";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
const PRESET_COLUMNS = {
|
|
4
|
+
entities: [
|
|
5
|
+
{ key: "id", label: "ID" },
|
|
6
|
+
{ key: "name", label: "Name" },
|
|
7
|
+
{ key: "type", label: "Type" },
|
|
8
|
+
{ key: "residentPermitNumber", label: "RPN" },
|
|
9
|
+
],
|
|
10
|
+
applications: [
|
|
11
|
+
{ key: "id", label: "ID" },
|
|
12
|
+
{ key: "statusId", label: "Status" },
|
|
13
|
+
{ key: "legalEntityId", label: "Legal Entity" },
|
|
14
|
+
{ key: "createdAt", label: "Created" },
|
|
15
|
+
],
|
|
16
|
+
documents: [
|
|
17
|
+
{ key: "id", label: "ID" },
|
|
18
|
+
{ key: "name", label: "Name" },
|
|
19
|
+
{ key: "version", label: "Version" },
|
|
20
|
+
{ key: "createdAt", label: "Created" },
|
|
21
|
+
{ key: "fileUrl", label: "URL" },
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
export function renderTable(data, preset, options = {}) {
|
|
25
|
+
const unwrapped = unwrapData(data);
|
|
26
|
+
if (preset) {
|
|
27
|
+
return renderRows(toRows(unwrapped), PRESET_COLUMNS[preset], options);
|
|
28
|
+
}
|
|
29
|
+
if (Array.isArray(unwrapped)) {
|
|
30
|
+
return renderRows(unwrapped, inferColumns(unwrapped), options);
|
|
31
|
+
}
|
|
32
|
+
if (isRecord(unwrapped)) {
|
|
33
|
+
return renderKeyValueTable(unwrapped, options);
|
|
34
|
+
}
|
|
35
|
+
return formatCell(unwrapped);
|
|
36
|
+
}
|
|
37
|
+
function renderRows(rows, columns, options) {
|
|
38
|
+
if (rows.length === 0) {
|
|
39
|
+
return "(empty)";
|
|
40
|
+
}
|
|
41
|
+
const table = new Table({
|
|
42
|
+
head: columns.map((column) => formatHeader(column.label, options.color)),
|
|
43
|
+
wordWrap: true,
|
|
44
|
+
});
|
|
45
|
+
for (const row of rows) {
|
|
46
|
+
table.push(columns.map((column) => formatCell(readPath(row, column.key))));
|
|
47
|
+
}
|
|
48
|
+
return table.toString();
|
|
49
|
+
}
|
|
50
|
+
function renderKeyValueTable(data, options) {
|
|
51
|
+
const table = new Table({
|
|
52
|
+
head: [formatHeader("Key", options.color), formatHeader("Value", options.color)],
|
|
53
|
+
wordWrap: true,
|
|
54
|
+
});
|
|
55
|
+
for (const [key, value] of Object.entries(data)) {
|
|
56
|
+
table.push([key, formatCell(value)]);
|
|
57
|
+
}
|
|
58
|
+
return table.toString();
|
|
59
|
+
}
|
|
60
|
+
function inferColumns(rows) {
|
|
61
|
+
const keys = new Set();
|
|
62
|
+
for (const row of rows) {
|
|
63
|
+
if (!isRecord(row)) {
|
|
64
|
+
return [{ key: "value", label: "Value" }];
|
|
65
|
+
}
|
|
66
|
+
for (const key of Object.keys(row)) {
|
|
67
|
+
keys.add(key);
|
|
68
|
+
if (keys.size >= 6) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (keys.size >= 6) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return [...keys].map((key) => ({ key, label: humanizeKey(key) }));
|
|
77
|
+
}
|
|
78
|
+
function toRows(value) {
|
|
79
|
+
return Array.isArray(value) ? value : [value];
|
|
80
|
+
}
|
|
81
|
+
function unwrapData(data) {
|
|
82
|
+
if (isRecord(data) && "data" in data) {
|
|
83
|
+
return data.data;
|
|
84
|
+
}
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
function readPath(value, path) {
|
|
88
|
+
if (path === "value") {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
let current = value;
|
|
92
|
+
for (const part of path.split(".")) {
|
|
93
|
+
if (!isRecord(current) || !(part in current)) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
current = current[part];
|
|
97
|
+
}
|
|
98
|
+
return current;
|
|
99
|
+
}
|
|
100
|
+
function formatCell(value) {
|
|
101
|
+
if (value === null || value === undefined) {
|
|
102
|
+
return "";
|
|
103
|
+
}
|
|
104
|
+
if (typeof value === "string") {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
108
|
+
return String(value);
|
|
109
|
+
}
|
|
110
|
+
return JSON.stringify(value);
|
|
111
|
+
}
|
|
112
|
+
function formatHeader(value, color) {
|
|
113
|
+
return color ? pc.bold(value) : value;
|
|
114
|
+
}
|
|
115
|
+
function humanizeKey(value) {
|
|
116
|
+
return value
|
|
117
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
118
|
+
.replace(/[_-]+/g, " ")
|
|
119
|
+
.replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
120
|
+
}
|
|
121
|
+
function isRecord(value) {
|
|
122
|
+
return typeof value === "object" && value !== null;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type OutputMode = "human" | "json" | "raw";
|
|
2
|
+
export type OutputModeOptions = {
|
|
3
|
+
json?: boolean;
|
|
4
|
+
raw?: boolean;
|
|
5
|
+
noAutoJson?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type TerminalCapabilityOptions = OutputModeOptions & {
|
|
8
|
+
mode?: OutputMode;
|
|
9
|
+
quiet?: boolean;
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
};
|
|
12
|
+
export type TerminalLike = {
|
|
13
|
+
isTTY?: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type TerminalStreams = {
|
|
16
|
+
stdin?: TerminalLike;
|
|
17
|
+
stdout?: TerminalLike;
|
|
18
|
+
stderr?: TerminalLike;
|
|
19
|
+
};
|
|
20
|
+
export type TerminalCapabilities = {
|
|
21
|
+
color: boolean;
|
|
22
|
+
spinner: boolean;
|
|
23
|
+
interactive: boolean;
|
|
24
|
+
};
|
|
25
|
+
export declare function resolveOutputMode(options?: OutputModeOptions, streams?: TerminalStreams): OutputMode;
|
|
26
|
+
export declare function terminalCapabilities(options?: TerminalCapabilityOptions, streams?: TerminalStreams): TerminalCapabilities;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export function resolveOutputMode(options = {}, streams = {}) {
|
|
2
|
+
if (options.raw) {
|
|
3
|
+
return "raw";
|
|
4
|
+
}
|
|
5
|
+
if (options.json) {
|
|
6
|
+
return "json";
|
|
7
|
+
}
|
|
8
|
+
const stdout = streams.stdout ?? process.stdout;
|
|
9
|
+
if (!options.noAutoJson && !isTty(stdout)) {
|
|
10
|
+
return "json";
|
|
11
|
+
}
|
|
12
|
+
return "human";
|
|
13
|
+
}
|
|
14
|
+
export function terminalCapabilities(options = {}, streams = {}) {
|
|
15
|
+
const mode = options.mode ?? resolveOutputMode(options, streams);
|
|
16
|
+
const stdout = streams.stdout ?? process.stdout;
|
|
17
|
+
const stderr = streams.stderr ?? process.stderr;
|
|
18
|
+
const stdin = streams.stdin ?? process.stdin;
|
|
19
|
+
const env = options.env ?? process.env;
|
|
20
|
+
const machineMode = mode !== "human";
|
|
21
|
+
const quiet = options.quiet ?? false;
|
|
22
|
+
const decorationsAllowed = !machineMode && !quiet && isTty(stdout);
|
|
23
|
+
const noColor = isSet(env.NO_COLOR);
|
|
24
|
+
const forceColor = isEnabled(env.FORCE_COLOR);
|
|
25
|
+
const ci = isEnabled(env.CI);
|
|
26
|
+
return {
|
|
27
|
+
color: decorationsAllowed && !noColor && (!ci || forceColor),
|
|
28
|
+
spinner: decorationsAllowed && isTty(stderr) && !ci,
|
|
29
|
+
interactive: !machineMode && !quiet && isTty(stdin),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function isTty(stream) {
|
|
33
|
+
return stream.isTTY === true;
|
|
34
|
+
}
|
|
35
|
+
function isSet(value) {
|
|
36
|
+
return value !== undefined && value !== "";
|
|
37
|
+
}
|
|
38
|
+
function isEnabled(value) {
|
|
39
|
+
return value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false";
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=tty.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type WatchApplicationState = {
|
|
2
|
+
id?: string;
|
|
3
|
+
statusId?: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
};
|
|
6
|
+
export type WatchApplicationOptions = {
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
initialIntervalMs?: number;
|
|
9
|
+
maxIntervalMs?: number;
|
|
10
|
+
now?: () => number;
|
|
11
|
+
sleep?: (ms: number) => Promise<void>;
|
|
12
|
+
onTransition?: (application: WatchApplicationState) => void | Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export type WatchApplicationResult = {
|
|
15
|
+
application: WatchApplicationState;
|
|
16
|
+
terminal: "approved";
|
|
17
|
+
};
|
|
18
|
+
export declare function watchApplication(fetchApplication: () => Promise<WatchApplicationState>, options?: WatchApplicationOptions): Promise<WatchApplicationResult>;
|
|
19
|
+
export declare function parseDurationMs(value: string | undefined, fallbackMs: number): number;
|