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
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/positional.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { ParamSpec } from \"./params.ts\";\n\nexport type ActionShapeForCli = {\n\tpathArgs: string[];\n\tparams: ParamSpec[];\n};\n\nexport type PositionalArg = {\n\tname: string;\n\trequired: boolean;\n\tdescription?: string;\n\ttype: import(\"./schema-shape.ts\").ParamType;\n\tformat?: string;\n\tenum?: string[];\n};\n\nexport type FlagsIndex = {\n\tflags: Array<\n\t\tPick<\n\t\t\timport(\"./params.ts\").ParamSpec,\n\t\t\t| \"in\"\n\t\t\t| \"name\"\n\t\t\t| \"flag\"\n\t\t\t| \"required\"\n\t\t\t| \"description\"\n\t\t\t| \"type\"\n\t\t\t| \"format\"\n\t\t\t| \"enum\"\n\t\t\t| \"itemType\"\n\t\t\t| \"itemFormat\"\n\t\t\t| \"itemEnum\"\n\t\t>\n\t>;\n};\n\nexport function derivePositionals(action: ActionShapeForCli): PositionalArg[] {\n\tconst byName = new Map<string, PositionalArg>();\n\n\t// Use pathArgs order; match metadata from params when available.\n\tfor (const name of action.pathArgs) {\n\t\tconst p = action.params.find(\n\t\t\t(x: ParamSpec) => x.in === \"path\" && x.name === name,\n\t\t);\n\t\tbyName.set(name, {\n\t\t\tname,\n\t\t\trequired: true,\n\t\t\tdescription: p?.description,\n\t\t\ttype: p?.type ?? \"unknown\",\n\t\t\tformat: p?.format,\n\t\t\tenum: p?.enum,\n\t\t});\n\t}\n\n\treturn [...byName.values()];\n}\n\nexport function deriveFlags(action: ActionShapeForCli): FlagsIndex {\n\treturn {\n\t\tflags: action.params\n\t\t\t.filter((p: ParamSpec) => p.kind === \"flag\")\n\t\t\t.map((p: ParamSpec) => ({\n\t\t\t\tin: p.in,\n\t\t\t\tname: p.name,\n\t\t\t\tflag: p.flag,\n\t\t\t\trequired: p.required,\n\t\t\t\tdescription: p.description,\n\t\t\t\ttype: p.type,\n\t\t\t\tformat: p.format,\n\t\t\t\tenum: p.enum,\n\t\t\t\titemType: p.itemType,\n\t\t\t\titemFormat: p.itemFormat,\n\t\t\t\titemEnum: p.itemEnum,\n\t\t\t})),\n\t};\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAmCO,SAAS,iBAAiB,CAAC,QAA4C;AAAA,EAC7E,MAAM,SAAS,IAAI;AAAA,EAGnB,WAAW,QAAQ,OAAO,UAAU;AAAA,IACnC,MAAM,IAAI,OAAO,OAAO,KACvB,CAAC,MAAiB,EAAE,OAAO,UAAU,EAAE,SAAS,IACjD;AAAA,IACA,OAAO,IAAI,MAAM;AAAA,MAChB;AAAA,MACA,UAAU;AAAA,MACV,aAAa,GAAG;AAAA,MAChB,MAAM,GAAG,QAAQ;AAAA,MACjB,QAAQ,GAAG;AAAA,MACX,MAAM,GAAG;AAAA,IACV,CAAC;AAAA,EACF;AAAA,EAEA,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAAA;AAGpB,SAAS,WAAW,CAAC,QAAuC;AAAA,EAClE,OAAO;AAAA,IACN,OAAO,OAAO,OACZ,OAAO,CAAC,MAAiB,EAAE,SAAS,MAAM,EAC1C,IAAI,CAAC,OAAkB;AAAA,MACvB,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,UAAU,EAAE;AAAA,MACZ,aAAa,EAAE;AAAA,MACf,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,MAAM,EAAE;AAAA,MACR,UAAU,EAAE;AAAA,MACZ,YAAY,EAAE;AAAA,MACd,UAAU,EAAE;AAAA,IACb,EAAE;AAAA,EACJ;AAAA;",
|
|
8
|
+
"debugId": "16EFAB2F171B486164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JsonSchema, NormalizedOperation } from "./types.js";
|
|
2
|
+
export type RequestBodyContent = {
|
|
3
|
+
contentType: string;
|
|
4
|
+
required: boolean;
|
|
5
|
+
schemaType: import("./schema-shape.js").ParamType;
|
|
6
|
+
schemaFormat?: string;
|
|
7
|
+
schemaEnum?: string[];
|
|
8
|
+
};
|
|
9
|
+
export type RequestBodyInfo = {
|
|
10
|
+
required: boolean;
|
|
11
|
+
content: RequestBodyContent[];
|
|
12
|
+
hasJson: boolean;
|
|
13
|
+
hasFormUrlEncoded: boolean;
|
|
14
|
+
hasMultipart: boolean;
|
|
15
|
+
bodyFlags: string[];
|
|
16
|
+
preferredContentType?: string;
|
|
17
|
+
preferredSchema?: JsonSchema;
|
|
18
|
+
};
|
|
19
|
+
export declare function deriveRequestBodyInfo(op: NormalizedOperation): RequestBodyInfo | undefined;
|
|
20
|
+
//# sourceMappingURL=request-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-body.d.ts","sourceRoot":"","sources":["../../../src/cli/request-body.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACX,UAAU,EACV,mBAAmB,EAEnB,MAAM,YAAY,CAAC;AAGpB,MAAM,MAAM,kBAAkB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,mBAAmB,EAAE,SAAS,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAE9B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IAGtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,eAAe,CAAC,EAAE,UAAU,CAAC;CAC7B,CAAC;AAQF,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,mBAAmB,GACrB,eAAe,GAAG,SAAS,CAiD7B"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// src/cli/schema-shape.ts
|
|
2
|
+
function getSchemaType(schema) {
|
|
3
|
+
if (!schema || typeof schema !== "object")
|
|
4
|
+
return "unknown";
|
|
5
|
+
const t = schema.type;
|
|
6
|
+
if (t === "string")
|
|
7
|
+
return "string";
|
|
8
|
+
if (t === "number")
|
|
9
|
+
return "number";
|
|
10
|
+
if (t === "integer")
|
|
11
|
+
return "integer";
|
|
12
|
+
if (t === "boolean")
|
|
13
|
+
return "boolean";
|
|
14
|
+
if (t === "array")
|
|
15
|
+
return "array";
|
|
16
|
+
if (t === "object")
|
|
17
|
+
return "object";
|
|
18
|
+
return "unknown";
|
|
19
|
+
}
|
|
20
|
+
function getSchemaFormat(schema) {
|
|
21
|
+
if (!schema || typeof schema !== "object")
|
|
22
|
+
return;
|
|
23
|
+
const f = schema.format;
|
|
24
|
+
return typeof f === "string" ? f : undefined;
|
|
25
|
+
}
|
|
26
|
+
function getSchemaEnumStrings(schema) {
|
|
27
|
+
if (!schema || typeof schema !== "object")
|
|
28
|
+
return;
|
|
29
|
+
const e = schema.enum;
|
|
30
|
+
if (!Array.isArray(e))
|
|
31
|
+
return;
|
|
32
|
+
const values = e.filter((v) => typeof v === "string");
|
|
33
|
+
return values.length ? values : undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/cli/types.ts
|
|
37
|
+
function isJsonSchema(value) {
|
|
38
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/cli/request-body.ts
|
|
42
|
+
function getRequestBody(op) {
|
|
43
|
+
return op.requestBody;
|
|
44
|
+
}
|
|
45
|
+
function deriveRequestBodyInfo(op) {
|
|
46
|
+
const rb = getRequestBody(op);
|
|
47
|
+
if (!rb)
|
|
48
|
+
return;
|
|
49
|
+
const content = [];
|
|
50
|
+
for (const contentType of rb.contentTypes) {
|
|
51
|
+
const schema = rb.schemasByContentType[contentType];
|
|
52
|
+
content.push({
|
|
53
|
+
contentType,
|
|
54
|
+
required: rb.required,
|
|
55
|
+
schemaType: getSchemaType(schema),
|
|
56
|
+
schemaFormat: getSchemaFormat(schema),
|
|
57
|
+
schemaEnum: getSchemaEnumStrings(schema)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
content.sort((a, b) => a.contentType.localeCompare(b.contentType));
|
|
61
|
+
const hasJson = content.some((c) => c.contentType.includes("json"));
|
|
62
|
+
const hasFormUrlEncoded = content.some((c) => c.contentType === "application/x-www-form-urlencoded");
|
|
63
|
+
const hasMultipart = content.some((c) => c.contentType.startsWith("multipart/"));
|
|
64
|
+
const bodyFlags = ["--data", "--file"];
|
|
65
|
+
const preferredContentType = content.find((c) => c.contentType === "application/json")?.contentType ?? content.find((c) => c.contentType.includes("json"))?.contentType ?? content[0]?.contentType;
|
|
66
|
+
const preferredSchema = preferredContentType ? rb.schemasByContentType[preferredContentType] : undefined;
|
|
67
|
+
return {
|
|
68
|
+
required: rb.required,
|
|
69
|
+
content,
|
|
70
|
+
hasJson,
|
|
71
|
+
hasFormUrlEncoded,
|
|
72
|
+
hasMultipart,
|
|
73
|
+
bodyFlags,
|
|
74
|
+
preferredContentType,
|
|
75
|
+
preferredSchema: isJsonSchema(preferredSchema) ? preferredSchema : undefined
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
deriveRequestBodyInfo
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
//# debugId=3A023F015349AA9164756E2164756E21
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/schema-shape.ts", "../../../src/cli/types.ts", "../../../src/cli/request-body.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export type ParamType =\n\t| \"string\"\n\t| \"number\"\n\t| \"integer\"\n\t| \"boolean\"\n\t| \"array\"\n\t| \"object\"\n\t| \"unknown\";\n\nexport function getSchemaType(schema: unknown): ParamType {\n\tif (!schema || typeof schema !== \"object\") return \"unknown\";\n\tconst t = (schema as { type?: unknown }).type;\n\tif (t === \"string\") return \"string\";\n\tif (t === \"number\") return \"number\";\n\tif (t === \"integer\") return \"integer\";\n\tif (t === \"boolean\") return \"boolean\";\n\tif (t === \"array\") return \"array\";\n\tif (t === \"object\") return \"object\";\n\treturn \"unknown\";\n}\n\nexport function getSchemaFormat(schema: unknown): string | undefined {\n\tif (!schema || typeof schema !== \"object\") return undefined;\n\tconst f = (schema as { format?: unknown }).format;\n\treturn typeof f === \"string\" ? f : undefined;\n}\n\nexport function getSchemaEnumStrings(schema: unknown): string[] | undefined {\n\tif (!schema || typeof schema !== \"object\") return undefined;\n\tconst e = (schema as { enum?: unknown }).enum;\n\tif (!Array.isArray(e)) return undefined;\n\n\t// We only surface string enums for now (enough for flag docs + completion).\n\tconst values = e.filter((v) => typeof v === \"string\") as string[];\n\treturn values.length ? values : undefined;\n}\n",
|
|
6
|
+
"export type SpecSource = \"embedded\" | \"file\" | \"url\";\n\nexport type SecurityRequirement = Record<string, string[]>;\n\nexport type OpenApiDoc = {\n\topenapi: string;\n\tinfo?: {\n\t\ttitle?: string;\n\t\tversion?: string;\n\t};\n\tservers?: Array<{ url: string; description?: string; variables?: unknown }>;\n\tsecurity?: SecurityRequirement[];\n\tcomponents?: {\n\t\tsecuritySchemes?: Record<string, unknown>;\n\t};\n\tpaths?: Record<string, unknown>;\n};\n\nexport type NormalizedParameter = {\n\tin: \"path\" | \"query\" | \"header\" | \"cookie\";\n\tname: string;\n\trequired: boolean;\n\tdescription?: string;\n\tschema?: unknown;\n};\n\n// Minimal JSON Schema-like shape for validation and flag expansion.\nexport type JsonSchema = Record<string, unknown>;\n\nexport function isJsonSchema(value: unknown): value is JsonSchema {\n\treturn Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport type NormalizedRequestBody = {\n\trequired: boolean;\n\tcontentTypes: string[];\n\tschemasByContentType: Record<string, unknown | undefined>;\n};\n\nexport type NormalizedOperation = {\n\tkey: string;\n\tmethod: string;\n\tpath: string;\n\toperationId?: string;\n\ttags: string[];\n\tsummary?: string;\n\tdescription?: string;\n\tdeprecated?: boolean;\n\tsecurity?: SecurityRequirement[];\n\tparameters: NormalizedParameter[];\n\trequestBody?: NormalizedRequestBody;\n};\n\nexport type LoadedSpec = {\n\tsource: SpecSource;\n\tid: string;\n\tfingerprint: string;\n\tdoc: OpenApiDoc;\n};\n",
|
|
7
|
+
"import {\n\tgetSchemaEnumStrings,\n\tgetSchemaFormat,\n\tgetSchemaType,\n} from \"./schema-shape.ts\";\nimport type {\n\tJsonSchema,\n\tNormalizedOperation,\n\tNormalizedRequestBody,\n} from \"./types.ts\";\nimport { isJsonSchema } from \"./types.ts\";\n\nexport type RequestBodyContent = {\n\tcontentType: string;\n\trequired: boolean;\n\tschemaType: import(\"./schema-shape.ts\").ParamType;\n\tschemaFormat?: string;\n\tschemaEnum?: string[];\n};\n\nexport type RequestBodyInfo = {\n\trequired: boolean;\n\tcontent: RequestBodyContent[];\n\t// Convenience flags for later arg generation.\n\thasJson: boolean;\n\thasFormUrlEncoded: boolean;\n\thasMultipart: boolean;\n\n\t// Phase 1 planning: supported generic body inputs.\n\tbodyFlags: string[];\n\tpreferredContentType?: string;\n\n\t// Original JSON Schema (for expanded flags + validation)\n\tpreferredSchema?: JsonSchema;\n};\n\nfunction getRequestBody(\n\top: NormalizedOperation,\n): NormalizedRequestBody | undefined {\n\treturn op.requestBody;\n}\n\nexport function deriveRequestBodyInfo(\n\top: NormalizedOperation,\n): RequestBodyInfo | undefined {\n\tconst rb = getRequestBody(op);\n\tif (!rb) return undefined;\n\n\tconst content: RequestBodyContent[] = [];\n\tfor (const contentType of rb.contentTypes) {\n\t\tconst schema = rb.schemasByContentType[contentType];\n\t\tcontent.push({\n\t\t\tcontentType,\n\t\t\trequired: rb.required,\n\t\t\tschemaType: getSchemaType(schema),\n\t\t\tschemaFormat: getSchemaFormat(schema),\n\t\t\tschemaEnum: getSchemaEnumStrings(schema),\n\t\t});\n\t}\n\n\tcontent.sort((a, b) => a.contentType.localeCompare(b.contentType));\n\n\tconst hasJson = content.some((c) => c.contentType.includes(\"json\"));\n\tconst hasFormUrlEncoded = content.some(\n\t\t(c) => c.contentType === \"application/x-www-form-urlencoded\",\n\t);\n\tconst hasMultipart = content.some((c) =>\n\t\tc.contentType.startsWith(\"multipart/\"),\n\t);\n\n\tconst bodyFlags = [\"--data\", \"--file\"]; // always available when requestBody exists\n\n\tconst preferredContentType =\n\t\tcontent.find((c) => c.contentType === \"application/json\")?.contentType ??\n\t\tcontent.find((c) => c.contentType.includes(\"json\"))?.contentType ??\n\t\tcontent[0]?.contentType;\n\n\tconst preferredSchema = preferredContentType\n\t\t? rb.schemasByContentType[preferredContentType]\n\t\t: undefined;\n\n\treturn {\n\t\trequired: rb.required,\n\t\tcontent,\n\t\thasJson,\n\t\thasFormUrlEncoded,\n\t\thasMultipart,\n\t\tbodyFlags,\n\t\tpreferredContentType,\n\t\tpreferredSchema: isJsonSchema(preferredSchema)\n\t\t\t? preferredSchema\n\t\t\t: undefined,\n\t};\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";AASO,SAAS,aAAa,CAAC,QAA4B;AAAA,EACzD,IAAI,CAAC,UAAU,OAAO,WAAW;AAAA,IAAU,OAAO;AAAA,EAClD,MAAM,IAAK,OAA8B;AAAA,EACzC,IAAI,MAAM;AAAA,IAAU,OAAO;AAAA,EAC3B,IAAI,MAAM;AAAA,IAAU,OAAO;AAAA,EAC3B,IAAI,MAAM;AAAA,IAAW,OAAO;AAAA,EAC5B,IAAI,MAAM;AAAA,IAAW,OAAO;AAAA,EAC5B,IAAI,MAAM;AAAA,IAAS,OAAO;AAAA,EAC1B,IAAI,MAAM;AAAA,IAAU,OAAO;AAAA,EAC3B,OAAO;AAAA;AAGD,SAAS,eAAe,CAAC,QAAqC;AAAA,EACpE,IAAI,CAAC,UAAU,OAAO,WAAW;AAAA,IAAU;AAAA,EAC3C,MAAM,IAAK,OAAgC;AAAA,EAC3C,OAAO,OAAO,MAAM,WAAW,IAAI;AAAA;AAG7B,SAAS,oBAAoB,CAAC,QAAuC;AAAA,EAC3E,IAAI,CAAC,UAAU,OAAO,WAAW;AAAA,IAAU;AAAA,EAC3C,MAAM,IAAK,OAA8B;AAAA,EACzC,IAAI,CAAC,MAAM,QAAQ,CAAC;AAAA,IAAG;AAAA,EAGvB,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,OAAO,MAAM,QAAQ;AAAA,EACpD,OAAO,OAAO,SAAS,SAAS;AAAA;;;ACL1B,SAAS,YAAY,CAAC,OAAqC;AAAA,EACjE,OAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAAA;;;ACM3E,SAAS,cAAc,CACtB,IACoC;AAAA,EACpC,OAAO,GAAG;AAAA;AAGJ,SAAS,qBAAqB,CACpC,IAC8B;AAAA,EAC9B,MAAM,KAAK,eAAe,EAAE;AAAA,EAC5B,IAAI,CAAC;AAAA,IAAI;AAAA,EAET,MAAM,UAAgC,CAAC;AAAA,EACvC,WAAW,eAAe,GAAG,cAAc;AAAA,IAC1C,MAAM,SAAS,GAAG,qBAAqB;AAAA,IACvC,QAAQ,KAAK;AAAA,MACZ;AAAA,MACA,UAAU,GAAG;AAAA,MACb,YAAY,cAAc,MAAM;AAAA,MAChC,cAAc,gBAAgB,MAAM;AAAA,MACpC,YAAY,qBAAqB,MAAM;AAAA,IACxC,CAAC;AAAA,EACF;AAAA,EAEA,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,cAAc,EAAE,WAAW,CAAC;AAAA,EAEjE,MAAM,UAAU,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,SAAS,MAAM,CAAC;AAAA,EAClE,MAAM,oBAAoB,QAAQ,KACjC,CAAC,MAAM,EAAE,gBAAgB,mCAC1B;AAAA,EACA,MAAM,eAAe,QAAQ,KAAK,CAAC,MAClC,EAAE,YAAY,WAAW,YAAY,CACtC;AAAA,EAEA,MAAM,YAAY,CAAC,UAAU,QAAQ;AAAA,EAErC,MAAM,uBACL,QAAQ,KAAK,CAAC,MAAM,EAAE,gBAAgB,kBAAkB,GAAG,eAC3D,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,SAAS,MAAM,CAAC,GAAG,eACrD,QAAQ,IAAI;AAAA,EAEb,MAAM,kBAAkB,uBACrB,GAAG,qBAAqB,wBACxB;AAAA,EAEH,OAAO;AAAA,IACN,UAAU,GAAG;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,aAAa,eAAe,IAC1C,kBACA;AAAA,EACJ;AAAA;",
|
|
10
|
+
"debugId": "3A023F015349AA9164756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argv.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/argv.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS3E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAElE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/cli/runtime/argv.ts
|
|
2
|
+
function getArgValue(argv, key) {
|
|
3
|
+
for (let i = 0;i < argv.length; i++) {
|
|
4
|
+
const a = argv[i];
|
|
5
|
+
if (!a)
|
|
6
|
+
continue;
|
|
7
|
+
if (a === key)
|
|
8
|
+
return argv[i + 1];
|
|
9
|
+
if (a.startsWith(`${key}=`))
|
|
10
|
+
return a.slice(key.length + 1);
|
|
11
|
+
}
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
function hasAnyArg(argv, names) {
|
|
15
|
+
return argv.some((a) => a && names.includes(a));
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
hasAnyArg,
|
|
19
|
+
getArgValue
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//# debugId=5952A660C549252B64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/argv.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export function getArgValue(argv: string[], key: string): string | undefined {\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst a = argv[i];\n\t\tif (!a) continue;\n\n\t\tif (a === key) return argv[i + 1];\n\t\tif (a.startsWith(`${key}=`)) return a.slice(key.length + 1);\n\t}\n\treturn undefined;\n}\n\nexport function hasAnyArg(argv: string[], names: string[]): boolean {\n\treturn argv.some((a) => a && names.includes(a));\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAO,SAAS,WAAW,CAAC,MAAgB,KAAiC;AAAA,EAC5E,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACrC,MAAM,IAAI,KAAK;AAAA,IACf,IAAI,CAAC;AAAA,MAAG;AAAA,IAER,IAAI,MAAM;AAAA,MAAK,OAAO,KAAK,IAAI;AAAA,IAC/B,IAAI,EAAE,WAAW,GAAG,MAAM;AAAA,MAAG,OAAO,EAAE,MAAM,IAAI,SAAS,CAAC;AAAA,EAC3D;AAAA,EACA;AAAA;AAGM,SAAS,SAAS,CAAC,MAAgB,OAA0B;AAAA,EACnE,OAAO,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,SAAS,CAAC,CAAC;AAAA;",
|
|
8
|
+
"debugId": "5952A660C549252B64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AuthScheme } from "../../auth-schemes.js";
|
|
2
|
+
export type AuthInputs = {
|
|
3
|
+
flagAuthScheme?: string;
|
|
4
|
+
profileAuthScheme?: string;
|
|
5
|
+
embeddedAuthScheme?: string;
|
|
6
|
+
hasStoredToken?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function resolveAuthScheme(authSchemes: AuthScheme[], required: import("../../auth-requirements.js").AuthSummary, inputs: AuthInputs): string | undefined;
|
|
9
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../../../src/cli/runtime/auth/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,UAAU,GAAG;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAQF,wBAAgB,iBAAiB,CAChC,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,4BAA4B,EAAE,WAAW,EAC1D,MAAM,EAAE,UAAU,GAChB,MAAM,GAAG,SAAS,CAuCpB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/cli/runtime/auth/resolve.ts
|
|
2
|
+
var BEARER_COMPATIBLE_KINDS = new Set([
|
|
3
|
+
"http-bearer",
|
|
4
|
+
"oauth2",
|
|
5
|
+
"openIdConnect"
|
|
6
|
+
]);
|
|
7
|
+
function resolveAuthScheme(authSchemes, required, inputs) {
|
|
8
|
+
if (inputs.flagAuthScheme)
|
|
9
|
+
return inputs.flagAuthScheme;
|
|
10
|
+
if (inputs.profileAuthScheme && authSchemes.some((s) => s.key === inputs.profileAuthScheme)) {
|
|
11
|
+
return inputs.profileAuthScheme;
|
|
12
|
+
}
|
|
13
|
+
if (inputs.embeddedAuthScheme && authSchemes.some((s) => s.key === inputs.embeddedAuthScheme)) {
|
|
14
|
+
return inputs.embeddedAuthScheme;
|
|
15
|
+
}
|
|
16
|
+
const alts = required.alternatives;
|
|
17
|
+
if (alts.length === 1 && alts[0]?.length === 1)
|
|
18
|
+
return alts[0][0]?.key;
|
|
19
|
+
if (authSchemes.length === 1)
|
|
20
|
+
return authSchemes[0]?.key;
|
|
21
|
+
if (inputs.hasStoredToken && alts.length > 0) {
|
|
22
|
+
for (const alt of alts) {
|
|
23
|
+
if (alt.length !== 1)
|
|
24
|
+
continue;
|
|
25
|
+
const key = alt[0]?.key;
|
|
26
|
+
const scheme = authSchemes.find((s) => s.key === key);
|
|
27
|
+
if (scheme && BEARER_COMPATIBLE_KINDS.has(scheme.kind)) {
|
|
28
|
+
return key;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
resolveAuthScheme
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//# debugId=28B781E4ECFEED9064756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/runtime/auth/resolve.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { AuthScheme } from \"../../auth-schemes.ts\";\n\nexport type AuthInputs = {\n\tflagAuthScheme?: string;\n\tprofileAuthScheme?: string;\n\tembeddedAuthScheme?: string;\n\thasStoredToken?: boolean;\n};\n\nconst BEARER_COMPATIBLE_KINDS = new Set([\n\t\"http-bearer\",\n\t\"oauth2\",\n\t\"openIdConnect\",\n]);\n\nexport function resolveAuthScheme(\n\tauthSchemes: AuthScheme[],\n\trequired: import(\"../../auth-requirements.ts\").AuthSummary,\n\tinputs: AuthInputs,\n): string | undefined {\n\t// Priority: CLI flag > profile > embedded default\n\tif (inputs.flagAuthScheme) return inputs.flagAuthScheme;\n\n\tif (\n\t\tinputs.profileAuthScheme &&\n\t\tauthSchemes.some((s) => s.key === inputs.profileAuthScheme)\n\t) {\n\t\treturn inputs.profileAuthScheme;\n\t}\n\n\tif (\n\t\tinputs.embeddedAuthScheme &&\n\t\tauthSchemes.some((s) => s.key === inputs.embeddedAuthScheme)\n\t) {\n\t\treturn inputs.embeddedAuthScheme;\n\t}\n\n\t// If operation requires exactly one scheme, choose it.\n\tconst alts = required.alternatives;\n\tif (alts.length === 1 && alts[0]?.length === 1) return alts[0][0]?.key;\n\n\t// Otherwise if there is only one scheme in spec, pick it.\n\tif (authSchemes.length === 1) return authSchemes[0]?.key;\n\n\t// If user has a stored token and operation accepts a bearer-compatible scheme,\n\t// automatically pick the first one that matches.\n\tif (inputs.hasStoredToken && alts.length > 0) {\n\t\tfor (const alt of alts) {\n\t\t\tif (alt.length !== 1) continue;\n\t\t\tconst key = alt[0]?.key;\n\t\t\tconst scheme = authSchemes.find((s) => s.key === key);\n\t\t\tif (scheme && BEARER_COMPATIBLE_KINDS.has(scheme.kind)) {\n\t\t\t\treturn key;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AASA,IAAM,0BAA0B,IAAI,IAAI;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAEM,SAAS,iBAAiB,CAChC,aACA,UACA,QACqB;AAAA,EAErB,IAAI,OAAO;AAAA,IAAgB,OAAO,OAAO;AAAA,EAEzC,IACC,OAAO,qBACP,YAAY,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO,iBAAiB,GACzD;AAAA,IACD,OAAO,OAAO;AAAA,EACf;AAAA,EAEA,IACC,OAAO,sBACP,YAAY,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO,kBAAkB,GAC1D;AAAA,IACD,OAAO,OAAO;AAAA,EACf;AAAA,EAGA,MAAM,OAAO,SAAS;AAAA,EACtB,IAAI,KAAK,WAAW,KAAK,KAAK,IAAI,WAAW;AAAA,IAAG,OAAO,KAAK,GAAG,IAAI;AAAA,EAGnE,IAAI,YAAY,WAAW;AAAA,IAAG,OAAO,YAAY,IAAI;AAAA,EAIrD,IAAI,OAAO,kBAAkB,KAAK,SAAS,GAAG;AAAA,IAC7C,WAAW,OAAO,MAAM;AAAA,MACvB,IAAI,IAAI,WAAW;AAAA,QAAG;AAAA,MACtB,MAAM,MAAM,IAAI,IAAI;AAAA,MACpB,MAAM,SAAS,YAAY,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAAA,MACpD,IAAI,UAAU,wBAAwB,IAAI,OAAO,IAAI,GAAG;AAAA,QACvD,OAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EAEA;AAAA;",
|
|
8
|
+
"debugId": "28B781E4ECFEED9064756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body flag generation and parsing utilities.
|
|
3
|
+
*
|
|
4
|
+
* Generates CLI flags from JSON schema properties and parses
|
|
5
|
+
* dot-notation flags back into nested objects.
|
|
6
|
+
*/
|
|
7
|
+
type JsonSchema = {
|
|
8
|
+
type?: string;
|
|
9
|
+
properties?: Record<string, JsonSchema>;
|
|
10
|
+
items?: JsonSchema;
|
|
11
|
+
required?: string[];
|
|
12
|
+
description?: string;
|
|
13
|
+
};
|
|
14
|
+
export type BodyFlagDef = {
|
|
15
|
+
flag: string;
|
|
16
|
+
path: string[];
|
|
17
|
+
type: "string" | "number" | "integer" | "boolean";
|
|
18
|
+
description: string;
|
|
19
|
+
required: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Generate flag definitions from a JSON schema.
|
|
23
|
+
* Recursively handles nested objects using dot notation.
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateBodyFlags(schema: JsonSchema | undefined, reservedFlags: Set<string>): BodyFlagDef[];
|
|
26
|
+
/**
|
|
27
|
+
* Parse flag values with dot notation into a nested object.
|
|
28
|
+
*
|
|
29
|
+
* Example:
|
|
30
|
+
* { "address.street": "123 Main", "address.city": "NYC", "name": "Ada" }
|
|
31
|
+
* Becomes:
|
|
32
|
+
* { address: { street: "123 Main", city: "NYC" }, name: "Ada" }
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseDotNotationFlags(flagValues: Record<string, unknown>, flagDefs: BodyFlagDef[]): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if all required fields are present.
|
|
37
|
+
* Returns list of missing field paths.
|
|
38
|
+
*/
|
|
39
|
+
export declare function findMissingRequired(flagValues: Record<string, unknown>, flagDefs: BodyFlagDef[]): string[];
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=body-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-flags.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/body-flags.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,KAAK,UAAU,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,WAAW,EAAE,CAWf;AAqDD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,EAAE,WAAW,EAAE,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAmCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,EAAE,WAAW,EAAE,GACrB,MAAM,EAAE,CAcV"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/cli/runtime/body-flags.ts
|
|
2
|
+
function generateBodyFlags(schema, reservedFlags) {
|
|
3
|
+
if (!schema || schema.type !== "object" || !schema.properties) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
const flags = [];
|
|
7
|
+
const requiredSet = new Set(schema.required ?? []);
|
|
8
|
+
collectFlags(schema.properties, [], requiredSet, flags, reservedFlags);
|
|
9
|
+
return flags;
|
|
10
|
+
}
|
|
11
|
+
function collectFlags(properties, pathPrefix, requiredAtRoot, out, reservedFlags) {
|
|
12
|
+
for (const [name, propSchema] of Object.entries(properties)) {
|
|
13
|
+
if (!name || typeof name !== "string")
|
|
14
|
+
continue;
|
|
15
|
+
if (!propSchema || typeof propSchema !== "object")
|
|
16
|
+
continue;
|
|
17
|
+
const path = [...pathPrefix, name];
|
|
18
|
+
const flagName = `--${path.join(".")}`;
|
|
19
|
+
if (reservedFlags.has(flagName))
|
|
20
|
+
continue;
|
|
21
|
+
const t = propSchema.type;
|
|
22
|
+
if (t === "object" && propSchema.properties) {
|
|
23
|
+
const nestedRequired = new Set(propSchema.required ?? []);
|
|
24
|
+
collectFlags(propSchema.properties, path, nestedRequired, out, reservedFlags);
|
|
25
|
+
} else if (t === "string" || t === "number" || t === "integer" || t === "boolean") {
|
|
26
|
+
const isRequired = pathPrefix.length === 0 ? requiredAtRoot.has(name) : false;
|
|
27
|
+
out.push({
|
|
28
|
+
flag: flagName,
|
|
29
|
+
path,
|
|
30
|
+
type: t,
|
|
31
|
+
description: propSchema.description ?? `Body field '${path.join(".")}'`,
|
|
32
|
+
required: isRequired
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function parseDotNotationFlags(flagValues, flagDefs) {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const def of flagDefs) {
|
|
40
|
+
const dotKey = def.path.join(".");
|
|
41
|
+
const value = flagValues[dotKey];
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
setNestedValue(result, def.path, value, def.type);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
function setNestedValue(obj, path, value, type) {
|
|
49
|
+
let current = obj;
|
|
50
|
+
for (let i = 0;i < path.length - 1; i++) {
|
|
51
|
+
const key = path[i];
|
|
52
|
+
if (!(key in current) || typeof current[key] !== "object") {
|
|
53
|
+
current[key] = {};
|
|
54
|
+
}
|
|
55
|
+
current = current[key];
|
|
56
|
+
}
|
|
57
|
+
const finalKey = path[path.length - 1];
|
|
58
|
+
if (type === "boolean") {
|
|
59
|
+
current[finalKey] = true;
|
|
60
|
+
} else if (type === "integer") {
|
|
61
|
+
current[finalKey] = Number.parseInt(String(value), 10);
|
|
62
|
+
} else if (type === "number") {
|
|
63
|
+
current[finalKey] = Number(String(value));
|
|
64
|
+
} else {
|
|
65
|
+
current[finalKey] = String(value);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function findMissingRequired(flagValues, flagDefs) {
|
|
69
|
+
const missing = [];
|
|
70
|
+
for (const def of flagDefs) {
|
|
71
|
+
if (!def.required)
|
|
72
|
+
continue;
|
|
73
|
+
const dotKey = def.path.join(".");
|
|
74
|
+
if (flagValues[dotKey] === undefined) {
|
|
75
|
+
missing.push(dotKey);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return missing;
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
parseDotNotationFlags,
|
|
82
|
+
generateBodyFlags,
|
|
83
|
+
findMissingRequired
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
//# debugId=0CD1D6E49259F68464756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/body-flags.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Body flag generation and parsing utilities.\n *\n * Generates CLI flags from JSON schema properties and parses\n * dot-notation flags back into nested objects.\n */\n\ntype JsonSchema = {\n\ttype?: string;\n\tproperties?: Record<string, JsonSchema>;\n\titems?: JsonSchema;\n\trequired?: string[];\n\tdescription?: string;\n};\n\nexport type BodyFlagDef = {\n\tflag: string; // e.g. \"--name\" or \"--address.street\"\n\tpath: string[]; // e.g. [\"name\"] or [\"address\", \"street\"]\n\ttype: \"string\" | \"number\" | \"integer\" | \"boolean\";\n\tdescription: string;\n\trequired: boolean;\n};\n\n/**\n * Generate flag definitions from a JSON schema.\n * Recursively handles nested objects using dot notation.\n */\nexport function generateBodyFlags(\n\tschema: JsonSchema | undefined,\n\treservedFlags: Set<string>,\n): BodyFlagDef[] {\n\tif (!schema || schema.type !== \"object\" || !schema.properties) {\n\t\treturn [];\n\t}\n\n\tconst flags: BodyFlagDef[] = [];\n\tconst requiredSet = new Set(schema.required ?? []);\n\n\tcollectFlags(schema.properties, [], requiredSet, flags, reservedFlags);\n\n\treturn flags;\n}\n\nfunction collectFlags(\n\tproperties: Record<string, JsonSchema>,\n\tpathPrefix: string[],\n\trequiredAtRoot: Set<string>,\n\tout: BodyFlagDef[],\n\treservedFlags: Set<string>,\n): void {\n\tfor (const [name, propSchema] of Object.entries(properties)) {\n\t\tif (!name || typeof name !== \"string\") continue;\n\t\tif (!propSchema || typeof propSchema !== \"object\") continue;\n\n\t\tconst path = [...pathPrefix, name];\n\t\tconst flagName = `--${path.join(\".\")}`;\n\n\t\t// Skip if this flag would conflict with an operation parameter\n\t\tif (reservedFlags.has(flagName)) continue;\n\n\t\tconst t = propSchema.type;\n\n\t\tif (t === \"object\" && propSchema.properties) {\n\t\t\t// Recurse into nested object\n\t\t\tconst nestedRequired = new Set(propSchema.required ?? []);\n\t\t\tcollectFlags(\n\t\t\t\tpropSchema.properties,\n\t\t\t\tpath,\n\t\t\t\tnestedRequired,\n\t\t\t\tout,\n\t\t\t\treservedFlags,\n\t\t\t);\n\t\t} else if (\n\t\t\tt === \"string\" ||\n\t\t\tt === \"number\" ||\n\t\t\tt === \"integer\" ||\n\t\t\tt === \"boolean\"\n\t\t) {\n\t\t\t// Leaf property - generate a flag\n\t\t\tconst isRequired =\n\t\t\t\tpathPrefix.length === 0 ? requiredAtRoot.has(name) : false;\n\n\t\t\tout.push({\n\t\t\t\tflag: flagName,\n\t\t\t\tpath,\n\t\t\t\ttype: t,\n\t\t\t\tdescription: propSchema.description ?? `Body field '${path.join(\".\")}'`,\n\t\t\t\trequired: isRequired,\n\t\t\t});\n\t\t}\n\t\t// Skip arrays and other complex types for now\n\t}\n}\n\n/**\n * Parse flag values with dot notation into a nested object.\n *\n * Example:\n * { \"address.street\": \"123 Main\", \"address.city\": \"NYC\", \"name\": \"Ada\" }\n * Becomes:\n * { address: { street: \"123 Main\", city: \"NYC\" }, name: \"Ada\" }\n */\nexport function parseDotNotationFlags(\n\tflagValues: Record<string, unknown>,\n\tflagDefs: BodyFlagDef[],\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\n\tfor (const def of flagDefs) {\n\t\t// Commander keeps dots in option names: --address.street -> \"address.street\"\n\t\tconst dotKey = def.path.join(\".\");\n\t\tconst value = flagValues[dotKey];\n\n\t\tif (value === undefined) continue;\n\n\t\tsetNestedValue(result, def.path, value, def.type);\n\t}\n\n\treturn result;\n}\n\n/**\n * Set a value at a nested path, creating intermediate objects as needed.\n */\nfunction setNestedValue(\n\tobj: Record<string, unknown>,\n\tpath: string[],\n\tvalue: unknown,\n\ttype: string,\n): void {\n\tlet current = obj;\n\n\tfor (let i = 0; i < path.length - 1; i++) {\n\t\tconst key = path[i] as string;\n\t\tif (!(key in current) || typeof current[key] !== \"object\") {\n\t\t\tcurrent[key] = {};\n\t\t}\n\t\tcurrent = current[key] as Record<string, unknown>;\n\t}\n\n\tconst finalKey = path[path.length - 1] as string;\n\n\t// Coerce value based on type\n\tif (type === \"boolean\") {\n\t\tcurrent[finalKey] = true;\n\t} else if (type === \"integer\") {\n\t\tcurrent[finalKey] = Number.parseInt(String(value), 10);\n\t} else if (type === \"number\") {\n\t\tcurrent[finalKey] = Number(String(value));\n\t} else {\n\t\tcurrent[finalKey] = String(value);\n\t}\n}\n\n/**\n * Check if all required fields are present.\n * Returns list of missing field paths.\n */\nexport function findMissingRequired(\n\tflagValues: Record<string, unknown>,\n\tflagDefs: BodyFlagDef[],\n): string[] {\n\tconst missing: string[] = [];\n\n\tfor (const def of flagDefs) {\n\t\tif (!def.required) continue;\n\n\t\t// Commander keeps dots in option names: --address.street -> \"address.street\"\n\t\tconst dotKey = def.path.join(\".\");\n\t\tif (flagValues[dotKey] === undefined) {\n\t\t\tmissing.push(dotKey);\n\t\t}\n\t}\n\n\treturn missing;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AA2BO,SAAS,iBAAiB,CAChC,QACA,eACgB;AAAA,EAChB,IAAI,CAAC,UAAU,OAAO,SAAS,YAAY,CAAC,OAAO,YAAY;AAAA,IAC9D,OAAO,CAAC;AAAA,EACT;AAAA,EAEA,MAAM,QAAuB,CAAC;AAAA,EAC9B,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,CAAC,CAAC;AAAA,EAEjD,aAAa,OAAO,YAAY,CAAC,GAAG,aAAa,OAAO,aAAa;AAAA,EAErE,OAAO;AAAA;AAGR,SAAS,YAAY,CACpB,YACA,YACA,gBACA,KACA,eACO;AAAA,EACP,YAAY,MAAM,eAAe,OAAO,QAAQ,UAAU,GAAG;AAAA,IAC5D,IAAI,CAAC,QAAQ,OAAO,SAAS;AAAA,MAAU;AAAA,IACvC,IAAI,CAAC,cAAc,OAAO,eAAe;AAAA,MAAU;AAAA,IAEnD,MAAM,OAAO,CAAC,GAAG,YAAY,IAAI;AAAA,IACjC,MAAM,WAAW,KAAK,KAAK,KAAK,GAAG;AAAA,IAGnC,IAAI,cAAc,IAAI,QAAQ;AAAA,MAAG;AAAA,IAEjC,MAAM,IAAI,WAAW;AAAA,IAErB,IAAI,MAAM,YAAY,WAAW,YAAY;AAAA,MAE5C,MAAM,iBAAiB,IAAI,IAAI,WAAW,YAAY,CAAC,CAAC;AAAA,MACxD,aACC,WAAW,YACX,MACA,gBACA,KACA,aACD;AAAA,IACD,EAAO,SACN,MAAM,YACN,MAAM,YACN,MAAM,aACN,MAAM,WACL;AAAA,MAED,MAAM,aACL,WAAW,WAAW,IAAI,eAAe,IAAI,IAAI,IAAI;AAAA,MAEtD,IAAI,KAAK;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,aAAa,WAAW,eAAe,eAAe,KAAK,KAAK,GAAG;AAAA,QACnE,UAAU;AAAA,MACX,CAAC;AAAA,IACF;AAAA,EAED;AAAA;AAWM,SAAS,qBAAqB,CACpC,YACA,UAC0B;AAAA,EAC1B,MAAM,SAAkC,CAAC;AAAA,EAEzC,WAAW,OAAO,UAAU;AAAA,IAE3B,MAAM,SAAS,IAAI,KAAK,KAAK,GAAG;AAAA,IAChC,MAAM,QAAQ,WAAW;AAAA,IAEzB,IAAI,UAAU;AAAA,MAAW;AAAA,IAEzB,eAAe,QAAQ,IAAI,MAAM,OAAO,IAAI,IAAI;AAAA,EACjD;AAAA,EAEA,OAAO;AAAA;AAMR,SAAS,cAAc,CACtB,KACA,MACA,OACA,MACO;AAAA,EACP,IAAI,UAAU;AAAA,EAEd,SAAS,IAAI,EAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AAAA,IACzC,MAAM,MAAM,KAAK;AAAA,IACjB,IAAI,EAAE,OAAO,YAAY,OAAO,QAAQ,SAAS,UAAU;AAAA,MAC1D,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,IACA,UAAU,QAAQ;AAAA,EACnB;AAAA,EAEA,MAAM,WAAW,KAAK,KAAK,SAAS;AAAA,EAGpC,IAAI,SAAS,WAAW;AAAA,IACvB,QAAQ,YAAY;AAAA,EACrB,EAAO,SAAI,SAAS,WAAW;AAAA,IAC9B,QAAQ,YAAY,OAAO,SAAS,OAAO,KAAK,GAAG,EAAE;AAAA,EACtD,EAAO,SAAI,SAAS,UAAU;AAAA,IAC7B,QAAQ,YAAY,OAAO,OAAO,KAAK,CAAC;AAAA,EACzC,EAAO;AAAA,IACN,QAAQ,YAAY,OAAO,KAAK;AAAA;AAAA;AAQ3B,SAAS,mBAAmB,CAClC,YACA,UACW;AAAA,EACX,MAAM,UAAoB,CAAC;AAAA,EAE3B,WAAW,OAAO,UAAU;AAAA,IAC3B,IAAI,CAAC,IAAI;AAAA,MAAU;AAAA,IAGnB,MAAM,SAAS,IAAI,KAAK,KAAK,GAAG;AAAA,IAChC,IAAI,WAAW,YAAY,WAAW;AAAA,MACrC,QAAQ,KAAK,MAAM;AAAA,IACpB;AAAA,EACD;AAAA,EAEA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "0CD1D6E49259F68464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type BodyInput = {
|
|
2
|
+
kind: "none";
|
|
3
|
+
} | {
|
|
4
|
+
kind: "data";
|
|
5
|
+
data: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "file";
|
|
8
|
+
path: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function loadBody(input: BodyInput): Promise<{
|
|
11
|
+
raw: string;
|
|
12
|
+
json?: unknown;
|
|
13
|
+
} | undefined>;
|
|
14
|
+
export declare function parseBodyAsJsonOrYaml(text: string): unknown;
|
|
15
|
+
//# sourceMappingURL=body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/body.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,wBAAsB,QAAQ,CAC7B,KAAK,EAAE,SAAS,GACd,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAMtD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM3D"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/cli/runtime/compat.ts
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
var isBun = typeof globalThis.Bun !== "undefined";
|
|
5
|
+
async function readFileText(path) {
|
|
6
|
+
if (isBun) {
|
|
7
|
+
return Bun.file(path).text();
|
|
8
|
+
}
|
|
9
|
+
return readFileSync(path, "utf-8");
|
|
10
|
+
}
|
|
11
|
+
function parseYamlContent(text) {
|
|
12
|
+
if (isBun) {
|
|
13
|
+
const { YAML } = globalThis.Bun;
|
|
14
|
+
return YAML.parse(text);
|
|
15
|
+
}
|
|
16
|
+
return parseYaml(text);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/cli/runtime/body.ts
|
|
20
|
+
async function loadBody(input) {
|
|
21
|
+
if (input.kind === "none")
|
|
22
|
+
return;
|
|
23
|
+
if (input.kind === "data")
|
|
24
|
+
return { raw: input.data };
|
|
25
|
+
const text = await readFileText(input.path);
|
|
26
|
+
return { raw: text };
|
|
27
|
+
}
|
|
28
|
+
function parseBodyAsJsonOrYaml(text) {
|
|
29
|
+
const trimmed = text.trimStart();
|
|
30
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
31
|
+
return JSON.parse(text);
|
|
32
|
+
}
|
|
33
|
+
return parseYamlContent(text);
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
parseBodyAsJsonOrYaml,
|
|
37
|
+
loadBody
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//# debugId=9F5BDD3591FC0D3E64756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/compat.ts", "../../../../src/cli/runtime/body.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Cross-runtime compatibility utilities for Bun and Node.js\n *\n * This module provides abstractions over Bun-specific APIs to allow\n * the exec command to run in Node.js while compile remains Bun-only.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { parse as parseYaml } from \"yaml\";\n\n/**\n * Detect if we're running in Bun\n */\nexport const isBun = typeof globalThis.Bun !== \"undefined\";\n\n/**\n * Read a file's text content - works in both Bun and Node.js\n */\nexport async function readFileText(path: string): Promise<string> {\n\tif (isBun) {\n\t\treturn Bun.file(path).text();\n\t}\n\treturn readFileSync(path, \"utf-8\");\n}\n\n/**\n * Check if a file exists - works in both Bun and Node.js\n */\nexport async function fileExists(path: string): Promise<boolean> {\n\tif (isBun) {\n\t\treturn Bun.file(path).exists();\n\t}\n\treturn existsSync(path);\n}\n\n/**\n * Write text to a file - works in both Bun and Node.js\n */\nexport async function writeFileText(\n\tpath: string,\n\tcontent: string,\n): Promise<void> {\n\tif (isBun) {\n\t\tawait Bun.write(path, content);\n\t\treturn;\n\t}\n\twriteFileSync(path, content, \"utf-8\");\n}\n\n/**\n * Create directory recursively - works in both Bun and Node.js\n */\nexport async function mkdirp(path: string): Promise<void> {\n\tif (isBun) {\n\t\tawait Bun.$`mkdir -p ${path}`;\n\t\treturn;\n\t}\n\tmkdirSync(path, { recursive: true });\n}\n\n/**\n * Parse YAML content - works in both Bun and Node.js\n */\nexport function parseYamlContent(text: string): unknown {\n\tif (isBun) {\n\t\tconst { YAML } = globalThis.Bun;\n\t\treturn YAML.parse(text);\n\t}\n\treturn parseYaml(text);\n}\n\n/**\n * Read from stdin - works in both Bun and Node.js\n */\nexport async function readStdinText(): Promise<string> {\n\tif (isBun) {\n\t\treturn Bun.stdin.text();\n\t}\n\t// Node.js stdin reading\n\treturn new Promise((resolve, reject) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => resolve(data));\n\t\tprocess.stdin.on(\"error\", reject);\n\t});\n}\n",
|
|
6
|
+
"import { parseYamlContent, readFileText } from \"./compat.ts\";\n\nexport type BodyInput =\n\t| { kind: \"none\" }\n\t| { kind: \"data\"; data: string }\n\t| { kind: \"file\"; path: string };\n\nexport async function loadBody(\n\tinput: BodyInput,\n): Promise<{ raw: string; json?: unknown } | undefined> {\n\tif (input.kind === \"none\") return undefined;\n\tif (input.kind === \"data\") return { raw: input.data };\n\n\tconst text = await readFileText(input.path);\n\treturn { raw: text };\n}\n\nexport function parseBodyAsJsonOrYaml(text: string): unknown {\n\tconst trimmed = text.trimStart();\n\tif (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n\t\treturn JSON.parse(text);\n\t}\n\treturn parseYamlContent(text);\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": ";AAOA;AACA,kBAAS;AAKF,IAAM,QAAQ,OAAO,WAAW,QAAQ;AAK/C,eAAsB,YAAY,CAAC,MAA+B;AAAA,EACjE,IAAI,OAAO;AAAA,IACV,OAAO,IAAI,KAAK,IAAI,EAAE,KAAK;AAAA,EAC5B;AAAA,EACA,OAAO,aAAa,MAAM,OAAO;AAAA;AAyC3B,SAAS,gBAAgB,CAAC,MAAuB;AAAA,EACvD,IAAI,OAAO;AAAA,IACV,QAAQ,SAAS,WAAW;AAAA,IAC5B,OAAO,KAAK,MAAM,IAAI;AAAA,EACvB;AAAA,EACA,OAAO,UAAU,IAAI;AAAA;;;AC7DtB,eAAsB,QAAQ,CAC7B,OACuD;AAAA,EACvD,IAAI,MAAM,SAAS;AAAA,IAAQ;AAAA,EAC3B,IAAI,MAAM,SAAS;AAAA,IAAQ,OAAO,EAAE,KAAK,MAAM,KAAK;AAAA,EAEpD,MAAM,OAAO,MAAM,aAAa,MAAM,IAAI;AAAA,EAC1C,OAAO,EAAE,KAAK,KAAK;AAAA;AAGb,SAAS,qBAAqB,CAAC,MAAuB;AAAA,EAC5D,MAAM,UAAU,KAAK,UAAU;AAAA,EAC/B,IAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG,GAAG;AAAA,IACvD,OAAO,KAAK,MAAM,IAAI;AAAA,EACvB;AAAA,EACA,OAAO,iBAAiB,IAAI;AAAA;",
|
|
9
|
+
"debugId": "9F5BDD3591FC0D3E64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/collect.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,GAC5B,MAAM,EAAE,CAEV"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/collect.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export function collectRepeatable(\n\tvalue: string,\n\tprevious: string[] | undefined,\n): string[] {\n\treturn [...(previous ?? []), value];\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAO,SAAS,iBAAiB,CAChC,OACA,UACW;AAAA,EACX,OAAO,CAAC,GAAI,YAAY,CAAC,GAAI,KAAK;AAAA;",
|
|
8
|
+
"debugId": "2D9C77C5781D4BD364756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-runtime compatibility utilities for Bun and Node.js
|
|
3
|
+
*
|
|
4
|
+
* This module provides abstractions over Bun-specific APIs to allow
|
|
5
|
+
* the exec command to run in Node.js while compile remains Bun-only.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Detect if we're running in Bun
|
|
9
|
+
*/
|
|
10
|
+
export declare const isBun: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Read a file's text content - works in both Bun and Node.js
|
|
13
|
+
*/
|
|
14
|
+
export declare function readFileText(path: string): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a file exists - works in both Bun and Node.js
|
|
17
|
+
*/
|
|
18
|
+
export declare function fileExists(path: string): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Write text to a file - works in both Bun and Node.js
|
|
21
|
+
*/
|
|
22
|
+
export declare function writeFileText(path: string, content: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Create directory recursively - works in both Bun and Node.js
|
|
25
|
+
*/
|
|
26
|
+
export declare function mkdirp(path: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Parse YAML content - works in both Bun and Node.js
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseYamlContent(text: string): unknown;
|
|
31
|
+
/**
|
|
32
|
+
* Read from stdin - works in both Bun and Node.js
|
|
33
|
+
*/
|
|
34
|
+
export declare function readStdinText(): Promise<string>;
|
|
35
|
+
//# sourceMappingURL=compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/compat.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,eAAO,MAAM,KAAK,SAAwC,CAAC;AAE3D;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKhE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAK/D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMtD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAcrD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/cli/runtime/compat.ts
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
var isBun = typeof globalThis.Bun !== "undefined";
|
|
5
|
+
async function readFileText(path) {
|
|
6
|
+
if (isBun) {
|
|
7
|
+
return Bun.file(path).text();
|
|
8
|
+
}
|
|
9
|
+
return readFileSync(path, "utf-8");
|
|
10
|
+
}
|
|
11
|
+
async function fileExists(path) {
|
|
12
|
+
if (isBun) {
|
|
13
|
+
return Bun.file(path).exists();
|
|
14
|
+
}
|
|
15
|
+
return existsSync(path);
|
|
16
|
+
}
|
|
17
|
+
async function writeFileText(path, content) {
|
|
18
|
+
if (isBun) {
|
|
19
|
+
await Bun.write(path, content);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
writeFileSync(path, content, "utf-8");
|
|
23
|
+
}
|
|
24
|
+
async function mkdirp(path) {
|
|
25
|
+
if (isBun) {
|
|
26
|
+
await Bun.$`mkdir -p ${path}`;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
mkdirSync(path, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
function parseYamlContent(text) {
|
|
32
|
+
if (isBun) {
|
|
33
|
+
const { YAML } = globalThis.Bun;
|
|
34
|
+
return YAML.parse(text);
|
|
35
|
+
}
|
|
36
|
+
return parseYaml(text);
|
|
37
|
+
}
|
|
38
|
+
async function readStdinText() {
|
|
39
|
+
if (isBun) {
|
|
40
|
+
return Bun.stdin.text();
|
|
41
|
+
}
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
let data = "";
|
|
44
|
+
process.stdin.setEncoding("utf8");
|
|
45
|
+
process.stdin.on("data", (chunk) => {
|
|
46
|
+
data += chunk;
|
|
47
|
+
});
|
|
48
|
+
process.stdin.on("end", () => resolve(data));
|
|
49
|
+
process.stdin.on("error", reject);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
writeFileText,
|
|
54
|
+
readStdinText,
|
|
55
|
+
readFileText,
|
|
56
|
+
parseYamlContent,
|
|
57
|
+
mkdirp,
|
|
58
|
+
isBun,
|
|
59
|
+
fileExists
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
//# debugId=9FD9ABD74376328F64756E2164756E21
|