oapiex 0.2.1 → 0.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 CHANGED
@@ -1,7 +1,8 @@
1
1
  # OAPIEX
2
2
 
3
3
  [![NPM Downloads](https://img.shields.io/npm/dt/oapiex.svg)](https://www.npmjs.com/package/oapiex)
4
- [![npm version](https://img.shields.io/npm/v/oapiex.svg)](https://www.npmjs.com/package/oapiex)
4
+ [![npm version](https://img.shields.io/npm/v/oapiex.svg?label=version)](https://www.npmjs.com/package/oapiex)
5
+ [![@oapiex/sdk-kit npm version](https://img.shields.io/npm/v/@oapiex/sdk-kit.svg?label=@oapiex/sdk-kit)](https://www.npmjs.com/package/@oapiex/sdk-kit)
5
6
  [![License](https://img.shields.io/npm/l/oapiex.svg)](https://github.com/toneflix/oapiex/blob/main/LICENSE)
6
7
  [![codecov](https://codecov.io/gh/toneflix/oapiex/graph/badge.svg?token=9C8arbqlX2)](https://codecov.io/gh/toneflix/oapiex)
7
8
  [![Publish Package](https://github.com/toneflix/oapiex/actions/workflows/publish.yml/badge.svg)](https://github.com/toneflix/oapiex/actions/workflows/publish.yml)
package/bin/cli.mjs CHANGED
@@ -28,10 +28,40 @@ import{JSDOM as e}from"jsdom";import{Window as t}from"happy-dom";import n from"a
28
28
  description?: string
29
29
  required: boolean
30
30
  content: Record<string, OpenApiMediaTypeDefinition<TInput>>
31
+ }`,`export interface OpenApiOauthFlowDefinition {
32
+ authorizationUrl?: string
33
+ tokenUrl?: string
34
+ refreshUrl?: string
35
+ scopes?: Record<string, string>
36
+ }`,`export type OpenApiSecurityRequirementDefinition = Record<string, string[]>`,`export type OpenApiSecuritySchemeDefinition =
37
+ | {
38
+ type: 'http'
39
+ description?: string
40
+ scheme: string
41
+ bearerFormat?: string
42
+ }
43
+ | {
44
+ type: 'apiKey'
45
+ description?: string
46
+ name: string
47
+ in: 'query' | 'header' | 'cookie'
48
+ }
49
+ | {
50
+ type: 'oauth2'
51
+ description?: string
52
+ flows?: Record<string, OpenApiOauthFlowDefinition>
53
+ }
54
+ | {
55
+ type: 'openIdConnect'
56
+ description?: string
57
+ openIdConnectUrl: string
58
+ }`,`export interface OpenApiComponentsDefinition {
59
+ securitySchemes?: Record<string, OpenApiSecuritySchemeDefinition>
31
60
  }`,`export interface OpenApiOperationDefinition<_TResponse = unknown, TResponseExample = unknown, TInput = Record<string, never>, _TQuery = Record<string, never>, _THeader = Record<string, never>, _TParams = Record<string, never>> {
32
61
  summary?: string
33
62
  description?: string
34
63
  operationId?: string
64
+ security?: OpenApiSecurityRequirementDefinition[]
35
65
  parameters?: OpenApiParameterDefinition[]
36
66
  requestBody?: OpenApiRequestBodyDefinition<TInput>
37
67
  responses: Record<string, OpenApiResponseDefinition<_TResponse, TResponseExample>>
@@ -41,6 +71,23 @@ import{JSDOM as e}from"jsdom";import{Window as t}from"happy-dom";import n from"a
41
71
  in: 'query' | 'header' | 'path'
42
72
  required: boolean
43
73
  description?: string
74
+ }`,`export interface OpenApiSdkSecurityRequirementSchemeManifest {
75
+ name: string
76
+ scopes: string[]
77
+ }`,`export interface OpenApiSdkSecurityRequirementManifest {
78
+ schemes: OpenApiSdkSecurityRequirementSchemeManifest[]
79
+ }`,`export interface OpenApiSdkSecuritySchemeManifest {
80
+ name: string
81
+ helperName: string
82
+ description?: string
83
+ type: 'http' | 'apiKey' | 'oauth2' | 'openIdConnect'
84
+ authType: 'bearer' | 'basic' | 'apiKey' | 'oauth2'
85
+ scheme?: string
86
+ bearerFormat?: string
87
+ in?: 'header' | 'query' | 'cookie'
88
+ parameterName?: string
89
+ openIdConnectUrl?: string
90
+ scopes?: string[]
44
91
  }`,`export interface OpenApiSdkOperationManifest {
45
92
  path: string
46
93
  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
@@ -60,12 +107,15 @@ import{JSDOM as e}from"jsdom";import{Window as t}from"happy-dom";import n from"a
60
107
  pathParams: OpenApiSdkParameterManifest[]
61
108
  queryParams: OpenApiSdkParameterManifest[]
62
109
  headerParams: OpenApiSdkParameterManifest[]
110
+ security?: OpenApiSdkSecurityRequirementManifest[]
63
111
  }`,`export interface OpenApiSdkGroupManifest {
64
112
  className: string
65
113
  propertyName: string
66
114
  operations: OpenApiSdkOperationManifest[]
67
115
  }`,`export interface OpenApiSdkManifest {
68
116
  groups: OpenApiSdkGroupManifest[]
117
+ securitySchemes: OpenApiSdkSecuritySchemeManifest[]
118
+ security?: OpenApiSdkSecurityRequirementManifest[]
69
119
  }`,`export interface OpenApiRuntimeBundle<TApi = unknown> {
70
120
  document: unknown
71
121
  manifest: OpenApiSdkManifest
@@ -78,7 +128,7 @@ import{JSDOM as e}from"jsdom";import{Window as t}from"happy-dom";import n from"a
78
128
  `)}).join(`
79
129
 
80
130
  `),`export interface Paths {\n${Object.keys(t.paths).map(e=>` ${this.formatPropertyKey(e)}: ${this.derivePathTypeName(e)}`).join(`
81
- `)}\n}`,`export interface ${e} {\n openapi: '3.1.0'\n info: OpenApiInfo\n paths: Paths\n}`].join(`
131
+ `)}\n}`,`export interface ${e} {\n openapi: '3.1.0'\n info: OpenApiInfo\n components?: OpenApiComponentsDefinition\n security?: OpenApiSecurityRequirementDefinition[]\n paths: Paths\n}`].join(`
82
132
 
83
133
  `)}renderSdkApiInterface(e,t){return`export interface ${e}Api {\n${t.groups.map(e=>{let t=e.operations.map(e=>` ${e.methodName}${this.renderSdkMethodSignature(e)}`).join(`
84
134
  `);return` ${e.propertyName}: {\n${t}\n }`}).join(`
@@ -86,7 +136,7 @@ import{JSDOM as e}from"jsdom";import{Window as t}from"happy-dom";import n from"a
86
136
  `)}renderValue(e){return this.renderLiteral(e,0)}renderOpenApiDocumentValue(e){return this.renderLiteral(this.normalizeOpenApiDocument(e),0)}toCamelCase(e){let t=this.sanitizeTypeName(e);return t.charAt(0).toLowerCase()+t.slice(1)}renderInterface(e){let t=e.properties.map(e=>` ${this.formatPropertyKey(e.key)}${e.optional?`?`:``}: ${this.renderShape(e.shape)}`).join(`
87
137
  `);return`export interface ${e.name} {\n${t}\n}`}renderShape(e){switch(e.kind){case`primitive`:return e.type;case`array`:return`${this.wrapUnion(this.renderShape(e.item))}[]`;case`union`:return e.types.map(e=>this.renderShape(e)).join(` | `);case`object`:return this.inlineObjectShape(e)}}inlineObjectShape(e){return e.properties.length===0?`Record<string, never>`:`{ ${e.properties.map(e=>`${this.formatPropertyKey(e.key)}${e.optional?`?`:``}: ${this.renderShape(e.shape)}`).join(`; `)} }`}wrapUnion(e){return e.includes(` | `)?`(${e})`:e}derivePathTypeName(e){let t=e.split(`/`).map(e=>e.trim()).filter(Boolean).filter(e=>!/^v\d+$/i.test(e)).map(e=>this.isPathParam(e)?`by ${this.stripPathParam(e)}`:e);return`${this.sanitizeTypeName(t.join(` `))}Path`}deriveOperationInterfaceName(e,t){return`${this.derivePathTypeName(e)}${this.sanitizeTypeName(t)}Operation`}sanitizeTypeName(e){let t=e.replace(/[^A-Za-z0-9]+/g,` `).trim();if(!t)return`GeneratedEntity`;let n=t.split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return/^[A-Za-z_$]/.test(n)?n:`Type${n}`}formatPropertyKey(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:`'${this.escapeStringLiteral(e)}'`}renderSdkMethodSignature(e){let t=[];return e.pathParams.length>0&&t.push(`(params: ${e.paramsType}`),e.queryParams.length>0&&t.push(`${t.length===0?`(`:`, `}query: ${e.queryType}`),e.hasBody&&t.push(`${t.length===0?`(`:`, `}body${e.bodyRequired?``:`?`}: ${e.inputType}`),e.headerParams.length>0&&t.push(`${t.length===0?`(`:`, `}headers?: ${e.headerType}`),t.length===0?`(): Promise<${e.responseType}>`:`${t.join(``)}): Promise<${e.responseType}>`}renderLiteral(e,t){if(e===null)return`null`;if(typeof e==`string`)return`'${this.escapeStringLiteral(e)}'`;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(Array.isArray(e)){if(e.length===0)return`[]`;let n=this.indent(t+1),r=this.indent(t);return`[\n${e.map(e=>`${n}${this.renderLiteral(e,t+1)}`).join(`,
88
138
  `)}\n${r}]`}if(typeof e==`object`){let n=Object.entries(e);if(n.length===0)return`{}`;let r=this.indent(t+1),i=this.indent(t);return`{\n${n.map(([e,n])=>`${r}${this.formatPropertyKey(e)}: ${this.renderLiteral(n,t+1)}`).join(`,
89
- `)}\n${i}}`}return`undefined`}normalizeOpenApiDocument(e){return this.normalizeObject(e,(e,t,n)=>{if(e===`example`&&n&&typeof n==`object`&&!Array.isArray(n)){let e=n;if(e.schema&&this.isPlainObject(e.schema))return this.normalizeExample(t,e.schema);if(this.isSchemaLike(e))return this.normalizeExample(t,e)}return t})}normalizeObject(e,t){if(Array.isArray(e))return e.map(e=>this.normalizeObject(e,t)).filter(e=>e!==void 0);if(!this.isPlainObject(e))return e;let n={};for(let[r,i]of Object.entries(e)){let a=t(r,i,e),o=this.normalizeObject(a,t);o!==void 0&&(n[r]=o)}return n}normalizeExample(e,t){if(e===void 0)return;let n=typeof t.type==`string`?t.type:void 0;if(n===`string`)return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):void 0;if(n===`number`||n===`integer`)return typeof e==`number`?e:typeof e==`string`&&e.trim()!==``&&Number.isFinite(Number(e))?Number(e):void 0;if(n===`boolean`)return typeof e==`boolean`?e:e===`true`?!0:e===`false`?!1:void 0;if(n===`array`){if(!Array.isArray(e))return;let n=this.isPlainObject(t.items)?t.items:void 0;return n?e.map(e=>this.normalizeExample(e,n)).filter(e=>e!==void 0):e}if(n===`object`){if(!this.isPlainObject(e))return;let n=this.isPlainObject(t.properties)?t.properties:{},r=Array.isArray(t.required)?t.required.filter(e=>typeof e==`string`):[],i={};for(let[t,r]of Object.entries(e)){let e=n[t],a=e?this.normalizeExample(r,e):r;a!==void 0&&(i[t]=a)}for(let e of r){if(e in i)continue;let t=n[e];if(!t)return;let r=t.default===void 0?t.example===void 0?void 0:this.normalizeExample(t.example,t):this.normalizeExample(t.default,t);if(r===void 0)return;i[e]=r}return i}return e}isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}isSchemaLike(e){return`type`in e||`properties`in e||`items`in e||`required`in e||`default`in e}indent(e){return` `.repeat(e)}escapeStringLiteral(e){return e.replace(/\\/g,String.raw`\\`).replace(/'/g,String.raw`\'`).replace(/\r/g,String.raw`\r`).replace(/\n/g,String.raw`\n`).replace(/\t/g,String.raw`\t`).replace(/\f/g,String.raw`\f`).replace(/\x08/g,String.raw`\b`).replace(/\u2028/g,String.raw`\u2028`).replace(/\u2029/g,String.raw`\u2029`)}isPathParam(e){return e.startsWith(`{`)&&e.endsWith(`}`)||/^:[A-Za-z0-9_]+$/.test(e)}stripPathParam(e){return e.replace(/^\{/,``).replace(/\}$/,``).replace(/^:/,``)}},ze=class e{static contextualTailSegments=new Set([`history`,`status`,`detail`,`details`]);static nestedContextSegments=new Set([`account`,`accounts`,`transaction`,`transactions`,`wallet`,`wallets`,`virtual-account`,`virtual-accounts`,`history`]);static roleSuffixes=[`Input`,`Query`,`Header`,`Params`];sanitizeTypeName(e){let t=e.replace(/[^A-Za-z0-9]+/g,` `).trim();if(!t)return`GeneratedEntity`;let n=t.split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return/^[A-Za-z_$]/.test(n)?n:`Type${n}`}isPathParam(e){return e.startsWith(`{`)&&e.endsWith(`}`)||/^:[A-Za-z0-9_]+$/.test(e)}stripPathParam(e){return e.replace(/^\{/,``).replace(/\}$/,``).replace(/^:/,``)}singularize(e){return/ies$/i.test(e)?`${e.slice(0,-3)}y`:/(sses|shes|ches|xes|zes)$/i.test(e)?e.slice(0,-2):e.endsWith(`s`)&&!e.endsWith(`ss`)&&e.length>1?e.slice(0,-1):e}pluralize(e){return/y$/i.test(e)?`${e.slice(0,-1)}ies`:/s$/i.test(e)?e:`${e}s`}toCamelCase(e){let t=this.sanitizeTypeName(e);return t.charAt(0).toLowerCase()+t.slice(1)}deriveOperationNaming(t){let n=this.getNormalizedPathSegments(t),r=n.filter(e=>!this.isPathParam(e)).map(e=>this.singularize(e)),i=n.filter(e=>this.isPathParam(e)).map(e=>this.singularize(this.stripPathParam(e))),a=r[r.length-1]??`resource`,o=r[r.length-2]??null,s=n.slice(0,-1).some(e=>this.isPathParam(e)),c=!!(o&&(e.contextualTailSegments.has(a.toLowerCase())||s&&e.nestedContextSegments.has(a.toLowerCase())));return{baseName:this.sanitizeTypeName(c?`${o} ${a}`:a),collisionSuffix:i.length>0?`By ${i.map(e=>this.sanitizeTypeName(e)).join(` And `)}`:o&&!c?this.sanitizeTypeName(o):``}}fallbackCollisionSuffix(e,t,n){let r=this.getNormalizedPathSegments(t),i=r.filter(e=>!this.isPathParam(e)),a=i[i.length-1]??``,o=r.some(e=>this.isPathParam(e));return e===`get`&&!o&&/s$/i.test(a)?`List`:e===`post`&&!o?`Create`:(e===`put`||e===`patch`)&&o?`Update`:e===`delete`?`Delete`:`${this.sanitizeTypeName(e)}${n}`}insertCollisionSuffix(t,n){if(!n)return t;for(let r of e.roleSuffixes)if(t.endsWith(r)&&t.length>r.length)return`${t.slice(0,-r.length)}${n}${r}`;return`${t}${n}`}deriveSdkGroupNamesBySignature(e,t){let n=new Map;for(let t of Object.keys(e.paths)){let e=this.getStaticPathSignature(t);n.has(e)||n.set(e,t)}let r=Array.from(n.entries()).map(([e,n])=>({signature:e,staticSegments:e.split(`/`).filter(Boolean),candidates:this.buildSdkGroupNameCandidates(n,t)})).sort((e,t)=>e.staticSegments.length-t.staticSegments.length||e.signature.localeCompare(t.signature)),i=new Map,a=new Set;for(let e of r){let t=e.candidates.find(e=>!a.has(e))??this.createUniqueSdkGroupName(e.candidates[e.candidates.length-1]??`Resource`,a);a.add(t),i.set(e.signature,t)}return i}getStaticPathSegments(e){return this.getNormalizedPathSegments(e).filter(e=>!this.isPathParam(e)).map(e=>this.singularize(e))}getStaticPathSignature(e){return this.getStaticPathSegments(e).join(`/`)}getNormalizedPathSegments(e){return e.split(`/`).map(e=>e.trim()).filter(Boolean).filter(e=>!/^v\d+$/i.test(e))}deriveSdkMethodName(e,t,n,r){if(r===`operation-id`&&n.operationId)return this.toCamelCase(this.sanitizeTypeName(n.operationId));let i=this.getNormalizedPathSegments(t).some(e=>this.isPathParam(e));return e===`get`?this.endsWithPluralStaticSegment(t)?`list`:i?`get`:`list`:e===`post`?`create`:e===`patch`||e===`put`?`update`:e===`delete`?`delete`:this.toCamelCase(this.sanitizeTypeName(e))}ensureUniqueSdkMethodNames(e){let t=new Map;return e.map(e=>{let n=t.get(e.methodName)??0;if(t.set(e.methodName,n+1),n===0)return e;let r=this.sanitizeTypeName(this.fallbackCollisionSuffix(e.method.toLowerCase(),e.path,`Operation`));return{...e,methodName:`${e.methodName}${r}`}})}createSdkParameterManifest(e,t,n){return[...(e??[]).filter(e=>e.in===t).sort((e,t)=>e.name.localeCompare(t.name)),...this.getInferredPathParameters(n,t,(e??[]).filter(e=>e.in===t))].sort((e,t)=>e.name.localeCompare(t.name)).map(e=>({name:e.name,accessor:this.toParameterAccessor(e.name),in:t,required:e.required??!1,description:e.description}))}getInferredPathParameters(e,t,n){if(t!==`path`||!e)return[];let r=new Set(n.map(e=>e.name));return this.getNormalizedPathSegments(e).filter(e=>this.isPathParam(e)).map(e=>this.stripPathParam(e)).filter(e=>!r.has(e)).map(e=>({name:e,in:`path`,required:!0,schema:{type:`string`}}))}buildSdkGroupNameCandidates(e,t){let n=this.getNormalizedPathSegments(e),r=n.filter(e=>!this.isPathParam(e)),i=r.map(e=>this.singularize(e)),a=this.deriveOperationNaming(e).baseName,o=this.getPreferredSdkGroupName(n,r,i),s=i.map((e,t,n)=>this.sanitizeTypeName(n.slice(t).join(` `))).reverse();return t===`scoped`?Array.from(new Set([o??``,this.sanitizeTypeName(i.join(` `)),...s,a].filter(Boolean))):Array.from(new Set([o??``,a,...s].filter(Boolean)))}getPreferredSdkGroupName(e,t,n){let r=t[t.length-1],i=n[n.length-1],a=n[n.length-2],o=e.some(e=>this.isPathParam(e)),s=e.slice(0,-1).some(e=>this.isPathParam(e));return!r||!i||!a?null:t.length===2&&!o?this.sanitizeTypeName(`${i} ${a}`):s?this.singularize(r)===r?this.sanitizeTypeName(`${i} ${a}`):this.sanitizeTypeName(`${a} ${i}`):null}createUniqueSdkGroupName(e,t){let n=2,r=e;for(;t.has(r);)r=`${e}${n}`,n+=1;return r}endsWithPluralStaticSegment(e){let t=this.getNormalizedPathSegments(e).at(-1);return!t||this.isPathParam(t)?!1:this.singularize(t)!==t}toParameterAccessor(e){let t=e.replace(/[^A-Za-z0-9]+/g,` `).trim();if(!t)return`value`;let[n,...r]=t.split(/\s+/).filter(Boolean),i=[n.toLowerCase(),...r.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase())].join(``);return/^[A-Za-z_$]/.test(i)?i:`value${i}`}},Be=class{constructor(e){this.naming=e}createContext(){return{declarations:[],declarationByName:new Map,nameBySignature:new Map,usedNames:new Set}}namespaceTopLevelShape(e,t){return e.kind===`object`?{...e,signature:`${t}:${e.signature}`}:e}inferShapeFromExample(e,t){if(e===null)return{kind:`primitive`,type:`null`};if(Array.isArray(e)){if(e.length===0)return{kind:`array`,item:{kind:`primitive`,type:`unknown`}};let n=this.dedupeShapes(e.map(e=>this.inferShapeFromExample(e,this.naming.singularize(t))));return{kind:`array`,item:n.length===1?n[0]:{kind:`union`,types:n}}}if(this.isRecord(e))return this.createObjectShape(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>({key:e,optional:!1,shape:this.inferShapeFromExample(t,e)})));switch(typeof e){case`string`:return{kind:`primitive`,type:`string`};case`number`:return{kind:`primitive`,type:`number`};case`boolean`:return{kind:`primitive`,type:`boolean`};default:return{kind:`primitive`,type:`unknown`}}}registerNamedShape(e,t,n,r){if(e.kind===`object`)return this.registerObjectShape(e,t,n,r,!0);let i=this.createUniqueTypeName(t,n,r),a={kind:`shape-alias`,name:i,shape:this.prepareNestedShape(e,t,n)};return n.declarations.push(a),n.declarationByName.set(i,a),i}registerObjectShape(e,t,n,r,i=!1){let a=n.nameBySignature.get(e.signature),o=this.findCompatibleObjectDeclaration(e,t,n);if(a){if(i&&a!==t&&!n.declarationByName.has(t)){let e=this.createUniqueTypeName(t,n,r);if(e!==a){let t={kind:`interface-alias`,name:e,target:a};n.declarations.push(t),n.declarationByName.set(e,t)}}return a}if(o){if(this.isObjectShapeAssignableTo(e,o.rawShape))return n.nameBySignature.set(e.signature,o.name),o.name;let t=this.mergeObjectShapes(o.rawShape,e);return o.rawShape=t,o.properties=t.properties.map(e=>({...e,shape:this.prepareNestedShape(e.shape,e.key,n)})),n.nameBySignature.set(e.signature,o.name),n.nameBySignature.set(t.signature,o.name),o.name}let s=this.createUniqueTypeName(t,n,r),c={kind:`interface`,name:s,baseName:this.naming.sanitizeTypeName(t),rawShape:e,properties:[]};return n.nameBySignature.set(e.signature,s),n.declarations.push(c),n.declarationByName.set(s,c),c.properties=e.properties.map(e=>({...e,shape:this.prepareNestedShape(e.shape,e.key,n)})),s}resolveSdkResponseType(e,t){let n=Object.entries(e).filter(([e])=>/^2\d\d$/.test(e)).sort(([e],[t])=>e.localeCompare(t))[0]?.[1];if(!n)return t;let r=this.getPreferredMediaType(n.content);if(!r)return t;let i=this.resolveResponsePayloadSchema(r.schema,r.example).schema??r.schema;return i&&this.resolveSchemaType(i)===`array`?`${t}[]`:t}getSuccessResponseShape(e){let t=Object.entries(e).filter(([e])=>/^2\d\d$/.test(e)).sort(([e],[t])=>e.localeCompare(t))[0]?.[1];if(!t)return this.emptyObjectShape;let n=this.getPreferredMediaType(t.content);if(!n)return this.emptyObjectShape;let r=this.resolveResponsePayloadSchema(n.schema,n.example);return r.schema?this.resolveSchemaType(r.schema)===`array`?this.schemaToShape(r.schema.items,`Item`,this.extractExampleArrayItem(r.example)):this.schemaToShape(r.schema,`Response`,r.example):this.schemaToShape(n.schema,`Response`,n.example)}getRequestInputShape(e){if(!e)return this.emptyObjectShape;let t=this.getPreferredMediaType(e.content);return t?this.schemaToShape(t.schema,`Input`,t.example):this.emptyObjectShape}getResponseExampleShape(e){let t=Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).flatMap(([,e])=>{let t=this.getPreferredMediaType(e.content);if(!t)return[];let n=t.example??t.schema?.example;return t.schema?[this.schemaToShape(t.schema,`ResponseExample`,n)]:n===void 0?[]:[this.inferShapeFromExample(n,`ResponseExample`)]}),n=this.dedupeShapes(t);return n.length===0?{kind:`primitive`,type:`unknown`}:n.length===1?n[0]:{kind:`union`,types:n}}createParameterGroupShape(e,t,n){let r=(e??[]).filter(e=>e.in===t).sort((e,t)=>e.name.localeCompare(t.name)),i=[...r,...this.naming.getInferredPathParameters(n,t,r)].sort((e,t)=>e.name.localeCompare(t.name));return i.length===0?this.emptyObjectShape:this.createObjectShape(i.map(e=>({key:e.name,optional:!(e.required??!1),shape:this.schemaToShape(e.schema,e.name,e.example)})))}get emptyObjectShape(){return this.createObjectShape([])}findCompatibleObjectDeclaration(e,t,n){let r=this.naming.sanitizeTypeName(t);return n.declarations.find(t=>t.kind!==`interface`||t.baseName!==r?!1:this.isObjectShapeAssignableTo(e,t.rawShape)||this.isObjectShapeAssignableTo(t.rawShape,e)||this.canMergeObjectShapes(t.rawShape,e))}canMergeObjectShapes(e,t){let n=new Set([...e.properties.map(e=>e.key),...t.properties.map(e=>e.key)]);for(let r of n){let n=e.properties.find(e=>e.key===r),i=t.properties.find(e=>e.key===r);if(!n||!i){if(!(n??i)?.optional)return!1;continue}if(!this.canMergeShapes(n.shape,i.shape))return!1}return!0}isObjectShapeAssignableTo(e,t){let n=new Map(t.properties.map(e=>[e.key,e]));for(let t of e.properties){let e=n.get(t.key);if(!e||t.optional&&!e.optional||!this.isShapeAssignableTo(t.shape,e.shape))return!1}return t.properties.every(t=>e.properties.some(e=>e.key===t.key)||t.optional)}isShapeAssignableTo(e,t){if(t.kind===`union`)return t.types.some(t=>this.isShapeAssignableTo(e,t));switch(e.kind){case`primitive`:return t.kind===`primitive`?e.type===t.type:!1;case`array`:return t.kind===`array`?this.isShapeAssignableTo(e.item,t.item):!1;case`union`:return e.types.every(e=>this.isShapeAssignableTo(e,t));case`object`:return t.kind===`object`?this.isObjectShapeAssignableTo(e,t):!1}}canMergeShapes(e,t){return e.kind===`union`?e.types.every(e=>this.canMergeShapes(e,t)):t.kind===`union`?t.types.every(t=>this.canMergeShapes(e,t)):e.kind===`primitive`&&t.kind===`primitive`?!0:e.kind===`array`&&t.kind===`array`?this.canMergeShapes(e.item,t.item):e.kind===`object`&&t.kind===`object`?this.canMergeObjectShapes(e,t):!1}mergeObjectShapes(e,t){let n=new Set([...e.properties.map(e=>e.key),...t.properties.map(e=>e.key)]);return this.createObjectShape(Array.from(n).map(n=>{let r=e.properties.find(e=>e.key===n),i=t.properties.find(e=>e.key===n);return r&&i?{key:n,optional:r.optional||i.optional,shape:this.mergeShapes(r.shape,i.shape)}:{key:n,optional:!0,shape:(r??i).shape}}))}mergeShapes(e,t){if(e.kind===`union`||t.kind===`union`||e.kind!==t.kind)return this.createUnionShape(e,t);switch(e.kind){case`primitive`:return t.kind===`primitive`&&e.type===t.type?e:this.createUnionShape(e,t);case`array`:return t.kind===`array`?{kind:`array`,item:this.mergeShapes(e.item,t.item)}:e;case`object`:return t.kind===`object`?this.mergeObjectShapes(e,t):e}}createUnionShape(...e){let t=e.flatMap(e=>e.kind===`union`?e.types:[e]),n=this.dedupeShapes(t);return n.length===1?n[0]:{kind:`union`,types:n}}prepareNestedShape(e,t,n){if(e.kind===`object`)return{kind:`primitive`,type:this.registerObjectShape(e,this.naming.sanitizeTypeName(this.naming.singularize(t)),n,this.naming.sanitizeTypeName(t))};if(e.kind===`array`)return{kind:`array`,item:this.prepareNestedShape(e.item,this.naming.singularize(t),n)};if(e.kind===`union`){let r=this.dedupeShapes(e.types.map((e,r)=>this.prepareNestedShape(e,this.getUnionMemberKeyHint(t,r,e),n)));return r.length===1?r[0]:{kind:`union`,types:r}}return e}getUnionMemberKeyHint(e,t,n){if(n.kind!==`object`&&n.kind!==`array`)return e;let r=this.naming.sanitizeTypeName(e);return r.endsWith(`ResponseExample`)?`${r}Variant${t+1}`:e}schemaToShape(e,t,n){if(!e)return this.inferShapeFromExample(n,t);let r=this.resolveSchemaType(e);if(r===`array`)return{kind:`array`,item:this.schemaToShape(e.items,this.naming.singularize(t),this.extractExampleArrayItem(e.example)??this.extractExampleArrayItem(n))};if(r===`object`){let r=this.isRecord(e.example)?e.example:this.isRecord(n)?n:void 0,i=Object.entries(e.properties??{}).sort(([e],[t])=>e.localeCompare(t)).map(([t,n])=>({key:t,optional:!(e.required??[]).includes(t),shape:this.schemaToShape(n,t,r?.[t])}));return i.length>0?this.createObjectShape(i):this.inferShapeFromExample(e.example??n,t)}return r===`integer`||r===`number`?{kind:`primitive`,type:`number`}:r===`string`?{kind:`primitive`,type:`string`}:r===`boolean`?{kind:`primitive`,type:`boolean`}:e.example===null||n===null?{kind:`primitive`,type:`null`}:e.example!==void 0||n!==void 0?this.inferShapeFromExample(e.example??n,t):{kind:`primitive`,type:`unknown`}}dedupeShapes(e){let t=new Set;return e.filter(e=>{let n=this.getShapeSignature(e);return t.has(n)?!1:(t.add(n),!0)})}createObjectShape(e){let t=e.map(e=>({...e})).sort((e,t)=>e.key.localeCompare(t.key));return{kind:`object`,signature:JSON.stringify(t.map(e=>({key:e.key,optional:e.optional,shape:this.getShapeSignature(e.shape)}))),properties:t}}getShapeSignature(e){switch(e.kind){case`primitive`:return`primitive:${e.type}`;case`array`:return`array:${this.getShapeSignature(e.item)}`;case`union`:return`union:${e.types.map(e=>this.getShapeSignature(e)).join(`|`)}`;case`object`:return`object:${e.signature}`}}getPreferredMediaType(e){if(e)return e[`application/json`]??e[`application/*+json`]??Object.values(e)[0]}resolveResponsePayloadSchema(e,t){for(let n of[[`data`],[`meta`,`data`]]){let r=this.getSchemaCandidateAtPath(e,t,n);if(r)return r}return{}}getSchemaCandidateAtPath(e,t,n){let r=this.getSchemaAtPath(e,n),i=this.getExampleAtPath(t,n);if(!(!r&&i===void 0))return r?{schema:r.example===void 0&&i!==void 0?{...r,example:i}:r,example:i??r.example}:{schema:{...this.inferSchemaTypeFromExample(i),example:i},example:i}}getSchemaAtPath(e,t){let n=e;for(let e of t){if(!n?.properties?.[e])return;n=n.properties[e]}return n}getExampleAtPath(e,t){let n=e;for(let e of t){if(!this.isRecord(n)||!(e in n))return;n=n[e]}return n}inferSchemaTypeFromExample(e){return Array.isArray(e)?{type:`array`,items:e.map(e=>this.inferSchemaTypeFromExample(e)).find(e=>this.hasSchemaDetails(e))??{}}:this.isRecord(e)?{type:`object`,properties:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,this.inferSchemaTypeFromExample(t)]))}:typeof e==`string`?{type:`string`}:typeof e==`number`?{type:`number`}:typeof e==`boolean`?{type:`boolean`}:{}}hasSchemaDetails(e){return!!(e?.type||e?.properties||e?.items||e?.example!==void 0)}resolveSchemaType(e){return e.type??(e.properties?`object`:void 0)}extractExampleArrayItem(e){return Array.isArray(e)?e[0]:void 0}createUniqueTypeName(e,t,n){let r=this.naming.sanitizeTypeName(e)||`GeneratedEntity`,i=this.naming.sanitizeTypeName(n),a=r,o=2;if(!t.usedNames.has(a)||(a=this.naming.insertCollisionSuffix(r,i),!t.usedNames.has(a)))return t.usedNames.add(a),a;for(;t.usedNames.has(a);)a=`${r}${o}`,o+=1;return t.usedNames.add(a),a}isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}},X=class{naming=new ze;shapes=new Be(this.naming);createContext(){return this.shapes.createContext()}collectSemanticModels(e){let t=[];for(let[n,r]of Object.entries(e.paths)){let e=this.naming.deriveOperationNaming(n),i=e.baseName,a=Object.entries(r).sort(([,e],[,t])=>this.getOperationPriority(t)-this.getOperationPriority(e));for(let[r,o]of a){let a=e.collisionSuffix||this.naming.fallbackCollisionSuffix(r,n,i);t.push({path:n,method:r,name:i,role:`response`,shape:this.shapes.getSuccessResponseShape(o.responses),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}ResponseExample`,role:`responseExample`,shape:this.shapes.getResponseExampleShape(o.responses),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Input`,role:`input`,shape:this.shapes.getRequestInputShape(o.requestBody),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Query`,role:`query`,shape:this.shapes.createParameterGroupShape(o.parameters,`query`,n),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Header`,role:`header`,shape:this.shapes.createParameterGroupShape(o.parameters,`header`,n),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Params`,role:`params`,shape:this.shapes.createParameterGroupShape(o.parameters,`path`,n),collisionSuffix:a})}}return t}buildSdkManifest(e,t,n={}){let r=this.naming.deriveSdkGroupNamesBySignature(e,n.namespaceStrategy??`smart`),i=new Map;for(let[a,o]of Object.entries(e.paths)){let e=this.naming.getStaticPathSegments(a).join(`/`),s=r.get(e)??`Resource`,c=this.naming.toCamelCase(this.naming.pluralize(s)),l=i.get(c)??{className:s,propertyName:c,operations:[]};for(let[e,r]of Object.entries(o)){let i=t.get(`${a}::${e}`)??{response:`Record<string, never>`,responseExample:`unknown`,input:`Record<string, never>`,query:`Record<string, never>`,header:`Record<string, never>`,params:`Record<string, never>`};l.operations.push({path:a,method:e.toUpperCase(),methodName:this.naming.deriveSdkMethodName(e,a,r,n.methodStrategy??`smart`),summary:r.summary,description:r.description,operationId:r.operationId,requestBodyDescription:r.requestBody?.description,responseDescription:this.resolveSuccessResponseDescription(r.responses),responseType:this.shapes.resolveSdkResponseType(r.responses,i.response),inputType:i.input,queryType:i.query,headerType:i.header,paramsType:i.params,hasBody:!!r.requestBody,bodyRequired:r.requestBody?.required??!1,pathParams:this.naming.createSdkParameterManifest(r.parameters,`path`,a),queryParams:this.naming.createSdkParameterManifest(r.parameters,`query`,a),headerParams:this.naming.createSdkParameterManifest(r.parameters,`header`,a)})}i.set(c,l)}return{groups:Array.from(i.values()).map(e=>({...e,operations:this.naming.ensureUniqueSdkMethodNames(e.operations)})).sort((e,t)=>e.propertyName.localeCompare(t.propertyName))}}inferShapeFromExample(e,t){return this.shapes.inferShapeFromExample(e,t)}sanitizeTypeName(e){return this.naming.sanitizeTypeName(e)}registerNamedShape(e,t,n,r){return this.shapes.registerNamedShape(e,t,n,r)}namespaceTopLevelShape(e,t){return this.shapes.namespaceTopLevelShape(e,t)}registerObjectShape(e,t,n,r,i=!1){return this.shapes.registerObjectShape(e,t,n,r,i)}getOperationPriority(e){return Number(!!e.requestBody)*10}resolveSuccessResponseDescription(e){for(let t of[`200`,`201`,`202`,`204`]){let n=e[t]?.description?.trim();if(n)return n}for(let t of Object.values(e)){let e=t.description?.trim();if(e)return e}}},Z=class e{typeBuilder=new X;moduleRenderer=new Re;static generateModule=(t,n=`GeneratedOutput`,r={})=>new e().generate(t,n,r);generate(e,t=`GeneratedOutput`,n={}){return this.isOpenApiDocumentLike(e)?this.generateModule(e,t,n):this.generateGenericModule(e,t)}generateModule(e,t,n={}){let r=this.typeBuilder.createContext(),i=new Map;for(let t of this.typeBuilder.collectSemanticModels(e)){let e=`${t.path}::${t.method}`,n=this.typeBuilder.registerNamedShape(this.typeBuilder.namespaceTopLevelShape(t.shape,t.role),t.name,r,t.collisionSuffix),a=i.get(e)??{response:`Record<string, never>`,responseExample:`unknown`,input:`Record<string, never>`,query:`Record<string, never>`,header:`Record<string, never>`,params:`Record<string, never>`};a[t.role]=n,i.set(e,a)}let a=r.declarations.map(e=>this.moduleRenderer.renderDeclaration(e)).join(`
139
+ `)}\n${i}}`}return`undefined`}normalizeOpenApiDocument(e){return this.normalizeObject(e,(e,t,n)=>{if(e===`example`&&n&&typeof n==`object`&&!Array.isArray(n)){let e=n;if(e.schema&&this.isPlainObject(e.schema))return this.normalizeExample(t,e.schema);if(this.isSchemaLike(e))return this.normalizeExample(t,e)}return t})}normalizeObject(e,t){if(Array.isArray(e))return e.map(e=>this.normalizeObject(e,t)).filter(e=>e!==void 0);if(!this.isPlainObject(e))return e;let n={};for(let[r,i]of Object.entries(e)){let a=t(r,i,e),o=this.normalizeObject(a,t);o!==void 0&&(n[r]=o)}return n}normalizeExample(e,t){if(e===void 0)return;let n=typeof t.type==`string`?t.type:void 0;if(n===`string`)return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):void 0;if(n===`number`||n===`integer`)return typeof e==`number`?e:typeof e==`string`&&e.trim()!==``&&Number.isFinite(Number(e))?Number(e):void 0;if(n===`boolean`)return typeof e==`boolean`?e:e===`true`?!0:e===`false`?!1:void 0;if(n===`array`){if(!Array.isArray(e))return;let n=this.isPlainObject(t.items)?t.items:void 0;return n?e.map(e=>this.normalizeExample(e,n)).filter(e=>e!==void 0):e}if(n===`object`){if(!this.isPlainObject(e))return;let n=this.isPlainObject(t.properties)?t.properties:{},r=Array.isArray(t.required)?t.required.filter(e=>typeof e==`string`):[],i={};for(let[t,r]of Object.entries(e)){let e=n[t],a=e?this.normalizeExample(r,e):r;a!==void 0&&(i[t]=a)}for(let e of r){if(e in i)continue;let t=n[e];if(!t)return;let r=t.default===void 0?t.example===void 0?void 0:this.normalizeExample(t.example,t):this.normalizeExample(t.default,t);if(r===void 0)return;i[e]=r}return i}return e}isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}isSchemaLike(e){return`type`in e||`properties`in e||`items`in e||`required`in e||`default`in e}indent(e){return` `.repeat(e)}escapeStringLiteral(e){return e.replace(/\\/g,String.raw`\\`).replace(/'/g,String.raw`\'`).replace(/\r/g,String.raw`\r`).replace(/\n/g,String.raw`\n`).replace(/\t/g,String.raw`\t`).replace(/\f/g,String.raw`\f`).replace(/\x08/g,String.raw`\b`).replace(/\u2028/g,String.raw`\u2028`).replace(/\u2029/g,String.raw`\u2029`)}isPathParam(e){return e.startsWith(`{`)&&e.endsWith(`}`)||/^:[A-Za-z0-9_]+$/.test(e)}stripPathParam(e){return e.replace(/^\{/,``).replace(/\}$/,``).replace(/^:/,``)}},ze=class e{static contextualTailSegments=new Set([`history`,`status`,`detail`,`details`]);static nestedContextSegments=new Set([`account`,`accounts`,`transaction`,`transactions`,`wallet`,`wallets`,`virtual-account`,`virtual-accounts`,`history`]);static roleSuffixes=[`Input`,`Query`,`Header`,`Params`];sanitizeTypeName(e){let t=e.replace(/[^A-Za-z0-9]+/g,` `).trim();if(!t)return`GeneratedEntity`;let n=t.split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return/^[A-Za-z_$]/.test(n)?n:`Type${n}`}isPathParam(e){return e.startsWith(`{`)&&e.endsWith(`}`)||/^:[A-Za-z0-9_]+$/.test(e)}stripPathParam(e){return e.replace(/^\{/,``).replace(/\}$/,``).replace(/^:/,``)}singularize(e){return/ies$/i.test(e)?`${e.slice(0,-3)}y`:/(sses|shes|ches|xes|zes)$/i.test(e)?e.slice(0,-2):e.endsWith(`s`)&&!e.endsWith(`ss`)&&e.length>1?e.slice(0,-1):e}pluralize(e){return/y$/i.test(e)?`${e.slice(0,-1)}ies`:/s$/i.test(e)?e:`${e}s`}toCamelCase(e){let t=this.sanitizeTypeName(e);return t.charAt(0).toLowerCase()+t.slice(1)}deriveOperationNaming(t){let n=this.getNormalizedPathSegments(t),r=n.filter(e=>!this.isPathParam(e)).map(e=>this.singularize(e)),i=n.filter(e=>this.isPathParam(e)).map(e=>this.singularize(this.stripPathParam(e))),a=r[r.length-1]??`resource`,o=r[r.length-2]??null,s=n.slice(0,-1).some(e=>this.isPathParam(e)),c=!!(o&&(e.contextualTailSegments.has(a.toLowerCase())||s&&e.nestedContextSegments.has(a.toLowerCase())));return{baseName:this.sanitizeTypeName(c?`${o} ${a}`:a),collisionSuffix:i.length>0?`By ${i.map(e=>this.sanitizeTypeName(e)).join(` And `)}`:o&&!c?this.sanitizeTypeName(o):``}}fallbackCollisionSuffix(e,t,n){let r=this.getNormalizedPathSegments(t),i=r.filter(e=>!this.isPathParam(e)),a=i[i.length-1]??``,o=r.some(e=>this.isPathParam(e));return e===`get`&&!o&&/s$/i.test(a)?`List`:e===`post`&&!o?`Create`:(e===`put`||e===`patch`)&&o?`Update`:e===`delete`?`Delete`:`${this.sanitizeTypeName(e)}${n}`}insertCollisionSuffix(t,n){if(!n)return t;for(let r of e.roleSuffixes)if(t.endsWith(r)&&t.length>r.length)return`${t.slice(0,-r.length)}${n}${r}`;return`${t}${n}`}deriveSdkGroupNamesBySignature(e,t){let n=new Map;for(let t of Object.keys(e.paths)){let e=this.getStaticPathSignature(t);n.has(e)||n.set(e,t)}let r=Array.from(n.entries()).map(([e,n])=>({signature:e,staticSegments:e.split(`/`).filter(Boolean),candidates:this.buildSdkGroupNameCandidates(n,t)})).sort((e,t)=>e.staticSegments.length-t.staticSegments.length||e.signature.localeCompare(t.signature)),i=new Map,a=new Set;for(let e of r){let t=e.candidates.find(e=>!a.has(e))??this.createUniqueSdkGroupName(e.candidates[e.candidates.length-1]??`Resource`,a);a.add(t),i.set(e.signature,t)}return i}getStaticPathSegments(e){return this.getNormalizedPathSegments(e).filter(e=>!this.isPathParam(e)).map(e=>this.singularize(e))}getStaticPathSignature(e){return this.getStaticPathSegments(e).join(`/`)}getNormalizedPathSegments(e){return e.split(`/`).map(e=>e.trim()).filter(Boolean).filter(e=>!/^v\d+$/i.test(e))}deriveSdkMethodName(e,t,n,r){if(r===`operation-id`&&n.operationId)return this.toCamelCase(this.sanitizeTypeName(n.operationId));let i=this.getNormalizedPathSegments(t).some(e=>this.isPathParam(e));return e===`get`?this.endsWithPluralStaticSegment(t)?`list`:i?`get`:`list`:e===`post`?`create`:e===`patch`||e===`put`?`update`:e===`delete`?`delete`:this.toCamelCase(this.sanitizeTypeName(e))}ensureUniqueSdkMethodNames(e){let t=new Map;return e.map(e=>{let n=t.get(e.methodName)??0;if(t.set(e.methodName,n+1),n===0)return e;let r=this.sanitizeTypeName(this.fallbackCollisionSuffix(e.method.toLowerCase(),e.path,`Operation`));return{...e,methodName:`${e.methodName}${r}`}})}createSdkParameterManifest(e,t,n){return[...(e??[]).filter(e=>e.in===t).sort((e,t)=>e.name.localeCompare(t.name)),...this.getInferredPathParameters(n,t,(e??[]).filter(e=>e.in===t))].sort((e,t)=>e.name.localeCompare(t.name)).map(e=>({name:e.name,accessor:this.toParameterAccessor(e.name),in:t,required:e.required??!1,description:e.description}))}getInferredPathParameters(e,t,n){if(t!==`path`||!e)return[];let r=new Set(n.map(e=>e.name));return this.getNormalizedPathSegments(e).filter(e=>this.isPathParam(e)).map(e=>this.stripPathParam(e)).filter(e=>!r.has(e)).map(e=>({name:e,in:`path`,required:!0,schema:{type:`string`}}))}buildSdkGroupNameCandidates(e,t){let n=this.getNormalizedPathSegments(e),r=n.filter(e=>!this.isPathParam(e)),i=r.map(e=>this.singularize(e)),a=this.deriveOperationNaming(e).baseName,o=this.getPreferredSdkGroupName(n,r,i),s=i.map((e,t,n)=>this.sanitizeTypeName(n.slice(t).join(` `))).reverse();return t===`scoped`?Array.from(new Set([o??``,this.sanitizeTypeName(i.join(` `)),...s,a].filter(Boolean))):Array.from(new Set([o??``,a,...s].filter(Boolean)))}getPreferredSdkGroupName(e,t,n){let r=t[t.length-1],i=n[n.length-1],a=n[n.length-2],o=e.some(e=>this.isPathParam(e)),s=e.slice(0,-1).some(e=>this.isPathParam(e));return!r||!i||!a?null:t.length===2&&!o?this.sanitizeTypeName(`${i} ${a}`):s?this.singularize(r)===r?this.sanitizeTypeName(`${i} ${a}`):this.sanitizeTypeName(`${a} ${i}`):null}createUniqueSdkGroupName(e,t){let n=2,r=e;for(;t.has(r);)r=`${e}${n}`,n+=1;return r}endsWithPluralStaticSegment(e){let t=this.getNormalizedPathSegments(e).at(-1);return!t||this.isPathParam(t)?!1:this.singularize(t)!==t}toParameterAccessor(e){let t=e.replace(/[^A-Za-z0-9]+/g,` `).trim();if(!t)return`value`;let[n,...r]=t.split(/\s+/).filter(Boolean),i=[n.toLowerCase(),...r.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase())].join(``);return/^[A-Za-z_$]/.test(i)?i:`value${i}`}},Be=class{constructor(e){this.naming=e}createContext(){return{declarations:[],declarationByName:new Map,nameBySignature:new Map,usedNames:new Set}}namespaceTopLevelShape(e,t){return e.kind===`object`?{...e,signature:`${t}:${e.signature}`}:e}inferShapeFromExample(e,t){if(e===null)return{kind:`primitive`,type:`null`};if(Array.isArray(e)){if(e.length===0)return{kind:`array`,item:{kind:`primitive`,type:`unknown`}};let n=this.dedupeShapes(e.map(e=>this.inferShapeFromExample(e,this.naming.singularize(t))));return{kind:`array`,item:n.length===1?n[0]:{kind:`union`,types:n}}}if(this.isRecord(e))return this.createObjectShape(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>({key:e,optional:!1,shape:this.inferShapeFromExample(t,e)})));switch(typeof e){case`string`:return{kind:`primitive`,type:`string`};case`number`:return{kind:`primitive`,type:`number`};case`boolean`:return{kind:`primitive`,type:`boolean`};default:return{kind:`primitive`,type:`unknown`}}}registerNamedShape(e,t,n,r){if(e.kind===`object`)return this.registerObjectShape(e,t,n,r,!0);let i=this.createUniqueTypeName(t,n,r),a={kind:`shape-alias`,name:i,shape:this.prepareNestedShape(e,t,n)};return n.declarations.push(a),n.declarationByName.set(i,a),i}registerObjectShape(e,t,n,r,i=!1){let a=n.nameBySignature.get(e.signature),o=this.findCompatibleObjectDeclaration(e,t,n);if(a){if(i&&a!==t&&!n.declarationByName.has(t)){let e=this.createUniqueTypeName(t,n,r);if(e!==a){let t={kind:`interface-alias`,name:e,target:a};n.declarations.push(t),n.declarationByName.set(e,t)}}return a}if(o){if(this.isObjectShapeAssignableTo(e,o.rawShape))return n.nameBySignature.set(e.signature,o.name),o.name;let t=this.mergeObjectShapes(o.rawShape,e);return o.rawShape=t,o.properties=t.properties.map(e=>({...e,shape:this.prepareNestedShape(e.shape,e.key,n)})),n.nameBySignature.set(e.signature,o.name),n.nameBySignature.set(t.signature,o.name),o.name}let s=this.createUniqueTypeName(t,n,r),c={kind:`interface`,name:s,baseName:this.naming.sanitizeTypeName(t),rawShape:e,properties:[]};return n.nameBySignature.set(e.signature,s),n.declarations.push(c),n.declarationByName.set(s,c),c.properties=e.properties.map(e=>({...e,shape:this.prepareNestedShape(e.shape,e.key,n)})),s}resolveSdkResponseType(e,t){let n=Object.entries(e).filter(([e])=>/^2\d\d$/.test(e)).sort(([e],[t])=>e.localeCompare(t))[0]?.[1];if(!n)return t;let r=this.getPreferredMediaType(n.content);if(!r)return t;let i=this.resolveResponsePayloadSchema(r.schema,r.example).schema??r.schema;return i&&this.resolveSchemaType(i)===`array`?`${t}[]`:t}getSuccessResponseShape(e){let t=Object.entries(e).filter(([e])=>/^2\d\d$/.test(e)).sort(([e],[t])=>e.localeCompare(t))[0]?.[1];if(!t)return this.emptyObjectShape;let n=this.getPreferredMediaType(t.content);if(!n)return this.emptyObjectShape;let r=this.resolveResponsePayloadSchema(n.schema,n.example);return r.schema?this.resolveSchemaType(r.schema)===`array`?this.schemaToShape(r.schema.items,`Item`,this.extractExampleArrayItem(r.example)):this.schemaToShape(r.schema,`Response`,r.example):this.schemaToShape(n.schema,`Response`,n.example)}getRequestInputShape(e){if(!e)return this.emptyObjectShape;let t=this.getPreferredMediaType(e.content);return t?this.schemaToShape(t.schema,`Input`,t.example):this.emptyObjectShape}getResponseExampleShape(e){let t=Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).flatMap(([,e])=>{let t=this.getPreferredMediaType(e.content);if(!t)return[];let n=t.example??t.schema?.example;return t.schema?[this.schemaToShape(t.schema,`ResponseExample`,n)]:n===void 0?[]:[this.inferShapeFromExample(n,`ResponseExample`)]}),n=this.dedupeShapes(t);return n.length===0?{kind:`primitive`,type:`unknown`}:n.length===1?n[0]:{kind:`union`,types:n}}createParameterGroupShape(e,t,n){let r=(e??[]).filter(e=>e.in===t).sort((e,t)=>e.name.localeCompare(t.name)),i=[...r,...this.naming.getInferredPathParameters(n,t,r)].sort((e,t)=>e.name.localeCompare(t.name));return i.length===0?this.emptyObjectShape:this.createObjectShape(i.map(e=>({key:e.name,optional:!(e.required??!1),shape:this.schemaToShape(e.schema,e.name,e.example)})))}get emptyObjectShape(){return this.createObjectShape([])}findCompatibleObjectDeclaration(e,t,n){let r=this.naming.sanitizeTypeName(t);return n.declarations.find(t=>t.kind!==`interface`||t.baseName!==r?!1:this.isObjectShapeAssignableTo(e,t.rawShape)||this.isObjectShapeAssignableTo(t.rawShape,e)||this.canMergeObjectShapes(t.rawShape,e))}canMergeObjectShapes(e,t){let n=new Set([...e.properties.map(e=>e.key),...t.properties.map(e=>e.key)]);for(let r of n){let n=e.properties.find(e=>e.key===r),i=t.properties.find(e=>e.key===r);if(!n||!i){if(!(n??i)?.optional)return!1;continue}if(!this.canMergeShapes(n.shape,i.shape))return!1}return!0}isObjectShapeAssignableTo(e,t){let n=new Map(t.properties.map(e=>[e.key,e]));for(let t of e.properties){let e=n.get(t.key);if(!e||t.optional&&!e.optional||!this.isShapeAssignableTo(t.shape,e.shape))return!1}return t.properties.every(t=>e.properties.some(e=>e.key===t.key)||t.optional)}isShapeAssignableTo(e,t){if(t.kind===`union`)return t.types.some(t=>this.isShapeAssignableTo(e,t));switch(e.kind){case`primitive`:return t.kind===`primitive`?e.type===t.type:!1;case`array`:return t.kind===`array`?this.isShapeAssignableTo(e.item,t.item):!1;case`union`:return e.types.every(e=>this.isShapeAssignableTo(e,t));case`object`:return t.kind===`object`?this.isObjectShapeAssignableTo(e,t):!1}}canMergeShapes(e,t){return e.kind===`union`?e.types.every(e=>this.canMergeShapes(e,t)):t.kind===`union`?t.types.every(t=>this.canMergeShapes(e,t)):e.kind===`primitive`&&t.kind===`primitive`?!0:e.kind===`array`&&t.kind===`array`?this.canMergeShapes(e.item,t.item):e.kind===`object`&&t.kind===`object`?this.canMergeObjectShapes(e,t):!1}mergeObjectShapes(e,t){let n=new Set([...e.properties.map(e=>e.key),...t.properties.map(e=>e.key)]);return this.createObjectShape(Array.from(n).map(n=>{let r=e.properties.find(e=>e.key===n),i=t.properties.find(e=>e.key===n);return r&&i?{key:n,optional:r.optional||i.optional,shape:this.mergeShapes(r.shape,i.shape)}:{key:n,optional:!0,shape:(r??i).shape}}))}mergeShapes(e,t){if(e.kind===`union`||t.kind===`union`||e.kind!==t.kind)return this.createUnionShape(e,t);switch(e.kind){case`primitive`:return t.kind===`primitive`&&e.type===t.type?e:this.createUnionShape(e,t);case`array`:return t.kind===`array`?{kind:`array`,item:this.mergeShapes(e.item,t.item)}:e;case`object`:return t.kind===`object`?this.mergeObjectShapes(e,t):e}}createUnionShape(...e){let t=e.flatMap(e=>e.kind===`union`?e.types:[e]),n=this.dedupeShapes(t);return n.length===1?n[0]:{kind:`union`,types:n}}prepareNestedShape(e,t,n){if(e.kind===`object`)return{kind:`primitive`,type:this.registerObjectShape(e,this.naming.sanitizeTypeName(this.naming.singularize(t)),n,this.naming.sanitizeTypeName(t))};if(e.kind===`array`)return{kind:`array`,item:this.prepareNestedShape(e.item,this.naming.singularize(t),n)};if(e.kind===`union`){let r=this.dedupeShapes(e.types.map((e,r)=>this.prepareNestedShape(e,this.getUnionMemberKeyHint(t,r,e),n)));return r.length===1?r[0]:{kind:`union`,types:r}}return e}getUnionMemberKeyHint(e,t,n){if(n.kind!==`object`&&n.kind!==`array`)return e;let r=this.naming.sanitizeTypeName(e);return r.endsWith(`ResponseExample`)?`${r}Variant${t+1}`:e}schemaToShape(e,t,n){if(!e)return this.inferShapeFromExample(n,t);let r=this.resolveSchemaType(e);if(r===`array`)return{kind:`array`,item:this.schemaToShape(e.items,this.naming.singularize(t),this.extractExampleArrayItem(e.example)??this.extractExampleArrayItem(n))};if(r===`object`){let r=this.isRecord(e.example)?e.example:this.isRecord(n)?n:void 0,i=Object.entries(e.properties??{}).sort(([e],[t])=>e.localeCompare(t)).map(([t,n])=>({key:t,optional:!(e.required??[]).includes(t),shape:this.schemaToShape(n,t,r?.[t])}));return i.length>0?this.createObjectShape(i):this.inferShapeFromExample(e.example??n,t)}return r===`integer`||r===`number`?{kind:`primitive`,type:`number`}:r===`string`?{kind:`primitive`,type:`string`}:r===`boolean`?{kind:`primitive`,type:`boolean`}:e.example===null||n===null?{kind:`primitive`,type:`null`}:e.example!==void 0||n!==void 0?this.inferShapeFromExample(e.example??n,t):{kind:`primitive`,type:`unknown`}}dedupeShapes(e){let t=new Set;return e.filter(e=>{let n=this.getShapeSignature(e);return t.has(n)?!1:(t.add(n),!0)})}createObjectShape(e){let t=e.map(e=>({...e})).sort((e,t)=>e.key.localeCompare(t.key));return{kind:`object`,signature:JSON.stringify(t.map(e=>({key:e.key,optional:e.optional,shape:this.getShapeSignature(e.shape)}))),properties:t}}getShapeSignature(e){switch(e.kind){case`primitive`:return`primitive:${e.type}`;case`array`:return`array:${this.getShapeSignature(e.item)}`;case`union`:return`union:${e.types.map(e=>this.getShapeSignature(e)).join(`|`)}`;case`object`:return`object:${e.signature}`}}getPreferredMediaType(e){if(e)return e[`application/json`]??e[`application/*+json`]??Object.values(e)[0]}resolveResponsePayloadSchema(e,t){for(let n of[[`data`],[`meta`,`data`]]){let r=this.getSchemaCandidateAtPath(e,t,n);if(r)return r}return{}}getSchemaCandidateAtPath(e,t,n){let r=this.getSchemaAtPath(e,n),i=this.getExampleAtPath(t,n);if(!(!r&&i===void 0))return r?{schema:r.example===void 0&&i!==void 0?{...r,example:i}:r,example:i??r.example}:{schema:{...this.inferSchemaTypeFromExample(i),example:i},example:i}}getSchemaAtPath(e,t){let n=e;for(let e of t){if(!n?.properties?.[e])return;n=n.properties[e]}return n}getExampleAtPath(e,t){let n=e;for(let e of t){if(!this.isRecord(n)||!(e in n))return;n=n[e]}return n}inferSchemaTypeFromExample(e){return Array.isArray(e)?{type:`array`,items:e.map(e=>this.inferSchemaTypeFromExample(e)).find(e=>this.hasSchemaDetails(e))??{}}:this.isRecord(e)?{type:`object`,properties:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,this.inferSchemaTypeFromExample(t)]))}:typeof e==`string`?{type:`string`}:typeof e==`number`?{type:`number`}:typeof e==`boolean`?{type:`boolean`}:{}}hasSchemaDetails(e){return!!(e?.type||e?.properties||e?.items||e?.example!==void 0)}resolveSchemaType(e){return e.type??(e.properties?`object`:void 0)}extractExampleArrayItem(e){return Array.isArray(e)?e[0]:void 0}createUniqueTypeName(e,t,n){let r=this.naming.sanitizeTypeName(e)||`GeneratedEntity`,i=this.naming.sanitizeTypeName(n),a=r,o=2;if(!t.usedNames.has(a)||(a=this.naming.insertCollisionSuffix(r,i),!t.usedNames.has(a)))return t.usedNames.add(a),a;for(;t.usedNames.has(a);)a=`${r}${o}`,o+=1;return t.usedNames.add(a),a}isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}},X=class{naming=new ze;shapes=new Be(this.naming);createContext(){return this.shapes.createContext()}collectSemanticModels(e){let t=[];for(let[n,r]of Object.entries(e.paths)){let e=this.naming.deriveOperationNaming(n),i=e.baseName,a=Object.entries(r).sort(([,e],[,t])=>this.getOperationPriority(t)-this.getOperationPriority(e));for(let[r,o]of a){let a=e.collisionSuffix||this.naming.fallbackCollisionSuffix(r,n,i);t.push({path:n,method:r,name:i,role:`response`,shape:this.shapes.getSuccessResponseShape(o.responses),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}ResponseExample`,role:`responseExample`,shape:this.shapes.getResponseExampleShape(o.responses),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Input`,role:`input`,shape:this.shapes.getRequestInputShape(o.requestBody),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Query`,role:`query`,shape:this.shapes.createParameterGroupShape(o.parameters,`query`,n),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Header`,role:`header`,shape:this.shapes.createParameterGroupShape(o.parameters,`header`,n),collisionSuffix:a}),t.push({path:n,method:r,name:`${i}Params`,role:`params`,shape:this.shapes.createParameterGroupShape(o.parameters,`path`,n),collisionSuffix:a})}}return t}buildSdkManifest(e,t,n={}){let r=this.naming.deriveSdkGroupNamesBySignature(e,n.namespaceStrategy??`smart`),i=new Map,a=this.buildSecuritySchemes(e),o=this.buildSecurityRequirements(e.security);for(let[a,o]of Object.entries(e.paths)){let e=this.naming.getStaticPathSegments(a).join(`/`),s=r.get(e)??`Resource`,c=this.naming.toCamelCase(this.naming.pluralize(s)),l=i.get(c)??{className:s,propertyName:c,operations:[]};for(let[e,r]of Object.entries(o)){let i=t.get(`${a}::${e}`)??{response:`Record<string, never>`,responseExample:`unknown`,input:`Record<string, never>`,query:`Record<string, never>`,header:`Record<string, never>`,params:`Record<string, never>`};l.operations.push({path:a,method:e.toUpperCase(),methodName:this.naming.deriveSdkMethodName(e,a,r,n.methodStrategy??`smart`),summary:r.summary,description:r.description,operationId:r.operationId,requestBodyDescription:r.requestBody?.description,responseDescription:this.resolveSuccessResponseDescription(r.responses),responseType:this.shapes.resolveSdkResponseType(r.responses,i.response),inputType:i.input,queryType:i.query,headerType:i.header,paramsType:i.params,hasBody:!!r.requestBody,bodyRequired:r.requestBody?.required??!1,pathParams:this.naming.createSdkParameterManifest(r.parameters,`path`,a),queryParams:this.naming.createSdkParameterManifest(r.parameters,`query`,a),headerParams:this.naming.createSdkParameterManifest(r.parameters,`header`,a),security:this.buildSecurityRequirements(r.security)})}i.set(c,l)}return{groups:Array.from(i.values()).map(e=>({...e,operations:this.naming.ensureUniqueSdkMethodNames(e.operations)})).sort((e,t)=>e.propertyName.localeCompare(t.propertyName)),securitySchemes:a,security:o}}inferShapeFromExample(e,t){return this.shapes.inferShapeFromExample(e,t)}sanitizeTypeName(e){return this.naming.sanitizeTypeName(e)}registerNamedShape(e,t,n,r){return this.shapes.registerNamedShape(e,t,n,r)}namespaceTopLevelShape(e,t){return this.shapes.namespaceTopLevelShape(e,t)}registerObjectShape(e,t,n,r,i=!1){return this.shapes.registerObjectShape(e,t,n,r,i)}getOperationPriority(e){return Number(!!e.requestBody)*10}resolveSuccessResponseDescription(e){for(let t of[`200`,`201`,`202`,`204`]){let n=e[t]?.description?.trim();if(n)return n}for(let t of Object.values(e)){let e=t.description?.trim();if(e)return e}}buildSecuritySchemes(e){return Object.entries(e.components?.securitySchemes??{}).map(([e,t])=>this.createSecuritySchemeManifest(e,t)).filter(e=>e!==null).sort((e,t)=>e.name.localeCompare(t.name))}createSecuritySchemeManifest(e,t){let n=this.createSecurityHelperName(e);if(t.type===`apiKey`)return{name:e,helperName:n,description:t.description,type:`apiKey`,authType:`apiKey`,in:t.in,parameterName:t.name};if(t.type===`oauth2`)return{name:e,helperName:n,description:t.description,type:`oauth2`,authType:`oauth2`,scopes:this.collectSecurityScopes(t)};if(t.type===`openIdConnect`)return{name:e,helperName:n,description:t.description,type:`openIdConnect`,authType:`oauth2`,openIdConnectUrl:t.openIdConnectUrl};let r=t.scheme.toLowerCase();return{name:e,helperName:n,description:t.description,type:`http`,authType:r===`basic`?`basic`:`bearer`,scheme:t.scheme,bearerFormat:t.bearerFormat}}buildSecurityRequirements(e){if(!e||e.length===0)return;let t=e.map(e=>({schemes:Object.entries(e).map(([e,t])=>({name:e,scopes:[...t].sort()})).sort((e,t)=>e.name.localeCompare(t.name))})).filter(e=>e.schemes.length>0);return t.length>0?t:void 0}collectSecurityScopes(e){let t=new Set;for(let n of Object.values(e.flows??{}))for(let e of Object.keys(n.scopes??{}))t.add(e);return t.size>0?Array.from(t).sort():void 0}createSecurityHelperName(e){let t=this.naming.sanitizeTypeName(e);return t.endsWith(`Auth`)?`create${t}`:`create${t}Auth`}},Z=class e{typeBuilder=new X;moduleRenderer=new Re;static generateModule=(t,n=`GeneratedOutput`,r={})=>new e().generate(t,n,r);generate(e,t=`GeneratedOutput`,n={}){return this.isOpenApiDocumentLike(e)?this.generateModule(e,t,n):this.generateGenericModule(e,t)}generateModule(e,t,n={}){let r=this.typeBuilder.createContext(),i=new Map;for(let t of this.typeBuilder.collectSemanticModels(e)){let e=`${t.path}::${t.method}`,n=this.typeBuilder.registerNamedShape(this.typeBuilder.namespaceTopLevelShape(t.shape,t.role),t.name,r,t.collisionSuffix),a=i.get(e)??{response:`Record<string, never>`,responseExample:`unknown`,input:`Record<string, never>`,query:`Record<string, never>`,header:`Record<string, never>`,params:`Record<string, never>`};a[t.role]=n,i.set(e,a)}let a=r.declarations.map(e=>this.moduleRenderer.renderDeclaration(e)).join(`
90
140
 
91
141
  `),o=this.moduleRenderer.toCamelCase(t),s=this.typeBuilder.buildSdkManifest(e,i,n);return[a,this.moduleRenderer.renderOpenApiDocumentDefinitions(t,e,i),this.moduleRenderer.renderSdkApiInterface(t,s),this.moduleRenderer.renderSdkManifest(o,s),`export const ${o}: ${t} = ${this.moduleRenderer.renderOpenApiDocumentValue(e)}`,this.moduleRenderer.renderSdkBundle(o,t),``,`export default ${o}`].filter(Boolean).join(`
92
142
 
@@ -94,20 +144,23 @@ import{JSDOM as e}from"jsdom";import{Window as t}from"happy-dom";import n from"a
94
144
 
95
145
  `),o,`export const ${s}: ${t} = ${this.moduleRenderer.renderValue(e)}`,``,`export default ${s}`].filter(Boolean).join(`
96
146
 
97
- `)}isOpenApiDocumentLike(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.info!=`object`||t.info===null||Array.isArray(t.info))return!1;let n=t.info;return t.openapi===`3.1.0`&&typeof n.title==`string`&&typeof n.version==`string`&&typeof t.paths==`object`&&t.paths!==null&&!Array.isArray(t.paths)}},Q=class{static serializeOutput=async(e,t,n=`ExtractedApiDocument`,r={})=>t===`js`?l.format(`export default ${JSON.stringify(e,null,2)}`,{parser:`babel`,semi:!1,singleQuote:!0}):t===`ts`?l.format(Z.generateModule(e,n,r),{parser:`typescript`,semi:!1,singleQuote:!0}):JSON.stringify(e,null,t===`json`?0:2);static buildFilePath=(e,t,n,r)=>{let a={pretty:`txt`,json:`json`,js:`js`,ts:`ts`}[r],o=this.toSafeSourceName(t),s=n===`openapi`?`.openapi`:``;return i.join(e,`output`,`${o||`output`}${s}.${a}`)};static buildArtifactDirectory=(e,t,n)=>{let r=this.toSafeSourceName(t);return i.join(e,`output`,`${r||n}.${n}`)};static toSafeSourceName(e){return e.replace(/[^a-zA-Z0-9_-]+/g,`_`).replace(/^_+|_+$/g,``)}static getRootTypeName=e=>e===`openapi`?`ExtractedApiDocument`:`ExtractedPayload`},Ve=class{typeBuilder=new X;typeScriptGenerator=new Z;generate(e,t={}){let n=t.outputMode??`both`,r=t.signatureStyle??`grouped`,i=t.rootTypeName??`ExtractedApiDocument`,a=t.schemaModule??this.typeScriptGenerator.generateModule(e,i,t),o=this.createOperationTypeRefs(e),s=this.typeBuilder.buildSdkManifest(e,o,t),c=s.groups.map(e=>e.className),l={"package.json":this.renderPackageJson(t),"README.md":this.renderReadme(s,t,n,r),"src/Schema.ts":a,"src/index.ts":this.renderIndexFile(c,n,i),"tsconfig.json":this.renderTsconfig(),"tsdown.config.ts":this.renderTsdownConfig(),"vitest.config.ts":this.renderVitestConfig(),"tests/exports.test.ts":this.renderExportsTest(i,n)};if(n!==`runtime`){l[`src/BaseApi.ts`]=this.renderBaseApi(),l[`src/ApiBinder.ts`]=this.renderApiBinder(s);for(let e of s.groups)l[`src/Apis/${e.className}.ts`]=this.renderApiClass(e,r);l[`src/Core.ts`]=this.renderCoreFile()}return l}createOperationTypeRefs(e){let t=this.typeBuilder.createContext(),n=new Map;for(let r of this.typeBuilder.collectSemanticModels(e)){let e=`${r.path}::${r.method}`,i=this.typeBuilder.registerNamedShape(this.typeBuilder.namespaceTopLevelShape(r.shape,r.role),r.name,t,r.collisionSuffix),a=n.get(e)??{response:`Record<string, never>`,responseExample:`unknown`,input:`Record<string, never>`,query:`Record<string, never>`,header:`Record<string, never>`,params:`Record<string, never>`};a[r.role]=i,n.set(e,a)}return n}renderBaseApi(){return[`import { BaseApi as KitBaseApi } from '@oapiex/sdk-kit'`,``,`export class BaseApi extends KitBaseApi {}`].join(`
147
+ `)}isOpenApiDocumentLike(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.info!=`object`||t.info===null||Array.isArray(t.info))return!1;let n=t.info;return t.openapi===`3.1.0`&&typeof n.title==`string`&&typeof n.version==`string`&&typeof t.paths==`object`&&t.paths!==null&&!Array.isArray(t.paths)}},Q=class{static serializeOutput=async(e,t,n=`ExtractedApiDocument`,r={})=>t===`js`?l.format(`export default ${JSON.stringify(e,null,2)}`,{parser:`babel`,semi:!1,singleQuote:!0}):t===`ts`?l.format(Z.generateModule(e,n,r),{parser:`typescript`,semi:!1,singleQuote:!0}):JSON.stringify(e,null,t===`json`?0:2);static buildFilePath=(e,t,n,r)=>{let a={pretty:`txt`,json:`json`,js:`js`,ts:`ts`}[r],o=this.toSafeSourceName(t),s=n===`openapi`?`.openapi`:``;return i.join(e,`output`,`${o||`output`}${s}.${a}`)};static buildArtifactDirectory=(e,t,n)=>{let r=this.toSafeSourceName(t);return i.join(e,`output`,`${r||n}.${n}`)};static toSafeSourceName(e){return e.replace(/[^a-zA-Z0-9_-]+/g,`_`).replace(/^_+|_+$/g,``)}static getRootTypeName=e=>e===`openapi`?`ExtractedApiDocument`:`ExtractedPayload`},Ve=class{typeBuilder=new X;typeScriptGenerator=new Z;generate(e,t={}){let n=t.outputMode??`both`,r=t.signatureStyle??`grouped`,i=t.rootTypeName??`ExtractedApiDocument`,a=t.schemaModule??this.typeScriptGenerator.generateModule(e,i,t),o=this.createOperationTypeRefs(e),s=this.typeBuilder.buildSdkManifest(e,o,t),c=s.groups.map(e=>e.className),l={"package.json":this.renderPackageJson(t),"README.md":this.renderReadme(s,t,n,r),"src/Schema.ts":a,"src/index.ts":this.renderIndexFile(c,n,i,s),"tsconfig.json":this.renderTsconfig(),"tsdown.config.ts":this.renderTsdownConfig(),"vitest.config.ts":this.renderVitestConfig(),"tests/exports.test.ts":this.renderExportsTest(i,n)};if(n!==`runtime`){l[`src/BaseApi.ts`]=this.renderBaseApi(),l[`src/ApiBinder.ts`]=this.renderApiBinder(s);for(let e of s.groups)l[`src/Apis/${e.className}.ts`]=this.renderApiClass(e,r);l[`src/Core.ts`]=this.renderCoreFile()}return l}createOperationTypeRefs(e){let t=this.typeBuilder.createContext(),n=new Map;for(let r of this.typeBuilder.collectSemanticModels(e)){let e=`${r.path}::${r.method}`,i=this.typeBuilder.registerNamedShape(this.typeBuilder.namespaceTopLevelShape(r.shape,r.role),r.name,t,r.collisionSuffix),a=n.get(e)??{response:`Record<string, never>`,responseExample:`unknown`,input:`Record<string, never>`,query:`Record<string, never>`,header:`Record<string, never>`,params:`Record<string, never>`};a[r.role]=i,n.set(e,a)}return n}renderBaseApi(){return[`import { BaseApi as KitBaseApi } from '@oapiex/sdk-kit'`,``,`export class BaseApi extends KitBaseApi {}`].join(`
98
148
  `)}renderApiBinder(e){return[`import { BaseApi } from './BaseApi'`,``,...e.groups.map(e=>`import { ${e.className} } from './Apis/${e.className}'`),``,`export class ApiBinder extends BaseApi {`,...e.groups.map(e=>` ${e.propertyName}!: ${e.className}`),``,` protected override boot () {`,...e.groups.map(e=>` this.${e.propertyName} = new ${e.className}(this.core)`),` }`,`}`].join(`
99
149
  `)}renderApiClass(e,t){let n=this.createTypeImportContext(e,t),r=[`import { BaseApi } from '../BaseApi'`,`import { Http } from '@oapiex/sdk-kit'`];return n.specifiers.length>0&&r.splice(1,0,`import type { ${n.specifiers.join(`, `)} } from '../Schema'`),[...r,``,`export class ${e.className} extends BaseApi {`,``,...e.operations.flatMap(e=>[this.renderApiMethod(e,t,n.aliasMap),``]).slice(0,-1),`}`].join(`
100
150
  `)}renderApiMethod(e,t,n){let r=t===`flat`?this.renderFlatSignature(e,n):this.renderGroupedSignature(e,n),i=t===`flat`?this.renderFlatObjectLiteral(e.paramsType,e.pathParams):e.pathParams.length>0?`params`:`{}`,a=t===`flat`?this.renderFlatObjectLiteral(e.queryType,e.queryParams):e.queryParams.length>0?`query`:`{}`,o=t===`flat`?this.renderFlatHeaders(e):e.headerParams.length>0?`((headers ? { ...headers } : {}) as Record<string, string | undefined>)`:`{}`,s=t===`flat`?e.hasBody?`body`:`{}`:e.hasBody?`body ?? {}`:`{}`,c=this.renderMethodDocComment(e,t,n);return[...c?[c]:[],` async ${e.methodName} ${r}: Promise<${this.rewriteTypeReference(e.responseType,n)}> {`,` await this.core.validateAccess()`,``,` const { data } = await Http.send<${this.rewriteTypeReference(e.responseType,n)}>(`,` this.core.builder.buildTargetUrl('${e.path}', ${i}, ${a}),`,` '${e.method}',`,` ${s},`,` ${o}`,` )`,``,` return data`,` }`].join(`
101
151
  `)}renderMethodDocComment(e,t,n){let r=[],i=e.summary?.trim(),a=e.description?.trim(),o=e.operationId?.trim(),s=this.rewriteTypeReference(e.responseType,n),c=e.responseDescription?.trim();i&&r.push(i),a&&a!==i&&(r.length>0&&r.push(``),r.push(...this.wrapDocText(a)));let l=[`HTTP ${e.method} ${e.path}`,...o?[`Operation ID: ${o}`]:[]];l.length>0&&(r.length>0&&r.push(``),r.push(...l));let u=t===`flat`?this.renderFlatParameterDocs(e,n):this.renderGroupedParameterDocs(e,n);return u.length>0&&(r.length>0&&r.push(``),r.push(...u)),r.push(`@returns ${c?`${c} `:``}${s}`.trim()),[` /**`,...r.map(e=>e?` * ${e}`:` *`),` */`].join(`
102
152
  `)}renderGroupedParameterDocs(e,t){let n=[];return e.pathParams.length>0&&n.push(this.renderParamDoc(`params`,e.paramsType,t,this.describeParameterGroup(e.pathParams,`path parameters`))),e.queryParams.length>0&&n.push(this.renderParamDoc(`query`,e.queryType,t,this.describeParameterGroup(e.queryParams,`query parameters`))),e.hasBody&&n.push(this.renderParamDoc(`body`,e.inputType,t,e.requestBodyDescription?.trim()||`Request body`)),e.headerParams.length>0&&n.push(this.renderParamDoc(`headers`,e.headerType,t,this.describeParameterGroup(e.headerParams,`request headers`))),n}renderFlatParameterDocs(e,t){return[...e.pathParams.map(n=>this.renderParamDoc(n.accessor,`${e.paramsType}[${JSON.stringify(n.name)}]`,t,n.description?.trim()||`Path parameter ${n.name}`)),...e.queryParams.map(n=>this.renderParamDoc(n.accessor,`${e.queryType}[${JSON.stringify(n.name)}]`,t,n.description?.trim()||`Query parameter ${n.name}`)),...e.hasBody?[this.renderParamDoc(`body`,e.inputType,t,e.requestBodyDescription?.trim()||`Request body`)]:[],...e.headerParams.map(n=>this.renderParamDoc(n.accessor,`${e.headerType}[${JSON.stringify(n.name)}]`,t,n.description?.trim()||`Header ${n.name}`))]}renderParamDoc(e,t,n,r){return`@param ${e} ${r} Type: ${this.rewriteTypeReference(t,n)}`}describeParameterGroup(e,t){let n=e.map(e=>e.description?.trim()?`${e.name}: ${e.description.trim()}`:e.name).filter(Boolean);return n.length===0?t:n.join(`; `)}wrapDocText(e){return e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean)}renderGroupedSignature(e,t){let n=[];return e.pathParams.length>0&&n.push(`params: ${this.rewriteTypeReference(e.paramsType,t)}`),e.queryParams.length>0&&n.push(`query: ${this.rewriteTypeReference(e.queryType,t)}`),e.hasBody&&n.push(`body${e.bodyRequired?``:`?`}: ${this.rewriteTypeReference(e.inputType,t)}`),e.headerParams.length>0&&n.push(`headers?: ${this.rewriteTypeReference(e.headerType,t)}`),`(${n.join(`, `)})`}renderFlatSignature(e,t){return`(${[...e.pathParams.map(n=>`${n.accessor}${n.required?``:`?`}: ${this.rewriteTypeReference(e.paramsType,t)}[${JSON.stringify(n.name)}]`),...e.queryParams.map(n=>`${n.accessor}${n.required?``:`?`}: ${this.rewriteTypeReference(e.queryType,t)}[${JSON.stringify(n.name)}]`),...e.hasBody?[`body${e.bodyRequired?``:`?`}: ${this.rewriteTypeReference(e.inputType,t)}`]:[],...e.headerParams.map(n=>`${n.accessor}${n.required?``:`?`}: ${this.rewriteTypeReference(e.headerType,t)}[${JSON.stringify(n.name)}]`)].join(`, `)})`}createTypeImportContext(e,t){let n=new Set;for(let t of e.operations)n.add(t.responseType),t.hasBody&&n.add(t.inputType),t.queryParams.length>0&&n.add(t.queryType),t.headerParams.length>0&&n.add(t.headerType),t.pathParams.length>0&&n.add(t.paramsType);let r=Array.from(new Set(Array.from(n).flatMap(e=>this.collectTypeIdentifiers(e)))).sort(),i=new Map;return{specifiers:r.map(t=>{if(t===e.className){let e=`${t}Model`;return i.set(t,e),`${t} as ${e}`}return t}),aliasMap:i}}rewriteTypeReference(e,t){let n=e;for(let[e,r]of t.entries())n=n.replace(RegExp(`\\b${e}\\b`,`g`),r);return n}renderFlatObjectLiteral(e,t){return t.length===0?`{}`:`{ ${t.map(e=>`${JSON.stringify(e.name)}: ${e.accessor}`).join(`, `)} }`}renderFlatHeaders(e){return e.headerParams.length===0?`{}`:`({ ${e.headerParams.map(e=>`${JSON.stringify(e.name)}: ${e.accessor}`).join(`, `)} } as Record<string, string | undefined>)`}renderCoreFile(){return[`import { Core as KitCore } from '@oapiex/sdk-kit'`,``,`import { ApiBinder } from './ApiBinder'`,``,`export class Core extends KitCore {`,` static override apiClass = ApiBinder`,``,` declare api: ApiBinder`,`}`].join(`
103
- `)}renderPackageJson(e){return JSON.stringify({name:e.packageName??`generated-sdk`,type:`module`,version:e.packageVersion??`0.1.0`,private:!0,description:e.packageDescription??`Generated SDK scaffold emitted by oapiex.`,main:`./dist/index.cjs`,module:`./dist/index.js`,types:`./dist/index.d.ts`,exports:{".":{import:`./dist/index.js`,require:`./dist/index.cjs`},"./package.json":`./package.json`},files:[`dist`],scripts:{test:`pnpm vitest --run`,"test:watch":`pnpm vitest`,build:`tsdown`},dependencies:{[e.sdkKitPackageName??`@oapiex/sdk-kit`]:`^0.1.1`},devDependencies:{"@types/node":`^20.14.5`,tsdown:`^0.20.1`,typescript:`^5.4.5`,vitest:`^3.2.4`}},null,2)}renderReadme(e,t,n,r){let i=t.packageName??`generated-sdk`,a=`# ${i}`,o=this.renderReadmeDescription(n),s=this.renderReadmeUsage(e,i,n,r),c=this.renderReadmeExports(n);return[a,``,o,``,`## Install`,``,"```bash",`pnpm add ${i}`,"```",``,`## Quick Start`,``,"```ts",s,"```",``,`## Main Exports`,``,...c.map(e=>`- ${e}`),``,`## Commands`,``,"```bash",`pnpm test`,`pnpm build`,"```"].join(`
104
- `)}renderReadmeDescription(e){return e===`runtime`?`Generated runtime-first TypeScript SDK emitted by oapiex.`:e===`classes`?`Generated class-based TypeScript SDK emitted by oapiex.`:`Generated TypeScript SDK emitted by oapiex with both class-based and runtime-first entrypoints.`}renderReadmeUsage(e,t,n,r){let i=this.pickExampleOperation(e),a=this.renderReadmeClientSnippet(t,`runtime`,r,i);if(n===`runtime`)return a;let o=this.renderReadmeClientSnippet(t,`classes`,r,i);if(n===`classes`)return o;let s=i?this.collectReadmeTypeImports(i.operation):[];return[s.length>0?`import { Core, createClient, type ${s.join(`, type `)} } from '${t}'`:`import { Core, createClient } from '${t}'`,``,...this.renderReadmeClientBody(`sdk`,`classes`,r,i),``,`// --- OR ---`,``,...this.renderReadmeClientBody(`runtimeSdk`,`runtime`,r,i)].join(`
105
- `)}renderReadmeClientSnippet(e,t,n,r){let i=t===`runtime`?[`createClient`]:[`Core`],a=r?this.collectReadmeTypeImports(r.operation):[],o=a.length>0?`import { ${i.join(`, `)}, type ${a.join(`, type `)} } from '${e}'`:`import { ${i.join(`, `)} } from '${e}'`,s=t===`runtime`?`runtimeSdk`:`sdk`;return[o,``,...this.renderReadmeClientBody(s,t,n,r)].join(`
106
- `)}renderReadmeClientBody(e,t,n,r){let i=t===`runtime`?`const ${e} = createClient({`:`const ${e} = new Core({`,a=r?this.renderReadmeOperationCall(e,r,t===`runtime`?`grouped`:n):[];return[i,` clientId: process.env.CLIENT_ID!,`,` clientSecret: process.env.CLIENT_SECRET!,`,` environment: 'sandbox',`,`})`,...a.length>0?[``,...a]:[]]}renderReadmeExports(e){return e===`runtime`?["`createClient()` for a typed runtime SDK instance","`Schema` exports for request, response, params, query, and header types"]:e===`classes`?["`Core` as the class-based SDK entrypoint","generated API classes plus `Schema` type exports"]:["`Core` for class-based usage","`createClient()` for runtime-first usage","`Schema` exports for generated request, response, params, query, and header types"]}pickExampleOperation(e){let t=e.groups[0],n=t?.operations[0];return!t||!n?null:{group:t,operation:n}}collectReadmeTypeImports(e){let t=new Set;return e.pathParams.length>0&&t.add(e.paramsType),e.queryParams.length>0&&t.add(e.queryType),e.hasBody&&t.add(e.inputType),e.headerParams.length>0&&t.add(e.headerType),Array.from(t).sort()}renderReadmeOperationCall(e,t,n){let{group:r,operation:i}=t,a=n===`flat`?this.renderReadmeFlatArgs(i):this.renderReadmeGroupedArgs(i);return[`await ${e}.api.${r.propertyName}.${i.methodName}(`,...a.map(e=>` ${e},`),`)`]}renderReadmeGroupedArgs(e){let t=[];return e.pathParams.length>0&&t.push(`{} as ${e.paramsType}`),e.queryParams.length>0&&t.push(`{} as ${e.queryType}`),e.hasBody&&t.push(`{} as ${e.inputType}`),e.headerParams.length>0&&t.push(`{} as ${e.headerType}`),t}renderReadmeFlatArgs(e){return[...e.pathParams.map(t=>`{} as ${e.paramsType}[${JSON.stringify(t.name)}]`),...e.queryParams.map(t=>`{} as ${e.queryType}[${JSON.stringify(t.name)}]`),...e.hasBody?[`{} as ${e.inputType}`]:[],...e.headerParams.map(t=>`{} as ${e.headerType}[${JSON.stringify(t.name)}]`)]}renderTsconfig(){return JSON.stringify({compilerOptions:{rootDir:`.`,outDir:`./dist`,target:`esnext`,module:`es2022`,moduleResolution:`bundler`,esModuleInterop:!0,strict:!0,allowJs:!0,skipLibCheck:!0,resolveJsonModule:!0},include:[`./src/**/*`,`./tests/**/*`],exclude:[`./dist`,`./node_modules`]},null,2)}renderTsdownConfig(){return[`import { defineConfig } from 'tsdown'`,``,`export default defineConfig({`,` entry: {`,` index: 'src/index.ts',`,` },`,` exports: true,`,` format: ['esm', 'cjs'],`,` outDir: 'dist',`,` dts: true,`,` sourcemap: false,`,` external: ['@oapiex/sdk-kit'],`,` clean: true,`,`})`].join(`
153
+ `)}renderPackageJson(e){return JSON.stringify({name:e.packageName??`generated-sdk`,type:`module`,version:e.packageVersion??`0.1.0`,private:!0,description:e.packageDescription??`Generated SDK scaffold emitted by oapiex.`,main:`./dist/index.cjs`,module:`./dist/index.js`,types:`./dist/index.d.ts`,exports:{".":{import:`./dist/index.js`,require:`./dist/index.cjs`},"./package.json":`./package.json`},files:[`dist`],scripts:{test:`pnpm vitest --run`,"test:watch":`pnpm vitest`,build:`tsdown`},dependencies:{[e.sdkKitPackageName??`@oapiex/sdk-kit`]:`^0.1.1`},devDependencies:{"@types/node":`^20.14.5`,tsdown:`^0.20.1`,typescript:`^5.4.5`,vitest:`^3.2.4`}},null,2)}renderReadme(e,t,n,r){let i=t.packageName??`generated-sdk`,a=`# ${i}`,o=this.renderReadmeDescription(n),s=this.renderReadmeUsage(e,i,n,r),c=this.renderReadmeExports(n,e);return[a,``,o,``,`## Install`,``,"```bash",`pnpm add ${i}`,"```",``,`## Quick Start`,``,"```ts",s,"```",``,`## Main Exports`,``,...c.map(e=>`- ${e}`),``,`## Commands`,``,"```bash",`pnpm test`,`pnpm build`,"```"].join(`
154
+ `)}renderReadmeDescription(e){return e===`runtime`?`Generated runtime-first TypeScript SDK emitted by oapiex.`:e===`classes`?`Generated class-based TypeScript SDK emitted by oapiex.`:`Generated TypeScript SDK emitted by oapiex with both class-based and runtime-first entrypoints.`}renderReadmeUsage(e,t,n,r){let i=this.pickExampleOperation(e),a=this.renderReadmeClientSnippet(t,`runtime`,r,i);if(n===`runtime`)return a;let o=this.renderReadmeClientSnippet(t,`classes`,r,i);if(n===`classes`)return o;let s=i?this.collectReadmeTypeImports(i.operation):[],c=[`Core`,`createClient`,...i?this.collectReadmeAuthHelperImports(i):[]];return[s.length>0?`import { ${c.join(`, `)}, type ${s.join(`, type `)} } from '${t}'`:`import { ${c.join(`, `)} } from '${t}'`,``,...this.renderReadmeClientBody(`sdk`,`classes`,r,i),``,`// --- OR ---`,``,...this.renderReadmeClientBody(`runtimeSdk`,`runtime`,r,i)].join(`
155
+ `)}renderReadmeClientSnippet(e,t,n,r){let i=t===`runtime`?[`createClient`]:[`Core`],a=r?this.collectReadmeTypeImports(r.operation):[],o=r?this.collectReadmeAuthHelperImports(r):[],s=[...i,...o],c=a.length>0?`import { ${s.join(`, `)}, type ${a.join(`, type `)} } from '${e}'`:`import { ${s.join(`, `)} } from '${e}'`,l=t===`runtime`?`runtimeSdk`:`sdk`;return[c,``,...this.renderReadmeClientBody(l,t,n,r)].join(`
156
+ `)}renderReadmeClientBody(e,t,n,r){let i=t===`runtime`?`const ${e} = createClient({`:`const ${e} = new Core({`,a=r?this.renderReadmeOperationCall(e,r,t===`runtime`?`grouped`:n):[];return[i,` clientId: process.env.CLIENT_ID!,`,` clientSecret: process.env.CLIENT_SECRET!,`,` environment: 'sandbox',`,...r?this.renderReadmeAuthLines(r.operation.security??r.groupSecurity??r.globalSecurity):[],`})`,...a.length>0?[``,...a]:[]]}renderReadmeExports(e,t){let n=t.securitySchemes.length>0?[`generated auth helpers derived from OpenAPI security schemes`]:[];return e===`runtime`?["`createClient()` for a typed runtime SDK instance",...n,"`Schema` exports for request, response, params, query, and header types"]:e===`classes`?["`Core` as the class-based SDK entrypoint",...n,"generated API classes plus `Schema` type exports"]:["`Core` for class-based usage","`createClient()` for runtime-first usage",...n,"`Schema` exports for generated request, response, params, query, and header types"]}pickExampleOperation(e){let t=e.groups[0],n=t?.operations[0];return!t||!n?null:{group:t,operation:n,groupSecurity:void 0,globalSecurity:e.security}}renderReadmeAuthLines(e){if(!e||e.length===0)return[];let t=e[0];if(!t||t.schemes.length===0)return[];let n=t.schemes.length===1?this.renderReadmeAuthFactoryCall(t.schemes[0].name):`[
157
+ ${t.schemes.map(e=>this.renderReadmeAuthFactoryCall(e.name)).join(`,
158
+ `)}
159
+ ]`,r=e.length>1?[` // Choose a generated auth helper that matches your API access setup.`]:[];return r.push(` auth: ${n},`),r}renderReadmeAuthFactoryCall(e){let t=this.createSecurityHelperName(e),n=this.toConstantCase(e);return/basic/i.test(e)?`${t}(process.env.${n}_USERNAME!, process.env.${n}_PASSWORD!)`:`${t}(process.env.${n}_VALUE!)`}collectReadmeAuthHelperImports(e){let t=(e.operation.security??e.groupSecurity??e.globalSecurity)?.[0];return t?t.schemes.map(e=>this.createSecurityHelperName(e.name)):[]}collectReadmeTypeImports(e){let t=new Set;return e.pathParams.length>0&&t.add(e.paramsType),e.queryParams.length>0&&t.add(e.queryType),e.hasBody&&t.add(e.inputType),e.headerParams.length>0&&t.add(e.headerType),Array.from(t).sort()}renderReadmeOperationCall(e,t,n){let{group:r,operation:i}=t,a=n===`flat`?this.renderReadmeFlatArgs(i):this.renderReadmeGroupedArgs(i);return[`await ${e}.api.${r.propertyName}.${i.methodName}(`,...a.map(e=>` ${e},`),`)`]}renderReadmeGroupedArgs(e){let t=[];return e.pathParams.length>0&&t.push(`{} as ${e.paramsType}`),e.queryParams.length>0&&t.push(`{} as ${e.queryType}`),e.hasBody&&t.push(`{} as ${e.inputType}`),e.headerParams.length>0&&t.push(`{} as ${e.headerType}`),t}renderReadmeFlatArgs(e){return[...e.pathParams.map(t=>`{} as ${e.paramsType}[${JSON.stringify(t.name)}]`),...e.queryParams.map(t=>`{} as ${e.queryType}[${JSON.stringify(t.name)}]`),...e.hasBody?[`{} as ${e.inputType}`]:[],...e.headerParams.map(t=>`{} as ${e.headerType}[${JSON.stringify(t.name)}]`)]}renderTsconfig(){return JSON.stringify({compilerOptions:{rootDir:`.`,outDir:`./dist`,target:`esnext`,module:`es2022`,moduleResolution:`bundler`,esModuleInterop:!0,strict:!0,allowJs:!0,skipLibCheck:!0,resolveJsonModule:!0},include:[`./src/**/*`,`./tests/**/*`],exclude:[`./dist`,`./node_modules`]},null,2)}renderTsdownConfig(){return[`import { defineConfig } from 'tsdown'`,``,`export default defineConfig({`,` entry: {`,` index: 'src/index.ts',`,` },`,` exports: true,`,` format: ['esm', 'cjs'],`,` outDir: 'dist',`,` dts: true,`,` sourcemap: false,`,` external: ['@oapiex/sdk-kit'],`,` clean: true,`,`})`].join(`
107
160
  `)}renderVitestConfig(){return[`import { defineConfig } from 'vitest/config'`,``,`export default defineConfig({`,` test: {`,` name: 'generated-sdk',`,` environment: 'node',`,` include: ['tests/*.{test,spec}.?(c|m)[jt]s?(x)'],`,` },`,`})`].join(`
108
161
  `)}renderExportsTest(e,t){let n=`${e.charAt(0).toLowerCase()}${e.slice(1)}`,r=[` expect(sdk.createClient).toBeTypeOf('function')`,` expect(sdk.createSdk).toBeTypeOf('function')`,` expect(sdk.${n}Sdk).toBeDefined()`,` expect(sdk.${n}Manifest).toBeDefined()`];return t!==`runtime`&&(r.unshift(` expect(sdk.Core).toBeTypeOf('function')`),r.unshift(` expect(sdk.BaseApi).toBeTypeOf('function')`)),[`import { describe, expect, it } from 'vitest'`,``,`import * as sdk from '../src/index'`,``,`describe('generated sdk exports', () => {`,` it('exposes the generated schema and runtime helpers', () => {`,...r,` })`,`})`].join(`
109
- `)}renderIndexFile(e,t,n){let r=`${n.charAt(0).toLowerCase()}${n.slice(1)}`,i=[`import type { ${n}Api } from './Schema'`,`import { ${r}Sdk } from './Schema'`,`import { createSdk as createBoundSdk } from '@oapiex/sdk-kit'`,`import type { BaseApi as KitBaseApi, Core as KitCore, InitOptions } from '@oapiex/sdk-kit'`,``,`export * from './Schema'`];return t!==`runtime`&&(i.push(`export { ApiBinder } from './ApiBinder'`),i.push(`export { BaseApi } from './BaseApi'`),i.push(...e.map(e=>`export { ${e} as ${e}Api } from './Apis/${e}'`)),i.push(`export { Core } from './Core'`)),i.push(``),i.push(`export const createClient = (`),i.push(` options: InitOptions`),i.push(`): KitCore & { api: KitBaseApi & ${n}Api } =>`),i.push(` createBoundSdk(${r}Sdk, options) as KitCore & { api: KitBaseApi & ${n}Api }`),i.push(``),i.push(`export {`),i.push(` BadRequestException,`),i.push(` Builder,`),i.push(` ForbiddenRequestException,`),i.push(` Http,`),i.push(` HttpException,`),i.push(` UnauthorizedRequestException,`),i.push(` WebhookValidator,`),i.push(` createSdk,`),i.push(`} from '@oapiex/sdk-kit'`),i.push(``),i.push(`export type {`),i.push(` InitOptions,`),i.push(` UnifiedResponse,`),i.push(` XGenericObject,`),i.push(`} from '@oapiex/sdk-kit'`),i.join(`
110
- `)}collectTypeIdentifiers(e){return Array.from(new Set((e.match(/\b[A-Z][A-Za-z0-9_]*/g)??[]).filter(e=>![`Record`,`Promise`].includes(e))))}};const $=new class{createDocument(e,t=`Extracted API`,n=`0.0.0`){let r={};for(let t of e){let e=this.transformOperation(t);!e||this.shouldSkipNormalizedOperation(e)||(r[e.path]??={},r[e.path][e.method]=e.operation)}return{openapi:`3.1.0`,info:{title:t,version:n},paths:r}}transformOperation(e){if(!e.method||!e.url)return null;let t=new URL(e.url);if(this.shouldSkipPlaceholderOperation(t,e))return null;let n=e.method.toLowerCase(),r=this.decodeOpenApiPathname(t.pathname);return{path:r,method:n,operation:{summary:e.sidebarLinks.find(e=>e.active)?.label,description:e.description??void 0,operationId:this.buildOperationId(n,r),parameters:this.createParameters(e.requestParams),requestBody:this.createRequestBody(e.requestParams,e.requestExampleNormalized?.body,this.hasExtractedBodyParams(e.requestParams)?null:this.resolveFallbackRequestBodyExample(e)),responses:this.createResponses(e.responseSchemas,e.responseBodies)}}}shouldSkipNormalizedOperation(e){return e.path===`/`&&e.method===`get`&&e.operation.operationId===`get`&&Object.keys(e.operation.responses).length===0}shouldSkipPlaceholderOperation(e,t){return e.hostname!==`example.com`||e.pathname!==`/`?!1:t.requestParams.length===0&&t.responseSchemas.length===0&&t.responseBodies.length===0&&t.requestExampleNormalized?.url===`https://example.com/`}decodeOpenApiPathname(e){return e.split(`/`).map(e=>{if(!e)return e;try{return decodeURIComponent(e)}catch{return e}}).join(`/`)}hasExtractedBodyParams(e){return e.some(e=>e.in===`body`||e.in===null)}createParameters(e){let t=e.filter(e=>this.isOpenApiParameterLocation(e.in)).map(e=>this.createParameter(e));return t.length>0?t:void 0}createRequestBody(e,t,n){let r=e.filter(e=>e.in===`body`||e.in===null);if(r.length===0&&t==null)return;let i=this.buildRequestBodySchema(r,t,n);return{required:r.length>0?r.some(e=>e.required):!1,content:{"application/json":{schema:i,...t==null?{}:{example:t}}}}}buildRequestBodySchema(e,t,n){let r=this.mergeOpenApiSchemas(this.createExampleSchema(t),this.createExampleSchema(n))??{type:`object`};t==null?n!=null&&(r.example=n):r.example=t;for(let t of e)this.insertRequestBodyParam(r,t);return r}inferSchemaFromExample(e){if(Array.isArray(e))return{type:`array`,items:this.inferSchemaFromExample(e[0])??{},example:e};if(T(e))return{type:`object`,properties:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,this.inferSchemaFromExample(t)??{}])),example:e};if(typeof e==`string`)return{type:`string`,example:e};if(typeof e==`number`)return{type:Number.isInteger(e)?`integer`:`number`,example:e};if(typeof e==`boolean`)return{type:`boolean`,example:e};if(e===null)return{}}insertRequestBodyParam(e,t){let n=t.path.length>0?t.path:[t.name],r=e;for(let[e,i]of n.slice(0,-1).entries())r.properties??={},r.properties[i]??={type:`object`},t.required&&(r.required=Array.from(new Set([...r.required??[],i]))),r=r.properties[i],r.type??=`object`,e===n.length-2&&t.required&&(r.required??=[]);let i=n[n.length-1]??t.name;r.properties??={},r.properties[i]=this.createParameterSchema(t),t.required&&(r.required=Array.from(new Set([...r.required??[],i])))}createParameter(e){return{name:e.name,in:e.in,required:e.in===`path`?!0:e.required,description:e.description??void 0,schema:this.createParameterSchema(e),example:e.defaultValue??void 0}}createParameterSchema(e){return{type:e.type??void 0,description:e.description??void 0,default:e.defaultValue??void 0}}createResponses(e,t){let n={};for(let r of e){if(!r.statusCode)continue;let e=t.filter(e=>e.statusCode===r.statusCode),i=this.createResponseContent(e);n[r.statusCode]={description:r.description??r.statusCode,...i?{content:i}:{}}}for(let e of t){if(!e.statusCode||n[e.statusCode])continue;let t=this.createResponseContent([e]);n[e.statusCode]={description:e.label??e.statusCode,...t?{content:t}:{}}}return n}createResponseContent(e){if(e.length===0)return;let t={};for(let n of e){let e=n.contentType??(n.format===`json`?`application/json`:`text/plain`),r=this.normalizeResponseExampleValue(n.body,n.format);t[e]={schema:this.inferSchemaFromBody(r,n.format),example:r}}return t}inferSchemaFromBody(e,t){if(t===`json`)return this.inferSchemaFromExample(e);if(t===`text`)return{type:`string`,example:e}}normalizeResponseExampleValue(e,t){return t!==`json`||typeof e!=`string`?e:w.parsePossiblyTruncated(e)??G(e)??e}resolveFallbackRequestBodyExample(e){return e.responseBodies.find(e=>e.format===`json`)?.body??(typeof e.responseExample==`object`&&e.responseExample!==null?e.responseExample:typeof e.responseExampleRaw==`string`?w.parsePossiblyTruncated(e.responseExampleRaw):typeof e.responseExample==`string`?w.parsePossiblyTruncated(e.responseExample):null)}createExampleSchema(e){return e==null?null:this.inferSchemaFromExample(e)??null}mergeOpenApiSchemas(e,t){if(!e)return t;if(!t)return e;let n={...t,...e,...e.type||t.type?{type:e.type??t.type}:{},...e.description||t.description?{description:e.description??t.description}:{},...e.default!==void 0||t.default!==void 0?{default:e.default??t.default}:{},...e.example!==void 0||t.example!==void 0?{example:e.example??t.example}:{}};if(e.properties||t.properties){let r=new Set([...Object.keys(e.properties??{}),...Object.keys(t.properties??{})]);n.properties=Object.fromEntries(Array.from(r).map(n=>[n,this.mergeOpenApiSchemas(e.properties?.[n]??null,t.properties?.[n]??null)??{}]))}return(e.items||t.items)&&(n.items=this.mergeOpenApiSchemas(e.items??null,t.items??null)??{}),(e.required||t.required)&&(n.required=Array.from(new Set([...t.required??[],...e.required??[]]))),n}buildOperationId(e,t){return`${e}${t.replace(/\{([^}]+)\}/g,`$1`).split(`/`).filter(Boolean).map(e=>e.replace(/[^a-zA-Z0-9]+/g,` `)).map(e=>e.trim()).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).replace(/\s+(.)/g,(e,t)=>t.toUpperCase())).join(``)}`}isOpenApiParameterLocation(e){return e===`query`||e===`header`||e===`path`||e===`cookie`}};var He=class extends s{signature=`generate
162
+ `)}renderIndexFile(e,t,n,r){let i=`${n.charAt(0).toLowerCase()}${n.slice(1)}`,a=[`import type { ${n}Api } from './Schema'`,`import { ${i}Manifest, ${i}Sdk } from './Schema'`,`import { createSdk as createBoundSdk } from '@oapiex/sdk-kit'`,`import type { AuthConfig, BaseApi as KitBaseApi, Core as KitCore, InitOptions } from '@oapiex/sdk-kit'`,``,`export * from './Schema'`];if(t!==`runtime`&&(a.push(`export { ApiBinder } from './ApiBinder'`),a.push(`export { BaseApi } from './BaseApi'`),a.push(...e.map(e=>`export { ${e} as ${e}Api } from './Apis/${e}'`)),a.push(`export { Core } from './Core'`)),a.push(``),a.push(`export const securitySchemes = ${i}Manifest.securitySchemes`),a.push(`export const security = ${i}Manifest.security`),r.securitySchemes.length>0){a.push(``);for(let e of r.securitySchemes)a.push(...this.renderSecurityHelper(e)),a.push(``)}return a.push(`export const createClient = (`),a.push(` options: InitOptions`),a.push(`): KitCore & { api: KitBaseApi & ${n}Api } =>`),a.push(` createBoundSdk(${i}Sdk, options) as KitCore & { api: KitBaseApi & ${n}Api }`),a.push(``),a.push(`export {`),a.push(` BadRequestException,`),a.push(` Builder,`),a.push(` ForbiddenRequestException,`),a.push(` Http,`),a.push(` HttpException,`),a.push(` UnauthorizedRequestException,`),a.push(` WebhookValidator,`),a.push(` createSdk,`),a.push(`} from '@oapiex/sdk-kit'`),a.push(``),a.push(`export type {`),a.push(` AuthConfig,`),a.push(` InitOptions,`),a.push(` UnifiedResponse,`),a.push(` XGenericObject,`),a.push(`} from '@oapiex/sdk-kit'`),a.join(`
163
+ `)}collectTypeIdentifiers(e){return Array.from(new Set((e.match(/\b[A-Z][A-Za-z0-9_]*/g)??[]).filter(e=>![`Record`,`Promise`].includes(e))))}renderSecurityHelper(e){return e.authType===`basic`?[`export const ${e.helperName} = (username: string, password: string): AuthConfig => ({`,` type: 'basic',`,` username,`,` password,`,`})`]:e.authType===`apiKey`?[`export const ${e.helperName} = (value: string): AuthConfig => ({`,` type: 'apiKey',`,` name: ${JSON.stringify(e.parameterName??e.name)},`,` value,`,` in: ${JSON.stringify(e.in??`header`)},`,`})`]:e.authType===`oauth2`?[`export const ${e.helperName} = (accessToken: string, tokenType = 'Bearer'): AuthConfig => ({`,` type: 'oauth2',`,` accessToken,`,` tokenType,`,`})`]:[`export const ${e.helperName} = (token: string): AuthConfig => ({`,` type: 'bearer',`,` token,`,...e.scheme&&e.scheme.toLowerCase()!==`bearer`?[` prefix: ${JSON.stringify(this.normalizeHttpAuthPrefix(e.scheme))},`]:[],`})`]}createSecurityHelperName(e){let t=this.typeBuilder.sanitizeTypeName(e);return t.endsWith(`Auth`)?`create${t}`:`create${t}Auth`}normalizeHttpAuthPrefix(e){return e.charAt(0).toUpperCase()+e.slice(1)}toConstantCase(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).replace(/[^A-Za-z0-9]+/g,`_`).replace(/^_+|_+$/g,``).toUpperCase()||`AUTH`}};const $=new class{createDocument(e,t=`Extracted API`,n=`0.0.0`){let r={};for(let t of e){let e=this.transformOperation(t);!e||this.shouldSkipNormalizedOperation(e)||(r[e.path]??={},r[e.path][e.method]=e.operation)}return{openapi:`3.1.0`,info:{title:t,version:n},paths:r}}transformOperation(e){if(!e.method||!e.url)return null;let t=new URL(e.url);if(this.shouldSkipPlaceholderOperation(t,e))return null;let n=e.method.toLowerCase(),r=this.decodeOpenApiPathname(t.pathname);return{path:r,method:n,operation:{summary:e.sidebarLinks.find(e=>e.active)?.label,description:e.description??void 0,operationId:this.buildOperationId(n,r),parameters:this.createParameters(e.requestParams),requestBody:this.createRequestBody(e.requestParams,e.requestExampleNormalized?.body,this.hasExtractedBodyParams(e.requestParams)?null:this.resolveFallbackRequestBodyExample(e)),responses:this.createResponses(e.responseSchemas,e.responseBodies)}}}shouldSkipNormalizedOperation(e){return e.path===`/`&&e.method===`get`&&e.operation.operationId===`get`&&Object.keys(e.operation.responses).length===0}shouldSkipPlaceholderOperation(e,t){return e.hostname!==`example.com`||e.pathname!==`/`?!1:t.requestParams.length===0&&t.responseSchemas.length===0&&t.responseBodies.length===0&&t.requestExampleNormalized?.url===`https://example.com/`}decodeOpenApiPathname(e){return e.split(`/`).map(e=>{if(!e)return e;try{return decodeURIComponent(e)}catch{return e}}).join(`/`)}hasExtractedBodyParams(e){return e.some(e=>e.in===`body`||e.in===null)}createParameters(e){let t=e.filter(e=>this.isOpenApiParameterLocation(e.in)).map(e=>this.createParameter(e));return t.length>0?t:void 0}createRequestBody(e,t,n){let r=e.filter(e=>e.in===`body`||e.in===null);if(r.length===0&&t==null)return;let i=this.buildRequestBodySchema(r,t,n);return{required:r.length>0?r.some(e=>e.required):!1,content:{"application/json":{schema:i,...t==null?{}:{example:t}}}}}buildRequestBodySchema(e,t,n){let r=this.mergeOpenApiSchemas(this.createExampleSchema(t),this.createExampleSchema(n))??{type:`object`};t==null?n!=null&&(r.example=n):r.example=t;for(let t of e)this.insertRequestBodyParam(r,t);return r}inferSchemaFromExample(e){if(Array.isArray(e))return{type:`array`,items:this.inferSchemaFromExample(e[0])??{},example:e};if(T(e))return{type:`object`,properties:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,this.inferSchemaFromExample(t)??{}])),example:e};if(typeof e==`string`)return{type:`string`,example:e};if(typeof e==`number`)return{type:Number.isInteger(e)?`integer`:`number`,example:e};if(typeof e==`boolean`)return{type:`boolean`,example:e};if(e===null)return{}}insertRequestBodyParam(e,t){let n=t.path.length>0?t.path:[t.name],r=e;for(let[e,i]of n.slice(0,-1).entries())r.properties??={},r.properties[i]??={type:`object`},t.required&&(r.required=Array.from(new Set([...r.required??[],i]))),r=r.properties[i],r.type??=`object`,e===n.length-2&&t.required&&(r.required??=[]);let i=n[n.length-1]??t.name;r.properties??={},r.properties[i]=this.createParameterSchema(t),t.required&&(r.required=Array.from(new Set([...r.required??[],i])))}createParameter(e){return{name:e.name,in:e.in,required:e.in===`path`?!0:e.required,description:e.description??void 0,schema:this.createParameterSchema(e),example:e.defaultValue??void 0}}createParameterSchema(e){return{type:e.type??void 0,description:e.description??void 0,default:e.defaultValue??void 0}}createResponses(e,t){let n={};for(let r of e){if(!r.statusCode)continue;let e=t.filter(e=>e.statusCode===r.statusCode),i=this.createResponseContent(e);n[r.statusCode]={description:r.description??r.statusCode,...i?{content:i}:{}}}for(let e of t){if(!e.statusCode||n[e.statusCode])continue;let t=this.createResponseContent([e]);n[e.statusCode]={description:e.label??e.statusCode,...t?{content:t}:{}}}return n}createResponseContent(e){if(e.length===0)return;let t={};for(let n of e){let e=n.contentType??(n.format===`json`?`application/json`:`text/plain`),r=this.normalizeResponseExampleValue(n.body,n.format);t[e]={schema:this.inferSchemaFromBody(r,n.format),example:r}}return t}inferSchemaFromBody(e,t){if(t===`json`)return this.inferSchemaFromExample(e);if(t===`text`)return{type:`string`,example:e}}normalizeResponseExampleValue(e,t){return t!==`json`||typeof e!=`string`?e:w.parsePossiblyTruncated(e)??G(e)??e}resolveFallbackRequestBodyExample(e){return e.responseBodies.find(e=>e.format===`json`)?.body??(typeof e.responseExample==`object`&&e.responseExample!==null?e.responseExample:typeof e.responseExampleRaw==`string`?w.parsePossiblyTruncated(e.responseExampleRaw):typeof e.responseExample==`string`?w.parsePossiblyTruncated(e.responseExample):null)}createExampleSchema(e){return e==null?null:this.inferSchemaFromExample(e)??null}mergeOpenApiSchemas(e,t){if(!e)return t;if(!t)return e;let n={...t,...e,...e.type||t.type?{type:e.type??t.type}:{},...e.description||t.description?{description:e.description??t.description}:{},...e.default!==void 0||t.default!==void 0?{default:e.default??t.default}:{},...e.example!==void 0||t.example!==void 0?{example:e.example??t.example}:{}};if(e.properties||t.properties){let r=new Set([...Object.keys(e.properties??{}),...Object.keys(t.properties??{})]);n.properties=Object.fromEntries(Array.from(r).map(n=>[n,this.mergeOpenApiSchemas(e.properties?.[n]??null,t.properties?.[n]??null)??{}]))}return(e.items||t.items)&&(n.items=this.mergeOpenApiSchemas(e.items??null,t.items??null)??{}),(e.required||t.required)&&(n.required=Array.from(new Set([...t.required??[],...e.required??[]]))),n}buildOperationId(e,t){return`${e}${t.replace(/\{([^}]+)\}/g,`$1`).split(`/`).filter(Boolean).map(e=>e.replace(/[^a-zA-Z0-9]+/g,` `)).map(e=>e.trim()).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).replace(/\s+(.)/g,(e,t)=>t.toUpperCase())).join(``)}`}isOpenApiParameterLocation(e){return e===`query`||e===`header`||e===`path`||e===`cookie`}};var He=class extends s{signature=`generate
111
164
  {artifact : Artifact to generate [sdk]}
112
165
  {source? : Documentation URL/local source or parsed TypeScript output file}
113
166
  {--d|dir? : Output directory for the generated artifact}