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,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/body-flags.ts", "../../../../src/cli/runtime/auth/resolve.ts", "../../../../src/cli/runtime/compat.ts", "../../../../src/cli/runtime/profile/secrets.ts", "../../../../src/cli/runtime/profile/store.ts", "../../../../src/cli/runtime/template.ts", "../../../../src/cli/runtime/server-url.ts", "../../../../src/cli/runtime/validate/ajv.ts", "../../../../src/cli/runtime/validate/coerce.ts", "../../../../src/cli/runtime/validate/error.ts", "../../../../src/cli/runtime/validate/schema.ts", "../../../../src/cli/runtime/request.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
|
+
"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",
|
|
7
|
+
"/**\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",
|
|
8
|
+
"import { isBun } from \"../compat.ts\";\n\nconst bunLiteral = \"bun\" as const;\n\nexport type SecretKey = {\n\tservice: string;\n\tname: string;\n};\n\nexport function secretServiceForSpec(specId: string): string {\n\treturn `specli:${specId}`;\n}\n\nexport function tokenSecretKey(specId: string, profile: string): SecretKey {\n\treturn {\n\t\tservice: secretServiceForSpec(specId),\n\t\tname: `profile:${profile}:token`,\n\t};\n}\n\n/**\n * Store a token securely.\n * In Bun: uses the native secrets store (system keychain)\n * In Node.js: secrets are not supported, warns user\n */\nexport async function setToken(\n\tspecId: string,\n\tprofile: string,\n\ttoken: string,\n): Promise<void> {\n\tif (!isBun) {\n\t\tconsole.warn(\n\t\t\t\"Warning: Secure token storage requires Bun. Token will not be persisted.\",\n\t\t);\n\t\tconsole.warn(\n\t\t\t\"Use --bearer-token <token> flag instead when running with Node.js.\",\n\t\t);\n\t\treturn;\n\t}\n\n\tconst { secrets } = await import(bunLiteral);\n\tconst key = tokenSecretKey(specId, profile);\n\tawait secrets.set({ service: key.service, name: key.name, value: token });\n}\n\n/**\n * Retrieve a stored token.\n * In Bun: retrieves from the native secrets store\n * In Node.js: returns null (secrets not supported)\n */\nexport async function getToken(\n\tspecId: string,\n\tprofile: string,\n): Promise<string | null> {\n\tif (!isBun) {\n\t\treturn null;\n\t}\n\n\tconst { secrets } = await import(bunLiteral);\n\tconst key = tokenSecretKey(specId, profile);\n\treturn await secrets.get({ service: key.service, name: key.name });\n}\n\n/**\n * Delete a stored token.\n * In Bun: removes from the native secrets store\n * In Node.js: returns false (secrets not supported)\n */\nexport async function deleteToken(\n\tspecId: string,\n\tprofile: string,\n): Promise<boolean> {\n\tif (!isBun) {\n\t\tconsole.warn(\n\t\t\t\"Warning: Secure token storage requires Bun. No token to delete.\",\n\t\t);\n\t\treturn false;\n\t}\n\n\tconst { secrets } = await import(bunLiteral);\n\tconst key = tokenSecretKey(specId, profile);\n\treturn await secrets.delete({ service: key.service, name: key.name });\n}\n",
|
|
9
|
+
"import {\n\tfileExists,\n\tmkdirp,\n\tparseYamlContent,\n\treadFileText,\n\twriteFileText,\n} from \"../compat.ts\";\n\nexport type Profile = {\n\tname: string;\n\tserver?: string;\n\tauthScheme?: string;\n\t// For apiKey schemes we also need the apiKey name/in from spec to inject,\n\t// but that is discoverable from the spec at runtime.\n};\n\nexport type ProfilesFile = {\n\tprofiles: Profile[];\n\tdefaultProfile?: string;\n};\n\nfunction configDir(): string {\n\t// Keep it simple (v1). We can move to env-paths later.\n\tconst home = process.env.HOME;\n\tif (!home) throw new Error(\"Missing HOME env var\");\n\treturn `${home}/.config/specli`;\n}\n\nfunction configPathJson(): string {\n\treturn `${configDir()}/profiles.json`;\n}\n\nfunction configPathYaml(): string {\n\treturn `${configDir()}/profiles.yaml`;\n}\n\nexport async function readProfiles(): Promise<ProfilesFile> {\n\tconst jsonPath = configPathJson();\n\tconst yamlPath = configPathYaml();\n\n\tconst jsonExists = await fileExists(jsonPath);\n\tconst yamlExists = await fileExists(yamlPath);\n\n\tconst filePath = jsonExists ? jsonPath : yamlExists ? yamlPath : null;\n\n\tif (!filePath) return { profiles: [] };\n\n\tconst text = await readFileText(filePath);\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = parseYamlContent(text) as unknown;\n\t} catch {\n\t\tparsed = JSON.parse(text) as unknown;\n\t}\n\n\tconst obj =\n\t\tparsed && typeof parsed === \"object\"\n\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t: {};\n\tconst profiles = Array.isArray(obj.profiles)\n\t\t? (obj.profiles as Profile[])\n\t\t: [];\n\n\treturn {\n\t\tprofiles: profiles.filter(Boolean),\n\t\tdefaultProfile:\n\t\t\ttypeof obj.defaultProfile === \"string\"\n\t\t\t\t? (obj.defaultProfile as string)\n\t\t\t\t: undefined,\n\t};\n}\n\nexport async function writeProfiles(data: ProfilesFile): Promise<void> {\n\tconst dir = configDir();\n\tawait mkdirp(dir);\n\tawait writeFileText(configPathJson(), JSON.stringify(data, null, 2));\n}\n\nexport function getProfile(\n\tdata: ProfilesFile,\n\tname: string | undefined,\n): Profile | undefined {\n\tconst wanted = name ?? data.defaultProfile;\n\tif (!wanted) return undefined;\n\treturn data.profiles.find((p) => p?.name === wanted);\n}\n\nexport function upsertProfile(\n\tdata: ProfilesFile,\n\tprofile: Profile,\n): ProfilesFile {\n\tconst profiles = data.profiles.filter((p) => p.name !== profile.name);\n\tprofiles.push(profile);\n\tprofiles.sort((a, b) => a.name.localeCompare(b.name));\n\treturn { ...data, profiles };\n}\n\nexport function removeProfile(data: ProfilesFile, name: string): ProfilesFile {\n\treturn { ...data, profiles: data.profiles.filter((p) => p.name !== name) };\n}\n",
|
|
10
|
+
"export function extractTemplateVars(template: string): string[] {\n\tconst out: string[] = [];\n\tconst re = /\\{([^}]+)\\}/g;\n\twhile (true) {\n\t\tconst match = re.exec(template);\n\t\tif (!match) break;\n\t\tout.push((match[1] ?? \"\").trim());\n\t}\n\treturn out.filter(Boolean);\n}\n\nexport function applyTemplate(\n\ttemplate: string,\n\tvars: Record<string, string>,\n\toptions?: { encode?: boolean },\n): string {\n\tconst encode = options?.encode ?? false;\n\treturn template.replace(/\\{([^}]+)\\}/g, (_, rawName) => {\n\t\tconst name = String(rawName).trim();\n\t\tconst value = vars[name];\n\t\tif (typeof value !== \"string\") {\n\t\t\tthrow new Error(`Missing template variable: ${name}`);\n\t\t}\n\t\treturn encode ? encodeURIComponent(value) : value;\n\t});\n}\n",
|
|
11
|
+
"import type { ServerInfo } from \"../server.ts\";\n\nimport { applyTemplate, extractTemplateVars } from \"./template.ts\";\n\nexport type ResolveServerInput = {\n\tserverOverride?: string;\n\tservers: ServerInfo[];\n\tserverVars: Record<string, string>;\n};\n\nexport function resolveServerUrl(input: ResolveServerInput): string {\n\t// Treat empty string as undefined (serverOverride can come from env vars or profiles)\n\tconst base = input.serverOverride || input.servers[0]?.url;\n\tif (!base) {\n\t\tthrow new Error(\n\t\t\t\"No server URL found. Provide --server <url> or define servers in the OpenAPI spec.\",\n\t\t);\n\t}\n\n\tconst names = extractTemplateVars(base);\n\tif (!names.length) return base;\n\n\tconst vars: Record<string, string> = {};\n\tfor (const name of names) {\n\t\tconst provided = input.serverVars[name];\n\t\tif (typeof provided === \"string\") {\n\t\t\tvars[name] = provided;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If spec has default for this var, use it.\n\t\tconst match = input.servers.find((s) => s.url === base);\n\t\tconst v = match?.variables.find((x) => x.name === name);\n\t\tif (typeof v?.default === \"string\") {\n\t\t\tvars[name] = v.default;\n\t\t\tcontinue;\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Missing server variable '${name}'. Provide --server-var ${name}=...`,\n\t\t);\n\t}\n\n\treturn applyTemplate(base, vars);\n}\n",
|
|
12
|
+
"import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\n\nexport function createAjv() {\n\tconst ajv = new Ajv({\n\t\tallErrors: true,\n\t\tstrict: false,\n\t\tcoerceTypes: false,\n\t});\n\n\taddFormats(ajv);\n\treturn ajv;\n}\n",
|
|
13
|
+
"import { InvalidArgumentError } from \"commander\";\n\nimport type { ParamType } from \"../../schema-shape.ts\";\n\nexport function coerceValue(raw: string, type: ParamType): unknown {\n\tif (type === \"string\" || type === \"unknown\") return raw;\n\n\tif (type === \"boolean\") {\n\t\t// Commander boolean options are handled without a value; keep for completeness.\n\t\tif (raw === \"true\") return true;\n\t\tif (raw === \"false\") return false;\n\t\tthrow new InvalidArgumentError(`Expected boolean, got '${raw}'`);\n\t}\n\n\tif (type === \"integer\") {\n\t\tconst n = Number.parseInt(raw, 10);\n\t\tif (!Number.isFinite(n))\n\t\t\tthrow new InvalidArgumentError(`Expected integer, got '${raw}'`);\n\t\treturn n;\n\t}\n\n\tif (type === \"number\") {\n\t\tconst n = Number(raw);\n\t\tif (!Number.isFinite(n))\n\t\t\tthrow new InvalidArgumentError(`Expected number, got '${raw}'`);\n\t\treturn n;\n\t}\n\n\t// For now, accept objects as JSON strings.\n\tif (type === \"object\") {\n\t\ttry {\n\t\t\treturn JSON.parse(raw);\n\t\t} catch {\n\t\t\tthrow new InvalidArgumentError(\n\t\t\t\t`Expected JSON object, got '${raw}'. Use --data/--file for complex bodies.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Arrays should usually be passed as repeatable flags or comma-separated,\n\t// but allow JSON arrays too.\n\tif (type === \"array\") {\n\t\treturn coerceArrayInput(raw, \"string\");\n\t}\n\n\treturn raw;\n}\n\nexport function coerceArrayInput(raw: string, itemType: ParamType): unknown[] {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return [];\n\n\tif (trimmed.startsWith(\"[\")) {\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(trimmed);\n\t\t} catch {\n\t\t\tthrow new InvalidArgumentError(`Expected JSON array, got '${raw}'`);\n\t\t}\n\t\tif (!Array.isArray(parsed)) {\n\t\t\tthrow new InvalidArgumentError(`Expected JSON array, got '${raw}'`);\n\t\t}\n\t\treturn parsed.map((v) => coerceValue(String(v), itemType));\n\t}\n\n\treturn trimmed\n\t\t.split(\",\")\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean)\n\t\t.map((s) => coerceValue(s, itemType));\n}\n",
|
|
14
|
+
"import type { ErrorObject } from \"ajv\";\n\nexport function formatAjvErrors(\n\terrors: ErrorObject[] | null | undefined,\n): string {\n\tif (!errors?.length) return \"Invalid input\";\n\n\treturn errors\n\t\t.map((e) => {\n\t\t\tconst path = e.instancePath || e.schemaPath || \"\";\n\n\t\t\tif (\n\t\t\t\te.keyword === \"required\" &&\n\t\t\t\te.params &&\n\t\t\t\ttypeof e.params === \"object\" &&\n\t\t\t\t\"missingProperty\" in e.params\n\t\t\t) {\n\t\t\t\tconst missing = String(\n\t\t\t\t\t(e.params as { missingProperty?: unknown }).missingProperty,\n\t\t\t\t);\n\t\t\t\tconst where = e.instancePath || \"/\";\n\t\t\t\treturn `${where} missing required property '${missing}'`.trim();\n\t\t\t}\n\n\t\t\tconst msg = e.message || \"invalid\";\n\t\t\treturn `${path} ${msg}`.trim();\n\t\t})\n\t\t.join(\"\\n\");\n}\n",
|
|
15
|
+
"import type { CommandAction } from \"../../command-model.ts\";\nimport type { JsonSchema } from \"../../types.ts\";\n\nexport type ValidationSchemas = {\n\tquerySchema?: JsonSchema;\n\theaderSchema?: JsonSchema;\n\tcookieSchema?: JsonSchema;\n};\n\ntype ObjectSchema = {\n\ttype: \"object\";\n\tproperties: Record<string, JsonSchema>;\n\trequired?: string[];\n};\n\nexport function deriveValidationSchemas(\n\taction: CommandAction,\n): ValidationSchemas {\n\t// We validate only simple containers for now.\n\t// Deep style/encoding differences for OpenAPI params are out of scope for v1.\n\tconst query: ObjectSchema = { type: \"object\", properties: {}, required: [] };\n\tconst header: ObjectSchema = { type: \"object\", properties: {}, required: [] };\n\tconst cookie: ObjectSchema = { type: \"object\", properties: {}, required: [] };\n\n\tfor (const p of action.params) {\n\t\tif (p.kind !== \"flag\") continue;\n\t\tconst target =\n\t\t\tp.in === \"query\"\n\t\t\t\t? query\n\t\t\t\t: p.in === \"header\"\n\t\t\t\t\t? header\n\t\t\t\t\t: p.in === \"cookie\"\n\t\t\t\t\t\t? cookie\n\t\t\t\t\t\t: undefined;\n\t\tif (!target) continue;\n\n\t\tconst schema = p.schema ?? (p.type === \"unknown\" ? {} : { type: p.type });\n\t\ttarget.properties[p.name] = schema;\n\t\tif (p.required) {\n\t\t\tif (!target.required) target.required = [];\n\t\t\ttarget.required.push(p.name);\n\t\t}\n\t}\n\n\tif (!query.required?.length) delete query.required;\n\tif (!header.required?.length) delete header.required;\n\tif (!cookie.required?.length) delete cookie.required;\n\n\treturn {\n\t\tquerySchema: Object.keys(query.properties).length ? query : undefined,\n\t\theaderSchema: Object.keys(header.properties).length ? header : undefined,\n\t\tcookieSchema: Object.keys(cookie.properties).length ? cookie : undefined,\n\t};\n}\n",
|
|
16
|
+
"import type { AuthScheme } from \"../auth-schemes.ts\";\nimport type { CommandAction } from \"../command-model.ts\";\n\nimport { resolveAuthScheme } from \"./auth/resolve.ts\";\nimport { getToken } from \"./profile/secrets.ts\";\nimport { getProfile, readProfiles } from \"./profile/store.ts\";\nimport { resolveServerUrl } from \"./server-url.ts\";\nimport { applyTemplate } from \"./template.ts\";\nimport {\n\tcreateAjv,\n\tderiveValidationSchemas,\n\tformatAjvErrors,\n} from \"./validate/index.ts\";\n\nexport type RuntimeGlobals = {\n\tspec?: string;\n\tserver?: string;\n\tserverVar?: string[];\n\n\tcurl?: boolean;\n\tjson?: boolean;\n\n\tauth?: string;\n\tbearerToken?: string;\n\toauthToken?: string;\n\tusername?: string;\n\tpassword?: string;\n\tapiKey?: string;\n};\n\nfunction parseKeyValuePairs(\n\tpairs: string[] | undefined,\n): Record<string, string> {\n\tconst out: Record<string, string> = {};\n\tfor (const pair of pairs ?? []) {\n\t\tconst idx = pair.indexOf(\"=\");\n\t\tif (idx === -1)\n\t\t\tthrow new Error(`Invalid pair '${pair}', expected name=value`);\n\t\tconst name = pair.slice(0, idx).trim();\n\t\tconst value = pair.slice(idx + 1).trim();\n\t\tif (!name) throw new Error(`Invalid pair '${pair}', missing name`);\n\t\tout[name] = value;\n\t}\n\treturn out;\n}\n\nfunction _parseTimeoutMs(value: string | undefined): number | undefined {\n\tif (!value) return undefined;\n\tconst n = Number(value);\n\tif (!Number.isFinite(n) || n <= 0)\n\t\tthrow new Error(\"--timeout must be a positive number\");\n\treturn n;\n}\n\nfunction pickAuthSchemeKey(\n\taction: CommandAction,\n\tglobals: RuntimeGlobals,\n): string | undefined {\n\tif (globals.auth) return globals.auth;\n\n\t// If operation declares a single requirement set with a single scheme, default to it.\n\tconst req = action.auth.alternatives;\n\tif (req.length === 1 && req[0]?.length === 1) {\n\t\treturn req[0][0]?.key;\n\t}\n\n\treturn undefined;\n}\n\nfunction applyAuth(\n\theaders: Headers,\n\turl: URL,\n\taction: CommandAction,\n\tglobals: RuntimeGlobals,\n\tauthSchemes: AuthScheme[],\n): { headers: Headers; url: URL } {\n\tconst schemeKey = pickAuthSchemeKey(action, globals);\n\tif (!schemeKey) return { headers, url };\n\n\tconst scheme = authSchemes.find((s) => s.key === schemeKey);\n\tif (!scheme) {\n\t\tthrow new Error(\n\t\t\t`Unknown auth scheme '${schemeKey}'. Available: ${authSchemes\n\t\t\t\t.map((s) => s.key)\n\t\t\t\t.join(\", \")}`,\n\t\t);\n\t}\n\n\tif (\n\t\tscheme.kind === \"http-bearer\" ||\n\t\tscheme.kind === \"oauth2\" ||\n\t\tscheme.kind === \"openIdConnect\"\n\t) {\n\t\tconst token = globals.bearerToken ?? globals.oauthToken;\n\t\tif (!token)\n\t\t\tthrow new Error(\"Missing token. Provide --bearer-token <token>.\");\n\t\theaders.set(\"Authorization\", `Bearer ${token}`);\n\t\treturn { headers, url };\n\t}\n\n\tif (scheme.kind === \"http-basic\") {\n\t\tif (!globals.username) throw new Error(\"Missing --username for basic auth\");\n\t\tif (!globals.password) throw new Error(\"Missing --password for basic auth\");\n\t\tconst raw = `${globals.username}:${globals.password}`;\n\t\tconst encoded = Buffer.from(raw, \"utf8\").toString(\"base64\");\n\t\theaders.set(\"Authorization\", `Basic ${encoded}`);\n\t\treturn { headers, url };\n\t}\n\n\tif (scheme.kind === \"api-key\") {\n\t\tif (!scheme.name)\n\t\t\tthrow new Error(`apiKey scheme '${scheme.key}' missing name`);\n\t\tif (!scheme.in)\n\t\t\tthrow new Error(`apiKey scheme '${scheme.key}' missing location`);\n\t\tif (!globals.apiKey) throw new Error(\"Missing --api-key for apiKey auth\");\n\n\t\tif (scheme.in === \"header\") {\n\t\t\theaders.set(scheme.name, globals.apiKey);\n\t\t}\n\t\tif (scheme.in === \"query\") {\n\t\t\turl.searchParams.set(scheme.name, globals.apiKey);\n\t\t}\n\t\tif (scheme.in === \"cookie\") {\n\t\t\tconst existing = headers.get(\"Cookie\");\n\t\t\tconst part = `${scheme.name}=${globals.apiKey}`;\n\t\t\theaders.set(\"Cookie\", existing ? `${existing}; ${part}` : part);\n\t\t}\n\n\t\treturn { headers, url };\n\t}\n\n\treturn { headers, url };\n}\n\nexport type EmbeddedDefaults = {\n\tserver?: string;\n\tserverVars?: string[];\n\tauth?: string;\n};\n\nexport type BuildRequestInput = {\n\tspecId: string;\n\taction: CommandAction;\n\tpositionalValues: string[];\n\tflagValues: Record<string, unknown>;\n\tglobals: RuntimeGlobals;\n\tservers: import(\"../server.ts\").ServerInfo[];\n\tauthSchemes: AuthScheme[];\n\tembeddedDefaults?: EmbeddedDefaults;\n\tbodyFlagDefs?: import(\"./body-flags.ts\").BodyFlagDef[];\n};\n\nexport async function buildRequest(\n\tinput: BuildRequestInput,\n): Promise<{ request: Request; curl: string }> {\n\t// Always use the \"default\" profile for simplicity\n\tconst defaultProfileName = \"default\";\n\tconst profilesFile = await readProfiles();\n\tconst profile = getProfile(profilesFile, defaultProfileName);\n\tconst embedded = input.embeddedDefaults;\n\n\t// Merge server vars: CLI flags override embedded defaults\n\tconst embeddedServerVars = parseKeyValuePairs(embedded?.serverVars);\n\tconst cliServerVars = parseKeyValuePairs(input.globals.serverVar);\n\tconst serverVars = { ...embeddedServerVars, ...cliServerVars };\n\n\t// Priority: CLI flag > profile > embedded default\n\tconst serverUrl = resolveServerUrl({\n\t\tserverOverride: input.globals.server ?? profile?.server ?? embedded?.server,\n\t\tservers: input.servers,\n\t\tserverVars,\n\t});\n\n\t// Path params: action.positionals order matches templated params order.\n\tconst pathVars: Record<string, string> = {};\n\tfor (let i = 0; i < input.action.positionals.length; i++) {\n\t\tconst pos = input.action.positionals[i];\n\t\tconst raw = input.action.pathArgs[i];\n\t\tconst value = input.positionalValues[i];\n\t\tif (typeof raw === \"string\" && typeof value === \"string\") {\n\t\t\tpathVars[raw] = value;\n\t\t}\n\t\t// Use cli name too as fallback\n\t\tif (pos?.name && typeof value === \"string\") {\n\t\t\tpathVars[pos.name] = value;\n\t\t}\n\t}\n\n\tconst path = applyTemplate(input.action.path, pathVars, { encode: true });\n\n\t// Build the full URL by combining server URL and path.\n\t// We need to handle the case where path starts with \"/\" carefully:\n\t// URL constructor treats absolute paths as relative to origin, not base path.\n\tconst baseUrl = serverUrl.endsWith(\"/\") ? serverUrl : `${serverUrl}/`;\n\tconst relativePath = path.startsWith(\"/\") ? path.slice(1) : path;\n\tconst url = new URL(relativePath, baseUrl);\n\n\tconst headers = new Headers();\n\n\t// Collect declared params for validation.\n\tconst queryValues: Record<string, unknown> = {};\n\tconst headerValues: Record<string, unknown> = {};\n\tconst cookieValues: Record<string, unknown> = {};\n\n\tfor (const p of input.action.params) {\n\t\tif (p.kind !== \"flag\") continue;\n\t\tconst optValue = input.flagValues[optionKeyFromFlag(p.flag)];\n\t\tif (typeof optValue === \"undefined\") continue;\n\n\t\tif (p.in === \"query\") {\n\t\t\tqueryValues[p.name] = optValue;\n\t\t}\n\t\tif (p.in === \"header\") {\n\t\t\theaderValues[p.name] = optValue;\n\t\t}\n\t\tif (p.in === \"cookie\") {\n\t\t\tcookieValues[p.name] = optValue;\n\t\t}\n\t}\n\n\t// Validate params (query/header/cookie) using Ajv.\n\tconst schemas = deriveValidationSchemas(input.action);\n\tconst ajv = createAjv();\n\n\tif (schemas.querySchema) {\n\t\tconst validate = ajv.compile(schemas.querySchema);\n\t\tif (!validate(queryValues)) {\n\t\t\tthrow new Error(formatAjvErrors(validate.errors));\n\t\t}\n\t}\n\tif (schemas.headerSchema) {\n\t\tconst validate = ajv.compile(schemas.headerSchema);\n\t\tif (!validate(headerValues)) {\n\t\t\tthrow new Error(formatAjvErrors(validate.errors));\n\t\t}\n\t}\n\tif (schemas.cookieSchema) {\n\t\tconst validate = ajv.compile(schemas.cookieSchema);\n\t\tif (!validate(cookieValues)) {\n\t\t\tthrow new Error(formatAjvErrors(validate.errors));\n\t\t}\n\t}\n\n\t// Apply params -> query/header/cookie\n\tfor (const [name, value] of Object.entries(queryValues)) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const item of value) {\n\t\t\t\turl.searchParams.append(name, String(item));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\turl.searchParams.set(name, String(value));\n\t}\n\tfor (const [name, value] of Object.entries(headerValues)) {\n\t\theaders.set(name, String(value));\n\t}\n\tfor (const [name, value] of Object.entries(cookieValues)) {\n\t\tconst existing = headers.get(\"Cookie\");\n\t\tconst part = `${name}=${String(value)}`;\n\t\theaders.set(\"Cookie\", existing ? `${existing}; ${part}` : part);\n\t}\n\n\tlet body: string | undefined;\n\tif (input.action.requestBody) {\n\t\t// Check if any body flags were provided using the flag definitions\n\t\tconst bodyFlagDefs = input.bodyFlagDefs ?? [];\n\t\tconst hasBodyFlags = bodyFlagDefs.some((def) => {\n\t\t\t// Commander keeps dots in option names: --address.street -> \"address.street\"\n\t\t\tconst dotKey = def.path.join(\".\");\n\t\t\treturn input.flagValues[dotKey] !== undefined;\n\t\t});\n\n\t\tconst contentType = input.action.requestBody.preferredContentType;\n\t\tif (contentType) headers.set(\"Content-Type\", contentType);\n\n\t\tconst schema = input.action.requestBodySchema;\n\n\t\t// Check if there are any required fields in the body\n\t\tconst requiredFields = bodyFlagDefs.filter((d) => d.required);\n\n\t\tif (!hasBodyFlags) {\n\t\t\tif (requiredFields.length > 0) {\n\t\t\t\t// Error: user must provide required fields\n\t\t\t\tconst flagList = requiredFields.map((d) => `--${d.path.join(\".\")}`);\n\t\t\t\tthrow new Error(`Required: ${flagList.join(\", \")}`);\n\t\t\t}\n\t\t\t// No required fields - send empty body if body is required, otherwise skip\n\t\t\tif (input.action.requestBody.required) {\n\t\t\t\tbody = \"{}\";\n\t\t\t}\n\t\t} else {\n\t\t\tif (!contentType?.includes(\"json\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Body field flags are only supported for JSON request bodies.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check for missing required fields\n\t\t\tconst { findMissingRequired, parseDotNotationFlags } = await import(\n\t\t\t\t\"./body-flags.ts\"\n\t\t\t);\n\t\t\tconst missing = findMissingRequired(input.flagValues, bodyFlagDefs);\n\t\t\tif (missing.length > 0) {\n\t\t\t\tconst missingFlags = missing.map((m) => `--${m}`).join(\", \");\n\t\t\t\tthrow new Error(`Missing required fields: ${missingFlags}`);\n\t\t\t}\n\n\t\t\t// Build nested object from dot-notation flags\n\t\t\tconst built = parseDotNotationFlags(input.flagValues, bodyFlagDefs);\n\n\t\t\tif (schema) {\n\t\t\t\tconst validate = ajv.compile(schema);\n\t\t\t\tif (!validate(built)) {\n\t\t\t\t\tthrow new Error(formatAjvErrors(validate.errors));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbody = JSON.stringify(built);\n\t\t}\n\t}\n\n\t// Check if user has a stored token (needed for auth scheme auto-selection)\n\tconst storedToken = profile?.name\n\t\t? await getToken(input.specId, profile.name)\n\t\t: null;\n\n\t// Auth resolution priority: CLI flag > profile > embedded default\n\tconst resolvedAuthScheme = resolveAuthScheme(\n\t\tinput.authSchemes,\n\t\tinput.action.auth,\n\t\t{\n\t\t\tflagAuthScheme: input.globals.auth,\n\t\t\tprofileAuthScheme: profile?.authScheme,\n\t\t\tembeddedAuthScheme: embedded?.auth,\n\t\t\thasStoredToken: Boolean(storedToken),\n\t\t},\n\t);\n\n\tconst tokenFromProfile = resolvedAuthScheme ? storedToken : null;\n\n\tconst globalsWithProfileAuth: RuntimeGlobals = {\n\t\t...input.globals,\n\t\tauth: resolvedAuthScheme,\n\t\tbearerToken:\n\t\t\tinput.globals.bearerToken ??\n\t\t\tinput.globals.oauthToken ??\n\t\t\ttokenFromProfile ??\n\t\t\tundefined,\n\t};\n\n\tconst final = applyAuth(\n\t\theaders,\n\t\turl,\n\t\tinput.action,\n\t\tglobalsWithProfileAuth,\n\t\tinput.authSchemes,\n\t);\n\n\tconst req = new Request(final.url.toString(), {\n\t\tmethod: input.action.method,\n\t\theaders: final.headers,\n\t\tbody,\n\t});\n\n\tconst curl = buildCurl(req, body);\n\treturn { request: req, curl };\n}\n\nfunction buildCurl(req: Request, body: string | undefined): string {\n\tconst parts: string[] = [\"curl\", \"-sS\", \"-X\", req.method];\n\tfor (const [k, v] of req.headers.entries()) {\n\t\tparts.push(\"-H\", shellQuote(`${k}: ${v}`));\n\t}\n\tif (typeof body === \"string\") {\n\t\tparts.push(\"--data\", shellQuote(body));\n\t}\n\tparts.push(shellQuote(req.url));\n\treturn parts.join(\" \");\n}\n\nfunction shellQuote(value: string): string {\n\treturn `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction optionKeyFromFlag(flag: string): string {\n\t// Commander uses camelCase property names derived from long flag.\n\t// Example: --x-request-id -> xRequestId\n\tconst name = flag.replace(/^--/, \"\");\n\treturn name.replace(/-([a-z])/g, (_, c) => String(c).toUpperCase());\n}\n"
|
|
17
|
+
],
|
|
18
|
+
"mappings": "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",
|
|
19
|
+
"debugId": "BCA27B5B66AE934264756E2164756E21",
|
|
20
|
+
"names": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ServerInfo } from "../server.js";
|
|
2
|
+
export type ResolveServerInput = {
|
|
3
|
+
serverOverride?: string;
|
|
4
|
+
servers: ServerInfo[];
|
|
5
|
+
serverVars: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
export declare function resolveServerUrl(input: ResolveServerInput): string;
|
|
8
|
+
//# sourceMappingURL=server-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-url.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/server-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,MAAM,MAAM,kBAAkB,GAAG;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAkClE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/cli/runtime/template.ts
|
|
2
|
+
function extractTemplateVars(template) {
|
|
3
|
+
const out = [];
|
|
4
|
+
const re = /\{([^}]+)\}/g;
|
|
5
|
+
while (true) {
|
|
6
|
+
const match = re.exec(template);
|
|
7
|
+
if (!match)
|
|
8
|
+
break;
|
|
9
|
+
out.push((match[1] ?? "").trim());
|
|
10
|
+
}
|
|
11
|
+
return out.filter(Boolean);
|
|
12
|
+
}
|
|
13
|
+
function applyTemplate(template, vars, options) {
|
|
14
|
+
const encode = options?.encode ?? false;
|
|
15
|
+
return template.replace(/\{([^}]+)\}/g, (_, rawName) => {
|
|
16
|
+
const name = String(rawName).trim();
|
|
17
|
+
const value = vars[name];
|
|
18
|
+
if (typeof value !== "string") {
|
|
19
|
+
throw new Error(`Missing template variable: ${name}`);
|
|
20
|
+
}
|
|
21
|
+
return encode ? encodeURIComponent(value) : value;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/cli/runtime/server-url.ts
|
|
26
|
+
function resolveServerUrl(input) {
|
|
27
|
+
const base = input.serverOverride || input.servers[0]?.url;
|
|
28
|
+
if (!base) {
|
|
29
|
+
throw new Error("No server URL found. Provide --server <url> or define servers in the OpenAPI spec.");
|
|
30
|
+
}
|
|
31
|
+
const names = extractTemplateVars(base);
|
|
32
|
+
if (!names.length)
|
|
33
|
+
return base;
|
|
34
|
+
const vars = {};
|
|
35
|
+
for (const name of names) {
|
|
36
|
+
const provided = input.serverVars[name];
|
|
37
|
+
if (typeof provided === "string") {
|
|
38
|
+
vars[name] = provided;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const match = input.servers.find((s) => s.url === base);
|
|
42
|
+
const v = match?.variables.find((x) => x.name === name);
|
|
43
|
+
if (typeof v?.default === "string") {
|
|
44
|
+
vars[name] = v.default;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Missing server variable '${name}'. Provide --server-var ${name}=...`);
|
|
48
|
+
}
|
|
49
|
+
return applyTemplate(base, vars);
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
resolveServerUrl
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
//# debugId=9629F0B7415413A164756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/template.ts", "../../../../src/cli/runtime/server-url.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export function extractTemplateVars(template: string): string[] {\n\tconst out: string[] = [];\n\tconst re = /\\{([^}]+)\\}/g;\n\twhile (true) {\n\t\tconst match = re.exec(template);\n\t\tif (!match) break;\n\t\tout.push((match[1] ?? \"\").trim());\n\t}\n\treturn out.filter(Boolean);\n}\n\nexport function applyTemplate(\n\ttemplate: string,\n\tvars: Record<string, string>,\n\toptions?: { encode?: boolean },\n): string {\n\tconst encode = options?.encode ?? false;\n\treturn template.replace(/\\{([^}]+)\\}/g, (_, rawName) => {\n\t\tconst name = String(rawName).trim();\n\t\tconst value = vars[name];\n\t\tif (typeof value !== \"string\") {\n\t\t\tthrow new Error(`Missing template variable: ${name}`);\n\t\t}\n\t\treturn encode ? encodeURIComponent(value) : value;\n\t});\n}\n",
|
|
6
|
+
"import type { ServerInfo } from \"../server.ts\";\n\nimport { applyTemplate, extractTemplateVars } from \"./template.ts\";\n\nexport type ResolveServerInput = {\n\tserverOverride?: string;\n\tservers: ServerInfo[];\n\tserverVars: Record<string, string>;\n};\n\nexport function resolveServerUrl(input: ResolveServerInput): string {\n\t// Treat empty string as undefined (serverOverride can come from env vars or profiles)\n\tconst base = input.serverOverride || input.servers[0]?.url;\n\tif (!base) {\n\t\tthrow new Error(\n\t\t\t\"No server URL found. Provide --server <url> or define servers in the OpenAPI spec.\",\n\t\t);\n\t}\n\n\tconst names = extractTemplateVars(base);\n\tif (!names.length) return base;\n\n\tconst vars: Record<string, string> = {};\n\tfor (const name of names) {\n\t\tconst provided = input.serverVars[name];\n\t\tif (typeof provided === \"string\") {\n\t\t\tvars[name] = provided;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If spec has default for this var, use it.\n\t\tconst match = input.servers.find((s) => s.url === base);\n\t\tconst v = match?.variables.find((x) => x.name === name);\n\t\tif (typeof v?.default === \"string\") {\n\t\t\tvars[name] = v.default;\n\t\t\tcontinue;\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Missing server variable '${name}'. Provide --server-var ${name}=...`,\n\t\t);\n\t}\n\n\treturn applyTemplate(base, vars);\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": ";AAAO,SAAS,mBAAmB,CAAC,UAA4B;AAAA,EAC/D,MAAM,MAAgB,CAAC;AAAA,EACvB,MAAM,KAAK;AAAA,EACX,OAAO,MAAM;AAAA,IACZ,MAAM,QAAQ,GAAG,KAAK,QAAQ;AAAA,IAC9B,IAAI,CAAC;AAAA,MAAO;AAAA,IACZ,IAAI,MAAM,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,EACjC;AAAA,EACA,OAAO,IAAI,OAAO,OAAO;AAAA;AAGnB,SAAS,aAAa,CAC5B,UACA,MACA,SACS;AAAA,EACT,MAAM,SAAS,SAAS,UAAU;AAAA,EAClC,OAAO,SAAS,QAAQ,gBAAgB,CAAC,GAAG,YAAY;AAAA,IACvD,MAAM,OAAO,OAAO,OAAO,EAAE,KAAK;AAAA,IAClC,MAAM,QAAQ,KAAK;AAAA,IACnB,IAAI,OAAO,UAAU,UAAU;AAAA,MAC9B,MAAM,IAAI,MAAM,8BAA8B,MAAM;AAAA,IACrD;AAAA,IACA,OAAO,SAAS,mBAAmB,KAAK,IAAI;AAAA,GAC5C;AAAA;;;ACdK,SAAS,gBAAgB,CAAC,OAAmC;AAAA,EAEnE,MAAM,OAAO,MAAM,kBAAkB,MAAM,QAAQ,IAAI;AAAA,EACvD,IAAI,CAAC,MAAM;AAAA,IACV,MAAM,IAAI,MACT,oFACD;AAAA,EACD;AAAA,EAEA,MAAM,QAAQ,oBAAoB,IAAI;AAAA,EACtC,IAAI,CAAC,MAAM;AAAA,IAAQ,OAAO;AAAA,EAE1B,MAAM,OAA+B,CAAC;AAAA,EACtC,WAAW,QAAQ,OAAO;AAAA,IACzB,MAAM,WAAW,MAAM,WAAW;AAAA,IAClC,IAAI,OAAO,aAAa,UAAU;AAAA,MACjC,KAAK,QAAQ;AAAA,MACb;AAAA,IACD;AAAA,IAGA,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,IAAI;AAAA,IACtD,MAAM,IAAI,OAAO,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,IACtD,IAAI,OAAO,GAAG,YAAY,UAAU;AAAA,MACnC,KAAK,QAAQ,EAAE;AAAA,MACf;AAAA,IACD;AAAA,IAEA,MAAM,IAAI,MACT,4BAA4B,+BAA+B,UAC5D;AAAA,EACD;AAAA,EAEA,OAAO,cAAc,MAAM,IAAI;AAAA;",
|
|
9
|
+
"debugId": "9629F0B7415413A164756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../../src/cli/runtime/template.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9D;AAED,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,MAAM,CAUR"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/cli/runtime/template.ts
|
|
2
|
+
function extractTemplateVars(template) {
|
|
3
|
+
const out = [];
|
|
4
|
+
const re = /\{([^}]+)\}/g;
|
|
5
|
+
while (true) {
|
|
6
|
+
const match = re.exec(template);
|
|
7
|
+
if (!match)
|
|
8
|
+
break;
|
|
9
|
+
out.push((match[1] ?? "").trim());
|
|
10
|
+
}
|
|
11
|
+
return out.filter(Boolean);
|
|
12
|
+
}
|
|
13
|
+
function applyTemplate(template, vars, options) {
|
|
14
|
+
const encode = options?.encode ?? false;
|
|
15
|
+
return template.replace(/\{([^}]+)\}/g, (_, rawName) => {
|
|
16
|
+
const name = String(rawName).trim();
|
|
17
|
+
const value = vars[name];
|
|
18
|
+
if (typeof value !== "string") {
|
|
19
|
+
throw new Error(`Missing template variable: ${name}`);
|
|
20
|
+
}
|
|
21
|
+
return encode ? encodeURIComponent(value) : value;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
extractTemplateVars,
|
|
26
|
+
applyTemplate
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
//# debugId=6139EC67E15CEBAC64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/runtime/template.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export function extractTemplateVars(template: string): string[] {\n\tconst out: string[] = [];\n\tconst re = /\\{([^}]+)\\}/g;\n\twhile (true) {\n\t\tconst match = re.exec(template);\n\t\tif (!match) break;\n\t\tout.push((match[1] ?? \"\").trim());\n\t}\n\treturn out.filter(Boolean);\n}\n\nexport function applyTemplate(\n\ttemplate: string,\n\tvars: Record<string, string>,\n\toptions?: { encode?: boolean },\n): string {\n\tconst encode = options?.encode ?? false;\n\treturn template.replace(/\\{([^}]+)\\}/g, (_, rawName) => {\n\t\tconst name = String(rawName).trim();\n\t\tconst value = vars[name];\n\t\tif (typeof value !== \"string\") {\n\t\t\tthrow new Error(`Missing template variable: ${name}`);\n\t\t}\n\t\treturn encode ? encodeURIComponent(value) : value;\n\t});\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAO,SAAS,mBAAmB,CAAC,UAA4B;AAAA,EAC/D,MAAM,MAAgB,CAAC;AAAA,EACvB,MAAM,KAAK;AAAA,EACX,OAAO,MAAM;AAAA,IACZ,MAAM,QAAQ,GAAG,KAAK,QAAQ;AAAA,IAC9B,IAAI,CAAC;AAAA,MAAO;AAAA,IACZ,IAAI,MAAM,MAAM,MAAM,IAAI,KAAK,CAAC;AAAA,EACjC;AAAA,EACA,OAAO,IAAI,OAAO,OAAO;AAAA;AAGnB,SAAS,aAAa,CAC5B,UACA,MACA,SACS;AAAA,EACT,MAAM,SAAS,SAAS,UAAU;AAAA,EAClC,OAAO,SAAS,QAAQ,gBAAgB,CAAC,GAAG,YAAY;AAAA,IACvD,MAAM,OAAO,OAAO,OAAO,EAAE,KAAK;AAAA,IAClC,MAAM,QAAQ,KAAK;AAAA,IACnB,IAAI,OAAO,UAAU,UAAU;AAAA,MAC9B,MAAM,IAAI,MAAM,8BAA8B,MAAM;AAAA,IACrD;AAAA,IACA,OAAO,SAAS,mBAAmB,KAAK,IAAI;AAAA,GAC5C;AAAA;",
|
|
8
|
+
"debugId": "6139EC67E15CEBAC64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ajv.d.ts","sourceRoot":"","sources":["../../../../../src/cli/runtime/validate/ajv.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AAGtB,wBAAgB,SAAS,QASxB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/cli/runtime/validate/ajv.ts
|
|
2
|
+
import Ajv from "ajv";
|
|
3
|
+
import addFormats from "ajv-formats";
|
|
4
|
+
function createAjv() {
|
|
5
|
+
const ajv = new Ajv({
|
|
6
|
+
allErrors: true,
|
|
7
|
+
strict: false,
|
|
8
|
+
coerceTypes: false
|
|
9
|
+
});
|
|
10
|
+
addFormats(ajv);
|
|
11
|
+
return ajv;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
createAjv
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//# debugId=F12F5CA5493A5FA464756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/runtime/validate/ajv.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\n\nexport function createAjv() {\n\tconst ajv = new Ajv({\n\t\tallErrors: true,\n\t\tstrict: false,\n\t\tcoerceTypes: false,\n\t});\n\n\taddFormats(ajv);\n\treturn ajv;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAA;AACA;AAEO,SAAS,SAAS,GAAG;AAAA,EAC3B,MAAM,MAAM,IAAI,IAAI;AAAA,IACnB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,aAAa;AAAA,EACd,CAAC;AAAA,EAED,WAAW,GAAG;AAAA,EACd,OAAO;AAAA;",
|
|
8
|
+
"debugId": "F12F5CA5493A5FA464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../../../../src/cli/runtime/validate/coerce.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CA0CjE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,EAAE,CAsB5E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// src/cli/runtime/validate/coerce.ts
|
|
2
|
+
import { InvalidArgumentError } from "commander";
|
|
3
|
+
function coerceValue(raw, type) {
|
|
4
|
+
if (type === "string" || type === "unknown")
|
|
5
|
+
return raw;
|
|
6
|
+
if (type === "boolean") {
|
|
7
|
+
if (raw === "true")
|
|
8
|
+
return true;
|
|
9
|
+
if (raw === "false")
|
|
10
|
+
return false;
|
|
11
|
+
throw new InvalidArgumentError(`Expected boolean, got '${raw}'`);
|
|
12
|
+
}
|
|
13
|
+
if (type === "integer") {
|
|
14
|
+
const n = Number.parseInt(raw, 10);
|
|
15
|
+
if (!Number.isFinite(n))
|
|
16
|
+
throw new InvalidArgumentError(`Expected integer, got '${raw}'`);
|
|
17
|
+
return n;
|
|
18
|
+
}
|
|
19
|
+
if (type === "number") {
|
|
20
|
+
const n = Number(raw);
|
|
21
|
+
if (!Number.isFinite(n))
|
|
22
|
+
throw new InvalidArgumentError(`Expected number, got '${raw}'`);
|
|
23
|
+
return n;
|
|
24
|
+
}
|
|
25
|
+
if (type === "object") {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(raw);
|
|
28
|
+
} catch {
|
|
29
|
+
throw new InvalidArgumentError(`Expected JSON object, got '${raw}'. Use --data/--file for complex bodies.`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (type === "array") {
|
|
33
|
+
return coerceArrayInput(raw, "string");
|
|
34
|
+
}
|
|
35
|
+
return raw;
|
|
36
|
+
}
|
|
37
|
+
function coerceArrayInput(raw, itemType) {
|
|
38
|
+
const trimmed = raw.trim();
|
|
39
|
+
if (!trimmed)
|
|
40
|
+
return [];
|
|
41
|
+
if (trimmed.startsWith("[")) {
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
parsed = JSON.parse(trimmed);
|
|
45
|
+
} catch {
|
|
46
|
+
throw new InvalidArgumentError(`Expected JSON array, got '${raw}'`);
|
|
47
|
+
}
|
|
48
|
+
if (!Array.isArray(parsed)) {
|
|
49
|
+
throw new InvalidArgumentError(`Expected JSON array, got '${raw}'`);
|
|
50
|
+
}
|
|
51
|
+
return parsed.map((v) => coerceValue(String(v), itemType));
|
|
52
|
+
}
|
|
53
|
+
return trimmed.split(",").map((s) => s.trim()).filter(Boolean).map((s) => coerceValue(s, itemType));
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
coerceValue,
|
|
57
|
+
coerceArrayInput
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//# debugId=463F52539EB6B40764756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/runtime/validate/coerce.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { InvalidArgumentError } from \"commander\";\n\nimport type { ParamType } from \"../../schema-shape.ts\";\n\nexport function coerceValue(raw: string, type: ParamType): unknown {\n\tif (type === \"string\" || type === \"unknown\") return raw;\n\n\tif (type === \"boolean\") {\n\t\t// Commander boolean options are handled without a value; keep for completeness.\n\t\tif (raw === \"true\") return true;\n\t\tif (raw === \"false\") return false;\n\t\tthrow new InvalidArgumentError(`Expected boolean, got '${raw}'`);\n\t}\n\n\tif (type === \"integer\") {\n\t\tconst n = Number.parseInt(raw, 10);\n\t\tif (!Number.isFinite(n))\n\t\t\tthrow new InvalidArgumentError(`Expected integer, got '${raw}'`);\n\t\treturn n;\n\t}\n\n\tif (type === \"number\") {\n\t\tconst n = Number(raw);\n\t\tif (!Number.isFinite(n))\n\t\t\tthrow new InvalidArgumentError(`Expected number, got '${raw}'`);\n\t\treturn n;\n\t}\n\n\t// For now, accept objects as JSON strings.\n\tif (type === \"object\") {\n\t\ttry {\n\t\t\treturn JSON.parse(raw);\n\t\t} catch {\n\t\t\tthrow new InvalidArgumentError(\n\t\t\t\t`Expected JSON object, got '${raw}'. Use --data/--file for complex bodies.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Arrays should usually be passed as repeatable flags or comma-separated,\n\t// but allow JSON arrays too.\n\tif (type === \"array\") {\n\t\treturn coerceArrayInput(raw, \"string\");\n\t}\n\n\treturn raw;\n}\n\nexport function coerceArrayInput(raw: string, itemType: ParamType): unknown[] {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return [];\n\n\tif (trimmed.startsWith(\"[\")) {\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(trimmed);\n\t\t} catch {\n\t\t\tthrow new InvalidArgumentError(`Expected JSON array, got '${raw}'`);\n\t\t}\n\t\tif (!Array.isArray(parsed)) {\n\t\t\tthrow new InvalidArgumentError(`Expected JSON array, got '${raw}'`);\n\t\t}\n\t\treturn parsed.map((v) => coerceValue(String(v), itemType));\n\t}\n\n\treturn trimmed\n\t\t.split(\",\")\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean)\n\t\t.map((s) => coerceValue(s, itemType));\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAA;AAIO,SAAS,WAAW,CAAC,KAAa,MAA0B;AAAA,EAClE,IAAI,SAAS,YAAY,SAAS;AAAA,IAAW,OAAO;AAAA,EAEpD,IAAI,SAAS,WAAW;AAAA,IAEvB,IAAI,QAAQ;AAAA,MAAQ,OAAO;AAAA,IAC3B,IAAI,QAAQ;AAAA,MAAS,OAAO;AAAA,IAC5B,MAAM,IAAI,qBAAqB,0BAA0B,MAAM;AAAA,EAChE;AAAA,EAEA,IAAI,SAAS,WAAW;AAAA,IACvB,MAAM,IAAI,OAAO,SAAS,KAAK,EAAE;AAAA,IACjC,IAAI,CAAC,OAAO,SAAS,CAAC;AAAA,MACrB,MAAM,IAAI,qBAAqB,0BAA0B,MAAM;AAAA,IAChE,OAAO;AAAA,EACR;AAAA,EAEA,IAAI,SAAS,UAAU;AAAA,IACtB,MAAM,IAAI,OAAO,GAAG;AAAA,IACpB,IAAI,CAAC,OAAO,SAAS,CAAC;AAAA,MACrB,MAAM,IAAI,qBAAqB,yBAAyB,MAAM;AAAA,IAC/D,OAAO;AAAA,EACR;AAAA,EAGA,IAAI,SAAS,UAAU;AAAA,IACtB,IAAI;AAAA,MACH,OAAO,KAAK,MAAM,GAAG;AAAA,MACpB,MAAM;AAAA,MACP,MAAM,IAAI,qBACT,8BAA8B,6CAC/B;AAAA;AAAA,EAEF;AAAA,EAIA,IAAI,SAAS,SAAS;AAAA,IACrB,OAAO,iBAAiB,KAAK,QAAQ;AAAA,EACtC;AAAA,EAEA,OAAO;AAAA;AAGD,SAAS,gBAAgB,CAAC,KAAa,UAAgC;AAAA,EAC7E,MAAM,UAAU,IAAI,KAAK;AAAA,EACzB,IAAI,CAAC;AAAA,IAAS,OAAO,CAAC;AAAA,EAEtB,IAAI,QAAQ,WAAW,GAAG,GAAG;AAAA,IAC5B,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,SAAS,KAAK,MAAM,OAAO;AAAA,MAC1B,MAAM;AAAA,MACP,MAAM,IAAI,qBAAqB,6BAA6B,MAAM;AAAA;AAAA,IAEnE,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAAA,MAC3B,MAAM,IAAI,qBAAqB,6BAA6B,MAAM;AAAA,IACnE;AAAA,IACA,OAAO,OAAO,IAAI,CAAC,MAAM,YAAY,OAAO,CAAC,GAAG,QAAQ,CAAC;AAAA,EAC1D;AAAA,EAEA,OAAO,QACL,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO,EACd,IAAI,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAAA;",
|
|
8
|
+
"debugId": "463F52539EB6B40764756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../../src/cli/runtime/validate/error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAEvC,wBAAgB,eAAe,CAC9B,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,GAAG,SAAS,GACtC,MAAM,CAwBR"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/cli/runtime/validate/error.ts
|
|
2
|
+
function formatAjvErrors(errors) {
|
|
3
|
+
if (!errors?.length)
|
|
4
|
+
return "Invalid input";
|
|
5
|
+
return errors.map((e) => {
|
|
6
|
+
const path = e.instancePath || e.schemaPath || "";
|
|
7
|
+
if (e.keyword === "required" && e.params && typeof e.params === "object" && "missingProperty" in e.params) {
|
|
8
|
+
const missing = String(e.params.missingProperty);
|
|
9
|
+
const where = e.instancePath || "/";
|
|
10
|
+
return `${where} missing required property '${missing}'`.trim();
|
|
11
|
+
}
|
|
12
|
+
const msg = e.message || "invalid";
|
|
13
|
+
return `${path} ${msg}`.trim();
|
|
14
|
+
}).join(`
|
|
15
|
+
`);
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
formatAjvErrors
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
//# debugId=AC421E95E0A5899864756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/runtime/validate/error.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { ErrorObject } from \"ajv\";\n\nexport function formatAjvErrors(\n\terrors: ErrorObject[] | null | undefined,\n): string {\n\tif (!errors?.length) return \"Invalid input\";\n\n\treturn errors\n\t\t.map((e) => {\n\t\t\tconst path = e.instancePath || e.schemaPath || \"\";\n\n\t\t\tif (\n\t\t\t\te.keyword === \"required\" &&\n\t\t\t\te.params &&\n\t\t\t\ttypeof e.params === \"object\" &&\n\t\t\t\t\"missingProperty\" in e.params\n\t\t\t) {\n\t\t\t\tconst missing = String(\n\t\t\t\t\t(e.params as { missingProperty?: unknown }).missingProperty,\n\t\t\t\t);\n\t\t\t\tconst where = e.instancePath || \"/\";\n\t\t\t\treturn `${where} missing required property '${missing}'`.trim();\n\t\t\t}\n\n\t\t\tconst msg = e.message || \"invalid\";\n\t\t\treturn `${path} ${msg}`.trim();\n\t\t})\n\t\t.join(\"\\n\");\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEO,SAAS,eAAe,CAC9B,QACS;AAAA,EACT,IAAI,CAAC,QAAQ;AAAA,IAAQ,OAAO;AAAA,EAE5B,OAAO,OACL,IAAI,CAAC,MAAM;AAAA,IACX,MAAM,OAAO,EAAE,gBAAgB,EAAE,cAAc;AAAA,IAE/C,IACC,EAAE,YAAY,cACd,EAAE,UACF,OAAO,EAAE,WAAW,YACpB,qBAAqB,EAAE,QACtB;AAAA,MACD,MAAM,UAAU,OACd,EAAE,OAAyC,eAC7C;AAAA,MACA,MAAM,QAAQ,EAAE,gBAAgB;AAAA,MAChC,OAAO,GAAG,oCAAoC,WAAW,KAAK;AAAA,IAC/D;AAAA,IAEA,MAAM,MAAM,EAAE,WAAW;AAAA,IACzB,OAAO,GAAG,QAAQ,MAAM,KAAK;AAAA,GAC7B,EACA,KAAK;AAAA,CAAI;AAAA;",
|
|
8
|
+
"debugId": "AC421E95E0A5899864756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/runtime/validate/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// src/cli/runtime/validate/ajv.ts
|
|
2
|
+
import Ajv from "ajv";
|
|
3
|
+
import addFormats from "ajv-formats";
|
|
4
|
+
function createAjv() {
|
|
5
|
+
const ajv = new Ajv({
|
|
6
|
+
allErrors: true,
|
|
7
|
+
strict: false,
|
|
8
|
+
coerceTypes: false
|
|
9
|
+
});
|
|
10
|
+
addFormats(ajv);
|
|
11
|
+
return ajv;
|
|
12
|
+
}
|
|
13
|
+
// src/cli/runtime/validate/coerce.ts
|
|
14
|
+
import { InvalidArgumentError } from "commander";
|
|
15
|
+
function coerceValue(raw, type) {
|
|
16
|
+
if (type === "string" || type === "unknown")
|
|
17
|
+
return raw;
|
|
18
|
+
if (type === "boolean") {
|
|
19
|
+
if (raw === "true")
|
|
20
|
+
return true;
|
|
21
|
+
if (raw === "false")
|
|
22
|
+
return false;
|
|
23
|
+
throw new InvalidArgumentError(`Expected boolean, got '${raw}'`);
|
|
24
|
+
}
|
|
25
|
+
if (type === "integer") {
|
|
26
|
+
const n = Number.parseInt(raw, 10);
|
|
27
|
+
if (!Number.isFinite(n))
|
|
28
|
+
throw new InvalidArgumentError(`Expected integer, got '${raw}'`);
|
|
29
|
+
return n;
|
|
30
|
+
}
|
|
31
|
+
if (type === "number") {
|
|
32
|
+
const n = Number(raw);
|
|
33
|
+
if (!Number.isFinite(n))
|
|
34
|
+
throw new InvalidArgumentError(`Expected number, got '${raw}'`);
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
if (type === "object") {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(raw);
|
|
40
|
+
} catch {
|
|
41
|
+
throw new InvalidArgumentError(`Expected JSON object, got '${raw}'. Use --data/--file for complex bodies.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (type === "array") {
|
|
45
|
+
return coerceArrayInput(raw, "string");
|
|
46
|
+
}
|
|
47
|
+
return raw;
|
|
48
|
+
}
|
|
49
|
+
function coerceArrayInput(raw, itemType) {
|
|
50
|
+
const trimmed = raw.trim();
|
|
51
|
+
if (!trimmed)
|
|
52
|
+
return [];
|
|
53
|
+
if (trimmed.startsWith("[")) {
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(trimmed);
|
|
57
|
+
} catch {
|
|
58
|
+
throw new InvalidArgumentError(`Expected JSON array, got '${raw}'`);
|
|
59
|
+
}
|
|
60
|
+
if (!Array.isArray(parsed)) {
|
|
61
|
+
throw new InvalidArgumentError(`Expected JSON array, got '${raw}'`);
|
|
62
|
+
}
|
|
63
|
+
return parsed.map((v) => coerceValue(String(v), itemType));
|
|
64
|
+
}
|
|
65
|
+
return trimmed.split(",").map((s) => s.trim()).filter(Boolean).map((s) => coerceValue(s, itemType));
|
|
66
|
+
}
|
|
67
|
+
// src/cli/runtime/validate/error.ts
|
|
68
|
+
function formatAjvErrors(errors) {
|
|
69
|
+
if (!errors?.length)
|
|
70
|
+
return "Invalid input";
|
|
71
|
+
return errors.map((e) => {
|
|
72
|
+
const path = e.instancePath || e.schemaPath || "";
|
|
73
|
+
if (e.keyword === "required" && e.params && typeof e.params === "object" && "missingProperty" in e.params) {
|
|
74
|
+
const missing = String(e.params.missingProperty);
|
|
75
|
+
const where = e.instancePath || "/";
|
|
76
|
+
return `${where} missing required property '${missing}'`.trim();
|
|
77
|
+
}
|
|
78
|
+
const msg = e.message || "invalid";
|
|
79
|
+
return `${path} ${msg}`.trim();
|
|
80
|
+
}).join(`
|
|
81
|
+
`);
|
|
82
|
+
}
|
|
83
|
+
// src/cli/runtime/validate/schema.ts
|
|
84
|
+
function deriveValidationSchemas(action) {
|
|
85
|
+
const query = { type: "object", properties: {}, required: [] };
|
|
86
|
+
const header = { type: "object", properties: {}, required: [] };
|
|
87
|
+
const cookie = { type: "object", properties: {}, required: [] };
|
|
88
|
+
for (const p of action.params) {
|
|
89
|
+
if (p.kind !== "flag")
|
|
90
|
+
continue;
|
|
91
|
+
const target = p.in === "query" ? query : p.in === "header" ? header : p.in === "cookie" ? cookie : undefined;
|
|
92
|
+
if (!target)
|
|
93
|
+
continue;
|
|
94
|
+
const schema = p.schema ?? (p.type === "unknown" ? {} : { type: p.type });
|
|
95
|
+
target.properties[p.name] = schema;
|
|
96
|
+
if (p.required) {
|
|
97
|
+
if (!target.required)
|
|
98
|
+
target.required = [];
|
|
99
|
+
target.required.push(p.name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (!query.required?.length)
|
|
103
|
+
delete query.required;
|
|
104
|
+
if (!header.required?.length)
|
|
105
|
+
delete header.required;
|
|
106
|
+
if (!cookie.required?.length)
|
|
107
|
+
delete cookie.required;
|
|
108
|
+
return {
|
|
109
|
+
querySchema: Object.keys(query.properties).length ? query : undefined,
|
|
110
|
+
headerSchema: Object.keys(header.properties).length ? header : undefined,
|
|
111
|
+
cookieSchema: Object.keys(cookie.properties).length ? cookie : undefined
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
formatAjvErrors,
|
|
116
|
+
deriveValidationSchemas,
|
|
117
|
+
createAjv,
|
|
118
|
+
coerceValue,
|
|
119
|
+
coerceArrayInput
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
//# debugId=588BE3E1CF0A20E964756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/runtime/validate/ajv.ts", "../../../../../src/cli/runtime/validate/coerce.ts", "../../../../../src/cli/runtime/validate/error.ts", "../../../../../src/cli/runtime/validate/schema.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\n\nexport function createAjv() {\n\tconst ajv = new Ajv({\n\t\tallErrors: true,\n\t\tstrict: false,\n\t\tcoerceTypes: false,\n\t});\n\n\taddFormats(ajv);\n\treturn ajv;\n}\n",
|
|
6
|
+
"import { InvalidArgumentError } from \"commander\";\n\nimport type { ParamType } from \"../../schema-shape.ts\";\n\nexport function coerceValue(raw: string, type: ParamType): unknown {\n\tif (type === \"string\" || type === \"unknown\") return raw;\n\n\tif (type === \"boolean\") {\n\t\t// Commander boolean options are handled without a value; keep for completeness.\n\t\tif (raw === \"true\") return true;\n\t\tif (raw === \"false\") return false;\n\t\tthrow new InvalidArgumentError(`Expected boolean, got '${raw}'`);\n\t}\n\n\tif (type === \"integer\") {\n\t\tconst n = Number.parseInt(raw, 10);\n\t\tif (!Number.isFinite(n))\n\t\t\tthrow new InvalidArgumentError(`Expected integer, got '${raw}'`);\n\t\treturn n;\n\t}\n\n\tif (type === \"number\") {\n\t\tconst n = Number(raw);\n\t\tif (!Number.isFinite(n))\n\t\t\tthrow new InvalidArgumentError(`Expected number, got '${raw}'`);\n\t\treturn n;\n\t}\n\n\t// For now, accept objects as JSON strings.\n\tif (type === \"object\") {\n\t\ttry {\n\t\t\treturn JSON.parse(raw);\n\t\t} catch {\n\t\t\tthrow new InvalidArgumentError(\n\t\t\t\t`Expected JSON object, got '${raw}'. Use --data/--file for complex bodies.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Arrays should usually be passed as repeatable flags or comma-separated,\n\t// but allow JSON arrays too.\n\tif (type === \"array\") {\n\t\treturn coerceArrayInput(raw, \"string\");\n\t}\n\n\treturn raw;\n}\n\nexport function coerceArrayInput(raw: string, itemType: ParamType): unknown[] {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return [];\n\n\tif (trimmed.startsWith(\"[\")) {\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(trimmed);\n\t\t} catch {\n\t\t\tthrow new InvalidArgumentError(`Expected JSON array, got '${raw}'`);\n\t\t}\n\t\tif (!Array.isArray(parsed)) {\n\t\t\tthrow new InvalidArgumentError(`Expected JSON array, got '${raw}'`);\n\t\t}\n\t\treturn parsed.map((v) => coerceValue(String(v), itemType));\n\t}\n\n\treturn trimmed\n\t\t.split(\",\")\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean)\n\t\t.map((s) => coerceValue(s, itemType));\n}\n",
|
|
7
|
+
"import type { ErrorObject } from \"ajv\";\n\nexport function formatAjvErrors(\n\terrors: ErrorObject[] | null | undefined,\n): string {\n\tif (!errors?.length) return \"Invalid input\";\n\n\treturn errors\n\t\t.map((e) => {\n\t\t\tconst path = e.instancePath || e.schemaPath || \"\";\n\n\t\t\tif (\n\t\t\t\te.keyword === \"required\" &&\n\t\t\t\te.params &&\n\t\t\t\ttypeof e.params === \"object\" &&\n\t\t\t\t\"missingProperty\" in e.params\n\t\t\t) {\n\t\t\t\tconst missing = String(\n\t\t\t\t\t(e.params as { missingProperty?: unknown }).missingProperty,\n\t\t\t\t);\n\t\t\t\tconst where = e.instancePath || \"/\";\n\t\t\t\treturn `${where} missing required property '${missing}'`.trim();\n\t\t\t}\n\n\t\t\tconst msg = e.message || \"invalid\";\n\t\t\treturn `${path} ${msg}`.trim();\n\t\t})\n\t\t.join(\"\\n\");\n}\n",
|
|
8
|
+
"import type { CommandAction } from \"../../command-model.ts\";\nimport type { JsonSchema } from \"../../types.ts\";\n\nexport type ValidationSchemas = {\n\tquerySchema?: JsonSchema;\n\theaderSchema?: JsonSchema;\n\tcookieSchema?: JsonSchema;\n};\n\ntype ObjectSchema = {\n\ttype: \"object\";\n\tproperties: Record<string, JsonSchema>;\n\trequired?: string[];\n};\n\nexport function deriveValidationSchemas(\n\taction: CommandAction,\n): ValidationSchemas {\n\t// We validate only simple containers for now.\n\t// Deep style/encoding differences for OpenAPI params are out of scope for v1.\n\tconst query: ObjectSchema = { type: \"object\", properties: {}, required: [] };\n\tconst header: ObjectSchema = { type: \"object\", properties: {}, required: [] };\n\tconst cookie: ObjectSchema = { type: \"object\", properties: {}, required: [] };\n\n\tfor (const p of action.params) {\n\t\tif (p.kind !== \"flag\") continue;\n\t\tconst target =\n\t\t\tp.in === \"query\"\n\t\t\t\t? query\n\t\t\t\t: p.in === \"header\"\n\t\t\t\t\t? header\n\t\t\t\t\t: p.in === \"cookie\"\n\t\t\t\t\t\t? cookie\n\t\t\t\t\t\t: undefined;\n\t\tif (!target) continue;\n\n\t\tconst schema = p.schema ?? (p.type === \"unknown\" ? {} : { type: p.type });\n\t\ttarget.properties[p.name] = schema;\n\t\tif (p.required) {\n\t\t\tif (!target.required) target.required = [];\n\t\t\ttarget.required.push(p.name);\n\t\t}\n\t}\n\n\tif (!query.required?.length) delete query.required;\n\tif (!header.required?.length) delete header.required;\n\tif (!cookie.required?.length) delete cookie.required;\n\n\treturn {\n\t\tquerySchema: Object.keys(query.properties).length ? query : undefined,\n\t\theaderSchema: Object.keys(header.properties).length ? header : undefined,\n\t\tcookieSchema: Object.keys(cookie.properties).length ? cookie : undefined,\n\t};\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "588BE3E1CF0A20E964756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CommandAction } from "../../command-model.js";
|
|
2
|
+
import type { JsonSchema } from "../../types.js";
|
|
3
|
+
export type ValidationSchemas = {
|
|
4
|
+
querySchema?: JsonSchema;
|
|
5
|
+
headerSchema?: JsonSchema;
|
|
6
|
+
cookieSchema?: JsonSchema;
|
|
7
|
+
};
|
|
8
|
+
export declare function deriveValidationSchemas(action: CommandAction): ValidationSchemas;
|
|
9
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../../src/cli/runtime/validate/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG;IAC/B,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,YAAY,CAAC,EAAE,UAAU,CAAC;CAC1B,CAAC;AAQF,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,aAAa,GACnB,iBAAiB,CAoCnB"}
|