@bitstack/ng-query-codegen-openapi 0.0.30

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.
Files changed (45) hide show
  1. package/README.md +77 -0
  2. package/lib/bin/cli.mjs +186 -0
  3. package/lib/bin/cli.mjs.map +1 -0
  4. package/lib/index.d.mts +191 -0
  5. package/lib/index.d.ts +191 -0
  6. package/lib/index.js +1392 -0
  7. package/lib/index.js.map +1 -0
  8. package/lib/index.mjs +1376 -0
  9. package/lib/index.mjs.map +1 -0
  10. package/package.json +91 -0
  11. package/src/bin/cli.ts +77 -0
  12. package/src/bin/utils.ts +85 -0
  13. package/src/generators/api-service-generator.ts +112 -0
  14. package/src/generators/cache-keys-generator.ts +43 -0
  15. package/src/generators/common-types-generator.ts +33 -0
  16. package/src/generators/component-schema-generator.ts +25 -0
  17. package/src/generators/do-not-modify-generator.ts +27 -0
  18. package/src/generators/index-generator.ts +11 -0
  19. package/src/generators/query-service-generator.ts +108 -0
  20. package/src/generators/types-generator.ts +285 -0
  21. package/src/generators/utils-generator.ts +33 -0
  22. package/src/index.ts +21 -0
  23. package/src/services/api-code-generator.ts +157 -0
  24. package/src/services/api-service-generator.ts +24 -0
  25. package/src/services/endpoint-info-extractor.ts +119 -0
  26. package/src/services/file-writer-service.ts +148 -0
  27. package/src/services/group-service.ts +84 -0
  28. package/src/services/openapi-parser-service.ts +72 -0
  29. package/src/services/openapi-service.ts +61 -0
  30. package/src/services/query-code-generator.ts +24 -0
  31. package/src/services/unified-code-generator.ts +353 -0
  32. package/src/types.ts +248 -0
  33. package/src/utils/capitalize.ts +3 -0
  34. package/src/utils/directory.ts +75 -0
  35. package/src/utils/downloadSchema.ts +33 -0
  36. package/src/utils/factory.ts +29 -0
  37. package/src/utils/getOperationDefinitions.ts +20 -0
  38. package/src/utils/getV3Doc.ts +24 -0
  39. package/src/utils/http.ts +86 -0
  40. package/src/utils/index.ts +9 -0
  41. package/src/utils/isQuery.ts +16 -0
  42. package/src/utils/isValidUrl.ts +9 -0
  43. package/src/utils/messages.ts +7 -0
  44. package/src/utils/prettier.ts +51 -0
  45. package/src/utils/removeUndefined.ts +3 -0
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/rtk-incubator/rtk-query/main/logo.png" width="400" />
3
+ </p>
4
+ <h2 align="center">
5
+ Code Generator
6
+ </h2>
7
+
8
+ <p align="center">
9
+ <a href="https://discord.gg/0ZcbPKXt5bZ6au5t" target="_blank">
10
+ <img src="https://img.shields.io/badge/chat-online-green" alt="Discord server" />
11
+ </a>
12
+ </p>
13
+
14
+ ### Introduction
15
+
16
+ This is a utility library meant to be used with [RTK Query](https://redux-toolkit.js.org/rtk-query/overview) that will generate a typed API client from an OpenAPI schema.
17
+
18
+ ### Features
19
+
20
+ - **Local Schema File Support**: Direct processing of local schema files via `schemaFile`
21
+ - **Remote Schema Download**: Download remote schemas to local files via `remoteFile` and `schemaFile`
22
+ - **Type Generation**: Generates TypeScript types from OpenAPI schemas
23
+ - **RTK Query Integration**: Seamless integration with RTK Query
24
+
25
+ ### Configuration Options
26
+
27
+ - `schemaFile`: The local OpenAPI schema file path (required)
28
+ - `remoteFile`: (Optional) Remote schema URL to download to `schemaFile` path
29
+ - `outputFile`: The output file path for generated code
30
+ - `apiFile`: The base API file path
31
+
32
+ ### Example Configuration
33
+
34
+ ```typescript
35
+ // For remote schemas with download
36
+ {
37
+ schemaFile: './schemas/api-schema.json',
38
+ remoteFile: 'https://api.example.com/openapi.json',
39
+ apiFile: './baseApi',
40
+ outputFile: './generated-api.ts'
41
+ }
42
+
43
+ // For local schema files
44
+ {
45
+ schemaFile: './schemas/api-schema.json',
46
+ apiFile: './baseApi',
47
+ outputFile: './generated-api.ts'
48
+ }
49
+ ```
50
+
51
+ ### Documentation
52
+
53
+ [View the RTK Query Code Generation docs](https://redux-toolkit.js.org/rtk-query/usage/code-generation)
54
+
55
+ ### Test
56
+
57
+ ```bash
58
+ npm run build && npx bitstack-ng-query-codegen-openapi ./rtk-query-codegen.config.ts
59
+ npm run build && npx bitstack-ng-query-codegen-openapi ./rtk-query-codegen-slice.config.ts
60
+ rm -rf test_output3/* && node lib/bin/cli.mjs rtk-query-codegen-slice.config.ts
61
+ ```
62
+
63
+ new
64
+
65
+ ```bash
66
+ npm run cli ./rtk-query-codegen-slice.config.ts
67
+ ```
68
+
69
+
70
+
71
+ ## Step
72
+
73
+ 1. [endpoint-generator] EndpointGenerator.generateEndpoints....
74
+ 2. [endpoint-generator] EndpointGenerator.generateForGroup.......
75
+ 2.1. [generate-new] generateApi........
76
+ 2. [endpoint-generator] EndpointGenerator.generateForGroup.......
77
+ 2.1. [generate-new] generateApi........
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env node
2
+ var K=Object.defineProperty;var Ne=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var Se=Object.prototype.hasOwnProperty;var V=(r,t)=>()=>(r&&(t=r(r=0)),t);var Te=(r,t)=>{for(var e in t)K(r,e,{get:t[e],enumerable:!0})},Pe=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Ae(t))!Se.call(r,o)&&o!==e&&K(r,o,{get:()=>t[o],enumerable:!(n=Ne(t,o))||n.enumerable});return r};var $e=r=>Pe(K({},"__esModule",{value:!0}),r);import{fileURLToPath as Ee}from"node:url";var Fe,m,s=V(()=>{"use strict";Fe=()=>Ee(import.meta.url),m=Fe()});var ne={};Te(ne,{argumentMatches:()=>ke,defaultIsDataResponse:()=>Qe,getOperationName:()=>A,getOverrides:()=>G,getTags:()=>Ue,operationMatches:()=>re});import{getOperationName as Ve}from"oazapfts/generate";function Qe(r,t){if(t&&r==="default")return!0;let e=Number(r);return!Number.isNaN(e)&&e>=200&&e<300}function A({verb:r,path:t}){return Ve(r,t,void 0)}function Ue({verb:r,pathItem:t}){return r?t[r]?.tags||[]:[]}function te(r){let t=Array.isArray(r)?r:[r];return function(n){return r?t.some(o=>typeof o=="string"?o===n:o?.test(n)):!0}}function re(r){let t=typeof r=="function"?r:te(r);return function(n){if(!r)return!0;let o=A(n);return t(o,n)}}function ke(r){let t=typeof r=="function"?r:te(r);return function(n){if(!r||n.in==="path")return!0;let o=n.name;return t(o,n)}}function G(r,t){return t?.find(e=>re(e.pattern)(r))}var I=V(()=>{"use strict";s()});s();import R from"commander";import{createRequire as Ye}from"node:module";s();import Re from"commander";import{createRequire as we}from"node:module";import{resolve as Q}from"node:path";import{existsSync as Ke,rmSync as qe}from"node:fs";var d=we(m);function U(r){let t=["/","/usr","/etc","/var","/home","/Users",".",".."],e=Q(r);t.some(n=>e===Q(n))&&(console.error(`Dangerous path detected: ${e}. Refusing to delete.`),process.exit(1)),Ke(r)&&(console.log(`Cleaning output directory: ${r}`),qe(r,{recursive:!0,force:!0}),console.log(`Directory cleaned: ${r}`))}function k(){try{if(d.resolve("esbuild")&&d.resolve("esbuild-runner"))return d("esbuild-runner/register"),!0}catch{}try{if(d.resolve("typescript")&&d.resolve("ts-node"))return d("ts-node").register({transpileOnly:!0,compilerOptions:{target:"es6",module:"commonjs"}}),!0}catch{}return!1}function W(r){(!r||!/\.([mc]?(jsx?|tsx?)|jsonc?)?$/.test(r))&&(console.error("Please provide a valid configuration file."),Re.help())}function _(r,t){/\.[mc]?tsx?$/.test(r)&&!t&&(console.error("Encountered a TypeScript config file, but neither esbuild-runner nor ts-node are installed."),process.exit(1))}import{dirname as Ze,resolve as Je}from"node:path";s();s();import D from"node:path";import he from"typescript";s();s();function b(r){return r.replace(r[0],r[0].toUpperCase())}s();import q from"node:fs";import Ge from"node:path";s();function L(r){try{new URL(r)}catch{return!1}return!0}async function z(r,t){if(!L(r))throw new Error(`remoteFile must be a valid URL: ${r}`);try{let e=Ge.dirname(t);q.existsSync(e)||await q.promises.mkdir(e,{recursive:!0});let n=await fetch(r);if(!n.ok)throw new Error(`Failed to download schema from ${r}: ${n.statusText}`);let o=await n.text();return await q.promises.writeFile(t,o,"utf-8"),console.log(`Schema downloaded from ${r} to ${t}`),t}catch(e){throw console.error(`Error downloading schema from ${r}:`,e),e}}s();s();var B=["get","put","post","delete","options","head","patch","trace"];function H(r){return Object.entries(r.paths).flatMap(([t,e])=>e?Object.entries(e).filter(n=>B.includes(n[0])).map(([n,o])=>({path:t,verb:n,pathItem:e,operation:o})):[])}s();import Ie from"@apidevtools/swagger-parser";import De from"swagger2openapi";async function Y(r,t){let e=await Ie.bundle(r,{resolve:{http:t}});return"openapi"in e&&e.openapi.startsWith("3")?e:(await De.convertObj(e,{})).openapi}s();function Z(r,t,e,n){return n?n(r,t):e?.type?e.type==="query":r==="get"}var x=class{docCache={};async getDocument(t,e){if(this.docCache[t])return this.docCache[t];let n=await Y(t,e);return this.docCache[t]=n,n}async downloadSchema(t,e){return z(t,e)}getPaths(t){return Object.keys(t.paths||{})}clearCache(){this.docCache={}}};s();import J from"lodash.camelcase";var C=class{groupPaths(t,e){let{groupKeyMatch:n,outputDir:o}=e,p=t.reduce((c,u)=>{let i=n(u),g=i?J(i):"_common";return c[g]||(c[g]=[]),c[g].push(u),c},{}),a={};for(let[c,u]of Object.entries(p))a[c]={groupKey:c,paths:u,outputPath:`${o}/${c}/query.service.ts`};return a}createGroupFilter(t,e){return(n,o)=>{let p=o.path,a=J(e.groupKeyMatch(p)||"");return a!==t&&(a||"_common")!==t?!1:e.filterEndpoint?e.filterEndpoint(n,p,t):!0}}};s();import Me from"node:fs";import h from"node:path";s();import je from"node:path";import X from"node:fs";async function ee(r){let t=je.dirname(r);X.existsSync(t)||await X.promises.mkdir(t,{recursive:!0})}var N=class{async writeFile(t,e){try{let n=h.resolve(process.cwd(),t);return await ee(n),Me.writeFileSync(n,e),{path:n,success:!0}}catch(n){return{path:t,success:!1,error:n}}}async writeFiles(t){let e=[];for(let[n,o]of Object.entries(t)){let p=await this.writeFile(n,o);e.push(p)}return e}async writeGroupFiles(t,e){let n={};return e.types&&(n[h.join(t,"types.ts")]=e.types),e.apiService&&(n[h.join(t,"api.service.ts")]=e.apiService),e.queryService&&(n[h.join(t,"query.service.ts")]=e.queryService),e.index&&(n[h.join(t,"index.ts")]=e.index),this.writeFiles(n)}async writeSharedFiles(t,e){let n={};return e.commonTypes&&(n[h.join(t,"common-types.ts")]=e.commonTypes),e.cacheKeys&&(n[h.join(t,"cache-keys.ts")]=e.cacheKeys),e.doNotModify&&(n[h.join(t,"DO_NOT_MODIFY.md")]=e.doNotModify),e.utils&&(n[h.join(t,"utils.ts")]=e.utils),this.writeFiles(n)}async writeSchemaFile(t,e){let n={};return n[h.join(t,"schema.ts")]=e,this.writeFiles(n)}};s();import We from"oazapfts/generate";var S=class{constructor(t,e){this.v3Doc=t;this.apiGen=new We(t,{unionUndefined:e.unionUndefined,useEnumType:e.useEnumType,mergeReadWriteOnly:e.mergeReadWriteOnly})}apiGen;initialize(){this.apiGen.spec.components?.schemas&&(this.apiGen.preprocessComponents(this.apiGen.spec.components.schemas),Object.keys(this.apiGen.spec.components.schemas).forEach(t=>{try{this.apiGen.getRefAlias({$ref:`#/components/schemas/${t}`})}catch{}}))}getOperationDefinitions(t){let{operationMatches:e}=(I(),$e(ne));return H(this.v3Doc).filter(e(t))}getApiGenerator(){return this.apiGen}getDocument(){return this.v3Doc}getSchemaTypeNames(){return new Set}};s();s();function oe(){return`/* eslint-disable */
3
+ // [Warning] Generated automatically - do not edit manually
4
+
5
+ /**
6
+ * Clear undefined in object
7
+ */
8
+ export function withoutUndefined(obj?: Record<string, any>) {
9
+ if(typeof obj === 'undefined') return;
10
+ return Object.fromEntries(
11
+ Object.entries(obj).filter(([_, v]) => v !== undefined && v !== null)
12
+ );
13
+ }
14
+
15
+ `}function ie(r){return r.toLowerCase().replace(/_([a-z])/g,(t,e)=>e.toUpperCase())}function se(r){let t=r.reduce((n,o)=>(n[o.groupKey]||(n[o.groupKey]=[]),n[o.groupKey].push({operationName:o.operationName,queryKeyName:o.queryKeyName}),n),{});return`// [Warning] Generated automatically - do not edit manually
16
+
17
+ /**
18
+ * Cache keys enum for all API queries
19
+ */
20
+ export enum ECacheKeys {
21
+ ${Object.entries(t).map(([n,o])=>{let p=` // ${n.charAt(0).toUpperCase()+n.slice(1)} related cache keys`,a=o.map(c=>` ${c.queryKeyName} = '${ie(c.queryKeyName)}',`).join(`
22
+ `);return`${p}
23
+ ${a}`}).join(`
24
+
25
+ `)}
26
+ }
27
+
28
+ export default ECacheKeys;
29
+ `}s();function ae(){return`/* eslint-disable */
30
+ // [Warning] Generated automatically - do not edit manually
31
+
32
+ export interface RequestOptions {
33
+ headers?: Record<string, string>;
34
+ observe?: 'body' | 'events' | 'response';
35
+ responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
36
+ reportProgress?: boolean;
37
+ withCredentials?: boolean;
38
+ timeout?: number;
39
+ }
40
+
41
+ export interface QueryConfig {
42
+ refetchOnMountOrArgChange?: boolean|number,
43
+ keepUnusedDataFor?: number,
44
+ }
45
+
46
+ export type IRestFulEndpointsQueryReturn<TVariables> = TVariables extends void ?
47
+ void | {fetchOptions?: RequestOptions;config?: QueryConfig;}:
48
+ {
49
+ variables: TVariables;
50
+ fetchOptions?: RequestOptions;
51
+ config?: QueryConfig;
52
+ };
53
+ `}s();import v from"typescript";function pe(r){let t=v.createPrinter({newLine:v.NewLineKind.LineFeed}),e=v.createSourceFile("component-schema.ts","",v.ScriptTarget.Latest,!1,v.ScriptKind.TS);return`/* eslint-disable */
54
+ // [Warning] Generated automatically - do not edit manually
55
+
56
+ ${Object.values(r).map(n=>t.printNode(v.EmitHint.Unspecified,n,e)).join(`
57
+ `)}
58
+ `}s();function ce(){return`# \u8ACB\u52FF\u4FEE\u6539\u6B64\u8CC7\u6599\u593E
59
+
60
+ \u26A0\uFE0F **\u91CD\u8981\u63D0\u9192\uFF1A\u8ACB\u52FF\u4FEE\u6539\u6B64\u8CC7\u6599\u593E\u4E2D\u7684\u4EFB\u4F55\u6A94\u6848**
61
+
62
+ \u6B64\u8CC7\u6599\u593E\u4E2D\u7684\u6240\u6709\u6A94\u6848\u90FD\u662F\u900F\u904E\u7A0B\u5F0F\u78BC\u7522\u751F\u5668\u81EA\u52D5\u7522\u751F\u7684\u3002\u4EFB\u4F55\u624B\u52D5\u4FEE\u6539\u7684\u5167\u5BB9\u5728\u4E0B\u6B21\u91CD\u65B0\u7522\u751F\u6642\u90FD\u5C07\u6703\u88AB\u8986\u84CB\u3002
63
+
64
+ ## \u5982\u4F55\u4FEE\u6539\u9019\u4E9B\u6A94\u6848\uFF1F
65
+
66
+ \u5982\u679C\u60A8\u9700\u8981\u4FEE\u6539\u9019\u4E9B\u6A94\u6848\u7684\u5167\u5BB9\uFF0C\u8ACB\uFF1A
67
+
68
+ 1. \u4FEE\u6539\u76F8\u5C0D\u61C9\u7684\u8A2D\u5B9A\u6A94\u6848\u6216\u6A21\u677F
69
+ 2. \u91CD\u65B0\u57F7\u884C\u7A0B\u5F0F\u78BC\u7522\u751F\u5668
70
+ 3. \u8B93\u7522\u751F\u5668\u81EA\u52D5\u66F4\u65B0\u9019\u4E9B\u6A94\u6848
71
+
72
+ ## \u7522\u751F\u5668\u76F8\u95DC\u8CC7\u8A0A
73
+
74
+ \u9019\u4E9B\u6A94\u6848\u662F\u7531 @bitstack/ng-query-codegen-openapi \u7522\u751F\u5668\u6240\u5EFA\u7ACB\u3002
75
+
76
+ \u5982\u6709\u7591\u554F\uFF0C\u8ACB\u53C3\u8003\u5C08\u6848\u6587\u4EF6\u6216\u806F\u7E6B\u958B\u767C\u5718\u968A\u3002
77
+ `}s();import fe from"typescript";s();I();import{supportDeepObjects as _e}from"oazapfts/generate";var T=class{constructor(t){this.options=t}extractEndpointInfos(t){return t.map(e=>this.extractSingleEndpointInfo(e))}extractSingleEndpointInfo(t){let{verb:e,path:n,operation:o}=t,{operationNameSuffix:p="",argSuffix:a="Req",responseSuffix:c="Res",queryMatch:u,endpointOverrides:i}=this.options,g=A({verb:e,path:n}),l=p?b(g+p):g,w=b(g+p+a),f=b(g+p+c),j=Z(e,n,G(t,i),u),M=`${g.replace(/([A-Z])/g,"_$1").toUpperCase()}`,Oe=o.summary||`${e.toUpperCase()} ${n}`,{queryParams:be,pathParams:xe,isVoidArg:Ce}=this.extractParameters(t);return{operationName:l,argTypeName:w,responseTypeName:f,isQuery:j,verb:e.toUpperCase(),path:n,queryKeyName:M,queryParams:be,pathParams:xe,isVoidArg:Ce,summary:Oe}}extractParameters(t){let{operation:e,pathItem:n}=t,o=this.resolveArray(e.parameters),p=this.resolveArray(n.parameters).filter(g=>!o.some(l=>l.name===g.name&&l.in===g.in)),a=_e([...p,...o]).filter(g=>g.in!=="header"),c=a.filter(g=>g.in==="query"),u=a.filter(g=>g.in==="path"),i=c.length===0&&u.length===0&&!e.requestBody;return{queryParams:c,pathParams:u,isVoidArg:i}}resolveArray(t){return t?Array.isArray(t)?t:[t]:[]}};s();function me(r,t,e,n){let o=`/* eslint-disable */
78
+ // [Warning] Generated automatically - do not edit manually
79
+
80
+ `;e&&Object.keys(e).length>0&&(o+=`import * as Schema from "../schema";
81
+ `),o+=`
82
+ `;let a=[],c=[];return r.forEach(u=>{let i=u.argTypeName,g=u.responseTypeName;if(i){let l=Le(u,n);l.trim()===""||l.includes("TODO")||l.includes("[key: string]: any")?c.push(`export type ${i} = void;`,""):c.push(`export type ${i} = {`,l,"};","")}if(g){let l=ze(u,n);l.trim()===""||l.includes("TODO")||l.includes("[key: string]: any")?c.push(`export type ${g} = void;`,""):c.push(`export type ${g} = {`,l,"};","")}}),c.length>0&&a.push(c.join(`
83
+ `)),a.length===0&&a.push("// \u6B64\u6A94\u6848\u7528\u65BC\u5B9A\u7FA9 API \u76F8\u95DC\u7684\u985E\u578B","// \u985E\u578B\u5B9A\u7FA9\u6703\u6839\u64DA OpenAPI Schema \u81EA\u52D5\u751F\u6210",""),o+a.join(`
84
+
85
+ `)}function Le(r,t){let e=[];r.queryParams&&r.queryParams.length>0&&r.queryParams.forEach(o=>{let p=o.required?"":"?",a=ue(o);e.push(` ${o.name}${p}: ${a};`)}),r.pathParams&&r.pathParams.length>0&&r.pathParams.forEach(o=>{let p=o.required?"":"?",a=ue(o);e.push(` ${o.name}${p}: ${a};`)});let n=t?.find(o=>o.operation?.operationId===r.operationName||o.operation?.operationId===r.operationName.toLowerCase()||o.verb===r.verb.toLowerCase()&&o.path===r.path);if(n?.operation?.requestBody){let p=n.operation.requestBody.content,a=p["application/json"],c=p["multipart/form-data"]||p["application/x-www-form-urlencoded"];if(a?.schema){let u=O(a.schema);e.push(` body: ${u};`)}else if(c?.schema){let u=O(c.schema);e.push(` body: ${u};`)}else e.push(" body?: any; // Request body from OpenAPI")}return e.length===0?"":e.join(`
86
+ `)}function ze(r,t){let e=[],n=t?.find(o=>o.operation?.operationId===r.operationName||o.operation?.operationId===r.operationName.toLowerCase()||o.verb===r.verb.toLowerCase()&&o.path===r.path);if(n?.operation?.responses){let o=n.operation.responses[200]||n.operation.responses[201];if(o?.content){let p=o.content["application/json"];if(p?.schema){let a=Be(p.schema);e.push(...a)}else e.push(" // Success response from OpenAPI"),e.push(" data?: any;")}}return e.length===0?"":e.join(`
87
+ `)}function Be(r){let t=[];if(r.type==="object"&&r.properties){let e=r.required||[];Object.entries(r.properties).forEach(([n,o])=>{let a=e.includes(n)?"":"?",c=O(o),u=o.description?` // ${o.description}`:"";t.push(` ${n}${a}: ${c};${u}`)})}return t}function O(r){if(!r)return"any";if(r.$ref){let t=r.$ref;if(t.startsWith("#/components/schemas/"))return`Schema.${t.replace("#/components/schemas/","")}`}switch(r.type){case"string":return r.enum?r.enum.map(e=>`"${e}"`).join(" | "):"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"array":return`${r.items?O(r.items):"any"}[]`;case"object":return r.properties?`{ ${Object.entries(r.properties).map(([n,o])=>{let a=(r.required||[]).includes(n)?"":"?",c=O(o);return`${n}${a}: ${c}`}).join("; ")} }`:"any";default:return"any"}}function ue(r){return r.schema?O(r.schema):"any"}s();function ye(r,t){let{groupKey:e}=t;return`export * from './types';
88
+ export * from './api.service';
89
+ export * from './query.service';
90
+ `}s();s();function ge(r,t){let{groupKey:e,refetchOnMountOrArgChange:n=60}=t,o=e?`${e.charAt(0).toUpperCase()+e.slice(1)}QueryService`:"QueryService",p=e?`${e.charAt(0).toUpperCase()+e.slice(1)}ApiService`:"ApiService",a=r.filter(i=>i.isQuery).map(i=>`
91
+ /**
92
+ * ${i.summary}
93
+ */
94
+ ${i.operationName}Query(${i.argTypeName!=="VoidApiArg"?`args: IRestFulEndpointsQueryReturn<${i.argTypeName}>`:""}): Observable<QueryState<${i.responseTypeName}>> {
95
+ return this.ntkQuery.query<${i.responseTypeName}, ${i.argTypeName!=="VoidApiArg"?`IRestFulEndpointsQueryReturn<${i.argTypeName}>`:"void"}>({
96
+ queryKey: [ECacheKeys.${i.queryKeyName}${i.argTypeName!=="VoidApiArg"?", args.variables":""}],
97
+ queryFn: () => {
98
+ return this.apiService.${i.operationName}(${i.argTypeName!=="VoidApiArg"?"args":""});
99
+ },
100
+ fetchOptions: args?.fetchOptions,
101
+ config: args?.config,
102
+ })${i.argTypeName!=="VoidApiArg"?"(args)":"()"};
103
+ }`).join(""),c=r.filter(i=>!i.isQuery).map(i=>`
104
+ /**
105
+ * ${i.summary}
106
+ */
107
+ ${i.operationName}Mutation(): MutationResponse<${i.responseTypeName}, {
108
+ variables: ${i.argTypeName!=="VoidApiArg"?i.argTypeName:"void"};
109
+ fetchOptions?: RequestOptions;
110
+ }, HttpErrorResponse> {
111
+ return this.ntkQuery.mutation<${i.responseTypeName}, ${i.argTypeName!=="VoidApiArg"?`IRestFulEndpointsQueryReturn<${i.argTypeName}>`:"void"}, HttpErrorResponse>({
112
+ endpointName: '${i.operationName}',
113
+ mutationFn: (${i.argTypeName!=="VoidApiArg"?"args":""}) => {
114
+ return this.apiService.${i.operationName}(${i.argTypeName!=="VoidApiArg"?"args":""});
115
+ },
116
+ });
117
+ }`).join(""),u=r.filter(i=>i.isQuery).map(i=>`
118
+ /**
119
+ * ${i.summary}
120
+ */
121
+ ${i.operationName}LazyQuery(): {
122
+ trigger: (${i.argTypeName!=="VoidApiArg"?`args: IRestFulEndpointsQueryReturn<${i.argTypeName}>, `:""}options?: { skipCache?: boolean }) => Observable<${i.responseTypeName}>
123
+ } {
124
+ return {
125
+ trigger: (${i.argTypeName!=="VoidApiArg"?"args, ":""}options = {}) => {
126
+ const { skipCache = true } = options;
127
+ if (!skipCache) {
128
+ const cachedResult = this.ntkQuery.getQueryCache<${i.responseTypeName}>([ECacheKeys.${i.queryKeyName}${i.argTypeName!=="VoidApiArg"?", args.variables":""}]);
129
+ if (cachedResult) {
130
+ return cachedResult;
131
+ }
132
+ }
133
+ return this.apiService.${i.operationName}(${i.argTypeName!=="VoidApiArg"?"args":""});
134
+ }
135
+ };
136
+ }`).join("");return`/* eslint-disable */
137
+ // [Warning] Generated automatically - do not edit manually
138
+
139
+ import {Injectable, inject} from '@angular/core';
140
+ import {Observable} from 'rxjs';
141
+ import {HttpErrorResponse} from '@angular/common/http';
142
+ import {NtkQueryService, MutationState, QueryState, MutationResponse} from '@core/ntk-query';
143
+ import {ECacheKeys} from '../cache-keys';
144
+ import {${p}} from './api.service';
145
+ import {IRestFulEndpointsQueryReturn, RequestOptions} from '../common-types';
146
+ import {${r.map(i=>` ${i.argTypeName}, ${i.responseTypeName}`).join(",")}} from './types';
147
+
148
+ @Injectable({
149
+ providedIn: 'root',
150
+ })
151
+ export class ${o} {
152
+ private apiService = inject(${p});
153
+ private ntkQuery = inject(NtkQueryService);
154
+ ${a}${c}${u}
155
+ }
156
+ `}var P=class{constructor(t){this.options=t}generateQueryService(t){let e={...this.options,apiConfiguration:this.options.apiConfiguration||{file:"@/store/webapi",importName:"WebApiConfiguration"}};return ge(t,e)}};s();s();function le(r,t){let{apiConfiguration:e,httpClient:n,groupKey:o}=t,p=o?`${o.charAt(0).toUpperCase()+o.slice(1)}ApiService`:"ApiService";return`/* eslint-disable */
157
+ // [Warning] Generated automatically - do not edit manually
158
+
159
+ import { ${n.importName} } from '${n.file}';
160
+ import { Injectable, inject } from '@angular/core';
161
+ import { Observable } from 'rxjs';
162
+ import { ${e.importName} } from '${e.file}';
163
+ import { RequestOptions, IRestFulEndpointsQueryReturn } from '../common-types';
164
+ import { withoutUndefined } from '../utils';
165
+ import {${r.map(a=>` ${a.argTypeName}, ${a.responseTypeName}`).join(",")} } from './types';
166
+
167
+ @Injectable({
168
+ providedIn: 'root',
169
+ })
170
+ export class ${p} {
171
+ private config = inject(${e.importName});
172
+ private http = inject(${n.importName});
173
+
174
+ ${r.map(a=>{let c=a.verb.toUpperCase()==="GET",u=a.argTypeName!=="VoidApiArg",i=f=>f.includes("{")&&u?`\`\${this.config.rootUrl}${f.replace(/\{([^}]+)\}/g,"${args.variables.$1}")}\``:`\`\${this.config.rootUrl}${f}\``,g=a.queryParams.length>0,l=!c&&u&&!a.isVoidArg,w=()=>{let f=["...args.fetchOptions"];return(l||!c)&&f.push("headers: { 'Content-Type': 'application/json', ...args.fetchOptions?.headers }"),g&&u&&f.push(He(a.queryParams)),l&&f.push("body: args.variables.body"),f.length>0?`{ ${f.join(", ")} }`:"{}"};return`
175
+ /**
176
+ * ${a.summary}
177
+ */
178
+ ${a.operationName}(
179
+ ${u?`args: IRestFulEndpointsQueryReturn<${a.argTypeName}>, `:""}
180
+ ): Observable<${a.responseTypeName}> {
181
+ const url = ${i(a.path)};
182
+ return this.http.request('${a.verb.toLowerCase()}', url, ${w()});
183
+ }`}).join("")}
184
+ }
185
+ `}function He(r){return`params: withoutUndefined({ ${r.map(e=>`${e.name}: args.variables.${e.name}`).join(", ")} })`}var $=class{constructor(t){this.options=t}generateApiService(t){let e={...this.options,apiConfiguration:this.options.apiConfiguration||{file:"@/store/webapi",importName:"WebApiConfiguration"}};return le(t,e)}};var E=class{constructor(t,e){this.parserService=t;this.options=e;this.infoExtractor=new T(e),this.queryGenerator=new P(e),this.apiServiceGenerator=new $(e)}infoExtractor;queryGenerator;apiServiceGenerator;async generate(){let t=this.parserService.getOperationDefinitions(this.options.filterEndpoints),e=this.infoExtractor.extractEndpointInfos(t),n=this.generateTypes(e),o=this.generateApiService(e),p=this.generateQueryService(e),a=this.generateIndex(),c=e.filter(i=>i.isQuery).map(i=>({operationName:i.operationName,queryKeyName:i.queryKeyName,groupKey:this.options.groupKey||"_common"}));return{operationNames:e.map(i=>i.operationName),files:{types:n,apiService:o,queryService:p,index:a,allEndpointCacheKeys:c}}}generateTypes(t){let e={...this.options,apiConfiguration:this.options.apiConfiguration||{file:"@/store/webapi",importName:"WebApiConfiguration"}},o=this.parserService.getApiGenerator().aliases.reduce((a,c)=>{if(fe.isInterfaceDeclaration(c)||fe.isTypeAliasDeclaration(c)){let u=c.name.text;return{...a,[u]:c}}return a},{}),p=this.parserService.getOperationDefinitions(this.options.filterEndpoints);return me(t,e,o,p)}generateApiService(t){return this.apiServiceGenerator.generateApiService(t)}generateQueryService(t){return this.queryGenerator.generateQueryService(t)}generateIndex(){let t={...this.options,apiConfiguration:this.options.apiConfiguration||{file:"@/store/webapi",importName:"WebApiConfiguration"}};return ye(this.options.groupKey||"",t)}};var F=class{_options;openApiService=new x;groupService=new C;fileWriterService=new N;openApiDoc=null;parserService=null;schemaInterfaces={};allEndpointCacheKeys=[];actualSchemaFile="";generatedContent={groups:[],cacheKeys:null,commonTypes:"",componentSchema:"",doNotModify:"",utils:""};constructor(t){this._options=t}async generateAll(){return await this.prepare(),await this.generateApi(),this.generateCacheKeysContent(),this.generateCommonTypesContent(),this.generateSchemaContent(),this.generateUtilsContent(),this.generateDoNotModifyContent(),await this.release()}async prepare(){this.actualSchemaFile=this._options.schemaFile,this._options.remoteFile&&(this.actualSchemaFile=await this.openApiService.downloadSchema(this._options.remoteFile,this._options.schemaFile)),this.openApiDoc=await this.openApiService.getDocument(this.actualSchemaFile,this._options.httpResolverOptions),this.parserService=new S(this.openApiDoc,this._options),this.parserService.initialize();let t=this.parserService.getApiGenerator();this.schemaInterfaces=t.aliases.reduce((e,n)=>{if(he.isInterfaceDeclaration(n)||he.isTypeAliasDeclaration(n)){let o=n.name.text;return{...e,[o]:n}}return e},{})}async generateApi(){if(!this.openApiDoc||!this.parserService)throw new Error("\u8ACB\u5148\u8ABF\u7528 prepare() \u65B9\u6CD5");let t=this.openApiService.getPaths(this.openApiDoc),e=this.groupService.groupPaths(t,this._options.outputFiles);for(let n of Object.values(e))try{let o=await this.generateApiGroupContent(this._options,n);o.operationNames.length>0&&this.generatedContent.groups.push({groupKey:n.groupKey,outputPath:n.outputPath,content:o})}catch(o){throw new Error(`\u7FA4\u7D44 ${n.groupKey} \u751F\u6210\u5931\u6557: ${o}`)}}async generateCacheKeysContent(){this.generatedContent.cacheKeys=se(this.allEndpointCacheKeys)}async generateCommonTypesContent(){this.generatedContent.commonTypes=ae()}async generateSchemaContent(){this.generatedContent.componentSchema=pe(this.schemaInterfaces)}async generateDoNotModifyContent(){this.generatedContent.doNotModify=ce()}async generateUtilsContent(){this.generatedContent.utils=oe()}async release(){let t=[],e=[],n=[];try{for(let p of this.generatedContent.groups)try{if(p.content?.files){let a=D.dirname(p.outputPath),c=await this.fileWriterService.writeGroupFiles(a,{types:p.content.files.types,apiService:p.content.files.apiService,queryService:p.content.files.queryService,index:p.content.files.index});t.push(...c),n.push(p.groupKey)}}catch(a){e.push(new Error(`\u5BEB\u5165\u7FA4\u7D44 ${p.groupKey} \u5931\u6557: ${a}`))}let o=this.generatedContent.groups[0]?D.dirname(D.dirname(this.generatedContent.groups[0].outputPath)):"./generated";if(this.generatedContent.cacheKeys||this.generatedContent.commonTypes||this.generatedContent.doNotModify||this.generatedContent.utils){let p=await this.fileWriterService.writeSharedFiles(o,{cacheKeys:this.generatedContent.cacheKeys||void 0,commonTypes:this.generatedContent.commonTypes||void 0,doNotModify:this.generatedContent.doNotModify||void 0,utils:this.generatedContent.utils||void 0});t.push(...p)}if(this.generatedContent.componentSchema){let p=await this.fileWriterService.writeSchemaFile(o,this.generatedContent.componentSchema);t.push(...p)}}catch(o){e.push(o)}return{success:e.length===0,writtenFiles:t,errors:e,generatedGroups:n}}async generateApiGroupContent(t,e){let{outputFiles:n,...o}=t,p={...o,schemaFile:this.actualSchemaFile,outputFile:e.outputPath,sharedTypesFile:`${n.outputDir}/common-types.ts`,filterEndpoints:this.groupService.createGroupFilter(e.groupKey,n),queryMatch:n.queryMatch,groupKey:e.groupKey};if(!this.openApiDoc||!this.parserService)throw new Error("OpenAPI \u6587\u6A94\u672A\u521D\u59CB\u5316\uFF0C\u8ACB\u5148\u8ABF\u7528 prepare()");let c=await new E(this.parserService,p).generate();if(c.files&&"allEndpointCacheKeys"in c.files){let u=c.files.allEndpointCacheKeys;this.allEndpointCacheKeys.push(...u)}return c}};async function de(r){let e=await new F(r).generateAll();if(!e.success&&e.errors.length>0)throw e.errors[0]}var ve=Ye(m);async function Xe(r){let t=Je(process.cwd(),r);process.chdir(Ze(t));let e=ve(t),n=e.default??e;"outputFiles"in n||(console.error('Configuration must include "outputFiles" property. Single file output is no longer supported.'),process.exit(1)),n.outputFiles&&n.outputFiles.outputDir&&U(n.outputFiles.outputDir);try{console.log("Generating multiple outputs..."),await de(n),console.log("Done")}catch(o){console.error("Generation failed:",o),process.exit(1)}}async function et(){let r=ve("../../package.json"),t=k();R.version(r.version).usage("<path/to/config.js>").parse(process.argv);let e=R.args[0];if(R.args.length===0){R.help();return}W(e),_(e,t),await Xe(e)}et().catch(r=>{console.error("CLI execution failed:",r),process.exit(1)});export{Xe as runGeneration};
186
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/utils/http.ts","../../src/bin/cli.ts","../../src/bin/utils.ts","../../src/index.ts","../../src/services/unified-code-generator.ts","../../src/services/openapi-service.ts","../../src/utils/capitalize.ts","../../src/utils/downloadSchema.ts","../../src/utils/isValidUrl.ts","../../src/utils/getOperationDefinitions.ts","../../src/types.ts","../../src/utils/getV3Doc.ts","../../src/utils/isQuery.ts","../../src/services/group-service.ts","../../src/services/file-writer-service.ts","../../src/utils/directory.ts","../../src/services/openapi-parser-service.ts","../../src/generators/cache-keys-generator.ts","../../src/generators/utils-generator.ts","../../src/generators/common-types-generator.ts","../../src/generators/component-schema-generator.ts","../../src/generators/do-not-modify-generator.ts","../../src/services/api-code-generator.ts","../../src/services/endpoint-info-extractor.ts","../../src/generators/types-generator.ts","../../src/generators/index-generator.ts","../../src/services/query-code-generator.ts","../../src/generators/query-service-generator.ts","../../src/services/api-service-generator.ts","../../src/generators/api-service-generator.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import type {\n EndpointMatcher, EndpointOverrides,\n OperationDefinition,\n ParameterDefinition,\n ParameterMatcher,\n TextMatcher,\n} from '../types';\nimport {\n getOperationName as _getOperationName,\n} from 'oazapfts/generate';\n\n\n/**\n * 判斷 HTTP 狀態碼是否為成功的數據響應\n */\nexport function defaultIsDataResponse(code: string, includeDefault: boolean) {\n if (includeDefault && code === 'default') {\n return true;\n }\n const parsedCode = Number(code);\n return !Number.isNaN(parsedCode) && parsedCode >= 200 && parsedCode < 300;\n}\n\n/**\n * 根據 HTTP 方法和路徑生成操作名稱\n */\nexport function getOperationName({ verb, path }: Pick<OperationDefinition, 'verb' | 'path'>) {\n return _getOperationName(verb, path, undefined);\n}\n\n\n\n\n/**\n * 從路徑項目中提取標籤(tags)\n */\nexport function getTags({ verb, pathItem }: Pick<OperationDefinition, 'verb' | 'pathItem'>): string[] {\n return verb ? pathItem[verb]?.tags || [] : [];\n}\n\n/**\n * 創建文本匹配器函數,用於過濾操作名稱\n */\nfunction patternMatches(pattern?: TextMatcher) {\n const filters = Array.isArray(pattern) ? pattern : [pattern];\n return function matcher(operationName: string) {\n if (!pattern) return true;\n return filters.some((filter) =>\n typeof filter === 'string' ? filter === operationName : filter?.test(operationName)\n );\n };\n}\n\n/**\n * 創建操作匹配器函數,用於過濾操作定義\n */\nexport function operationMatches(pattern?: EndpointMatcher) {\n const checkMatch = typeof pattern === 'function' ? pattern : patternMatches(pattern);\n return function matcher(operationDefinition: OperationDefinition) {\n if (!pattern) return true;\n const operationName = getOperationName(operationDefinition);\n return checkMatch(operationName, operationDefinition);\n };\n}\n\n/**\n * 創建參數匹配器函數,用於過濾參數定義\n */\nexport function argumentMatches(pattern?: ParameterMatcher) {\n const checkMatch = typeof pattern === 'function' ? pattern : patternMatches(pattern);\n return function matcher(argumentDefinition: ParameterDefinition) {\n if (!pattern || argumentDefinition.in === 'path') return true;\n const argumentName = argumentDefinition.name;\n return checkMatch(argumentName, argumentDefinition);\n };\n}\n\n/**\n * 獲取操作的覆蓋配置\n */\nexport function getOverrides(\n operation: OperationDefinition,\n endpointOverrides?: EndpointOverrides[]\n): EndpointOverrides | undefined {\n return endpointOverrides?.find((override) => operationMatches(override.pattern)(operation));\n}","#!/usr/bin/env node\n\nimport program from 'commander';\nimport { createRequire } from 'node:module';\nimport { cleanOutputDirectory, setupTypeScriptSupport, validateConfigFile, validateTypeScriptSupport } from './utils';\nimport { dirname, resolve } from 'node:path';\nimport { generateEndpoints } from '../index';\n\nconst require = createRequire(__filename);\n\n\n\n\n\n/**\n * 執行代碼生成流程\n * 載入設定檔並驗證是否包含 outputFiles 屬性,清理輸出目錄,然後執行端點生成\n * @param {string} configFile - 設定檔案路徑\n */\nexport async function runGeneration(configFile: string): Promise<void> {\n const absoluteConfigPath = resolve(process.cwd(), configFile);\n process.chdir(dirname(absoluteConfigPath));\n\n const unparsedConfig = require(absoluteConfigPath);\n const config = unparsedConfig.default ?? unparsedConfig;\n\n if (!('outputFiles' in config)) {\n console.error('Configuration must include \"outputFiles\" property. Single file output is no longer supported.');\n process.exit(1);\n }\n\n // 清理輸出目錄\n if (config.outputFiles && config.outputFiles.outputDir) {\n cleanOutputDirectory(config.outputFiles.outputDir);\n }\n\n try {\n console.log('Generating multiple outputs...');\n await generateEndpoints(config);\n console.log('Done');\n } catch (err) {\n console.error('Generation failed:', err);\n process.exit(1);\n }\n}\n\n\n/**\n * CLI 主要執行函數\n * 設置 TypeScript 支援、解析命令列參數、驗證設定檔並執行代碼生成\n */\nasync function main(): Promise<void> {\n const meta = require('../../package.json');\n const hasTypeScriptSupport = setupTypeScriptSupport();\n\n program\n .version(meta.version)\n .usage('<path/to/config.js>')\n .parse(process.argv);\n\n const configFile = program.args[0];\n\n if (program.args.length === 0) {\n program.help();\n return;\n }\n\n validateConfigFile(configFile);\n validateTypeScriptSupport(configFile, hasTypeScriptSupport);\n\n await runGeneration(configFile);\n}\n\nmain().catch((err) => {\n console.error('CLI execution failed:', err);\n process.exit(1);\n});","import program from 'commander';\nimport { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport { existsSync, rmSync } from 'node:fs';\n\nconst require = createRequire(__filename);\n\n\n\n\n/**\n * 清理輸出目錄\n * 移除設定檔中指定的 outputDir 目錄及其內容\n * @param {string} outputDir - 要清理的目錄路徑\n */\nexport function cleanOutputDirectory(outputDir: string): void {\n // 安全檢查:避免刪除重要目錄\n const dangerousPaths = ['/', '/usr', '/etc', '/var', '/home', '/Users', '.', '..'];\n const normalizedPath = resolve(outputDir);\n\n if (dangerousPaths.some(path => normalizedPath === resolve(path))) {\n console.error(`Dangerous path detected: ${normalizedPath}. Refusing to delete.`);\n process.exit(1);\n }\n\n if (existsSync(outputDir)) {\n console.log(`Cleaning output directory: ${outputDir}`);\n rmSync(outputDir, { recursive: true, force: true });\n console.log(`Directory cleaned: ${outputDir}`);\n }\n}\n\n\n/**\n * 設置 TypeScript 支援\n * 優先使用 esbuild-runner,其次使用 ts-node\n * @returns {boolean} 是否成功設置 TypeScript 支援\n */\nexport function setupTypeScriptSupport(): boolean {\n try {\n if (require.resolve('esbuild') && require.resolve('esbuild-runner')) {\n require('esbuild-runner/register');\n return true;\n }\n } catch {}\n\n try {\n if (require.resolve('typescript') && require.resolve('ts-node')) {\n (require('ts-node') as typeof import('ts-node')).register({\n transpileOnly: true,\n compilerOptions: {\n target: 'es6',\n module: 'commonjs',\n },\n });\n return true;\n }\n } catch {}\n\n return false;\n}\n\n/**\n * 驗證設定檔案格式是否有效\n * 支援 .js/.ts/.mjs/.mts/.cjs/.cts/.json/.jsonc 格式\n * @param {string} configFile - 設定檔案路徑\n */\nexport function validateConfigFile(configFile: string): void {\n if (!configFile || !/\\.([mc]?(jsx?|tsx?)|jsonc?)?$/.test(configFile)) {\n console.error('Please provide a valid configuration file.');\n program.help();\n }\n}\n\n/**\n * 驗證 TypeScript 設定檔是否有相應的執行環境支援\n * @param {string} configFile - 設定檔案路徑\n * @param {boolean} hasTypeScriptSupport - 是否已設置 TypeScript 支援\n */\nexport function validateTypeScriptSupport(configFile: string, hasTypeScriptSupport: boolean): void {\n if (/\\.[mc]?tsx?$/.test(configFile) && !hasTypeScriptSupport) {\n console.error('Encountered a TypeScript config file, but neither esbuild-runner nor ts-node are installed.');\n process.exit(1);\n }\n}\n","import { UnifiedCodeGenerator, type UnifiedGenerationOptions, type UnifiedGenerationResult } from './services/unified-code-generator';\n\nexport type { OutputFilesConfig, ConfigFile } from './types';\n\n\n/**\n * 產生 Endpoints - 直接使用統一代碼生成器\n * @param options - 端點生成選項\n */\nexport async function generateEndpoints(options: UnifiedGenerationOptions): Promise<string | void> {\n const generator = new UnifiedCodeGenerator(options);\n\n const result = await generator.generateAll();\n \n if (!result.success) {\n if (result.errors.length > 0) {\n throw result.errors[0];\n }\n }\n return;\n}\n","import path from 'node:path';\nimport ts from 'typescript';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport { OpenApiService } from './openapi-service';\nimport { GroupService, type GroupConfig } from './group-service';\nimport { FileWriterService, type FileWriteResult } from './file-writer-service';\nexport interface EndpointCacheKey {\n operationName: string;\n queryKeyName: string;\n groupKey: string;\n}\nimport { OpenApiParserService } from './openapi-parser-service';\nimport { generateCacheKeysFile } from '../generators/cache-keys-generator';\nimport { generateCommonTypesFile } from '../generators/common-types-generator';\nimport { generateComponentSchemaFile } from '../generators/component-schema-generator';\nimport { generateDoNotModifyFile } from '../generators/do-not-modify-generator';\nimport type { GenerationOptions, CommonOptions } from '../types';\nimport { ApiCodeGenerator } from './api-code-generator';\nimport { generateUtilsFile } from '../generators/utils-generator';\n\n/**\n * 統一代碼生成器選項\n */\nexport interface UnifiedGenerationOptions extends CommonOptions {\n outputFiles: GroupConfig;\n remoteFile?: string;\n}\n\n/**\n * 統一代碼生成器結果\n */\nexport interface UnifiedGenerationResult {\n success: boolean;\n writtenFiles: FileWriteResult[];\n errors: Error[];\n generatedGroups: string[];\n}\n\n/**\n * 統一代碼生成器\n * \n * 設計理念:\n * - 統一管理所有生成流程\n * - 內建 schema 處理和存儲\n * - 提供準備、生成、發佈的分階段操作\n * - 避免重複初始化和處理\n * \n * 使用方式:\n * 1. prepare() - 準備階段:解析 schema、初始化服務\n * 2. generateContent() - 生成階段:產生所有內容但不寫檔\n * 3. release() - 發佈階段:統一寫入所有檔案\n */\nexport class UnifiedCodeGenerator {\n private _options: UnifiedGenerationOptions;\n\n private openApiService = new OpenApiService();\n private groupService = new GroupService();\n private fileWriterService = new FileWriterService();\n \n // 內部狀態存儲\n private openApiDoc: OpenAPIV3.Document | null = null;\n private parserService: OpenApiParserService | null = null;\n private schemaInterfaces: Record<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration> = {};\n private allEndpointCacheKeys: EndpointCacheKey[] = [];\n private actualSchemaFile: string = '';\n \n // 生成內容存儲\n private generatedContent: {\n groups: Array<{\n groupKey: string;\n outputPath: string;\n content: any;\n }>;\n cacheKeys: string | null;\n commonTypes: string;\n componentSchema: string;\n doNotModify: string;\n utils: string;\n } = {\n groups: [],\n cacheKeys: null,\n commonTypes: '',\n componentSchema: '',\n doNotModify: '',\n utils: ''\n };\n\n\n constructor(options: UnifiedGenerationOptions) {\n this._options = options;\n }\n\n\n\n /**\n * 一次性生成(整合所有階段)\n */\n async generateAll(): Promise<UnifiedGenerationResult> {\n await this.prepare();\n\n // 生成各API文件\n await this.generateApi();\n // await this.generateQuery();\n\n // 生成共用\n this.generateCacheKeysContent()\n this.generateCommonTypesContent()\n this.generateSchemaContent()\n this.generateUtilsContent()\n this.generateDoNotModifyContent()\n\n return await this.release();\n }\n\n\n\n /**\n * 準備階段:解析 schema 並初始化所有服務\n */\n async prepare(): Promise<void> {\n // console.log('UnifiedCodeGenerator: 準備階段開始...');\n \n // 步驟 1: 解析實際的 schema 檔案路徑\n this.actualSchemaFile = this._options.schemaFile;\n if (this._options.remoteFile) {\n this.actualSchemaFile = await this.openApiService.downloadSchema(\n this._options.remoteFile,\n this._options.schemaFile\n );\n }\n\n // 步驟 2: 獲取 OpenAPI 文檔(只初始化一次)\n this.openApiDoc = await this.openApiService.getDocument(\n this.actualSchemaFile,\n this._options.httpResolverOptions\n );\n\n // 步驟 3: 初始化解析器服務並處理 schema\n this.parserService = new OpenApiParserService(this.openApiDoc, this._options);\n this.parserService.initialize();\n\n // 步驟 4: 提取並儲存 schema interfaces\n const apiGen = this.parserService.getApiGenerator();\n this.schemaInterfaces = apiGen.aliases.reduce<Record<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>>((curr, alias) => {\n if (ts.isInterfaceDeclaration(alias) || ts.isTypeAliasDeclaration(alias)) {\n const name = alias.name.text;\n return {\n ...curr,\n [name]: alias,\n };\n }\n return curr;\n }, {});\n\n // console.log('UnifiedCodeGenerator: 準備階段完成');\n }\n\n\n\n /**\n * 生成階段:產生所有內容但不寫檔\n */\n async generateApi(): Promise<void> {\n if (!this.openApiDoc || !this.parserService) {\n throw new Error('請先調用 prepare() 方法');\n }\n\n // console.log('UnifiedCodeGenerator: 內容生成階段開始...');\n\n // 獲取所有 API 接口Path並分組\n const paths = this.openApiService.getPaths(this.openApiDoc);\n const groupInfos = this.groupService.groupPaths(paths, this._options.outputFiles);\n\n // 為每個群組生成內容\n for (const groupInfo of Object.values(groupInfos)) {\n try {\n const groupContent = await this.generateApiGroupContent(\n this._options,\n groupInfo\n );\n\n // 檢查群組是否有任何有效的 endpoint\n if (groupContent.operationNames.length > 0) {\n this.generatedContent.groups.push({\n groupKey: groupInfo.groupKey,\n outputPath: groupInfo.outputPath,\n content: groupContent\n });\n }\n // 如果沒有任何 endpoint,則跳過此群組,不創建資料夾\n } catch (error) {\n throw new Error(`群組 ${groupInfo.groupKey} 生成失敗: ${error}`);\n }\n }\n\n // console.log('UnifiedCodeGenerator: 內容生成階段完成');\n }\n\n\n /**\n * 生成 cache keys\n */\n private async generateCacheKeysContent(): Promise<void> {\n this.generatedContent.cacheKeys = generateCacheKeysFile(this.allEndpointCacheKeys);\n }\n\n /**\n * 生成 common types\n */\n private async generateCommonTypesContent(): Promise<void> {\n this.generatedContent.commonTypes = generateCommonTypesFile();\n }\n\n /**\n * 生成Schema\n */\n private async generateSchemaContent(): Promise<void> {\n this.generatedContent.componentSchema = generateComponentSchemaFile(this.schemaInterfaces);\n }\n\n /**\n * 生成 DO_NOT_MODIFY.md\n */\n private async generateDoNotModifyContent(): Promise<void> {\n this.generatedContent.doNotModify = generateDoNotModifyFile();\n }\n\n\n /**\n * 生成 Utils Function\n */\n private async generateUtilsContent(): Promise<void> {\n this.generatedContent.utils = generateUtilsFile();\n }\n\n\n\n\n /**\n * 發佈階段:統一寫入所有檔案\n */\n async release(): Promise<UnifiedGenerationResult> {\n const results: FileWriteResult[] = [];\n const errors: Error[] = [];\n const generatedGroups: string[] = [];\n\n // console.log('UnifiedCodeGenerator: 發佈階段開始...');\n\n try {\n // 寫入群組檔案\n for (const group of this.generatedContent.groups) {\n try {\n if (group.content?.files) {\n const groupOutputDir = path.dirname(group.outputPath);\n const groupResults = await this.fileWriterService.writeGroupFiles(\n groupOutputDir,\n {\n types: group.content.files.types,\n apiService: group.content.files.apiService,\n queryService: group.content.files.queryService,\n index: group.content.files.index\n }\n );\n results.push(...groupResults);\n generatedGroups.push(group.groupKey);\n }\n } catch (error) {\n errors.push(new Error(`寫入群組 ${group.groupKey} 失敗: ${error}`));\n }\n }\n\n // 寫入共用檔案\n const outputDir = this.generatedContent.groups[0] ? \n path.dirname(path.dirname(this.generatedContent.groups[0].outputPath)) : \n './generated';\n\n // 寫入共用檔案 (包含 DO_NOT_MODIFY.md)\n if (this.generatedContent.cacheKeys || this.generatedContent.commonTypes || this.generatedContent.doNotModify || this.generatedContent.utils) {\n const sharedResults = await this.fileWriterService.writeSharedFiles(\n outputDir,\n { \n cacheKeys: this.generatedContent.cacheKeys || undefined,\n commonTypes: this.generatedContent.commonTypes || undefined,\n doNotModify: this.generatedContent.doNotModify || undefined,\n utils: this.generatedContent.utils || undefined\n }\n );\n results.push(...sharedResults);\n }\n\n // 寫入 component schema\n if (this.generatedContent.componentSchema) {\n const schemaResults = await this.fileWriterService.writeSchemaFile(\n outputDir,\n this.generatedContent.componentSchema\n );\n results.push(...schemaResults);\n }\n\n } catch (error) {\n errors.push(error as Error);\n }\n\n // console.log('UnifiedCodeGenerator: 發佈階段完成');\n\n return {\n success: errors.length === 0,\n writtenFiles: results,\n errors,\n generatedGroups\n };\n }\n\n\n /**\n * 為單一群組生成內容\n */\n private async generateApiGroupContent(\n options: UnifiedGenerationOptions,\n groupInfo: { groupKey: string; paths: string[]; outputPath: string }\n ): Promise<any> {\n const { outputFiles, ...commonConfig } = options;\n\n // 建立群組特定的生成選項\n const groupOptions: GenerationOptions = {\n ...commonConfig,\n schemaFile: this.actualSchemaFile,\n outputFile: groupInfo.outputPath,\n sharedTypesFile: `${outputFiles.outputDir}/common-types.ts`,\n filterEndpoints: this.groupService.createGroupFilter(groupInfo.groupKey, outputFiles),\n queryMatch: outputFiles.queryMatch,\n groupKey: groupInfo.groupKey,\n };\n\n // 使用新的 ApiCodeGenerator 生成程式碼,重用已處理的 v3Doc\n if (!this.openApiDoc || !this.parserService) {\n throw new Error('OpenAPI 文檔未初始化,請先調用 prepare()');\n }\n \n const apiGenerator = new ApiCodeGenerator(this.parserService, groupOptions);\n const result = await apiGenerator.generate();\n\n // 提取並儲存快取鍵\n if (result.files && 'allEndpointCacheKeys' in result.files) {\n const cacheKeys = result.files.allEndpointCacheKeys as EndpointCacheKey[];\n this.allEndpointCacheKeys.push(...cacheKeys);\n }\n\n return result;\n }\n\n\n}","import type { OpenAPIV3 } from 'openapi-types';\nimport { getV3Doc, downloadSchemaFile } from '../utils';\n\n/**\n * OpenAPI 服務 - 負責獲取和處理 OpenAPI 文檔\n * \n * 單一職責:\n * - 從本地文件或遠程URL獲取OpenAPI文檔\n * - 管理文檔快取\n * - 提供文檔基本操作方法\n * \n * 設計原則:\n * - 非收集模式:每次調用都是獨立的操作\n * - 無副作用:不修改傳入的參數\n * - 可測試性:所有方法都有明確的輸入輸出\n */\nexport class OpenApiService {\n private docCache: Record<string, OpenAPIV3.Document> = {};\n\n /**\n * 獲取 OpenAPI 文檔\n * @param schemaLocation - Schema 位置 (URL 或本地路徑)\n * @param httpResolverOptions - HTTP 解析選項\n */\n async getDocument(\n schemaLocation: string, \n httpResolverOptions?: any\n ): Promise<OpenAPIV3.Document> {\n if (this.docCache[schemaLocation]) {\n return this.docCache[schemaLocation];\n }\n\n const doc = await getV3Doc(schemaLocation, httpResolverOptions);\n this.docCache[schemaLocation] = doc;\n return doc;\n }\n\n /**\n * 下載遠程 Schema 文件\n * @param remoteUrl - 遠程 URL\n * @param localPath - 本地儲存路徑\n */\n async downloadSchema(remoteUrl: string, localPath: string): Promise<string> {\n return downloadSchemaFile(remoteUrl, localPath);\n }\n\n /**\n * 獲取所有 API 路徑\n * @param doc - OpenAPI 文檔\n */\n getPaths(doc: OpenAPIV3.Document): string[] {\n return Object.keys(doc.paths || {});\n }\n\n /**\n * 清除快取\n */\n clearCache(): void {\n this.docCache = {};\n }\n}","export function capitalize(str: string) {\n return str.replace(str[0], str[0].toUpperCase());\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { isValidUrl } from './isValidUrl';\n\nexport async function downloadSchemaFile(remoteFile: string, targetPath: string): Promise<string> {\n // 如果不是網址,拋出錯誤\n if (!isValidUrl(remoteFile)) {\n throw new Error(`remoteFile must be a valid URL: ${remoteFile}`);\n }\n\n try {\n // 確保目錄存在\n const dir = path.dirname(targetPath);\n if (!fs.existsSync(dir)) {\n await fs.promises.mkdir(dir, { recursive: true });\n }\n\n // 下載檔案\n const response = await fetch(remoteFile);\n if (!response.ok) {\n throw new Error(`Failed to download schema from ${remoteFile}: ${response.statusText}`);\n }\n\n const content = await response.text();\n await fs.promises.writeFile(targetPath, content, 'utf-8');\n\n console.log(`Schema downloaded from ${remoteFile} to ${targetPath}`);\n return targetPath;\n } catch (error) {\n console.error(`Error downloading schema from ${remoteFile}:`, error);\n throw error;\n }\n} ","export function isValidUrl(string: string) {\n try {\n new URL(string);\n } catch (_) {\n return false;\n }\n\n return true;\n}\n","import type { OpenAPIV3 } from 'openapi-types';\nimport type { OperationDefinition } from '../types';\nimport { operationKeys } from '../types';\n\nexport function getOperationDefinitions(v3Doc: OpenAPIV3.Document): OperationDefinition[] {\n return Object.entries(v3Doc.paths).flatMap(([path, pathItem]) =>\n !pathItem\n ? []\n : Object.entries(pathItem)\n .filter((arg): arg is [(typeof operationKeys)[number], OpenAPIV3.OperationObject] =>\n operationKeys.includes(arg[0] as any)\n )\n .map(([verb, operation]) => ({\n path,\n verb,\n pathItem,\n operation,\n }))\n );\n}\n","import type SwaggerParser from '@apidevtools/swagger-parser';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport ts from 'typescript';\n\n// 重新匯出服務相關類型\nexport type { \n GroupConfig,\n GroupInfo \n} from './services/group-service';\n\nexport type { \n FileWriteResult \n} from './services/file-writer-service';\n\nexport type {\n EndpointCacheKey\n} from './services/unified-code-generator';\n\nexport type {\n UnifiedGenerationOptions as EndpointGenerationOptions,\n UnifiedGenerationResult as EndpointGenerationResult\n} from './services/unified-code-generator';\n\nexport type OperationDefinition = {\n path: string;\n verb: (typeof operationKeys)[number];\n pathItem: OpenAPIV3.PathItemObject;\n operation: OpenAPIV3.OperationObject;\n};\n\nexport type ParameterDefinition = OpenAPIV3.ParameterObject;\n\ntype Require<T, K extends keyof T> = { [k in K]-?: NonNullable<T[k]> } & Omit<T, K>;\ntype Optional<T, K extends keyof T> = { [k in K]?: NonNullable<T[k]> } & Omit<T, K>;\ntype Id<T> = { [K in keyof T]: T[K] } & {};\ntype AtLeastOneKey<T> = {\n [K in keyof T]-?: Pick<T, K> & Partial<T>;\n}[keyof T];\n\nexport const operationKeys = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'] as const;\n\nexport type GenerationOptions = Id<\n CommonOptions &\n Optional<OutputFileOptions, 'outputFile'> & {\n isDataResponse?(\n code: string,\n includeDefault: boolean,\n response: OpenAPIV3.ResponseObject,\n allResponses: OpenAPIV3.ResponsesObject\n ): boolean;\n }\n>;\n\nexport interface CommonOptions {\n /**\n * local schema file path (only supports local files)\n */\n schemaFile: string;\n /**\n * remote schema file URL (when provided, will download to schemaFile path)\n */\n remoteFile?: string;\n /**\n * Configuration for WebApiConfiguration import\n * defaults to { file: \"@core/api/web-api-configuration\", importName: \"WebApiConfiguration\" }\n */\n apiConfiguration?: {\n file: string;\n importName: string;\n };\n /**\n * HttpClient for WebApiConfiguration import\n * defaults to { file: \"@core/httpClient/webapi/webapi-http-client.providers\", importName: \"WEBAPI_HTTP_CLIENT\" }\n */\n httpClient?: {\n file: string;\n importName: string;\n };\n /**\n * defaults to \"enhancedApi\"\n */\n exportName?: string;\n /**\n * defaults to \"Req\"\n */\n argSuffix?: string;\n /**\n * defaults to \"Res\"\n */\n responseSuffix?: string;\n /**\n * defaults to empty\n */\n operationNameSuffix?: string;\n /**\n * defaults to `false`\n * `true` will generate hooks for queries and mutations, but no lazyQueries\n */\n hooks?: boolean | { queries: boolean; lazyQueries: boolean; mutations: boolean };\n /**\n * defaults to false\n * `true` will generate a union type for `undefined` properties like: `{ id?: string | undefined }` instead of `{ id?: string }`\n */\n unionUndefined?: boolean;\n /**\n * defaults to false\n * `true` will result in all generated endpoints having `providesTags`/`invalidatesTags` declarations for the `tags` of their respective operation definition\n * @see https://redux-toolkit.js.org/rtk-query/usage/code-generation for more information\n */\n tag?: boolean;\n /**\n * defaults to false\n * `true` will add `encodeURIComponent` to the generated path parameters\n */\n encodePathParams?: boolean;\n /**\n * defaults to false\n * `true` will add `encodeURIComponent` to the generated query parameters\n */\n encodeQueryParams?: boolean;\n /**\n * defaults to false\n * `true` will \"flatten\" the arg so that you can do things like `useGetEntityById(1)` instead of `useGetEntityById({ entityId: 1 })`\n */\n flattenArg?: boolean;\n /**\n * default to false\n * If set to `true`, the default response type will be included in the generated code for all endpoints.\n * @see https://swagger.io/docs/specification/describing-responses/#default\n */\n includeDefault?: boolean;\n /**\n * default to false\n * `true` will not generate separate types for read-only and write-only properties.\n */\n mergeReadWriteOnly?: boolean;\n /**\n *\n * HTTPResolverOptions object that is passed to the SwaggerParser bundle function.\n */\n httpResolverOptions?: SwaggerParser.HTTPResolverOptions;\n\n /**\n * defaults to undefined\n * If present the given file will be used as prettier config when formatting the generated code. If undefined the default prettier config\n * resolution mechanism will be used.\n */\n prettierConfigFile?: string;\n /**\n * defaults to \"@acrool/react-fetcher\"\n * File path for importing IRestFulEndpointsQueryReturn type\n */\n endpointsQueryReturnTypeFile?: string;\n /**\n * defaults to 60 (seconds)\n * Number of seconds to wait before refetching data when component mounts or args change\n */\n refetchOnMountOrArgChange?: number;\n}\n\nexport type TextMatcher = string | RegExp | (string | RegExp)[];\n\nexport type EndpointMatcherFunction = (operationName: string, operationDefinition: OperationDefinition) => boolean;\n\nexport type EndpointMatcher = TextMatcher | EndpointMatcherFunction;\n\nexport type ParameterMatcherFunction = (parameterName: string, parameterDefinition: ParameterDefinition) => boolean;\n\nexport type ParameterMatcher = TextMatcher | ParameterMatcherFunction;\n\nexport interface OutputFileOptions extends Partial<CommonOptions> {\n outputFile: string;\n filterEndpoints?: EndpointMatcher;\n endpointOverrides?: EndpointOverrides[];\n queryMatch?: (method: string, path: string) => boolean;\n /**\n * defaults to false\n * If passed as true it will generate TS enums instead of union of strings\n */\n useEnumType?: boolean;\n sharedTypesFile?: string;\n /**\n * groupKey for service class naming, e.g., \"room\" -> \"RoomService\"\n */\n groupKey?: string;\n}\n\nexport type EndpointOverrides = {\n pattern: EndpointMatcher;\n} & AtLeastOneKey<{\n type: 'mutation' | 'query';\n parameterFilter: ParameterMatcher;\n}>;\n\nexport type OutputFilesConfig = {\n groupKeyMatch: (path: string) => string;\n outputDir: string;\n queryMatch?: (method: string, path: string) => boolean;\n filterEndpoint?: (operationName: string, path: string, groupKey: string) => boolean;\n};\n\nexport type ConfigFile =\n | Id<Require<CommonOptions & OutputFileOptions, 'outputFile'>>\n | Id<\n Omit<CommonOptions, 'outputFile'> & {\n // outputFiles: { [outputFile: string]: Omit<OutputFileOptions, 'outputFile'> };\n outputFiles: OutputFilesConfig\n }\n >;\n\nexport type GenerateApiResult = {\n operationNames: string[];\n files: {\n types: string;\n apiService: string;\n queryService: string;\n index: string;\n commonTypes?: string;\n cacheKeys?: string;\n componentSchema?: string;\n allEndpointCacheKeys?: Array<{\n operationName: string\n queryKeyName: string\n groupKey: string\n }>;\n };\n};\n\n\n\nexport type QueryArgDefinition = {\n name: string;\n originalName: string;\n type: ts.TypeNode;\n required?: boolean;\n param?: OpenAPIV3.ParameterObject;\n} & (\n | {\n origin: 'param';\n param: OpenAPIV3.ParameterObject;\n}\n | {\n origin: 'body';\n body: OpenAPIV3.RequestBodyObject;\n}\n );\n\nexport type QueryArgDefinitions = Record<string, QueryArgDefinition>;","import SwaggerParser from '@apidevtools/swagger-parser';\nimport type { OpenAPIV3 } from 'openapi-types';\n// @ts-ignore\nimport converter from 'swagger2openapi';\n\nexport async function getV3Doc(\n spec: string,\n httpResolverOptions?: SwaggerParser.HTTPResolverOptions\n): Promise<OpenAPIV3.Document> {\n const doc = await SwaggerParser.bundle(spec, {\n resolve: {\n http: httpResolverOptions,\n },\n });\n\n const isOpenApiV3 = 'openapi' in doc && doc.openapi.startsWith('3');\n\n if (isOpenApiV3) {\n return doc as OpenAPIV3.Document;\n } else {\n const result = await converter.convertObj(doc, {});\n return result.openapi as OpenAPIV3.Document;\n }\n}\n","import type { EndpointOverrides, operationKeys } from '../types';\n\nexport function isQuery(\n verb: (typeof operationKeys)[number],\n path: string,\n overrides: EndpointOverrides | undefined,\n queryMatch?: (method: string, path: string) => boolean\n) {\n if (queryMatch) {\n return queryMatch(verb, path);\n }\n if (overrides?.type) {\n return overrides.type === 'query';\n }\n return verb === 'get';\n}\n","import camelCase from 'lodash.camelcase';\n\n/**\n * 群組配置介面\n */\nexport interface GroupConfig {\n outputDir: string;\n groupKeyMatch: (path: string) => string | null;\n filterEndpoint?: (operationName: string, path: string, groupKey: string) => boolean;\n queryMatch?: (operationName: string) => boolean;\n}\n\n/**\n * 群組信息介面\n */\nexport interface GroupInfo {\n groupKey: string;\n paths: string[];\n outputPath: string;\n}\n\n/**\n * 群組服務 - 負責處理 API 路徑分組\n */\nexport class GroupService {\n /**\n * 根據配置對路徑進行分組\n * @param paths - API 路徑陣列\n * @param config - 群組配置\n */\n groupPaths(paths: string[], config: GroupConfig): Record<string, GroupInfo> {\n const { groupKeyMatch, outputDir } = config;\n \n const groupedPaths = paths.reduce((acc, path) => {\n const rawGroupKey = groupKeyMatch(path);\n const groupKey = rawGroupKey ? camelCase(rawGroupKey) : '_common';\n \n if (!acc[groupKey]) {\n acc[groupKey] = [];\n }\n acc[groupKey].push(path);\n return acc;\n }, {} as Record<string, string[]>);\n\n // 轉換為 GroupInfo 格式\n const result: Record<string, GroupInfo> = {};\n for (const [groupKey, paths] of Object.entries(groupedPaths)) {\n result[groupKey] = {\n groupKey,\n paths,\n outputPath: `${outputDir}/${groupKey}/query.service.ts`\n };\n }\n\n return result;\n }\n\n /**\n * 為特定群組建立篩選函數\n * @param groupKey - 群組鍵\n * @param config - 群組配置\n */\n createGroupFilter(\n groupKey: string,\n config: GroupConfig\n ): (operationName: string, operationDefinition: any) => boolean {\n return (operationName: string, operationDefinition: any) => {\n const path = operationDefinition.path;\n\n // 檢查路徑是否匹配當前分組\n const pathGroupKey = camelCase(config.groupKeyMatch(path) || '');\n if (pathGroupKey !== groupKey && (pathGroupKey || '_common') !== groupKey) {\n return false;\n }\n\n // 使用 filterEndpoint 進行額外篩選\n if (config.filterEndpoint) {\n return config.filterEndpoint(operationName, path, groupKey);\n }\n\n return true;\n };\n }\n}","import fs from 'node:fs';\nimport path from 'node:path';\nimport { ensureDirectoryExists } from '../utils/directory';\n\n/**\n * 檔案寫入結果\n */\nexport interface FileWriteResult {\n path: string;\n success: boolean;\n error?: Error;\n}\n\n/**\n * 檔案寫入服務 - 負責將產生的內容寫入檔案\n */\nexport class FileWriterService {\n /**\n * 寫入單一檔案\n * @param filePath - 檔案路徑\n * @param content - 檔案內容\n */\n async writeFile(filePath: string, content: string): Promise<FileWriteResult> {\n try {\n const resolvedPath = path.resolve(process.cwd(), filePath);\n await ensureDirectoryExists(resolvedPath);\n \n fs.writeFileSync(resolvedPath, content);\n \n return {\n path: resolvedPath,\n success: true\n };\n } catch (error) {\n return {\n path: filePath,\n success: false,\n error: error as Error\n };\n }\n }\n\n /**\n * 批次寫入多個檔案\n * @param files - 檔案路徑與內容的對應表\n */\n async writeFiles(files: Record<string, string>): Promise<FileWriteResult[]> {\n const results: FileWriteResult[] = [];\n \n for (const [filePath, content] of Object.entries(files)) {\n const result = await this.writeFile(filePath, content);\n results.push(result);\n }\n \n return results;\n }\n\n /**\n * 為群組寫入標準檔案結構\n * @param groupOutputDir - 群組輸出目錄\n * @param files - 檔案內容\n */\n async writeGroupFiles(\n groupOutputDir: string,\n files: {\n types?: string;\n apiService?: string;\n queryService?: string;\n index?: string;\n }\n ): Promise<FileWriteResult[]> {\n const filesToWrite: Record<string, string> = {};\n\n if (files.types) {\n filesToWrite[path.join(groupOutputDir, 'types.ts')] = files.types;\n }\n \n if (files.apiService) {\n filesToWrite[path.join(groupOutputDir, 'api.service.ts')] = files.apiService;\n }\n \n if (files.queryService) {\n filesToWrite[path.join(groupOutputDir, 'query.service.ts')] = files.queryService;\n }\n \n if (files.index) {\n filesToWrite[path.join(groupOutputDir, 'index.ts')] = files.index;\n }\n\n return this.writeFiles(filesToWrite);\n }\n\n /**\n * 寫入共享檔案\n * @param outputDir - 輸出目錄\n * @param sharedFiles - 共享檔案內容\n */\n async writeSharedFiles(\n outputDir: string,\n sharedFiles: {\n commonTypes?: string;\n cacheKeys?: string;\n doNotModify?: string;\n utils?: string;\n }\n ): Promise<FileWriteResult[]> {\n const filesToWrite: Record<string, string> = {};\n\n if (sharedFiles.commonTypes) {\n filesToWrite[path.join(outputDir, 'common-types.ts')] = sharedFiles.commonTypes;\n }\n \n if (sharedFiles.cacheKeys) {\n filesToWrite[path.join(outputDir, 'cache-keys.ts')] = sharedFiles.cacheKeys;\n }\n\n if (sharedFiles.doNotModify) {\n filesToWrite[path.join(outputDir, 'DO_NOT_MODIFY.md')] = sharedFiles.doNotModify;\n }\n\n if (sharedFiles.utils) {\n filesToWrite[path.join(outputDir, 'utils.ts')] = sharedFiles.utils;\n }\n\n return this.writeFiles(filesToWrite);\n }\n\n\n\n\n /**\n * 寫入共享檔案\n * @param outputDir - 輸出目錄\n * @param schema\n */\n async writeSchemaFile(\n outputDir: string,\n schema: string\n ): Promise<FileWriteResult[]> {\n const filesToWrite: Record<string, string> = {};\n\n filesToWrite[path.join(outputDir, 'schema.ts')] = schema;\n\n return this.writeFiles(filesToWrite);\n }\n\n\n}","import path from 'node:path';\nimport fs from 'node:fs';\n\n/**\n * 確保目錄存在的函數\n * @param filePath\n */\nexport async function ensureDirectoryExists(filePath: string) {\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) {\n await fs.promises.mkdir(dirname, { recursive: true });\n }\n}\n\n/**\n * 檢查檔案是否存在的函數\n * @param filePath\n */\nexport function fileExists(filePath: string): boolean {\n try {\n return fs.statSync(filePath).isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * 獲取資料夾名稱並轉換為 API 名稱\n * @param dirPath\n */\nexport function getApiNameFromDir(dirPath: string): string {\n const dirName = path.basename(dirPath);\n return `${dirName}Api`;\n}\n\n\n\n\n/**\n * 確保基礎文件存在的函數\n * @param outputDir\n * @param operationNames\n */\nexport async function ensureBaseFilesExist(outputDir: string, operationNames: string[]) {\n const enhanceEndpointsPath = path.join(outputDir, 'enhanceEndpoints.ts');\n const indexPath = path.join(outputDir, 'index.ts');\n\n // 如果 enhanceEndpoints.ts 不存在,創建它\n if (!fileExists(enhanceEndpointsPath)) {\n // 生成操作名稱的字符串\n const operationNamesString = operationNames\n .map(name => ` ${name}: {},`)\n .join('\\n');\n\n const enhanceEndpointsContent = `import api from './query.service';\n\nconst enhancedApi = api.enhanceEndpoints({\n endpoints: {\n${operationNamesString}\n },\n});\n\nexport default enhancedApi;\n`;\n await fs.promises.writeFile(enhanceEndpointsPath, enhanceEndpointsContent, 'utf-8');\n }\n // 如果文件已存在,不做任何修改\n\n // 如果 index.ts 不存在,創建它\n if (!fileExists(indexPath)) {\n const indexContent = `export * from './query.service';\n`;\n await fs.promises.writeFile(indexPath, indexContent, 'utf-8');\n }\n}","import ApiGenerator from 'oazapfts/generate';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport type { GenerationOptions } from '../types';\nimport { getOperationDefinitions } from '../utils';\n\n/**\n * OpenAPI 解析器服務 - 負責解析 OpenAPI 文檔並提取相關數據\n */\nexport class OpenApiParserService {\n private apiGen: ApiGenerator;\n\n constructor(\n private v3Doc: OpenAPIV3.Document,\n options: Partial<GenerationOptions>\n ) {\n this.apiGen = new ApiGenerator(v3Doc, {\n unionUndefined: options.unionUndefined,\n useEnumType: options.useEnumType,\n mergeReadWriteOnly: options.mergeReadWriteOnly,\n });\n }\n\n /**\n * 初始化 - 預處理組件\n */\n initialize(): void {\n if (this.apiGen.spec.components?.schemas) {\n this.apiGen.preprocessComponents(this.apiGen.spec.components.schemas);\n \n // 手動為每個 schema 生成 type alias\n Object.keys(this.apiGen.spec.components.schemas).forEach(schemaName => {\n try {\n this.apiGen.getRefAlias({ $ref: `#/components/schemas/${schemaName}` });\n } catch (error) {\n // 忽略無法生成的 schema\n }\n });\n }\n }\n\n /**\n * 獲取操作定義列表\n * @param filterEndpoints - 端點過濾函數\n */\n getOperationDefinitions(filterEndpoints?: any) {\n const { operationMatches } = require('../utils/http');\n return getOperationDefinitions(this.v3Doc).filter(operationMatches(filterEndpoints));\n }\n\n /**\n * 獲取 API 生成器實例\n */\n getApiGenerator(): ApiGenerator {\n return this.apiGen;\n }\n\n /**\n * 獲取 OpenAPI 文檔\n */\n getDocument(): OpenAPIV3.Document {\n return this.v3Doc;\n }\n\n /**\n * 獲取所有 schema 類型名稱\n */\n getSchemaTypeNames(): Set<string> {\n const schemeTypeNames = new Set<string>();\n // 這裡可以根據需要添加 schema 類型名稱的提取邏輯\n return schemeTypeNames;\n }\n}","import { toCamelCase } from './utils-generator';\n\n\nexport function generateCacheKeysFile(allEndpointInfos: Array<{\n operationName: string;\n queryKeyName: string;\n groupKey: string;\n}>) {\n\n // 按 group 分組\n const groupedKeys = allEndpointInfos.reduce((acc, info) => {\n if (!acc[info.groupKey]) {\n acc[info.groupKey] = [];\n }\n acc[info.groupKey].push({\n operationName: info.operationName,\n queryKeyName: info.queryKeyName\n });\n return acc;\n }, {} as Record<string, Array<{operationName: string, queryKeyName: string}>>);\n\n // 生成 enum 內容\n const enumEntries = Object.entries(groupedKeys).map(([groupKey, keys]) => {\n const groupComment = ` // ${groupKey.charAt(0).toUpperCase() + groupKey.slice(1)} related cache keys`;\n const keyEntries = keys.map(key =>\n ` ${key.queryKeyName} = '${toCamelCase(key.queryKeyName)}',`\n ).join('\\n');\n\n return `${groupComment}\\n${keyEntries}`;\n }).join('\\n\\n');\n\n return `// [Warning] Generated automatically - do not edit manually \n \n/**\n * Cache keys enum for all API queries\n */\nexport enum ECacheKeys {\n${enumEntries}\n}\n\nexport default ECacheKeys;\n`;\n}","import ts from 'typescript';\n\n\n/**\n * 產生 Utils function 內容\n * @param interfaces\n */\nexport function generateUtilsFile() {\n\n // 分析接口內容以找出需要從 shared-types 導入的類型\n return `/* eslint-disable */\n// [Warning] Generated automatically - do not edit manually \n \n/**\n* Clear undefined in object\n*/\nexport function withoutUndefined(obj?: Record<string, any>) {\n if(typeof obj === 'undefined') return;\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v !== undefined && v !== null)\n );\n}\n\n`\n}\n\n/**\n * 大寫底線字串 轉 小駝峰\n * @param str\n */\nexport function toCamelCase(str: string): string {\n return str.toLowerCase().replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}","/**\n * 產生 CommonTypeFile\n */\nexport function generateCommonTypesFile() {\n\n return `/* eslint-disable */\n// [Warning] Generated automatically - do not edit manually\n \nexport interface RequestOptions {\n headers?: Record<string, string>;\n observe?: 'body' | 'events' | 'response';\n responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';\n reportProgress?: boolean;\n withCredentials?: boolean;\n timeout?: number;\n}\n\nexport interface QueryConfig {\n refetchOnMountOrArgChange?: boolean|number,\n keepUnusedDataFor?: number,\n}\n\nexport type IRestFulEndpointsQueryReturn<TVariables> = TVariables extends void ? \n void | {fetchOptions?: RequestOptions;config?: QueryConfig;}: \n {\n variables: TVariables;\n fetchOptions?: RequestOptions;\n config?: QueryConfig;\n };\n`;\n\n}\n\n","import ts from 'typescript';\n\n\n/**\n * 產生 component-schema.ts 內容\n * @param interfaces\n */\nexport function generateComponentSchemaFile(interfaces: Record<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>) {\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n \n const resultFile = ts.createSourceFile(\n 'component-schema.ts',\n '',\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS\n );\n\n // 分析接口內容以找出需要從 shared-types 導入的類型\n return `/* eslint-disable */\n// [Warning] Generated automatically - do not edit manually \n \n${Object.values(interfaces).map(i => printer.printNode(ts.EmitHint.Unspecified, i, resultFile)).join('\\n')}\n`\n}","/**\n * 產生 DO_NOT_MODIFY.md 說明檔案\n * \n * 此檔案用於提醒開發者不要修改產生器生成的程式碼\n */\nexport function generateDoNotModifyFile(): string {\n return `# 請勿修改此資料夾\n\n⚠️ **重要提醒:請勿修改此資料夾中的任何檔案**\n\n此資料夾中的所有檔案都是透過程式碼產生器自動產生的。任何手動修改的內容在下次重新產生時都將會被覆蓋。\n\n## 如何修改這些檔案?\n\n如果您需要修改這些檔案的內容,請:\n\n1. 修改相對應的設定檔案或模板\n2. 重新執行程式碼產生器\n3. 讓產生器自動更新這些檔案\n\n## 產生器相關資訊\n\n這些檔案是由 @bitstack/ng-query-codegen-openapi 產生器所建立。\n\n如有疑問,請參考專案文件或聯繫開發團隊。\n`;\n}","import type { OpenAPIV3 } from 'openapi-types';\nimport ts from 'typescript';\nimport { OpenApiParserService } from './openapi-parser-service';\nimport { EndpointInfoExtractor } from './endpoint-info-extractor';\nimport { generateTypesFile } from '../generators/types-generator';\nimport { generateIndexFile } from '../generators/index-generator';\nimport { QueryCodeGenerator } from './query-code-generator';\nimport { ApiServiceGenerator } from './api-service-generator';\nimport type { GenerationOptions, GenerateApiResult } from '../types';\n\n/**\n * API 程式碼生成器 - 負責生成單一群組的 API 相關程式碼\n * \n * 設計理念:\n * - 類別化管理:使用 class 封裝邏輯\n * - 分離關注點:將 Query 和 API 服務分開生成\n * - 重用資源:接受外部已處理的 v3Doc,避免重複處理\n */\nexport class ApiCodeGenerator {\n private infoExtractor: EndpointInfoExtractor;\n private queryGenerator: QueryCodeGenerator;\n private apiServiceGenerator: ApiServiceGenerator;\n\n constructor(\n private parserService: OpenApiParserService,\n private options: GenerationOptions\n ) {\n \n // // 初始化端點資訊提取器\n this.infoExtractor = new EndpointInfoExtractor(options);\n //\n // 初始化分離的生成器\n this.queryGenerator = new QueryCodeGenerator(options);\n this.apiServiceGenerator = new ApiServiceGenerator(options);\n }\n\n /**\n * 生成完整的 API 程式碼\n */\n async generate(): Promise<GenerateApiResult> {\n // console.log('ApiCodeGenerator: 開始生成 API 程式碼...');\n\n // 步驟 1: 獲取操作定義\n const operationDefinitions = this.parserService.getOperationDefinitions(this.options.filterEndpoints);\n\n // 步驟 2: 提取端點資訊\n const endpointInfos = this.infoExtractor.extractEndpointInfos(operationDefinitions);\n\n\n // 步驟 3: 生成各種內容\n const typesContent = this.generateTypes(endpointInfos);\n \n\n const apiServiceContent = this.generateApiService(endpointInfos);\n const queryServiceContent = this.generateQueryService(endpointInfos);\n const indexContent = this.generateIndex();\n\n // 步驟 4: 收集端點快取鍵資訊(只收集 Query 類型的端點)\n const allEndpointCacheKeys = endpointInfos\n .filter(info => info.isQuery) // 只收集查詢類型的端點\n .map(info => ({\n operationName: info.operationName,\n queryKeyName: info.queryKeyName,\n groupKey: this.options.groupKey || '_common'\n }));\n\n // 步驟 5: 收集操作名稱\n const operationNames = endpointInfos.map(info => info.operationName);\n\n // console.log('ApiCodeGenerator: API 程式碼生成完成');\n\n return {\n operationNames,\n files: {\n types: typesContent,\n apiService: apiServiceContent,\n queryService: queryServiceContent,\n index: indexContent,\n allEndpointCacheKeys: allEndpointCacheKeys\n }\n };\n }\n\n /**\n * 生成 Types 檔案內容\n */\n private generateTypes(endpointInfos: Array<any>): string {\n const generatorOptions = {\n ...this.options,\n apiConfiguration: this.options.apiConfiguration || { \n file: '@/store/webapi', \n importName: 'WebApiConfiguration' \n }\n };\n\n // 從 parser service 獲取 schema interfaces\n const apiGen = this.parserService.getApiGenerator();\n const schemaInterfaces = apiGen.aliases.reduce<Record<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>>((curr, alias) => {\n if (ts.isInterfaceDeclaration(alias) || ts.isTypeAliasDeclaration(alias)) {\n const name = alias.name.text;\n return {\n ...curr,\n [name]: alias,\n };\n }\n return curr;\n }, {});\n\n // 獲取操作定義以供類型生成使用\n const operationDefinitions = this.parserService.getOperationDefinitions(this.options.filterEndpoints);\n\n return generateTypesFile(endpointInfos, generatorOptions, schemaInterfaces, operationDefinitions);\n }\n\n /**\n * 生成 API Service 檔案內容\n */\n private generateApiService(endpointInfos: Array<any>): string {\n return this.apiServiceGenerator.generateApiService(endpointInfos);\n }\n\n /**\n * 生成 Query Service 檔案內容\n */\n private generateQueryService(endpointInfos: Array<any>): string {\n return this.queryGenerator.generateQueryService(endpointInfos);\n }\n\n /**\n * 生成 Index 檔案內容\n */\n private generateIndex(): string {\n const generatorOptions = {\n ...this.options,\n apiConfiguration: this.options.apiConfiguration || { \n file: '@/store/webapi', \n importName: 'WebApiConfiguration' \n }\n };\n\n return generateIndexFile(this.options.groupKey || '', generatorOptions);\n }\n\n // /**\n // * 獲取已解析的 parser service(供外部使用)\n // */\n // getParserService(): OpenApiParserService {\n // return this.parserService;\n // }\n //\n // /**\n // * 獲取端點資訊提取器(供外部使用)\n // */\n // getInfoExtractor(): EndpointInfoExtractor {\n // return this.infoExtractor;\n // }\n}","import { capitalize, isQuery as testIsQuery } from '../utils';\nimport { getOperationName, getOverrides } from '../utils/http';\nimport type { OperationDefinition, GenerationOptions } from '../types';\nimport { supportDeepObjects } from 'oazapfts/generate';\n\n/**\n * 端點資訊介面\n */\nexport interface EndpointInfo {\n operationName: string;\n argTypeName: string;\n responseTypeName: string;\n isQuery: boolean;\n verb: string;\n path: string;\n queryKeyName: string;\n queryParams: any[];\n pathParams: any[];\n isVoidArg: boolean;\n summary: string;\n}\n\n/**\n * 端點資訊提取器 - 專門負責從操作定義中提取端點資訊\n */\nexport class EndpointInfoExtractor {\n constructor(\n private options: Pick<GenerationOptions, 'operationNameSuffix' | 'argSuffix' | 'responseSuffix' | 'queryMatch' | 'endpointOverrides'>\n ) {}\n\n /**\n * 從操作定義列表提取端點資訊\n * @param operationDefinitions - 操作定義列表\n */\n extractEndpointInfos(operationDefinitions: OperationDefinition[]): EndpointInfo[] {\n return operationDefinitions.map((operationDefinition) => {\n return this.extractSingleEndpointInfo(operationDefinition);\n });\n }\n\n /**\n * 從單一操作定義提取端點資訊\n * @param operationDefinition - 操作定義\n */\n private extractSingleEndpointInfo(operationDefinition: OperationDefinition): EndpointInfo {\n const { verb, path, operation } = operationDefinition;\n const { operationNameSuffix = '', argSuffix = 'Req', responseSuffix = 'Res', queryMatch, endpointOverrides } = this.options;\n\n // 獲取操作名稱\n const operationName = getOperationName({ verb, path });\n const finalOperationName = operationNameSuffix ? capitalize(operationName + operationNameSuffix) : operationName;\n\n // 生成類型名稱\n const argTypeName = capitalize(operationName + operationNameSuffix + argSuffix);\n const responseTypeName = capitalize(operationName + operationNameSuffix + responseSuffix);\n\n // 判斷是否為查詢類型\n const isQuery = testIsQuery(verb, path, getOverrides(operationDefinition, endpointOverrides), queryMatch);\n \n // 生成查詢鍵名稱\n const queryKeyName = `${operationName.replace(/([A-Z])/g, '_$1').toUpperCase()}`;\n\n // 提取 OpenAPI summary\n const summary = operation.summary || `${verb.toUpperCase()} ${path}`;\n\n // 解析參數\n const { queryParams, pathParams, isVoidArg } = this.extractParameters(operationDefinition);\n\n return {\n operationName: finalOperationName,\n argTypeName,\n responseTypeName,\n isQuery,\n verb: verb.toUpperCase(),\n path,\n queryKeyName,\n queryParams,\n pathParams,\n isVoidArg,\n summary\n };\n }\n\n /**\n * 提取操作的參數資訊\n * @param operationDefinition - 操作定義\n */\n private extractParameters(operationDefinition: OperationDefinition) {\n const { operation, pathItem } = operationDefinition;\n\n // 解析參數\n const operationParameters = this.resolveArray(operation.parameters);\n const pathItemParameters = this.resolveArray(pathItem.parameters)\n .filter((pp) => !operationParameters.some((op) => op.name === pp.name && op.in === pp.in));\n \n const allParameters = supportDeepObjects([...pathItemParameters, ...operationParameters])\n .filter((param) => param.in !== 'header');\n\n const queryParams = allParameters.filter(param => param.in === 'query');\n const pathParams = allParameters.filter(param => param.in === 'path');\n\n // 檢查是否為 void 類型參數\n const isVoidArg = queryParams.length === 0 && pathParams.length === 0 && !operation.requestBody;\n\n return {\n queryParams,\n pathParams,\n isVoidArg\n };\n }\n\n /**\n * 解析參數陣列 (模擬 apiGen.resolveArray)\n */\n private resolveArray(parameters: any): any[] {\n if (!parameters) return [];\n return Array.isArray(parameters) ? parameters : [parameters];\n }\n}","import ts from 'typescript';\nimport type { GenerationOptions } from '../types';\n\nexport interface EndpointInfo {\n operationName: string;\n argTypeName: string;\n responseTypeName: string;\n isQuery: boolean;\n verb: string;\n path: string;\n queryKeyName: string;\n queryParams: any[];\n pathParams: any[];\n isVoidArg: boolean;\n summary: string;\n}\n\nexport function generateTypesFile(\n endpointInfos: EndpointInfo[], \n _options: GenerationOptions,\n schemaInterfaces?: Record<string, ts.InterfaceDeclaration | ts.TypeAliasDeclaration>,\n operationDefinitions?: any[]\n) {\n\n // 生成 import 語句\n let importStatement = `/* eslint-disable */\n// [Warning] Generated automatically - do not edit manually \n \n`;\n \n // 檢查是否需要引入 schema.ts\n const hasSchemaTypes = schemaInterfaces && Object.keys(schemaInterfaces).length > 0;\n if (hasSchemaTypes) {\n importStatement += `import * as Schema from \"../schema\";\\n`;\n }\n \n importStatement += '\\n';\n \n // 收集所有需要的類型定義\n const typeDefinitions: string[] = [];\n \n // 注意:不再在 types.ts 中重複生成 schema 類型\n // schema 類型已經在 schema.ts 中生成,這裡直接使用 Schema.* 引用\n \n // 無論是否有 schema,都要生成 endpoint 特定的 Req/Res 類型\n const endpointTypes: string[] = [];\n \n // 為每個端點生成 Req/Res 類型\n endpointInfos.forEach(endpoint => {\n // 使用 endpoint 中提供的準確類型名稱\n const reqTypeName = endpoint.argTypeName;\n const resTypeName = endpoint.responseTypeName;\n \n // 生成 Request 類型(總是生成)\n if (reqTypeName) {\n const requestTypeContent = generateRequestTypeContent(endpoint, operationDefinitions);\n if (requestTypeContent.trim() === '' || requestTypeContent.includes('TODO') || requestTypeContent.includes('[key: string]: any')) {\n // 如果沒有實際內容,使用 void\n endpointTypes.push(\n `export type ${reqTypeName} = void;`,\n ``\n );\n } else {\n // 有實際內容,使用 type 定義\n endpointTypes.push(\n `export type ${reqTypeName} = {`,\n requestTypeContent,\n `};`,\n ``\n );\n }\n }\n \n // 生成 Response 類型(總是生成)\n if (resTypeName) {\n const responseTypeContent = generateResponseTypeContent(endpoint, operationDefinitions);\n if (responseTypeContent.trim() === '' || responseTypeContent.includes('TODO') || responseTypeContent.includes('[key: string]: any')) {\n // 如果沒有實際內容,使用 void\n endpointTypes.push(\n `export type ${resTypeName} = void;`,\n ``\n );\n } else {\n // 有實際內容,使用 type 定義\n endpointTypes.push(\n `export type ${resTypeName} = {`,\n responseTypeContent,\n `};`,\n ``\n );\n }\n }\n });\n \n if (endpointTypes.length > 0) {\n typeDefinitions.push(endpointTypes.join('\\n'));\n }\n \n // 如果沒有任何類型定義,至少添加一些基本說明\n if (typeDefinitions.length === 0) {\n typeDefinitions.push(\n `// 此檔案用於定義 API 相關的類型`,\n `// 類型定義會根據 OpenAPI Schema 自動生成`,\n ``\n );\n }\n \n return importStatement + typeDefinitions.join('\\n\\n');\n}\n\n/**\n * 生成 Request 類型的內容\n */\nfunction generateRequestTypeContent(endpoint: EndpointInfo, operationDefinitions?: any[]): string {\n const properties: string[] = [];\n \n // 如果有 query 參數\n if (endpoint.queryParams && endpoint.queryParams.length > 0) {\n endpoint.queryParams.forEach(param => {\n const optional = param.required ? '' : '?';\n const paramType = getTypeFromParameter(param);\n properties.push(` ${param.name}${optional}: ${paramType};`);\n });\n }\n \n // 如果有 path 參數\n if (endpoint.pathParams && endpoint.pathParams.length > 0) {\n endpoint.pathParams.forEach(param => {\n const optional = param.required ? '' : '?';\n const paramType = getTypeFromParameter(param);\n properties.push(` ${param.name}${optional}: ${paramType};`);\n });\n }\n \n // 如果有 request body(從 operationDefinitions 中獲取)\n const operationDef = operationDefinitions?.find(op => {\n // 嘗試多種匹配方式\n return op.operation?.operationId === endpoint.operationName ||\n op.operation?.operationId === endpoint.operationName.toLowerCase() ||\n // 也嘗試匹配 verb + path 組合\n (op.verb === endpoint.verb.toLowerCase() && op.path === endpoint.path);\n });\n \n if (operationDef?.operation?.requestBody) {\n const requestBody = operationDef.operation.requestBody;\n const content = requestBody.content;\n \n // 處理不同的 content types\n const jsonContent = content['application/json'];\n const formContent = content['multipart/form-data'] || content['application/x-www-form-urlencoded'];\n \n if (jsonContent?.schema) {\n const bodyType = getTypeFromSchema(jsonContent.schema);\n properties.push(` body: ${bodyType};`);\n } else if (formContent?.schema) {\n const bodyType = getTypeFromSchema(formContent.schema);\n properties.push(` body: ${bodyType};`);\n } else {\n properties.push(` body?: any; // Request body from OpenAPI`);\n }\n }\n \n // 如果沒有任何參數,返回空內容(將由調用方處理為 void)\n if (properties.length === 0) {\n return ''; // 返回空字串,讓調用方決定使用 void\n }\n \n return properties.join('\\n');\n}\n\n/**\n * 生成 Response 類型的內容\n */\nfunction generateResponseTypeContent(endpoint: EndpointInfo, operationDefinitions?: any[]): string {\n const properties: string[] = [];\n \n // 嘗試從 operationDefinitions 中獲取響應結構\n const operationDef = operationDefinitions?.find(op => {\n // 嘗試多種匹配方式\n return op.operation?.operationId === endpoint.operationName ||\n op.operation?.operationId === endpoint.operationName.toLowerCase() ||\n // 也嘗試匹配 verb + path 組合\n (op.verb === endpoint.verb.toLowerCase() && op.path === endpoint.path);\n });\n \n if (operationDef?.operation?.responses) {\n // 檢查 200 響應\n const successResponse = operationDef.operation.responses['200'] || \n operationDef.operation.responses['201'];\n \n if (successResponse?.content) {\n const jsonContent = successResponse.content['application/json'];\n if (jsonContent?.schema) {\n const responseProps = parseSchemaProperties(jsonContent.schema);\n properties.push(...responseProps);\n } else {\n properties.push(` // Success response from OpenAPI`);\n properties.push(` data?: any;`);\n }\n }\n }\n \n // 如果沒有響應定義,返回空內容(將由調用方處理為 void)\n if (properties.length === 0) {\n return ''; // 返回空字串,讓調用方決定使用 void\n }\n \n return properties.join('\\n');\n}\n\n/**\n * 解析 OpenAPI schema 的 properties 並生成 TypeScript 屬性定義\n */\nfunction parseSchemaProperties(schema: any): string[] {\n const properties: string[] = [];\n \n if (schema.type === 'object' && schema.properties) {\n const required = schema.required || [];\n \n Object.entries(schema.properties).forEach(([propName, propSchema]: [string, any]) => {\n const isRequired = required.includes(propName);\n const optional = isRequired ? '' : '?';\n const propType = getTypeFromSchema(propSchema);\n const description = propSchema.description ? ` // ${propSchema.description}` : '';\n \n properties.push(` ${propName}${optional}: ${propType};${description}`);\n });\n }\n \n return properties;\n}\n\n/**\n * 從 OpenAPI schema 獲取 TypeScript 類型\n */\nfunction getTypeFromSchema(schema: any): string {\n if (!schema) return 'any';\n \n // 處理 $ref 引用,使用 Schema.TypeName 格式\n if (schema.$ref) {\n const refPath = schema.$ref;\n if (refPath.startsWith('#/components/schemas/')) {\n const typeName = refPath.replace('#/components/schemas/', '');\n return `Schema.${typeName}`;\n }\n }\n \n switch (schema.type) {\n case 'string':\n if (schema.enum) {\n return schema.enum.map((val: string) => `\"${val}\"`).join(' | ');\n }\n return 'string';\n case 'number':\n case 'integer':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'array':\n const itemType = schema.items ? getTypeFromSchema(schema.items) : 'any';\n return `${itemType}[]`;\n case 'object':\n if (schema.properties) {\n // 如果有具體的屬性定義,生成內聯對象類型\n const props = Object.entries(schema.properties).map(([key, propSchema]: [string, any]) => {\n const required = schema.required || [];\n const optional = required.includes(key) ? '' : '?';\n const type = getTypeFromSchema(propSchema);\n return `${key}${optional}: ${type}`;\n }).join('; ');\n return `{ ${props} }`;\n }\n return 'any';\n default:\n return 'any';\n }\n}\n\n/**\n * 從參數定義中獲取 TypeScript 類型\n */\nfunction getTypeFromParameter(param: any): string {\n if (!param.schema) return 'any';\n return getTypeFromSchema(param.schema);\n}","import type { GenerationOptions } from '../types';\n\nexport function generateIndexFile(groupKey: string, options: GenerationOptions) {\n const { groupKey: optionsGroupKey } = options;\n \n\n return `export * from './types';\nexport * from './api.service';\nexport * from './query.service';\n`;\n}","import type { GenerationOptions } from '../types';\nimport { generateQueryServiceFile } from '../generators/query-service-generator';\n\n/**\n * Query 服務程式碼生成器 - 專門負責生成 Query Service 相關程式碼\n */\nexport class QueryCodeGenerator {\n constructor(private options: GenerationOptions) {}\n\n /**\n * 生成 Query Service 檔案內容\n */\n generateQueryService(endpointInfos: Array<any>): string {\n const generatorOptions = {\n ...this.options,\n apiConfiguration: this.options.apiConfiguration || { \n file: '@/store/webapi', \n importName: 'WebApiConfiguration' \n }\n };\n\n return generateQueryServiceFile(endpointInfos, generatorOptions);\n }\n}","import type { GenerationOptions } from '../types';\n\nexport function generateQueryServiceFile(endpointInfos: Array<{\n operationName: string;\n argTypeName: string;\n responseTypeName: string;\n isQuery: boolean;\n verb: string;\n path: string;\n queryKeyName: string;\n queryParams: any[];\n pathParams: any[];\n isVoidArg: boolean;\n summary: string;\n}>, options: GenerationOptions) {\n\n const { groupKey, refetchOnMountOrArgChange = 60 } = options;\n \n // 確定服務名稱 - 使用 groupKey 如果有提供的話\n const queryServiceName = groupKey ?\n `${groupKey.charAt(0).toUpperCase() + groupKey.slice(1)}QueryService` :\n 'QueryService';\n \n const apiServiceName = groupKey ? \n `${groupKey.charAt(0).toUpperCase() + groupKey.slice(1)}ApiService` :\n 'ApiService';\n\n // 分別處理 Query 和 Mutation 方法\n const queryMethods = endpointInfos\n .filter(info => info.isQuery)\n .map(info => `\n /**\n * ${info.summary}\n */\n ${info.operationName}Query(${info.argTypeName !== 'VoidApiArg' ? `args: IRestFulEndpointsQueryReturn<${info.argTypeName}>` : ''}): Observable<QueryState<${info.responseTypeName}>> {\n return this.ntkQuery.query<${info.responseTypeName}, ${info.argTypeName !== 'VoidApiArg' ? `IRestFulEndpointsQueryReturn<${info.argTypeName}>` : 'void'}>({\n queryKey: [ECacheKeys.${info.queryKeyName}${info.argTypeName !== 'VoidApiArg' ? ', args.variables' : ''}],\n queryFn: () => {\n return this.apiService.${info.operationName}(${info.argTypeName !== 'VoidApiArg' ? 'args' : ''});\n },\n fetchOptions: args?.fetchOptions,\n config: args?.config,\n })${info.argTypeName !== 'VoidApiArg' ? '(args)' : '()'};\n }`).join('');\n\n const mutationMethods = endpointInfos\n .filter(info => !info.isQuery)\n .map(info => `\n /**\n * ${info.summary}\n */\n ${info.operationName}Mutation(): MutationResponse<${info.responseTypeName}, {\n variables: ${info.argTypeName !== 'VoidApiArg' ? info.argTypeName : 'void'};\n fetchOptions?: RequestOptions;\n }, HttpErrorResponse> {\n return this.ntkQuery.mutation<${info.responseTypeName}, ${info.argTypeName !== 'VoidApiArg' ? `IRestFulEndpointsQueryReturn<${info.argTypeName}>` : 'void'}, HttpErrorResponse>({\n endpointName: '${info.operationName}',\n mutationFn: (${info.argTypeName !== 'VoidApiArg' ? 'args' : ''}) => {\n return this.apiService.${info.operationName}(${info.argTypeName !== 'VoidApiArg' ? 'args' : ''});\n },\n });\n }`).join('');\n\n const lazyQueryMethods = endpointInfos\n .filter(info => info.isQuery)\n .map(info => `\n /**\n * ${info.summary}\n */\n ${info.operationName}LazyQuery(): {\n trigger: (${info.argTypeName !== 'VoidApiArg' ? `args: IRestFulEndpointsQueryReturn<${info.argTypeName}>, ` : ''}options?: { skipCache?: boolean }) => Observable<${info.responseTypeName}>\n } {\n return {\n trigger: (${info.argTypeName !== 'VoidApiArg' ? 'args, ' : ''}options = {}) => {\n const { skipCache = true } = options;\n if (!skipCache) {\n const cachedResult = this.ntkQuery.getQueryCache<${info.responseTypeName}>([ECacheKeys.${info.queryKeyName}${info.argTypeName !== 'VoidApiArg' ? ', args.variables' : ''}]);\n if (cachedResult) {\n return cachedResult;\n }\n }\n return this.apiService.${info.operationName}(${info.argTypeName !== 'VoidApiArg' ? 'args' : ''});\n }\n };\n }`).join('');\n\n return `/* eslint-disable */\n// [Warning] Generated automatically - do not edit manually \n \nimport {Injectable, inject} from '@angular/core';\nimport {Observable} from 'rxjs';\nimport {HttpErrorResponse} from '@angular/common/http';\nimport {NtkQueryService, MutationState, QueryState, MutationResponse} from '@core/ntk-query';\nimport {ECacheKeys} from '../cache-keys';\nimport {${apiServiceName}} from './api.service';\nimport {IRestFulEndpointsQueryReturn, RequestOptions} from '../common-types';\nimport {${endpointInfos.map(info => ` ${info.argTypeName}, ${info.responseTypeName}`).join(',')}} from './types';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ${queryServiceName} {\n private apiService = inject(${apiServiceName});\n private ntkQuery = inject(NtkQueryService);\n${queryMethods}${mutationMethods}${lazyQueryMethods}\n}\n`;\n}","import type { GenerationOptions } from '../types';\nimport { generateApiServiceFile } from '../generators/api-service-generator';\n\n/**\n * API 服務程式碼生成器 - 專門負責生成 API Service 相關程式碼\n */\nexport class ApiServiceGenerator {\n constructor(private options: GenerationOptions) {}\n\n /**\n * 生成 API Service 檔案內容\n */\n generateApiService(endpointInfos: Array<any>): string {\n const generatorOptions = {\n ...this.options,\n apiConfiguration: this.options.apiConfiguration || { \n file: '@/store/webapi', \n importName: 'WebApiConfiguration' \n }\n };\n\n return generateApiServiceFile(endpointInfos, generatorOptions);\n }\n}","import type { GenerationOptions } from '../types';\n\nexport function generateApiServiceFile(endpointInfos: Array<{\n operationName: string;\n argTypeName: string;\n responseTypeName: string;\n isQuery: boolean;\n verb: string;\n path: string;\n queryKeyName: string;\n queryParams: any[];\n pathParams: any[];\n isVoidArg: boolean;\n summary: string;\n}>, options: GenerationOptions) {\n \n const { apiConfiguration, httpClient, groupKey } = options;\n \n // 確定服務名稱,使用業務名稱\n const apiServiceClassName = groupKey ? \n `${groupKey.charAt(0).toUpperCase() + groupKey.slice(1)}ApiService` :\n 'ApiService';\n\n return `/* eslint-disable */\n// [Warning] Generated automatically - do not edit manually \n \nimport { ${httpClient!.importName} } from '${httpClient!.file}';\nimport { Injectable, inject } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { ${apiConfiguration!.importName} } from '${apiConfiguration!.file}';\nimport { RequestOptions, IRestFulEndpointsQueryReturn } from '../common-types';\nimport { withoutUndefined } from '../utils';\nimport {${endpointInfos.map(info => ` ${info.argTypeName}, ${info.responseTypeName}`).join(',')} } from './types';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ${apiServiceClassName} {\n private config = inject(${apiConfiguration!.importName});\n private http = inject(${httpClient!.importName});\n\n${endpointInfos.map(info => {\n const isGet = info.verb.toUpperCase() === 'GET';\n const hasArgs = info.argTypeName !== 'VoidApiArg';\n \n // 生成 URL 模板字面量,直接替換路徑參數\n const generateUrlTemplate = (path: string) => {\n const hasPathParams = path.includes('{');\n if (hasPathParams && hasArgs) {\n // 將 {paramName} 替換為 ${args.variables.paramName}\n const urlTemplate = path.replace(/\\{([^}]+)\\}/g, '${args.variables.$1}');\n return `\\`\\${this.config.rootUrl}${urlTemplate}\\``;\n } else {\n return `\\`\\${this.config.rootUrl}${path}\\``;\n }\n };\n \n const hasQueryParams = info.queryParams.length > 0;\n const hasBody = !isGet && hasArgs && !info.isVoidArg;\n \n // 生成 HTTP 請求選項\n const generateRequestOptions = () => {\n const options = [\n '...args.fetchOptions',\n ];\n\n // 添加 Content-Type header,特別是對於有 body 的請求\n if (hasBody || !isGet) {\n options.push(`headers: { 'Content-Type': 'application/json', ...args.fetchOptions?.headers }`);\n }\n\n if (hasQueryParams && hasArgs) {\n options.push(generateQueryParams(info.queryParams));\n }\n\n if (hasBody) {\n options.push('body: args.variables.body');\n }\n\n return options.length > 0 ? `{ ${options.join(', ')} }` : '{}';\n };\n\n return `\n /**\n * ${info.summary}\n */\n ${info.operationName}(\n ${hasArgs ? `args: IRestFulEndpointsQueryReturn<${info.argTypeName}>, ` : ''}\n ): Observable<${info.responseTypeName}> {\n const url = ${generateUrlTemplate(info.path)};\n return this.http.request('${info.verb.toLowerCase()}', url, ${generateRequestOptions()});\n }`;\n \n \n \n}).join('')}\n}\n`;\n}\n\n\n/**\n * 產生 QueryParams 參數\n * @param queryParams\n */\nfunction generateQueryParams(queryParams: Record<string, string>[]) {\n const paramEntries = queryParams.map(param =>\n `${param.name}: args.variables.${param.name}`\n ).join(', ');\n\n return `params: withoutUndefined({ ${paramEntries} })`;\n}"],"mappings":";ycAEA,OAAS,iBAAAA,OAAqB,WAF9B,IAIMC,GAIOC,EARbC,EAAAC,EAAA,kBAIMH,GAAc,IAAMD,GAAc,YAAY,GAAG,EAI1CE,EAA6BD,GAAY,ICRtD,IAAAI,GAAA,GAAAC,GAAAD,GAAA,qBAAAE,GAAA,0BAAAC,GAAA,qBAAAC,EAAA,iBAAAC,EAAA,YAAAC,GAAA,qBAAAC,KAOA,OACE,oBAAoBC,OACf,oBAMA,SAASL,GAAsBM,EAAcC,EAAyB,CAC3E,GAAIA,GAAkBD,IAAS,UAC7B,MAAO,GAET,IAAME,EAAa,OAAOF,CAAI,EAC9B,MAAO,CAAC,OAAO,MAAME,CAAU,GAAKA,GAAc,KAAOA,EAAa,GACxE,CAKO,SAASP,EAAiB,CAAE,KAAAQ,EAAM,KAAAC,CAAK,EAA+C,CAC3F,OAAOL,GAAkBI,EAAMC,EAAM,MAAS,CAChD,CAQO,SAASP,GAAQ,CAAE,KAAAM,EAAM,SAAAE,CAAS,EAA6D,CACpG,OAAOF,EAAOE,EAASF,CAAI,GAAG,MAAQ,CAAC,EAAI,CAAC,CAC9C,CAKA,SAASG,GAAeC,EAAuB,CAC7C,IAAMC,EAAU,MAAM,QAAQD,CAAO,EAAIA,EAAU,CAACA,CAAO,EAC3D,OAAO,SAAiBE,EAAuB,CAC7C,OAAKF,EACEC,EAAQ,KAAME,GACnB,OAAOA,GAAW,SAAWA,IAAWD,EAAgBC,GAAQ,KAAKD,CAAa,CACpF,EAHqB,EAIvB,CACF,CAKO,SAASX,GAAiBS,EAA2B,CAC1D,IAAMI,EAAa,OAAOJ,GAAY,WAAaA,EAAUD,GAAeC,CAAO,EACnF,OAAO,SAAiBK,EAA0C,CAChE,GAAI,CAACL,EAAS,MAAO,GACrB,IAAME,EAAgBd,EAAiBiB,CAAmB,EAC1D,OAAOD,EAAWF,EAAeG,CAAmB,CACtD,CACF,CAKO,SAASnB,GAAgBc,EAA4B,CAC1D,IAAMI,EAAa,OAAOJ,GAAY,WAAaA,EAAUD,GAAeC,CAAO,EACnF,OAAO,SAAiBM,EAAyC,CAC/D,GAAI,CAACN,GAAWM,EAAmB,KAAO,OAAQ,MAAO,GACzD,IAAMC,EAAeD,EAAmB,KACxC,OAAOF,EAAWG,EAAcD,CAAkB,CACpD,CACF,CAKO,SAASjB,EACdmB,EACAC,EAC+B,CAC/B,OAAOA,GAAmB,KAAMC,GAAanB,GAAiBmB,EAAS,OAAO,EAAEF,CAAS,CAAC,CAC5F,CArFA,IAAAG,EAAAC,EAAA,kBAAAC,MCAAC,IAEA,OAAOC,MAAa,YACpB,OAAS,iBAAAC,OAAqB,cCH9BC,IAAA,OAAOC,OAAa,YACpB,OAAS,iBAAAC,OAAqB,cAC9B,OAAS,WAAAC,MAAe,YACxB,OAAS,cAAAC,GAAY,UAAAC,OAAc,UAEnC,IAAMC,EAAUJ,GAAcK,CAAU,EAUjC,SAASC,EAAqBC,EAAyB,CAE5D,IAAMC,EAAiB,CAAC,IAAK,OAAQ,OAAQ,OAAQ,QAAS,SAAU,IAAK,IAAI,EAC3EC,EAAiBR,EAAQM,CAAS,EAEpCC,EAAe,KAAKE,GAAQD,IAAmBR,EAAQS,CAAI,CAAC,IAC9D,QAAQ,MAAM,4BAA4BD,CAAc,uBAAuB,EAC/E,QAAQ,KAAK,CAAC,GAGZP,GAAWK,CAAS,IACtB,QAAQ,IAAI,8BAA8BA,CAAS,EAAE,EACrDJ,GAAOI,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAClD,QAAQ,IAAI,sBAAsBA,CAAS,EAAE,EAEjD,CAQO,SAASI,GAAkC,CAChD,GAAI,CACF,GAAIP,EAAQ,QAAQ,SAAS,GAAKA,EAAQ,QAAQ,gBAAgB,EAChE,OAAAA,EAAQ,yBAAyB,EAC1B,EAEX,MAAQ,CAAC,CAET,GAAI,CACF,GAAIA,EAAQ,QAAQ,YAAY,GAAKA,EAAQ,QAAQ,SAAS,EAC5D,OAACA,EAAQ,SAAS,EAA+B,SAAS,CACxD,cAAe,GACf,gBAAiB,CACf,OAAQ,MACR,OAAQ,UACV,CACF,CAAC,EACM,EAEX,MAAQ,CAAC,CAET,MAAO,EACT,CAOO,SAASQ,EAAmBC,EAA0B,EACvD,CAACA,GAAc,CAAC,gCAAgC,KAAKA,CAAU,KACjE,QAAQ,MAAM,4CAA4C,EAC1Dd,GAAQ,KAAK,EAEjB,CAOO,SAASe,EAA0BD,EAAoBE,EAAqC,CAC7F,eAAe,KAAKF,CAAU,GAAK,CAACE,IACtC,QAAQ,MAAM,6FAA6F,EAC3G,QAAQ,KAAK,CAAC,EAElB,CD/EA,OAAS,WAAAC,GAAS,WAAAC,OAAe,YELjCC,ICAAC,IAAA,OAAOC,MAAU,YACjB,OAAOC,OAAQ,aCDfC,ICAAC,IAAO,SAASC,EAAWC,EAAa,CACtC,OAAOA,EAAI,QAAQA,EAAI,CAAC,EAAGA,EAAI,CAAC,EAAE,YAAY,CAAC,CACjD,CCFAC,IAAA,OAAOC,MAAQ,UACf,OAAOC,OAAU,YCDjBC,IAAO,SAASC,EAAWC,EAAgB,CACzC,GAAI,CACF,IAAI,IAAIA,CAAM,CAChB,MAAY,CACV,MAAO,EACT,CAEA,MAAO,EACT,CDJA,eAAsBC,EAAmBC,EAAoBC,EAAqC,CAEhG,GAAI,CAACC,EAAWF,CAAU,EACxB,MAAM,IAAI,MAAM,mCAAmCA,CAAU,EAAE,EAGjE,GAAI,CAEF,IAAMG,EAAMC,GAAK,QAAQH,CAAU,EAC9BI,EAAG,WAAWF,CAAG,GACpB,MAAME,EAAG,SAAS,MAAMF,EAAK,CAAE,UAAW,EAAK,CAAC,EAIlD,IAAMG,EAAW,MAAM,MAAMN,CAAU,EACvC,GAAI,CAACM,EAAS,GACZ,MAAM,IAAI,MAAM,kCAAkCN,CAAU,KAAKM,EAAS,UAAU,EAAE,EAGxF,IAAMC,EAAU,MAAMD,EAAS,KAAK,EACpC,aAAMD,EAAG,SAAS,UAAUJ,EAAYM,EAAS,OAAO,EAExD,QAAQ,IAAI,0BAA0BP,CAAU,OAAOC,CAAU,EAAE,EAC5DA,CACT,OAASO,EAAO,CACd,cAAQ,MAAM,iCAAiCR,CAAU,IAAKQ,CAAK,EAC7DA,CACR,CACF,CEhCAC,ICAAC,IAuCO,IAAMC,EAAgB,CAAC,MAAO,MAAO,OAAQ,SAAU,UAAW,OAAQ,QAAS,OAAO,EDnC1F,SAASC,EAAwBC,EAAkD,CACxF,OAAO,OAAO,QAAQA,EAAM,KAAK,EAAE,QAAQ,CAAC,CAACC,EAAMC,CAAQ,IACxDA,EAEG,OAAO,QAAQA,CAAQ,EACpB,OAAQC,GACPC,EAAc,SAASD,EAAI,CAAC,CAAQ,CACtC,EACC,IAAI,CAAC,CAACE,EAAMC,CAAS,KAAO,CAC3B,KAAAL,EACA,KAAAI,EACA,SAAAH,EACA,UAAAI,CACF,EAAE,EAVJ,CAAC,CAWP,CACF,CEnBAC,IAAA,OAAOC,OAAmB,8BAG1B,OAAOC,OAAe,kBAEtB,eAAsBC,EACpBC,EACAC,EAC6B,CAC7B,IAAMC,EAAM,MAAML,GAAc,OAAOG,EAAM,CAC3C,QAAS,CACP,KAAMC,CACR,CACF,CAAC,EAID,MAFoB,YAAaC,GAAOA,EAAI,QAAQ,WAAW,GAAG,EAGzDA,GAEQ,MAAMJ,GAAU,WAAWI,EAAK,CAAC,CAAC,GACnC,OAElB,CCvBAC,IAEO,SAASC,EACdC,EACAC,EACAC,EACAC,EACA,CACA,OAAIA,EACKA,EAAWH,EAAMC,CAAI,EAE1BC,GAAW,KACNA,EAAU,OAAS,QAErBF,IAAS,KAClB,CPCO,IAAMI,EAAN,KAAqB,CAClB,SAA+C,CAAC,EAOxD,MAAM,YACJC,EACAC,EAC6B,CAC7B,GAAI,KAAK,SAASD,CAAc,EAC9B,OAAO,KAAK,SAASA,CAAc,EAGrC,IAAME,EAAM,MAAMC,EAASH,EAAgBC,CAAmB,EAC9D,YAAK,SAASD,CAAc,EAAIE,EACzBA,CACT,CAOA,MAAM,eAAeE,EAAmBC,EAAoC,CAC1E,OAAOC,EAAmBF,EAAWC,CAAS,CAChD,CAMA,SAASH,EAAmC,CAC1C,OAAO,OAAO,KAAKA,EAAI,OAAS,CAAC,CAAC,CACpC,CAKA,YAAmB,CACjB,KAAK,SAAW,CAAC,CACnB,CACF,EQ5DAK,IAAA,OAAOC,MAAe,mBAwBf,IAAMC,EAAN,KAAmB,CAMxB,WAAWC,EAAiBC,EAAgD,CAC1E,GAAM,CAAE,cAAAC,EAAe,UAAAC,CAAU,EAAIF,EAE/BG,EAAeJ,EAAM,OAAO,CAACK,EAAKC,IAAS,CAC/C,IAAMC,EAAcL,EAAcI,CAAI,EAChCE,EAAWD,EAAcT,EAAUS,CAAW,EAAI,UAExD,OAAKF,EAAIG,CAAQ,IACfH,EAAIG,CAAQ,EAAI,CAAC,GAEnBH,EAAIG,CAAQ,EAAE,KAAKF,CAAI,EAChBD,CACT,EAAG,CAAC,CAA6B,EAG3BI,EAAoC,CAAC,EAC3C,OAAW,CAACD,EAAUR,CAAK,IAAK,OAAO,QAAQI,CAAY,EACzDK,EAAOD,CAAQ,EAAI,CACjB,SAAAA,EACA,MAAAR,EACA,WAAY,GAAGG,CAAS,IAAIK,CAAQ,mBACtC,EAGF,OAAOC,CACT,CAOA,kBACED,EACAP,EAC8D,CAC9D,MAAO,CAACS,EAAuBC,IAA6B,CAC1D,IAAML,EAAOK,EAAoB,KAG3BC,EAAed,EAAUG,EAAO,cAAcK,CAAI,GAAK,EAAE,EAC/D,OAAIM,IAAiBJ,IAAaI,GAAgB,aAAeJ,EACxD,GAILP,EAAO,eACFA,EAAO,eAAeS,EAAeJ,EAAME,CAAQ,EAGrD,EACT,CACF,CACF,ECnFAK,IAAA,OAAOC,OAAQ,UACf,OAAOC,MAAU,YCDjBC,IAAA,OAAOC,OAAU,YACjB,OAAOC,MAAQ,UAMf,eAAsBC,GAAsBC,EAAkB,CAC5D,IAAMC,EAAUJ,GAAK,QAAQG,CAAQ,EAChCF,EAAG,WAAWG,CAAO,GACxB,MAAMH,EAAG,SAAS,MAAMG,EAAS,CAAE,UAAW,EAAK,CAAC,CAExD,CDIO,IAAMC,EAAN,KAAwB,CAM7B,MAAM,UAAUC,EAAkBC,EAA2C,CAC3E,GAAI,CACF,IAAMC,EAAeC,EAAK,QAAQ,QAAQ,IAAI,EAAGH,CAAQ,EACzD,aAAMI,GAAsBF,CAAY,EAExCG,GAAG,cAAcH,EAAcD,CAAO,EAE/B,CACL,KAAMC,EACN,QAAS,EACX,CACF,OAASI,EAAO,CACd,MAAO,CACL,KAAMN,EACN,QAAS,GACT,MAAOM,CACT,CACF,CACF,CAMA,MAAM,WAAWC,EAA2D,CAC1E,IAAMC,EAA6B,CAAC,EAEpC,OAAW,CAACR,EAAUC,CAAO,IAAK,OAAO,QAAQM,CAAK,EAAG,CACvD,IAAME,EAAS,MAAM,KAAK,UAAUT,EAAUC,CAAO,EACrDO,EAAQ,KAAKC,CAAM,CACrB,CAEA,OAAOD,CACT,CAOA,MAAM,gBACJE,EACAH,EAM4B,CAC5B,IAAMI,EAAuC,CAAC,EAE9C,OAAIJ,EAAM,QACRI,EAAaR,EAAK,KAAKO,EAAgB,UAAU,CAAC,EAAIH,EAAM,OAG1DA,EAAM,aACRI,EAAaR,EAAK,KAAKO,EAAgB,gBAAgB,CAAC,EAAIH,EAAM,YAGhEA,EAAM,eACRI,EAAaR,EAAK,KAAKO,EAAgB,kBAAkB,CAAC,EAAIH,EAAM,cAGlEA,EAAM,QACRI,EAAaR,EAAK,KAAKO,EAAgB,UAAU,CAAC,EAAIH,EAAM,OAGvD,KAAK,WAAWI,CAAY,CACrC,CAOA,MAAM,iBACJC,EACAC,EAM4B,CAC5B,IAAMF,EAAuC,CAAC,EAE9C,OAAIE,EAAY,cACdF,EAAaR,EAAK,KAAKS,EAAW,iBAAiB,CAAC,EAAIC,EAAY,aAGlEA,EAAY,YACdF,EAAaR,EAAK,KAAKS,EAAW,eAAe,CAAC,EAAIC,EAAY,WAGhEA,EAAY,cACdF,EAAaR,EAAK,KAAKS,EAAW,kBAAkB,CAAC,EAAIC,EAAY,aAGnEA,EAAY,QACdF,EAAaR,EAAK,KAAKS,EAAW,UAAU,CAAC,EAAIC,EAAY,OAGxD,KAAK,WAAWF,CAAY,CACrC,CAUA,MAAM,gBACJC,EACAE,EAC4B,CAC5B,IAAMH,EAAuC,CAAC,EAE9C,OAAAA,EAAaR,EAAK,KAAKS,EAAW,WAAW,CAAC,EAAIE,EAE3C,KAAK,WAAWH,CAAY,CACrC,CAGF,EEnJAI,IAAA,OAAOC,OAAkB,oBAQlB,IAAMC,EAAN,KAA2B,CAGhC,YACUC,EACRC,EACA,CAFQ,WAAAD,EAGR,KAAK,OAAS,IAAIE,GAAaF,EAAO,CACpC,eAAgBC,EAAQ,eACxB,YAAaA,EAAQ,YACrB,mBAAoBA,EAAQ,kBAC9B,CAAC,CACH,CAXQ,OAgBR,YAAmB,CACb,KAAK,OAAO,KAAK,YAAY,UAC/B,KAAK,OAAO,qBAAqB,KAAK,OAAO,KAAK,WAAW,OAAO,EAGpE,OAAO,KAAK,KAAK,OAAO,KAAK,WAAW,OAAO,EAAE,QAAQE,GAAc,CACrE,GAAI,CACF,KAAK,OAAO,YAAY,CAAE,KAAM,wBAAwBA,CAAU,EAAG,CAAC,CACxE,MAAgB,CAEhB,CACF,CAAC,EAEL,CAMA,wBAAwBC,EAAuB,CAC7C,GAAM,CAAE,iBAAAC,CAAiB,EAAI,aAC7B,OAAOC,EAAwB,KAAK,KAAK,EAAE,OAAOD,EAAiBD,CAAe,CAAC,CACrF,CAKA,iBAAgC,CAC9B,OAAO,KAAK,MACd,CAKA,aAAkC,CAChC,OAAO,KAAK,KACd,CAKA,oBAAkC,CAGhC,OAFwB,IAAI,GAG9B,CACF,ECvEAG,ICAAC,IAOO,SAASC,IAAoB,CAGlC,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAcT,CAMO,SAASC,GAAYC,EAAqB,CAC/C,OAAOA,EAAI,YAAY,EAAE,QAAQ,YAAa,CAACC,EAAGC,IAAWA,EAAO,YAAY,CAAC,CACnF,CD7BO,SAASC,GAAsBC,EAIlC,CAGF,IAAMC,EAAcD,EAAiB,OAAO,CAACE,EAAKC,KAC3CD,EAAIC,EAAK,QAAQ,IACpBD,EAAIC,EAAK,QAAQ,EAAI,CAAC,GAExBD,EAAIC,EAAK,QAAQ,EAAE,KAAK,CACtB,cAAeA,EAAK,cACpB,aAAcA,EAAK,YACrB,CAAC,EACMD,GACN,CAAC,CAAyE,EAY7E,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EATa,OAAO,QAAQD,CAAW,EAAE,IAAI,CAAC,CAACG,EAAUC,CAAI,IAAM,CACxE,IAAMC,EAAe,QAAQF,EAAS,OAAO,CAAC,EAAE,YAAY,EAAIA,EAAS,MAAM,CAAC,CAAC,sBAC3EG,EAAaF,EAAK,IAAIG,GAC1B,KAAKA,EAAI,YAAY,OAAOC,GAAYD,EAAI,YAAY,CAAC,IAC3D,EAAE,KAAK;AAAA,CAAI,EAEX,MAAO,GAAGF,CAAY;AAAA,EAAKC,CAAU,EACvC,CAAC,EAAE,KAAK;AAAA;AAAA,CAAM,CAQH;AAAA;AAAA;AAAA;AAAA,CAKb,CE1CAG,IAGO,SAASC,IAA0B,CAExC,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA0BT,CC/BAC,IAAA,OAAOC,MAAQ,aAOR,SAASC,GAA4BC,EAA+E,CACzH,IAAMC,EAAUH,EAAG,cAAc,CAAE,QAASA,EAAG,YAAY,QAAS,CAAC,EAE/DI,EAAaJ,EAAG,iBACpB,sBACA,GACAA,EAAG,aAAa,OAChB,GACAA,EAAG,WAAW,EAChB,EAGA,MAAO;AAAA;AAAA;AAAA,EAGP,OAAO,OAAOE,CAAU,EAAE,IAAIG,GAAKF,EAAQ,UAAUH,EAAG,SAAS,YAAaK,EAAGD,CAAU,CAAC,EAAE,KAAK;AAAA,CAAI,CAAC;AAAA,CAE1G,CCxBAE,IAKO,SAASC,IAAkC,CAChD,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAoBT,CC1BAC,IACA,OAAOC,OAAQ,aCDfC,IACAC,IAEA,OAAS,sBAAAC,OAA0B,oBAsB5B,IAAMC,EAAN,KAA4B,CACjC,YACUC,EACR,CADQ,aAAAA,CACP,CAMH,qBAAqBC,EAA6D,CAChF,OAAOA,EAAqB,IAAKC,GACxB,KAAK,0BAA0BA,CAAmB,CAC1D,CACH,CAMQ,0BAA0BA,EAAwD,CACxF,GAAM,CAAE,KAAAC,EAAM,KAAAC,EAAM,UAAAC,CAAU,EAAIH,EAC5B,CAAE,oBAAAI,EAAsB,GAAI,UAAAC,EAAY,MAAO,eAAAC,EAAiB,MAAO,WAAAC,EAAY,kBAAAC,CAAkB,EAAI,KAAK,QAG9GC,EAAgBC,EAAiB,CAAE,KAAAT,EAAM,KAAAC,CAAK,CAAC,EAC/CS,EAAqBP,EAAsBQ,EAAWH,EAAgBL,CAAmB,EAAIK,EAG7FI,EAAcD,EAAWH,EAAgBL,EAAsBC,CAAS,EACxES,EAAmBF,EAAWH,EAAgBL,EAAsBE,CAAc,EAGlFS,EAAUA,EAAYd,EAAMC,EAAMc,EAAahB,EAAqBQ,CAAiB,EAAGD,CAAU,EAGlGU,EAAe,GAAGR,EAAc,QAAQ,WAAY,KAAK,EAAE,YAAY,CAAC,GAGxES,GAAUf,EAAU,SAAW,GAAGF,EAAK,YAAY,CAAC,IAAIC,CAAI,GAG5D,CAAE,YAAAiB,GAAa,WAAAC,GAAY,UAAAC,EAAU,EAAI,KAAK,kBAAkBrB,CAAmB,EAEzF,MAAO,CACL,cAAeW,EACf,YAAAE,EACA,iBAAAC,EACA,QAAAC,EACA,KAAMd,EAAK,YAAY,EACvB,KAAAC,EACA,aAAAe,EACA,YAAAE,GACA,WAAAC,GACA,UAAAC,GACA,QAAAH,EACF,CACF,CAMQ,kBAAkBlB,EAA0C,CAClE,GAAM,CAAE,UAAAG,EAAW,SAAAmB,CAAS,EAAItB,EAG1BuB,EAAsB,KAAK,aAAapB,EAAU,UAAU,EAC5DqB,EAAqB,KAAK,aAAaF,EAAS,UAAU,EAC7D,OAAQG,GAAO,CAACF,EAAoB,KAAMG,GAAOA,EAAG,OAASD,EAAG,MAAQC,EAAG,KAAOD,EAAG,EAAE,CAAC,EAErFE,EAAgB/B,GAAmB,CAAC,GAAG4B,EAAoB,GAAGD,CAAmB,CAAC,EACrF,OAAQK,GAAUA,EAAM,KAAO,QAAQ,EAEpCT,EAAcQ,EAAc,OAAOC,GAASA,EAAM,KAAO,OAAO,EAChER,EAAaO,EAAc,OAAOC,GAASA,EAAM,KAAO,MAAM,EAG9DP,EAAYF,EAAY,SAAW,GAAKC,EAAW,SAAW,GAAK,CAACjB,EAAU,YAEpF,MAAO,CACL,YAAAgB,EACA,WAAAC,EACA,UAAAC,CACF,CACF,CAKQ,aAAaQ,EAAwB,CAC3C,OAAKA,EACE,MAAM,QAAQA,CAAU,EAAIA,EAAa,CAACA,CAAU,EADnC,CAAC,CAE3B,CACF,ECtHAC,IAiBO,SAASC,GACdC,EACAC,EACAC,EACAC,EACA,CAGA,IAAIC,EAAkB;AAAA;AAAA;AAAA,EAMCF,GAAoB,OAAO,KAAKA,CAAgB,EAAE,OAAS,IAEhFE,GAAmB;AAAA,GAGrBA,GAAmB;AAAA,EAGnB,IAAMC,EAA4B,CAAC,EAM7BC,EAA0B,CAAC,EAGjC,OAAAN,EAAc,QAAQO,GAAY,CAEhC,IAAMC,EAAcD,EAAS,YACvBE,EAAcF,EAAS,iBAG7B,GAAIC,EAAa,CACf,IAAME,EAAqBC,GAA2BJ,EAAUJ,CAAoB,EAChFO,EAAmB,KAAK,IAAM,IAAMA,EAAmB,SAAS,MAAM,GAAKA,EAAmB,SAAS,oBAAoB,EAE7HJ,EAAc,KACZ,eAAeE,CAAW,WAC1B,EACF,EAGAF,EAAc,KACZ,eAAeE,CAAW,OAC1BE,EACA,KACA,EACF,CAEJ,CAGA,GAAID,EAAa,CACf,IAAMG,EAAsBC,GAA4BN,EAAUJ,CAAoB,EAClFS,EAAoB,KAAK,IAAM,IAAMA,EAAoB,SAAS,MAAM,GAAKA,EAAoB,SAAS,oBAAoB,EAEhIN,EAAc,KACZ,eAAeG,CAAW,WAC1B,EACF,EAGAH,EAAc,KACZ,eAAeG,CAAW,OAC1BG,EACA,KACA,EACF,CAEJ,CACF,CAAC,EAEGN,EAAc,OAAS,GACzBD,EAAgB,KAAKC,EAAc,KAAK;AAAA,CAAI,CAAC,EAI3CD,EAAgB,SAAW,GAC7BA,EAAgB,KACd,mFACA,wFACA,EACF,EAGKD,EAAkBC,EAAgB,KAAK;AAAA;AAAA,CAAM,CACtD,CAKA,SAASM,GAA2BJ,EAAwBJ,EAAsC,CAChG,IAAMW,EAAuB,CAAC,EAG1BP,EAAS,aAAeA,EAAS,YAAY,OAAS,GACxDA,EAAS,YAAY,QAAQQ,GAAS,CACpC,IAAMC,EAAWD,EAAM,SAAW,GAAK,IACjCE,EAAYC,GAAqBH,CAAK,EAC5CD,EAAW,KAAK,KAAKC,EAAM,IAAI,GAAGC,CAAQ,KAAKC,CAAS,GAAG,CAC7D,CAAC,EAICV,EAAS,YAAcA,EAAS,WAAW,OAAS,GACtDA,EAAS,WAAW,QAAQQ,GAAS,CACnC,IAAMC,EAAWD,EAAM,SAAW,GAAK,IACjCE,EAAYC,GAAqBH,CAAK,EAC5CD,EAAW,KAAK,KAAKC,EAAM,IAAI,GAAGC,CAAQ,KAAKC,CAAS,GAAG,CAC7D,CAAC,EAIH,IAAME,EAAehB,GAAsB,KAAKiB,GAEvCA,EAAG,WAAW,cAAgBb,EAAS,eACvCa,EAAG,WAAW,cAAgBb,EAAS,cAAc,YAAY,GAEhEa,EAAG,OAASb,EAAS,KAAK,YAAY,GAAKa,EAAG,OAASb,EAAS,IACzE,EAED,GAAIY,GAAc,WAAW,YAAa,CAExC,IAAME,EADcF,EAAa,UAAU,YACf,QAGtBG,EAAcD,EAAQ,kBAAkB,EACxCE,EAAcF,EAAQ,qBAAqB,GAAKA,EAAQ,mCAAmC,EAEjG,GAAIC,GAAa,OAAQ,CACvB,IAAME,EAAWC,EAAkBH,EAAY,MAAM,EACrDR,EAAW,KAAK,WAAWU,CAAQ,GAAG,CACxC,SAAWD,GAAa,OAAQ,CAC9B,IAAMC,EAAWC,EAAkBF,EAAY,MAAM,EACrDT,EAAW,KAAK,WAAWU,CAAQ,GAAG,CACxC,MACEV,EAAW,KAAK,4CAA4C,CAEhE,CAGA,OAAIA,EAAW,SAAW,EACjB,GAGFA,EAAW,KAAK;AAAA,CAAI,CAC7B,CAKA,SAASD,GAA4BN,EAAwBJ,EAAsC,CACjG,IAAMW,EAAuB,CAAC,EAGxBK,EAAehB,GAAsB,KAAKiB,GAEvCA,EAAG,WAAW,cAAgBb,EAAS,eACvCa,EAAG,WAAW,cAAgBb,EAAS,cAAc,YAAY,GAEhEa,EAAG,OAASb,EAAS,KAAK,YAAY,GAAKa,EAAG,OAASb,EAAS,IACzE,EAED,GAAIY,GAAc,WAAW,UAAW,CAEtC,IAAMO,EAAkBP,EAAa,UAAU,UAAU,GAAK,GACvCA,EAAa,UAAU,UAAU,GAAK,EAE7D,GAAIO,GAAiB,QAAS,CAC5B,IAAMJ,EAAcI,EAAgB,QAAQ,kBAAkB,EAC9D,GAAIJ,GAAa,OAAQ,CACvB,IAAMK,EAAgBC,GAAsBN,EAAY,MAAM,EAC9DR,EAAW,KAAK,GAAGa,CAAa,CAClC,MACEb,EAAW,KAAK,oCAAoC,EACpDA,EAAW,KAAK,eAAe,CAEnC,CACF,CAGA,OAAIA,EAAW,SAAW,EACjB,GAGFA,EAAW,KAAK;AAAA,CAAI,CAC7B,CAKA,SAASc,GAAsBC,EAAuB,CACpD,IAAMf,EAAuB,CAAC,EAE9B,GAAIe,EAAO,OAAS,UAAYA,EAAO,WAAY,CACjD,IAAMC,EAAWD,EAAO,UAAY,CAAC,EAErC,OAAO,QAAQA,EAAO,UAAU,EAAE,QAAQ,CAAC,CAACE,EAAUC,CAAU,IAAqB,CAEnF,IAAMhB,EADac,EAAS,SAASC,CAAQ,EACf,GAAK,IAC7BE,EAAWR,EAAkBO,CAAU,EACvCE,EAAcF,EAAW,YAAc,OAAOA,EAAW,WAAW,GAAK,GAE/ElB,EAAW,KAAK,KAAKiB,CAAQ,GAAGf,CAAQ,KAAKiB,CAAQ,IAAIC,CAAW,EAAE,CACxE,CAAC,CACH,CAEA,OAAOpB,CACT,CAKA,SAASW,EAAkBI,EAAqB,CAC9C,GAAI,CAACA,EAAQ,MAAO,MAGpB,GAAIA,EAAO,KAAM,CACf,IAAMM,EAAUN,EAAO,KACvB,GAAIM,EAAQ,WAAW,uBAAuB,EAE5C,MAAO,UADUA,EAAQ,QAAQ,wBAAyB,EAAE,CACnC,EAE7B,CAEA,OAAQN,EAAO,KAAM,CACnB,IAAK,SACH,OAAIA,EAAO,KACFA,EAAO,KAAK,IAAKO,GAAgB,IAAIA,CAAG,GAAG,EAAE,KAAK,KAAK,EAEzD,SACT,IAAK,SACL,IAAK,UACH,MAAO,SACT,IAAK,UACH,MAAO,UACT,IAAK,QAEH,MAAO,GADUP,EAAO,MAAQJ,EAAkBI,EAAO,KAAK,EAAI,KAChD,KACpB,IAAK,SACH,OAAIA,EAAO,WAQF,KANO,OAAO,QAAQA,EAAO,UAAU,EAAE,IAAI,CAAC,CAACQ,EAAKL,CAAU,IAAqB,CAExF,IAAMhB,GADWa,EAAO,UAAY,CAAC,GACX,SAASQ,CAAG,EAAI,GAAK,IACzCC,EAAOb,EAAkBO,CAAU,EACzC,MAAO,GAAGK,CAAG,GAAGrB,CAAQ,KAAKsB,CAAI,EACnC,CAAC,EAAE,KAAK,IAAI,CACK,KAEZ,MACT,QACE,MAAO,KACX,CACF,CAKA,SAASpB,GAAqBH,EAAoB,CAChD,OAAKA,EAAM,OACJU,EAAkBV,EAAM,MAAM,EADX,KAE5B,CC5RAwB,IAEO,SAASC,GAAkBC,EAAkBC,EAA4B,CAC9E,GAAM,CAAE,SAAUC,CAAgB,EAAID,EAGtC,MAAO;AAAA;AAAA;AAAA,CAIT,CCVAE,ICAAC,IAEO,SAASC,GAAyBC,EAYrCC,EAA4B,CAE9B,GAAM,CAAE,SAAAC,EAAU,0BAAAC,EAA4B,EAAG,EAAIF,EAG/CG,EAAmBF,EACvB,GAAGA,EAAS,OAAO,CAAC,EAAE,YAAY,EAAIA,EAAS,MAAM,CAAC,CAAC,eACvD,eAEIG,EAAiBH,EACrB,GAAGA,EAAS,OAAO,CAAC,EAAE,YAAY,EAAIA,EAAS,MAAM,CAAC,CAAC,aACvD,aAGII,EAAeN,EAClB,OAAOO,GAAQA,EAAK,OAAO,EAC3B,IAAIA,GAAQ;AAAA;AAAA,OAEVA,EAAK,OAAO;AAAA;AAAA,IAEfA,EAAK,aAAa,SAASA,EAAK,cAAgB,aAAe,sCAAsCA,EAAK,WAAW,IAAM,EAAE,4BAA4BA,EAAK,gBAAgB;AAAA,iCACjJA,EAAK,gBAAgB,KAAKA,EAAK,cAAgB,aAAe,gCAAgCA,EAAK,WAAW,IAAM,MAAM;AAAA,8BAC7HA,EAAK,YAAY,GAAGA,EAAK,cAAgB,aAAe,mBAAqB,EAAE;AAAA;AAAA,iCAE5EA,EAAK,aAAa,IAAIA,EAAK,cAAgB,aAAe,OAAS,EAAE;AAAA;AAAA;AAAA;AAAA,QAI9FA,EAAK,cAAgB,aAAe,SAAW,IAAI;AAAA,IACvD,EAAE,KAAK,EAAE,EAELC,EAAkBR,EACrB,OAAOO,GAAQ,CAACA,EAAK,OAAO,EAC5B,IAAIA,GAAQ;AAAA;AAAA,OAEVA,EAAK,OAAO;AAAA;AAAA,IAEfA,EAAK,aAAa,gCAAgCA,EAAK,gBAAgB;AAAA,iBAC1DA,EAAK,cAAgB,aAAeA,EAAK,YAAc,MAAM;AAAA;AAAA;AAAA,oCAG1CA,EAAK,gBAAgB,KAAKA,EAAK,cAAgB,aAAe,gCAAgCA,EAAK,WAAW,IAAM,MAAM;AAAA,uBACvIA,EAAK,aAAa;AAAA,qBACpBA,EAAK,cAAgB,aAAe,OAAS,EAAE;AAAA,iCACnCA,EAAK,aAAa,IAAIA,EAAK,cAAgB,aAAe,OAAS,EAAE;AAAA;AAAA;AAAA,IAGlG,EAAE,KAAK,EAAE,EAELE,EAAmBT,EACtB,OAAOO,GAAQA,EAAK,OAAO,EAC3B,IAAIA,GAAQ;AAAA;AAAA,OAEVA,EAAK,OAAO;AAAA;AAAA,IAEfA,EAAK,aAAa;AAAA,gBACNA,EAAK,cAAgB,aAAe,sCAAsCA,EAAK,WAAW,MAAQ,EAAE,oDAAoDA,EAAK,gBAAgB;AAAA;AAAA;AAAA,kBAG3KA,EAAK,cAAgB,aAAe,SAAW,EAAE;AAAA;AAAA;AAAA,6DAGNA,EAAK,gBAAgB,iBAAiBA,EAAK,YAAY,GAAGA,EAAK,cAAgB,aAAe,mBAAqB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,iCAKjJA,EAAK,aAAa,IAAIA,EAAK,cAAgB,aAAe,OAAS,EAAE;AAAA;AAAA;AAAA,IAGlG,EAAE,KAAK,EAAE,EAEX,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQCF,CAAc;AAAA;AAAA,UAEdL,EAAc,IAAIO,GAAQ,IAAIA,EAAK,WAAW,KAAKA,EAAK,gBAAgB,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,eAKhFH,CAAgB;AAAA,gCACCC,CAAc;AAAA;AAAA,EAE5CC,CAAY,GAAGE,CAAe,GAAGC,CAAgB;AAAA;AAAA,CAGnD,CDrGO,IAAMC,EAAN,KAAyB,CAC9B,YAAoBC,EAA4B,CAA5B,aAAAA,CAA6B,CAKjD,qBAAqBC,EAAmC,CACtD,IAAMC,EAAmB,CACvB,GAAG,KAAK,QACR,iBAAkB,KAAK,QAAQ,kBAAoB,CACjD,KAAM,iBACN,WAAY,qBACd,CACF,EAEA,OAAOC,GAAyBF,EAAeC,CAAgB,CACjE,CACF,EEvBAE,ICAAC,IAEO,SAASC,GAAuBC,EAYnCC,EAA4B,CAE9B,GAAM,CAAE,iBAAAC,EAAkB,WAAAC,EAAY,SAAAC,CAAS,EAAIH,EAG7CI,EAAsBD,EAC1B,GAAGA,EAAS,OAAO,CAAC,EAAE,YAAY,EAAIA,EAAS,MAAM,CAAC,CAAC,aACvD,aAEF,MAAO;AAAA;AAAA;AAAA,WAGED,EAAY,UAAU,YAAYA,EAAY,IAAI;AAAA;AAAA;AAAA,WAGlDD,EAAkB,UAAU,YAAYA,EAAkB,IAAI;AAAA;AAAA;AAAA,UAG/DF,EAAc,IAAIM,GAAQ,IAAIA,EAAK,WAAW,KAAKA,EAAK,gBAAgB,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,eAKhFD,CAAmB;AAAA,4BACNH,EAAkB,UAAU;AAAA,0BAC9BC,EAAY,UAAU;AAAA;AAAA,EAE9CH,EAAc,IAAIM,GAAQ,CAC1B,IAAMC,EAAQD,EAAK,KAAK,YAAY,IAAM,MACpCE,EAAUF,EAAK,cAAgB,aAG/BG,EAAuBC,GACLA,EAAK,SAAS,GAAG,GAClBF,EAGZ,4BADaE,EAAK,QAAQ,eAAgB,sBAAsB,CACzB,KAEvC,4BAA4BA,CAAI,KAIrCC,EAAiBL,EAAK,YAAY,OAAS,EAC3CM,EAAU,CAACL,GAASC,GAAW,CAACF,EAAK,UAGrCO,EAAyB,IAAM,CACnC,IAAMZ,EAAU,CACd,sBACF,EAGA,OAAIW,GAAW,CAACL,IACdN,EAAQ,KAAK,gFAAgF,EAG3FU,GAAkBH,GACpBP,EAAQ,KAAKa,GAAoBR,EAAK,WAAW,CAAC,EAGhDM,GACFX,EAAQ,KAAK,2BAA2B,EAGnCA,EAAQ,OAAS,EAAI,KAAKA,EAAQ,KAAK,IAAI,CAAC,KAAO,IAC5D,EAEE,MAAO;AAAA;AAAA,OAEJK,EAAK,OAAO;AAAA;AAAA,IAEfA,EAAK,aAAa;AAAA,MAChBE,EAAU,sCAAsCF,EAAK,WAAW,MAAQ,EAAE;AAAA,kBAC9DA,EAAK,gBAAgB;AAAA,kBACrBG,EAAoBH,EAAK,IAAI,CAAC;AAAA,gCAChBA,EAAK,KAAK,YAAY,CAAC,WAAWO,EAAuB,CAAC;AAAA,IAK1F,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA,CAGX,CAOA,SAASC,GAAoBC,EAAuC,CAKlE,MAAO,8BAJcA,EAAY,IAAIC,GACnC,GAAGA,EAAM,IAAI,oBAAoBA,EAAM,IAAI,EAC7C,EAAE,KAAK,IAAI,CAEsC,KACnD,CDzGO,IAAMC,EAAN,KAA0B,CAC/B,YAAoBC,EAA4B,CAA5B,aAAAA,CAA6B,CAKjD,mBAAmBC,EAAmC,CACpD,IAAMC,EAAmB,CACvB,GAAG,KAAK,QACR,iBAAkB,KAAK,QAAQ,kBAAoB,CACjD,KAAM,iBACN,WAAY,qBACd,CACF,EAEA,OAAOC,GAAuBF,EAAeC,CAAgB,CAC/D,CACF,ENLO,IAAME,EAAN,KAAuB,CAK5B,YACUC,EACAC,EACR,CAFQ,mBAAAD,EACA,aAAAC,EAIR,KAAK,cAAgB,IAAIC,EAAsBD,CAAO,EAGtD,KAAK,eAAiB,IAAIE,EAAmBF,CAAO,EACpD,KAAK,oBAAsB,IAAIG,EAAoBH,CAAO,CAC5D,CAfQ,cACA,eACA,oBAkBR,MAAM,UAAuC,CAI3C,IAAMI,EAAuB,KAAK,cAAc,wBAAwB,KAAK,QAAQ,eAAe,EAG9FC,EAAgB,KAAK,cAAc,qBAAqBD,CAAoB,EAI5EE,EAAe,KAAK,cAAcD,CAAa,EAG/CE,EAAoB,KAAK,mBAAmBF,CAAa,EACzDG,EAAsB,KAAK,qBAAqBH,CAAa,EAC7DI,EAAe,KAAK,cAAc,EAGlCC,EAAuBL,EAC1B,OAAOM,GAAQA,EAAK,OAAO,EAC3B,IAAIA,IAAS,CACZ,cAAeA,EAAK,cACpB,aAAcA,EAAK,aACnB,SAAU,KAAK,QAAQ,UAAY,SACrC,EAAE,EAOJ,MAAO,CACL,eALqBN,EAAc,IAAIM,GAAQA,EAAK,aAAa,EAMjE,MAAO,CACL,MAAOL,EACP,WAAYC,EACZ,aAAcC,EACd,MAAOC,EACP,qBAAsBC,CACxB,CACF,CACF,CAKQ,cAAcL,EAAmC,CACvD,IAAMO,EAAmB,CACvB,GAAG,KAAK,QACR,iBAAkB,KAAK,QAAQ,kBAAoB,CACjD,KAAM,iBACN,WAAY,qBACd,CACF,EAIMC,EADS,KAAK,cAAc,gBAAgB,EAClB,QAAQ,OAA0E,CAACC,EAAMC,IAAU,CACjI,GAAIC,GAAG,uBAAuBD,CAAK,GAAKC,GAAG,uBAAuBD,CAAK,EAAG,CACxE,IAAME,EAAOF,EAAM,KAAK,KACxB,MAAO,CACL,GAAGD,EACH,CAACG,CAAI,EAAGF,CACV,CACF,CACA,OAAOD,CACT,EAAG,CAAC,CAAC,EAGCV,EAAuB,KAAK,cAAc,wBAAwB,KAAK,QAAQ,eAAe,EAEpG,OAAOc,GAAkBb,EAAeO,EAAkBC,EAAkBT,CAAoB,CAClG,CAKQ,mBAAmBC,EAAmC,CAC5D,OAAO,KAAK,oBAAoB,mBAAmBA,CAAa,CAClE,CAKQ,qBAAqBA,EAAmC,CAC9D,OAAO,KAAK,eAAe,qBAAqBA,CAAa,CAC/D,CAKQ,eAAwB,CAC9B,IAAMO,EAAmB,CACvB,GAAG,KAAK,QACR,iBAAkB,KAAK,QAAQ,kBAAoB,CACjD,KAAM,iBACN,WAAY,qBACd,CACF,EAEA,OAAOO,GAAkB,KAAK,QAAQ,UAAY,GAAIP,CAAgB,CACxE,CAeF,ElBxGO,IAAMQ,EAAN,KAA2B,CACxB,SAEA,eAAiB,IAAIC,EACrB,aAAe,IAAIC,EACnB,kBAAoB,IAAIC,EAGxB,WAAwC,KACxC,cAA6C,KAC7C,iBAAsF,CAAC,EACvF,qBAA2C,CAAC,EAC5C,iBAA2B,GAG3B,iBAWJ,CACF,OAAQ,CAAC,EACT,UAAW,KACX,YAAa,GACb,gBAAiB,GACjB,YAAa,GACb,MAAO,EACT,EAGA,YAAYC,EAAmC,CAC7C,KAAK,SAAWA,CAClB,CAOA,MAAM,aAAgD,CACpD,aAAM,KAAK,QAAQ,EAGnB,MAAM,KAAK,YAAY,EAIvB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAEzB,MAAM,KAAK,QAAQ,CAC5B,CAOA,MAAM,SAAyB,CAI7B,KAAK,iBAAmB,KAAK,SAAS,WAClC,KAAK,SAAS,aAChB,KAAK,iBAAmB,MAAM,KAAK,eAAe,eAChD,KAAK,SAAS,WACd,KAAK,SAAS,UAChB,GAIF,KAAK,WAAa,MAAM,KAAK,eAAe,YAC1C,KAAK,iBACL,KAAK,SAAS,mBAChB,EAGA,KAAK,cAAgB,IAAIC,EAAqB,KAAK,WAAY,KAAK,QAAQ,EAC5E,KAAK,cAAc,WAAW,EAG9B,IAAMC,EAAS,KAAK,cAAc,gBAAgB,EAClD,KAAK,iBAAmBA,EAAO,QAAQ,OAA0E,CAACC,EAAMC,IAAU,CAChI,GAAIC,GAAG,uBAAuBD,CAAK,GAAKC,GAAG,uBAAuBD,CAAK,EAAG,CACxE,IAAME,EAAOF,EAAM,KAAK,KACxB,MAAO,CACL,GAAGD,EACH,CAACG,CAAI,EAAGF,CACV,CACF,CACA,OAAOD,CACT,EAAG,CAAC,CAAC,CAGP,CAOA,MAAM,aAA6B,CACjC,GAAI,CAAC,KAAK,YAAc,CAAC,KAAK,cAC5B,MAAM,IAAI,MAAM,iDAAmB,EAMrC,IAAMI,EAAQ,KAAK,eAAe,SAAS,KAAK,UAAU,EACpDC,EAAa,KAAK,aAAa,WAAWD,EAAO,KAAK,SAAS,WAAW,EAGhF,QAAWE,KAAa,OAAO,OAAOD,CAAU,EAC9C,GAAI,CACF,IAAME,EAAe,MAAM,KAAK,wBAC9B,KAAK,SACLD,CACF,EAGIC,EAAa,eAAe,OAAS,GACvC,KAAK,iBAAiB,OAAO,KAAK,CAChC,SAAUD,EAAU,SACpB,WAAYA,EAAU,WACtB,QAASC,CACX,CAAC,CAGL,OAASC,EAAO,CACd,MAAM,IAAI,MAAM,gBAAMF,EAAU,QAAQ,8BAAUE,CAAK,EAAE,CAC3D,CAIJ,CAMA,MAAc,0BAA0C,CACtD,KAAK,iBAAiB,UAAYC,GAAsB,KAAK,oBAAoB,CACnF,CAKA,MAAc,4BAA4C,CACxD,KAAK,iBAAiB,YAAcC,GAAwB,CAC9D,CAKA,MAAc,uBAAuC,CACnD,KAAK,iBAAiB,gBAAkBC,GAA4B,KAAK,gBAAgB,CAC3F,CAKA,MAAc,4BAA4C,CACxD,KAAK,iBAAiB,YAAcC,GAAwB,CAC9D,CAMA,MAAc,sBAAsC,CAClD,KAAK,iBAAiB,MAAQC,GAAkB,CAClD,CAQA,MAAM,SAA4C,CAChD,IAAMC,EAA6B,CAAC,EAC9BC,EAAkB,CAAC,EACnBC,EAA4B,CAAC,EAInC,GAAI,CAEF,QAAWC,KAAS,KAAK,iBAAiB,OACxC,GAAI,CACF,GAAIA,EAAM,SAAS,MAAO,CACxB,IAAMC,EAAiBC,EAAK,QAAQF,EAAM,UAAU,EAC9CG,EAAe,MAAM,KAAK,kBAAkB,gBAChDF,EACA,CACE,MAAOD,EAAM,QAAQ,MAAM,MAC3B,WAAYA,EAAM,QAAQ,MAAM,WAChC,aAAcA,EAAM,QAAQ,MAAM,aAClC,MAAOA,EAAM,QAAQ,MAAM,KAC7B,CACF,EACAH,EAAQ,KAAK,GAAGM,CAAY,EAC5BJ,EAAgB,KAAKC,EAAM,QAAQ,CACrC,CACF,OAAST,EAAO,CACdO,EAAO,KAAK,IAAI,MAAM,4BAAQE,EAAM,QAAQ,kBAAQT,CAAK,EAAE,CAAC,CAC9D,CAIF,IAAMa,EAAY,KAAK,iBAAiB,OAAO,CAAC,EAC9CF,EAAK,QAAQA,EAAK,QAAQ,KAAK,iBAAiB,OAAO,CAAC,EAAE,UAAU,CAAC,EACrE,cAGF,GAAI,KAAK,iBAAiB,WAAa,KAAK,iBAAiB,aAAe,KAAK,iBAAiB,aAAe,KAAK,iBAAiB,MAAO,CAC5I,IAAMG,EAAgB,MAAM,KAAK,kBAAkB,iBACjDD,EACA,CACE,UAAW,KAAK,iBAAiB,WAAa,OAC9C,YAAa,KAAK,iBAAiB,aAAe,OAClD,YAAa,KAAK,iBAAiB,aAAe,OAClD,MAAO,KAAK,iBAAiB,OAAS,MACxC,CACF,EACAP,EAAQ,KAAK,GAAGQ,CAAa,CAC/B,CAGA,GAAI,KAAK,iBAAiB,gBAAiB,CACzC,IAAMC,EAAgB,MAAM,KAAK,kBAAkB,gBACjDF,EACA,KAAK,iBAAiB,eACxB,EACAP,EAAQ,KAAK,GAAGS,CAAa,CAC/B,CAEF,OAASf,EAAO,CACdO,EAAO,KAAKP,CAAc,CAC5B,CAIA,MAAO,CACL,QAASO,EAAO,SAAW,EAC3B,aAAcD,EACd,OAAAC,EACA,gBAAAC,CACF,CACF,CAMA,MAAc,wBACZnB,EACAS,EACc,CACd,GAAM,CAAE,YAAAkB,EAAa,GAAGC,CAAa,EAAI5B,EAGnC6B,EAAkC,CACtC,GAAGD,EACH,WAAY,KAAK,iBACjB,WAAYnB,EAAU,WACtB,gBAAiB,GAAGkB,EAAY,SAAS,mBACzC,gBAAiB,KAAK,aAAa,kBAAkBlB,EAAU,SAAUkB,CAAW,EACpF,WAAYA,EAAY,WACxB,SAAUlB,EAAU,QACtB,EAGA,GAAI,CAAC,KAAK,YAAc,CAAC,KAAK,cAC5B,MAAM,IAAI,MAAM,sFAA+B,EAIjD,IAAMqB,EAAS,MADM,IAAIC,EAAiB,KAAK,cAAeF,CAAY,EACxC,SAAS,EAG3C,GAAIC,EAAO,OAAS,yBAA0BA,EAAO,MAAO,CAC1D,IAAME,EAAYF,EAAO,MAAM,qBAC/B,KAAK,qBAAqB,KAAK,GAAGE,CAAS,CAC7C,CAEA,OAAOF,CACT,CAGF,EDvVA,eAAsBG,GAAkBC,EAA2D,CAGjG,IAAMC,EAAS,MAFG,IAAIC,EAAqBF,CAAO,EAEnB,YAAY,EAE3C,GAAI,CAACC,EAAO,SACNA,EAAO,OAAO,OAAS,EACzB,MAAMA,EAAO,OAAO,CAAC,CAI3B,CFZA,IAAME,GAAUC,GAAcC,CAAU,EAWxC,eAAsBC,GAAcC,EAAmC,CACrE,IAAMC,EAAqBC,GAAQ,QAAQ,IAAI,EAAGF,CAAU,EAC5D,QAAQ,MAAMG,GAAQF,CAAkB,CAAC,EAEzC,IAAMG,EAAiBR,GAAQK,CAAkB,EAC3CI,EAASD,EAAe,SAAWA,EAEnC,gBAAiBC,IACrB,QAAQ,MAAM,+FAA+F,EAC7G,QAAQ,KAAK,CAAC,GAIZA,EAAO,aAAeA,EAAO,YAAY,WAC3CC,EAAqBD,EAAO,YAAY,SAAS,EAGnD,GAAI,CACF,QAAQ,IAAI,gCAAgC,EAC5C,MAAME,GAAkBF,CAAM,EAC9B,QAAQ,IAAI,MAAM,CACpB,OAASG,EAAK,CACZ,QAAQ,MAAM,qBAAsBA,CAAG,EACvC,QAAQ,KAAK,CAAC,CAChB,CACF,CAOA,eAAeC,IAAsB,CACnC,IAAMC,EAAOd,GAAQ,oBAAoB,EACnCe,EAAuBC,EAAuB,EAEpDC,EACG,QAAQH,EAAK,OAAO,EACpB,MAAM,qBAAqB,EAC3B,MAAM,QAAQ,IAAI,EAErB,IAAMV,EAAaa,EAAQ,KAAK,CAAC,EAEjC,GAAIA,EAAQ,KAAK,SAAW,EAAG,CAC7BA,EAAQ,KAAK,EACb,MACF,CAEAC,EAAmBd,CAAU,EAC7Be,EAA0Bf,EAAYW,CAAoB,EAE1D,MAAMZ,GAAcC,CAAU,CAChC,CAEAS,GAAK,EAAE,MAAOD,GAAQ,CACpB,QAAQ,MAAM,wBAAyBA,CAAG,EAC1C,QAAQ,KAAK,CAAC,CAChB,CAAC","names":["fileURLToPath","getFilename","__filename","init_esm_shims","__esmMin","http_exports","__export","argumentMatches","defaultIsDataResponse","getOperationName","getOverrides","getTags","operationMatches","_getOperationName","code","includeDefault","parsedCode","verb","path","pathItem","patternMatches","pattern","filters","operationName","filter","checkMatch","operationDefinition","argumentDefinition","argumentName","operation","endpointOverrides","override","init_http","__esmMin","init_esm_shims","init_esm_shims","program","createRequire","init_esm_shims","program","createRequire","resolve","existsSync","rmSync","require","__filename","cleanOutputDirectory","outputDir","dangerousPaths","normalizedPath","path","setupTypeScriptSupport","validateConfigFile","configFile","validateTypeScriptSupport","hasTypeScriptSupport","dirname","resolve","init_esm_shims","init_esm_shims","path","ts","init_esm_shims","init_esm_shims","capitalize","str","init_esm_shims","fs","path","init_esm_shims","isValidUrl","string","downloadSchemaFile","remoteFile","targetPath","isValidUrl","dir","path","fs","response","content","error","init_esm_shims","init_esm_shims","operationKeys","getOperationDefinitions","v3Doc","path","pathItem","arg","operationKeys","verb","operation","init_esm_shims","SwaggerParser","converter","getV3Doc","spec","httpResolverOptions","doc","init_esm_shims","isQuery","verb","path","overrides","queryMatch","OpenApiService","schemaLocation","httpResolverOptions","doc","getV3Doc","remoteUrl","localPath","downloadSchemaFile","init_esm_shims","camelCase","GroupService","paths","config","groupKeyMatch","outputDir","groupedPaths","acc","path","rawGroupKey","groupKey","result","operationName","operationDefinition","pathGroupKey","init_esm_shims","fs","path","init_esm_shims","path","fs","ensureDirectoryExists","filePath","dirname","FileWriterService","filePath","content","resolvedPath","path","ensureDirectoryExists","fs","error","files","results","result","groupOutputDir","filesToWrite","outputDir","sharedFiles","schema","init_esm_shims","ApiGenerator","OpenApiParserService","v3Doc","options","ApiGenerator","schemaName","filterEndpoints","operationMatches","getOperationDefinitions","init_esm_shims","init_esm_shims","generateUtilsFile","toCamelCase","str","_","letter","generateCacheKeysFile","allEndpointInfos","groupedKeys","acc","info","groupKey","keys","groupComment","keyEntries","key","toCamelCase","init_esm_shims","generateCommonTypesFile","init_esm_shims","ts","generateComponentSchemaFile","interfaces","printer","resultFile","i","init_esm_shims","generateDoNotModifyFile","init_esm_shims","ts","init_esm_shims","init_http","supportDeepObjects","EndpointInfoExtractor","options","operationDefinitions","operationDefinition","verb","path","operation","operationNameSuffix","argSuffix","responseSuffix","queryMatch","endpointOverrides","operationName","getOperationName","finalOperationName","capitalize","argTypeName","responseTypeName","isQuery","getOverrides","queryKeyName","summary","queryParams","pathParams","isVoidArg","pathItem","operationParameters","pathItemParameters","pp","op","allParameters","param","parameters","init_esm_shims","generateTypesFile","endpointInfos","_options","schemaInterfaces","operationDefinitions","importStatement","typeDefinitions","endpointTypes","endpoint","reqTypeName","resTypeName","requestTypeContent","generateRequestTypeContent","responseTypeContent","generateResponseTypeContent","properties","param","optional","paramType","getTypeFromParameter","operationDef","op","content","jsonContent","formContent","bodyType","getTypeFromSchema","successResponse","responseProps","parseSchemaProperties","schema","required","propName","propSchema","propType","description","refPath","val","key","type","init_esm_shims","generateIndexFile","groupKey","options","optionsGroupKey","init_esm_shims","init_esm_shims","generateQueryServiceFile","endpointInfos","options","groupKey","refetchOnMountOrArgChange","queryServiceName","apiServiceName","queryMethods","info","mutationMethods","lazyQueryMethods","QueryCodeGenerator","options","endpointInfos","generatorOptions","generateQueryServiceFile","init_esm_shims","init_esm_shims","generateApiServiceFile","endpointInfos","options","apiConfiguration","httpClient","groupKey","apiServiceClassName","info","isGet","hasArgs","generateUrlTemplate","path","hasQueryParams","hasBody","generateRequestOptions","generateQueryParams","queryParams","param","ApiServiceGenerator","options","endpointInfos","generatorOptions","generateApiServiceFile","ApiCodeGenerator","parserService","options","EndpointInfoExtractor","QueryCodeGenerator","ApiServiceGenerator","operationDefinitions","endpointInfos","typesContent","apiServiceContent","queryServiceContent","indexContent","allEndpointCacheKeys","info","generatorOptions","schemaInterfaces","curr","alias","ts","name","generateTypesFile","generateIndexFile","UnifiedCodeGenerator","OpenApiService","GroupService","FileWriterService","options","OpenApiParserService","apiGen","curr","alias","ts","name","paths","groupInfos","groupInfo","groupContent","error","generateCacheKeysFile","generateCommonTypesFile","generateComponentSchemaFile","generateDoNotModifyFile","generateUtilsFile","results","errors","generatedGroups","group","groupOutputDir","path","groupResults","outputDir","sharedResults","schemaResults","outputFiles","commonConfig","groupOptions","result","ApiCodeGenerator","cacheKeys","generateEndpoints","options","result","UnifiedCodeGenerator","require","createRequire","__filename","runGeneration","configFile","absoluteConfigPath","resolve","dirname","unparsedConfig","config","cleanOutputDirectory","generateEndpoints","err","main","meta","hasTypeScriptSupport","setupTypeScriptSupport","program","validateConfigFile","validateTypeScriptSupport"]}