specli 0.0.5 → 0.0.8
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/bin/specli.js +19 -0
- package/cli.ts +13 -4
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2331 -0
- package/dist/cli.js.map +53 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2032 -0
- package/dist/index.js.map +48 -0
- package/dist/src/ai/tools.d.ts +139 -0
- package/dist/src/ai/tools.d.ts.map +1 -0
- package/dist/src/ai/tools.js +1656 -0
- package/dist/src/ai/tools.js.map +45 -0
- package/dist/src/cli/auth-requirements.d.ts +10 -0
- package/dist/src/cli/auth-requirements.d.ts.map +1 -0
- package/dist/src/cli/auth-requirements.js +66 -0
- package/dist/src/cli/auth-requirements.js.map +10 -0
- package/dist/src/cli/auth-schemes.d.ts +22 -0
- package/dist/src/cli/auth-schemes.d.ts.map +1 -0
- package/dist/src/cli/auth-schemes.js +116 -0
- package/dist/src/cli/auth-schemes.js.map +11 -0
- package/dist/src/cli/capabilities.d.ts +32 -0
- package/dist/src/cli/capabilities.d.ts.map +1 -0
- package/dist/src/cli/capabilities.js +45 -0
- package/dist/src/cli/capabilities.js.map +10 -0
- package/dist/src/cli/command-id.d.ts +8 -0
- package/dist/src/cli/command-id.d.ts.map +1 -0
- package/dist/src/cli/command-id.js +18 -0
- package/dist/src/cli/command-id.js.map +11 -0
- package/dist/src/cli/command-index.d.ts +6 -0
- package/dist/src/cli/command-index.d.ts.map +1 -0
- package/dist/src/cli/command-index.js +15 -0
- package/dist/src/cli/command-index.js.map +10 -0
- package/dist/src/cli/command-model.d.ts +40 -0
- package/dist/src/cli/command-model.d.ts.map +1 -0
- package/dist/src/cli/command-model.js +274 -0
- package/dist/src/cli/command-model.js.map +18 -0
- package/dist/src/cli/compile.d.ts +15 -0
- package/dist/src/cli/compile.d.ts.map +1 -0
- package/dist/src/cli/compile.js +146 -0
- package/dist/src/cli/compile.js.map +11 -0
- package/dist/src/cli/crypto.d.ts +2 -0
- package/dist/src/cli/crypto.d.ts.map +1 -0
- package/dist/src/cli/crypto.js +15 -0
- package/dist/src/cli/crypto.js.map +10 -0
- package/dist/src/cli/derive-name.d.ts +9 -0
- package/dist/src/cli/derive-name.d.ts.map +1 -0
- package/dist/src/cli/derive-name.js +70 -0
- package/dist/src/cli/derive-name.js.map +10 -0
- package/dist/src/cli/exec.d.ts +14 -0
- package/dist/src/cli/exec.d.ts.map +1 -0
- package/dist/src/cli/exec.js +2077 -0
- package/dist/src/cli/exec.js.map +49 -0
- package/dist/src/cli/main.d.ts +10 -0
- package/dist/src/cli/main.d.ts.map +1 -0
- package/dist/src/cli/main.js +2032 -0
- package/dist/src/cli/main.js.map +48 -0
- package/dist/src/cli/naming.d.ts +12 -0
- package/dist/src/cli/naming.d.ts.map +1 -0
- package/dist/src/cli/naming.js +216 -0
- package/dist/src/cli/naming.js.map +12 -0
- package/dist/src/cli/operations.d.ts +3 -0
- package/dist/src/cli/operations.d.ts.map +1 -0
- package/dist/src/cli/operations.js +103 -0
- package/dist/src/cli/operations.js.map +10 -0
- package/dist/src/cli/params.d.ts +19 -0
- package/dist/src/cli/params.d.ts.map +1 -0
- package/dist/src/cli/params.js +79 -0
- package/dist/src/cli/params.js.map +12 -0
- package/dist/src/cli/pluralize.d.ts +2 -0
- package/dist/src/cli/pluralize.d.ts.map +1 -0
- package/dist/src/cli/pluralize.js +43 -0
- package/dist/src/cli/pluralize.js.map +10 -0
- package/dist/src/cli/positional.d.ts +19 -0
- package/dist/src/cli/positional.d.ts.map +1 -0
- package/dist/src/cli/positional.js +39 -0
- package/dist/src/cli/positional.js.map +10 -0
- package/dist/src/cli/request-body.d.ts +20 -0
- package/dist/src/cli/request-body.d.ts.map +1 -0
- package/dist/src/cli/request-body.js +82 -0
- package/dist/src/cli/request-body.js.map +12 -0
- package/dist/src/cli/runtime/argv.d.ts +3 -0
- package/dist/src/cli/runtime/argv.d.ts.map +1 -0
- package/dist/src/cli/runtime/argv.js +22 -0
- package/dist/src/cli/runtime/argv.js.map +10 -0
- package/dist/src/cli/runtime/auth/resolve.d.ts +9 -0
- package/dist/src/cli/runtime/auth/resolve.d.ts.map +1 -0
- package/dist/src/cli/runtime/auth/resolve.js +38 -0
- package/dist/src/cli/runtime/auth/resolve.js.map +10 -0
- package/dist/src/cli/runtime/body-flags.d.ts +41 -0
- package/dist/src/cli/runtime/body-flags.d.ts.map +1 -0
- package/dist/src/cli/runtime/body-flags.js +86 -0
- package/dist/src/cli/runtime/body-flags.js.map +10 -0
- package/dist/src/cli/runtime/body.d.ts +15 -0
- package/dist/src/cli/runtime/body.d.ts.map +1 -0
- package/dist/src/cli/runtime/body.js +40 -0
- package/dist/src/cli/runtime/body.js.map +11 -0
- package/dist/src/cli/runtime/collect.d.ts +2 -0
- package/dist/src/cli/runtime/collect.d.ts.map +1 -0
- package/dist/src/cli/runtime/collect.js +9 -0
- package/dist/src/cli/runtime/collect.js.map +10 -0
- package/dist/src/cli/runtime/compat.d.ts +35 -0
- package/dist/src/cli/runtime/compat.d.ts.map +1 -0
- package/dist/src/cli/runtime/compat.js +62 -0
- package/dist/src/cli/runtime/compat.js.map +10 -0
- package/dist/src/cli/runtime/context.d.ts +16 -0
- package/dist/src/cli/runtime/context.d.ts.map +1 -0
- package/dist/src/cli/runtime/context.js +936 -0
- package/dist/src/cli/runtime/context.js.map +32 -0
- package/dist/src/cli/runtime/execute.d.ts +33 -0
- package/dist/src/cli/runtime/execute.d.ts.map +1 -0
- package/dist/src/cli/runtime/execute.js +670 -0
- package/dist/src/cli/runtime/execute.js.map +22 -0
- package/dist/src/cli/runtime/generated.d.ts +14 -0
- package/dist/src/cli/runtime/generated.d.ts.map +1 -0
- package/dist/src/cli/runtime/generated.js +869 -0
- package/dist/src/cli/runtime/generated.js.map +23 -0
- package/dist/src/cli/runtime/headers.d.ts +9 -0
- package/dist/src/cli/runtime/headers.d.ts.map +1 -0
- package/dist/src/cli/runtime/headers.js +36 -0
- package/dist/src/cli/runtime/headers.js.map +10 -0
- package/dist/src/cli/runtime/index.d.ts +4 -0
- package/dist/src/cli/runtime/index.d.ts.map +1 -0
- package/dist/src/cli/runtime/index.js +1808 -0
- package/dist/src/cli/runtime/index.js.map +46 -0
- package/dist/src/cli/runtime/profile/secrets.d.ts +25 -0
- package/dist/src/cli/runtime/profile/secrets.d.ts.map +1 -0
- package/dist/src/cli/runtime/profile/secrets.js +51 -0
- package/dist/src/cli/runtime/profile/secrets.js.map +11 -0
- package/dist/src/cli/runtime/profile/store.d.ts +15 -0
- package/dist/src/cli/runtime/profile/store.d.ts.map +1 -0
- package/dist/src/cli/runtime/profile/store.js +102 -0
- package/dist/src/cli/runtime/profile/store.js.map +11 -0
- package/dist/src/cli/runtime/request.d.ts +36 -0
- package/dist/src/cli/runtime/request.d.ts.map +1 -0
- package/dist/src/cli/runtime/request.js +571 -0
- package/dist/src/cli/runtime/request.js.map +21 -0
- package/dist/src/cli/runtime/server-url.d.ts +8 -0
- package/dist/src/cli/runtime/server-url.d.ts.map +1 -0
- package/dist/src/cli/runtime/server-url.js +55 -0
- package/dist/src/cli/runtime/server-url.js.map +11 -0
- package/dist/src/cli/runtime/template.d.ts +5 -0
- package/dist/src/cli/runtime/template.d.ts.map +1 -0
- package/dist/src/cli/runtime/template.js +29 -0
- package/dist/src/cli/runtime/template.js.map +10 -0
- package/dist/src/cli/runtime/validate/ajv.d.ts +3 -0
- package/dist/src/cli/runtime/validate/ajv.d.ts.map +1 -0
- package/dist/src/cli/runtime/validate/ajv.js +17 -0
- package/dist/src/cli/runtime/validate/ajv.js.map +10 -0
- package/dist/src/cli/runtime/validate/coerce.d.ts +4 -0
- package/dist/src/cli/runtime/validate/coerce.d.ts.map +1 -0
- package/dist/src/cli/runtime/validate/coerce.js +60 -0
- package/dist/src/cli/runtime/validate/coerce.js.map +10 -0
- package/dist/src/cli/runtime/validate/error.d.ts +3 -0
- package/dist/src/cli/runtime/validate/error.d.ts.map +1 -0
- package/dist/src/cli/runtime/validate/error.js +21 -0
- package/dist/src/cli/runtime/validate/error.js.map +10 -0
- package/dist/src/cli/runtime/validate/index.d.ts +5 -0
- package/dist/src/cli/runtime/validate/index.d.ts.map +1 -0
- package/dist/src/cli/runtime/validate/index.js +122 -0
- package/dist/src/cli/runtime/validate/index.js.map +13 -0
- package/dist/src/cli/runtime/validate/schema.d.ts +9 -0
- package/dist/src/cli/runtime/validate/schema.d.ts.map +1 -0
- package/dist/src/cli/runtime/validate/schema.js +36 -0
- package/dist/src/cli/runtime/validate/schema.js.map +10 -0
- package/dist/src/cli/schema-shape.d.ts +5 -0
- package/dist/src/cli/schema-shape.d.ts.map +1 -0
- package/dist/src/cli/schema-shape.js +41 -0
- package/dist/src/cli/schema-shape.js.map +10 -0
- package/dist/src/cli/schema.d.ts +30 -0
- package/dist/src/cli/schema.d.ts.map +1 -0
- package/dist/src/cli/schema.js +38 -0
- package/dist/src/cli/schema.js.map +10 -0
- package/dist/src/cli/server.d.ts +16 -0
- package/dist/src/cli/server.d.ts.map +1 -0
- package/dist/src/cli/server.js +64 -0
- package/dist/src/cli/server.js.map +11 -0
- package/dist/src/cli/spec-id.d.ts +3 -0
- package/dist/src/cli/spec-id.d.ts.map +1 -0
- package/dist/src/cli/spec-id.js +21 -0
- package/dist/src/cli/spec-id.js.map +11 -0
- package/dist/src/cli/spec-loader.d.ts +7 -0
- package/dist/src/cli/spec-loader.d.ts.map +1 -0
- package/dist/src/cli/spec-loader.js +110 -0
- package/dist/src/cli/spec-loader.js.map +15 -0
- package/dist/src/cli/stable-json.d.ts +4 -0
- package/dist/src/cli/stable-json.d.ts.map +1 -0
- package/dist/src/cli/stable-json.js +35 -0
- package/dist/src/cli/stable-json.js.map +10 -0
- package/dist/src/cli/strings.d.ts +3 -0
- package/dist/src/cli/strings.d.ts.map +1 -0
- package/dist/src/cli/strings.js +16 -0
- package/dist/src/cli/strings.js.map +10 -0
- package/dist/src/cli/types.d.ts +53 -0
- package/dist/src/cli/types.d.ts.map +1 -0
- package/dist/src/cli/types.js +9 -0
- package/dist/src/cli/types.js.map +10 -0
- package/package.json +32 -4
- package/src/ai/tools.ts +211 -0
- package/src/cli/main.ts +3 -2
- package/src/cli/runtime/body.ts +3 -3
- package/src/cli/runtime/compat.ts +89 -0
- package/src/cli/runtime/execute.ts +98 -39
- package/src/cli/runtime/generated.ts +111 -4
- package/src/cli/runtime/profile/secrets.ts +42 -1
- package/src/cli/runtime/profile/store.ts +15 -13
- package/src/cli/runtime/request.ts +12 -4
- package/src/cli/spec-loader.ts +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
|
|
3
3
|
import type { AuthScheme } from "../auth-schemes.ts";
|
|
4
|
-
import type { CommandModel } from "../command-model.ts";
|
|
4
|
+
import type { CommandAction, CommandModel } from "../command-model.ts";
|
|
5
5
|
import type { ServerInfo } from "../server.ts";
|
|
6
6
|
|
|
7
7
|
import { type BodyFlagDef, generateBodyFlags } from "./body-flags.ts";
|
|
@@ -9,6 +9,106 @@ import { executeAction } from "./execute.ts";
|
|
|
9
9
|
import type { EmbeddedDefaults } from "./request.ts";
|
|
10
10
|
import { coerceArrayInput, coerceValue } from "./validate/index.ts";
|
|
11
11
|
|
|
12
|
+
// Flag type from CommandAction
|
|
13
|
+
type CommandFlag = CommandAction["flags"][number];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Format help output that is clear for both humans and AI agents.
|
|
17
|
+
* Groups options into Required, Optional, and Global sections.
|
|
18
|
+
*/
|
|
19
|
+
function formatCustomHelp(
|
|
20
|
+
cmd: Command,
|
|
21
|
+
action: CommandAction,
|
|
22
|
+
operationFlags: CommandFlag[],
|
|
23
|
+
bodyFlagDefs: BodyFlagDef[],
|
|
24
|
+
): string {
|
|
25
|
+
const lines: string[] = [];
|
|
26
|
+
const cmdName = cmd.name();
|
|
27
|
+
const parentName = cmd.parent?.name() ?? "";
|
|
28
|
+
const fullCmd = parentName ? `${parentName} ${cmdName}` : cmdName;
|
|
29
|
+
|
|
30
|
+
// Usage line
|
|
31
|
+
const positionals = action.positionals.map((p) => `<${p.name}>`).join(" ");
|
|
32
|
+
const usageSuffix = positionals ? ` ${positionals}` : "";
|
|
33
|
+
lines.push(`Usage: ${fullCmd}${usageSuffix} [options]`);
|
|
34
|
+
lines.push("");
|
|
35
|
+
|
|
36
|
+
// Description
|
|
37
|
+
const desc =
|
|
38
|
+
action.summary ?? action.description ?? `${action.method} ${action.path}`;
|
|
39
|
+
lines.push(desc);
|
|
40
|
+
lines.push("");
|
|
41
|
+
|
|
42
|
+
// Collect all options into categories
|
|
43
|
+
const requiredOpts: string[] = [];
|
|
44
|
+
const optionalOpts: string[] = [];
|
|
45
|
+
|
|
46
|
+
// Format a single option line
|
|
47
|
+
const formatOpt = (
|
|
48
|
+
flag: string,
|
|
49
|
+
type: string,
|
|
50
|
+
desc: string,
|
|
51
|
+
required: boolean,
|
|
52
|
+
): string => {
|
|
53
|
+
const typeStr = type === "boolean" ? "" : ` <${type}>`;
|
|
54
|
+
const reqMarker = required ? " (required)" : "";
|
|
55
|
+
return ` ${flag}${typeStr}${reqMarker}\n ${desc}`;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Operation flags (query/header/path params)
|
|
59
|
+
for (const f of operationFlags) {
|
|
60
|
+
const type = f.type === "array" ? `${f.itemType ?? "string"}[]` : f.type;
|
|
61
|
+
const line = formatOpt(
|
|
62
|
+
f.flag,
|
|
63
|
+
type,
|
|
64
|
+
f.description ?? `${f.in} parameter`,
|
|
65
|
+
f.required,
|
|
66
|
+
);
|
|
67
|
+
if (f.required) {
|
|
68
|
+
requiredOpts.push(line);
|
|
69
|
+
} else {
|
|
70
|
+
optionalOpts.push(line);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Body flags
|
|
75
|
+
for (const def of bodyFlagDefs) {
|
|
76
|
+
const line = formatOpt(def.flag, def.type, def.description, def.required);
|
|
77
|
+
if (def.required) {
|
|
78
|
+
requiredOpts.push(line);
|
|
79
|
+
} else {
|
|
80
|
+
optionalOpts.push(line);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Required options section
|
|
85
|
+
if (requiredOpts.length > 0) {
|
|
86
|
+
lines.push("Required:");
|
|
87
|
+
lines.push(...requiredOpts);
|
|
88
|
+
lines.push("");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Optional options section
|
|
92
|
+
if (optionalOpts.length > 0) {
|
|
93
|
+
lines.push("Options:");
|
|
94
|
+
lines.push(...optionalOpts);
|
|
95
|
+
lines.push("");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Global options (always available)
|
|
99
|
+
lines.push("Global:");
|
|
100
|
+
lines.push(" --curl\n Print curl command instead of executing");
|
|
101
|
+
lines.push(" --json\n Output response as JSON");
|
|
102
|
+
lines.push(" --server <url>\n Override the API server URL");
|
|
103
|
+
lines.push(
|
|
104
|
+
" --bearer-token <token>\n Provide auth token (or use 'login' command)",
|
|
105
|
+
);
|
|
106
|
+
lines.push(" -h, --help\n Show this help message");
|
|
107
|
+
lines.push("");
|
|
108
|
+
|
|
109
|
+
return lines.join("\n");
|
|
110
|
+
}
|
|
111
|
+
|
|
12
112
|
export type GeneratedCliContext = {
|
|
13
113
|
servers: ServerInfo[];
|
|
14
114
|
authSchemes: AuthScheme[];
|
|
@@ -78,11 +178,11 @@ export function addGeneratedCommands(
|
|
|
78
178
|
}
|
|
79
179
|
|
|
80
180
|
// Collect reserved flags: operation params + --curl
|
|
81
|
-
const
|
|
82
|
-
const reservedFlags = new Set([...
|
|
181
|
+
const operationFlagSet = new Set(action.flags.map((f) => f.flag));
|
|
182
|
+
const reservedFlags = new Set([...operationFlagSet, "--curl"]);
|
|
83
183
|
|
|
84
184
|
// Only --curl is a built-in flag (for debugging)
|
|
85
|
-
if (!
|
|
185
|
+
if (!operationFlagSet.has("--curl")) {
|
|
86
186
|
cmd.option("--curl", "Print curl command without sending");
|
|
87
187
|
}
|
|
88
188
|
|
|
@@ -106,6 +206,12 @@ export function addGeneratedCommands(
|
|
|
106
206
|
}
|
|
107
207
|
}
|
|
108
208
|
|
|
209
|
+
// Custom help output for better agent/human readability
|
|
210
|
+
cmd.configureHelp({
|
|
211
|
+
formatHelp: () =>
|
|
212
|
+
formatCustomHelp(cmd, action, action.flags, bodyFlagDefs),
|
|
213
|
+
});
|
|
214
|
+
|
|
109
215
|
// Commander passes positional args and then the Command instance as last arg.
|
|
110
216
|
cmd.action(async (...args) => {
|
|
111
217
|
const command = args[args.length - 1];
|
|
@@ -128,6 +234,7 @@ export function addGeneratedCommands(
|
|
|
128
234
|
specId: context.specId,
|
|
129
235
|
embeddedDefaults: context.embeddedDefaults,
|
|
130
236
|
bodyFlagDefs,
|
|
237
|
+
resourceName: resource.resource,
|
|
131
238
|
});
|
|
132
239
|
});
|
|
133
240
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isBun } from "../compat.ts";
|
|
2
|
+
|
|
3
|
+
const bunLiteral = "bun" as const;
|
|
2
4
|
|
|
3
5
|
export type SecretKey = {
|
|
4
6
|
service: string;
|
|
@@ -16,27 +18,66 @@ export function tokenSecretKey(specId: string, profile: string): SecretKey {
|
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Store a token securely.
|
|
23
|
+
* In Bun: uses the native secrets store (system keychain)
|
|
24
|
+
* In Node.js: secrets are not supported, warns user
|
|
25
|
+
*/
|
|
19
26
|
export async function setToken(
|
|
20
27
|
specId: string,
|
|
21
28
|
profile: string,
|
|
22
29
|
token: string,
|
|
23
30
|
): Promise<void> {
|
|
31
|
+
if (!isBun) {
|
|
32
|
+
console.warn(
|
|
33
|
+
"Warning: Secure token storage requires Bun. Token will not be persisted.",
|
|
34
|
+
);
|
|
35
|
+
console.warn(
|
|
36
|
+
"Use --bearer-token <token> flag instead when running with Node.js.",
|
|
37
|
+
);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { secrets } = await import(bunLiteral);
|
|
24
42
|
const key = tokenSecretKey(specId, profile);
|
|
25
43
|
await secrets.set({ service: key.service, name: key.name, value: token });
|
|
26
44
|
}
|
|
27
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Retrieve a stored token.
|
|
48
|
+
* In Bun: retrieves from the native secrets store
|
|
49
|
+
* In Node.js: returns null (secrets not supported)
|
|
50
|
+
*/
|
|
28
51
|
export async function getToken(
|
|
29
52
|
specId: string,
|
|
30
53
|
profile: string,
|
|
31
54
|
): Promise<string | null> {
|
|
55
|
+
if (!isBun) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { secrets } = await import(bunLiteral);
|
|
32
60
|
const key = tokenSecretKey(specId, profile);
|
|
33
61
|
return await secrets.get({ service: key.service, name: key.name });
|
|
34
62
|
}
|
|
35
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Delete a stored token.
|
|
66
|
+
* In Bun: removes from the native secrets store
|
|
67
|
+
* In Node.js: returns false (secrets not supported)
|
|
68
|
+
*/
|
|
36
69
|
export async function deleteToken(
|
|
37
70
|
specId: string,
|
|
38
71
|
profile: string,
|
|
39
72
|
): Promise<boolean> {
|
|
73
|
+
if (!isBun) {
|
|
74
|
+
console.warn(
|
|
75
|
+
"Warning: Secure token storage requires Bun. No token to delete.",
|
|
76
|
+
);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const { secrets } = await import(bunLiteral);
|
|
40
81
|
const key = tokenSecretKey(specId, profile);
|
|
41
82
|
return await secrets.delete({ service: key.service, name: key.name });
|
|
42
83
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
fileExists,
|
|
3
|
+
mkdirp,
|
|
4
|
+
parseYamlContent,
|
|
5
|
+
readFileText,
|
|
6
|
+
writeFileText,
|
|
7
|
+
} from "../compat.ts";
|
|
2
8
|
|
|
3
9
|
export type Profile = {
|
|
4
10
|
name: string;
|
|
@@ -32,21 +38,17 @@ export async function readProfiles(): Promise<ProfilesFile> {
|
|
|
32
38
|
const jsonPath = configPathJson();
|
|
33
39
|
const yamlPath = configPathYaml();
|
|
34
40
|
|
|
35
|
-
const
|
|
36
|
-
const
|
|
41
|
+
const jsonExists = await fileExists(jsonPath);
|
|
42
|
+
const yamlExists = await fileExists(yamlPath);
|
|
37
43
|
|
|
38
|
-
const
|
|
39
|
-
? jsonFile
|
|
40
|
-
: (await yamlFile.exists())
|
|
41
|
-
? yamlFile
|
|
42
|
-
: null;
|
|
44
|
+
const filePath = jsonExists ? jsonPath : yamlExists ? yamlPath : null;
|
|
43
45
|
|
|
44
|
-
if (!
|
|
46
|
+
if (!filePath) return { profiles: [] };
|
|
45
47
|
|
|
46
|
-
const text = await
|
|
48
|
+
const text = await readFileText(filePath);
|
|
47
49
|
let parsed: unknown;
|
|
48
50
|
try {
|
|
49
|
-
parsed =
|
|
51
|
+
parsed = parseYamlContent(text) as unknown;
|
|
50
52
|
} catch {
|
|
51
53
|
parsed = JSON.parse(text) as unknown;
|
|
52
54
|
}
|
|
@@ -70,8 +72,8 @@ export async function readProfiles(): Promise<ProfilesFile> {
|
|
|
70
72
|
|
|
71
73
|
export async function writeProfiles(data: ProfilesFile): Promise<void> {
|
|
72
74
|
const dir = configDir();
|
|
73
|
-
await
|
|
74
|
-
await
|
|
75
|
+
await mkdirp(dir);
|
|
76
|
+
await writeFileText(configPathJson(), JSON.stringify(data, null, 2));
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
export function getProfile(
|
|
@@ -275,9 +275,18 @@ export async function buildRequest(
|
|
|
275
275
|
|
|
276
276
|
const schema = input.action.requestBodySchema;
|
|
277
277
|
|
|
278
|
+
// Check if there are any required fields in the body
|
|
279
|
+
const requiredFields = bodyFlagDefs.filter((d) => d.required);
|
|
280
|
+
|
|
278
281
|
if (!hasBodyFlags) {
|
|
282
|
+
if (requiredFields.length > 0) {
|
|
283
|
+
// Error: user must provide required fields
|
|
284
|
+
const flagList = requiredFields.map((d) => `--${d.path.join(".")}`);
|
|
285
|
+
throw new Error(`Required: ${flagList.join(", ")}`);
|
|
286
|
+
}
|
|
287
|
+
// No required fields - send empty body if body is required, otherwise skip
|
|
279
288
|
if (input.action.requestBody.required) {
|
|
280
|
-
|
|
289
|
+
body = "{}";
|
|
281
290
|
}
|
|
282
291
|
} else {
|
|
283
292
|
if (!contentType?.includes("json")) {
|
|
@@ -292,9 +301,8 @@ export async function buildRequest(
|
|
|
292
301
|
);
|
|
293
302
|
const missing = findMissingRequired(input.flagValues, bodyFlagDefs);
|
|
294
303
|
if (missing.length > 0) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
);
|
|
304
|
+
const missingFlags = missing.map((m) => `--${m}`).join(", ");
|
|
305
|
+
throw new Error(`Missing required fields: ${missingFlags}`);
|
|
298
306
|
}
|
|
299
307
|
|
|
300
308
|
// Build nested object from dot-notation flags
|
package/src/cli/spec-loader.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
2
|
-
import { YAML } from "bun";
|
|
3
2
|
|
|
4
3
|
import { sha256Hex } from "./crypto.ts";
|
|
4
|
+
import { parseYamlContent } from "./runtime/compat.ts";
|
|
5
5
|
import { getSpecId } from "./spec-id.ts";
|
|
6
6
|
import { stableStringify } from "./stable-json.ts";
|
|
7
7
|
import type { LoadedSpec, OpenApiDoc, SpecSource } from "./types.ts";
|
|
@@ -21,7 +21,7 @@ function parseSpecText(text: string): unknown {
|
|
|
21
21
|
return JSON.parse(text);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
return
|
|
24
|
+
return parseYamlContent(text);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export async function loadSpec(options: LoadSpecOptions): Promise<LoadedSpec> {
|