@tzurp/openapi-skills 1.2.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/dist/cli.min.js +43 -23
- package/package.json +1 -1
- package/skill-templates/SKILL.md +30 -16
package/README.md
CHANGED
|
@@ -56,6 +56,7 @@ Here’s a concise comparison to help you understand where each version shines:
|
|
|
56
56
|
| **AI agent workflows** | ✔ Optional skill bundle for LLM agents | ✔ Enhanced Skills (OpenAPI annotation generation) |
|
|
57
57
|
| **Mock server** | — | ✔ Local mock server from schema artifacts |
|
|
58
58
|
| **HTML API documentation** | — | ✔ Generate interactive HTML docs |
|
|
59
|
+
| **Compare API responses with response schemas** | — | ✔ Validate API responses against their OpenAPI response schemas |
|
|
59
60
|
| **Schema diffing / version comparison** | — | ✔ Operation‑level diffing & breaking‑change detection |
|
|
60
61
|
| **Code‑first OpenAPI generation** | — | ✔ Bootstrap OpenAPI from annotated source code |
|
|
61
62
|
| **Distribution** | ``npm install -g`` | Native installers (Windows/macOS/Linux) |
|
|
@@ -71,10 +72,10 @@ Enable the optional Skill bundle, and AI agents (Copilot, Claude, Cursor, etc.)
|
|
|
71
72
|
- Explore operations by method, path, tag, or keyword
|
|
72
73
|
- Describe endpoints with full request/response details
|
|
73
74
|
- Prepare and execute live API requests (Postman‑like, no code needed)
|
|
74
|
-
- Parse OpenAPI 2.0/3.x and GraphQL schemas
|
|
75
|
+
- Parse OpenAPI 2.0/3.0.x and GraphQL schemas
|
|
75
76
|
- Generate artifacts (`endpoints.json`, `schemas/`)
|
|
76
77
|
- Work with multiple API schemas simultaneously (stored under: .openapi-skills/<apiName>/ directory)
|
|
77
|
-
- Validate schemas
|
|
78
|
+
- Validate schemas; validates API responses against response schemas
|
|
78
79
|
- Build multi-step scenarios
|
|
79
80
|
- AI Skills bundle for agent-driven workflows (code, tests, clients, docs)
|
|
80
81
|
|
|
@@ -123,9 +124,13 @@ openapi-skills describe addPet --api petstore
|
|
|
123
124
|
### Prepare and execute a request manually
|
|
124
125
|
|
|
125
126
|
```bash
|
|
126
|
-
openapi-skills request addPet --api petstore --force --update-request '{"body.id":1,"body.name":"
|
|
127
|
+
openapi-skills request addPet --api petstore --force --update-request '{"body.id":1,"body.name":""}' --omit-empty
|
|
127
128
|
```
|
|
128
129
|
|
|
130
|
+
Use `--force-request` to reset only the request artifact from the cached operation schema. `--force` refreshes both the operation schema and the request artifact.
|
|
131
|
+
|
|
132
|
+
`--omit-empty` removes empty-string values from optional fields using the operation schema; required fields and other values are preserved.
|
|
133
|
+
|
|
129
134
|
---
|
|
130
135
|
|
|
131
136
|
## ⚡ One‑line agent command
|
|
@@ -274,7 +279,3 @@ If you run into issues or have questions:
|
|
|
274
279
|
- npm package: [https://www.npmjs.com/package/@tzurp/openapi-skills](https://www.npmjs.com/package/@tzurp/openapi-skills)
|
|
275
280
|
- GitHub repository: [https://github.com/tzurp/openapi-skills-cli](https://github.com/tzurp/openapi-skills-cli)
|
|
276
281
|
- Bedekbyte: [https://www.bedekbyte.com](https://www.bedekbyte.com)
|
|
277
|
-
|
|
278
|
-
## npm package release (maintainers)
|
|
279
|
-
|
|
280
|
-
Run `npm run package:npm` to build and test the project, bundle the CLI into a minified `dist/cli.min.js` using esbuild, and create an npm tarball under `dist/npm/`. Publish the generated tarball with `npm publish <tarball-path>`. This npm packaging flow is separate from `publish-to-public.bat`.
|
package/dist/cli.min.js
CHANGED
|
@@ -1,37 +1,57 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var en=Object.defineProperty;var E=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var tn=(e,t)=>{for(var r in t)en(e,r,{get:t[r],enumerable:!0})};function re(e){return e.normalize("NFKD").replace(/[\\/]/g,"_").split("_").map(s=>s===""?"_":(s=s.replace(/\./g,"_"),s=s.replace(/[^a-zA-Z0-9_-]/g,"_"),s=s.replace(/^_+|_+$/g,""),s||"_")).join("_")}var ut=E(()=>{"use strict"});import Ee from"fs-extra";import rn from"os";import Se from"path";import{createRequire as Bt}from"module";import{pathToFileURL as nn}from"url";import{buildSchema as sn,isEnumType as Vt,isInputObjectType as an,isListType as zt,isNonNullType as Ht,isObjectType as on,isScalarType as Wt}from"graphql";function Kt(e){if(!(e instanceof Error))return[String(e)];let t=[e.message],r=e.cause;return r instanceof Error?t.push(...Kt(r)):r!=null&&t.push(String(r)),t}function un(e){return!/typescript/i.test(e)||!/(?:Cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND)/i.test(e)?!1:/['"]typescript(?:\/(?:unstable\/)?(?:ast|sync))?['"]/i.test(e)||/Cannot find typescript(?:\/(?:unstable\/)?(?:ast|sync))?/i.test(e)}function Yt(e){return Kt(e).some(t=>/TypeScript is required to analyze builder GraphQL schemas/i.test(t)||un(t))}function Xt(e){let t=[Bt(import.meta.url),Bt(Se.join(process.cwd(),"package.json"))];for(let r of t)try{return nn(r.resolve(e)).href}catch{}throw new Error(`Cannot find ${e}`)}async function dn(){let e;for(let t of pn)try{let r=await ln(t);if(typeof r.isCallExpression=="function")return r;e=new Error(`TypeScript module '${t}' does not export the AST API.`)}catch(r){e=r;try{let n=await import(Xt(t));if(typeof n.isCallExpression=="function")return n;e=new Error(`TypeScript module '${t}' does not export the AST API.`)}catch(n){e=n}}throw e??new Error("TypeScript is required to analyze builder GraphQL schemas.")}async function ln(e){return await import(e)}async function fn(){let e;for(let t of cn)try{let r=await mn(t);if(typeof r.API=="function")return r.API;let n=Qt(r);if(n)return n;e=new Error(`TypeScript module '${t}' does not export API.`)}catch(r){e=r;try{let n=await import(Xt(t));if(typeof n.API=="function")return n.API;let s=Qt(n);if(s)return s;e=new Error(`TypeScript module '${t}' does not export API.`)}catch(n){e=n}}throw e??new Error("TypeScript is required to analyze builder GraphQL schemas.")}function Qt(e){return typeof e.createSourceFile!="function"||!e.ScriptTarget||!e.ScriptKind?null:class{updateSnapshot(r){let n=r.openFiles[0],s=Ee.readFileSync(n,"utf8"),i=e.createSourceFile(n,s,e.ScriptTarget.Latest,!0,e.ScriptKind.TS);return{getDefaultProjectForFile:()=>({program:{getSourceFile:()=>i}}),dispose:()=>{}}}close(){}}}async function mn(e){return await import(e)}async function Zt(){if(fe&&Ue)return fe;try{fe=await dn(),Ue=await fn()}catch(e){throw new Error("TypeScript is required to analyze builder GraphQL schemas.",{cause:e})}return fe}function F(){if(!fe)throw new Error("TypeScript has not been loaded.");return fe}async function gn(e,t){await Zt();let r=Se.extname(t??"").toLowerCase(),n=`graphql-source${r===".tsx"||r===".jsx"?r:".ts"}`,s=await Ee.mkdtemp(Se.join(rn.tmpdir(),"openapi-skills-graphql-")),i=Se.join(s,n);if(await Ee.writeFile(i,e,"utf8"),!Ue)throw new Error("TypeScript API has not been loaded.");let a=new Ue,o=a.updateSnapshot({openFiles:[i]});try{let c=o.getDefaultProjectForFile(i)?.program.getSourceFile(i);if(!c)throw new Error("TypeScript could not parse the GraphQL builder source.");return c}finally{o.dispose(),a.close(),await Ee.remove(s)}}function hn(e,t){return t&&[".ts",".tsx",".mts",".cts"].includes(Se.extname(t).toLowerCase())?!0:[/\bbuilder\.queryType\s*\(/,/\bbuilder\.mutationType\s*\(/,/\bbuilder\.subscriptionType\s*\(/,/\bobjectType\s*\(/,/\bnew\s+SchemaBuilder\s*\(/].some(r=>r.test(e))}async function Qe(e){if(/^https?:\/\//i.test(e)){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to load GraphQL source from ${e}: HTTP ${t.status}`);return await t.text()}return await Ee.readFile(e,"utf8")}function Me(e){return[/\btype\s+Query\b/i,/\btype\s+Mutation\b/i,/\btype\s+Subscription\b/i,/\bschema\s*\{/i,/\bextend\s+type\s+Query\b/i,/\bbuilder\.(queryType|mutationType|subscriptionType)\s*\(/i,/\btoSchema\s*\(/i].some(t=>t.test(e))}function dt(e){let t=F();if(e&&(t.isStringLiteral(e)||t.isNoSubstitutionTemplateLiteral(e)))return e.text}function yn(e,t){let r=F();if(e)return e.properties.find(n=>r.isPropertyAssignment(n)||r.isShorthandPropertyAssignment(n)?(r.isIdentifier(n.name)||r.isStringLiteral(n.name)||r.isNumericLiteral(n.name)?n.name.text:n.name.getText())===t:!1)}function L(e,t){let r=F(),n=yn(e,t);if(!(!n||!r.isPropertyAssignment(n)))return n.initializer}function me(e){let t=F(),r=e;for(;r&&t.isParenthesizedExpression(r);)r=r.expression;return r}function G(e){let t=F(),r=me(e);if(r){if(t.isObjectLiteralExpression(r))return r;if(t.isArrowFunction(r)||t.isFunctionExpression(r)){if(t.isBlock(r.body)){for(let n of r.body.statements)if(t.isReturnStatement(n)&&n.expression){let s=G(n.expression);if(s)return s}return}return G(r.body)}}}function wn(e){let t=F(),r=e.expression;if(!t.isPropertyAccessExpression(r))return;let n=r.name.text;if(n==="queryType")return"query";if(n==="mutationType")return"mutation";if(n==="subscriptionType")return"subscription"}function Mt(e,t){let r=F(),n=me(e);if(n)return r.isStringLiteral(n)||r.isNoSubstitutionTemplateLiteral(n)?n.text:r.isIdentifier(n)?t.objectTypeNames[n.text]??n.text:n.getText()}function bn(e,t){let r=F(),n=me(e);if(n){if(r.isCallExpression(n)){let s=n.expression.getText();if(/\.exposeID$/i.test(s))return"ID";if(/\.exposeString$/i.test(s))return"String";if(/\.exposeInt$/i.test(s))return"Int";if(/\.exposeFloat$/i.test(s))return"Float";if(/\.exposeBoolean$/i.test(s))return"Boolean";if(/\.string$/i.test(s))return"String";if(/\.int$/i.test(s))return"Int";if(/\.float$/i.test(s))return"Float";if(/\.boolean$/i.test(s))return"Boolean";if(/\.id$/i.test(s))return"ID";if(/\.stringList$/i.test(s))return"[String]";if(/\.intList$/i.test(s))return"[Int]";if(/\.floatList$/i.test(s))return"[Float]";if(/\.booleanList$/i.test(s))return"[Boolean]";if(/\.idList$/i.test(s))return"[ID]";let i=n.arguments[0];if(i&&r.isObjectLiteralExpression(i)){let a=L(i,"type");if(a){let o=Mt(a,t);if(o)return o}}}return Mt(n,t)}}function Tn(e){let t=F(),r={},n={};function s(i){if(t.isVariableDeclaration(i)&&i.initializer&&t.isCallExpression(i.initializer)&&t.isPropertyAccessExpression(i.initializer.expression)&&i.initializer.expression.name.text==="objectRef"){let a=i.initializer.arguments[0],o=i.name.getText(e);a&&t.isStringLiteral(a)&&(r[o]=a.text)}if(t.isCallExpression(i)&&t.isPropertyAccessExpression(i.expression)&&i.expression.name.text==="objectType"&&i.arguments.length>1){let a=i.arguments[0],o=G(i.arguments[1]),p=L(o,"name")?dt(L(o,"name")):a&&t.isIdentifier(a)?r[a.text]??a.text:a&&t.isStringLiteral(a)?a.text:void 0;if(p&&o){let c=L(o,"fields"),u=G(c);if(u){let g={};for(let f of u.properties){if(!t.isPropertyAssignment(f))continue;let l=t.isIdentifier(f.name)||t.isStringLiteral(f.name)||t.isNumericLiteral(f.name)?f.name.text:f.name.getText(e),h=bn(f.initializer,{objectTypeNames:r,objectFields:n});h&&(g[l]=h)}n[p]=g}}}i.forEachChild(s)}return s(e),{objectTypeNames:r,objectFields:n}}function $e(e,t,r=new Set){let n=e.trim();if(!n)return{kind:"unknown",typeName:"Unknown"};if(n.endsWith("!"))return{kind:"non-null",typeName:n,required:!0,ofType:$e(n.slice(0,-1),t,r)};if(n.startsWith("[")&&n.endsWith("]"))return{kind:"list",typeName:n,ofType:$e(n.slice(1,-1).trim(),t,r)};if(mt.has(n))return{kind:"scalar",typeName:n};let s=t.objectTypeNames[n]??n;if(r.has(s))return{kind:"object",typeName:s,circular:s,fields:{}};let i=t.objectFields[s];if(!i)return{kind:"object",typeName:s};let a=new Set(r);a.add(s);let o={};for(let[p,c]of Object.entries(i))o[p]=$e(c,t,a);return{kind:"object",typeName:s,fields:o}}function Ve(e){let t=e.trim();for(;t.endsWith("!");)t=t.slice(0,-1).trim();return t.startsWith("[")&&t.endsWith("]")&&(t=t.slice(1,-1).trim()),t}function An(e,t){let r=Ve(e);return mt.has(r)?"scalar":t&&/input|filter|where|args?/i.test(r)||t?"input-object":"object"}function Ge(e,t){let r=e.trim();if(!r)return{kind:"unknown",typeName:"Unknown"};if(r.endsWith("!"))return{kind:"non-null",typeName:r,required:!0,ofType:Ge(r.slice(0,-1),t)};if(r.startsWith("[")&&r.endsWith("]")){let s=r.slice(1,-1).trim();return{kind:"list",typeName:r,ofType:Ge(s,t)}}return{kind:An(r,t),typeName:r}}function Be(e){let t=F(),r=me(e);if(r){if(t.isStringLiteral(r)||t.isNoSubstitutionTemplateLiteral(r))return r.text;if(t.isNumericLiteral(r))return Number(r.text);if(r.kind===t.SyntaxKind.TrueKeyword)return!0;if(r.kind===t.SyntaxKind.FalseKeyword)return!1;if(r.kind===t.SyntaxKind.NullKeyword)return null;if(t.isArrayLiteralExpression(r))return r.elements.map(n=>Be(n));if(t.isObjectLiteralExpression(r)){let n={};for(let s of r.properties)if(t.isPropertyAssignment(s)){let i=t.isIdentifier(s.name)||t.isStringLiteral(s.name)||t.isNumericLiteral(s.name)?s.name.text:s.name.getText();n[i]=Be(s.initializer)}return n}t.isIdentifier(r)&&r.text}}function kn(e){let t=F(),r=me(e);if(!r)return{kind:"unknown",typeName:"Unknown"};if(t.isCallExpression(r)){let n=r.expression.getText(),s=r.arguments[0];if(s&&t.isObjectLiteralExpression(s)){let i=L(s,"type"),a=L(s,"required"),o=L(s,"defaultValue"),p;if(i?p=Ge(i.getText(),!0):/\.string$/i.test(n)?p={kind:"scalar",typeName:"String"}:/\.int$/i.test(n)?p={kind:"scalar",typeName:"Int"}:/\.float$/i.test(n)?p={kind:"scalar",typeName:"Float"}:/\.boolean$/i.test(n)?p={kind:"scalar",typeName:"Boolean"}:/\.id$/i.test(n)&&(p={kind:"scalar",typeName:"ID"}),p)return p.defaultValue=Be(o),a&&Be(a)===!0?{kind:"non-null",typeName:`${p.typeName}!`,required:!0,ofType:p}:p}if(/\.string$/i.test(n))return{kind:"scalar",typeName:"String"};if(/\.int$/i.test(n))return{kind:"scalar",typeName:"Int"};if(/\.float$/i.test(n))return{kind:"scalar",typeName:"Float"};if(/\.boolean$/i.test(n))return{kind:"scalar",typeName:"Boolean"};if(/\.id$/i.test(n))return{kind:"scalar",typeName:"ID"}}return Ge(r.getText(),!0)}function xn(e){let t=Ve(e);return t==="Boolean"?!1:t==="Int"||t==="Float"?0:t==="ID"||t==="String"?"":null}function lt(e){if(e.kind==="non-null"&&e.ofType)return lt(e.ofType);if(e.kind==="list")return[];if(e.kind==="scalar")return xn(e.typeName);if(e.kind==="enum")return e.enumValues?.[0]??null;if(e.kind==="input-object"){let t={};for(let[r,n]of Object.entries(e.fields??{}))t[r]=lt(n);return t}return null}function ft(e){return e.kind==="non-null"&&e.ofType?`${ft(e.ofType)}!`:e.kind==="list"&&e.ofType?`[${ft(e.ofType)}]`:e.typeName}function En(e){let t=Ve(e.typeName);return e.kind==="scalar"||e.kind==="enum"||mt.has(t)}function De(e,t=new Set){if(e.kind==="non-null"&&e.ofType||e.kind==="list"&&e.ofType)return De(e.ofType,t);if(En(e))return"";let r=Ve(e.typeName);if(t.has(r))return"__typename";if(e.kind==="object"||e.kind==="input-object"){let n=new Set(t);n.add(r);let s=Object.entries(e.fields??{});return s.length===0?"{ __typename }":`{ ${s.map(([a,o])=>{let p=De(o,n);if(!p)return a;if(o.kind==="object"||o.kind==="input-object"||o.kind==="list"||o.kind==="non-null"){let c=p.startsWith("{")?p:`{ ${p} }`;return`${a} ${c}`}return`${a} ${p}`}).join(" ")} }`}return"__typename"}function Sn(e){let t=Object.keys(e.args),r=t.map(u=>{let g=e.args[u];return`$${u}: ${g?ft(g):"String"}`}),n={};for(let[u,g]of Object.entries(e.args))n[u]=lt(g);let s=t.map(u=>`${u}: $${u}`).join(", "),i=De(e.returns),a=i?` ${i}`:"",o=re(e.operationId)||e.operationId,p=r.length>0?`(${r.join(", ")})`:"",c=s.length>0?`(${s})`:"";return{query:`${e.rootType} ${o}${p} { ${e.name}${c}${a} }`,variables:n}}function Rn(e){let t=sn(e),r=[["query",t.getQueryType()],["mutation",t.getMutationType()],["subscription",t.getSubscriptionType()]],n=[];for(let[s,i]of r)if(i)for(let a of Object.values(i.getFields())){let o={};for(let u of a.args){let g=Fe(u.type);u.defaultValue!==void 0&&(g.defaultValue=u.defaultValue),o[u.name]=g}let p={name:a.name,operationId:a.name,sanitizedOperationId:re(a.name),rootType:s,args:o,returns:Je(a.type)},c=a.description?.split(`
|
|
3
|
-
`).map(u=>u.trim()).filter(Boolean)[0];c&&(p.summary=c),
|
|
4
|
-
`:e)}function
|
|
5
|
-
`)},progress(e){
|
|
6
|
-
`)}}});import{promises as
|
|
2
|
+
var fn=Object.defineProperty;var S=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var mn=(e,t)=>{for(var r in t)fn(e,r,{get:t[r],enumerable:!0})};function se(e){return e.normalize("NFKD").replace(/[\\/]/g,"_").split("_").map(s=>s===""?"_":(s=s.replace(/\./g,"_"),s=s.replace(/[^a-zA-Z0-9_-]/g,"_"),s=s.replace(/^_+|_+$/g,""),s||"_")).join("_")}var mt=S(()=>{"use strict"});import Pe from"fs-extra";import gn from"os";import Ie from"path";import{createRequire as zt}from"module";import{pathToFileURL as hn}from"url";import{buildSchema as yn,isEnumType as Kt,isInputObjectType as wn,isListType as Yt,isNonNullType as Xt,isObjectType as bn,isScalarType as Zt,valueFromAST as An}from"graphql";function er(e){if(!(e instanceof Error))return[String(e)];let t=[e.message],r=e.cause;return r instanceof Error?t.push(...er(r)):r!=null&&t.push(String(r)),t}function xn(e){return!/typescript/i.test(e)||!/(?:Cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND)/i.test(e)?!1:/['"]typescript(?:\/(?:unstable\/)?(?:ast|sync))?['"]/i.test(e)||/Cannot find typescript(?:\/(?:unstable\/)?(?:ast|sync))?/i.test(e)}function tr(e){return er(e).some(t=>/TypeScript is required to analyze builder GraphQL schemas/i.test(t)||xn(t))}function rr(e){let t=[zt(import.meta.url),zt(Ie.join(process.cwd(),"package.json"))];for(let r of t)try{return hn(r.resolve(e)).href}catch{}throw new Error(`Cannot find ${e}`)}async function En(){let e;for(let t of Tn)try{let r=await Sn(t);if(typeof r.isCallExpression=="function")return r;e=new Error(`TypeScript module '${t}' does not export the AST API.`)}catch(r){e=r;try{let n=await import(rr(t));if(typeof n.isCallExpression=="function")return n;e=new Error(`TypeScript module '${t}' does not export the AST API.`)}catch(n){e=n}}throw e??new Error("TypeScript is required to analyze builder GraphQL schemas.")}async function Sn(e){return await import(e)}async function Pn(){let e;for(let t of kn)try{let r=await In(t);if(typeof r.API=="function")return r.API;let n=Ht(r);if(n)return n;e=new Error(`TypeScript module '${t}' does not export API.`)}catch(r){e=r;try{let n=await import(rr(t));if(typeof n.API=="function")return n.API;let s=Ht(n);if(s)return s;e=new Error(`TypeScript module '${t}' does not export API.`)}catch(n){e=n}}throw e??new Error("TypeScript is required to analyze builder GraphQL schemas.")}function Ht(e){return typeof e.createSourceFile!="function"||!e.ScriptTarget||!e.ScriptKind?null:class{updateSnapshot(r){let n=r.openFiles[0],s=Pe.readFileSync(n,"utf8"),i=e.createSourceFile(n,s,e.ScriptTarget.Latest,!0,e.ScriptKind.TS);return{getDefaultProjectForFile:()=>({program:{getSourceFile:()=>i}}),dispose:()=>{}}}close(){}}}async function In(e){return await import(e)}async function nr(){if(ge&&Me)return ge;try{ge=await En(),Me=await Pn()}catch(e){throw new Error("TypeScript is required to analyze builder GraphQL schemas.",{cause:e})}return ge}function J(){if(!ge)throw new Error("TypeScript has not been loaded.");return ge}async function Rn(e,t){await nr();let r=Ie.extname(t??"").toLowerCase(),n=`graphql-source${r===".tsx"||r===".jsx"?r:".ts"}`,s=await Pe.mkdtemp(Ie.join(gn.tmpdir(),"openapi-skills-graphql-")),i=Ie.join(s,n);if(await Pe.writeFile(i,e,"utf8"),!Me)throw new Error("TypeScript API has not been loaded.");let o=new Me,a=o.updateSnapshot({openFiles:[i]});try{let c=a.getDefaultProjectForFile(i)?.program.getSourceFile(i);if(!c)throw new Error("TypeScript could not parse the GraphQL builder source.");return c}finally{a.dispose(),o.close(),await Pe.remove(s)}}function On(e,t){return t&&[".ts",".tsx",".mts",".cts"].includes(Ie.extname(t).toLowerCase())?!0:[/\bbuilder\.queryType\s*\(/,/\bbuilder\.mutationType\s*\(/,/\bbuilder\.subscriptionType\s*\(/,/\bobjectType\s*\(/,/\bnew\s+SchemaBuilder\s*\(/].some(r=>r.test(e))}async function He(e){if(/^https?:\/\//i.test(e)){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to load GraphQL source from ${e}: HTTP ${t.status}`);return await t.text()}return await Pe.readFile(e,"utf8")}function We(e){return[/\btype\s+Query\b/i,/\btype\s+Mutation\b/i,/\btype\s+Subscription\b/i,/\bschema\s*\{/i,/\bextend\s+type\s+Query\b/i,/\bbuilder\.(queryType|mutationType|subscriptionType)\s*\(/i,/\btoSchema\s*\(/i].some(t=>t.test(e))}function gt(e){let t=J();if(e&&(t.isStringLiteral(e)||t.isNoSubstitutionTemplateLiteral(e)))return e.text}function qn(e,t){let r=J();if(e)return e.properties.find(n=>r.isPropertyAssignment(n)||r.isShorthandPropertyAssignment(n)?(r.isIdentifier(n.name)||r.isStringLiteral(n.name)||r.isNumericLiteral(n.name)?n.name.text:n.name.getText())===t:!1)}function C(e,t){let r=J(),n=qn(e,t);if(!(!n||!r.isPropertyAssignment(n)))return n.initializer}function he(e){let t=J(),r=e;for(;r&&t.isParenthesizedExpression(r);)r=r.expression;return r}function G(e){let t=J(),r=he(e);if(r){if(t.isObjectLiteralExpression(r))return r;if(t.isArrowFunction(r)||t.isFunctionExpression(r)){if(t.isBlock(r.body)){for(let n of r.body.statements)if(t.isReturnStatement(n)&&n.expression){let s=G(n.expression);if(s)return s}return}return G(r.body)}}}function vn(e){let t=J(),r=e.expression;if(!t.isPropertyAccessExpression(r))return;let n=r.name.text;if(n==="queryType")return"query";if(n==="mutationType")return"mutation";if(n==="subscriptionType")return"subscription"}function Wt(e,t){let r=J(),n=he(e);if(n)return r.isStringLiteral(n)||r.isNoSubstitutionTemplateLiteral(n)?n.text:r.isIdentifier(n)?t.objectTypeNames[n.text]??n.text:n.getText()}function Nn(e,t){let r=J(),n=he(e);if(n){if(r.isCallExpression(n)){let s=n.expression.getText();if(/\.exposeID$/i.test(s))return"ID";if(/\.exposeString$/i.test(s))return"String";if(/\.exposeInt$/i.test(s))return"Int";if(/\.exposeFloat$/i.test(s))return"Float";if(/\.exposeBoolean$/i.test(s))return"Boolean";if(/\.string$/i.test(s))return"String";if(/\.int$/i.test(s))return"Int";if(/\.float$/i.test(s))return"Float";if(/\.boolean$/i.test(s))return"Boolean";if(/\.id$/i.test(s))return"ID";if(/\.stringList$/i.test(s))return"[String]";if(/\.intList$/i.test(s))return"[Int]";if(/\.floatList$/i.test(s))return"[Float]";if(/\.booleanList$/i.test(s))return"[Boolean]";if(/\.idList$/i.test(s))return"[ID]";let i=n.arguments[0];if(i&&r.isObjectLiteralExpression(i)){let o=C(i,"type");if(o){let a=Wt(o,t);if(a)return a}}}return Wt(n,t)}}function jn(e){let t=J(),r={},n={};function s(i){if(t.isVariableDeclaration(i)&&i.initializer&&t.isCallExpression(i.initializer)&&t.isPropertyAccessExpression(i.initializer.expression)&&i.initializer.expression.name.text==="objectRef"){let o=i.initializer.arguments[0],a=i.name.getText(e);o&&t.isStringLiteral(o)&&(r[a]=o.text)}if(t.isCallExpression(i)&&t.isPropertyAccessExpression(i.expression)&&i.expression.name.text==="objectType"&&i.arguments.length>1){let o=i.arguments[0],a=G(i.arguments[1]),p=C(a,"name")?gt(C(a,"name")):o&&t.isIdentifier(o)?r[o.text]??o.text:o&&t.isStringLiteral(o)?o.text:void 0;if(p&&a){let c=C(a,"fields"),u=G(c);if(u){let m={};for(let f of u.properties){if(!t.isPropertyAssignment(f))continue;let l=t.isIdentifier(f.name)||t.isStringLiteral(f.name)||t.isNumericLiteral(f.name)?f.name.text:f.name.getText(e),g=Nn(f.initializer,{objectTypeNames:r,objectFields:n});g&&(m[l]=g)}n[p]=m}}}i.forEachChild(s)}return s(e),{objectTypeNames:r,objectFields:n}}function Ue(e,t,r=new Set){let n=e.trim();if(!n)return{kind:"unknown",typeName:"Unknown"};if(n.endsWith("!"))return{kind:"non-null",typeName:n,required:!0,ofType:Ue(n.slice(0,-1),t,r)};if(n.startsWith("[")&&n.endsWith("]"))return{kind:"list",typeName:n,ofType:Ue(n.slice(1,-1).trim(),t,r)};if(wt.has(n))return{kind:"scalar",typeName:n};let s=t.objectTypeNames[n]??n;if(r.has(s))return{kind:"object",typeName:s,circular:s,fields:{}};let i=t.objectFields[s];if(!i)return{kind:"object",typeName:s};let o=new Set(r);o.add(s);let a={};for(let[p,c]of Object.entries(i))a[p]=Ue(c,t,o);return{kind:"object",typeName:s,fields:a}}function Ke(e){let t=e.trim();for(;t.endsWith("!");)t=t.slice(0,-1).trim();return t.startsWith("[")&&t.endsWith("]")&&(t=t.slice(1,-1).trim()),t}function _n(e,t){let r=Ke(e);return wt.has(r)?"scalar":t&&/input|filter|where|args?/i.test(r)||t?"input-object":"object"}function Ve(e,t){let r=e.trim();if(!r)return{kind:"unknown",typeName:"Unknown"};if(r.endsWith("!"))return{kind:"non-null",typeName:r,required:!0,ofType:Ve(r.slice(0,-1),t)};if(r.startsWith("[")&&r.endsWith("]")){let s=r.slice(1,-1).trim();return{kind:"list",typeName:r,ofType:Ve(s,t)}}return{kind:_n(r,t),typeName:r}}function ze(e){let t=J(),r=he(e);if(r){if(t.isStringLiteral(r)||t.isNoSubstitutionTemplateLiteral(r))return r.text;if(t.isNumericLiteral(r))return Number(r.text);if(r.kind===t.SyntaxKind.TrueKeyword)return!0;if(r.kind===t.SyntaxKind.FalseKeyword)return!1;if(r.kind===t.SyntaxKind.NullKeyword)return null;if(t.isArrayLiteralExpression(r))return r.elements.map(n=>ze(n));if(t.isObjectLiteralExpression(r)){let n={};for(let s of r.properties)if(t.isPropertyAssignment(s)){let i=t.isIdentifier(s.name)||t.isStringLiteral(s.name)||t.isNumericLiteral(s.name)?s.name.text:s.name.getText();n[i]=ze(s.initializer)}return n}t.isIdentifier(r)&&r.text}}function Ln(e){let t=J(),r=he(e);if(!r)return{kind:"unknown",typeName:"Unknown"};if(t.isCallExpression(r)){let n=r.expression.getText(),s=r.arguments[0];if(s&&t.isObjectLiteralExpression(s)){let i=C(s,"type"),o=C(s,"required"),a=C(s,"defaultValue"),p;if(i?p=Ve(i.getText(),!0):/\.string$/i.test(n)?p={kind:"scalar",typeName:"String"}:/\.int$/i.test(n)?p={kind:"scalar",typeName:"Int"}:/\.float$/i.test(n)?p={kind:"scalar",typeName:"Float"}:/\.boolean$/i.test(n)?p={kind:"scalar",typeName:"Boolean"}:/\.id$/i.test(n)&&(p={kind:"scalar",typeName:"ID"}),p)return p.defaultValue=ze(a),o&&ze(o)===!0?{kind:"non-null",typeName:`${p.typeName}!`,required:!0,ofType:p}:p}if(/\.string$/i.test(n))return{kind:"scalar",typeName:"String"};if(/\.int$/i.test(n))return{kind:"scalar",typeName:"Int"};if(/\.float$/i.test(n))return{kind:"scalar",typeName:"Float"};if(/\.boolean$/i.test(n))return{kind:"scalar",typeName:"Boolean"};if(/\.id$/i.test(n))return{kind:"scalar",typeName:"ID"}}return Ve(r.getText(),!0)}function Cn(e){let t=Ke(e);return t==="Boolean"?!1:t==="Int"||t==="Float"?0:t==="ID"||t==="String"?"":null}function ht(e){if(e.kind==="non-null"&&e.ofType)return ht(e.ofType);if(e.kind==="list")return[];if(e.kind==="scalar")return Cn(e.typeName);if(e.kind==="enum")return e.enumValues?.[0]??null;if(e.kind==="input-object"){let t={};for(let[r,n]of Object.entries(e.fields??{}))t[r]=ht(n);return t}return null}function yt(e){return e.kind==="non-null"&&e.ofType?`${yt(e.ofType)}!`:e.kind==="list"&&e.ofType?`[${yt(e.ofType)}]`:e.typeName}function $n(e){let t=Ke(e.typeName);return e.kind==="scalar"||e.kind==="enum"||wt.has(t)}function Ge(e,t=new Set){if(e.kind==="non-null"&&e.ofType||e.kind==="list"&&e.ofType)return Ge(e.ofType,t);if($n(e))return"";let r=Ke(e.typeName);if(t.has(r))return"__typename";if(e.kind==="object"||e.kind==="input-object"){let n=new Set(t);n.add(r);let s=Object.entries(e.fields??{});return s.length===0?"{ __typename }":`{ ${s.map(([o,a])=>{let p=Ge(a,n);if(!p)return o;if(a.kind==="object"||a.kind==="input-object"||a.kind==="list"||a.kind==="non-null"){let c=p.startsWith("{")?p:`{ ${p} }`;return`${o} ${c}`}return`${o} ${p}`}).join(" ")} }`}return"__typename"}function Dn(e){let t=Object.keys(e.args),r=t.map(u=>{let m=e.args[u];return`$${u}: ${m?yt(m):"String"}`}),n={};for(let[u,m]of Object.entries(e.args))n[u]=ht(m);let s=t.map(u=>`${u}: $${u}`).join(", "),i=Ge(e.returns),o=i?` ${i}`:"",a=se(e.operationId)||e.operationId,p=r.length>0?`(${r.join(", ")})`:"",c=s.length>0?`(${s})`:"";return{query:`${e.rootType} ${a}${p} { ${e.name}${c}${o} }`,variables:n}}function Fn(e){let t=yn(e),r=[["query",t.getQueryType()],["mutation",t.getMutationType()],["subscription",t.getSubscriptionType()]],n=[];for(let[s,i]of r)if(i)for(let o of Object.values(i.getFields())){let a={};for(let u of o.args){let m=Be(u.type),f=sr(u);f!==void 0&&(m.defaultValue=f),a[u.name]=m}let p={name:o.name,operationId:o.name,sanitizedOperationId:se(o.name),rootType:s,args:a,returns:Qe(o.type)},c=o.description?.split(`
|
|
3
|
+
`).map(u=>u.trim()).filter(Boolean)[0];c&&(p.summary=c),o.description&&(p.description=o.description),n.push(p)}return n}function sr(e){if(e.defaultValue!==void 0)return e.defaultValue;let t=e.astNode?.defaultValue;return t?An(t,e.type):void 0}function Be(e,t=new Set){if(Xt(e))return{kind:"non-null",typeName:e.toString(),required:!0,ofType:Be(e.ofType,t)};if(Yt(e))return{kind:"list",typeName:e.toString(),ofType:Be(e.ofType,t)};if(Zt(e))return{kind:"scalar",typeName:e.name};if(Kt(e))return{kind:"enum",typeName:e.name,enumValues:e.getValues().map(r=>r.name)};if(wn(e)){if(t.has(e.name))return{kind:"input-object",typeName:e.name,circular:e.name,fields:{}};let r=new Set(t);r.add(e.name);let n={};for(let[s,i]of Object.entries(e.getFields())){let o=Be(i.type,r),a=sr(i);a!==void 0&&(o.defaultValue=a),n[s]=o}return{kind:"input-object",typeName:e.name,fields:n}}return{kind:"unknown",typeName:String(e)}}function Qe(e,t=new Set){if(Xt(e))return{kind:"non-null",typeName:e.toString(),required:!0,ofType:Qe(e.ofType,t)};if(Yt(e))return{kind:"list",typeName:e.toString(),ofType:Qe(e.ofType,t)};if(Zt(e))return{kind:"scalar",typeName:e.name};if(Kt(e))return{kind:"enum",typeName:e.name,enumValues:e.getValues().map(r=>r.name)};if(bn(e)){if(t.has(e.name))return{kind:"object",typeName:e.name,circular:e.name,fields:{}};let r=new Set(t);r.add(e.name);let n={};for(let[s,i]of Object.entries(e.getFields()))n[s]=Qe(i.type,r);return{kind:"object",typeName:e.name,fields:n}}return{kind:"unknown",typeName:e.toString()}}async function Jn(e,t){let r=await nr(),n=await Rn(e,t),s=jn(n),i=[];function o(a){if(r.isCallExpression(a)&&r.isPropertyAccessExpression(a.expression)){let p=vn(a);if(p&&a.arguments.length>0){let c=G(a.arguments[0]),u=C(c,"fields"),m=G(u);if(m)for(let f of m.properties){if(!r.isPropertyAssignment(f))continue;let l=r.isIdentifier(f.name)||r.isStringLiteral(f.name)||r.isNumericLiteral(f.name)?f.name.text:f.name.getText(n),g=G(f.initializer)??G(f.initializer),b=he(f.initializer),T=b&&r.isCallExpression(b)?b:void 0,h=T?G(T.arguments[0]):g,y=C(h,"type"),A=gt(C(h,"summary")),P=gt(C(h,"description")),O=C(h,"args"),E=G(O),V={};if(E)for(let D of E.properties){if(!r.isPropertyAssignment(D))continue;let ne=r.isIdentifier(D.name)||r.isStringLiteral(D.name)||r.isNumericLiteral(D.name)?D.name.text:D.name.getText(n);V[ne]=Ln(D.initializer)}let x={name:l,operationId:l,sanitizedOperationId:se(l),rootType:p,args:V,returns:y?Ue(y.getText(n),s):{kind:"unknown",typeName:"Unknown"}};A&&(x.summary=A),P&&(x.description=P),i.push(x)}}}a.forEachChild(o)}return o(n),i}async function Ye(e,t){return On(e,t)?await Jn(e,t):Fn(e)}async function ye(e,t,r,n){let i=(await Ye(e,n)).find(o=>o.rootType===t&&o.name===r);if(!i)throw new Error(`GraphQL field '${r}' not found on root type '${t}'.`);return i}function Re(e){return Dn(e)}var wt,bt,Tn,kn,ge,Me,Oe=S(()=>{"use strict";mt();wt=new Set(["String","Int","Float","Boolean","ID"]),bt="npm install typescript",Tn=["typescript/ast","typescript","typescript/unstable/ast"],kn=["typescript/sync","typescript","typescript/unstable/sync"],ge=null,Me=null});function we(e,t){process.stderr.write(t?`${e}
|
|
4
|
+
`:e)}function W(e){return e instanceof Error?e.message:String(e)}var H,d,be=S(()=>{"use strict";H=process.stderr.isTTY&&process.stdout.isTTY;d={info(e){we(e,!0)},warn(e){let t="\u26A0\uFE0F ";if(H){let r=`\x1B[33m${t}${e}\x1B[0m`;we(r,!0)}else we(t+e,!0)},banner(e){we(H?`\x1B[35m${e}\x1B[0m`:e,!0)},error(e){process.stderr.write(`\u274C ${e}
|
|
5
|
+
`)},progress(e){H&&we(e,!1)},progressLine(e){H&&we(e,!0)},result(e){process.stdout.write(`${JSON.stringify(e)}
|
|
6
|
+
`)}}});import{promises as Xe}from"fs";import ir from"path";import Ze from"fs-extra";async function ar(e){try{return await Ze.readJSON(e,"utf8")}catch(t){if(t.code==="ENOENT")return{};throw t}}function Un(e,t,r){let n=t.split("."),s=e;for(let i=0;i<n.length;i++){let o=n[i]??"",a=i===n.length-1,p=typeof o=="string"&&/^[0-9]+$/.test(o),c=p?Number(o):void 0;if(a)p&&Array.isArray(s)&&c!==void 0?s[c]=r:s[o]=r;else if(p&&c!==void 0){if(!Array.isArray(s)&&i>0){let u=n[i-1]??"";s[u]=[],s=s[u]}s[c]||(s[c]={}),s=s[c]}else(!(o in s)||typeof s[o]!="object"||s[o]===null)&&(s[o]={}),s=s[o]}}function Gn(e,t){let r=t.split(".");if(r.length===0)return!1;let n=e;for(let o=0;o<r.length-1;o++){let a=r[o]??"",c=/^[0-9]+$/.test(a)&&Array.isArray(n)?n[Number(a)]:n&&typeof n=="object"?n[a]:void 0;if(c==null)return!1;n=c}let s=r[r.length-1]??"",i=/^[0-9]+$/.test(s);if(Array.isArray(n)&&i){let o=Number(s);return o<0||o>=n.length?!1:(n.splice(o,1),!0)}return n&&typeof n=="object"&&Object.prototype.hasOwnProperty.call(n,s)?(delete n[s],!0):!1}function Bn(e,t){return e===t||e.startsWith(`${t}.`)}function Qn(e,t){let r=e.split("."),n=t.split(".");if(r.length!==n.length)return n.length-r.length;let s=r[r.length-1]??"",i=n[n.length-1]??"",o=r.slice(0,-1).join("."),a=n.slice(0,-1).join(".");return o===a&&/^[0-9]+$/.test(s)&&/^[0-9]+$/.test(i)?Number(i)-Number(s):t.localeCompare(e)}async function qe(e,t,r=2,n={}){let s={};try{let h=await Xe.readFile(e,"utf8");s=JSON.parse(h)}catch(h){if(h.code!=="ENOENT")throw h}let i=JSON.parse(JSON.stringify(s)),o=n.deleteSentinel,a=o===void 0?[]:Object.entries(t).filter(([,h])=>h===o).map(([h])=>h).sort(Qn);for(let h of a)Gn(i,h);for(let[h,y]of Object.entries(t))o!==void 0&&y===o||a.some(A=>Bn(h,A))||Un(i,h,y);if(n.transform?.(i),!(JSON.stringify(s)!==JSON.stringify(i)))return{changed:!1,before:s,after:i};let c=ir.resolve(e),u=ir.dirname(c),m=Math.random().toString(36).slice(2,10),f=`${c}.tmp.${process.pid}.${m}`,l,g=new Set(["EPERM","EACCES","EBUSY"]);async function b(h){await new Promise(y=>setTimeout(y,h))}async function T(h,y){for(let P=1;P<=5;P++)try{await Xe.rename(h,y);return}catch(O){if(!g.has(O?.code)||P===5)throw O;await b(25*P)}}try{await Xe.mkdir(u,{recursive:!0}),l=await Xe.open(f,"w"),await l.writeFile(JSON.stringify(i,null,r),"utf8"),await l.sync(),await l.close(),await T(f,c);try{let h=Ze.openSync(u,"r");Ze.fsyncSync(h),Ze.closeSync(h)}catch{}return{changed:!0,before:s,after:i}}catch(h){if(l)try{await l.close()}catch{}throw(h.code==="EPERM"||h.code==="EACCES"||h.code==="EBUSY")&&d.error(`Failed to atomically update JSON file due to a file lock or permission error.
|
|
7
7
|
Please close any programs that may have the file open and try again.
|
|
8
|
-
The temporary file with your changes is: ${f}`),m}}var Ke,ht=E(()=>{"use strict";ye();Ke="__delete__"});import B from"path";import Nn from"find-root";function se(e,t){let r=q(e);return B.join(r,`${t}.json`)}function ie(e){return B.resolve(ne,".openapi-skills",e,"bundled.json")}function yt(e){return B.resolve(ne,".openapi-skills",e,"components.json")}function ae(e,t){let r=q(e);return B.resolve(r,t)}function q(e){return B.resolve(ne,".openapi-skills",e,"schemas")}function Oe(e){return B.resolve(ne,".openapi-skills",e)}function rr(){return B.resolve(ne,".openapi-skills","config.json")}function j(e){return B.resolve(ne,".openapi-skills",e,"endpoints.json")}function Ye(e,t,r){let n=ae(e,t),s=r==="response-schema"?"response-schema.json":`${r}.json`;return B.join(n,s)}function Xe(){return B.resolve(ne,".openapi-skills")}function Ze(){let e=process.cwd();try{return Nn(e)}catch{return e}}var ne,W=E(()=>{"use strict";ne=Ze()});import{readFile as jn}from"fs/promises";import _n from"path";import oe from"fs-extra";async function J(){return await oe.readJSON(we)}async function wt(){if(await oe.ensureDir(Cn),!await oe.pathExists(we)){let e={apis:{}};await oe.writeJson(we,e,{spaces:2})}}function nr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function be(e,t={}){if(typeof e!="string"||e.trim().length===0)throw new Error("API name is required.");let{baseUrl:r,auth:n,vars:s,version:i,openapiSource:a,schemaType:o,removeApi:p}=t,c={};if(p){if(!await oe.pathExists(we))throw new Error("Config file not found.");let u=await J();if(!nr(u)||!nr(u.apis))throw new Error("Invalid config file.");if(!(e in u.apis))throw new Error(`API '${e}' not found`);delete u.apis[e],await oe.writeJson(we,u,{spaces:2});return}if(await wt(),n!==void 0&&(c[`apis.${e}.auth.headers`]=n),s!==void 0)for(let[u,g]of Object.entries(s))c[`apis.${e}.vars.${u}`]=g;if(i!==void 0&&(c[`apis.${e}.version`]=i),a!==void 0){let u=a;try{new URL(a)}catch{u=_n.normalize(a)}c[`apis.${e}.openapiSource`]=u}r!==void 0&&(c[`apis.${e}.baseUrl`]=r),o!==void 0&&(c[`apis.${e}.schemaType`]=o),Object.keys(c).length!==0&&await Ie(we,c,2)}function Ln(e){let t=e instanceof Error?e.message:String(e);return/config/i.test(t)?{type:"ConfigError",message:t}:/permission|EACCES|EPERM/i.test(t)?{type:"DirectoryDeletionError",message:t}:{type:"DeleteApiError",message:t}}async function sr(e){if(typeof e!="string"||e.trim().length===0)return{ok:!1,error:{type:"InvalidApiName",message:"API name is required."}};try{if(!(await pe()).includes(e))return{ok:!1,error:{type:"ApiNotFound",message:`API '${e}' is not installed.`}};await be(e,{removeApi:!0});let r=Oe(e);return await oe.remove(r),{ok:!0,message:`API ${e} removed successfully`,data:{removedApi:e}}}catch(t){return{ok:!1,error:Ln(t)}}}async function et(e,t){let n=(await J()).apis[e];if(!n)throw new Error(`API '${e}' not found`);switch(t){case"version":return n.version??"unknown";case"baseUrl":return n.baseUrl;case"authHeaders":return n.auth?.headers??{};case"vars":return Object.entries(n.vars??{})}}async function ir(e){try{let t=await jn(j(e),"utf-8");return JSON.parse(t)}catch(t){throw t instanceof SyntaxError?new Error(`Failed to parse endpoints.json: Invalid JSON format. ${t.message}`):new Error(`Failed to read endpoints.json: ${t instanceof Error?t.message:String(t)}`)}}async function pe(){let e=await J();return Object.keys(e.apis)||[]}var Cn,we,ce=E(()=>{"use strict";ht();W();Cn=Xe(),we=rr()});import bt from"@apidevtools/swagger-parser";import $n from"@apidevtools/json-schema-ref-parser";import S from"fs-extra";import K from"path";function ar(e){let t;try{let r=new URL(e);t=K.basename(r.pathname,K.extname(r.pathname))}catch{t=K.basename(e,K.extname(e))}return re(t||"api")}function Dn(e){if(e instanceof Error)return/circular/i.test(e.message)||/circular/i.test(e.name);if(typeof e=="object"&&e!==null){let t=String(e.message??""),r=String(e.name??"");return/circular/i.test(t)||/circular/i.test(r)}return!1}function Tt(e,t=new WeakSet){if(e&&typeof e=="object"){if(t.has(e))return;if(t.add(e),Array.isArray(e)){let n=e.map(s=>Tt(s,t));return t.delete(e),n}let r={};for(let[n,s]of Object.entries(e)){let i=Tt(s,t);i!==void 0&&(r[n]=i)}return t.delete(e),r}return e}async function Fn(e){let t=ie(e),r=await S.readJson(t),n=typeof r?.source=="string"?r.source:typeof r?.sourceText=="string"?r.sourceText:void 0;if(!n)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);return n}async function Jn(e,t,r,n=!1){let s=se(e,r);if(!n&&await S.pathExists(s))return S.readJson(s);let i=await S.readJson(j(e)),a=Array.isArray(i)?i.find(u=>u.operationId===t||u.name===t||u.sanitizedOperationId===r):void 0;if(!a)throw new Error(`Endpoint '${t}' not found in GraphQL endpoint list.`);let o=typeof a.rootType=="string"?a.rootType:typeof a.method=="string"?a.method:void 0;if(!o||o!=="query"&&o!=="mutation"&&o!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let p=await Fn(e),c=await ge(p,o,t);return await S.ensureDir(K.dirname(s)),await S.writeJson(s,c,{spaces:2}),c}function Un(e,t){for(let[r,n]of Object.entries(e))for(let[s,i]of Object.entries(n))if(i&&typeof i=="object"&&"operationId"in i){let a=i;if(a.operationId===t)return{pathKey:r,method:s,operation:a}}}async function Gn(e,t){let r=typeof e.operationId=="string"?e.operationId:"unknown-operation",n=typeof e.method=="string"?e.method.toUpperCase():"GET",s=typeof e.path=="string"?e.path:"unknown-path",i=z;i&&d.progressLine(`Dereferencing endpoint ${r} (${n} ${s})...`);let a={openapi:"3.0.0",paths:{"/temp":{get:e}},definitions:t,components:t},o=await $n.dereference(a,{mutateInputSchema:!1,dereference:{circular:"ignore"}}),p=Tt(o),c=p.paths,u=c&&typeof c=="object"?c["/temp"]:void 0,g=u&&typeof u=="object"?u.get:void 0;return g&&typeof g=="object"?(i&&d.progressLine(`Endpoint ${r} (${n} ${s}) dereference complete.`),g):(i&&d.progressLine(`Endpoint ${r} (${n} ${s}) dereference complete.`),p)}async function Q(e,t,r,n=!1){let s=se(e,r);if(!n&&await S.pathExists(s))return S.readJson(s);let i=ie(e),a=yt(e),o=await S.readJson(i);if(o&&typeof o=="object"&&o.schemaType==="graphql")return await Jn(e,t,r,n);if(!o||typeof o!="object"||!("paths"in o))throw new Error(`Bundled OpenAPI document not found for API '${e}'. Run generate first.`);let p={},c=o.components,u=o.definitions;c&&typeof c=="object"&&!Array.isArray(c)?p=c:u&&typeof u=="object"&&!Array.isArray(u)?p=u:await S.pathExists(a)&&(p=await S.readJson(a));let g=Un(o.paths,t);if(!g)throw new Error(`Endpoint '${t}' not found in bundled OpenAPI document.`);let f={operationId:t,method:g.method,path:g.pathKey,...g.operation},l=await Gn(f,p);return await S.ensureDir(K.dirname(s)),await S.writeJson(s,l,{spaces:2}),l}async function Bn(e,t){if(!t)return bt.bundle(e);try{return await bt.dereference(e,{dereference:{circular:!1}})}catch(r){throw Dn(r)?new Error("The --dereference flag cannot be used because this OpenAPI spec contains circular references. Try running without --dereference."):r}}function Qn(e){return typeof e.swagger=="string"&&e.swagger.startsWith("2.")?"2":typeof e.openapi=="string"&&e.openapi.startsWith("3.")?"3":"2"}async function Mn(e,t,r={}){let n="",s="unknown",i,a=r.progress!==!1&&z;try{a&&d.progressLine(`Loading OpenAPI document from ${e}...`),i=await Bn(e,r.dereference===!0),a&&d.progressLine("OpenAPI document load complete.")}catch(o){throw d.error(`Error during parsing OpenAPI schema: ${o instanceof Error?o.message:String(o)}`),o}if(typeof i!="object"||!i.paths)throw new Error("Invalid OpenAPI schema: Missing 'paths'");try{s=Qn(i),n=r.rename||ar(e);let o=Oe(n);await S.remove(o);let p=q(n);await S.ensureDir(p);let c=ie(n);if(await S.writeJson(c,i,{spaces:2}),!r.dereference){let h=yt(n);await S.writeJson(h,i?.components??{},{spaces:2})}let u=[],g=0,f=0,l=r.progress!==!1&&z;for(let[h,w]of Object.entries(i.paths))for(let[T,m]of Object.entries(w))m&&typeof m=="object"&&"operationId"in m&&m.operationId&&(g+=1);for(let[h,w]of Object.entries(i.paths))for(let[T,m]of Object.entries(w))if(m&&typeof m=="object"&&"operationId"in m){let y=m;if(y.operationId){let O={operationId:y.operationId,sanitizedOperationId:re(y.operationId),method:T,path:h};if(Array.isArray(y.tags)){let x=y.tags.map(P=>typeof P=="string"?P.trim():"").filter(P=>P.length>0);x.length>0&&(O.tags=x)}y.summary!==void 0&&(O.summary=y.summary),y.description!==void 0&&(O.description=y.description),u.push(O),f+=1,l&&d.progress(`\rProcessed ${f}/${g}`)}}l&&g>0&&d.progressLine("");try{let h=K.join(o,"endpoints.json");await S.writeJson(h,u,{spaces:2})}catch(h){throw d.error(`Error writing endpoints.json: ${h instanceof Error?h.message:String(h)}`),h}try{await be(n,{baseUrl:t,openapiSource:e,schemaType:"openapi",version:s});let h=t?"with baseUrl":"without baseUrl";d.info(`Schema '${n}' added to config.json ${h} and openapiSource recorded.`)}catch(h){throw d.error(`Error updating config.json: ${h instanceof Error?h.message:String(h)}`),h}}catch(o){throw d.error(`Error during OpenAPI schema processing: ${o instanceof Error?o.message:String(o)}`),o}return n}async function Vn(e,t,r={},n){let s="",i=r.progress!==!1&&z,a=n??await Qe(e);if(!Me(a))throw new Error("Invalid GraphQL schema: missing GraphQL schema markers or builder pattern.");i&&d.progressLine(`Loading GraphQL schema from ${e}...`),s=r.rename||ar(e);let o=Oe(s);await S.remove(o);let p=q(s);await S.ensureDir(p);let c=await ze(a,e);if(c.length===0)throw new Error("Invalid GraphQL schema: no query, mutation, or subscription fields were found.");let u=ie(s);await S.writeJson(u,{schemaType:"graphql",source:a},{spaces:2});let g=c.map(f=>({name:f.name,sanitizedOperationId:f.sanitizedOperationId,rootType:f.rootType,summary:f.summary,description:f.description}));for(let f of c){let l=se(s,f.sanitizedOperationId);await S.ensureDir(K.dirname(l)),await S.writeJson(l,f,{spaces:2})}await S.writeJson(K.join(o,"endpoints.json"),g,{spaces:2});try{await be(s,{baseUrl:t,openapiSource:e,schemaType:"graphql",version:"graphql"});let f=t?"with baseUrl":"without baseUrl";d.info(`Schema '${s}' added to config.json ${f} and GraphQL source recorded.`)}catch(f){throw d.error(`Error updating config.json: ${f instanceof Error?f.message:String(f)}`),f}return i&&d.progressLine("GraphQL schema load complete."),s}async function or(e,t,r={}){let n=await Qe(e).catch(()=>{});return n&&Me(n)?await Vn(e,t,r,n):await Mn(e,t,r)}async function pr(e){try{let t=await Qe(e).catch(()=>{});if(t&&Me(t)){await ze(t,e);return}await bt.validate(e);return}catch(t){throw new Error(t instanceof Error?t.message:String(t))}}var Te=E(()=>{"use strict";Pe();ce();W();ye();ut()});function zn(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function At(e){if(!(!e||typeof e!="object"))return zn(e.schema)?e.schema:e}function cr(e){let t=At(e);switch(typeof t?.type=="string"?t.type:typeof e?.type=="string"?e.type:void 0){case"string":return"";case"number":case"integer":return 0;case"boolean":return!1;case"array":return[];case"object":return{};default:return null}}var kt=E(()=>{"use strict"});import Ae from"fs-extra";function tt(e){return e.replace(/[^a-zA-Z0-9]+(.)/g,(t,r)=>r.toUpperCase()).replace(/^[a-z]/,t=>t.toUpperCase())}function X(e,t,r){if(!(!e||typeof e!="object")){if(Array.isArray(e.enum)){let n=tt(r);t[n]=e.enum}if(e.properties&&typeof e.properties=="object")for(let[n,s]of Object.entries(e.properties))X(s,t,`${r}_${n}`);e.items&&X(e.items,t,`${r}_item`),e.oneOf&&e.oneOf.forEach((n,s)=>X(n,t,`${r}_oneOf_${s}`)),e.anyOf&&e.anyOf.forEach((n,s)=>X(n,t,`${r}_anyOf_${s}`)),e.allOf&&e.allOf.forEach((n,s)=>X(n,t,`${r}_allOf_${s}`))}}function Z(e){if(!(!e||typeof e!="object")){if(delete e.xml,e.properties&&typeof e.properties=="object")for(let t of Object.values(e.properties))Z(t);e.items&&Z(e.items),e.oneOf&&e.oneOf.forEach(Z),e.anyOf&&e.anyOf.forEach(Z),e.allOf&&e.allOf.forEach(Z)}}function ur(e){if(!e||typeof e!="object")return null;let r=Object.keys(e).filter(n=>/^\d{3}$/.test(n)).find(n=>n.startsWith("2"));return r?e[r]:null}function xt(e){if(!e||typeof e!="object")return null;let t=Object.entries(e).find(([r])=>r.toLowerCase().includes("json"));return t?t[1]:null}function Hn(e){let t=ur(e);if(!t)return null;if(t.content){let r=xt(t.content);return!r||!r.schema?null:r.schema}return t.schema??null}function Wn(e){let t=ur(e);return t?t.schema??null:null}function Kn(e){let t=Array.isArray(e?.parameters)?e.parameters:[],r=t.find(i=>i.in==="body");if(r?.schema)return r.schema;let n=t.filter(i=>i.in==="formData");if(n.length===0)return null;let s={type:"object",properties:{}};for(let i of n){let a={};i.schema&&typeof i.schema=="object"?Object.assign(a,i.schema):(typeof i.type=="string"&&(a.type=i.type),i.items&&(a.items=i.items),typeof i.format=="string"&&(a.format=i.format),Array.isArray(i.enum)&&(a.enum=i.enum),i.type==="file"&&(a.type="string",a.format="binary")),s.properties[i.name]=a}return s}function Xn(e){let t={};if(!e||typeof e!="object")return t;for(let[r,n]of Object.entries(e)){if(!/^\d{3}$/.test(r)||r.startsWith("2"))continue;let s=n.content,i=s?xt(s):null,a=i&&i.schema?i.schema:n.schema??Yn;t[r]=a}return t}function Zn(e,t){let r={};for(let n of["path","query","header"])for(let[s,i]of Object.entries(e[n]||{}))r[s]={...i.schema,required:i.required??!1,description:i.description,in:n};return{typeName:`${tt(t)}Params`,schema:r}}async function qe(e,t,r,n=!1){let s=await J(),i=await Ae.readJson(j(e)),a=Array.isArray(i)&&i.some(y=>typeof y?.rootType=="string");if(s.apis?.[e]?.schemaType==="graphql"||s.apis?.[e]?.schemaType!=="openapi"&&a){let y=i.find(k=>k.operationId===t||k.name===t);if(!y)throw new Error(`Endpoint with operationId '${t}' not found.`);let O=typeof y.rootType=="string"?y.rootType:typeof y.method=="string"?y.method:void 0;if(!O||O!=="query"&&O!=="mutation"&&O!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let x=q(e)+`/${r}.json`,P;if(!n&&await Ae.pathExists(x))P=await Ae.readJson(x);else{let k=await Ae.readJson(ie(e)),U=typeof k?.source=="string"?k.source:typeof k?.sourceText=="string"?k.sourceText:void 0;if(!U)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);P=await ge(U,O,t),await Ae.ensureDir(q(e)),await Ae.writeJson(x,P,{spaces:2})}return{schemaType:"graphql",fieldName:y.name??t,rootType:O,args:Object.fromEntries(Object.entries(P.args??{}).map(([k,U])=>{let _=U;return[k,{type:_.typeName??"unknown",required:_.required===!0}]})),returnType:P.returns?.typeName??"unknown",query:Re(P).query}}let p=i.find(y=>y.operationId===t);if(!p)throw new Error(`Endpoint with operationId '${t}' not found.`);let c=await Q(e,t,r,n),u={path:{},query:{},header:{}};for(let y of c.parameters||[])(y.in==="path"||y.in==="query"||y.in==="header")&&(u[y.in][y.name]={description:y.description,required:y.required,schema:At(y)});let g=Hn(c.responses)??Wn(c.responses),f={};g&&(Z(g),X(g,f,`${t}_response`));let l=Zn(u,t),h=Xn(c.responses),w=null,T=c.requestBody;if(T&&T.content){let y=xt(T.content);y&&y.schema&&(w=y.schema,Z(w),X(w,f,`${t}_request`))}else w=Kn(c),w&&(Z(w),X(w,f,`${t}_request`));let m=tt(t.replace(/^(get|post|put|delete|patch|head|options)/i,"")||t);return{schemaType:"rest",operationId:t,method:p.method,path:p.path,deprecated:p.deprecated??c.deprecated??!1,params:l,response:g?{typeName:m,schema:g}:null,requestBody:w?{typeName:`${tt(t)}Request`,schema:w}:null,errors:h,enums:f}}var Yn,Et=E(()=>{"use strict";W();Te();kt();Pe();ce();Yn={type:"object",properties:{message:{type:"string"},status:{type:"number"}}}});var ve,dr=E(()=>{"use strict";ve=class{constructor(t){this.baseUrl=t}baseUrl;async request(t,r,n={}){if(!/^https?:\/\//i.test(this.baseUrl))throw new Error(`Invalid baseUrl: "${this.baseUrl}". Must include http:// or https://`);let s=this.baseUrl.endsWith("/")?this.baseUrl:this.baseUrl+"/",i=new URL(r.replace(/^\//,""),s).toString(),a="body"in n&&n.body!==void 0&&t!=="GET"&&t!=="HEAD",o=new Headers(n.headers??{}),p=null;if(a){let f=n.body,l=typeof FormData<"u"&&f instanceof FormData,h=typeof Blob<"u"&&f instanceof Blob,w=f instanceof ArrayBuffer||ArrayBuffer.isView(f),T=typeof Buffer<"u"&&Buffer.isBuffer(f);l?(o.delete("Content-Type"),p=f):h||w||T||typeof f=="string"?p=f:(o.has("Content-Type")||o.set("Content-Type","application/json"),p=JSON.stringify(f))}let c=await fetch(i,{method:t,headers:o,body:p}),u=await c.text(),g={};if(u.trim().length>0)try{g=JSON.parse(u)}catch{g=u}return g!==null&&typeof g=="object"&&!Array.isArray(g)?{...g,status:c.status,statusText:c.statusText}:{body:g,status:c.status,statusText:c.statusText}}get(t,r){return this.request("GET",t,r)}head(t,r){return this.request("HEAD",t,r)}options(t,r){return this.request("OPTIONS",t,r)}post(t,r){return this.request("POST",t,r)}put(t,r){return this.request("PUT",t,r)}patch(t,r){return this.request("PATCH",t,r)}delete(t,r){return this.request("DELETE",t,r)}}});import es from"fs-extra";function lr(e){return{orGroups:e.trim().toLowerCase().split("|").map(r=>r.trim()).filter(Boolean).map(r=>r.split(/\s+/).filter(Boolean))}}function ts(e,t){return t.orGroups.length===0?!0:t.orGroups.some(r=>r.every(n=>e.includes(n)))}function rs(e){return e.split("/").map(t=>t.trim().toLowerCase()).filter(Boolean).flatMap(t=>{if(t.startsWith("{")&&t.endsWith("}")){let r=t.slice(1,-1).trim();return r?[t,r]:[t]}return[t]})}function ns(e,t){return t?t===":param"?/\{[^/{}]+\}/.test(e):t.startsWith("/")?e.startsWith(t):rs(e).includes(t):!0}function ss(e,t){return lr(t).orGroups.some(n=>n.every(s=>ns(e,s)))}function is(e){return e?(Array.isArray(e)?e:[e]).map(t=>t.trim()).filter(Boolean):[]}function as(e,t){if(typeof t!="string"||t.trim().length===0||t.trim()===":")return e;let r=t.trim(),n=r.match(/^-?\d+$/),s=r.match(/^(-?\d*)?:(-?\d*)?$/),i,a;if(n)i=Number(r),a=i;else if(s){let f=s[1],l=s[2];i=f===void 0||f===""?0:Number(f),a=l===void 0||l===""?e.length-1:Number(l)}else throw new Error(`Invalid --index value: ${t}`);if(Number.isNaN(i)||Number.isNaN(a))throw new Error(`Invalid --index value: ${t}`);let o=f=>f<0?e.length+f:f,p=o(i),c=o(a);if(e.length===0)return[];let u=Math.max(0,p),g=Math.min(e.length-1,c);return u>g?[]:e.slice(u,g+1)}function fr(e,t){return as(e,t)}function rt(e,t){let r=e;if(t.operationId){let s=t.operationId.toLowerCase();r=r.filter(i=>(i.operationId||"").toLowerCase()===s)}if(t.method){let s=t.method.toLowerCase();r=r.filter(i=>(i.method||"").toLowerCase()===s)}if(t.rootType){let s=t.rootType.toLowerCase();r=r.filter(i=>(i.rootType||"").toLowerCase()===s)}if(t.tag){let s=t.tag.toLowerCase();r=r.filter(i=>(Array.isArray(i.tags)?i.tags:[]).some(o=>typeof o=="string"&&o.toLowerCase()===s))}let n=is(t.path);if(n.length>0&&(r=r.filter(s=>{let i=(s.path||"").toString().toLowerCase();return n.every(a=>ss(i,a))})),t.filter){let s=lr(t.filter);r=r.filter(i=>{let a=[i.operationId,i.name,i.method,i.rootType,i.path,i.summary,i.description].map(o=>(o||"").toString().toLowerCase()).join(" ");return ts(a,s)})}return r}async function os(e){let t=q(e);try{let r=await es.readdir(t,{withFileTypes:!0});return new Set(r.filter(n=>n.isFile()&&n.name.toLowerCase().endsWith(".json")).map(n=>n.name.slice(0,-5)))}catch(r){if(r?.code==="ENOENT")return new Set;throw r}}async function mr(e,t){let r=await os(e);return r.size===0?[]:t.filter(n=>{let s=typeof n.sanitizedOperationId=="string"?n.sanitizedOperationId:"";return r.has(s)})}var St=E(()=>{"use strict";W()});async function Y(e,t){let r={operationId:t},n=await ir(e),s=rt(n,r)[0]??n.find(i=>i.name===t);return s?.sanitizedOperationId??s?.operationId??s?.name??""}var ue,nt=E(()=>{"use strict";ce();St();ue=Y});function ps(e){return e.replace(/\[(\d+)\]/g,".$1").split(".").filter(r=>r.length>0).map(r=>/^\d+$/.test(r)?Number(r):r)}function Ne(e,t){let r=e;for(let n of ps(t)){if(r==null)return;if(typeof n=="number"){if(!Array.isArray(r)&&typeof r!="object")return;r=r[n];continue}if(typeof r!="object")return;r=r[n]}return r}function gr(e,t,r){return Array.isArray(e)?e.filter(n=>String(Ne(n,t))===String(r)):e}var Rt=E(()=>{"use strict"});import A from"fs-extra";import R from"path";import cs from"ajv";import{fileURLToPath as us}from"url";function je(e,t="",r={}){if(!e||typeof e!="object"||Array.isArray(e))return r;for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)?je(s,i,r):r[i]=s}return r}function Tr(e,t=""){if(!e||typeof e!="object"||Array.isArray(e))return[];let r=[];for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)&&(r.push(i),r.push(...Tr(s,i)))}return Array.from(new Set(r))}function ds(e){let t=Tr(e);if(t.length===0)return;let r=je(e);return["Use only flattened object dot-notation keys with --force.",`Example: --force --update-request '${JSON.stringify(r)}'.`,`Detected nested keys: ${t.join(", ")}.`].join(" ")}function hr(e){return e===null?"null":Ar(e)?"file":Array.isArray(e)?"array":typeof e}function Ar(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.kind==="file"}function vt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.path=="string"&&(e.kind===void 0||e.kind==="file")}function ls(e,t){return Ar(e)?typeof t=="string"||vt(t):e===null?t===null:Array.isArray(e)?Array.isArray(t):typeof e=="object"?!!t&&typeof t=="object"&&!Array.isArray(t):typeof t==typeof e}function kr(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.query=="string"&&typeof e.variables=="object"&&!Array.isArray(e.variables)}function xr(e){if(e)return e.split(",")[0]?.trim()||void 0}function fs(e){switch(R.extname(e).toLowerCase()){case".pdf":return"application/pdf";case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".webp":return"image/webp";case".gif":return"image/gif";case".txt":return"text/plain";case".csv":return"text/csv";case".json":return"application/json";case".xml":return"application/xml";case".xlsx":return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case".xls":return"application/vnd.ms-excel";case".docx":return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";case".zip":return"application/zip";default:return"application/octet-stream"}}function yr(e){let t=e.trim();return t.startsWith("@")?R.resolve(t.slice(1)):t.startsWith("file://")?R.resolve(us(new URL(t))):R.resolve(t)}async function Pt(e,t){let r,n,s;if(typeof e=="string"){if(e.trim().length===0)throw new Error("File upload path cannot be empty.");r=yr(e)}else if(vt(e)){if(e.path.trim().length===0)throw new Error("File upload path cannot be empty.");r=yr(e.path),n=e.fileName?.trim()||void 0,s=e.mimeType?.trim()||void 0}if(!r)throw new Error("File upload values must be a file path string or { kind: 'file', path, fileName?, mimeType? } object.");if(!await A.pathExists(r))throw new Error(`Upload file not found: ${r}`);let i=await A.readFile(r),a=n||R.basename(r),o=s||xr(t)||fs(r);return{buffer:i,path:r,fileName:a,mimeType:o}}function wr(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function ms(e){let t=Object.entries(e),r=t.find(([a])=>a.toLowerCase().includes("multipart/form-data"));if(r)return{contentType:r[0],contentObject:r[1]};let n=t.find(([a,o])=>{let p=o?.schema;return a.toLowerCase().includes("octet-stream")||p?.type==="string"&&p?.format==="binary"});if(n)return{contentType:n[0],contentObject:n[1]};let s=t.find(([a])=>a.toLowerCase().includes("json"));if(s)return{contentType:s[0],contentObject:s[1]};let i=t[0];return i?{contentType:i[0],contentObject:i[1]}:void 0}function gs(e){let t=e?.requestBody,n=(Array.isArray(e?.parameters)?e.parameters:[]).filter(o=>o&&o.in==="formData"),i=(Array.isArray(e?.consumes)?e.consumes:[]).some(o=>typeof o=="string"&&o.toLowerCase().includes("multipart/form-data"));if(n.length>0&&i)return{kind:"multipart",schema:Ot(e)??{type:"object",properties:{}},encoding:{}};if(!t||typeof t!="object")return n.length>0?{kind:"multipart",schema:Ot(e)??{type:"object",properties:{}},encoding:{}}:{kind:"json"};let a=t.content;if(a&&typeof a=="object"&&!Array.isArray(a)){let o=ms(a);if(!o)return{kind:"json"};let p=o.contentObject,c=p?.schema;if(o.contentType.toLowerCase().includes("multipart/form-data"))return{kind:"multipart",schema:c&&typeof c=="object"?c:{type:"object",properties:{}},encoding:p?.encoding??{}};if(o.contentType.toLowerCase().includes("octet-stream")||c?.type==="string"&&c?.format==="binary")return{kind:"binary",contentType:o.contentType}}return{kind:"json"}}async function It(e,t){let r=gs(e);if(r.kind==="multipart"){let a=t,o=!!a&&typeof a=="object"&&!Array.isArray(a)&&("requestBody"in a||"parameters"in a),p=o?a.requestBody:t,c=o&&Array.isArray(a?.parameters)?Object.fromEntries(a.parameters.filter(l=>!!l&&l.in==="formData"&&typeof l.name=="string").map(l=>[l.name,l.value])):{},u=p&&typeof p=="object"&&!Array.isArray(p)?p:c;if(!u||typeof u!="object"||Array.isArray(u))throw new Error("multipart/form-data request bodies must be JSON objects.");let g=new FormData,f=r.schema?.properties&&typeof r.schema.properties=="object"?r.schema.properties:{};for(let[l,h]of Object.entries(u)){let w=f[l],T=r.encoding[l],m=xr(T?.contentType);if(w?.type==="string"&&w?.format==="binary"){let y=await Pt(h,m);g.append(l,new Blob([wr(y.buffer)],{type:y.mimeType}),y.fileName);continue}if(vt(h)){let y=await Pt(h,m);g.append(l,new Blob([wr(y.buffer)],{type:y.mimeType}),y.fileName);continue}h==null?g.append(l,""):typeof h=="object"?g.append(l,JSON.stringify(h)):g.append(l,String(h))}return{kind:"multipart",body:g,headers:{}}}if(r.kind==="binary"){let a=t,p=!!a&&typeof a=="object"&&!Array.isArray(a)&&"requestBody"in a?a.requestBody:t,c=await Pt(p,r.contentType);return{kind:"binary",body:c.buffer,headers:{"Content-Type":c.mimeType}}}let n=t;return{kind:"json",body:!!n&&typeof n=="object"&&!Array.isArray(n)&&"requestBody"in n?n.requestBody:t,headers:{}}}function hs(e){let t={};for(let[r,n]of Object.entries(e)){let s=n.type.trim(),i=s.endsWith("!")?s.slice(0,-1).trim():s;i.startsWith("[")&&i.endsWith("]")?t[r]=[]:i==="Boolean"?t[r]=!1:i==="Int"||i==="Float"?t[r]=0:t[r]=""}return t}async function Nt(e){let r=(await J()).apis?.[e]?.schemaType;if(r==="graphql")return"graphql";if(r==="openapi")return"openapi";try{let n=await A.readJson(j(e));if(Array.isArray(n)&&n.some(s=>typeof s?.rootType=="string"))return"graphql"}catch{}return"openapi"}async function ys(e){let t=R.join(R.dirname(q(e)),"bundled.json"),r=await A.readJson(t),n=typeof r?.source=="string"?r.source:typeof r?.sourceText=="string"?r.sourceText:void 0;if(!n)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);return n}async function jt(e,t,r=!1){let n=await ue(e,t),s=se(e,n);if(!r&&await A.pathExists(s))return await A.readJson(s);let a=(await A.readJson(j(e))).find(u=>u.operationId===t||u.name===t);if(!a)throw new Error(`Endpoint '${t}' not found in GraphQL endpoint list.`);let o=await ys(e),p=typeof a.rootType=="string"?a.rootType:typeof a.method=="string"?a.method:void 0;if(!p||p!=="query"&&p!=="mutation"&&p!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let c=await ge(o,p,t);return await A.ensureDir(R.dirname(s)),await A.writeJson(s,c,{spaces:2}),c}async function _t(e){return await Nt(e)}function Ct(e,t){let r=je(t),n=[];for(let[s,i]of Object.entries(r)){if(i===Ke)continue;let a=Ne(e,s);a!==void 0&&(ls(a,i)||n.push(`--update-request type mismatch at ${s}: expected ${hr(a)}, received ${hr(i)}.`))}return n}async function Lt(e,t){if(await _t(e)==="graphql"){let p=await ue(e,t),c=R.join(ae(e,p),"response-schema.json");if(await A.pathExists(c))return await A.readJson(c);let u=await jt(e,t,!1);return await A.ensureDir(R.dirname(c)),await A.writeJson(c,u,{spaces:2}),u}let r=await ue(e,t),n=q(e),s=await tr(R.resolve(n,`${r}.json`)),i=ae(e,r),a=R.join(i,"response-schema.json");if(await A.pathExists(a))return await A.readJson(a);let o=Is(s);return o!==void 0&&(await A.ensureDir(i),await A.writeJson(a,o,{spaces:2})),o}async function $t(e,t,r=!1,n,s,i){let a=await qe(e,t,await ue(e,t),r),o=await J(),p=o.apis?.[e]?.baseUrl;if(!p)throw new Error("Base URL not found in config");if(a.schemaType==="graphql"){let k=await ue(e,t),U=await jt(e,t,r),{requestJson:_,responseJsonPath:C}=await ws(e,k,r,U),le=R.join(q(e),k,"request.json"),ot=_,Ut=[];if(i&&i.length>0&&Ut.push(...i),s&&typeof s=="object"&&Object.keys(s).length>0){let ct={...je(s)};for(let[Gt,Zr]of Object.entries(s))Gt in ct||(ct[Gt]=Zr);await Ie(le,ct,2,{deleteSentinel:Ke}),ot=await A.readJson(le)}let Kr={...hs(a.args),...kr(ot)?ot.variables:{}},pt={query:a.query,variables:Kr},D={headers:{"Content-Type":"application/json"},url:"",warnings:Ut,responseJsonPath:C},Yr=new ve(p),N;try{if(N=await Yr.post(p,{headers:D.headers,body:pt}),N&&typeof N=="object"&&"status"in N){let V=N.status;typeof V=="number"&&(V<200||V>=300)&&D.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}: HTTP ${V}${"statusText"in N&&typeof N.statusText=="string"&&N.statusText?` ${N.statusText}`:""}`)}N&&typeof N=="object"&&Array.isArray(N.errors)&&N.errors?.length&&D.warnings.push("\u26A0\uFE0F GraphQL response contains errors."),await A.writeJson(D.responseJsonPath,N,{spaces:2})}catch(V){if(D.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}: ${V instanceof Error?V.message:String(V)}`),!await A.pathExists(D.responseJsonPath))return D.warnings.push(`response.json not found at ${D.responseJsonPath}`),{request:pt,response:void 0,warnings:D.warnings}}let Xr=await A.readJson(D.responseJsonPath);return{request:pt,response:Xr?.data?.[a.fieldName],warnings:D.warnings}}let c=await ue(e,t),u=await qe(e,t,c);if(u.schemaType!=="rest")throw new Error(`Invalid REST endpoint metadata for '${t}'.`);let g=await Q(e,t,c,r),{requestJson:f,responseJsonPath:l}=await Sr(e,c,r),h=R.join(q(e),c,"request.json"),w=f,T=[];if(i&&i.length>0&&T.push(...i),s&&typeof s=="object"&&Object.keys(s).length>0){let k=ds(s);k&&T.push(k);let _={...je(s)};for(let[C,le]of Object.entries(s))C in _||(_[C]=le);await Ie(h,_,2,{deleteSentinel:Ke}),w=await A.readJson(h)}let m=Ts(e,u,w,o,l,n,T),y=new ve(p);if(!u.method||!u.path)throw new Error(`Invalid OpenAPI endpoint metadata for '${t}'.`);let O=u.method.toLowerCase(),x;try{switch(O){case"get":x=await y.get(m.url,{headers:m.headers});break;case"post":{let k=await It(g,w);x=await y.post(m.url,{headers:{...m.headers,...k.headers},body:k.body})}break;case"put":{let k=await It(g,w);x=await y.put(m.url,{headers:{...m.headers,...k.headers},body:k.body})}break;case"delete":x=await y.delete(m.url,{headers:m.headers});break;case"patch":{let k=await It(g,w);x=await y.patch(m.url,{headers:{...m.headers,...k.headers},body:k.body})}break;case"head":x=await y.head(m.url,{headers:m.headers});break;case"options":x=await y.options(m.url,{headers:m.headers});break;default:throw new Error(`Unsupported HTTP method: ${u.method}`)}if(x&&typeof x=="object"&&"status"in x){let k=x.status;typeof k=="number"&&(k<200||k>=300)&&m.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}${m.url}: HTTP ${k}${"statusText"in x&&typeof x.statusText=="string"&&x.statusText?` ${x.statusText}`:""}`)}await A.writeJson(m.responseJsonPath,x,{spaces:2})}catch(k){if(m.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}${m.url}: ${k instanceof Error?k.message:String(k)}`),!await A.pathExists(m.responseJsonPath))return m.warnings.push(`response.json not found at ${m.responseJsonPath}`),{request:w,response:void 0,warnings:m.warnings}}let P=await A.readJson(m.responseJsonPath);return{request:w,response:P,warnings:m.warnings}}async function Er(e,t,r=!1,n,s,i){let{request:a,response:o,warnings:p}=await $t(e,t,r,n,s,i),c=p??[];if(await _t(e)==="graphql"){if(!o||typeof o!="object")return{valid:!1,warnings:c,errors:["response.body missing or invalid"]};let h=o;return Array.isArray(h.errors)&&h.errors.length>0?{valid:!1,warnings:c,errors:["GraphQL response contains errors"]}:{valid:!0,warnings:c}}let u=await Lt(e,t);if(u===void 0||Object.keys(u).length===0)return p.push("No response schema found for this operation. Skipping validation."),{valid:!0,warnings:c};if(!o)return{valid:!1,warnings:c};let f=new cs({allErrors:!0,strict:!1,strictSchema:!1,allowUnknownKeywords:!0,removeAdditional:!1}).compile(u);return f(o)?{valid:!0,warnings:c}:{valid:!1,errors:(f.errors||[]).map(w=>`${w.instancePath?w.instancePath.replace(/^\//,"response.body.").replace(/\//g,"."):"response.body"} ${w.message}`),warnings:c}}async function _e(e,t,r=!1){if(await _t(e)==="graphql"){let a=await jt(e,t,r),o=R.join(q(e),t,"request.json"),p=R.join(ae(e,t),"response.json"),c=Re(a);return await A.ensureDir(R.dirname(o)),await A.writeJson(o,c,{spaces:2}),{requestJsonPath:o,responseJsonPath:p,requestJson:c}}let{requestJson:n,responseJsonPath:s}=await Sr(e,t,r);return{requestJsonPath:R.join(q(e),t,"request.json"),responseJsonPath:s,requestJson:n}}async function Sr(e,t,r){let n=se(e,t),s=await A.readJson(n),i=R.join(q(e),t);await A.ensureDir(i);let a=R.join(i,"request.json"),o=R.join(i,"response.json");if(await(async()=>{if(r||!await A.pathExists(a))return!0;let c=await A.readJson(a);return!bs(c)})()){let c=ks(s);return await A.writeJson(a,c,{spaces:2}),{requestJson:c,responseJsonPath:o}}return{requestJson:await A.readJson(a),responseJsonPath:o}}async function ws(e,t,r,n){let s=R.join(q(e),t);await A.ensureDir(s);let i=R.join(s,"request.json"),a=R.join(s,"response.json");if(await(async()=>{if(r||!await A.pathExists(i))return!0;let p=await A.readJson(i);return!kr(p)})()){let p=Re(n);return await A.writeJson(i,p,{spaces:2}),{requestJson:p,responseJsonPath:a}}return{requestJson:await A.readJson(i),responseJsonPath:a}}function bs(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return Object.prototype.hasOwnProperty.call(t,"parameters")&&Array.isArray(t.parameters)}function Ts(e,t,r,n,s,i,a=[]){let o={},p=n.apis?.[e]?.auth?.headers;p&&typeof p=="object"&&Object.assign(o,p),i&&typeof i=="object"&&Object.assign(o,i);let c={},u={};for(let l of r.parameters||[])l.in==="path"?c[l.name]=l.value:l.in==="query"?u[l.name]=l.value:l.in==="header"&&(o[l.name]=String(l.value));if(!t.path)throw new Error(`Invalid OpenAPI endpoint metadata for '${t.operationId}'.`);let g=xs(t.path,c),f=As(u);return{headers:o,url:g+f,warnings:a,responseJsonPath:s}}function As(e){return Object.keys(e).length?"?"+Object.entries(e).map(([t,r])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(r))}`).join("&"):""}function ks(e){let t=[];if(Array.isArray(e.parameters))for(let s of e.parameters){let i=cr(s);t.push({name:s.name,in:s.in,value:i})}let r=null;(e?.requestBody||e?.parameters)&&(r=Es(e));let n={parameters:t};return r!==null&&(n.requestBody=r),n}function xs(e,t){return e.replace(/\{([^}]+)\}/g,(r,n)=>{if(!(n in t))throw new Error(`Missing path parameter: ${n}`);return encodeURIComponent(t[n])})}function Es(e){let t=Ss(e);if(t)return ke(t);let r=Ot(e);return r?ke(r):null}function Ss(e){let t=e?.requestBody?.content;if(!t||typeof t!="object")return null;for(let r of Object.values(t)){let n=r;if(n?.schema)return n.schema}return null}function Ot(e){let t=Array.isArray(e?.parameters)?e.parameters:[],r=t.find(a=>a.in==="body");if(r?.schema){let a=r.schema;return!a.type&&a.properties&&(a.type="object"),a}let n=e?.consumes||[],s=n.includes("application/x-www-form-urlencoded")||n.includes("multipart/form-data"),i=t.filter(a=>a.in==="formData");if(s&&i.length){let a={type:"object",properties:{},required:[]};for(let o of i){let p={};o.schema?Object.assign(p,o.schema):(o.type&&(p.type=o.type),o.items&&(p.items=o.items),o.format&&(p.format=o.format),o.enum&&(p.enum=o.enum),o.type==="file"&&(p.type="string",p.format="binary")),a.properties[o.name]=p,o.required&&a.required.push(o.name)}return a.required.length===0&&delete a.required,a}return null}function ke(e){if(!e)return null;if(e.const!==void 0)return e.const;if(e.default!==void 0)return e.default;if(Array.isArray(e.allOf)&&e.allOf.length>0){let t=e.allOf.map(r=>ke(r)).filter(r=>r!=null).reduce((r,n)=>Rr(r,n),{});if(t!=null)return t}if(Array.isArray(e.oneOf)&&e.oneOf.length>0)return br(e.oneOf.map(t=>ke(t)));if(Array.isArray(e.anyOf)&&e.anyOf.length>0)return br(e.anyOf.map(t=>ke(t)));if(!e.type&&e.properties&&(e.type="object"),e.$ref)throw new Error("Schema contains $ref. Resolve references before building template.");switch(e.type){case"string":return e.format==="binary"?{kind:"file",path:"",fileName:"",mimeType:""}:e.example??"";case"integer":case"number":return e.example??0;case"boolean":return e.example??!1;case"array":return[];case"object":let t={};if(e.properties)for(let[r,n]of Object.entries(e.properties))t[r]=ke(n);return t;default:return null}}function qt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Rr(e,t){if(e==null)return t;if(t==null)return e;if(qt(e)&&qt(t)){let r={...e};for(let[n,s]of Object.entries(t))r[n]=n in r?Rr(r[n],s):s;return r}return t}function br(e){let t=e.filter(n=>n!=null);if(t.length===0)return null;let r=t.filter(qt);return r.length>0?r.reduce((n,s)=>{let i=Object.keys(n).length;return Object.keys(s).length>i?s:n}):t[0]}function Rs(e){let t=e?.responses;if(!t)return null;let r=t[200]||t[201]||t.default||Object.values(t)[0];if(!r?.content)return null;let n=r.content["application/json"];if(n?.schema)return n.schema;for(let s of Object.values(r.content)){let i=s;if(i.schema)return i.schema}return null}function Ps(e){let t=e?.responses;return t?(t[200]||t[201]||t.default||Object.values(t)[0])?.schema||{}:{}}function Is(e){let t=Rs(e);if(t)return t;let r=Ps(e);if(r)return r}var Dt=E(()=>{"use strict";dr();W();Et();ht();ce();nt();kt();Rt();Pe();W();Te()});import*as ee from"node:fs/promises";import $ from"path";import Os from"readline";import{fileURLToPath as qs}from"url";function xe(e){return e?"Yes":"No"}function Ns(e){return Array.isArray(e)?e.join(`
|
|
9
|
-
`):e}function
|
|
8
|
+
The temporary file with your changes is: ${f}`),h}}var et,At=S(()=>{"use strict";be();et="__delete__"});import B from"path";import Mn from"find-root";function ae(e,t){let r=v(e);return B.join(r,`${t}.json`)}function oe(e){return B.resolve(ie,".openapi-skills",e,"bundled.json")}function Tt(e){return B.resolve(ie,".openapi-skills",e,"components.json")}function pe(e,t){let r=v(e);return B.resolve(r,t)}function v(e){return B.resolve(ie,".openapi-skills",e,"schemas")}function ve(e){return B.resolve(ie,".openapi-skills",e)}function or(){return B.resolve(ie,".openapi-skills","config.json")}function L(e){return B.resolve(ie,".openapi-skills",e,"endpoints.json")}function tt(e,t,r){let n=pe(e,t),s=r==="response-schema"?"response-schema.json":`${r}.json`;return B.join(n,s)}function rt(){return B.resolve(ie,".openapi-skills")}function nt(){let e=process.cwd();try{return Mn(e)}catch{return e}}var ie,K=S(()=>{"use strict";ie=nt()});import{readFile as Vn}from"fs/promises";import zn from"path";import ce from"fs-extra";async function U(){return await ce.readJSON(Ae)}async function kt(){if(await ce.ensureDir(Hn),!await ce.pathExists(Ae)){let e={apis:{}};await ce.writeJson(Ae,e,{spaces:2})}}function pr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function Te(e,t={}){if(typeof e!="string"||e.trim().length===0)throw new Error("API name is required.");let{baseUrl:r,auth:n,vars:s,version:i,openapiSource:o,schemaType:a,removeApi:p}=t,c={};if(p){if(!await ce.pathExists(Ae))throw new Error("Config file not found.");let u=await U();if(!pr(u)||!pr(u.apis))throw new Error("Invalid config file.");if(!(e in u.apis))throw new Error(`API '${e}' not found`);delete u.apis[e],await ce.writeJson(Ae,u,{spaces:2});return}if(await kt(),n!==void 0&&(c[`apis.${e}.auth.headers`]=n),s!==void 0)for(let[u,m]of Object.entries(s))c[`apis.${e}.vars.${u}`]=m;if(i!==void 0&&(c[`apis.${e}.version`]=i),o!==void 0){let u=o;try{new URL(o)}catch{u=zn.normalize(o)}c[`apis.${e}.openapiSource`]=u}r!==void 0&&(c[`apis.${e}.baseUrl`]=r),a!==void 0&&(c[`apis.${e}.schemaType`]=a),Object.keys(c).length!==0&&await qe(Ae,c,2)}function Wn(e){let t=e instanceof Error?e.message:String(e);return/config/i.test(t)?{type:"ConfigError",message:t}:/permission|EACCES|EPERM/i.test(t)?{type:"DirectoryDeletionError",message:t}:{type:"DeleteApiError",message:t}}async function cr(e){if(typeof e!="string"||e.trim().length===0)return{ok:!1,error:{type:"InvalidApiName",message:"API name is required."}};try{if(!(await ue()).includes(e))return{ok:!1,error:{type:"ApiNotFound",message:`API '${e}' is not installed.`}};await Te(e,{removeApi:!0});let r=ve(e);return await ce.remove(r),{ok:!0,message:`API ${e} removed successfully`,data:{removedApi:e}}}catch(t){return{ok:!1,error:Wn(t)}}}async function st(e,t){let n=(await U()).apis[e];if(!n)throw new Error(`API '${e}' not found`);switch(t){case"version":return n.version??"unknown";case"baseUrl":return n.baseUrl;case"authHeaders":return n.auth?.headers??{};case"vars":return Object.entries(n.vars??{})}}async function ur(e){try{let t=await Vn(L(e),"utf-8");return JSON.parse(t)}catch(t){throw t instanceof SyntaxError?new Error(`Failed to parse endpoints.json: Invalid JSON format. ${t.message}`):new Error(`Failed to read endpoints.json: ${t instanceof Error?t.message:String(t)}`)}}async function ue(){let e=await U();return Object.keys(e.apis)||[]}var Hn,Ae,de=S(()=>{"use strict";At();K();Hn=rt(),Ae=or()});import xt from"@apidevtools/swagger-parser";import Kn from"@apidevtools/json-schema-ref-parser";import I from"fs-extra";import Y from"path";function dr(e){let t;try{let r=new URL(e);t=Y.basename(r.pathname,Y.extname(r.pathname))}catch{t=Y.basename(e,Y.extname(e))}return se(t||"api")}function Yn(e){if(e instanceof Error)return/circular/i.test(e.message)||/circular/i.test(e.name);if(typeof e=="object"&&e!==null){let t=String(e.message??""),r=String(e.name??"");return/circular/i.test(t)||/circular/i.test(r)}return!1}function Et(e,t=new WeakSet){if(e&&typeof e=="object"){if(t.has(e))return;if(t.add(e),Array.isArray(e)){let n=e.map(s=>Et(s,t));return t.delete(e),n}let r={};for(let[n,s]of Object.entries(e)){let i=Et(s,t);i!==void 0&&(r[n]=i)}return t.delete(e),r}return e}async function Xn(e){let t=oe(e),r=await I.readJson(t),n=typeof r?.source=="string"?r.source:typeof r?.sourceText=="string"?r.sourceText:void 0;if(!n)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);return n}async function Zn(e,t,r,n=!1){let s=ae(e,r);if(!n&&await I.pathExists(s))return I.readJson(s);let i=await I.readJson(L(e)),o=Array.isArray(i)?i.find(u=>u.operationId===t||u.name===t||u.sanitizedOperationId===r):void 0;if(!o)throw new Error(`Endpoint '${t}' not found in GraphQL endpoint list.`);let a=typeof o.rootType=="string"?o.rootType:typeof o.method=="string"?o.method:void 0;if(!a||a!=="query"&&a!=="mutation"&&a!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let p=await Xn(e),c=await ye(p,a,t);return await I.ensureDir(Y.dirname(s)),await I.writeJson(s,c,{spaces:2}),c}function es(e,t){for(let[r,n]of Object.entries(e))for(let[s,i]of Object.entries(n))if(i&&typeof i=="object"&&"operationId"in i){let o=i;if(o.operationId===t)return{pathKey:r,method:s,operation:o}}}async function ts(e,t){let r=typeof e.operationId=="string"?e.operationId:"unknown-operation",n=typeof e.method=="string"?e.method.toUpperCase():"GET",s=typeof e.path=="string"?e.path:"unknown-path",i=H;i&&d.progressLine(`Dereferencing endpoint ${r} (${n} ${s})...`);let o={openapi:"3.0.0",paths:{"/temp":{get:e}},definitions:t,components:t},a=await Kn.dereference(o,{mutateInputSchema:!1,dereference:{circular:"ignore"}}),p=Et(a),c=p.paths,u=c&&typeof c=="object"?c["/temp"]:void 0,m=u&&typeof u=="object"?u.get:void 0;return m&&typeof m=="object"?(i&&d.progressLine(`Endpoint ${r} (${n} ${s}) dereference complete.`),m):(i&&d.progressLine(`Endpoint ${r} (${n} ${s}) dereference complete.`),p)}async function Q(e,t,r,n=!1){let s=ae(e,r);if(!n&&await I.pathExists(s))return I.readJson(s);let i=oe(e),o=Tt(e),a=await I.readJson(i);if(a&&typeof a=="object"&&a.schemaType==="graphql")return await Zn(e,t,r,n);if(!a||typeof a!="object"||!("paths"in a))throw new Error(`Bundled OpenAPI document not found for API '${e}'. Run generate first.`);let p={},c=a.components,u=a.definitions;c&&typeof c=="object"&&!Array.isArray(c)?p=c:u&&typeof u=="object"&&!Array.isArray(u)?p=u:await I.pathExists(o)&&(p=await I.readJson(o));let m=es(a.paths,t);if(!m)throw new Error(`Endpoint '${t}' not found in bundled OpenAPI document.`);let f={operationId:t,method:m.method,path:m.pathKey,...m.operation},l=await ts(f,p);return await I.ensureDir(Y.dirname(s)),await I.writeJson(s,l,{spaces:2}),l}async function rs(e,t){if(!t)return xt.bundle(e);try{return await xt.dereference(e,{dereference:{circular:!1}})}catch(r){throw Yn(r)?new Error("The --dereference flag cannot be used because this OpenAPI spec contains circular references. Try running without --dereference."):r}}function ns(e){if(typeof e!="object"||e===null||Array.isArray(e))throw new Error("Invalid OpenAPI schema: expected a document object.");let t=e;if(t.swagger!==void 0&&t.openapi!==void 0)throw new Error("Invalid OpenAPI schema: both 'swagger' and 'openapi' version fields are present.");if(t.swagger!==void 0){if(t.swagger==="2.0")return"2";throw new Error(`Unsupported Swagger version '${String(t.swagger)}'. This CLI supports Swagger 2.0 and OpenAPI 3.0.x.`)}if(t.openapi!==void 0){if(typeof t.openapi!="string")throw new Error("Invalid OpenAPI schema: 'openapi' version must be a string.");if(/^3\.0\.\d+$/.test(t.openapi))return"3";throw new Error(`Unsupported OpenAPI version '${t.openapi}'. This CLI supports OpenAPI 2.0 and 3.0.x; For OpenAPI 3.1.0 and later, please use openapi-skills Pro.`)}throw new Error("Invalid OpenAPI schema: missing version declaration ('swagger' or 'openapi'); cannot determine a supported version.")}async function ss(e,t,r={}){let n="",s="unknown",i,o=r.progress!==!1&&H;try{o&&d.progressLine(`Loading OpenAPI document from ${e}...`),i=await rs(e,r.dereference===!0),o&&d.progressLine("OpenAPI document load complete.")}catch(a){throw d.error(`Error during parsing OpenAPI schema: ${a instanceof Error?a.message:String(a)}`),a}if(typeof i!="object"||!i.paths)throw new Error("Invalid OpenAPI schema: Missing 'paths'");try{s=ns(i),n=r.rename||dr(e);let a=ve(n);await I.remove(a);let p=v(n);await I.ensureDir(p);let c=oe(n);if(await I.writeJson(c,i,{spaces:2}),!r.dereference){let g=Tt(n);await I.writeJson(g,i?.components??{},{spaces:2})}let u=[],m=0,f=0,l=r.progress!==!1&&H;for(let[g,b]of Object.entries(i.paths))for(let[T,h]of Object.entries(b))h&&typeof h=="object"&&"operationId"in h&&h.operationId&&(m+=1);for(let[g,b]of Object.entries(i.paths))for(let[T,h]of Object.entries(b))if(h&&typeof h=="object"&&"operationId"in h){let y=h;if(y.operationId){let A={operationId:y.operationId,sanitizedOperationId:se(y.operationId),method:T,path:g};if(Array.isArray(y.tags)){let P=y.tags.map(O=>typeof O=="string"?O.trim():"").filter(O=>O.length>0);P.length>0&&(A.tags=P)}y.summary!==void 0&&(A.summary=y.summary),y.description!==void 0&&(A.description=y.description),u.push(A),f+=1,l&&d.progress(`\rProcessed ${f}/${m}`)}}l&&m>0&&d.progressLine("");try{let g=Y.join(a,"endpoints.json");await I.writeJson(g,u,{spaces:2})}catch(g){throw d.error(`Error writing endpoints.json: ${g instanceof Error?g.message:String(g)}`),g}try{await Te(n,{baseUrl:t,openapiSource:e,schemaType:"openapi",version:s});let g=t?"with baseUrl":"without baseUrl";d.info(`Schema '${n}' added to config.json ${g} and openapiSource recorded.`)}catch(g){throw d.error(`Error updating config.json: ${g instanceof Error?g.message:String(g)}`),g}}catch(a){throw d.error(`Error during OpenAPI schema processing: ${a instanceof Error?a.message:String(a)}`),a}return n}async function is(e,t,r={},n){let s="",i=r.progress!==!1&&H,o=n??await He(e);if(!We(o))throw new Error("Invalid GraphQL schema: missing GraphQL schema markers or builder pattern.");i&&d.progressLine(`Loading GraphQL schema from ${e}...`),s=r.rename||dr(e);let a=ve(s);await I.remove(a);let p=v(s);await I.ensureDir(p);let c=await Ye(o,e);if(c.length===0)throw new Error("Invalid GraphQL schema: no query, mutation, or subscription fields were found.");let u=oe(s);await I.writeJson(u,{schemaType:"graphql",source:o},{spaces:2});let m=c.map(f=>({name:f.name,sanitizedOperationId:f.sanitizedOperationId,rootType:f.rootType,summary:f.summary,description:f.description}));for(let f of c){let l=ae(s,f.sanitizedOperationId);await I.ensureDir(Y.dirname(l)),await I.writeJson(l,f,{spaces:2})}await I.writeJson(Y.join(a,"endpoints.json"),m,{spaces:2});try{await Te(s,{baseUrl:t,openapiSource:e,schemaType:"graphql",version:"graphql"});let f=t?"with baseUrl":"without baseUrl";d.info(`Schema '${s}' added to config.json ${f} and GraphQL source recorded.`)}catch(f){throw d.error(`Error updating config.json: ${f instanceof Error?f.message:String(f)}`),f}return i&&d.progressLine("GraphQL schema load complete."),s}async function lr(e,t,r={}){let n=await He(e).catch(()=>{});return n&&We(n)?await is(e,t,r,n):await ss(e,t,r)}async function fr(e){try{let t=await He(e).catch(()=>{});if(t&&We(t)){await Ye(t,e);return}await xt.validate(e);return}catch(t){throw new Error(t instanceof Error?t.message:String(t))}}var ke=S(()=>{"use strict";Oe();de();K();be();mt()});function as(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function St(e){if(!(!e||typeof e!="object"))return as(e.schema)?e.schema:e}function mr(e){let t=St(e);switch(typeof t?.type=="string"?t.type:typeof e?.type=="string"?e.type:void 0){case"string":return"";case"number":case"integer":return 0;case"boolean":return!1;case"array":return[];case"object":return{};default:return null}}var Pt=S(()=>{"use strict"});import xe from"fs-extra";function it(e){return e.replace(/[^a-zA-Z0-9]+(.)/g,(t,r)=>r.toUpperCase()).replace(/^[a-z]/,t=>t.toUpperCase())}function Z(e,t,r){if(!(!e||typeof e!="object")){if(Array.isArray(e.enum)){let n=it(r);t[n]=e.enum}if(e.properties&&typeof e.properties=="object")for(let[n,s]of Object.entries(e.properties))Z(s,t,`${r}_${n}`);e.items&&Z(e.items,t,`${r}_item`),e.oneOf&&e.oneOf.forEach((n,s)=>Z(n,t,`${r}_oneOf_${s}`)),e.anyOf&&e.anyOf.forEach((n,s)=>Z(n,t,`${r}_anyOf_${s}`)),e.allOf&&e.allOf.forEach((n,s)=>Z(n,t,`${r}_allOf_${s}`))}}function ee(e){if(!(!e||typeof e!="object")){if(delete e.xml,e.properties&&typeof e.properties=="object")for(let t of Object.values(e.properties))ee(t);e.items&&ee(e.items),e.oneOf&&e.oneOf.forEach(ee),e.anyOf&&e.anyOf.forEach(ee),e.allOf&&e.allOf.forEach(ee)}}function gr(e){if(!e||typeof e!="object")return null;let r=Object.keys(e).filter(n=>/^\d{3}$/.test(n)).find(n=>n.startsWith("2"));return r?e[r]:null}function It(e){if(!e||typeof e!="object")return null;let t=Object.entries(e).find(([r])=>r.toLowerCase().includes("json"));return t?t[1]:null}function os(e){let t=gr(e);if(!t)return null;if(t.content){let r=It(t.content);return!r||!r.schema?null:r.schema}return t.schema??null}function ps(e){let t=gr(e);return t?t.schema??null:null}function cs(e){let t=Array.isArray(e?.parameters)?e.parameters:[],r=t.find(i=>i.in==="body");if(r?.schema)return r.schema;let n=t.filter(i=>i.in==="formData");if(n.length===0)return null;let s={type:"object",properties:{}};for(let i of n){let o={};i.schema&&typeof i.schema=="object"?Object.assign(o,i.schema):(typeof i.type=="string"&&(o.type=i.type),i.items&&(o.items=i.items),typeof i.format=="string"&&(o.format=i.format),Array.isArray(i.enum)&&(o.enum=i.enum),i.type==="file"&&(o.type="string",o.format="binary")),s.properties[i.name]=o}return s}function ds(e){let t={};if(!e||typeof e!="object")return t;for(let[r,n]of Object.entries(e)){if(!/^\d{3}$/.test(r)||r.startsWith("2"))continue;let s=n.content,i=s?It(s):null,o=i&&i.schema?i.schema:n.schema??us;t[r]=o}return t}function ls(e,t){let r={};for(let n of["path","query","header"])for(let[s,i]of Object.entries(e[n]||{}))r[s]={...i.schema,required:i.required??!1,description:i.description,in:n};return{typeName:`${it(t)}Params`,schema:r}}async function Ne(e,t,r,n=!1){let s=await U(),i=await xe.readJson(L(e)),o=Array.isArray(i)&&i.some(y=>typeof y?.rootType=="string");if(s.apis?.[e]?.schemaType==="graphql"||s.apis?.[e]?.schemaType!=="openapi"&&o){let y=i.find(E=>E.operationId===t||E.name===t);if(!y)throw new Error(`Endpoint with operationId '${t}' not found.`);let A=typeof y.rootType=="string"?y.rootType:typeof y.method=="string"?y.method:void 0;if(!A||A!=="query"&&A!=="mutation"&&A!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let P=v(e)+`/${r}.json`,O;if(!n&&await xe.pathExists(P))O=await xe.readJson(P);else{let E=await xe.readJson(oe(e)),V=typeof E?.source=="string"?E.source:typeof E?.sourceText=="string"?E.sourceText:void 0;if(!V)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);O=await ye(V,A,t),await xe.ensureDir(v(e)),await xe.writeJson(P,O,{spaces:2})}return{schemaType:"graphql",fieldName:y.name??t,rootType:A,args:Object.fromEntries(Object.entries(O.args??{}).map(([E,V])=>{let x=V;return[E,{type:x.typeName??"unknown",required:x.required===!0}]})),returnType:O.returns?.typeName??"unknown",query:Re(O).query}}let p=i.find(y=>y.operationId===t);if(!p)throw new Error(`Endpoint with operationId '${t}' not found.`);let c=await Q(e,t,r,n),u={path:{},query:{},header:{}};for(let y of c.parameters||[])(y.in==="path"||y.in==="query"||y.in==="header")&&(u[y.in][y.name]={description:y.description,required:y.required,schema:St(y)});let m=os(c.responses)??ps(c.responses),f={};m&&(ee(m),Z(m,f,`${t}_response`));let l=ls(u,t),g=ds(c.responses),b=null,T=c.requestBody;if(T&&T.content){let y=It(T.content);y&&y.schema&&(b=y.schema,ee(b),Z(b,f,`${t}_request`))}else b=cs(c),b&&(ee(b),Z(b,f,`${t}_request`));let h=it(t.replace(/^(get|post|put|delete|patch|head|options)/i,"")||t);return{schemaType:"rest",operationId:t,method:p.method,path:p.path,deprecated:p.deprecated??c.deprecated??!1,params:l,response:m?{typeName:h,schema:m}:null,requestBody:b?{typeName:`${it(t)}Request`,schema:b}:null,errors:g,enums:f}}var us,Rt=S(()=>{"use strict";K();ke();Pt();Oe();de();us={type:"object",properties:{message:{type:"string"},status:{type:"number"}}}});var je,hr=S(()=>{"use strict";je=class{constructor(t){this.baseUrl=t}baseUrl;async request(t,r,n={}){if(!/^https?:\/\//i.test(this.baseUrl))throw new Error(`Invalid baseUrl: "${this.baseUrl}". Must include http:// or https://`);let s=this.baseUrl.endsWith("/")?this.baseUrl:this.baseUrl+"/",i=new URL(r.replace(/^\//,""),s).toString(),o="body"in n&&n.body!==void 0&&t!=="GET"&&t!=="HEAD",a=new Headers(n.headers??{}),p=null;if(o){let f=n.body,l=typeof FormData<"u"&&f instanceof FormData,g=typeof Blob<"u"&&f instanceof Blob,b=f instanceof ArrayBuffer||ArrayBuffer.isView(f),T=typeof Buffer<"u"&&Buffer.isBuffer(f);l?(a.delete("Content-Type"),p=f):g||b||T||typeof f=="string"?p=f:(a.has("Content-Type")||a.set("Content-Type","application/json"),p=JSON.stringify(f))}let c=await fetch(i,{method:t,headers:a,body:p}),u=await c.text(),m={};if(u.trim().length>0)try{m=JSON.parse(u)}catch{m=u}return m!==null&&typeof m=="object"&&!Array.isArray(m)?{...m,status:c.status,statusText:c.statusText}:{body:m,status:c.status,statusText:c.statusText}}get(t,r){return this.request("GET",t,r)}head(t,r){return this.request("HEAD",t,r)}options(t,r){return this.request("OPTIONS",t,r)}post(t,r){return this.request("POST",t,r)}put(t,r){return this.request("PUT",t,r)}patch(t,r){return this.request("PATCH",t,r)}delete(t,r){return this.request("DELETE",t,r)}}});import fs from"fs-extra";function yr(e){return{orGroups:e.trim().toLowerCase().split("|").map(r=>r.trim()).filter(Boolean).map(r=>r.split(/\s+/).filter(Boolean))}}function ms(e,t){return t.orGroups.length===0?!0:t.orGroups.some(r=>r.every(n=>e.includes(n)))}function gs(e){return e.split("/").map(t=>t.trim().toLowerCase()).filter(Boolean).flatMap(t=>{if(t.startsWith("{")&&t.endsWith("}")){let r=t.slice(1,-1).trim();return r?[t,r]:[t]}return[t]})}function hs(e,t){return t?t===":param"?/\{[^/{}]+\}/.test(e):t.startsWith("/")?e.startsWith(t):gs(e).includes(t):!0}function ys(e,t){return yr(t).orGroups.some(n=>n.every(s=>hs(e,s)))}function ws(e){return e?(Array.isArray(e)?e:[e]).map(t=>t.trim()).filter(Boolean):[]}function bs(e,t){if(typeof t!="string"||t.trim().length===0||t.trim()===":")return e;let r=t.trim(),n=r.match(/^-?\d+$/),s=r.match(/^(-?\d*)?:(-?\d*)?$/),i,o;if(n)i=Number(r),o=i;else if(s){let f=s[1],l=s[2];i=f===void 0||f===""?0:Number(f),o=l===void 0||l===""?e.length-1:Number(l)}else throw new Error(`Invalid --index value: ${t}`);if(Number.isNaN(i)||Number.isNaN(o))throw new Error(`Invalid --index value: ${t}`);let a=f=>f<0?e.length+f:f,p=a(i),c=a(o);if(e.length===0)return[];let u=Math.max(0,p),m=Math.min(e.length-1,c);return u>m?[]:e.slice(u,m+1)}function wr(e,t){return bs(e,t)}function at(e,t){let r=e;if(t.operationId){let s=t.operationId.toLowerCase();r=r.filter(i=>(i.operationId||"").toLowerCase()===s)}if(t.method){let s=t.method.toLowerCase();r=r.filter(i=>(i.method||"").toLowerCase()===s)}if(t.rootType){let s=t.rootType.toLowerCase();r=r.filter(i=>(i.rootType||"").toLowerCase()===s)}if(t.tag){let s=t.tag.toLowerCase();r=r.filter(i=>(Array.isArray(i.tags)?i.tags:[]).some(a=>typeof a=="string"&&a.toLowerCase()===s))}let n=ws(t.path);if(n.length>0&&(r=r.filter(s=>{let i=(s.path||"").toString().toLowerCase();return n.every(o=>ys(i,o))})),t.filter){let s=yr(t.filter);r=r.filter(i=>{let o=[i.operationId,i.name,i.method,i.rootType,i.path,i.summary,i.description].map(a=>(a||"").toString().toLowerCase()).join(" ");return ms(o,s)})}return r}async function As(e){let t=v(e);try{let r=await fs.readdir(t,{withFileTypes:!0});return new Set(r.filter(n=>n.isFile()&&n.name.toLowerCase().endsWith(".json")).map(n=>n.name.slice(0,-5)))}catch(r){if(r?.code==="ENOENT")return new Set;throw r}}async function br(e,t){let r=await As(e);return r.size===0?[]:t.filter(n=>{let s=typeof n.sanitizedOperationId=="string"?n.sanitizedOperationId:"";return r.has(s)})}var Ot=S(()=>{"use strict";K()});async function X(e,t){let r={operationId:t},n=await ur(e),s=at(n,r)[0]??n.find(i=>i.name===t);return s?.sanitizedOperationId??s?.operationId??s?.name??""}var le,ot=S(()=>{"use strict";de();Ot();le=X});function Ts(e){return e.replace(/\[(\d+)\]/g,".$1").split(".").filter(r=>r.length>0).map(r=>/^\d+$/.test(r)?Number(r):r)}function _e(e,t){let r=e;for(let n of Ts(t)){if(r==null)return;if(typeof n=="number"){if(!Array.isArray(r)&&typeof r!="object")return;r=r[n];continue}if(typeof r!="object")return;r=r[n]}return r}function Ar(e,t,r){return Array.isArray(e)?e.filter(n=>String(_e(n,t))===String(r)):e}var qt=S(()=>{"use strict"});function N(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ks(e){let t=e.requestBody;if(N(t)&&N(t.content)){for(let a of Object.values(t.content))if(N(a)&&a.schema)return a.schema}let r=Array.isArray(e.parameters)?e.parameters:[],n=r.find(a=>N(a)&&a.in==="body");if(N(n)&&n.schema)return n.schema;let s=r.filter(a=>N(a)&&a.in==="formData");if(s.length===0)return;let i={},o=[];for(let a of s)!N(a)||typeof a.name!="string"||(i[a.name]=N(a.schema)?a.schema:Object.fromEntries(["type","items","format","enum"].filter(p=>a[p]!==void 0).map(p=>[p,a[p]])),a.required===!0&&o.push(a.name));return{type:"object",properties:i,...o.length>0?{required:o}:{}}}function xs(e){let t=[],r=new Set,n=!1,s=i=>{if(!N(i)){n=!0;return}if(r.has(i)){n=!0;return}if("$ref"in i||"oneOf"in i||"anyOf"in i||"not"in i){n=!0;return}if(r.add(i),t.push(i),Array.isArray(i.allOf))for(let o of i.allOf)s(o);r.delete(i)};for(let i of e)s(i);return{schemas:t,ambiguous:n}}function vt(e,t){let r=xs(t);if(r.ambiguous)return!1;let n=r.schemas;if(Array.isArray(e)){let a=n.map(p=>p.items).filter(p=>N(p));return a.length===0?!1:e.reduce((p,c)=>vt(c,a)||p,!1)}if(!N(e))return!1;let s=new Set(n.flatMap(a=>Array.isArray(a.required)?a.required.filter(p=>typeof p=="string"):[])),i=new Map;for(let a of n)if(N(a.properties))for(let[p,c]of Object.entries(a.properties)){let u=i.get(p)??[];u.push(c),i.set(p,u)}let o=!1;for(let[a,p]of Object.entries(e)){let c=i.get(a);if(c){if(p===""&&!s.has(a)){delete e[a],o=!0;continue}o=vt(p,c)||o}}return o}function kr(e,t){if(!N(e)||!N(t))return!1;let r=!1;if(Array.isArray(e.parameters)&&Array.isArray(t.parameters)){let s=t.parameters.filter(N),i=e.parameters.filter(o=>{if(!N(o)||o.value!==""||!["path","query","header"].includes(String(o.in)))return!0;let a=s.find(p=>p.name===o.name&&p.in===o.in);return!a||o.in==="path"||a.required===!0?!0:(r=!0,!1)});r&&(e.parameters=i)}let n=ks(t);return n&&"requestBody"in e&&(r=vt(e.requestBody,[n])||r),r}function Tr(e){let t=e;for(;t&&t.kind==="non-null"&&t.ofType;)t=t.ofType;return t}function Es(e){if(!e)return!1;let t=e;for(;t;){if(t.defaultValue!==void 0)return!1;t=t.ofType}return e.required===!0||e.kind==="non-null"||e.typeName.trim().endsWith("!")}function xr(e,t){if(Array.isArray(e)){let n=Tr(t);return n?.kind!=="list"||!n.ofType?!1:e.reduce((s,i)=>xr(i,n.ofType)||s,!1)}if(!N(e))return!1;let r=Tr(t);return r?.kind!=="input-object"||!r.fields?!1:Er(e,r.fields)}function Er(e,t){let r=!1;for(let[n,s]of Object.entries(e)){let i=t[n];if(i){if(s===""&&!Es(i)){delete e[n],r=!0;continue}r=xr(s,i)||r}}return r}function Sr(e,t){return!N(e)||!N(e.variables)?!1:Er(e.variables,t.args)}var Pr=S(()=>{"use strict"});import k from"fs-extra";import R from"path";import Ss from"ajv";import{fileURLToPath as Ps}from"url";function Le(e,t="",r={}){if(!e||typeof e!="object"||Array.isArray(e))return r;for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)?Le(s,i,r):r[i]=s}return r}function vr(e,t=""){if(!e||typeof e!="object"||Array.isArray(e))return[];let r=[];for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)&&(r.push(i),r.push(...vr(s,i)))}return Array.from(new Set(r))}function Is(e){let t=vr(e);if(t.length===0)return;let r=Le(e);return["Use only flattened object dot-notation keys with --force.",`Example: --force --update-request '${JSON.stringify(r)}'.`,`Detected nested keys: ${t.join(", ")}.`].join(" ")}function Ir(e){return e===null?"null":Nr(e)?"file":Array.isArray(e)?"array":typeof e}function Nr(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.kind==="file"}function Ct(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.path=="string"&&(e.kind===void 0||e.kind==="file")}function Rs(e,t){return Nr(e)?typeof t=="string"||Ct(t):e===null?t===null:Array.isArray(e)?Array.isArray(t):typeof e=="object"?!!t&&typeof t=="object"&&!Array.isArray(t):typeof t==typeof e}function jr(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.query=="string"&&typeof e.variables=="object"&&!Array.isArray(e.variables)}function _r(e){if(e)return e.split(",")[0]?.trim()||void 0}function Os(e){switch(R.extname(e).toLowerCase()){case".pdf":return"application/pdf";case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".webp":return"image/webp";case".gif":return"image/gif";case".txt":return"text/plain";case".csv":return"text/csv";case".json":return"application/json";case".xml":return"application/xml";case".xlsx":return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case".xls":return"application/vnd.ms-excel";case".docx":return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";case".zip":return"application/zip";default:return"application/octet-stream"}}function Rr(e){let t=e.trim();return t.startsWith("@")?R.resolve(t.slice(1)):t.startsWith("file://")?R.resolve(Ps(new URL(t))):R.resolve(t)}async function Nt(e,t){let r,n,s;if(typeof e=="string"){if(e.trim().length===0)throw new Error("File upload path cannot be empty.");r=Rr(e)}else if(Ct(e)){if(e.path.trim().length===0)throw new Error("File upload path cannot be empty.");r=Rr(e.path),n=e.fileName?.trim()||void 0,s=e.mimeType?.trim()||void 0}if(!r)throw new Error("File upload values must be a file path string or { kind: 'file', path, fileName?, mimeType? } object.");if(!await k.pathExists(r))throw new Error(`Upload file not found: ${r}`);let i=await k.readFile(r),o=n||R.basename(r),a=s||_r(t)||Os(r);return{buffer:i,path:r,fileName:o,mimeType:a}}function Or(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function qs(e){let t=Object.entries(e),r=t.find(([o])=>o.toLowerCase().includes("multipart/form-data"));if(r)return{contentType:r[0],contentObject:r[1]};let n=t.find(([o,a])=>{let p=a?.schema;return o.toLowerCase().includes("octet-stream")||p?.type==="string"&&p?.format==="binary"});if(n)return{contentType:n[0],contentObject:n[1]};let s=t.find(([o])=>o.toLowerCase().includes("json"));if(s)return{contentType:s[0],contentObject:s[1]};let i=t[0];return i?{contentType:i[0],contentObject:i[1]}:void 0}function vs(e){let t=e?.requestBody,n=(Array.isArray(e?.parameters)?e.parameters:[]).filter(a=>a&&a.in==="formData"),i=(Array.isArray(e?.consumes)?e.consumes:[]).some(a=>typeof a=="string"&&a.toLowerCase().includes("multipart/form-data"));if(n.length>0&&i)return{kind:"multipart",schema:_t(e)??{type:"object",properties:{}},encoding:{}};if(!t||typeof t!="object")return n.length>0?{kind:"multipart",schema:_t(e)??{type:"object",properties:{}},encoding:{}}:{kind:"json"};let o=t.content;if(o&&typeof o=="object"&&!Array.isArray(o)){let a=qs(o);if(!a)return{kind:"json"};let p=a.contentObject,c=p?.schema;if(a.contentType.toLowerCase().includes("multipart/form-data"))return{kind:"multipart",schema:c&&typeof c=="object"?c:{type:"object",properties:{}},encoding:p?.encoding??{}};if(a.contentType.toLowerCase().includes("octet-stream")||c?.type==="string"&&c?.format==="binary")return{kind:"binary",contentType:a.contentType}}return{kind:"json"}}async function jt(e,t){let r=vs(e);if(r.kind==="multipart"){let o=t,a=!!o&&typeof o=="object"&&!Array.isArray(o)&&("requestBody"in o||"parameters"in o),p=a?o.requestBody:t,c=a&&Array.isArray(o?.parameters)?Object.fromEntries(o.parameters.filter(l=>!!l&&l.in==="formData"&&typeof l.name=="string").map(l=>[l.name,l.value])):{},u=p&&typeof p=="object"&&!Array.isArray(p)?p:c;if(!u||typeof u!="object"||Array.isArray(u))throw new Error("multipart/form-data request bodies must be JSON objects.");let m=new FormData,f=r.schema?.properties&&typeof r.schema.properties=="object"?r.schema.properties:{};for(let[l,g]of Object.entries(u)){let b=f[l],T=r.encoding[l],h=_r(T?.contentType);if(b?.type==="string"&&b?.format==="binary"){let y=await Nt(g,h);m.append(l,new Blob([Or(y.buffer)],{type:y.mimeType}),y.fileName);continue}if(Ct(g)){let y=await Nt(g,h);m.append(l,new Blob([Or(y.buffer)],{type:y.mimeType}),y.fileName);continue}g==null?m.append(l,""):typeof g=="object"?m.append(l,JSON.stringify(g)):m.append(l,String(g))}return{kind:"multipart",body:m,headers:{}}}if(r.kind==="binary"){let o=t,p=!!o&&typeof o=="object"&&!Array.isArray(o)&&"requestBody"in o?o.requestBody:t,c=await Nt(p,r.contentType);return{kind:"binary",body:c.buffer,headers:{"Content-Type":c.mimeType}}}let n=t;return{kind:"json",body:!!n&&typeof n=="object"&&!Array.isArray(n)&&"requestBody"in n?n.requestBody:t,headers:{}}}function Ns(e){let t={};for(let[r,n]of Object.entries(e)){let s=n.type.trim(),i=s.endsWith("!")?s.slice(0,-1).trim():s;i.startsWith("[")&&i.endsWith("]")?t[r]=[]:i==="Boolean"?t[r]=!1:i==="Int"||i==="Float"?t[r]=0:t[r]=""}return t}async function $t(e){let r=(await U()).apis?.[e]?.schemaType;if(r==="graphql")return"graphql";if(r==="openapi")return"openapi";try{let n=await k.readJson(L(e));if(Array.isArray(n)&&n.some(s=>typeof s?.rootType=="string"))return"graphql"}catch{}return"openapi"}async function js(e){let t=R.join(R.dirname(v(e)),"bundled.json"),r=await k.readJson(t),n=typeof r?.source=="string"?r.source:typeof r?.sourceText=="string"?r.sourceText:void 0;if(!n)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);return n}async function Dt(e,t,r=!1){let n=await le(e,t),s=ae(e,n);if(!r&&await k.pathExists(s))return await k.readJson(s);let o=(await k.readJson(L(e))).find(u=>u.operationId===t||u.name===t);if(!o)throw new Error(`Endpoint '${t}' not found in GraphQL endpoint list.`);let a=await js(e),p=typeof o.rootType=="string"?o.rootType:typeof o.method=="string"?o.method:void 0;if(!p||p!=="query"&&p!=="mutation"&&p!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let c=await ye(a,p,t);return await k.ensureDir(R.dirname(s)),await k.writeJson(s,c,{spaces:2}),c}async function Ft(e){return await $t(e)}function Jt(e,t){let r=Le(t),n=[];for(let[s,i]of Object.entries(r)){if(i===et)continue;let o=_e(e,s);o!==void 0&&(Rs(o,i)||n.push(`--update-request type mismatch at ${s}: expected ${Ir(o)}, received ${Ir(i)}.`))}return n}async function Ut(e,t){if(await Ft(e)==="graphql"){let p=await le(e,t),c=R.join(pe(e,p),"response-schema.json");if(await k.pathExists(c))return await k.readJson(c);let u=await Dt(e,t,!1);return await k.ensureDir(R.dirname(c)),await k.writeJson(c,u,{spaces:2}),u}let r=await le(e,t),n=v(e),s=await ar(R.resolve(n,`${r}.json`)),i=pe(e,r),o=R.join(i,"response-schema.json");if(await k.pathExists(o))return await k.readJson(o);let a=Qs(s);return a!==void 0&&(await k.ensureDir(i),await k.writeJson(o,a,{spaces:2})),a}async function Gt(e,t,r=!1,n,s,i,o=!1,a=!1){let p=await Ne(e,t,await le(e,t),r),c=await U(),u=c.apis?.[e]?.baseUrl;if(!u)throw new Error("Base URL not found in config");if(p.schemaType==="graphql"){let x=await le(e,t),D=await Dt(e,t,r),{requestJson:ne,responseJsonPath:me}=await _s(e,x,r||a,D),Fe=R.join(v(e),x,"request.json"),dt=ne,Vt=[];if(i&&i.length>0&&Vt.push(...i),s&&typeof s=="object"&&Object.keys(s).length>0||o){let ft={...s?Le(s):{}};for(let[Je,ln]of Object.entries(s??{}))Je in ft||(ft[Je]=ln);await qe(Fe,ft,2,{deleteSentinel:et,transform:o?Je=>Sr(Je,D):void 0}),dt=await k.readJson(Fe)}let cn={...Ns(p.args),...jr(dt)?dt.variables:{}},lt={query:p.query,variables:cn},F={headers:{"Content-Type":"application/json"},url:"",warnings:Vt,responseJsonPath:me},un=new je(u),_;try{if(_=await un.post(u,{headers:F.headers,body:lt}),_&&typeof _=="object"&&"status"in _){let z=_.status;typeof z=="number"&&(z<200||z>=300)&&F.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${u}: HTTP ${z}${"statusText"in _&&typeof _.statusText=="string"&&_.statusText?` ${_.statusText}`:""}`)}_&&typeof _=="object"&&Array.isArray(_.errors)&&_.errors?.length&&F.warnings.push("\u26A0\uFE0F GraphQL response contains errors."),await k.writeJson(F.responseJsonPath,_,{spaces:2})}catch(z){if(F.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${u}: ${z instanceof Error?z.message:String(z)}`),!await k.pathExists(F.responseJsonPath))return F.warnings.push(`response.json not found at ${F.responseJsonPath}`),{request:lt,response:void 0,warnings:F.warnings}}let dn=await k.readJson(F.responseJsonPath);return{request:lt,response:dn?.data?.[p.fieldName],warnings:F.warnings}}let m=await le(e,t),f=await Ne(e,t,m);if(f.schemaType!=="rest")throw new Error(`Invalid REST endpoint metadata for '${t}'.`);let l=await Q(e,t,m,r),{requestJson:g,responseJsonPath:b}=await Cr(e,m,r||a),T=R.join(v(e),m,"request.json"),h=g,y=[];if(i&&i.length>0&&y.push(...i),s&&typeof s=="object"&&Object.keys(s).length>0||o){let x=s?Is(s):void 0;x&&y.push(x);let ne={...s?Le(s):{}};for(let[me,Fe]of Object.entries(s??{}))me in ne||(ne[me]=Fe);await qe(T,ne,2,{deleteSentinel:et,transform:o?me=>kr(me,l):void 0}),h=await k.readJson(T)}let A=Cs(e,f,h,c,b,n,y),P=new je(u);if(!f.method||!f.path)throw new Error(`Invalid OpenAPI endpoint metadata for '${t}'.`);let O=f.method.toLowerCase(),E;try{switch(O){case"get":E=await P.get(A.url,{headers:A.headers});break;case"post":{let x=await jt(l,h);E=await P.post(A.url,{headers:{...A.headers,...x.headers},body:x.body})}break;case"put":{let x=await jt(l,h);E=await P.put(A.url,{headers:{...A.headers,...x.headers},body:x.body})}break;case"delete":E=await P.delete(A.url,{headers:A.headers});break;case"patch":{let x=await jt(l,h);E=await P.patch(A.url,{headers:{...A.headers,...x.headers},body:x.body})}break;case"head":E=await P.head(A.url,{headers:A.headers});break;case"options":E=await P.options(A.url,{headers:A.headers});break;default:throw new Error(`Unsupported HTTP method: ${f.method}`)}if(E&&typeof E=="object"&&"status"in E){let x=E.status;typeof x=="number"&&(x<200||x>=300)&&A.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${u}${A.url}: HTTP ${x}${"statusText"in E&&typeof E.statusText=="string"&&E.statusText?` ${E.statusText}`:""}`)}await k.writeJson(A.responseJsonPath,E,{spaces:2})}catch(x){if(A.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${u}${A.url}: ${x instanceof Error?x.message:String(x)}`),!await k.pathExists(A.responseJsonPath))return A.warnings.push(`response.json not found at ${A.responseJsonPath}`),{request:h,response:void 0,warnings:A.warnings}}let V=await k.readJson(A.responseJsonPath);return{request:h,response:V,warnings:A.warnings}}async function Lr(e,t,r=!1,n,s,i,o=!1,a=!1){let{request:p,response:c,warnings:u}=await Gt(e,t,r,n,s,i,o,a),m=u??[];if(await Ft(e)==="graphql"){if(!c||typeof c!="object")return{valid:!1,warnings:m,errors:["response.body missing or invalid"]};let T=c;return Array.isArray(T.errors)&&T.errors.length>0?{valid:!1,warnings:m,errors:["GraphQL response contains errors"]}:{valid:!0,warnings:m}}let f=await Ut(e,t);if(f===void 0||Object.keys(f).length===0)return u.push("No response schema found for this operation. Skipping validation."),{valid:!0,warnings:m};if(!c)return{valid:!1,warnings:m};let g=new Ss({allErrors:!0,strict:!1,strictSchema:!1,allowUnknownKeywords:!0,removeAdditional:!1}).compile(f);return g(c)?{valid:!0,warnings:m}:{valid:!1,errors:(g.errors||[]).map(h=>`${h.instancePath?h.instancePath.replace(/^\//,"response.body.").replace(/\//g,"."):"response.body"} ${h.message}`),warnings:m}}async function Ce(e,t,r=!1,n=!1){if(await Ft(e)==="graphql"){let a=await Dt(e,t,r),p=R.join(v(e),t,"request.json"),c=R.join(pe(e,t),"response.json"),u=Re(a);return await k.ensureDir(R.dirname(p)),await k.writeJson(p,u,{spaces:2}),{requestJsonPath:p,responseJsonPath:c,requestJson:u}}let{requestJson:s,responseJsonPath:i}=await Cr(e,t,r||n);return{requestJsonPath:R.join(v(e),t,"request.json"),responseJsonPath:i,requestJson:s}}async function Cr(e,t,r){let n=ae(e,t),s=await k.readJson(n),i=R.join(v(e),t);await k.ensureDir(i);let o=R.join(i,"request.json"),a=R.join(i,"response.json");if(await(async()=>{if(r||!await k.pathExists(o))return!0;let c=await k.readJson(o);return!Ls(c)})()){let c=Ds(s);return await k.writeJson(o,c,{spaces:2}),{requestJson:c,responseJsonPath:a}}return{requestJson:await k.readJson(o),responseJsonPath:a}}async function _s(e,t,r,n){let s=R.join(v(e),t);await k.ensureDir(s);let i=R.join(s,"request.json"),o=R.join(s,"response.json");if(await(async()=>{if(r||!await k.pathExists(i))return!0;let p=await k.readJson(i);return!jr(p)})()){let p=Re(n);return await k.writeJson(i,p,{spaces:2}),{requestJson:p,responseJsonPath:o}}return{requestJson:await k.readJson(i),responseJsonPath:o}}function Ls(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return Object.prototype.hasOwnProperty.call(t,"parameters")&&Array.isArray(t.parameters)}function Cs(e,t,r,n,s,i,o=[]){let a={},p=n.apis?.[e]?.auth?.headers;p&&typeof p=="object"&&Object.assign(a,p),i&&typeof i=="object"&&Object.assign(a,i);let c={},u={};for(let l of r.parameters||[])l.in==="path"?c[l.name]=l.value:l.in==="query"?u[l.name]=l.value:l.in==="header"&&(a[l.name]=String(l.value));if(!t.path)throw new Error(`Invalid OpenAPI endpoint metadata for '${t.operationId}'.`);let m=Fs(t.path,c),f=$s(u);return{headers:a,url:m+f,warnings:o,responseJsonPath:s}}function $s(e){return Object.keys(e).length?"?"+Object.entries(e).map(([t,r])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(r))}`).join("&"):""}function Ds(e){let t=[];if(Array.isArray(e.parameters))for(let s of e.parameters){let i=mr(s);t.push({name:s.name,in:s.in,value:i})}let r=null;(e?.requestBody||e?.parameters)&&(r=Js(e));let n={parameters:t};return r!==null&&(n.requestBody=r),n}function Fs(e,t){return e.replace(/\{([^}]+)\}/g,(r,n)=>{if(!(n in t))throw new Error(`Missing path parameter: ${n}`);return encodeURIComponent(t[n])})}function Js(e){let t=Us(e);if(t)return Ee(t);let r=_t(e);return r?Ee(r):null}function Us(e){let t=e?.requestBody?.content;if(!t||typeof t!="object")return null;for(let r of Object.values(t)){let n=r;if(n?.schema)return n.schema}return null}function _t(e){let t=Array.isArray(e?.parameters)?e.parameters:[],r=t.find(o=>o.in==="body");if(r?.schema){let o=r.schema;return!o.type&&o.properties&&(o.type="object"),o}let n=e?.consumes||[],s=n.includes("application/x-www-form-urlencoded")||n.includes("multipart/form-data"),i=t.filter(o=>o.in==="formData");if(s&&i.length){let o={type:"object",properties:{},required:[]};for(let a of i){let p={};a.schema?Object.assign(p,a.schema):(a.type&&(p.type=a.type),a.items&&(p.items=a.items),a.format&&(p.format=a.format),a.enum&&(p.enum=a.enum),a.type==="file"&&(p.type="string",p.format="binary")),o.properties[a.name]=p,a.required&&o.required.push(a.name)}return o.required.length===0&&delete o.required,o}return null}function Ee(e){if(!e)return null;if(e.const!==void 0)return e.const;if(e.default!==void 0)return e.default;if(Array.isArray(e.allOf)&&e.allOf.length>0){let t=e.allOf.map(r=>Ee(r)).filter(r=>r!=null).reduce((r,n)=>$r(r,n),{});if(t!=null)return t}if(Array.isArray(e.oneOf)&&e.oneOf.length>0)return qr(e.oneOf.map(t=>Ee(t)));if(Array.isArray(e.anyOf)&&e.anyOf.length>0)return qr(e.anyOf.map(t=>Ee(t)));if(!e.type&&e.properties&&(e.type="object"),e.$ref)throw new Error("Schema contains $ref. Resolve references before building template.");switch(e.type){case"string":return e.format==="binary"?{kind:"file",path:"",fileName:"",mimeType:""}:e.example??"";case"integer":case"number":return e.example??0;case"boolean":return e.example??!1;case"array":return[];case"object":let t={};if(e.properties)for(let[r,n]of Object.entries(e.properties))t[r]=Ee(n);return t;default:return null}}function Lt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function $r(e,t){if(e==null)return t;if(t==null)return e;if(Lt(e)&&Lt(t)){let r={...e};for(let[n,s]of Object.entries(t))r[n]=n in r?$r(r[n],s):s;return r}return t}function qr(e){let t=e.filter(n=>n!=null);if(t.length===0)return null;let r=t.filter(Lt);return r.length>0?r.reduce((n,s)=>{let i=Object.keys(n).length;return Object.keys(s).length>i?s:n}):t[0]}function Gs(e){let t=e?.responses;if(!t)return null;let r=t[200]||t[201]||t.default||Object.values(t)[0];if(!r?.content)return null;let n=r.content["application/json"];if(n?.schema)return n.schema;for(let s of Object.values(r.content)){let i=s;if(i.schema)return i.schema}return null}function Bs(e){let t=e?.responses;return t?(t[200]||t[201]||t.default||Object.values(t)[0])?.schema||{}:{}}function Qs(e){let t=Gs(e);if(t)return t;let r=Bs(e);if(r)return r}var Bt=S(()=>{"use strict";hr();K();Rt();At();de();ot();Pt();qt();Oe();K();ke();Pr()});import*as te from"node:fs/promises";import $ from"path";import Ms from"readline";import{fileURLToPath as Vs}from"url";function Se(e){return e?"Yes":"No"}function Hs(e){return Array.isArray(e)?e.join(`
|
|
9
|
+
`):e}function Ws(e){let t=e.arguments.length>0?e.arguments.map(s=>{let i=[s.type,s.required?"required":"optional"];s.positional&&i.push("positional"),s.flag&&i.push("flag");let o=s.description?`: ${s.description}`:"",a=s.flag?"--":"";return`- \`${s.positional?s.name:`${a}${s.name}`}\` (${i.join(", ")})${o}`}).join(`
|
|
10
10
|
`):"- None",r=e.examples.length>0?e.examples.map(s=>`- \`\`\`bash
|
|
11
11
|
${s}
|
|
12
12
|
\`\`\``).join(`
|
|
13
|
-
`):"- None",n=e.filesWritten.length>0?e.filesWritten.map(s=>`\`${s}\``).join(", "):"None";return[`### ${e.name}`,"",`**Category:** ${e.category}`,"","**Usage:**","```bash",e.usage,"```","",`**Description:** ${
|
|
14
|
-
`)}async function
|
|
13
|
+
`):"- None",n=e.filesWritten.length>0?e.filesWritten.map(s=>`\`${s}\``).join(", "):"None";return[`### ${e.name}`,"",`**Category:** ${e.category}`,"","**Usage:**","```bash",e.usage,"```","",`**Description:** ${Hs(e.description)}`,"","**Arguments:**",t,"","**Examples:**",r,"",`**Returns:** ${e.returns.type} - ${e.returns.description}`,"",`**Side Effects:** Writes Files: ${Se(e.sideEffects.writesFiles)}, Reads Files: ${Se(e.sideEffects.readsFiles)}, Network: ${Se(e.sideEffects.network)}`,"",`**Constraints:** Destructive: ${Se(e.constraints.destructive)}, Idempotent: ${Se(e.constraints.idempotent)}, Requires Parsed API: ${Se(e.constraints.requiresParsedApi)}`,"",`**Files Written:** ${n}`].join(`
|
|
14
|
+
`)}async function Ks(){let{program:e}=await Br().then(()=>Gr);return e.commands.filter(n=>!!n.agentMeta).filter(n=>n.agentMeta.name!=="help"&&n.agentMeta.name!=="install").map(n=>Ws(n.agentMeta)).join(`
|
|
15
15
|
|
|
16
|
-
`)}async function
|
|
17
|
-
https://openapi-skills.lemonsqueezy.com/`)}catch{}}var
|
|
18
|
-
`),payload:a}}var
|
|
16
|
+
`)}async function Fr(e,t){let r=[{label:"~/.claude/skills/openapi-skills",value:$.join(e,".claude","skills","openapi-skills")},{label:"~/.cursor/skills/openapi-skills",value:$.join(e,".cursor","skills","openapi-skills")},{label:"~/.agents/skills/openapi-skills",value:$.join(e,".agents","skills","openapi-skills")},{label:"~/.github/skills/openapi-skills",value:$.join(e,".github","skills","openapi-skills")},{label:"Other (enter a custom path)",value:"__custom__"}];function n(i){let o=Ms.createInterface({input:process.stdin,output:process.stderr});return new Promise(a=>o.question(i,p=>{o.close(),a(p)}))}d.info("Select install location:"),r.forEach((i,o)=>{d.info(` ${o+1}) ${i.label}`)});let s;for(;;){s=await n(`Enter number (1-${r.length}): `);let i=parseInt(s,10)-1;if(!isNaN(i)&&i>=0&&i<r.length&&r[i])return r[i].value==="__custom__"?(await n(`Enter custom install path [${t}]: `)).trim()||t:r[i].value;d.warn(`Invalid selection. Please enter a number between 1 and ${r.length}.`)}}async function Dr(e,t,r){let n=$.join(zs,"../skill-templates",e);try{let s=await te.readFile(n,"utf8"),i=r?await r(s):s;await te.mkdir($.dirname(t),{recursive:!0}),await te.writeFile(t,i,"utf8")}catch(s){let i=s instanceof Error?s.message:String(s);throw new Error(`Failed to copy skill template "${e}" from "${n}" to "${t}": ${i}`,{cause:s instanceof Error?s:void 0})}}async function Jr(e,t){await te.mkdir(t,{recursive:!0});let r=$.join(t,"references");await te.mkdir(r,{recursive:!0});let n=[{templateName:"SKILL.md",outputPath:$.join(t,"SKILL.md")},{templateName:"write-client-code.md",outputPath:$.join(r,"write-client-code.md")},{templateName:"create-endpoint-test.md",outputPath:$.join(r,"create-endpoint-test.md")},{templateName:"http-client.md",outputPath:$.join(r,"http-client.md")}];for(let s of n){if(s.templateName==="SKILL.md"){await Dr(s.templateName,s.outputPath,async i=>{let o=await Ks();if(!i.includes("<command-list-here>"))throw new Error("SKILL.md template is missing <command-list-here>.");return i.replace("<command-list-here>",o)});continue}await Dr(s.templateName,s.outputPath)}return{destDir:t,files:n.map(s=>s.outputPath)}}var zs,Ur=S(()=>{"use strict";be();zs=$.dirname(Vs(import.meta.url))});import Qr from"fs-extra";import Ys from"https";import Xs from"os";import Zs from"path";async function Mr(e){try{let t=new Date().toISOString().slice(0,10),r=Zs.join(Xs.tmpdir(),`openapi-skills-session-${t}`);if(Qr.existsSync(r))return;Qr.writeFileSync(r,String(Date.now()));let n=await new Promise((s,i)=>{Ys.get("https://registry.npmjs.org/@tzurp/openapi-skills/latest",o=>{let a="";o.on("data",p=>a+=p),o.on("end",()=>{try{let p=JSON.parse(a);s(p.version)}catch(p){i(p)}})}).on("error",i)});n&&n!==e&&(d.warn(`UPDATE_AVAILABLE: A newer version of openapi-skills is available \u2192 ${n} (current: ${e})`),d.warn("Update with: npm install -g @tzurp/openapi-skills")),d.banner(`\u{1F48E} openapi-skills v2 is available \u2014 including mock APIs, HTML docs, schema diffing, code\u2011first tools, full OpenAPI 3.1 support, premium support, and additional Pro tools.
|
|
17
|
+
https://openapi-skills.lemonsqueezy.com/`)}catch{}}var Vr=S(()=>{"use strict";be()});function $e(e){let t=JSON.stringify(e)??"",r=Buffer.byteLength(t,"utf8");return{text:t,sizeBytes:r}}var zr=S(()=>{"use strict"});import ei from"readline";async function Hr(e){let t=`Are you sure you want to delete ${e}? Y/n `;return await new Promise(r=>{let n=ei.createInterface({input:process.stdin,output:process.stderr});n.question(t,s=>{n.close();let i=s.trim().toLowerCase();r(i==="y"||i==="yes")})})}var Wr=S(()=>{"use strict"});function De(e,t="",r=new Set){if(t&&r.add(t),!e||typeof e!="object")return r;if(Array.isArray(e)){for(let n=0;n<e.length;n++){let s=t?`${t}.${n}`:`${n}`;De(e[n],s,r)}return r}for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;De(s,i,r)}return r}function pt(e,t="",r=new Set){if(!e||typeof e!="object")return r;if(Array.isArray(e))return t&&r.add(t),r;for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)?pt(s,i,r):r.add(i)}return r}function Kr(e){let t=[];return e.request&&t.push("request"),e.response&&t.push("response"),e.responseSchema&&t.push("response-schema"),t.length!==1?{artifactName:void 0,error:t.length===0?"Exactly one of --request, --response, or --response-schema is required.":"Only one of --request, --response, or --response-schema can be used at a time."}:{artifactName:t[0],error:void 0}}var Yr=S(()=>{"use strict"});import Xr from"fs-extra";function ct(e,t){let r=pe(e,t);return{fileCount:Xr.existsSync(r)?Xr.readdirSync(r).length:0}}async function ti(e,t){let r=new Set,n=new Set;for(let o of t)r.has(o)&&n.add(o),r.add(o);if(n.size>0)throw new Error(`Duplicate operationId(s) are not allowed in prepare-only mode: ${Array.from(n).join(", ")}`);let s=await ue();if(!Array.isArray(s)||!s.includes(e))throw new Error(`API '${e}' is not installed. Run generate first.`);let i=[];for(let o of t){let a=await X(e,o);if(!a)throw new Error(`OperationId '${o}' was not found for API '${e}'.`);i.push({operationId:o,sanitizedOperationId:a})}return i}async function Zr(e,t,r=!1,n=!1){let s=await ti(e,t),i=[];for(let{operationId:p,sanitizedOperationId:c}of s){await Q(e,p,c),await Ce(e,c,r,n);let u=ct(e,c);i.push({kind:"request-result",apiName:e,operationId:p,sanitizedOperationId:c,preparedOnly:!0,request:null,response:null,warnings:[],...u})}let o=[`Prepared request templates for ${i.length} operations:`,"",...i.map(p=>` \u2713 ${p.operationId}`),"","No live requests were executed.","Use `openapi-skills request <operationId> --force-request --update-request ...` with only flattened object dot-notation keys to reset the request template from the cached schema and run each step."],a={kind:"request-result",apiName:e,preparedOnly:!0,operationIds:t,summary:o,message:"No live requests were executed.",hint:"Use `openapi-skills request <operationId> --force-request --update-request ...` with only flattened object dot-notation keys to reset the request template from the cached schema and run each step.",operations:i};return{operations:i,summaryText:o.join(`
|
|
18
|
+
`),payload:a}}var en=S(()=>{"use strict";ke();de();ot();K();Bt()});function tn(e){let t=e.trim();if(t==="count")return{kind:"count"};if(/^-?\d+$/.test(t))return{kind:"index",index:Number(t)};let r=t.match(/^(-?\d*):(-?\d*)$/);if(r)return{kind:"range",start:r[1]===""?0:Number(r[1]),end:r[2]===""?Number.POSITIVE_INFINITY:Number(r[2])};let n=t.indexOf("=");if(n>0){let s=t.slice(0,n).trim();if(s)return{kind:"path",path:s,value:t.slice(n+1)}}return{kind:"invalid"}}var rn=S(()=>{"use strict"});function ri(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ut(e,t){if(typeof e!="string"||e.trim().length===0)throw new Error(`${t} must be a non-empty base64url string.`);let r;try{r=Buffer.from(e,"base64url").toString("utf8")}catch{throw new Error(`${t} must be valid base64url-encoded JSON.`)}let n;try{n=JSON.parse(r)}catch(s){let i=s instanceof Error?s.message:String(s);throw new Error(`${t} decoded value must be valid JSON: ${i}`)}if(!ri(n))throw new Error(`${t} decoded value must be a JSON object.`);return n}var nn=S(()=>{"use strict"});var sn,an,Qt=S(()=>{"use strict";sn={UNKNOWN_API:{reason:"The API name is not registered in .openapi-skills/config.json.",nextCommandHint:"Run 'openapi-skills get-api-names' to list available APIs, then use the correct name."},MISSING_PARSED_API:{reason:"No APIs have been parsed yet. The workspace is empty.",nextCommandHint:"Run 'openapi-skills generate' with an OpenAPI or GraphQL source."},NO_ENDPOINTS_FOUND:{reason:"The API endpoint file does not exist. Run generate first.",nextCommandHint:"Run 'openapi-skills generate' to create endpoints.json."},NO_RESPONSE_SCHEMA:{reason:"The response schema artifact has not been created yet.",nextCommandHint:"Run 'openapi-skills request <operationId> --api <apiName>' to create the response-schema artifact."},REQUEST_TEMPLATE_STALE:{reason:"The request template does not exist for this operation.",nextCommandHint:"Run the command again with --force to regenerate the request template."},SCHEMA_VALIDATION_FAILED:{reason:"The provided OpenAPI or GraphQL schema is malformed.",nextCommandHint:"Fix the schema at its source and retry."},INVALID_FILTER_SYNTAX:{reason:"--filter requires the target to be an array.",nextCommandHint:"Use --response-schema first to inspect the response shape, then use --get to narrow the value before filtering."},MISSING_FILTER_ARGUMENT:{reason:"The list command requires at least one filter to avoid returning large, unbounded result sets.",nextCommandHint:"Add --path, --filter, --method, --root-type, or --index to narrow results."},SCHEMA_TYPE_MISMATCH:{reason:"The flag used is incompatible with this schema type.",nextCommandHint:"Use --path and --method for OpenAPI; use --root-type for GraphQL."},INVALID_JSON_ARGUMENT:{reason:"The provided JSON argument is malformed.",nextCommandHint:"Fix the JSON syntax and retry."},INVALID_VARIABLE_SYNTAX:{reason:"Variable syntax is invalid. Expected key=value format.",nextCommandHint:"Use --var key=value format."},INVALID_UPDATE_REQUEST_JSON:{reason:"The --update-request JSON could not be parsed.",nextCommandHint:"Fix the JSON syntax and retry."},INVALID_REQUEST_UPDATE:{reason:"The request keys specified do not exist in request.json.",nextCommandHint:"Use valid request.json keys. Inspect with 'openapi-skills get-operation <operationId> --api <apiName> --request' first."},OVERSIZED_OUTPUT:{reason:"The output is too large to display.",nextCommandHint:"Use --get or --filter to reduce output size."},API_PARSE_ERROR:{reason:"An error occurred while parsing the API schema.",nextCommandHint:"Review the error details and fix the schema at its source."},REQUEST_FAILED:{reason:"The HTTP request failed.",nextCommandHint:"Check the base URL, authentication headers, and network connectivity."},VALIDATION_FAILED:{reason:"The response does not match the expected schema.",nextCommandHint:"Verify that the API response matches the declared schema."},CONFIG_ERROR:{reason:"Failed to read or write configuration file.",nextCommandHint:"Check file permissions on .openapi-skills/config.json."}},an={UNKNOWN_API:"usage",MISSING_FILTER_ARGUMENT:"usage",INVALID_FILTER_SYNTAX:"usage",SCHEMA_TYPE_MISMATCH:"usage",INVALID_VARIABLE_SYNTAX:"usage",INVALID_JSON_ARGUMENT:"usage",SCHEMA_VALIDATION_FAILED:"validation",INVALID_REQUEST_UPDATE:"validation",INVALID_UPDATE_REQUEST_JSON:"validation",MISSING_PARSED_API:"state",NO_ENDPOINTS_FOUND:"state",NO_RESPONSE_SCHEMA:"state",REQUEST_TEMPLATE_STALE:"state",OVERSIZED_OUTPUT:"state",API_PARSE_ERROR:"runtime",REQUEST_FAILED:"runtime",VALIDATION_FAILED:"runtime",CONFIG_ERROR:"runtime"}});function w(e,t){let r=an[e],n=sn[e],s=t.nextCommand??"None",i=t.reason??n?.reason??"Unable to remediate automatically.",o=t.severity??"error";return{ok:!1,error:{code:e,category:r,severity:o,summary:t.summary,message:t.message,remediation:{required:!0,next_command:s,reason:i},context:t.context??{}}}}function q(e,t){let r={ok:!0,data:e};return t?.kind!==void 0&&(r.kind=t.kind),r}var on=S(()=>{"use strict";Qt()});var Gr={};mn(Gr,{program:()=>j});import{Command as ni}from"commander";import M from"fs-extra";import si from"path";import ii from"os";import{createRequire as ai}from"module";async function fe(e){return(await ue().catch(()=>[])).includes(e)?!0:(d.result(w("UNKNOWN_API",{summary:`API '${e}' is not installed.`,message:`No API named '${e}' was found. Run 'openapi-skills get-api-names' to list installed APIs, or run 'openapi-skills generate <openapi-source>' first.`,context:{api_name:e},nextCommand:"openapi-skills get-api-names"})),process.exitCode=1,!1)}var oi,Mt,pi,Uo,j,pn,ci,ui,di,li,fi,mi,gi,hi,yi,wi,bi,Ai,Ti,ki,Br=S(async()=>{ke();K();de();Rt();Bt();Ur();ke();be();Ot();ot();Vr();zr();Wr();Yr();en();qt();rn();nn();on();Qt();Oe();oi=ai(import.meta.url),Mt=oi("../package.json"),pi=Mt.repository.url;await Mr(Mt.version);Uo=rt(),j=new ni,pn=process.argv.includes("--silent");j.name("openapi-skills").description("A command\u2011line tool for working with OpenAPI/Swagger and GraphQL specs. Use it to parse specs into artifacts, explore API endpoints and root fields, validate requests, generate typed client metadata, and teach AI agents how to operate the CLI and write API tests and client code.").version(Mt.version);ci=`
|
|
19
19
|
\x1B[32m
|
|
20
20
|
\u2584\u2584\u2584 \u2584\u2584\u2584\u2584 \u2584\u2584\u2584\u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584\u2584 \u2584\u2584\u2584\u2584 \u2584\u2584 \u2584\u2584\u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584\u2584\u2584
|
|
21
21
|
\u2588\u2588\u2580\u2588\u2588 \u2588\u2588\u2584\u2588\u2580 \u2588\u2588\u2584\u2584 \u2588\u2588\u2588\u2584\u2588\u2588 \u2588\u2588\u2580\u2588\u2588 \u2588\u2588\u2584\u2588\u2580 \u2588\u2588 \u2584\u2584\u2584 \u2588\u2588\u2588\u2584\u2584 \u2588\u2588\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2584\u2584
|
|
22
22
|
\u2580\u2588\u2588\u2588\u2580 \u2588\u2588 \u2588\u2588\u2584\u2584\u2584 \u2588\u2588 \u2580\u2588\u2588 \u2588\u2588\u2580\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2584\u2584\u2588\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2584\u2584\u2584 \u2588\u2588\u2584\u2584\u2584 \u2584\u2584\u2588\u2588\u2580
|
|
23
23
|
\x1B[0m
|
|
24
|
-
`;
|
|
24
|
+
`;j.option("--silent","Hide the banner and Pro feature summary in help output for agent-friendly usage.");pn||j.addHelpText("before",ci);j.addHelpText("before",`
|
|
25
25
|
===================
|
|
26
26
|
openapi-skills CLI
|
|
27
27
|
===================
|
|
28
|
-
`);
|
|
28
|
+
`);ui=2026,di=new Date().getFullYear(),li=`${ui}-${di}`;pn||j.addHelpText("after",`
|
|
29
|
+
\x1B[35m
|
|
29
30
|
-------------------------------------------------------------------------------
|
|
30
|
-
|
|
31
|
+
openapi-skills Pro-only commands:
|
|
32
|
+
generate-openapi Generate an OpenAPI document from source annotations.
|
|
33
|
+
docs Generate and serve an HTML viewer for an OpenAPI schema.
|
|
34
|
+
compare Compare APIs/operations or responses with response schemas.
|
|
35
|
+
mock-server Start a local mock HTTP server.
|
|
36
|
+
|
|
37
|
+
Pro-only options on shared commands:
|
|
38
|
+
install --skills-annotator
|
|
39
|
+
request --mock, --update-request-file <path>
|
|
40
|
+
request --patch-set <path=value>, --patch-set-num <path=value>,
|
|
41
|
+
--patch-set-bool <path=value>, --patch-append <path=value>,
|
|
42
|
+
--patch-append-num <path=value>, --patch-append-bool <path=value>,
|
|
43
|
+
--patch-delete <path>
|
|
44
|
+
|
|
45
|
+
Learn more: https://github.com/tzurp/openapi-skills-pro
|
|
46
|
+
-------------------------------------------------------------------------------
|
|
47
|
+
\x1B[0m
|
|
48
|
+
`);j.addHelpText("after",`
|
|
49
|
+
-------------------------------------------------------------------------------
|
|
50
|
+
Copyright \xA9 ${li} Tzur Paldi \u2014 Powered by Bedekbyte\xAE All rights reserved
|
|
31
51
|
Support: tzur.paldi@outlook.com
|
|
32
|
-
Project: ${
|
|
52
|
+
Project: ${pi}
|
|
33
53
|
-------------------------------------------------------------------------------
|
|
34
|
-
`);
|
|
54
|
+
`);j.command("install").description("Install SKILL.md and scenario markdowns for agent frameworks like Claude and GitHub Copilot. Supports: --skills [--global].").option("--skills","Install SKILL.md files for agent frameworks.").option("--global","Install the skill bundle under the user's home directory instead of the current project.").action(async e=>{if(e.global&&!e.skills){d.result(w("CONFIG_ERROR",{summary:"--global requires --skills.",message:"Use `openapi-skills install --skills --global` to install the skill bundle under your home directory.",context:{},nextCommand:"openapi-skills install --skills --global"})),process.exitCode=1;return}if(!e.skills){await kt(),d.info(".openapi-skills directory and configuration installed. Use --skills to install SKILL.md files for agent frameworks.");return}let t=e.global?ii.homedir():nt(),r=nt(),n=si.join(t,"installed-skills");d.info(`Source directory (copied): ${r}`);let s=await Fr(t,n);d.info(`Target install directory: ${s}`);try{let i=await Jr(r,s);d.info("openapi-skills skill bundle installed")}catch(i){d.result(w("CONFIG_ERROR",{summary:"Failed to install skill bundle.",message:i instanceof Error?i.message:String(i),context:{install_path:s},nextCommand:"openapi-skills install --skills"})),process.exitCode=1}});fi=j.command("generate [openapi-source]").description("Parse an OpenAPI 2.0, OpenAPI 3.0.x, or GraphQL source (file path or URL) and generate endpoints.json, schemas/, and config.json. OpenAPI 3.1.0 and later are not supported. Run this command first for a new spec. Supports: --validate, --base-url, --dereference, --no-progress.").option("--validate <schema>","Validate an OpenAPI or GraphQL schema (file path or URL) and exit").option("--base-url <url>","Base URL for the API").option("--dereference","Fully dereference the entire OpenAPI document before processing endpoints").option("--no-progress","Disable the progress indicator").option("--rename <newName>","Optional new name for the generated schema.").action(async(e,t)=>{try{if(typeof t.validate=="string"&&t.validate.length>0){try{await fr(t.validate),d.result(q({valid:!0,schemaSource:t.validate,message:"Schema is valid"},{kind:"schema-validation"})),process.exitCode=0}catch(o){d.result(w("SCHEMA_VALIDATION_FAILED",{summary:"OpenAPI or GraphQL schema is invalid.",message:`Schema validation failed: ${W(o)}`,context:{schema_source:t.validate},nextCommand:`openapi-skills generate ${t.validate}`})),process.exitCode=1}return}if(!e)throw new Error("An OpenAPI source is required unless --validate is used.");let r=typeof t.baseUrl=="string"?t.baseUrl.trim():"",n=r.length>0,i=await lr(e,n?r:"",{dereference:t.dereference===!0,progress:t.progress!==!1,rename:t.rename});if(!n){let o=[`You haven't included --base-url for API "${i}".`,`If you need to make requests and validations, add baseUrl directly to .openapi-skills/config.json under apis.${i}.baseUrl.`,"Example:",`{
|
|
35
55
|
"apis": {
|
|
36
56
|
"${i}": {
|
|
37
57
|
"baseUrl": "https://petstore3.swagger.io/api/v3",
|
|
@@ -39,13 +59,13 @@ Project: ${Vs}
|
|
|
39
59
|
}
|
|
40
60
|
}
|
|
41
61
|
}`].join(`
|
|
42
|
-
`);d.warn(
|
|
43
|
-
`),(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).option("--filter <filterPattern>","Filter operations by any of their searchable properties. Supports AND/OR (use spaces for AND, | for OR), e.g. --filter 'create account|register user'.").option("--tag <tag>","Filter OpenAPI operations by an exact tag, case-insensitive.").option("--method <method>","Filter operations by HTTP method (GET, POST, etc). Use this for OpenAPI operations.").option("--root-type <rootType>","Filter GraphQL root fields by root type (query, mutation, or subscription).").option("--index <range>","Slice the filtered results with inclusive Python-like range syntax, e.g. 0:10, 5:, :10, -1, or :").action(async e=>{let t=e.api;if(await
|
|
62
|
+
`);d.warn(o),d.result(q({apiName:i,openapiSource:e,warning:o},{kind:"generate-warning"}))}d.result(q({apiName:i,openapiSource:e,fileCount:3},{kind:"generate-result"})),process.exitCode=0}catch(r){if(tr(r)){d.result(w("API_PARSE_ERROR",{summary:"TypeScript is required to analyze builder GraphQL schemas.",message:`TypeScript is not available in this environment. Install it with \`${bt}\` and rerun the command.`,context:{openapi_source:e},nextCommand:bt,reason:"GraphQL builder parsing requires TypeScript to be installed in the current workspace."})),process.exitCode=1;return}d.result(w(t.validate?"SCHEMA_VALIDATION_FAILED":"API_PARSE_ERROR",{summary:t.validate?"OpenAPI or GraphQL schema is invalid.":"Failed to parse the provided schema.",message:W(r),context:{openapi_source:e},nextCommand:t.validate?`openapi-skills generate ${t.validate}`:`openapi-skills generate ${e??"<openapi-source>"}`})),process.exitCode=1}});fi.agentMeta={name:"generate",category:"Generation",usage:"openapi-skills generate [openapi-source] [--validate <schema>] [--base-url <url>] [--dereference] [--no-progress] [--rename <newName>]",description:"Parse an OpenAPI 2.0, OpenAPI 3.0.x, or GraphQL source file or URL and generate the API artifacts used by the rest of the CLI. OpenAPI 3.1.0 and later are not supported. Use --validate to check a schema and exit, --base-url to set the API base URL, --dereference when full dereferencing is appropriate, --rename to override the generated API name, and --no-progress to suppress progress output.",arguments:[{name:"openapi-source",type:"path|url",required:!1,positional:!0,description:"OpenAPI source file path or URL."},{name:"validate",type:"path|url",required:!1,flag:!0,description:"Validate an OpenAPI schema and exit."},{name:"base-url",type:"string",required:!1,flag:!0,description:"Base URL for the generated API."},{name:"dereference",type:"boolean",required:!1,flag:!0,description:"Fully dereference the OpenAPI document before processing endpoints."},{name:"no-progress",type:"boolean",required:!1,flag:!0,description:"Disable the progress indicator."},{name:"rename",type:"string",required:!1,flag:!0,description:"Optional new name for the generated schema."}],examples:["openapi-skills generate ./petstore.yaml --base-url https://api.example.com","openapi-skills generate https://example.com/openapi.yaml","openapi-skills generate ./petstore.yaml --validate ./petstore.yaml","openapi-skills generate ./petstore.yaml --dereference","openapi-skills generate ./petstore.yaml --rename petstore-v2","openapi-skills generate ./petstore.yaml --no-progress"],returns:{type:"json",description:"Prints output directory and config.json path."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!0},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!1},filesWritten:["endpoints.json","schemas/","config.json"]};mi=j.command("list").description("List summarized operation objects for the specified API as JSON. Supports --filter, --tag, --resolved/--dereferenced, --index slicing, and --count for operation totals. Also supports OpenAPI\u2011only options (--path, --method) and the GraphQL\u2011only option (--root-type). At least one filter is required unless --index : is used intentionally. GraphQL APIs reject --method, --path, and --tag, and OpenAPI APIs reject --root-type.").requiredOption("--api <apiName>","API name to use").option("--count","Return the number of operations after applying any list filters and index slicing. With no filters, returns the total operation count.").option("--resolved, --dereferenced","Show only operations that already have generated schema details saved.").option("--path <path>",["Filter operations by path structure. Repeatable; multiple values are ANDed.","Supports:"," - Path prefix: /users (matches operations whose path begins with /users)"," - Parameter detection: :param (matches operations with any {param} in the path)"," - Segment matching: 'store order' (matches operations whose path contains BOTH 'store' AND 'order' as segments, in any order)"," - OR within a clause: 'store|shop' (matches operations whose path contains EITHER 'store' OR 'shop')"," - Combined AND+OR: 'store order|shop item' (matches endpoints with both 'store' and 'order', OR both 'shop' and 'item')"," - Multiple --path flags are ANDed: --path /store --path order (matches endpoints starting with /store AND containing 'order')","","Examples:"," --path /users"," --path :param"," --path 'store order'"," --path 'store|shop'"," --path /store --path order"].join(`
|
|
63
|
+
`),(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).option("--filter <filterPattern>","Filter operations by any of their searchable properties. Supports AND/OR (use spaces for AND, | for OR), e.g. --filter 'create account|register user'.").option("--tag <tag>","Filter OpenAPI operations by an exact tag, case-insensitive.").option("--method <method>","Filter operations by HTTP method (GET, POST, etc). Use this for OpenAPI operations.").option("--root-type <rootType>","Filter GraphQL root fields by root type (query, mutation, or subscription).").option("--index <range>","Slice the filtered results with inclusive Python-like range syntax, e.g. 0:10, 5:, :10, -1, or :").action(async e=>{let t=e.api;if(await fe(t))try{let r=L(t),n=await $t(t),s=e.resolved===!0||e.dereferenced===!0,i=!!(e.path||e.filter||e.tag||e.method||e.rootType||e.index||s),o={};if((typeof e.path=="string"||Array.isArray(e.path))&&(o.path=e.path),typeof e.filter=="string"&&(o.filter=e.filter),typeof e.tag=="string"&&(o.tag=e.tag),typeof e.method=="string"&&(o.method=e.method),typeof e.rootType=="string"&&(o.rootType=e.rootType),n==="graphql"&&(typeof e.method=="string"||typeof e.path=="string"||typeof e.tag=="string")){d.result(w("SCHEMA_TYPE_MISMATCH",{summary:"--method, --path, and --tag are only valid for OpenAPI APIs.",message:"This API is GraphQL. Use --root-type with --filter instead.",context:{api_name:t,schema_type:n},nextCommand:`openapi-skills list --api ${t} --root-type query`})),process.exitCode=2;return}if(n==="openapi"&&typeof e.rootType=="string"){d.result(w("SCHEMA_TYPE_MISMATCH",{summary:"--root-type is only valid for GraphQL APIs.",message:"This API is OpenAPI. Use --method and --path or --filter instead.",context:{api_name:t,schema_type:n},nextCommand:`openapi-skills list --api ${t} --method GET`})),process.exitCode=2;return}if(!e.count&&!i){d.result(w("MISSING_FILTER_ARGUMENT",{summary:"No filter provided. Use --path, --filter, --tag, --method, --root-type, or --index.",message:"The list command requires at least one filter to avoid returning large, unbounded result sets.",context:{api_name:t},nextCommand:`openapi-skills list --api ${t} --index :`,severity:"warning"})),process.exitCode=0;return}if(M.existsSync(r)===!1){if(e.count){d.result(q({count:0,message:`No endpoints.json found for API "${t}".`},{kind:"endpoint-count"}));return}d.result(w("NO_ENDPOINTS_FOUND",{summary:`No endpoints.json found for API "${t}".`,message:"The API has not been parsed yet. Run 'openapi-skills generate' to create it.",context:{api_name:t},nextCommand:`openapi-skills generate <openapi-source> --rename ${t}`,reason:"The API artifacts have not been generated."})),d.warn(`No endpoints found for "${t}". This API name may be misspelled or not generated yet. (openapi-skills generate <openapi-source> [options])`);return}let a=await M.readJson(r),p=at(a,o);s&&(p=await br(t,p)),p=wr(p,e.index);let c=p.map(({tags:u,...m})=>m);if(e.count){d.result(q({count:p.length,apiName:t},{kind:"endpoint-count"}));return}if(p.length===0){if(d.result(q({apiName:t,items:[]},{kind:"endpoint-list"})),e.path||e.filter||e.tag||e.method||e.rootType||e.index||s){let u=Array.isArray(e.path)?e.path.join(", "):e.path,m=u?`path "${u}"`:"",f=e.filter?`filter "${e.filter}"`:"",l=e.tag?`tag "${e.tag}"`:"",g=e.method?`method "${e.method}"`:"",b=e.rootType?`rootType "${e.rootType}"`:"",T=s?"resolve":"",h=e.index?`index "${e.index}"`:"",y=[m,f,l,g,b,T,h].filter(Boolean).join(", ");d.warn(`No endpoints matched the ${y}.`)}return}d.result(q({apiName:t,items:c},{kind:"endpoint-list"}))}catch(r){d.result(w("API_PARSE_ERROR",{summary:"Error listing endpoints.",message:W(r),context:{api_name:t}})),process.exitCode=1}});mi.agentMeta={name:"list",category:"Navigation",usage:"openapi-skills list --api <apiName> [--count] [--resolved|--dereferenced] [--path <path>]... [--filter <pattern>] [--tag <tag>] [--method <method>] [--root-type <rootType>] [--index <range>]",description:["List operation summaries for a parsed API as JSON.","At least one filter is required. --index is treated as a filter input, so the command can run when only a slice is requested.","Use --count to return the number of operations after filtering and slicing, or --resolved to show only operations that already have generated schema details saved.","Filter usage differs by schema type: use --method, --path, and --tag for OpenAPI operations, use --root-type for GraphQL root fields, and use --filter and --index with either schema. Filtering is case-insensitive and supports:","- Path prefix: --path '/users' (matches operations whose path begins with the prefix)","- Parameter detection: --path :param (matches operations that contain at least one '{...}' path placeholder)","- Segment matching: --path 'store order' (matches endpoints whose path contains both segments)","- OR within a single path clause: --path 'store|shop' (matches either segment)","- Multiple path flags are ANDed: --path /store --path order","- Exact tag matching: --tag pet (matches OpenAPI operations whose tag is exactly 'pet', ignoring case)","- Simple substring filtering: --filter 'user account' (matches operations containing both 'user' and 'account' in any field, including GraphQL name/rootType fields)","- OR filtering: --filter 'create|register|signup' (matches any operation containing any of the words)","- Combined AND+OR: --filter 'create account|register user' (matches operations containing both 'create' and 'account', OR both 'register' and 'user')","- Path substring search: --filter '/users' (matches operations whose path contains the substring)","- OperationId: --filter 'getUser' (matches operationId field)","- Summary/description: --filter 'delete permanently'","- Method filtering: --method GET (OpenAPI only; can be combined with --path and/or --filter)","- GraphQL root type filtering: --root-type query (query, mutation, or subscription)","- Index slicing: --index 0:10, --index 5:, --index :10, --index -1, --index :"," Slices the filtered results using inclusive Python-like range syntax:"," N = only the Nth item (0-based, negative counts from end)"," start:end = all items from start to end, inclusive"," start: = from start to last"," :end = from first to end"," : = all items"," Negative indices count from the end (e.g., -1 is the last item, -2 is second-to-last)."," Examples:"," --index 0:2 (first three items)"," --index 5: (from 6th to last)"," --index :3 (first four items)"," --index -1 (last item)"," --index : (all items)"," --count (return the filtered/sliced endpoint count, or the total count when no filters are used)",`
|
|
44
64
|
`,"Use --path for path-aware matching. Use --filter for substring matching across path, operationId/name, rootType, summary, or description.","If no operations match, outputs [] and prints a message to stderr."].join(`
|
|
45
|
-
`),arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"API name to use."},{name:"count",type:"flag",required:!1,flag:!0,description:"Return the number of operations after filtering and slicing."},{name:"resolved",type:"flag",required:!1,flag:!0,description:"Show only operations that already have generated schema details saved. Alias: --dereferenced."},{name:"path",type:"string[]",required:!1,flag:!0,description:"Filter operations by path structure."},{name:"filter",type:"string",required:!1,flag:!0,description:"Filter operations by keywords, operationId/name, rootType, path, summary, or description."},{name:"tag",type:"string",required:!1,flag:!0,description:"Filter OpenAPI operations by an exact tag, case-insensitive."},{name:"method",type:"string",required:!1,flag:!0,description:"Filter OpenAPI operations by HTTP method."},{name:"rootType",type:"string",required:!1,flag:!0,description:"Filter GraphQL operations by root type (query, mutation, or subscription)."},{name:"index",type:"string",required:!1,flag:!0,description:"Slice the filtered results with inclusive Python-like range syntax."}],examples:["openapi-skills list --api petstore","openapi-skills list --api petstore --count","openapi-skills list --api petstore --resolved","openapi-skills list --api petstore --tag pet","openapi-skills list --api petstore --path /users","openapi-skills list --api petstore --path /store --path order","openapi-skills list --api petstore --path 'store order'","openapi-skills list --api petstore --path :param","openapi-skills list --api petstore --filter addpet","openapi-skills list --api petstore --filter 'create|register' --method POST","openapi-skills list --api countries --root-type query","openapi-skills list --api petstore --resolved --count","openapi-skills list --api petstore --filter '/users'","openapi-skills list --api petstore --index 0:10"],returns:{type:"json",description:"Returns filtered operation summaries as JSON, or a count object when --count is used. When no filters are provided, returns a structured warning object."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};
|
|
46
|
-
`),arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId of the endpoint to describe."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"force",type:"flag",required:!1,flag:!0,description:"Overwrite the cached schema file before printing the raw schema."}],examples:["openapi-skills describe getPetById --api petstore","openapi-skills describe deletePet --api petstore","openapi-skills describe getPetById --api petstore --force"],returns:{type:"json",description:"Structured JSON with a fallback warning and the raw OpenAPI schema nested under `schema`."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};ri=v.command("get-operation <operationId>").alias("get-operation-artifact").requiredOption("--api <apiName>","API name to use").option("--request","Return request artifact for the operation.").option("--response","Return response artifact for the operation.").option("--response-schema","Return response-schema artifact for the operation. Inspect this first when the response shape is unknown.").option("--get <path>","Select a nested value by dot-notation path first. Inspect --response-schema first so the path matches the actual response shape.").option("--filter <expr>","Filter the selected value using count, index, range, or <path>=<value> syntax (e.g. count, 0, 0:10, status=sold). Select path first with --get, then filter or slice the selected value.").description("Return one stored operation artifact as JSON. Run `request` first for the same operationId so the artifact exists. Exactly one of --request, --response, or --response-schema is required. Select path first with --get, then apply --filter to the selected value. Use --response-schema first when the response shape is unknown.").action(async(e,t)=>{let r=t.api;if(!await de(r))return;let n=Fr(t),s=await Y(r,e);if(n.error||!n.artifactName){d.result(b("INVALID_REQUEST_UPDATE",{summary:"Invalid operation artifact selection.",message:n.error??"Invalid operation artifact selection.",context:{api_name:r,operation_id:e},nextCommand:`openapi-skills get-operation ${e} --api ${r} --request`})),process.exitCode=1;return}let i=Ye(r,s,n.artifactName);if(!await M.pathExists(i)){if(n.artifactName==="response-schema"){d.result(b("NO_RESPONSE_SCHEMA",{summary:"No response schema artifact exists for this operation.",message:"The response schema has not been created yet.",context:{api_name:r,operation_id:e,artifact_type:"response-schema"},nextCommand:`openapi-skills request ${e} --api ${r}`,reason:"Make a request first to generate the response-schema artifact."})),process.exitCode=1;return}d.result(b("REQUEST_TEMPLATE_STALE",{summary:`Artifact '${n.artifactName}' is missing for this operation.`,message:`The '${n.artifactName}' artifact does not exist yet.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName},nextCommand:`openapi-skills request ${e} --api ${r} --force`})),process.exitCode=1;return}try{let a=await M.readJson(i),o=typeof t.get=="string"?t.get:void 0,p=typeof t.filter=="string"?t.filter:void 0,c=typeof o=="string"&&o.length>0,u=typeof p=="string"&&p.length>0,g=c?Ne(a,o):a;if(c&&!u){let{sizeBytes:l}=Ce(g);l>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The selected value is ${l} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:l},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --get ${o} --filter count`})):d.result(I({apiName:r,value:g},{kind:"artifact-value"}));return}if(u){let l=g,h=[];!Array.isArray(l)&&l!==null&&typeof l=="object"&&(h=Object.values(l).filter(y=>Array.isArray(y)),h.length===1&&(l=h[0]));let w=Qr(p),T;if(w.kind==="count"||w.kind==="index"||w.kind==="range"){if(!Array.isArray(l))if(h.length===1)l=h[0];else{d.result(b("INVALID_FILTER_SYNTAX",{summary:"--filter requires the target to be an array.",message:"The selected value is not an array and contains no single array field to unwrap.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:c?o:void 0},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --response-schema`})),process.exitCode=1;return}if(!Array.isArray(l)){d.result(b("INVALID_FILTER_SYNTAX",{summary:"--filter requires the target to be an array.",message:"The selected value is not an array.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:c?o:void 0},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName}`})),process.exitCode=1;return}if(w.kind==="count")T=l.length;else if(w.kind==="index"){let y=w.index<0?l.length+w.index:w.index;T=l[y]}else T=l.slice(w.start,w.end)}else if(w.kind==="path"){let y=w.path,x=w.value;if(c&&!Array.isArray(l)){d.result(b("INVALID_FILTER_SYNTAX",{summary:"--filter requires the --get result to be an array.",message:`The value at path '${o}' is not an array.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:o},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --response-schema`})),process.exitCode=1;return}if(!Array.isArray(l)){let{sizeBytes:P}=Ce(l);P>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The selected value is ${P} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:P},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter count`})):d.result(I({apiName:r,value:l},{kind:"artifact-value"}));return}T=gr(l,y,x)}else{d.result(b("INVALID_FILTER_SYNTAX",{summary:"Invalid --filter syntax.",message:"--filter must use count, index, range, or <path>=<value> syntax.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter 0`})),process.exitCode=1;return}let{sizeBytes:m}=Ce(T);m>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The filtered result is ${m} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:m},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter count`})):d.result(I({apiName:r,value:T},{kind:"artifact-value"}));return}let{sizeBytes:f}=Ce(a);f>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The artifact is ${f} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:f},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --get <path> --filter count`})):d.result(I({apiName:r,operationId:e,artifact:a},{kind:"artifact"}))}catch(a){d.result(b("API_PARSE_ERROR",{summary:`Failed to read artifact '${n.artifactName}'.`,message:H(a),context:{api_name:r,operation_id:e,artifact_type:n.artifactName}})),process.exitCode=1}});ri.agentMeta={name:"get-operation",category:"Navigation",usage:"openapi-skills get-operation|get-operation-artifact <operationId> --api <apiName> [--request] [--response] [--response-schema] [--get <path>] [--filter count|<index>|<range>|<path>=<value>]",description:"Return a stored operation artifact created by `openapi-skills request` as raw JSON. Run `request` first so the artifact exists. Use --get to select a nested value, then --filter to count, slice, or match values. Use --response-schema first when the response shape is unknown. Exactly one of --request, --response, or --response-schema is required. Alias: `get-operation-artifact`.",arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId whose stored artifact should be returned."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"request",type:"flag",required:!1,flag:!0,description:"Return request artifact for the operation."},{name:"response",type:"flag",required:!1,flag:!0,description:"Return response artifact for the operation."},{name:"response-schema",type:"flag",required:!1,flag:!0,description:"Return response-schema artifact for the operation. Inspect this first when the response shape is unknown."},{name:"get",type:"string",required:!1,flag:!0,description:"Select a nested value by dot-notation path first. Inspect get-operation --response-schema first so the path matches the actual response shape."},{name:"filter",type:"string",required:!1,flag:!0,description:"Filter the selected value using count, index, range, or <path>=<value> syntax. Examples: --filter count, --filter 0, --filter 0:10, --filter status=sold. Select path first with --get, then filter or slice the selected value."}],examples:["openapi-skills request getPetById --api petstore --force","openapi-skills get-operation getPetById --api petstore --request","openapi-skills get-operation-artifact getPetById --api petstore --request","openapi-skills get-operation getPetById --api petstore --response-schema","openapi-skills get-operation-artifact getPetById --api petstore --response-schema","openapi-skills get-operation getPetById --api petstore --response","openapi-skills get-operation-artifact getPetById --api petstore --response","openapi-skills get-operation getPetById --api petstore --response --get name","openapi-skills get-operation getPetById --api petstore --response --get body --filter id=555","openapi-skills get-operation getPetById --api petstore --response --filter id=5555","openapi-skills get-operation getPetById --api petstore --response --filter count","openapi-skills get-operation getPetById --api petstore --response --filter 0","openapi-skills get-operation getPetById --api petstore --response --filter 0:10"],returns:{type:"json",description:"Returns the selected artifact as raw JSON, or a nested value / filtered array when --get or --filter is supplied. When both are used, --get runs first and --filter applies to the narrowed result. Inspect --response-schema first when the response shape is unknown so --get and --filter can be applied in the right order. --filter can also return an array count, single item, or slice when the selected target is an array."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};ni=v.command("request <operationId...>").description("Make a live HTTP request for a specific operation, or prepare a multi-step request scenario without executing requests. Supports: --validate (validate only the response against the schema after the request is sent; it does not validate request bodies or guarantee a response exists), --force (regenerate request artifact; use it when you want the original schema-shaped template), --update-request (patch request artifact using flattened dot-notation keys; binary fields can be file paths or {kind:'file', path,...} descriptors), --update-request-encoded (patch request artifact using base64url-encoded JSON), --header (add headers), --header-encoded (add headers using base64url-encoded JSON).").requiredOption("--api <apiName>","API name to use").option("--validate","Validate only the response against the schema after the request is sent. Does not validate the request body or guarantee a response exists.").option("--force","Force overwrite request artifact with default values. Use this when you want the original schema-shaped template; omit it if you want to keep previous request values.").option("--update-request <json>",["Update request artifact before making the request using a single-quoted JSON string that represents a flattened object with dot-notation keys.","Nested JSON objects are supported (they will be flattened and issue a warning), but the top-level value must be a JSON object. Invalid JSON will cause the command to fail.",'To delete a field, set its value to "__delete__".','Binary request fields may be patched with a file path string or an object like {"kind":"file","path":"c:/path/file.pdf","fileName":"file.pdf","mimeType":"application/pdf"}.',`Format (POSIX shells): --update-request '{"field.path":value,...}'`,'Format (PowerShell): --update-request "{"field.path":value,...}" (escape inner quotes as needed)'," - Only flattened object dot-notation keys are recommended (e.g. 'items.0.name').","Examples:",` --update-request '{"person.id":"2"}'`,` --update-request '{"items.0.name":"Alice","items.1.value":42}'`,` --update-request '{"parameters.0":"__delete__"}'`,` --update-request '{"address.street":"Main St","address.zip":12345}'`,"Note: The CLI runs JSON.parse on the provided value; if parsing fails the command exits with an error."].join(`
|
|
65
|
+
`),arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"API name to use."},{name:"count",type:"flag",required:!1,flag:!0,description:"Return the number of operations after filtering and slicing."},{name:"resolved",type:"flag",required:!1,flag:!0,description:"Show only operations that already have generated schema details saved. Alias: --dereferenced."},{name:"path",type:"string[]",required:!1,flag:!0,description:"Filter operations by path structure."},{name:"filter",type:"string",required:!1,flag:!0,description:"Filter operations by keywords, operationId/name, rootType, path, summary, or description."},{name:"tag",type:"string",required:!1,flag:!0,description:"Filter OpenAPI operations by an exact tag, case-insensitive."},{name:"method",type:"string",required:!1,flag:!0,description:"Filter OpenAPI operations by HTTP method."},{name:"rootType",type:"string",required:!1,flag:!0,description:"Filter GraphQL operations by root type (query, mutation, or subscription)."},{name:"index",type:"string",required:!1,flag:!0,description:"Slice the filtered results with inclusive Python-like range syntax."}],examples:["openapi-skills list --api petstore","openapi-skills list --api petstore --count","openapi-skills list --api petstore --resolved","openapi-skills list --api petstore --tag pet","openapi-skills list --api petstore --path /users","openapi-skills list --api petstore --path /store --path order","openapi-skills list --api petstore --path 'store order'","openapi-skills list --api petstore --path :param","openapi-skills list --api petstore --filter addpet","openapi-skills list --api petstore --filter 'create|register' --method POST","openapi-skills list --api countries --root-type query","openapi-skills list --api petstore --resolved --count","openapi-skills list --api petstore --filter '/users'","openapi-skills list --api petstore --index 0:10"],returns:{type:"json",description:"Returns filtered operation summaries as JSON, or a count object when --count is used. When no filters are provided, returns a structured warning object."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};gi=j.command("generate-client-schema <operationId>").requiredOption("--api <apiName>","API name to use").option("--force","Overwrite the cached <operationId> artifact file before generating metadata.").description("Return structured metadata for client code generation for a specific operation. Use --force to overwrite the cached <operationId> artifact file before reading it.").action(async(e,t)=>{let r=t.api;if(await fe(r))try{let n=await X(r,e),s=await Ne(r,e,n,t.force===!0);d.result(q(s,{kind:"client-schema"}))}catch(n){let s=n instanceof Error?n.message:String(n);d.result(w("API_PARSE_ERROR",{summary:"Error generating client code metadata.",message:s,context:{api_name:r,operation_id:e}})),process.exitCode=1}});gi.agentMeta={name:"generate-client-schema",category:"Code Generation",usage:"openapi-skills generate-client-schema <operationId> --api <apiName> [--force]",description:"Print structured metadata optimized for client code generation as pretty-printed JSON. Returns `response: null` for operations with no JSON response body, in which case the generated client should return `Promise<void>`. The cached artifact is reused unless --force is provided.",arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId of the operation to inspect."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"force",type:"flag",required:!1,flag:!0,description:"Overwrite the cached artifact file before generating metadata."}],examples:["openapi-skills generate-client-schema addPet --api petstore","openapi-skills generate-client-schema addPet --api petstore --force"],returns:{type:"json",description:"Returns metadata as pretty-printed JSON."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};hi=j.command("describe <operationId>").requiredOption("--api <apiName>","API name to use").option("--force","Overwrite the cached <operationId> artifact file before printing the raw schema.").description("describe \u2192 fallback for generate-client-schema. Use generate-client-schema first. Prints the complete raw schema for a specific operation as JSON, including all parameters, request body, and all response codes. The cached <operationId> artifact file is reused unless --force is provided, which overwrites the cached schema from the bundled API document before output.").action(async(e,t)=>{let r=t.api;if(await fe(r))try{let n=await X(r,e),s=await Q(r,e,n,t.force===!0);d.result(q({operationId:e,warnings:["describe \u2192 fallback for generate-client-schema. Use openapi-skills generate-client-schema first for client code generation."],schema:s},{kind:"describe-result"}));return}catch(n){let s=n instanceof Error?n.message:String(n);d.result(w("API_PARSE_ERROR",{summary:"Error describing operation.",message:s,context:{api_name:r,operation_id:e}})),process.exitCode=1;return}});hi.agentMeta={name:"describe",category:"Navigation",usage:"openapi-skills describe <operationId> --api <apiName> [--force]",description:["Fallback for generate-client-schema. Prints the complete raw schema for a specific operation as JSON, including all parameters, request body, and response codes. The cached artifact is reused unless --force is provided.","","**Agents MUST use `generate-client-schema` for client code generation. Use `describe` only when you need full raw schema detail beyond what `generate-client-schema` provides.**"].join(`
|
|
66
|
+
`),arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId of the endpoint to describe."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"force",type:"flag",required:!1,flag:!0,description:"Overwrite the cached schema file before printing the raw schema."}],examples:["openapi-skills describe getPetById --api petstore","openapi-skills describe deletePet --api petstore","openapi-skills describe getPetById --api petstore --force"],returns:{type:"json",description:"Structured JSON with a fallback warning and the raw OpenAPI schema nested under `schema`."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};yi=j.command("get-operation <operationId>").alias("get-operation-artifact").requiredOption("--api <apiName>","API name to use").option("--request","Return request artifact for the operation.").option("--response","Return response artifact for the operation.").option("--response-schema","Return response-schema artifact for the operation. Inspect this first when the response shape is unknown.").option("--get <path>","Select a nested value by dot-notation path first. Inspect --response-schema first so the path matches the actual response shape.").option("--filter <expr>","Filter the selected value using count, index, range, or <path>=<value> syntax (e.g. count, 0, 0:10, status=sold). Select path first with --get, then filter or slice the selected value.").description("Return one stored operation artifact as JSON. Run `request` first for the same operationId so the artifact exists. Exactly one of --request, --response, or --response-schema is required. Select path first with --get, then apply --filter to the selected value. Use --response-schema first when the response shape is unknown.").action(async(e,t)=>{let r=t.api;if(!await fe(r))return;let n=Kr(t),s=await X(r,e);if(n.error||!n.artifactName){d.result(w("INVALID_REQUEST_UPDATE",{summary:"Invalid operation artifact selection.",message:n.error??"Invalid operation artifact selection.",context:{api_name:r,operation_id:e},nextCommand:`openapi-skills get-operation ${e} --api ${r} --request`})),process.exitCode=1;return}let i=tt(r,s,n.artifactName);if(!await M.pathExists(i)){if(n.artifactName==="response-schema"){d.result(w("NO_RESPONSE_SCHEMA",{summary:"No response schema artifact exists for this operation.",message:"The response schema has not been created yet.",context:{api_name:r,operation_id:e,artifact_type:"response-schema"},nextCommand:`openapi-skills request ${e} --api ${r}`,reason:"Make a request first to generate the response-schema artifact."})),process.exitCode=1;return}d.result(w("REQUEST_TEMPLATE_STALE",{summary:`Artifact '${n.artifactName}' is missing for this operation.`,message:`The '${n.artifactName}' artifact does not exist yet.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName},nextCommand:`openapi-skills request ${e} --api ${r}`})),process.exitCode=1;return}try{let o=await M.readJson(i),a=typeof t.get=="string"?t.get:void 0,p=typeof t.filter=="string"?t.filter:void 0,c=typeof a=="string"&&a.length>0,u=typeof p=="string"&&p.length>0,m=c?_e(o,a):o;if(c&&!u){let{sizeBytes:l}=$e(m);l>=51200?d.result(w("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The selected value is ${l} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:l},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --get ${a} --filter count`})):d.result(q({apiName:r,value:m},{kind:"artifact-value"}));return}if(u){let l=m,g=[];!Array.isArray(l)&&l!==null&&typeof l=="object"&&(g=Object.values(l).filter(y=>Array.isArray(y)),g.length===1&&(l=g[0]));let b=tn(p),T;if(b.kind==="count"||b.kind==="index"||b.kind==="range"){if(!Array.isArray(l))if(g.length===1)l=g[0];else{d.result(w("INVALID_FILTER_SYNTAX",{summary:"--filter requires the target to be an array.",message:"The selected value is not an array and contains no single array field to unwrap.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:c?a:void 0},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --response-schema`})),process.exitCode=1;return}if(!Array.isArray(l)){d.result(w("INVALID_FILTER_SYNTAX",{summary:"--filter requires the target to be an array.",message:"The selected value is not an array.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:c?a:void 0},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName}`})),process.exitCode=1;return}if(b.kind==="count")T=l.length;else if(b.kind==="index"){let y=b.index<0?l.length+b.index:b.index;T=l[y]}else T=l.slice(b.start,b.end)}else if(b.kind==="path"){let y=b.path,P=b.value;if(c&&!Array.isArray(l)){d.result(w("INVALID_FILTER_SYNTAX",{summary:"--filter requires the --get result to be an array.",message:`The value at path '${a}' is not an array.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:a},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --response-schema`})),process.exitCode=1;return}if(!Array.isArray(l)){let{sizeBytes:O}=$e(l);O>=51200?d.result(w("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The selected value is ${O} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:O},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter count`})):d.result(q({apiName:r,value:l},{kind:"artifact-value"}));return}T=Ar(l,y,P)}else{d.result(w("INVALID_FILTER_SYNTAX",{summary:"Invalid --filter syntax.",message:"--filter must use count, index, range, or <path>=<value> syntax.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter 0`})),process.exitCode=1;return}let{sizeBytes:h}=$e(T);h>=51200?d.result(w("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The filtered result is ${h} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:h},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter count`})):d.result(q({apiName:r,value:T},{kind:"artifact-value"}));return}let{sizeBytes:f}=$e(o);f>=51200?d.result(w("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The artifact is ${f} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:f},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --get <path> --filter count`})):d.result(q({apiName:r,operationId:e,artifact:o},{kind:"artifact"}))}catch(o){d.result(w("API_PARSE_ERROR",{summary:`Failed to read artifact '${n.artifactName}'.`,message:W(o),context:{api_name:r,operation_id:e,artifact_type:n.artifactName}})),process.exitCode=1}});yi.agentMeta={name:"get-operation",category:"Navigation",usage:"openapi-skills get-operation|get-operation-artifact <operationId> --api <apiName> [--request] [--response] [--response-schema] [--get <path>] [--filter count|<index>|<range>|<path>=<value>]",description:"Return a stored operation artifact created by `openapi-skills request` as raw JSON. Run `request` first so the artifact exists. Use --get to select a nested value, then --filter to count, slice, or match values. Use --response-schema first when the response shape is unknown. Exactly one of --request, --response, or --response-schema is required. Alias: `get-operation-artifact`.",arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId whose stored artifact should be returned."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"request",type:"flag",required:!1,flag:!0,description:"Return request artifact for the operation."},{name:"response",type:"flag",required:!1,flag:!0,description:"Return response artifact for the operation."},{name:"response-schema",type:"flag",required:!1,flag:!0,description:"Return response-schema artifact for the operation. Inspect this first when the response shape is unknown."},{name:"get",type:"string",required:!1,flag:!0,description:"Select a nested value by dot-notation path first. Inspect get-operation --response-schema first so the path matches the actual response shape."},{name:"filter",type:"string",required:!1,flag:!0,description:"Filter the selected value using count, index, range, or <path>=<value> syntax. Examples: --filter count, --filter 0, --filter 0:10, --filter status=sold. Select path first with --get, then filter or slice the selected value."}],examples:["openapi-skills request getPetById --api petstore --force","openapi-skills get-operation getPetById --api petstore --request","openapi-skills get-operation-artifact getPetById --api petstore --request","openapi-skills get-operation getPetById --api petstore --response-schema","openapi-skills get-operation-artifact getPetById --api petstore --response-schema","openapi-skills get-operation getPetById --api petstore --response","openapi-skills get-operation-artifact getPetById --api petstore --response","openapi-skills get-operation getPetById --api petstore --response --get name","openapi-skills get-operation getPetById --api petstore --response --get body --filter id=555","openapi-skills get-operation getPetById --api petstore --response --filter id=5555","openapi-skills get-operation getPetById --api petstore --response --filter count","openapi-skills get-operation getPetById --api petstore --response --filter 0","openapi-skills get-operation getPetById --api petstore --response --filter 0:10"],returns:{type:"json",description:"Returns the selected artifact as raw JSON, or a nested value / filtered array when --get or --filter is supplied. When both are used, --get runs first and --filter applies to the narrowed result. Inspect --response-schema first when the response shape is unknown so --get and --filter can be applied in the right order. --filter can also return an array count, single item, or slice when the selected target is an array."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};wi=j.command("request <operationId...>").description("Make a live HTTP request for a specific operation, or prepare a multi-step request scenario without executing requests. Supports: --validate (validate only the response against the schema after the request is sent; it does not validate request bodies or guarantee a response exists), --force (refresh operation schema and regenerate request artifact), --force-request (regenerate only request artifact from the cached operation schema), --update-request (patch request artifact using flattened dot-notation keys; binary fields can be file paths or {kind:'file', path,...} descriptors), --update-request-encoded (patch request artifact using base64url-encoded JSON), --omit-empty (remove empty-string values from schema-optional request fields before sending), --header (add headers), --header-encoded (add headers using base64url-encoded JSON).").requiredOption("--api <apiName>","API name to use").option("--validate","Validate only the response against the schema after the request is sent. Does not validate the request body or guarantee a response exists.").option("--omit-empty","For single-operation requests, remove empty-string values from schema-optional fields before sending and persist the cleaned artifact.").option("--force","Refresh the operation schema and overwrite the request artifact with defaults.").option("--force-request","Force overwrite only the request artifact with defaults from the cached operation schema; does not refresh the operation schema.").option("--update-request <json>",["Update request artifact before making the request using a single-quoted JSON string that represents a flattened object with dot-notation keys.","Nested JSON objects are supported (they will be flattened and issue a warning), but the top-level value must be a JSON object. Invalid JSON will cause the command to fail.",'To delete a field, set its value to "__delete__".','Binary request fields may be patched with a file path string or an object like {"kind":"file","path":"c:/path/file.pdf","fileName":"file.pdf","mimeType":"application/pdf"}.',`Format (POSIX shells): --update-request '{"field.path":value,...}'`,'Format (PowerShell): --update-request "{"field.path":value,...}" (escape inner quotes as needed)'," - Only flattened object dot-notation keys are recommended (e.g. 'items.0.name').","Examples:",` --update-request '{"person.id":"2"}'`,` --update-request '{"items.0.name":"Alice","items.1.value":42}'`,` --update-request '{"parameters.0":"__delete__"}'`,` --update-request '{"address.street":"Main St","address.zip":12345}'`,"Note: The CLI runs JSON.parse on the provided value; if parsing fails the command exits with an error."].join(`
|
|
47
67
|
`)).option("--update-request-encoded <base64url>",["Patch request artifact before making the request using base64url-encoded JSON.","Use this when a shell or agent may strip quotes from literal JSON.","Example:"," --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9"].join(`
|
|
48
68
|
`)).option("--header <json>",["Additional headers as a JSON string (merged with config and defaults).",`Format: --header '{"Header-Name":"value"}'`,"Example:",` --header '{"X-Api-Key":"abc"}'`].join(`
|
|
49
69
|
`)).option("--header-encoded <base64url>",["Additional headers as base64url-encoded JSON (merged with config and defaults).","Use this when a shell or agent may strip quotes from literal JSON.","Example:"," --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9"].join(`
|
|
50
|
-
`)).action(async(e,t)=>{let r=t.api;if(!await de(r))return;if(e.length>1){try{let{summaryText:o,payload:p}=await Gr(r,e,t.force===!0);d.result(I({summary:o,operationIds:e,apiName:r},{kind:"request-prepare"})),process.exitCode=0}catch(o){let p=H(o);d.result(b("API_PARSE_ERROR",{summary:"Failed to prepare multi-operation request scenario.",message:p,context:{api_name:r,operation_ids:e}})),process.exitCode=1}return}let n=e[0];if(!n){d.result(b("INVALID_REQUEST_UPDATE",{summary:"An operationId is required.",message:"Provide at least one operationId to invoke.",context:{api_name:r},nextCommand:`openapi-skills request <operationId> --api ${r}`})),process.exitCode=1;return}let s,i;if(t.updateRequest&&t.updateRequestEncoded){d.result(b("INVALID_REQUEST_UPDATE",{summary:"Specify only one of --update-request or --update-request-encoded.",message:"Choose the raw JSON form or the base64url-encoded form, not both.",context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}if(t.updateRequest){let o;try{o=JSON.parse(t.updateRequest)}catch(h){let w=`Invalid JSON for --update-request: ${h instanceof Error?h.message:String(h)}`;d.result(b("INVALID_UPDATE_REQUEST_JSON",{summary:"--update-request JSON is malformed.",message:w,context:{api_name:r,operation_id:n,update_request:t.updateRequest},nextCommand:`openapi-skills request ${n} --api ${r} --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}if(typeof o!="object"||Array.isArray(o)||!o||Object.keys(o).length===0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request must be a non-empty JSON object.",message:"Use flattened dot-notation keys and provide at least one update.",context:{api_name:r,operation_id:n,update_request:t.updateRequest},nextCommand:`openapi-skills request ${n} --api ${r} --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}let p=await Y(r,n),c=Ye(r,p,"request");if(t.force===!0){let w=(await J()).apis?.[r]?.schemaType,T=w==="graphql";if(!T&&w!=="openapi")try{let m=await M.readJson(j(r));T=Array.isArray(m)&&m.some(y=>typeof y?.rootType=="string")}catch{T=!1}T||await Q(r,n,p),await _e(r,p,!0)}else if(!await M.pathExists(c)){d.result(b("REQUEST_TEMPLATE_STALE",{summary:"request.json does not exist for this operation.",message:"--update-request requires an existing request.json artifact. Use --force to regenerate the request template.",context:{api_name:r,operation_id:n,artifact_type:"request"},nextCommand:`openapi-skills request ${n} --api ${r} --force --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}let u=await M.readJson(c),g=Le(u),f=st(o),l=Array.from(f).filter(h=>!g.has(h));if(l.length>0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request contains keys not present in request.json.",message:`The following keys are missing from request.json: ${l.join(", ")}.`,context:{api_name:r,operation_id:n,update_request:t.updateRequest,missing_keys:l},nextCommand:`openapi-skills request ${n} --api ${r} --force`})),process.exitCode=2;return}if(t.force===!0){let h=Ct(u,o);h.length>0&&(i=h)}s=o}if(t.updateRequestEncoded){let o;try{o=at(t.updateRequestEncoded,"--update-request-encoded")}catch(h){let w=`Invalid base64url for --update-request-encoded: ${h instanceof Error?h.message:String(h)}`;d.result(b("INVALID_UPDATE_REQUEST_JSON",{summary:"--update-request-encoded value is malformed.",message:w,context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}if(typeof o!="object"||Array.isArray(o)||!o||Object.keys(o).length===0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request-encoded must decode to a non-empty JSON object.",message:"The decoded payload must contain at least one flattened dot-notation key.",context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}let p=await Y(r,n),c=Ye(r,p,"request");if(t.force===!0){let w=(await J()).apis?.[r]?.schemaType,T=w==="graphql";if(!T&&w!=="openapi")try{let m=await M.readJson(j(r));T=Array.isArray(m)&&m.some(y=>typeof y?.rootType=="string")}catch{T=!1}T||await Q(r,n,p),await _e(r,p,!0)}else if(!await M.pathExists(c)){d.result(b("REQUEST_TEMPLATE_STALE",{summary:"request.json does not exist for this operation.",message:"--update-request-encoded requires an existing request.json artifact. Use --force to regenerate the request template.",context:{api_name:r,operation_id:n,artifact_type:"request"},nextCommand:`openapi-skills request ${n} --api ${r} --force --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}let u=await M.readJson(c),g=Le(u),f=st(o),l=Array.from(f).filter(h=>!g.has(h));if(l.length>0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request-encoded contains keys not present in request.json.",message:`The following keys are missing from request.json: ${l.join(", ")}.`,context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded,missing_keys:l},nextCommand:`openapi-skills request ${n} --api ${r} --force`})),process.exitCode=2;return}if(t.force===!0){let h=Ct(u,o);h.length>0&&(i=h)}s=o}if(t.header&&t.headerEncoded){d.result(b("INVALID_JSON_ARGUMENT",{summary:"Provide only one of --header or --header-encoded.",message:"--header and --header-encoded are mutually exclusive.",context:{api_name:r,operation_id:n,header:t.header,header_encoded:t.headerEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=2;return}let a;if(t.header)try{if(a=JSON.parse(t.header),typeof a!="object"||Array.isArray(a)||!a)throw new Error("--header must be a JSON object")}catch{d.result(b("INVALID_JSON_ARGUMENT",{summary:"--header JSON is malformed.",message:`Invalid --header JSON. Example: --header '{"X-Api-Key":"abc"}'`,context:{header:t.header},nextCommand:`openapi-skills request ${n} --api ${r} --header '{"Header-Name":"value"}'`})),process.exitCode=2;return}if(t.headerEncoded)try{a=at(t.headerEncoded,"--header-encoded")}catch(o){let p=`Invalid base64url for --header-encoded: ${o instanceof Error?o.message:String(o)}`;d.result(b("INVALID_JSON_ARGUMENT",{summary:"--header-encoded value is malformed.",message:p,context:{header_encoded:t.headerEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=2;return}if(t.validate)try{let o=await Er(r,n,t.force,a,s,i),p=it(r,n);if(!o.valid){d.result(b("VALIDATION_FAILED",{summary:"Response validation failed.",message:(o.errors??[]).join("; ")||"The response did not match the expected schema.",context:{api_name:r,operation_id:n,validation_warnings:o.warnings??[],validation_errors:o.errors??[],operation_artifact_count:p.fileCount},nextCommand:`openapi-skills request ${n} --api ${r} --validate`})),process.exitCode=1;return}d.result(I({apiName:r,operationId:n,valid:o.valid,warnings:o.warnings??[],errors:o.errors??[],operationArtifactCount:p.fileCount,retrieveArtifacts:"Use `get-operation-artifact [--request|--response|--response-schema] <operationId>` to view this operation's artifacts."},{kind:"validation-result"})),process.exitCode=0}catch(o){d.result(b("VALIDATION_FAILED",{summary:"Validation failed.",message:H(o),context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r} --validate`})),process.exitCode=2;return}else try{let{request:o,response:p,warnings:c}=await $t(r,n,t.force,a,s,i);await Lt(r,n);let u=it(r,n);d.result(I({apiName:r,operationId:n,warnings:c??[],fileCount:u.fileCount,retrieveArtifacts:"Use `get-operation-artifact [--request|--response|--response-schema] <operationId>` to view this operation's artifacts."},{kind:"request-result"})),process.exitCode=0}catch(o){d.result(b("REQUEST_FAILED",{summary:"Request failed.",message:H(o),context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r}`})),process.exitCode=2;return}});ni.agentMeta={name:"request",category:"Validation",usage:"openapi-skills request <operationId...> --api <apiName> [--validate] [--force] [--update-request <json>] [--update-request-encoded <base64url>] [--header <json>] [--header-encoded <base64url>]",description:["Make a live HTTP request for an operation, or prepare a multi-step request scenario without executing requests.","When multiple operationIds are supplied, the command enters prepare-only mode and refreshes request artifact templates for the scenario.","With --validate, validate only the response against the schema after the request is sent.","With --force, regenerate the request artifact from schema defaults.",'With --update-request, patch the request artifact using flattened dot-notation keys. Nested JSON objects are accepted, but the provided value must be valid JSON. With --update-request-encoded, pass base64url-encoded JSON instead. With --header, merge JSON headers into the request. With --header-encoded, pass base64url-encoded JSON headers instead. Binary fields can be set to a file path string or a file descriptor object. Set a field to "__delete__" to remove it.'].join(" "),arguments:[{name:"operationId",type:"string[]",required:!0,positional:!0,description:"One or more operationIds to invoke. Multiple values switch the command into prepare-only mode for a multi-step scenario."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"validate",type:"flag",required:!1,flag:!0,description:"Validate only the response against the schema after the request is sent. Does not validate the request body or guarantee a response exists."},{name:"force",type:"flag",required:!1,flag:!0,description:"Force overwrite request artifact with default values. Use this when you want the original schema-shaped template; omit it if you want to keep previous request values."},{name:"update-request",type:"json",required:!1,flag:!0,description:'Patch request artifact before making the request. Only flattened object dot-notation keys are allowed. Binary fields can be set to a file path string or file descriptor object. Set a field to "__delete__" to remove it. Use with --force to rebuild defaults first.'},{name:"update-request-encoded",type:"string",required:!1,flag:!0,description:"Patch request artifact before making the request using base64url-encoded JSON. Use this when quoting is unreliable."},{name:"header",type:"json",required:!1,flag:!0,description:"Additional headers as a JSON string."},{name:"header-encoded",type:"string",required:!1,flag:!0,description:"Additional headers as base64url-encoded JSON. Use this when quoting is unreliable."}],examples:["openapi-skills request getPetById --api petstore","openapi-skills request getPetById --api petstore --validate",`openapi-skills request getPetById --api petstore --force --update-request '{"user.profile.name":"Ada"}'`,"openapi-skills request getPetById --api petstore --force --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9",`openapi-skills request getPetById --api petstore --update-request '{"user.profile.name":"Ada"}'`,`openapi-skills request getPetById --api petstore --update-request '{"parameters.0.id":1}'`,"openapi-skills request getPetById --api petstore --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",`openapi-skills request getPetById --api petstore --update-request '{"parameters.0":"__delete__"}'`,"openapi-skills request operationId1 operationId2 --api petstore"],returns:{type:"json",description:"Returns raw request and response for single-operation requests, or a structured batch preparation summary when multiple operationIds are supplied."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!0},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!0},filesWritten:["request artifact","response artifact","response-schema artifact (when response has JSON body)"]};si=v.command("set-env").requiredOption("--api <apiName>","API name to use").option("--base-url <url>","Base URL for the API environment.").option("--auth <json>","Authentication headers as a JSON string.").option("--auth-encoded <base64url>","Authentication headers as base64url-encoded JSON. Use this when a shell or agent may strip quotes from literal JSON.").option("--var <key=value>","Set a runtime variable for the API environment. Repeatable.",(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).description("Set or update the runtime environment for a parsed API.").addHelpText("after",["Use this command to set baseUrl, auth headers, and runtime vars for a parsed API.","Pass auth headers with --auth as JSON or --auth-encoded as base64url-encoded JSON when quoting is unreliable.","","Examples:",` set-env --api petstore --base-url https://dev.example.com --auth '{"Authorization":"Bearer abc"}'`," set-env --api petstore --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",` set-env --api petstore --auth '{"Authorization":"Bearer abc"}'`," set-env --api petstore --var userId=123"].join(`
|
|
51
|
-
`)).action(async e=>{let t=e.api;if(!await
|
|
70
|
+
`)).action(async(e,t)=>{let r=t.api;if(!await fe(r))return;if(e.length>1){if(t.omitEmpty){d.result(w("INVALID_REQUEST_UPDATE",{summary:"--omit-empty requires a single operation request.",message:"Multiple operationIds prepare a request scenario without sending requests, so there are no request values to omit.",context:{api_name:r,operation_ids:e},nextCommand:`openapi-skills request <operationId> --api ${r} --omit-empty`})),process.exitCode=2;return}try{let{summaryText:a,payload:p}=await Zr(r,e,t.force===!0,t.forceRequest===!0);d.result(q({summary:a,operationIds:e,apiName:r},{kind:"request-prepare"})),process.exitCode=0}catch(a){let p=W(a);d.result(w("API_PARSE_ERROR",{summary:"Failed to prepare multi-operation request scenario.",message:p,context:{api_name:r,operation_ids:e}})),process.exitCode=1}return}let n=e[0];if(!n){d.result(w("INVALID_REQUEST_UPDATE",{summary:"An operationId is required.",message:"Provide at least one operationId to invoke.",context:{api_name:r},nextCommand:`openapi-skills request <operationId> --api ${r}`})),process.exitCode=1;return}let s,i;if(t.updateRequest&&t.updateRequestEncoded){d.result(w("INVALID_REQUEST_UPDATE",{summary:"Specify only one of --update-request or --update-request-encoded.",message:"Choose the raw JSON form or the base64url-encoded form, not both.",context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}if(t.updateRequest){let a;try{a=JSON.parse(t.updateRequest)}catch(g){let b=`Invalid JSON for --update-request: ${g instanceof Error?g.message:String(g)}`;d.result(w("INVALID_UPDATE_REQUEST_JSON",{summary:"--update-request JSON is malformed.",message:b,context:{api_name:r,operation_id:n,update_request:t.updateRequest},nextCommand:`openapi-skills request ${n} --api ${r} --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}if(typeof a!="object"||Array.isArray(a)||!a||Object.keys(a).length===0){d.result(w("INVALID_REQUEST_UPDATE",{summary:"--update-request must be a non-empty JSON object.",message:"Use flattened dot-notation keys and provide at least one update.",context:{api_name:r,operation_id:n,update_request:t.updateRequest},nextCommand:`openapi-skills request ${n} --api ${r} --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}let p=await X(r,n),c=tt(r,p,"request");if(t.force===!0||t.forceRequest===!0){let b=(await U()).apis?.[r]?.schemaType,T=b==="graphql";if(!T&&b!=="openapi")try{let h=await M.readJson(L(r));T=Array.isArray(h)&&h.some(y=>typeof y?.rootType=="string")}catch{T=!1}T||await Q(r,n,p),await Ce(r,p,t.force===!0,t.forceRequest===!0)}else if(!await M.pathExists(c)){d.result(w("REQUEST_TEMPLATE_STALE",{summary:"request.json does not exist for this operation.",message:"--update-request requires an existing request.json artifact. Use --force-request to regenerate it from the cached operation schema, or --force to refresh the schema too.",context:{api_name:r,operation_id:n,artifact_type:"request"},nextCommand:`openapi-skills request ${n} --api ${r} --force-request --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}let u=await M.readJson(c),m=De(u),f=pt(a),l=Array.from(f).filter(g=>!m.has(g));if(l.length>0){d.result(w("INVALID_REQUEST_UPDATE",{summary:"--update-request contains keys not present in request.json.",message:`The following keys are missing from request.json: ${l.join(", ")}.`,context:{api_name:r,operation_id:n,update_request:t.updateRequest,missing_keys:l},nextCommand:`openapi-skills request ${n} --api ${r} ${t.force?"--force":"--force-request"}`})),process.exitCode=2;return}if(t.force===!0||t.forceRequest===!0){let g=Jt(u,a);g.length>0&&(i=g)}s=a}if(t.updateRequestEncoded){let a;try{a=ut(t.updateRequestEncoded,"--update-request-encoded")}catch(g){let b=`Invalid base64url for --update-request-encoded: ${g instanceof Error?g.message:String(g)}`;d.result(w("INVALID_UPDATE_REQUEST_JSON",{summary:"--update-request-encoded value is malformed.",message:b,context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}if(typeof a!="object"||Array.isArray(a)||!a||Object.keys(a).length===0){d.result(w("INVALID_REQUEST_UPDATE",{summary:"--update-request-encoded must decode to a non-empty JSON object.",message:"The decoded payload must contain at least one flattened dot-notation key.",context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}let p=await X(r,n),c=tt(r,p,"request");if(t.force===!0||t.forceRequest===!0){let b=(await U()).apis?.[r]?.schemaType,T=b==="graphql";if(!T&&b!=="openapi")try{let h=await M.readJson(L(r));T=Array.isArray(h)&&h.some(y=>typeof y?.rootType=="string")}catch{T=!1}T||await Q(r,n,p),await Ce(r,p,t.force===!0,t.forceRequest===!0)}else if(!await M.pathExists(c)){d.result(w("REQUEST_TEMPLATE_STALE",{summary:"request.json does not exist for this operation.",message:"--update-request-encoded requires an existing request.json artifact. Use --force-request to regenerate it from the cached operation schema, or --force to refresh the schema too.",context:{api_name:r,operation_id:n,artifact_type:"request"},nextCommand:`openapi-skills request ${n} --api ${r} --force-request --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}let u=await M.readJson(c),m=De(u),f=pt(a),l=Array.from(f).filter(g=>!m.has(g));if(l.length>0){d.result(w("INVALID_REQUEST_UPDATE",{summary:"--update-request-encoded contains keys not present in request.json.",message:`The following keys are missing from request.json: ${l.join(", ")}.`,context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded,missing_keys:l},nextCommand:`openapi-skills request ${n} --api ${r} ${t.force?"--force":"--force-request"}`})),process.exitCode=2;return}if(t.force===!0||t.forceRequest===!0){let g=Jt(u,a);g.length>0&&(i=g)}s=a}if(t.header&&t.headerEncoded){d.result(w("INVALID_JSON_ARGUMENT",{summary:"Provide only one of --header or --header-encoded.",message:"--header and --header-encoded are mutually exclusive.",context:{api_name:r,operation_id:n,header:t.header,header_encoded:t.headerEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=2;return}let o;if(t.header)try{if(o=JSON.parse(t.header),typeof o!="object"||Array.isArray(o)||!o)throw new Error("--header must be a JSON object")}catch{d.result(w("INVALID_JSON_ARGUMENT",{summary:"--header JSON is malformed.",message:`Invalid --header JSON. Example: --header '{"X-Api-Key":"abc"}'`,context:{header:t.header},nextCommand:`openapi-skills request ${n} --api ${r} --header '{"Header-Name":"value"}'`})),process.exitCode=2;return}if(t.headerEncoded)try{o=ut(t.headerEncoded,"--header-encoded")}catch(a){let p=`Invalid base64url for --header-encoded: ${a instanceof Error?a.message:String(a)}`;d.result(w("INVALID_JSON_ARGUMENT",{summary:"--header-encoded value is malformed.",message:p,context:{header_encoded:t.headerEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=2;return}if(t.validate)try{let a=await Lr(r,n,t.force,o,s,i,t.omitEmpty,t.forceRequest),p=ct(r,n);if(!a.valid){d.result(w("VALIDATION_FAILED",{summary:"Response validation failed.",message:(a.errors??[]).join("; ")||"The response did not match the expected schema.",context:{api_name:r,operation_id:n,validation_warnings:a.warnings??[],validation_errors:a.errors??[],operation_artifact_count:p.fileCount},nextCommand:`openapi-skills request ${n} --api ${r} --validate`})),process.exitCode=1;return}d.result(q({apiName:r,operationId:n,valid:a.valid,warnings:a.warnings??[],errors:a.errors??[],operationArtifactCount:p.fileCount,retrieveArtifacts:"Use `get-operation-artifact [--request|--response|--response-schema] <operationId>` to view this operation's artifacts."},{kind:"validation-result"})),process.exitCode=0}catch(a){d.result(w("VALIDATION_FAILED",{summary:"Validation failed.",message:W(a),context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r} --validate`})),process.exitCode=2;return}else try{let{request:a,response:p,warnings:c}=await Gt(r,n,t.force,o,s,i,t.omitEmpty,t.forceRequest);await Ut(r,n);let u=ct(r,n);d.result(q({apiName:r,operationId:n,warnings:c??[],fileCount:u.fileCount,retrieveArtifacts:"Use `get-operation-artifact [--request|--response|--response-schema] <operationId>` to view this operation's artifacts."},{kind:"request-result"})),process.exitCode=0}catch(a){d.result(w("REQUEST_FAILED",{summary:"Request failed.",message:W(a),context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r}`})),process.exitCode=2;return}});wi.agentMeta={name:"request",category:"Validation",usage:"openapi-skills request <operationId...> --api <apiName> [--validate] [--force] [--force-request] [--update-request <json>] [--update-request-encoded <base64url>] [--omit-empty] [--header <json>] [--header-encoded <base64url>]",description:["Make a live HTTP request for an operation, or prepare a multi-step request scenario without executing requests.","When multiple operationIds are supplied, the command enters prepare-only mode and refreshes request artifact templates for the scenario.","With --validate, validate only the response against the schema after the request is sent.","With --force, refresh the operation schema and regenerate the request artifact from defaults.","With --force-request, regenerate only the request artifact from the cached operation schema without refreshing the schema.",'With --update-request, patch the request artifact using flattened dot-notation keys. Nested JSON objects are accepted, but the provided value must be valid JSON. With --update-request-encoded, pass base64url-encoded JSON instead. With --omit-empty on a single-operation request, remove empty-string values from schema-optional fields after updates and persist the cleaned artifact; this option is not available in multi-operation prepare-only mode. With --header, merge JSON headers into the request. With --header-encoded, pass base64url-encoded JSON headers instead. Binary fields can be set to a file path string or a file descriptor object. Set a field to "__delete__" to remove it.'].join(" "),arguments:[{name:"operationId",type:"string[]",required:!0,positional:!0,description:"One or more operationIds to invoke. Multiple values switch the command into prepare-only mode for a multi-step scenario."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"validate",type:"flag",required:!1,flag:!0,description:"Validate only the response against the schema after the request is sent. Does not validate the request body or guarantee a response exists."},{name:"force",type:"flag",required:!1,flag:!0,description:"Refresh the operation schema and overwrite the request artifact with defaults."},{name:"force-request",type:"flag",required:!1,flag:!0,description:"Force overwrite only the request artifact with defaults from the cached operation schema; does not refresh the operation schema. If used with --force, --force behavior applies."},{name:"omit-empty",type:"flag",required:!1,flag:!0,description:"For single-operation requests, remove empty-string values from schema-optional fields after updates and persist the cleaned request artifact."},{name:"update-request",type:"json",required:!1,flag:!0,description:'Patch request artifact before making the request. Only flattened object dot-notation keys are allowed. Binary fields can be set to a file path string or file descriptor object. Set a field to "__delete__" to remove it. Use with --force-request to rebuild defaults from the cached schema, or --force to refresh the schema too.'},{name:"update-request-encoded",type:"string",required:!1,flag:!0,description:"Patch request artifact before making the request using base64url-encoded JSON. Use this when quoting is unreliable."},{name:"header",type:"json",required:!1,flag:!0,description:"Additional headers as a JSON string."},{name:"header-encoded",type:"string",required:!1,flag:!0,description:"Additional headers as base64url-encoded JSON. Use this when quoting is unreliable."}],examples:["openapi-skills request getPetById --api petstore","openapi-skills request getPetById --api petstore --validate","openapi-skills request createPet --api petstore --omit-empty",`openapi-skills request getPetById --api petstore --force-request --update-request '{"user.profile.name":"Ada"}'`,"openapi-skills request getPetById --api petstore --force-request","openapi-skills request getPetById --api petstore --force --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9",`openapi-skills request getPetById --api petstore --update-request '{"user.profile.name":"Ada"}'`,`openapi-skills request getPetById --api petstore --update-request '{"parameters.0.id":1}'`,"openapi-skills request getPetById --api petstore --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",`openapi-skills request getPetById --api petstore --update-request '{"parameters.0":"__delete__"}'`,"openapi-skills request operationId1 operationId2 --api petstore"],returns:{type:"json",description:"Returns raw request and response for single-operation requests, or a structured batch preparation summary when multiple operationIds are supplied."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!0},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!0},filesWritten:["request artifact","response artifact","response-schema artifact (when response has JSON body)"]};bi=j.command("set-env").requiredOption("--api <apiName>","API name to use").option("--base-url <url>","Base URL for the API environment.").option("--auth <json>","Authentication headers as a JSON string.").option("--auth-encoded <base64url>","Authentication headers as base64url-encoded JSON. Use this when a shell or agent may strip quotes from literal JSON.").option("--var <key=value>","Set a runtime variable for the API environment. Repeatable.",(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).description("Set or update the runtime environment for a parsed API.").addHelpText("after",["Use this command to set baseUrl, auth headers, and runtime vars for a parsed API.","Pass auth headers with --auth as JSON or --auth-encoded as base64url-encoded JSON when quoting is unreliable.","","Examples:",` set-env --api petstore --base-url https://dev.example.com --auth '{"Authorization":"Bearer abc"}'`," set-env --api petstore --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",` set-env --api petstore --auth '{"Authorization":"Bearer abc"}'`," set-env --api petstore --var userId=123"].join(`
|
|
71
|
+
`)).action(async e=>{let t=e.api;if(!await fe(t))return;let r=typeof e.baseUrl=="string"?e.baseUrl.trim():"",n=r.length>0?r:void 0,s;if(typeof e.auth=="string"&&typeof e.authEncoded=="string"){d.result(w("INVALID_JSON_ARGUMENT",{summary:"Provide only one of --auth or --auth-encoded.",message:"--auth and --auth-encoded are mutually exclusive.",context:{api_name:t,auth:e.auth,auth_encoded:e.authEncoded},nextCommand:`openapi-skills set-env --api ${t} --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=1;return}if(typeof e.auth=="string")try{let a=JSON.parse(e.auth);if(typeof a!="object"||Array.isArray(a)||!a)throw new Error("Auth must be a JSON object");s=a}catch{d.result(w("INVALID_JSON_ARGUMENT",{summary:"--auth JSON is malformed.",message:`Invalid --auth JSON. Example: '{"Authorization":"Bearer abc"}'`,context:{api_name:t,auth:e.auth??null},nextCommand:`openapi-skills set-env --api ${t} --auth '{"Authorization":"Bearer abc"}'`})),process.exitCode=1;return}if(typeof e.authEncoded=="string")try{let a=ut(e.authEncoded,"--auth-encoded"),p={};for(let[c,u]of Object.entries(a)){if(typeof u!="string")throw new Error(`Auth header "${c}" must be a string`);p[c]=u}s=p}catch(a){d.result(w("INVALID_JSON_ARGUMENT",{summary:"--auth-encoded value is malformed.",message:`Invalid base64url for --auth-encoded: ${a instanceof Error?a.message:String(a)}`,context:{api_name:t,auth_encoded:e.authEncoded},nextCommand:`openapi-skills set-env --api ${t} --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=1;return}let i=e.var?Array.isArray(e.var)?e.var:[e.var]:[],o={};for(let a of i){let p=a.indexOf("=");if(p<=0){d.result(w("INVALID_VARIABLE_SYNTAX",{summary:"Invalid --var syntax.",message:`Invalid --var value "${a}". Use key=value.`,context:{api_name:t,variable:a},nextCommand:`openapi-skills set-env --api ${t} --var userId=123`})),process.exitCode=1;return}let c=a.slice(0,p).trim(),u=a.slice(p+1);if(!c){d.result(w("INVALID_VARIABLE_SYNTAX",{summary:"Invalid --var syntax.",message:`Invalid --var value "${a}". Use key=value.`,context:{api_name:t,variable:a},nextCommand:`openapi-skills set-env --api ${t} --var userId=123`})),process.exitCode=1;return}o[c]=u}try{let a={};n!==void 0&&(a.baseUrl=n),s!==void 0&&(a.auth=s),Object.keys(o).length>0&&(a.vars=o),await Te(t,a),d.result(q({apiName:t,baseUrl:n,hasAuth:s!==void 0,varCount:Object.keys(o).length},{kind:"set-env-result"}))}catch(a){d.result(w("CONFIG_ERROR",{summary:"Failed to update API environment.",message:W(a),context:{api_name:t,base_url:n??null,var_count:Object.keys(o).length},nextCommand:`openapi-skills set-env --api ${t}`})),process.exitCode=1}});bi.agentMeta={name:"set-env",category:"Configuration",usage:"openapi-skills set-env --api <apiName> [--base-url <url>] [--auth <json>] [--auth-encoded <base64url>] [--var key=value]",description:"Set or update the runtime environment for a parsed API. Persists baseUrl, auth headers, and named vars in config.json.",arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"base-url",type:"string",required:!1,flag:!0,description:"Base URL for the API environment."},{name:"auth",type:"json",required:!1,flag:!0,description:"Authentication headers as a JSON object."},{name:"auth-encoded",type:"string",required:!1,flag:!0,description:"Authentication headers as base64url-encoded JSON."},{name:"var",type:"string",required:!1,flag:!0,description:"Runtime variable in key=value form. Repeatable."}],examples:[`openapi-skills set-env --api petstore --base-url https://dev.example.com --auth '{"Authorization":"Bearer abc"}'`,"openapi-skills set-env --api petstore --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",`openapi-skills set-env --api petstore --auth '{"Authorization":"Bearer abc"}'`,"openapi-skills set-env --api petstore --var userId=123 --var env=staging"],returns:{type:"json",description:"Returns success or error message."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!1},filesWritten:["config.json"]};Ai=j.command("get-env").requiredOption("--api <apiName>","API name to use").option("--base-url","Include baseUrl in output").option("--auth","Include auth headers in output").option("--var <key=value>","Request one or more runtime vars. Repeatable; only the key part is used to filter output.",(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).description("Read API environment configuration from `.openapi-skills/config.json`. Returns all values unless a specific field is requested via flags.").action(async e=>{let t=e.api;if(await fe(t))try{let r=e.baseUrl===!0,n=e.auth===!0,s=e.var?Array.isArray(e.var)?e.var:[e.var]:[],i=r||n||s.length>0,o=await st(t,"baseUrl"),a=await st(t,"authHeaders"),p=await st(t,"vars"),c=Array.isArray(p)?p:[],u=Object.fromEntries(c),m={apiName:t};if((!i||r)&&(m.baseUrl=o),(!i||n)&&(m.authHeaders=a),!i)m.vars=c;else if(s.length>0){let f=s.map(l=>{let g=l.indexOf("=");return g>=0?l.slice(0,g).trim():l.trim()}).filter(Boolean);m.vars=f.map(l=>[l,u[l]]).filter(([l,g])=>g!==void 0)}d.result(q(m,{kind:"get-env-result"})),process.exitCode=0}catch(r){d.result(w("CONFIG_ERROR",{summary:"Failed to read API environment.",message:r instanceof Error?r.message:String(r),context:{api_name:t},nextCommand:`openapi-skills get-env --api ${t}`})),process.exitCode=1}});Ai.agentMeta={name:"get-env",category:"Configuration",usage:"openapi-skills get-env --api <apiName>",description:"Read environment configuration for an API. Returns all values by default, or only a specific field when a flag is provided.",arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."}],examples:["openapi-skills get-env --api petstore","openapi-skills get-env --api petstore --base-url","openapi-skills get-env --api petstore --var userId"],returns:{type:"json",description:"Prints { apiName, baseUrl, authHeaders, vars } where vars is an entries array."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!1},filesWritten:[]};Ti=j.command("get-api-names").description("List all available API names (parsed OpenAPI bundles) in the project.").action(async()=>{try{let e=await ue();d.result(q({apiNames:e},{kind:"api-list"})),(!e||e.length===0)&&d.warn("No APIs were generated yet. Run first: openapi-skills generate <openapi-source> [options]")}catch{d.result(w("CONFIG_ERROR",{summary:"Failed to list APIs.",message:"Run `openapi-skills generate [options] [openapi-source]` to parse APIs first.",context:{},nextCommand:"openapi-skills generate <openapi-source>"})),process.exitCode=1}});Ti.agentMeta={name:"get-api-names",category:"Navigation",usage:"openapi-skills get-api-names",description:"List all available parsed API names in the project. Output is always JSON: { kind: 'api-list', apiNames: [<apiName>, ...] }.",arguments:[],examples:["openapi-skills get-api-names"],returns:{type:"json",description:"Returns { kind: 'api-list', apiNames: [<apiName>, ...] } as JSON."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!1},filesWritten:[]};ki=j.command("remove-api <apiName>").description("Remove an API from config.json and delete its .openapi-skills directory after confirmation.").option("-y, --yes","Confirm removal automatically without prompting.").action(async(e,t)=>{let r=e;try{if(!(await ue()).includes(r)){d.result(w("UNKNOWN_API",{summary:`API '${r}' is not installed.`,message:`API '${r}' is not installed.`,context:{api_name:r},nextCommand:"openapi-skills get-api-names"})),process.exitCode=1;return}if(!(t?.yes===!0?!0:await Hr(r))){d.result(q({cancelled:!0,apiName:r},{kind:"remove-api-result"})),process.exitCode=0;return}let i=await cr(r);if(i.ok){d.result(q({removedApi:i.data.removedApi,message:i.message},{kind:"remove-api-result"})),process.exitCode=0;return}let o=/config/i.test(i.error.message)?"CONFIG_ERROR":i.error.type==="ApiNotFound"?"UNKNOWN_API":"REQUEST_FAILED";d.result(w(o,{summary:`Remove API error for ${r}.`,message:i.error.message,context:{api_name:r},nextCommand:o==="UNKNOWN_API"?"openapi-skills get-api-names":"None"})),process.exitCode=1;return}catch(n){let s=n instanceof Error?n.message:String(n);d.result(w(/config/i.test(s)?"CONFIG_ERROR":"REQUEST_FAILED",{summary:`Remove API error for ${r}.`,message:s,context:{api_name:r},nextCommand:/config/i.test(s)?"None":`openapi-skills remove-api ${r} --yes`})),process.exitCode=1}});ki.agentMeta={name:"remove-api",category:"Configuration",usage:"openapi-skills remove-api <apiName> [--yes|-y]",description:"Remove a parsed API after confirmation. The command deletes the API entry from config.json and removes the API directory under .openapi-skills.",arguments:[{name:"apiName",type:"string",required:!0,positional:!0,description:"The API name to remove."},{name:"yes",type:"flag",required:!1,flag:!0,description:"Confirm removal automatically without prompting."}],examples:["openapi-skills remove-api petstore --yes"],returns:{type:"json",description:"Returns a structured success or error result for the deletion operation."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!1},constraints:{destructive:!0,idempotent:!1,requiresParsedApi:!0},filesWritten:["config.json"]};j.parse(process.argv)});await Br();export{j as program};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tzurp/openapi-skills",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "CLI toolkit for exploring OpenAPI and GraphQL schemas, generating operation artifacts, validators, and tests. Includes an agent skill bundle that teaches AI tools how to operate the CLI safely and efficiently.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"openapi-skills": "dist/cli.min.js"
|
package/skill-templates/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: openapi-skills
|
|
3
|
-
description: Use this skill for any OpenAPI, GraphQL, Swagger, REST API, or openapi-skills CLI task, especially when the user wants to inspect operations (OpenAPI endpoints / `operationId`, GraphQL root fields), filter or list operations, generate client code, write operation tests, validate
|
|
3
|
+
description: Use this skill for any OpenAPI, GraphQL, Swagger, REST API, or openapi-skills CLI task, especially when the user wants to inspect operations (OpenAPI endpoints / `operationId`, GraphQL root fields), filter or list operations, generate client code, write operation tests, explicitly validate API responses against schemas, debug API requests or responses, patch request templates, set auth headers, or chain multi-step API workflows. Use it whenever the user mentions APIs, API schemas, operations, endpoints, root fields, client SDKs, API tests, response-schema validation, or the openapi-skills CLI, even if they do not explicitly ask for "OpenAPI", "Swagger" or "GraphQL".
|
|
4
4
|
allowed-tools: Bash(openapi-skills*)
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -18,16 +18,18 @@ Before doing anything else, check these first:
|
|
|
18
18
|
|
|
19
19
|
0. Use the encoded flags when quoting is fragile.
|
|
20
20
|
- Prefer `--update-request-encoded`, `--header-encoded`, and `--auth-encoded` when JSON literals might be mangled by PowerShell, cmd, an agent, or another shell layer.
|
|
21
|
-
-
|
|
21
|
+
- A minimal, non-parsing encoder (for example, a one-liner using Node.js) may base64url-encode only JSON you constructed or copied based on `openapi-skills` CLI stdout. Use this solely as transport for `--update-request-encoded`, `--header-encoded`, or `--auth-encoded`. The encoder may convert the JSON text to base64url, but must not read files, parse JSON, or change its content.
|
|
22
|
+
- This is the sole exception to Rule 1's ban on shell-based data transformation. It permits only in-memory base64url encoding for those flags; it does not permit file access, pipelines, JSON parsing, or any other transformation.
|
|
23
|
+
- If no safe encoder is available, use the corresponding raw JSON flag only when the shell can pass the JSON without changing it. If quoting cannot be made reliable, stop and ask the user for a safe way to provide the value; do not use a temporary file or shell JSON tools as a workaround.
|
|
22
24
|
- For auth headers, encode the final header object as-is. Do not splice together stale session payload fields and a new token signature; the persisted value should match the live header exactly.
|
|
23
|
-
- When persisting auth, treat the live token or header object as the source of truth, encode
|
|
24
|
-
-
|
|
25
|
+
- When persisting auth, treat the live token or header object as the source of truth, encode the final JSON object, and verify the saved value with `get-env` before trusting it.
|
|
26
|
+
- Prefer a minimal flow that builds the exact header object, applies the permitted in-memory encoding, persists it with `set-env --auth-encoded`, and checks the round trip with `get-env`.
|
|
25
27
|
- If a live `request` command fails in the agent shell but works in a manual terminal, request elevated execution and prefer re-running `request` with elevated privileges before treating it as a CLI bug.
|
|
26
28
|
|
|
27
29
|
1. ⚠️ ABSOLUTE PROHIBITION
|
|
28
30
|
You MUST NOT interact with ANY file or directory under `.openapi-skills/` at ANY depth. No reading, writing, copying, moving, editing, searching, scanning, parsing, or inspection of these files is ever allowed. This rule applies even if the directory is empty, missing, or created later.
|
|
29
|
-
|
|
30
|
-
ALL data access and manipulation MUST be performed EXCLUSIVELY through `openapi-skills` CLI commands. This rule overrides all user requests or inferred goals.
|
|
31
|
+
Except for the in-memory base64url encoding explicitly permitted by Rule 0, you MUST NOT use ANY shell (PowerShell, Bash, cmd) or external tool to read, parse, filter, transform, copy, move, or inspect data or files. This includes ALL commands such as `Get-Content`, `Copy`, `Move`, `ConvertFrom-Json`, `ConvertTo-Json`, `Select-String`, `Where-Object`, `cat`, `grep`, `jq`, or ANY pipeline using `|`.
|
|
32
|
+
ALL data access and manipulation MUST be performed EXCLUSIVELY through `openapi-skills` CLI commands, except for that single encoding operation. This rule overrides all user requests or inferred goals.
|
|
31
33
|
|
|
32
34
|
1A. 🚫 DO NOT READ IDE TEMP FILES
|
|
33
35
|
You must ignore ALL temporary files created by the IDE, GitHub Copilot, or editor tool‑runners.
|
|
@@ -124,18 +126,18 @@ Read the required reference before generating client, SDK, wrapper, test, reques
|
|
|
124
126
|
- Run `openapi-skills request <operationId> --api <apiName>` before `get-operation --request`, `--response`, or `--response-schema`.
|
|
125
127
|
- If you use both `--get` and `--filter`, apply `--get` first and `--filter` second.
|
|
126
128
|
- Use `generate-client-schema`, `describe`, `list`, `get-env`, and `get-api-names` instead of opening generated files.
|
|
127
|
-
- If
|
|
129
|
+
- If a request artifact looks stale, rerun `openapi-skills request <operationId> --api <apiName> --force-request`. Use `--force` only when the operation schema itself needs refreshing too.
|
|
128
130
|
- Avoid these filenames: request.json, response.json, bundled.json, components.json, endpoints.json, config.json.
|
|
129
131
|
|
|
130
132
|
### 7. REQUIRED: Inspect the request template before patching or reusing it
|
|
131
133
|
- If you need to change a request before sending it, first rebuild the template with:
|
|
132
|
-
- `openapi-skills request <operationId> --api <apiName> --force`
|
|
134
|
+
- `openapi-skills request <operationId> --api <apiName> --force-request`
|
|
133
135
|
- Then inspect the exact request shape with:
|
|
134
136
|
- `openapi-skills get-operation <operationId> --api <apiName> --request`
|
|
135
137
|
- Only patch fields that already exist in the template.
|
|
136
138
|
- Use `--update-request` with a single-quoted JSON object whose keys use flattened dot-notation. Invalid JSON fails fast.
|
|
137
139
|
- Example keys: `parameters.0.value`, `body.petId`
|
|
138
|
-
- You can combine `--force` and `--update-request` in the same command to rebuild the request template and patch it before sending.
|
|
140
|
+
- You can combine `--force-request` and `--update-request` in the same command to rebuild the request template from the cached operation schema and patch it before sending. Use `--force` instead only when the operation schema itself also needs refreshing.
|
|
139
141
|
- Do not guess field names or add new top-level keys unless the template already contains them.
|
|
140
142
|
- For multi-step flows, always inspect the request template before using values from a previous response.
|
|
141
143
|
- If the template shape is unclear, stop and inspect it again rather than sending an ad-hoc request.
|
|
@@ -155,7 +157,7 @@ Read the required reference before generating client, SDK, wrapper, test, reques
|
|
|
155
157
|
- Run `get-operation --response-schema` before `--get` or `--filter` when the response shape is unknown.
|
|
156
158
|
- Apply `--get` before `--filter`.
|
|
157
159
|
- Run `generate-client-schema` before `describe` for client code.
|
|
158
|
-
- Run `request --force` before `--update-request` when you need
|
|
160
|
+
- Run `request --force-request` before `--update-request` when you need a fresh request template based on the cached operation schema. Use `request --force` when the schema itself must also be refreshed.
|
|
159
161
|
|
|
160
162
|
## Command Reference
|
|
161
163
|
|
|
@@ -186,11 +188,23 @@ All commands use Bash syntax: `openapi-skills <command> [options]`.
|
|
|
186
188
|
|
|
187
189
|
### Debug a Request
|
|
188
190
|
|
|
189
|
-
1.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
1. Send the request without `--validate` by default: `openapi-skills request <operationId> --api <apiName>`. Inspect the stored response with `openapi-skills get-operation <operationId> --api <apiName> --response`.
|
|
192
|
+
2. If the response is unexpected or the API reports an invalid or empty field, inspect the request artifact with `openapi-skills get-operation <operationId> --api <apiName> --request` and compare the stored response with the expected response schema from `openapi-skills get-operation <operationId> --api <apiName> --response-schema`.
|
|
193
|
+
3. Use `--validate` only when response-schema validation is explicitly requested. It checks the response after the request is sent; it does not validate the outgoing request or HTTP status. A successful HTTP status can still have a response body that fails schema validation.
|
|
194
|
+
4. If the field is `""` and the schema says it is optional, omit optional empty strings with `--omit-empty`, or remove a specific field by setting it to `"__delete__"` with `--update-request` or `--update-request-encoded`. Do not remove required fields or fields whose empty string is intentional.
|
|
195
|
+
5. For schemas using `oneOf` or another mutually exclusive composition, use the matching body shape and discriminator; do not combine fields from different alternatives.
|
|
196
|
+
6. Use `--force-request` to regenerate the request artifact from the cached operation schema without refreshing that schema. Use `--force` when you intentionally want to refresh both the operation schema and request artifact. Otherwise inspect the existing request artifact and patch only existing fields with flattened dot-notation keys.
|
|
197
|
+
7. Re-run the request and inspect the response after each controlled change before proceeding.
|
|
198
|
+
|
|
199
|
+
### Persist API Authentication
|
|
200
|
+
|
|
201
|
+
1. Run `openapi-skills get-api-names`. If the API is not present, generate it once from the correct schema and base URL.
|
|
202
|
+
2. Confirm the intended environment and host with the user. Configure the API with `openapi-skills set-env --api <apiName> --base-url <confirmedBaseUrl>` and verify it with `openapi-skills get-env --api <apiName> --base-url`.
|
|
203
|
+
3. Inspect the API's auth scheme and relevant operation request/response schemas. Choose the operation sequence and credential location from that metadata; do not assume Bearer tokens or fixed operation names.
|
|
204
|
+
4. Run each auth step as a separate `request` command. Build each payload from its inspected request schema. Use `--force-request` to regenerate the template from the cached schema, or `--force` when you also intend to refresh the operation schema. Prefer `--update-request-encoded` when shell quoting is fragile.
|
|
205
|
+
5. Inspect each response before continuing. Retrieve a token or credential only from the response path identified by the schema. If the API rejects an optional empty string, omit it using the schema-aware guidance above rather than changing unrelated fields.
|
|
206
|
+
6. Persist the exact live auth header object with `openapi-skills set-env --api <apiName> --auth-encoded <base64urlJson>`. Follow Rule 0 for encoding; do not combine a new credential with stale auth fields. Verify the stored auth with `openapi-skills get-env --api <apiName> --auth`.
|
|
207
|
+
7. Make one authenticated smoke request using a schema-confirmed, safe read-only operation. Do not expose credentials in the final response or commit them.
|
|
194
208
|
|
|
195
209
|
### Prepare a Multi-Step Flow
|
|
196
210
|
|
|
@@ -201,4 +215,4 @@ All commands use Bash syntax: `openapi-skills <command> [options]`.
|
|
|
201
215
|
|
|
202
216
|
### Update Request Template
|
|
203
217
|
|
|
204
|
-
Use `request --force` to reset the request artifact
|
|
218
|
+
Use `request --force-request` to reset only the request artifact from the cached operation schema. Use `request --force` when both the operation schema and request artifact should be refreshed. Use `--update-request` to patch existing fields and `"__delete__"` to remove a specific field entirely. For a single-operation request, add `--omit-empty` to remove values that are exactly `""` when the schema says the field is optional; it runs after updates and persists the cleaned artifact. Required fields and `null`, `0`, `false`, empty arrays, and empty objects are preserved. If schema composition makes optionality unclear, the CLI leaves the value unchanged. Use `"__delete__"` for a targeted removal. When shell quoting is unreliable, use `--update-request-encoded` with the encoder exception described in Rule 0. Inspect the artifact after each change using the CLI. Multi-operation prepare-only requests do not support `--omit-empty`.
|