@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.
Files changed (91) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +140 -0
  4. package/bin/eprospera.js +3 -0
  5. package/cli.ocs.yaml +406 -0
  6. package/dist/bundle/eprospera.mjs +28349 -0
  7. package/dist/completions/eprospera.bash +7 -0
  8. package/dist/completions/eprospera.fish +2 -0
  9. package/dist/completions/eprospera.ps1 +7 -0
  10. package/dist/completions/eprospera.zsh +4 -0
  11. package/dist/src/api/client.d.ts +29 -0
  12. package/dist/src/api/client.js +131 -0
  13. package/dist/src/api/errors.d.ts +11 -0
  14. package/dist/src/api/errors.js +125 -0
  15. package/dist/src/api/generated.d.ts +1159 -0
  16. package/dist/src/api/generated.js +6 -0
  17. package/dist/src/commands/application/create.d.ts +5 -0
  18. package/dist/src/commands/application/create.js +62 -0
  19. package/dist/src/commands/application/get.d.ts +2 -0
  20. package/dist/src/commands/application/get.js +11 -0
  21. package/dist/src/commands/application/list.d.ts +2 -0
  22. package/dist/src/commands/application/list.js +8 -0
  23. package/dist/src/commands/application/pay.d.ts +5 -0
  24. package/dist/src/commands/application/pay.js +27 -0
  25. package/dist/src/commands/application/watch.d.ts +7 -0
  26. package/dist/src/commands/application/watch.js +42 -0
  27. package/dist/src/commands/auth/login.d.ts +7 -0
  28. package/dist/src/commands/auth/login.js +60 -0
  29. package/dist/src/commands/auth/logout.d.ts +2 -0
  30. package/dist/src/commands/auth/logout.js +14 -0
  31. package/dist/src/commands/auth/whoami.d.ts +2 -0
  32. package/dist/src/commands/auth/whoami.js +19 -0
  33. package/dist/src/commands/completion.d.ts +3 -0
  34. package/dist/src/commands/completion.js +80 -0
  35. package/dist/src/commands/config/get.d.ts +2 -0
  36. package/dist/src/commands/config/get.js +9 -0
  37. package/dist/src/commands/config/list.d.ts +2 -0
  38. package/dist/src/commands/config/list.js +7 -0
  39. package/dist/src/commands/config/set.d.ts +2 -0
  40. package/dist/src/commands/config/set.js +9 -0
  41. package/dist/src/commands/config/unset.d.ts +2 -0
  42. package/dist/src/commands/config/unset.js +9 -0
  43. package/dist/src/commands/entity/documents.d.ts +2 -0
  44. package/dist/src/commands/entity/documents.js +11 -0
  45. package/dist/src/commands/entity/get.d.ts +2 -0
  46. package/dist/src/commands/entity/get.js +11 -0
  47. package/dist/src/commands/entity/search.d.ts +2 -0
  48. package/dist/src/commands/entity/search.js +17 -0
  49. package/dist/src/commands/entity/verify.d.ts +2 -0
  50. package/dist/src/commands/entity/verify.js +9 -0
  51. package/dist/src/commands/files.d.ts +2 -0
  52. package/dist/src/commands/files.js +24 -0
  53. package/dist/src/commands/me/id-verification.d.ts +2 -0
  54. package/dist/src/commands/me/id-verification.js +8 -0
  55. package/dist/src/commands/me/profile.d.ts +2 -0
  56. package/dist/src/commands/me/profile.js +8 -0
  57. package/dist/src/commands/me/residency.d.ts +2 -0
  58. package/dist/src/commands/me/residency.js +8 -0
  59. package/dist/src/commands/runtime.d.ts +56 -0
  60. package/dist/src/commands/runtime.js +101 -0
  61. package/dist/src/commands/schema.d.ts +2 -0
  62. package/dist/src/commands/schema.js +13 -0
  63. package/dist/src/config/store.d.ts +14 -0
  64. package/dist/src/config/store.js +99 -0
  65. package/dist/src/credentials/resolve.d.ts +15 -0
  66. package/dist/src/credentials/resolve.js +63 -0
  67. package/dist/src/credentials/store.d.ts +22 -0
  68. package/dist/src/credentials/store.js +184 -0
  69. package/dist/src/credentials/types.d.ts +15 -0
  70. package/dist/src/credentials/types.js +5 -0
  71. package/dist/src/errors.d.ts +39 -0
  72. package/dist/src/errors.js +38 -0
  73. package/dist/src/index.d.ts +4 -0
  74. package/dist/src/index.js +244 -0
  75. package/dist/src/output/format.d.ts +27 -0
  76. package/dist/src/output/format.js +126 -0
  77. package/dist/src/output/table.d.ts +5 -0
  78. package/dist/src/output/table.js +124 -0
  79. package/dist/src/output/tty.d.ts +26 -0
  80. package/dist/src/output/tty.js +41 -0
  81. package/dist/src/polling/watch.d.ts +19 -0
  82. package/dist/src/polling/watch.js +86 -0
  83. package/dist/src/prompts/confirm.d.ts +2 -0
  84. package/dist/src/prompts/confirm.js +19 -0
  85. package/dist/src/scopes/check.d.ts +17 -0
  86. package/dist/src/scopes/check.js +64 -0
  87. package/dist/src/scopes/map.d.ts +81 -0
  88. package/dist/src/scopes/map.js +76 -0
  89. package/dist/src/version.d.ts +1 -0
  90. package/dist/src/version.js +35 -0
  91. 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,5 @@
1
+ export type TablePreset = "entities" | "applications" | "documents";
2
+ export type RenderTableOptions = {
3
+ color?: boolean;
4
+ };
5
+ export declare function renderTable(data: unknown, preset?: TablePreset, options?: RenderTableOptions): string;
@@ -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;