@ahoo-wang/fetcher-generator 3.8.3 → 3.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("commander"),l=require("./index.cjs");require("@ahoo-wang/fetcher");require("yaml");require("fs");require("path");class h{getTimestamp(){return new Date().toTimeString().slice(0,8)}info(e,...t){const o=this.getTimestamp();t.length>0?console.log(`[${o}] ℹ️ ${e}`,...t):console.log(`[${o}] ℹ️ ${e}`)}success(e,...t){const o=this.getTimestamp();t.length>0?console.log(`[${o}] ✅ ${e}`,...t):console.log(`[${o}] ✅ ${e}`)}error(e,...t){const o=this.getTimestamp();t.length>0?console.error(`[${o}] ❌ ${e}`,...t):console.error(`[${o}] ❌ ${e}`)}progress(e,t=0,...o){const i=this.getTimestamp(),r=" ".repeat(t);o.length>0?console.log(`[${i}] 🔄 ${r}${e}`,...o):console.log(`[${i}] 🔄 ${r}${e}`)}progressWithCount(e,t,o,i=0,...r){const c=this.getTimestamp(),a=" ".repeat(i),p=`[${e}/${t}]`;r.length>0?console.log(`[${c}] 🔄 ${a}${p} ${o}`,...r):console.log(`[${c}] 🔄 ${a}${p} ${o}`)}}const f="@ahoo-wang/fetcher-generator",m="3.8.3",$="A powerful TypeScript code generation tool that automatically generates type-safe API client code based on OpenAPI specifications. It is designed for general use cases and is also deeply optimized for the [Wow](https://github.com/Ahoo-Wang/Wow) Domain-Driven Design framework, providing native support for the CQRS architectural pattern.",y=["fetch","http","client","openapi","openapi3","swagger","generator","typescript","codegen","api","rest"],v="Ahoo-Wang",w="Apache-2.0",T="https://github.com/Ahoo-Wang/fetcher/tree/master/packages/generator",b={type:"git",url:"https://github.com/Ahoo-Wang/fetcher.git",directory:"packages/generator"},A={url:"https://github.com/Ahoo-Wang/fetcher/issues"},I="module",x="./dist/index.umd.js",C="./dist/index.es.js",P="./dist/index.d.ts",S={"fetcher-generator":"./dist/cli.js"},j={".":{types:"./dist/index.d.ts",import:"./dist/index.es.js",require:"./dist/index.umd.js"}},k=["dist","README.md","README.zh-CN.md"],D={build:"vite build","test:ui":"vitest --ui",test:"vitest run --coverage --testTimeout=15000",lint:"eslint . --fix",clean:"rm -rf dist",analyze:"npx vite-bundle-analyzer -p auto",generate:"node dist/cli.js generate -i test/demo.spec.json -o test-output -t tsconfig.json"},L={"@ahoo-wang/fetcher":"workspace:^3.0.0","@ahoo-wang/fetcher-eventstream":"workspace:^3.0.0","@ahoo-wang/fetcher-decorator":"workspace:^3.0.0","@ahoo-wang/fetcher-openapi":"workspace:^3.0.0","@ahoo-wang/fetcher-wow":"workspace:^3.0.0"},O={"ts-morph":"catalog:",commander:"catalog:",yaml:"catalog:"},W={"@eslint/js":"catalog:","@types/node":"catalog:","@vitest/coverage-v8":"catalog:","@vitest/ui":"catalog:",eslint:"catalog:",globals:"catalog:",prettier:"catalog:",typescript:"catalog:","typescript-eslint":"catalog:","unplugin-dts":"catalog:",vite:"catalog:","vite-bundle-analyzer":"catalog:",vitest:"catalog:"},g={name:f,version:m,description:$,keywords:y,author:v,license:w,homepage:T,repository:b,bugs:A,type:I,main:x,module:C,types:P,bin:S,exports:j,files:k,scripts:D,peerDependencies:L,dependencies:O,devDependencies:W};function q(n){if(!n)return!1;try{const e=new URL(n);return e.protocol==="http:"||e.protocol==="https:"}catch{return n.length>0}}async function G(n){const e=new h;process.on("SIGINT",()=>{e.error("Generation interrupted by user"),process.exit(130)}),q(n.input)||(e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"),process.exit(2));try{e.info(`Fetcher Generator v${g.version}`),e.info("Starting code generation...");const t={inputPath:n.input,outputDir:n.output,configPath:n.config,tsConfigFilePath:n.tsConfigFilePath,logger:e};await new l.CodeGenerator(t).generate(),e.success(`Code generation completed successfully! Files generated in: ${n.output}`)}catch(t){e.error(`Error during code generation:
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("commander"),l=require("./index.cjs");require("@ahoo-wang/fetcher");require("yaml");require("fs");require("path");class h{getTimestamp(){return new Date().toTimeString().slice(0,8)}info(e,...t){const o=this.getTimestamp();t.length>0?console.log(`[${o}] ℹ️ ${e}`,...t):console.log(`[${o}] ℹ️ ${e}`)}success(e,...t){const o=this.getTimestamp();t.length>0?console.log(`[${o}] ✅ ${e}`,...t):console.log(`[${o}] ✅ ${e}`)}error(e,...t){const o=this.getTimestamp();t.length>0?console.error(`[${o}] ❌ ${e}`,...t):console.error(`[${o}] ❌ ${e}`)}progress(e,t=0,...o){const i=this.getTimestamp(),r=" ".repeat(t);o.length>0?console.log(`[${i}] 🔄 ${r}${e}`,...o):console.log(`[${i}] 🔄 ${r}${e}`)}progressWithCount(e,t,o,i=0,...r){const c=this.getTimestamp(),a=" ".repeat(i),p=`[${e}/${t}]`;r.length>0?console.log(`[${c}] 🔄 ${a}${p} ${o}`,...r):console.log(`[${c}] 🔄 ${a}${p} ${o}`)}}const f="@ahoo-wang/fetcher-generator",m="3.8.6",$="A powerful TypeScript code generation tool that automatically generates type-safe API client code based on OpenAPI specifications. It is designed for general use cases and is also deeply optimized for the [Wow](https://github.com/Ahoo-Wang/Wow) Domain-Driven Design framework, providing native support for the CQRS architectural pattern.",y=["fetch","http","client","openapi","openapi3","swagger","generator","typescript","codegen","api","rest"],v="Ahoo-Wang",w="Apache-2.0",T="https://github.com/Ahoo-Wang/fetcher/tree/master/packages/generator",b={type:"git",url:"https://github.com/Ahoo-Wang/fetcher.git",directory:"packages/generator"},A={url:"https://github.com/Ahoo-Wang/fetcher/issues"},I="module",x="./dist/index.umd.js",C="./dist/index.es.js",P="./dist/index.d.ts",S={"fetcher-generator":"./dist/cli.js"},j={".":{types:"./dist/index.d.ts",import:"./dist/index.es.js",require:"./dist/index.umd.js"}},k=["dist","README.md","README.zh-CN.md"],D={build:"vite build","test:ui":"vitest --ui",test:"vitest run --coverage --testTimeout=15000",lint:"eslint . --fix",clean:"rm -rf dist",analyze:"npx vite-bundle-analyzer -p auto",generate:"node dist/cli.js generate -i test/demo.spec.json -o test-output -t tsconfig.json"},L={"@ahoo-wang/fetcher":"workspace:^3.0.0","@ahoo-wang/fetcher-eventstream":"workspace:^3.0.0","@ahoo-wang/fetcher-decorator":"workspace:^3.0.0","@ahoo-wang/fetcher-openapi":"workspace:^3.0.0","@ahoo-wang/fetcher-wow":"workspace:^3.0.0"},O={"ts-morph":"catalog:",commander:"catalog:",yaml:"catalog:"},W={"@eslint/js":"catalog:","@types/node":"catalog:","@vitest/coverage-v8":"catalog:","@vitest/ui":"catalog:",eslint:"catalog:",globals:"catalog:",prettier:"catalog:",typescript:"catalog:","typescript-eslint":"catalog:","unplugin-dts":"catalog:",vite:"catalog:","vite-bundle-analyzer":"catalog:",vitest:"catalog:"},g={name:f,version:m,description:$,keywords:y,author:v,license:w,homepage:T,repository:b,bugs:A,type:I,main:x,module:C,types:P,bin:S,exports:j,files:k,scripts:D,peerDependencies:L,dependencies:O,devDependencies:W};function q(n){if(!n)return!1;try{const e=new URL(n);return e.protocol==="http:"||e.protocol==="https:"}catch{return n.length>0}}async function G(n){const e=new h;process.on("SIGINT",()=>{e.error("Generation interrupted by user"),process.exit(130)}),q(n.input)||(e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"),process.exit(2));try{e.info(`Fetcher Generator v${g.version}`),e.info("Starting code generation...");const t={inputPath:n.input,outputDir:n.output,configPath:n.config,tsConfigFilePath:n.tsConfigFilePath,logger:e};await new l.CodeGenerator(t).generate(),e.success(`Code generation completed successfully! Files generated in: ${n.output}`)}catch(t){e.error(`Error during code generation:
3
3
  `,t),process.exit(1)}}function u(){return s.program.name("fetcher-generator").description("OpenAPI Specification TypeScript code generator for Wow").version(g.version,"-v, --version"),s.program.command("generate").description("Generate TypeScript code from OpenAPI specification").requiredOption("-i, --input <file>","Input OpenAPI specification file path or URL (http/https)").option("-o, --output <path>","Output directory path","src/generated").option("-c, --config <file>","Configuration file path",l.DEFAULT_CONFIG_PATH).option("-t, --ts-config-file-path <file>","TypeScript configuration file path").action(G),s.program}function d(){u().parse()}d();exports.runCLI=d;exports.setupCLI=u;
4
4
  //# sourceMappingURL=cli.cjs.map
package/dist/cli.js CHANGED
@@ -33,7 +33,7 @@ class u {
33
33
  ) : console.log(`[${c}] 🔄 ${a}${p} ${o}`);
34
34
  }
35
35
  }
36
- const h = "@ahoo-wang/fetcher-generator", f = "3.8.3", m = "A powerful TypeScript code generation tool that automatically generates type-safe API client code based on OpenAPI specifications. It is designed for general use cases and is also deeply optimized for the [Wow](https://github.com/Ahoo-Wang/Wow) Domain-Driven Design framework, providing native support for the CQRS architectural pattern.", $ = ["fetch", "http", "client", "openapi", "openapi3", "swagger", "generator", "typescript", "codegen", "api", "rest"], v = "Ahoo-Wang", y = "Apache-2.0", w = "https://github.com/Ahoo-Wang/fetcher/tree/master/packages/generator", T = { type: "git", url: "https://github.com/Ahoo-Wang/fetcher.git", directory: "packages/generator" }, A = { url: "https://github.com/Ahoo-Wang/fetcher/issues" }, b = "module", x = "./dist/index.umd.js", I = "./dist/index.es.js", C = "./dist/index.d.ts", P = { "fetcher-generator": "./dist/cli.js" }, S = { ".": { types: "./dist/index.d.ts", import: "./dist/index.es.js", require: "./dist/index.umd.js" } }, k = ["dist", "README.md", "README.zh-CN.md"], D = { build: "vite build", "test:ui": "vitest --ui", test: "vitest run --coverage --testTimeout=15000", lint: "eslint . --fix", clean: "rm -rf dist", analyze: "npx vite-bundle-analyzer -p auto", generate: "node dist/cli.js generate -i test/demo.spec.json -o test-output -t tsconfig.json" }, j = { "@ahoo-wang/fetcher": "workspace:^3.0.0", "@ahoo-wang/fetcher-eventstream": "workspace:^3.0.0", "@ahoo-wang/fetcher-decorator": "workspace:^3.0.0", "@ahoo-wang/fetcher-openapi": "workspace:^3.0.0", "@ahoo-wang/fetcher-wow": "workspace:^3.0.0" }, W = { "ts-morph": "catalog:", commander: "catalog:", yaml: "catalog:" }, G = { "@eslint/js": "catalog:", "@types/node": "catalog:", "@vitest/coverage-v8": "catalog:", "@vitest/ui": "catalog:", eslint: "catalog:", globals: "catalog:", prettier: "catalog:", typescript: "catalog:", "typescript-eslint": "catalog:", "unplugin-dts": "catalog:", vite: "catalog:", "vite-bundle-analyzer": "catalog:", vitest: "catalog:" }, l = {
36
+ const h = "@ahoo-wang/fetcher-generator", f = "3.8.6", m = "A powerful TypeScript code generation tool that automatically generates type-safe API client code based on OpenAPI specifications. It is designed for general use cases and is also deeply optimized for the [Wow](https://github.com/Ahoo-Wang/Wow) Domain-Driven Design framework, providing native support for the CQRS architectural pattern.", $ = ["fetch", "http", "client", "openapi", "openapi3", "swagger", "generator", "typescript", "codegen", "api", "rest"], v = "Ahoo-Wang", y = "Apache-2.0", w = "https://github.com/Ahoo-Wang/fetcher/tree/master/packages/generator", T = { type: "git", url: "https://github.com/Ahoo-Wang/fetcher.git", directory: "packages/generator" }, A = { url: "https://github.com/Ahoo-Wang/fetcher/issues" }, b = "module", x = "./dist/index.umd.js", I = "./dist/index.es.js", C = "./dist/index.d.ts", P = { "fetcher-generator": "./dist/cli.js" }, S = { ".": { types: "./dist/index.d.ts", import: "./dist/index.es.js", require: "./dist/index.umd.js" } }, k = ["dist", "README.md", "README.zh-CN.md"], D = { build: "vite build", "test:ui": "vitest --ui", test: "vitest run --coverage --testTimeout=15000", lint: "eslint . --fix", clean: "rm -rf dist", analyze: "npx vite-bundle-analyzer -p auto", generate: "node dist/cli.js generate -i test/demo.spec.json -o test-output -t tsconfig.json" }, j = { "@ahoo-wang/fetcher": "workspace:^3.0.0", "@ahoo-wang/fetcher-eventstream": "workspace:^3.0.0", "@ahoo-wang/fetcher-decorator": "workspace:^3.0.0", "@ahoo-wang/fetcher-openapi": "workspace:^3.0.0", "@ahoo-wang/fetcher-wow": "workspace:^3.0.0" }, W = { "ts-morph": "catalog:", commander: "catalog:", yaml: "catalog:" }, G = { "@eslint/js": "catalog:", "@types/node": "catalog:", "@vitest/coverage-v8": "catalog:", "@vitest/ui": "catalog:", eslint: "catalog:", globals: "catalog:", prettier: "catalog:", typescript: "catalog:", "typescript-eslint": "catalog:", "unplugin-dts": "catalog:", vite: "catalog:", "vite-bundle-analyzer": "catalog:", vitest: "catalog:" }, l = {
37
37
  name: h,
38
38
  version: f,
39
39
  description: m,
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("ts-morph"),m=require("@ahoo-wang/fetcher"),z=require("@ahoo-wang/fetcher-wow"),K=require("yaml"),Ce=require("fs"),O=require("path");function T(n){return n.$ref.split("/").pop()}function S(n,e){const t=T(n);return e.schemas?.[t]}function Y(n,e){const t=T(n);return e.requestBodies?.[t]}function Z(n,e){const t=T(n);return e.parameters?.[t]}function v(n,e){return{key:T(n),schema:S(n,e)}}const Pe=/[-_'\s./?;:,()[\]{}|\\]+/;function M(n){return n.split(Pe)}function X(n){return Array.isArray(n)?n.flatMap(e=>B(M(e))):B(M(n))}function B(n){return n.flatMap(e=>{if(e.length===0)return[];const t=[];let o="";for(let r=0;r<e.length;r++){const i=e[r],s=/[A-Z]/.test(i),a=r>0&&/[a-z]/.test(e[r-1]);s&&a&&o?(t.push(o),o=i):o+=i}return o&&t.push(o),t})}function w(n){return n===""||n.length===0?"":X(n).filter(t=>t.length>0).map(t=>{const o=t.charAt(0),r=t.slice(1);return(/[a-zA-Z]/.test(o)?o.toUpperCase():o)+r.toLowerCase()}).join("")}function h(n){const e=w(n);return e.charAt(0).toLowerCase()+e.slice(1)}function ee(n){return n===""||Array.isArray(n)&&n.length===0?"":X(n).filter(t=>t.length>0).map(t=>t.toUpperCase()).join("_")}function b(n){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(n)?n:`'${n}'`}function $e(n){return/^\d+$/.test(n)?`NUM_${n}`:b(ee(n))}function p(n){return!!(n&&typeof n=="object"&&"$ref"in n)}function G(n,e){if(e&&!p(e)&&e.content)return e.content[n]?.schema}function te(n){return G(m.ContentTypeValues.APPLICATION_JSON,n)}function Te(n){return G(m.ContentTypeValues.TEXT_EVENT_STREAM,n)}function ve(n){return G("*/*",n)}const Ie=["string","number","integer","boolean","null"];function ne(n){return Array.isArray(n)?!0:Ie.includes(n)}function U(n){return Array.isArray(n.enum)&&n.enum.length>0}function I(n){return n.type==="object"&&!!n.properties}function R(n){return n.type==="array"&&!!n.items}function Ee(n){return Array.isArray(n.anyOf)&&n.anyOf.length>0}function Se(n){return Array.isArray(n.oneOf)&&n.oneOf.length>0}function q(n){return Array.isArray(n.allOf)&&n.allOf.length>0}function J(n){return Ee(n)||Se(n)||q(n)}function oe(n){return n.includes("|")||n.includes("&")?`(${n})[]`:`${n}[]`}function re(n){return n.type==="object"&&!n.properties&&n.additionalProperties!==void 0}function Re(n){return n.type!=="object"?!1:n.properties?Object.keys(n.properties).length===0:!0}function we(n){return n.readOnly===!0}function D(n){if(Array.isArray(n))return n.map(e=>D(e)).join(" | ");switch(n){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"null":return"null";default:return"any"}}function De(n){if(!I(n))return[];const e=n.required||[];return Object.keys(n.properties).filter(t=>!e.includes(t))}function Ne(n,e){return n.operation.operationId&&e.operation.operationId?n.operation.operationId.localeCompare(e.operation.operationId):n.path&&e.path?n.path.localeCompare(e.path):n.method&&e.method?n.method.localeCompare(e.method):0}function ie(n){const e=[];for(const[t,o]of Object.entries(n))se(o).forEach(r=>{e.push({method:r.method,operation:r.operation,path:t})});return e.sort(Ne)}function se(n){return[{method:"get",operation:n.get},{method:"put",operation:n.put},{method:"post",operation:n.post},{method:"delete",operation:n.delete},{method:"options",operation:n.options},{method:"head",operation:n.head},{method:"patch",operation:n.patch},{method:"trace",operation:n.trace}].filter(({operation:e})=>e!==void 0)}function W(n){return n.responses[200]}function Q(n){const e=W(n);return te(e)}function Oe(n,e){return n.parameters?n.parameters.map(t=>p(t)?Z(t,e):t).filter(t=>t.in==="path"):[]}const Me="string";function ae(n){return!n.schema||p(n.schema)||!n.schema.type||!ne(n.schema.type)?Me:D(n.schema.type)}function ce(n){return n.startsWith("http://")||n.startsWith("https://")?be(n):qe(n)}async function be(n){return await(await fetch(n)).text()}function qe(n){return new Promise((e,t)=>{Ce.readFile(n,"utf-8",(o,r)=>{o?t(o):e(r)})})}async function Fe(n){const e=await ce(n);switch(pe(e)){case"json":return JSON.parse(e);case"yaml":return K.parse(e);default:throw new Error(`Unsupported file format: ${n}`)}}async function je(n){const e=await ce(n);switch(pe(e)){case"json":return JSON.parse(e);case"yaml":return K.parse(e);default:throw new Error(`Unsupported file format: ${n}`)}}function pe(n){const e=n.trimStart();if(e.startsWith("{")||e.startsWith("["))return"json";if(e.startsWith("-")||e.startsWith("%YAML"))return"yaml";try{return JSON.parse(e),"json"}catch{if(e.length>0)return"yaml"}throw new Error("Unable to infer file format")}const ge="types.ts",_e="@";function Ge(n){return m.combineURLs(n.path,ge)}function ue(n,e,t){const o=m.combineURLs(e,t),r=n.getSourceFile(o);return r||n.createSourceFile(o,"",{overwrite:!0})}function C(n,e,t){let o=n.getImportDeclaration(r=>r.getModuleSpecifierValue()===e);o||(o=n.addImportDeclaration({moduleSpecifier:e})),t.forEach(r=>{o.getNamedImports().some(s=>s.getName()===r)||o.addNamedImport(r)})}function d(n,e,t){if(t.path.startsWith(_e)){C(n,t.path,[t.name]);return}const o=n.getDirectoryPath(),r=O.join(e,t.path,ge);let i=O.relative(o,r);i=i.replace(/\.ts$/,""),i=i.split(O.sep).join("/"),i.startsWith(".")||(i="./"+i),C(n,i,[t.name])}function We(n,e,t,o){n.path!==o.path&&d(e,t,o)}function le(n,e=`
2
- `){if(!Array.isArray(n))return;const t=n.filter(o=>typeof o=="string"&&o.length>0);return t.length>0?t.join(e):void 0}function $(n,e){const t=le(e);t&&n.addJsDoc(t)}function k(n,e){const t=[n.title,n.description];return e&&t.push(`- key: ${e}`),n.format&&t.push(`- format: ${n.format}`),V(t,n,"default"),V(t,n,"example"),ze(t,n),Be(t,n),Ue(t,n),t}function ke(n,e,t){const o=k(e,t);$(n,o)}function Le(n,e,t){const o=k(e,t);de(o,"schema",e),$(n,o)}function V(n,e,t){const o=e[t];if(o){if(typeof o!="object"){n.push(`- ${t}: \`${o}\``);return}de(n,t,o)}}function de(n,e,t){n.push(`- ${e}: `),n.push("```json"),n.push(JSON.stringify(t,null,2)),n.push("```")}function ze(n,e){const t=["- Numeric Constraints"];e.minimum!==void 0&&t.push(` - minimum: ${e.minimum}`),e.maximum!==void 0&&t.push(` - maximum: ${e.maximum}`),e.exclusiveMinimum!==void 0&&t.push(` - exclusiveMinimum: ${e.exclusiveMinimum}`),e.exclusiveMaximum!==void 0&&t.push(` - exclusiveMaximum: ${e.exclusiveMaximum}`),e.multipleOf!==void 0&&t.push(` - multipleOf: ${e.multipleOf}`),t.length!==1&&n.push(...t)}function Be(n,e){const t=["- String Constraints"];e.minLength!==void 0&&t.push(` - minLength: ${e.minLength}`),e.maxLength!==void 0&&t.push(` - maxLength: ${e.maxLength}`),e.pattern!==void 0&&t.push(` - pattern: ${e.pattern}`),t.length!==1&&n.push(...t)}function Ue(n,e){const t=["- Array Constraints"];e.minItems!==void 0&&t.push(` - minItems: ${e.minItems}`),e.maxItems!==void 0&&t.push(` - maxItems: ${e.maxItems}`),e.uniqueItems!==void 0&&t.push(` - uniqueItems: ${e.uniqueItems}`),t.length!==1&&n.push(...t)}function Je(n){const e=n.split(".");return e.length!=2||e[0].length===0||e[1].length===0?null:e}function Qe(n){const e=Je(n.name);return e?{tag:n,contextAlias:e[0],aggregateName:e[1]}:null}function Ve(n){const e=n?.map(o=>Qe(o)).filter(o=>o!==null);if(!e)return new Map;const t=new Map;return e.forEach(o=>{t.set(o.tag.name,{aggregate:o,commands:new Map,events:new Map})}),t}function He(n){if(!n)return null;const e=n.split(".");return e.length!=3?null:e[2]}const Ke="#/components/responses/wow.CommandOk",Ye="#/components/parameters/wow.id";class Ze{constructor(e){this.openAPI=e,this.aggregates=Ve(e.tags),this.build()}aggregates;build(){const e=ie(this.openAPI.paths);for(const t of e)this.commands(t.path,t),this.state(t.operation),this.events(t.operation),this.fields(t.operation)}resolve(){const e=new Map;for(const t of this.aggregates.values()){if(!t.state||!t.fields)continue;const o=t.aggregate.contextAlias;let r=e.get(o);r||(r=new Set,e.set(o,r)),r.add(t)}return e}commands(e,t){const o=t.operation;if(o.operationId==="wow.command.send")return;const r=He(o.operationId);if(!r)return;const i=W(o);if(!i||!p(i)||i.$ref!==Ke||!o.requestBody)return;const s=o.parameters??[],a=s.filter(u=>p(u)&&u.$ref===Ye).at(0),c=s.filter(u=>!p(u)&&u.in==="path");if(a){const u=Z(a,this.openAPI.components);c.push(u)}const g=o.requestBody.content[m.ContentTypeValues.APPLICATION_JSON].schema,f=v(g,this.openAPI.components);f.schema.title=f.schema.title||o.summary,f.schema.description=f.schema.description||o.description;const Ae={name:r,method:t.method,path:e,pathParameters:c,summary:o.summary,description:o.description,schema:f,operation:o};o.tags?.forEach(u=>{const L=this.aggregates.get(u);L&&L.commands.set(r,Ae)})}state(e){if(!e.operationId?.endsWith(".snapshot_state.single"))return;const t=Q(e);if(!p(t))return;const o=v(t,this.openAPI.components);e.tags?.forEach(r=>{const i=this.aggregates.get(r);i&&(i.state=o)})}events(e){if(!this.openAPI.components||!e.operationId?.endsWith(".event.list_query"))return;const t=Q(e);if(p(t))return;const o=t?.items;if(!p(o))return;const i=S(o,this.openAPI.components).properties.body.items.anyOf.map(s=>{const a=s.title,c=s.properties.name.const,y=s.properties.body,g=v(y,this.openAPI.components);return g.schema.title=g.schema.title||s.title,{title:a,name:c,schema:g}});e.tags?.forEach(s=>{const a=this.aggregates.get(s);a&&i.forEach(c=>{a.events.set(c.name,c)})})}fields(e){if(!this.openAPI.components||!e.operationId?.endsWith(".snapshot.count"))return;const o=Y(e.requestBody,this.openAPI.components).content[m.ContentTypeValues.APPLICATION_JSON].schema,i=S(o,this.openAPI.components).properties?.field,s=v(i,this.openAPI.components);e.tags?.forEach(a=>{const c=this.aggregates.get(a);c&&(c.fields=s)})}}const A="@ahoo-wang/fetcher-wow",Xe={"wow.command.CommandResult":"CommandResult","wow.command.CommandResultArray":"CommandResultArray","wow.MessageHeaderSqlType":"MessageHeaderSqlType","wow.api.BindingError":"BindingError","wow.api.DefaultErrorInfo":"ErrorInfo","wow.api.RecoverableType":"RecoverableType","wow.api.command.DefaultDeleteAggregate":"DeleteAggregate","wow.api.command.DefaultRecoverAggregate":"RecoverAggregate","wow.api.messaging.FunctionInfoData":"FunctionInfo","wow.api.messaging.FunctionKind":"FunctionKind","wow.api.modeling.AggregateId":"AggregateId","wow.api.query.Condition":"Condition","wow.api.query.ConditionOptions":"ConditionOptions","wow.api.query.ListQuery":"ListQuery","wow.api.query.Operator":"Operator","wow.api.query.PagedQuery":"PagedQuery","wow.api.query.Pagination":"Pagination","wow.api.query.Projection":"Projection","wow.api.query.Sort":"FieldSort","wow.api.query.Sort.Direction":"SortDirection","wow.api.query.DynamicDocument":"DynamicDocument","wow.api.query.DynamicDocumentArray":"DynamicDocumentArray","wow.command.CommandStage":"CommandStage","wow.command.SimpleWaitSignal":"WaitSignal","wow.configuration.Aggregate":"Aggregate","wow.configuration.BoundedContext":"BoundedContext","wow.configuration.WowMetadata":"WowMetadata","wow.modeling.DomainEvent":"DomainEvent","wow.openapi.BatchResult":"BatchResult","wow.messaging.CompensationTarget":"CompensationTarget"};function l(n){if(!n)return{name:"",path:"/"};const e=Xe[n];if(e)return{name:e,path:A};const t=n.split(".");let o=-1;for(let c=0;c<t.length;c++)if(t[c]&&/^[A-Z]/.test(t[c])){o=c;break}const r=t.slice(0,o),i=r.length>0?`/${r.join("/")}`:"/",s=t.slice(o);return{name:w(s),path:i}}function E(n){const e=T(n);return l(e)}function N(n){return`${ee(n)}_BOUNDED_CONTEXT_ALIAS`}class et{constructor(e,t,o,r){this.modelInfo=e,this.sourceFile=t,this.keySchema=o,this.outputDir=r}generate(){const e=this.process();e&&Le(e,this.keySchema.schema,this.keySchema.key)}process(){const{schema:e}=this.keySchema;return U(e)?this.processEnum(e):I(e)?this.processInterface(e):R(e)?this.processArray(e):q(e)?this.processIntersection(e):J(e)?this.processComposition(e):this.processTypeAlias(e)}resolveReference(e){const t=E(e);return We(this.modelInfo,this.sourceFile,this.outputDir,t),t}resolveAdditionalProperties(e){return e.additionalProperties===void 0||e.additionalProperties===!1?"":e.additionalProperties===!0?"[key: string]: any":`[key: string]: ${this.resolveType(e.additionalProperties)}`}resolvePropertyDefinitions(e){const{properties:t}=e;return Object.entries(t).map(([o,r])=>{const i=this.resolveType(r),s=b(o);if(!p(r)){const a=k(r),c=le(a,`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("ts-morph"),m=require("@ahoo-wang/fetcher"),z=require("@ahoo-wang/fetcher-wow"),H=require("yaml"),Ce=require("fs"),O=require("path");function $(n){return n.$ref.split("/").pop()}function S(n,e){const t=$(n);return e.schemas?.[t]}function Y(n,e){const t=$(n);return e.requestBodies?.[t]}function X(n,e){const t=$(n);return e.parameters?.[t]}function v(n,e){return{key:$(n),schema:S(n,e)}}const Pe=/[-_'\s./?;:,()[\]{}|\\]+/;function M(n){return n.split(Pe)}function Z(n){return Array.isArray(n)?n.flatMap(e=>B(M(e))):B(M(n))}function B(n){return n.flatMap(e=>{if(e.length===0)return[];const t=[];let o="";for(let r=0;r<e.length;r++){const i=e[r],s=/[A-Z]/.test(i),a=r>0&&/[a-z]/.test(e[r-1]);s&&a&&o?(t.push(o),o=i):o+=i}return o&&t.push(o),t})}function w(n){return n===""||n.length===0?"":Z(n).filter(t=>t.length>0).map(t=>{const o=t.charAt(0),r=t.slice(1);return(/[a-zA-Z]/.test(o)?o.toUpperCase():o)+r.toLowerCase()}).join("")}function h(n){const e=w(n);return e.charAt(0).toLowerCase()+e.slice(1)}function ee(n){return n===""||Array.isArray(n)&&n.length===0?"":Z(n).filter(t=>t.length>0).map(t=>t.toUpperCase()).join("_")}function b(n){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(n)?n:`'${n}'`}function Te(n){return/^\d+$/.test(n)?`NUM_${n}`:b(ee(n))}function p(n){return!!(n&&typeof n=="object"&&"$ref"in n)}function G(n,e){if(e&&!p(e)&&e.content)return e.content[n]?.schema}function te(n){return G(m.ContentTypeValues.APPLICATION_JSON,n)}function $e(n){return G(m.ContentTypeValues.TEXT_EVENT_STREAM,n)}function ve(n){return G("*/*",n)}const Ie=["string","number","integer","boolean","null"];function ne(n){return Array.isArray(n)?!0:Ie.includes(n)}function U(n){return Array.isArray(n.enum)&&n.enum.length>0}function I(n){return n.type==="object"&&!!n.properties}function R(n){return n.type==="array"&&!!n.items}function Ee(n){return Array.isArray(n.anyOf)&&n.anyOf.length>0}function Se(n){return Array.isArray(n.oneOf)&&n.oneOf.length>0}function q(n){return Array.isArray(n.allOf)&&n.allOf.length>0}function J(n){return Ee(n)||Se(n)||q(n)}function oe(n){return n.includes("|")||n.includes("&")?`(${n})[]`:`${n}[]`}function re(n){return n.type==="object"&&!n.properties&&n.additionalProperties!==void 0}const Re="x-map-key-schema";function we(n){return n[Re]}function De(n){return n.type!=="object"?!1:n.properties?Object.keys(n.properties).length===0:!0}function Ne(n){return n.readOnly===!0}function D(n){if(Array.isArray(n))return n.map(e=>D(e)).join(" | ");switch(n){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"null":return"null";default:return"any"}}function Oe(n){if(!I(n))return[];const e=n.required||[];return Object.keys(n.properties).filter(t=>!e.includes(t))}function Me(n,e){return n.operation.operationId&&e.operation.operationId?n.operation.operationId.localeCompare(e.operation.operationId):n.path&&e.path?n.path.localeCompare(e.path):n.method&&e.method?n.method.localeCompare(e.method):0}function ie(n){const e=[];for(const[t,o]of Object.entries(n))se(o).forEach(r=>{e.push({method:r.method,operation:r.operation,path:t})});return e.sort(Me)}function se(n){return[{method:"get",operation:n.get},{method:"put",operation:n.put},{method:"post",operation:n.post},{method:"delete",operation:n.delete},{method:"options",operation:n.options},{method:"head",operation:n.head},{method:"patch",operation:n.patch},{method:"trace",operation:n.trace}].filter(({operation:e})=>e!==void 0)}function W(n){return n.responses[200]}function Q(n){const e=W(n);return te(e)}function be(n,e){return n.parameters?n.parameters.map(t=>p(t)?X(t,e):t).filter(t=>t.in==="path"):[]}const qe="string";function ae(n){return!n.schema||p(n.schema)||!n.schema.type||!ne(n.schema.type)?qe:D(n.schema.type)}function ce(n){return n.startsWith("http://")||n.startsWith("https://")?Fe(n):je(n)}async function Fe(n){return await(await fetch(n)).text()}function je(n){return new Promise((e,t)=>{Ce.readFile(n,"utf-8",(o,r)=>{o?t(o):e(r)})})}async function _e(n){const e=await ce(n);switch(pe(e)){case"json":return JSON.parse(e);case"yaml":return H.parse(e);default:throw new Error(`Unsupported file format: ${n}`)}}async function Ge(n){const e=await ce(n);switch(pe(e)){case"json":return JSON.parse(e);case"yaml":return H.parse(e);default:throw new Error(`Unsupported file format: ${n}`)}}function pe(n){const e=n.trimStart();if(e.startsWith("{")||e.startsWith("["))return"json";if(e.startsWith("-")||e.startsWith("%YAML"))return"yaml";try{return JSON.parse(e),"json"}catch{if(e.length>0)return"yaml"}throw new Error("Unable to infer file format")}const ge="types.ts",We="@";function ke(n){return m.combineURLs(n.path,ge)}function ue(n,e,t){const o=m.combineURLs(e,t),r=n.getSourceFile(o);return r||n.createSourceFile(o,"",{overwrite:!0})}function C(n,e,t){let o=n.getImportDeclaration(r=>r.getModuleSpecifierValue()===e);o||(o=n.addImportDeclaration({moduleSpecifier:e})),t.forEach(r=>{o.getNamedImports().some(s=>s.getName()===r)||o.addNamedImport(r)})}function d(n,e,t){if(t.path.startsWith(We)){C(n,t.path,[t.name]);return}const o=n.getDirectoryPath(),r=O.join(e,t.path,ge);let i=O.relative(o,r);i=i.replace(/\.ts$/,""),i=i.split(O.sep).join("/"),i.startsWith(".")||(i="./"+i),C(n,i,[t.name])}function Le(n,e,t,o){n.path!==o.path&&d(e,t,o)}function le(n,e=`
2
+ `){if(!Array.isArray(n))return;const t=n.filter(o=>typeof o=="string"&&o.length>0);return t.length>0?t.join(e):void 0}function T(n,e){const t=le(e);t&&n.addJsDoc(t)}function k(n,e){const t=[n.title,n.description];return e&&t.push(`- key: ${e}`),n.format&&t.push(`- format: ${n.format}`),V(t,n,"default"),V(t,n,"example"),Ue(t,n),Je(t,n),Qe(t,n),t}function ze(n,e,t){const o=k(e,t);T(n,o)}function Be(n,e,t){const o=k(e,t);de(o,"schema",e),T(n,o)}function V(n,e,t){const o=e[t];if(o){if(typeof o!="object"){n.push(`- ${t}: \`${o}\``);return}de(n,t,o)}}function de(n,e,t){n.push(`- ${e}: `),n.push("```json"),n.push(JSON.stringify(t,null,2)),n.push("```")}function Ue(n,e){const t=["- Numeric Constraints"];e.minimum!==void 0&&t.push(` - minimum: ${e.minimum}`),e.maximum!==void 0&&t.push(` - maximum: ${e.maximum}`),e.exclusiveMinimum!==void 0&&t.push(` - exclusiveMinimum: ${e.exclusiveMinimum}`),e.exclusiveMaximum!==void 0&&t.push(` - exclusiveMaximum: ${e.exclusiveMaximum}`),e.multipleOf!==void 0&&t.push(` - multipleOf: ${e.multipleOf}`),t.length!==1&&n.push(...t)}function Je(n,e){const t=["- String Constraints"];e.minLength!==void 0&&t.push(` - minLength: ${e.minLength}`),e.maxLength!==void 0&&t.push(` - maxLength: ${e.maxLength}`),e.pattern!==void 0&&t.push(` - pattern: ${e.pattern}`),t.length!==1&&n.push(...t)}function Qe(n,e){const t=["- Array Constraints"];e.minItems!==void 0&&t.push(` - minItems: ${e.minItems}`),e.maxItems!==void 0&&t.push(` - maxItems: ${e.maxItems}`),e.uniqueItems!==void 0&&t.push(` - uniqueItems: ${e.uniqueItems}`),t.length!==1&&n.push(...t)}function Ve(n){const e=n.split(".");return e.length!=2||e[0].length===0||e[1].length===0?null:e}function Ke(n){const e=Ve(n.name);return e?{tag:n,contextAlias:e[0],aggregateName:e[1]}:null}function He(n){const e=n?.map(o=>Ke(o)).filter(o=>o!==null);if(!e)return new Map;const t=new Map;return e.forEach(o=>{t.set(o.tag.name,{aggregate:o,commands:new Map,events:new Map})}),t}function Ye(n){if(!n)return null;const e=n.split(".");return e.length!=3?null:e[2]}const Xe="#/components/responses/wow.CommandOk",Ze="#/components/parameters/wow.id";class et{constructor(e){this.openAPI=e,this.aggregates=He(e.tags),this.build()}aggregates;build(){const e=ie(this.openAPI.paths);for(const t of e)this.commands(t.path,t),this.state(t.operation),this.events(t.operation),this.fields(t.operation)}resolve(){const e=new Map;for(const t of this.aggregates.values()){if(!t.state||!t.fields)continue;const o=t.aggregate.contextAlias;let r=e.get(o);r||(r=new Set,e.set(o,r)),r.add(t)}return e}commands(e,t){const o=t.operation;if(o.operationId==="wow.command.send")return;const r=Ye(o.operationId);if(!r)return;const i=W(o);if(!i||!p(i)||i.$ref!==Xe||!o.requestBody)return;const s=o.parameters??[],a=s.filter(u=>p(u)&&u.$ref===Ze).at(0),c=s.filter(u=>!p(u)&&u.in==="path");if(a){const u=X(a,this.openAPI.components);c.push(u)}const g=o.requestBody.content[m.ContentTypeValues.APPLICATION_JSON].schema,f=v(g,this.openAPI.components);f.schema.title=f.schema.title||o.summary,f.schema.description=f.schema.description||o.description;const Ae={name:r,method:t.method,path:e,pathParameters:c,summary:o.summary,description:o.description,schema:f,operation:o};o.tags?.forEach(u=>{const L=this.aggregates.get(u);L&&L.commands.set(r,Ae)})}state(e){if(!e.operationId?.endsWith(".snapshot_state.single"))return;const t=Q(e);if(!p(t))return;const o=v(t,this.openAPI.components);e.tags?.forEach(r=>{const i=this.aggregates.get(r);i&&(i.state=o)})}events(e){if(!this.openAPI.components||!e.operationId?.endsWith(".event.list_query"))return;const t=Q(e);if(p(t))return;const o=t?.items;if(!p(o))return;const i=S(o,this.openAPI.components).properties.body.items.anyOf.map(s=>{const a=s.title,c=s.properties.name.const,y=s.properties.body,g=v(y,this.openAPI.components);return g.schema.title=g.schema.title||s.title,{title:a,name:c,schema:g}});e.tags?.forEach(s=>{const a=this.aggregates.get(s);a&&i.forEach(c=>{a.events.set(c.name,c)})})}fields(e){if(!this.openAPI.components||!e.operationId?.endsWith(".snapshot.count"))return;const o=Y(e.requestBody,this.openAPI.components).content[m.ContentTypeValues.APPLICATION_JSON].schema,i=S(o,this.openAPI.components).properties?.field,s=v(i,this.openAPI.components);e.tags?.forEach(a=>{const c=this.aggregates.get(a);c&&(c.fields=s)})}}const A="@ahoo-wang/fetcher-wow",tt={"wow.command.CommandResult":"CommandResult","wow.command.CommandResultArray":"CommandResultArray","wow.MessageHeaderSqlType":"MessageHeaderSqlType","wow.api.BindingError":"BindingError","wow.api.DefaultErrorInfo":"ErrorInfo","wow.api.RecoverableType":"RecoverableType","wow.api.command.DefaultDeleteAggregate":"DeleteAggregate","wow.api.command.DefaultRecoverAggregate":"RecoverAggregate","wow.api.messaging.FunctionInfoData":"FunctionInfo","wow.api.messaging.FunctionKind":"FunctionKind","wow.api.modeling.AggregateId":"AggregateId","wow.api.query.Condition":"Condition","wow.api.query.ConditionOptions":"ConditionOptions","wow.api.query.ListQuery":"ListQuery","wow.api.query.Operator":"Operator","wow.api.query.PagedQuery":"PagedQuery","wow.api.query.Pagination":"Pagination","wow.api.query.Projection":"Projection","wow.api.query.Sort":"FieldSort","wow.api.query.Sort.Direction":"SortDirection","wow.api.query.DynamicDocument":"DynamicDocument","wow.api.query.DynamicDocumentArray":"DynamicDocumentArray","wow.command.CommandStage":"CommandStage","wow.command.SimpleWaitSignal":"WaitSignal","wow.configuration.Aggregate":"Aggregate","wow.configuration.BoundedContext":"BoundedContext","wow.configuration.WowMetadata":"WowMetadata","wow.modeling.DomainEvent":"DomainEvent","wow.openapi.BatchResult":"BatchResult","wow.messaging.CompensationTarget":"CompensationTarget"};function l(n){if(!n)return{name:"",path:"/"};const e=tt[n];if(e)return{name:e,path:A};const t=n.split(".");let o=-1;for(let c=0;c<t.length;c++)if(t[c]&&/^[A-Z]/.test(t[c])){o=c;break}const r=t.slice(0,o),i=r.length>0?`/${r.join("/")}`:"/",s=t.slice(o);return{name:w(s),path:i}}function E(n){const e=$(n);return l(e)}function N(n){return`${ee(n)}_BOUNDED_CONTEXT_ALIAS`}class nt{constructor(e,t,o,r){this.modelInfo=e,this.sourceFile=t,this.keySchema=o,this.outputDir=r}generate(){const e=this.process();e&&Be(e,this.keySchema.schema,this.keySchema.key)}process(){const{schema:e}=this.keySchema;return U(e)?this.processEnum(e):I(e)?this.processInterface(e):R(e)?this.processArray(e):q(e)?this.processIntersection(e):J(e)?this.processComposition(e):this.processTypeAlias(e)}resolveReference(e){const t=E(e);return Le(this.modelInfo,this.sourceFile,this.outputDir,t),t}resolveAdditionalProperties(e){return e.additionalProperties===void 0||e.additionalProperties===!1?"":e.additionalProperties===!0?"[key: string]: any":`[key: string]: ${this.resolveType(e.additionalProperties)}`}resolvePropertyDefinitions(e){const{properties:t}=e;return Object.entries(t).map(([o,r])=>{const i=this.resolveType(r),s=b(o);if(!p(r)){const a=k(r),c=le(a,`
3
3
  * `);if(c)return`
4
4
  /**
5
5
  * ${c}
@@ -8,14 +8,14 @@
8
8
  `}return`${s}: ${i}`})}resolveObjectType(e){const t=[];if(I(e)){const r=this.resolvePropertyDefinitions(e);t.push(...r)}const o=this.resolveAdditionalProperties(e);return o&&t.push(o),t.length===0?"Record<string, any>":`{
9
9
  ${t.join(`;
10
10
  `)};
11
- }`}resolveMapValueType(e){return e.additionalProperties===void 0||e.additionalProperties===!1||e.additionalProperties===!0?"any":this.resolveType(e.additionalProperties)}resolveType(e){if(p(e))return this.resolveReference(e).name;if(re(e))return`Record<string,${this.resolveMapValueType(e)}>`;if(e.const)return`'${e.const}'`;if(U(e))return e.enum.map(t=>`\`${t}\``).join(" | ");if(J(e)){const o=(e.oneOf||e.anyOf||e.allOf||[]).map(i=>this.resolveType(i)),r=q(e)?" & ":" | ";return`(${o.join(r)})`}if(R(e)){const t=this.resolveType(e.items);return oe(t)}return e.type==="object"?this.resolveObjectType(e):e.type?D(e.type):"any"}processEnum(e){return this.sourceFile.addEnum({name:this.modelInfo.name,isExported:!0,members:e.enum.filter(t=>typeof t=="string"&&t.length>0).map(t=>({name:$e(t),initializer:`\`${t}\``}))})}addPropertyToInterface(e,t,o){const r=this.resolveType(o),i=b(t);let s=e.getProperty(i);s?s.setType(r):s=e.addProperty({name:i,type:r,isReadonly:we(o)}),ke(s,o)}processInterface(e){const t=this.sourceFile.addInterface({name:this.modelInfo.name,isExported:!0}),o=e.properties||{};return Object.entries(o).forEach(([r,i])=>{this.addPropertyToInterface(t,r,i)}),e.additionalProperties&&t.addIndexSignature({keyName:"key",keyType:"string",returnType:this.resolveType(e.additionalProperties===!0?{}:e.additionalProperties)}).addJsDoc("Additional properties"),t}processArray(e){const t=this.resolveType(e.items);return this.sourceFile.addTypeAlias({name:this.modelInfo.name,type:`Array<${t}>`,isExported:!0})}processComposition(e){return this.sourceFile.addTypeAlias({name:this.modelInfo.name,type:this.resolveType(e),isExported:!0})}processIntersection(e){const t=this.sourceFile.addInterface({name:this.modelInfo.name,isExported:!0});return e.allOf.forEach(o=>{if(p(o)){const r=this.resolveType(o);t.addExtends(r);return}I(o)&&Object.entries(o.properties).forEach(([r,i])=>{this.addPropertyToInterface(t,r,i)})}),t}processTypeAlias(e){return this.sourceFile.addTypeAlias({name:this.modelInfo.name,type:this.resolveType(e),isExported:!0})}}class tt{constructor(e){this.context=e}getOrCreateSourceFile(e){const t=Ge(e);return this.context.getOrCreateSourceFile(t)}generate(){const e=this.context.openAPI.components?.schemas;if(!e){this.context.logger.info("No schemas found in OpenAPI specification");return}const t=this.stateAggregatedTypeNames(),o=this.filterSchemas(e,t);this.context.logger.progress(`Generating models for ${o.length} schemas`),o.forEach((r,i)=>{this.context.logger.progressWithCount(i+1,o.length,`Processing schema: ${r.key}`,2),this.generateKeyedSchema(r)}),this.context.logger.success("Model generation completed")}filterSchemas(e,t){return Object.entries(e).map(([o,r])=>({key:o,schema:r})).filter(o=>!this.isWowSchema(o.key,t))}isWowSchema(e,t){if(e!=="wow.api.query.PagedList"&&e.startsWith("wow.api.query.")&&e.endsWith("PagedList"))return!1;if(e.startsWith("wow.")||e.endsWith("AggregatedCondition")||e.endsWith("AggregatedDomainEventStream")||e.endsWith("AggregatedDomainEventStreamPagedList")||e.endsWith("AggregatedDomainEventStreamServerSentEventNonNullData")||e.endsWith("AggregatedListQuery")||e.endsWith("AggregatedPagedQuery")||e.endsWith("AggregatedSingleQuery"))return!0;const o=l(e);return t.has(o.name)}aggregatedSchemaSuffix=["MaterializedSnapshot","MaterializedSnapshotPagedList","MaterializedSnapshotServerSentEventNonNullData","PagedList","ServerSentEventNonNullData","Snapshot","StateEvent"];stateAggregatedTypeNames(){const e=new Set;for(const[t,o]of this.context.contextAggregates){this.generateBoundedContext(t);for(const r of o)this.aggregatedSchemaSuffix.forEach(i=>{const s=l(r.state.key),a=w(s.name)+i;e.add(a)})}return e}generateKeyedSchema(e){const t=l(e.key),o=this.getOrCreateSourceFile(t);new et(t,o,e,this.context.outputDir).generate()}generateBoundedContext(e){const t=`${e}/boundedContext.ts`;this.context.logger.info(`Creating bounded context file: ${t}`);const o=this.context.getOrCreateSourceFile(t),r=N(e);o.addStatements(`export const ${r} = '${e}';`)}}const nt="@ahoo-wang/fetcher",ot=["ResultExtractors"],rt="@ahoo-wang/fetcher-decorator",it=["type ApiMetadata","type ApiMetadataCapable","type ParameterRequest","api","get","post","put","patch","del","request","attribute","path","autoGeneratedError"],st={type:"Promise<Response>",metadata:"{resultExtractor: ResultExtractors.Response }"},H={type:"Promise<string>",metadata:"{resultExtractor: ResultExtractors.Text }"},F=`{
11
+ }`}resolveMapValueType(e){return e.additionalProperties===void 0||e.additionalProperties===!1||e.additionalProperties===!0?"any":this.resolveType(e.additionalProperties)}resolveMapKeyType(e){const t=we(e);return t?this.resolveType(t):"string"}resolveMapType(e){const t=this.resolveMapKeyType(e),o=this.resolveMapValueType(e);return`Record<${t},${o}>`}resolveType(e){if(p(e))return this.resolveReference(e).name;if(re(e))return this.resolveMapType(e);if(e.const)return`'${e.const}'`;if(U(e))return e.enum.map(t=>`\`${t}\``).join(" | ");if(J(e)){const o=(e.oneOf||e.anyOf||e.allOf||[]).map(i=>this.resolveType(i)),r=q(e)?" & ":" | ";return`(${o.join(r)})`}if(R(e)){const t=this.resolveType(e.items);return oe(t)}return e.type==="object"?this.resolveObjectType(e):e.type?D(e.type):"any"}processEnum(e){return this.sourceFile.addEnum({name:this.modelInfo.name,isExported:!0,members:e.enum.filter(t=>typeof t=="string"&&t.length>0).map(t=>({name:Te(t),initializer:`\`${t}\``}))})}addPropertyToInterface(e,t,o){const r=this.resolveType(o),i=b(t);let s=e.getProperty(i);s?s.setType(r):s=e.addProperty({name:i,type:r,isReadonly:Ne(o)}),ze(s,o)}processInterface(e){const t=this.sourceFile.addInterface({name:this.modelInfo.name,isExported:!0}),o=e.properties||{};return Object.entries(o).forEach(([r,i])=>{this.addPropertyToInterface(t,r,i)}),e.additionalProperties&&t.addIndexSignature({keyName:"key",keyType:"string",returnType:this.resolveType(e.additionalProperties===!0?{}:e.additionalProperties)}).addJsDoc("Additional properties"),t}processArray(e){const t=this.resolveType(e.items);return this.sourceFile.addTypeAlias({name:this.modelInfo.name,type:`Array<${t}>`,isExported:!0})}processComposition(e){return this.sourceFile.addTypeAlias({name:this.modelInfo.name,type:this.resolveType(e),isExported:!0})}processIntersection(e){const t=this.sourceFile.addInterface({name:this.modelInfo.name,isExported:!0});return e.allOf.forEach(o=>{if(p(o)){const r=this.resolveType(o);t.addExtends(r);return}I(o)&&Object.entries(o.properties).forEach(([r,i])=>{this.addPropertyToInterface(t,r,i)})}),t}processTypeAlias(e){return this.sourceFile.addTypeAlias({name:this.modelInfo.name,type:this.resolveType(e),isExported:!0})}}class ot{constructor(e){this.context=e}getOrCreateSourceFile(e){const t=ke(e);return this.context.getOrCreateSourceFile(t)}generate(){const e=this.context.openAPI.components?.schemas;if(!e){this.context.logger.info("No schemas found in OpenAPI specification");return}const t=this.stateAggregatedTypeNames(),o=this.filterSchemas(e,t);this.context.logger.progress(`Generating models for ${o.length} schemas`),o.forEach((r,i)=>{this.context.logger.progressWithCount(i+1,o.length,`Processing schema: ${r.key}`,2),this.generateKeyedSchema(r)}),this.context.logger.success("Model generation completed")}filterSchemas(e,t){return Object.entries(e).map(([o,r])=>({key:o,schema:r})).filter(o=>!this.isWowSchema(o.key,t))}isWowSchema(e,t){if(e!=="wow.api.query.PagedList"&&e.startsWith("wow.api.query.")&&e.endsWith("PagedList")||e.startsWith("wow.api.query.Operator")&&e.endsWith("Map"))return!1;if(e.startsWith("wow.")||e.endsWith("AggregatedCondition")||e.endsWith("AggregatedDomainEventStream")||e.endsWith("AggregatedDomainEventStreamPagedList")||e.endsWith("AggregatedDomainEventStreamServerSentEventNonNullData")||e.endsWith("AggregatedListQuery")||e.endsWith("AggregatedPagedQuery")||e.endsWith("AggregatedSingleQuery"))return!0;const o=l(e);return t.has(o.name)}aggregatedSchemaSuffix=["MaterializedSnapshot","MaterializedSnapshotPagedList","MaterializedSnapshotServerSentEventNonNullData","PagedList","ServerSentEventNonNullData","Snapshot","StateEvent"];stateAggregatedTypeNames(){const e=new Set;for(const[t,o]of this.context.contextAggregates){this.generateBoundedContext(t);for(const r of o)this.aggregatedSchemaSuffix.forEach(i=>{const s=l(r.state.key),a=w(s.name)+i;e.add(a)})}return e}generateKeyedSchema(e){const t=l(e.key),o=this.getOrCreateSourceFile(t);new nt(t,o,e,this.context.outputDir).generate()}generateBoundedContext(e){const t=`${e}/boundedContext.ts`;this.context.logger.info(`Creating bounded context file: ${t}`);const o=this.context.getOrCreateSourceFile(t),r=N(e);o.addStatements(`export const ${r} = '${e}';`)}}const rt="@ahoo-wang/fetcher",it=["ResultExtractors"],st="@ahoo-wang/fetcher-decorator",at=["type ApiMetadata","type ApiMetadataCapable","type ParameterRequest","api","get","post","put","patch","del","request","attribute","path","autoGeneratedError"],ct={type:"Promise<Response>",metadata:"{resultExtractor: ResultExtractors.Response }"},K={type:"Promise<string>",metadata:"{resultExtractor: ResultExtractors.Text }"},F=`{
12
12
  headers: { Accept: ContentTypeValues.TEXT_EVENT_STREAM },
13
13
  resultExtractor: JsonEventStreamResultExtractor,
14
- }`;function at(n){C(n,nt,ot)}function me(n){C(n,rt,it)}function j(n,e,t=[],o=[],r){return e.addClass({name:n,isExported:!0,typeParameters:o,extends:r,decorators:[{name:"api",arguments:t}]})}function fe(n,e){n.addImplements("ApiMetadataCapable"),n.addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",hasQuestionToken:e===void 0,scope:P.Scope.Public,isReadonly:!0,initializer:e}]})}const ct="@ahoo-wang/fetcher-eventstream";function he(n){C(n,ct,["JsonEventStreamResultExtractor","type JsonServerSentEventStream"])}function pt(n){let e=0,t=0;return n.commands.forEach(o=>{o.path.startsWith(z.ResourceAttributionPathSpec.TENANT)&&(e+=1),o.path.startsWith(z.ResourceAttributionPathSpec.OWNER)&&(t+=1)}),e===0&&t===0?"ResourceAttributionPathSpec.NONE":e>t?"ResourceAttributionPathSpec.TENANT":"ResourceAttributionPathSpec.OWNER"}function ye(n,e,t,o){const r=`${t.contextAlias}/${t.aggregateName}/${o}.ts`;return ue(n,e,r)}function x(n,e){return`${w(n.aggregateName)}${e}`}function _(n){return n==="delete"?"del":n}const gt="x-fetcher-method";function ut(n,e){const t=n[gt];if(t)return t;if(!n.operationId)return;const o=M(n.operationId);for(let r=o.length-1;r>=0;r--){const i=h(o.slice(r));if(!e(i))return i}return h(o)}class lt{constructor(e){this.context=e,this.apiMetadataCtorInitializer=this.context.currentContextAlias?`{basePath:${N(this.context.currentContextAlias)}}`:void 0}defaultParameterRequestType="ParameterRequest";defaultReturnType=st;apiMetadataCtorInitializer;generate(){this.context.logger.info("Starting API client generation");const e=this.resolveApiTags();this.context.logger.info(`Resolved ${e.size} API client tags: ${Array.from(e.keys()).join(", ")}`);const t=this.groupOperations(e);this.context.logger.info(`Grouped operations into ${t.size} tag groups`),this.generateApiClients(e,t),this.context.logger.success("API client generation completed")}generateApiClients(e,t){this.context.logger.info(`Generating ${t.size} API client classes`);let o=0;for(const[r,i]of t){o++,this.context.logger.progressWithCount(o,t.size,`Generating API client for tag: ${r}`);const s=e.get(r);this.generateApiClient(s,i)}}createApiClientFile(e){let t=e.path;return this.context.currentContextAlias&&(t=m.combineURLs(this.context.currentContextAlias,t)),t=m.combineURLs(t,`${e.name}ApiClient.ts`),this.context.logger.info(`Creating API client file: ${t}`),this.context.getOrCreateSourceFile(t)}generateApiClient(e,t){const o=l(e.name);this.context.logger.info(`Generating API client class: ${o.name}ApiClient with ${t.size} operations`);const r=this.createApiClientFile(o);at(r),me(r),he(r);const i=j(o.name+"ApiClient",r);$(i,[e.description]),fe(i,this.apiMetadataCtorInitializer),this.context.logger.info(`Processing ${t.size} operations for ${o.name}ApiClient`),t.forEach(s=>{this.processOperation(e,r,i,s)}),this.context.logger.success(`Completed API client: ${o.name}ApiClient`)}getMethodName(e,t){const o=ut(t,r=>e.getMethod(r)!==void 0);if(!o)throw new Error(`Unable to resolve method name for apiClientClass:${e.getName()}.`);return o}resolveRequestType(e,t){if(!t.requestBody)return this.context.logger.info(`No request body found for operation ${t.operationId}, using default: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType;let o;if(p(t.requestBody)?(this.context.logger.info(`Extracting request body from reference for operation: ${t.operationId}`),o=Y(t.requestBody,this.context.openAPI.components)):o=t.requestBody,!o)return this.context.logger.info(`Request body extraction failed for operation ${t.operationId}, using default: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType;if(o.content["multipart/form-data"])return this.context.logger.info(`Detected multipart/form-data content for operation ${t.operationId}, using ParameterRequest<FormData>`),"ParameterRequest<FormData>";if(o.content["application/json"]){const r=o.content["application/json"].schema;if(p(r)){const i=E(r);this.context.logger.info(`Adding import for request body model: ${i.name} from ${i.path}`),d(e,this.context.outputDir,i);const s=`ParameterRequest<${i.name}>`;return this.context.logger.info(`Resolved request type for operation ${t.operationId}: ${s}`),s}}return this.context.logger.info(`Using default request type for operation ${t.operationId}: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType}resolveParameters(e,t,o){const r=Oe(o,this.context.openAPI.components).filter(a=>!this.context.isIgnoreApiClientPathParameters(e.name,a.name));this.context.logger.info(`Found ${r.length} path parameters for operation ${o.operationId}`);const i=r.map(a=>{const c=ae(a);return this.context.logger.info(`Adding path parameter: ${a.name} (type: ${c})`),{name:a.name,type:c,hasQuestionToken:!1,decorators:[{name:"path",arguments:[`'${a.name}'`]}]}}),s=this.resolveRequestType(t,o);return this.context.logger.info(`Adding httpRequest parameter: ${s}`),i.push({name:"httpRequest",hasQuestionToken:s===this.defaultParameterRequestType,type:`${s}`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: Record<string, any>"),i.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),i}resolveType(e,t){if(p(t)){const o=E(t);return d(e,this.context.outputDir,o),o.name}if(R(t)){const o=this.resolveType(e,t.items);return oe(o)}if(re(t)){const o=t.additionalProperties;return typeof o=="boolean"?"Record<string, any>":`Record<string, ${this.resolveType(e,o)}>`}return t.type&&ne(t.type)?D(t.type):"any"}resolveSchemaReturnType(e,t){return`Promise<${this.resolveType(e,t)}>`}resolveReturnType(e,t){const o=W(t);if(!o)return this.context.logger.info(`No OK response found for operation ${t.operationId}, using default return type: ${this.defaultReturnType.type}`),this.defaultReturnType;const r=te(o)||ve(o);if(r){const s=this.resolveSchemaReturnType(e,r);return this.context.logger.info(`Resolved JSON/wildcard response return type for operation ${t.operationId}: ${s}`),{type:s,metadata:s===H.type?H.metadata:void 0}}const i=Te(o);if(i){if(p(i)){const a=S(i,this.context.openAPI.components);if(R(a)&&p(a.items)){const c=E(a.items);this.context.logger.info(`Adding import for event stream model: ${c.name} from ${c.path}`),d(e,this.context.outputDir,c);const g=`Promise<JsonServerSentEventStream<${c.name.includes("ServerSentEvent")?`${c.name}['data']`:c.name}>>`;return this.context.logger.info(`Resolved event stream return type for operation ${t.operationId}: ${g}`),{type:g,metadata:F}}}const s="Promise<JsonServerSentEventStream<any>>";return this.context.logger.info(`Resolved generic event stream return type for operation ${t.operationId}: ${s}`),{type:s,metadata:F}}return this.context.logger.info(`Using default return type for operation ${t.operationId}: ${this.defaultReturnType.type}`),this.defaultReturnType}processOperation(e,t,o,r){this.context.logger.info(`Processing operation: ${r.operation.operationId} (${r.method} ${r.path})`);const i=this.getMethodName(o,r.operation);this.context.logger.info(`Generated method name: ${i}`);const s=this.resolveParameters(e,t,r.operation),a=this.resolveReturnType(t,r.operation),c=a.metadata?{name:_(r.method),arguments:[`'${r.path}'`,a.metadata]}:{name:_(r.method),arguments:[`'${r.path}'`]};this.context.logger.info(`Creating method with ${s.length} parameters, return type: ${a.type}`);const y=o.addMethod({name:i,decorators:[c],parameters:s,returnType:a.type,statements:[`throw autoGeneratedError(${s.map(g=>g.name).join(",")});`]});$(y,[r.operation.summary,r.operation.description,`- operationId: \`${r.operation.operationId}\``,`- path: \`${r.path}\``]),this.context.logger.success(`Operation method generated: ${i}`)}groupOperations(e){this.context.logger.info("Grouping operations by API client tags");const t=new Map,o=ie(this.context.openAPI.paths).filter(i=>{if(!i.operation.operationId)return!1;const s=i.operation.tags;return!s||s.length==0?!1:s.every(a=>e.has(a))});let r=0;for(const i of o)i.operation.tags.forEach(s=>{t.has(s)||t.set(s,new Set),t.get(s).add(i),r++});return this.context.logger.info(`Grouped ${r} operations into ${t.size} tag groups`),t}shouldIgnoreTag(e){return e==="wow"||e==="Actuator"||this.isAggregateTag(e)}resolveApiTags(){this.context.logger.info("Resolving API client tags from OpenAPI specification");const e=new Map,t=this.context.openAPI.tags?.length||0;for(const r of Object.values(this.context.openAPI.paths))se(r).forEach(i=>{i.operation.tags?.forEach(s=>{!this.shouldIgnoreTag(s)&&!e.has(s)&&e.set(s,{name:s,description:""})})});let o=0;return this.context.openAPI.tags?.forEach(r=>{this.shouldIgnoreTag(r.name)?this.context.logger.info(`Excluded tag: ${r.name} (wow/Actuator/aggregate)`):(e.set(r.name,r),o++,this.context.logger.info(`Included API client tag: ${r.name}`))}),this.context.logger.info(`Resolved ${o} API client tags from ${t} total tags`),e}isAggregateTag(e){for(const t of this.context.contextAggregates.values())for(const o of t)if(o.aggregate.tag.name===e)return!0;return!1}}class dt{constructor(e){this.context=e}commandEndpointPathsSuffix="CommandEndpointPaths";defaultCommandClientOptionsName="DEFAULT_COMMAND_CLIENT_OPTIONS";generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((o,r)=>o+r.size,0);this.context.logger.info("--- Generating Command Clients ---"),this.context.logger.progress(`Generating command clients for ${e} aggregates`);let t=0;for(const[,o]of this.context.contextAggregates)o.forEach(r=>{t++,this.context.logger.progressWithCount(t,e,`Processing command client for aggregate: ${r.aggregate.aggregateName}`),this.processAggregate(r)});this.context.logger.success("Command client generation completed")}processAggregate(e){this.context.logger.info(`Processing command client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`);const t=ye(this.context.project,this.context.outputDir,e.aggregate,"commandClient");this.context.logger.info(`Processing command endpoint paths for ${e.commands.size} commands`);const o=this.processCommandEndpointPaths(t,e);this.processCommandTypes(t,e),this.context.logger.info(`Creating default command client options: ${this.defaultCommandClientOptionsName}`),t.addVariableStatement({declarationKind:P.VariableDeclarationKind.Const,declarations:[{name:this.defaultCommandClientOptionsName,type:"ApiMetadata",initializer:`{
14
+ }`;function pt(n){C(n,rt,it)}function me(n){C(n,st,at)}function j(n,e,t=[],o=[],r){return e.addClass({name:n,isExported:!0,typeParameters:o,extends:r,decorators:[{name:"api",arguments:t}]})}function fe(n,e){n.addImplements("ApiMetadataCapable"),n.addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",hasQuestionToken:e===void 0,scope:P.Scope.Public,isReadonly:!0,initializer:e}]})}const gt="@ahoo-wang/fetcher-eventstream";function he(n){C(n,gt,["JsonEventStreamResultExtractor","type JsonServerSentEventStream"])}function ut(n){let e=0,t=0;return n.commands.forEach(o=>{o.path.startsWith(z.ResourceAttributionPathSpec.TENANT)&&(e+=1),o.path.startsWith(z.ResourceAttributionPathSpec.OWNER)&&(t+=1)}),e===0&&t===0?"ResourceAttributionPathSpec.NONE":e>t?"ResourceAttributionPathSpec.TENANT":"ResourceAttributionPathSpec.OWNER"}function ye(n,e,t,o){const r=`${t.contextAlias}/${t.aggregateName}/${o}.ts`;return ue(n,e,r)}function x(n,e){return`${w(n.aggregateName)}${e}`}function _(n){return n==="delete"?"del":n}const lt="x-fetcher-method";function dt(n,e){const t=n[lt];if(t)return t;if(!n.operationId)return;const o=M(n.operationId);for(let r=o.length-1;r>=0;r--){const i=h(o.slice(r));if(!e(i))return i}return h(o)}class mt{constructor(e){this.context=e,this.apiMetadataCtorInitializer=this.context.currentContextAlias?`{basePath:${N(this.context.currentContextAlias)}}`:void 0}defaultParameterRequestType="ParameterRequest";defaultReturnType=ct;apiMetadataCtorInitializer;generate(){this.context.logger.info("Starting API client generation");const e=this.resolveApiTags();this.context.logger.info(`Resolved ${e.size} API client tags: ${Array.from(e.keys()).join(", ")}`);const t=this.groupOperations(e);this.context.logger.info(`Grouped operations into ${t.size} tag groups`),this.generateApiClients(e,t),this.context.logger.success("API client generation completed")}generateApiClients(e,t){this.context.logger.info(`Generating ${t.size} API client classes`);let o=0;for(const[r,i]of t){o++,this.context.logger.progressWithCount(o,t.size,`Generating API client for tag: ${r}`);const s=e.get(r);this.generateApiClient(s,i)}}createApiClientFile(e){let t=e.path;return this.context.currentContextAlias&&(t=m.combineURLs(this.context.currentContextAlias,t)),t=m.combineURLs(t,`${e.name}ApiClient.ts`),this.context.logger.info(`Creating API client file: ${t}`),this.context.getOrCreateSourceFile(t)}generateApiClient(e,t){const o=l(e.name);this.context.logger.info(`Generating API client class: ${o.name}ApiClient with ${t.size} operations`);const r=this.createApiClientFile(o);pt(r),me(r),he(r);const i=j(o.name+"ApiClient",r);T(i,[e.description]),fe(i,this.apiMetadataCtorInitializer),this.context.logger.info(`Processing ${t.size} operations for ${o.name}ApiClient`),t.forEach(s=>{this.processOperation(e,r,i,s)}),this.context.logger.success(`Completed API client: ${o.name}ApiClient`)}getMethodName(e,t){const o=dt(t,r=>e.getMethod(r)!==void 0);if(!o)throw new Error(`Unable to resolve method name for apiClientClass:${e.getName()}.`);return o}resolveRequestType(e,t){if(!t.requestBody)return this.context.logger.info(`No request body found for operation ${t.operationId}, using default: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType;let o;if(p(t.requestBody)?(this.context.logger.info(`Extracting request body from reference for operation: ${t.operationId}`),o=Y(t.requestBody,this.context.openAPI.components)):o=t.requestBody,!o)return this.context.logger.info(`Request body extraction failed for operation ${t.operationId}, using default: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType;if(o.content["multipart/form-data"])return this.context.logger.info(`Detected multipart/form-data content for operation ${t.operationId}, using ParameterRequest<FormData>`),"ParameterRequest<FormData>";if(o.content["application/json"]){const r=o.content["application/json"].schema;if(p(r)){const i=E(r);this.context.logger.info(`Adding import for request body model: ${i.name} from ${i.path}`),d(e,this.context.outputDir,i);const s=`ParameterRequest<${i.name}>`;return this.context.logger.info(`Resolved request type for operation ${t.operationId}: ${s}`),s}}return this.context.logger.info(`Using default request type for operation ${t.operationId}: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType}resolveParameters(e,t,o){const r=be(o,this.context.openAPI.components).filter(a=>!this.context.isIgnoreApiClientPathParameters(e.name,a.name));this.context.logger.info(`Found ${r.length} path parameters for operation ${o.operationId}`);const i=r.map(a=>{const c=ae(a);return this.context.logger.info(`Adding path parameter: ${a.name} (type: ${c})`),{name:a.name,type:c,hasQuestionToken:!1,decorators:[{name:"path",arguments:[`'${a.name}'`]}]}}),s=this.resolveRequestType(t,o);return this.context.logger.info(`Adding httpRequest parameter: ${s}`),i.push({name:"httpRequest",hasQuestionToken:s===this.defaultParameterRequestType,type:`${s}`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: Record<string, any>"),i.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),i}resolveType(e,t){if(p(t)){const o=E(t);return d(e,this.context.outputDir,o),o.name}if(R(t)){const o=this.resolveType(e,t.items);return oe(o)}if(re(t)){const o=t.additionalProperties;return typeof o=="boolean"?"Record<string, any>":`Record<string, ${this.resolveType(e,o)}>`}return t.type&&ne(t.type)?D(t.type):"any"}resolveSchemaReturnType(e,t){return`Promise<${this.resolveType(e,t)}>`}resolveReturnType(e,t){const o=W(t);if(!o)return this.context.logger.info(`No OK response found for operation ${t.operationId}, using default return type: ${this.defaultReturnType.type}`),this.defaultReturnType;const r=te(o)||ve(o);if(r){const s=this.resolveSchemaReturnType(e,r);return this.context.logger.info(`Resolved JSON/wildcard response return type for operation ${t.operationId}: ${s}`),{type:s,metadata:s===K.type?K.metadata:void 0}}const i=$e(o);if(i){if(p(i)){const a=S(i,this.context.openAPI.components);if(R(a)&&p(a.items)){const c=E(a.items);this.context.logger.info(`Adding import for event stream model: ${c.name} from ${c.path}`),d(e,this.context.outputDir,c);const g=`Promise<JsonServerSentEventStream<${c.name.includes("ServerSentEvent")?`${c.name}['data']`:c.name}>>`;return this.context.logger.info(`Resolved event stream return type for operation ${t.operationId}: ${g}`),{type:g,metadata:F}}}const s="Promise<JsonServerSentEventStream<any>>";return this.context.logger.info(`Resolved generic event stream return type for operation ${t.operationId}: ${s}`),{type:s,metadata:F}}return this.context.logger.info(`Using default return type for operation ${t.operationId}: ${this.defaultReturnType.type}`),this.defaultReturnType}processOperation(e,t,o,r){this.context.logger.info(`Processing operation: ${r.operation.operationId} (${r.method} ${r.path})`);const i=this.getMethodName(o,r.operation);this.context.logger.info(`Generated method name: ${i}`);const s=this.resolveParameters(e,t,r.operation),a=this.resolveReturnType(t,r.operation),c=a.metadata?{name:_(r.method),arguments:[`'${r.path}'`,a.metadata]}:{name:_(r.method),arguments:[`'${r.path}'`]};this.context.logger.info(`Creating method with ${s.length} parameters, return type: ${a.type}`);const y=o.addMethod({name:i,decorators:[c],parameters:s,returnType:a.type,statements:[`throw autoGeneratedError(${s.map(g=>g.name).join(",")});`]});T(y,[r.operation.summary,r.operation.description,`- operationId: \`${r.operation.operationId}\``,`- path: \`${r.path}\``]),this.context.logger.success(`Operation method generated: ${i}`)}groupOperations(e){this.context.logger.info("Grouping operations by API client tags");const t=new Map,o=ie(this.context.openAPI.paths).filter(i=>{if(!i.operation.operationId)return!1;const s=i.operation.tags;return!s||s.length==0?!1:s.every(a=>e.has(a))});let r=0;for(const i of o)i.operation.tags.forEach(s=>{t.has(s)||t.set(s,new Set),t.get(s).add(i),r++});return this.context.logger.info(`Grouped ${r} operations into ${t.size} tag groups`),t}shouldIgnoreTag(e){return e==="wow"||e==="Actuator"||this.isAggregateTag(e)}resolveApiTags(){this.context.logger.info("Resolving API client tags from OpenAPI specification");const e=new Map,t=this.context.openAPI.tags?.length||0;for(const r of Object.values(this.context.openAPI.paths))se(r).forEach(i=>{i.operation.tags?.forEach(s=>{!this.shouldIgnoreTag(s)&&!e.has(s)&&e.set(s,{name:s,description:""})})});let o=0;return this.context.openAPI.tags?.forEach(r=>{this.shouldIgnoreTag(r.name)?this.context.logger.info(`Excluded tag: ${r.name} (wow/Actuator/aggregate)`):(e.set(r.name,r),o++,this.context.logger.info(`Included API client tag: ${r.name}`))}),this.context.logger.info(`Resolved ${o} API client tags from ${t} total tags`),e}isAggregateTag(e){for(const t of this.context.contextAggregates.values())for(const o of t)if(o.aggregate.tag.name===e)return!0;return!1}}class ft{constructor(e){this.context=e}commandEndpointPathsSuffix="CommandEndpointPaths";defaultCommandClientOptionsName="DEFAULT_COMMAND_CLIENT_OPTIONS";generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((o,r)=>o+r.size,0);this.context.logger.info("--- Generating Command Clients ---"),this.context.logger.progress(`Generating command clients for ${e} aggregates`);let t=0;for(const[,o]of this.context.contextAggregates)o.forEach(r=>{t++,this.context.logger.progressWithCount(t,e,`Processing command client for aggregate: ${r.aggregate.aggregateName}`),this.processAggregate(r)});this.context.logger.success("Command client generation completed")}processAggregate(e){this.context.logger.info(`Processing command client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`);const t=ye(this.context.project,this.context.outputDir,e.aggregate,"commandClient");this.context.logger.info(`Processing command endpoint paths for ${e.commands.size} commands`);const o=this.processCommandEndpointPaths(t,e);this.processCommandTypes(t,e),this.context.logger.info(`Creating default command client options: ${this.defaultCommandClientOptionsName}`),t.addVariableStatement({declarationKind:P.VariableDeclarationKind.Const,declarations:[{name:this.defaultCommandClientOptionsName,type:"ApiMetadata",initializer:`{
15
15
  basePath: ${N(e.aggregate.contextAlias)}
16
- }`}],isExported:!1}),this.context.logger.info(`Adding imports from ${A}: CommandRequest, CommandResult, CommandResultEventStream, CommandBody, DeleteAggregateCommand, RecoverAggregateCommand`),t.addImportDeclaration({moduleSpecifier:A,namedImports:["CommandRequest","CommandResult","CommandResultEventStream","CommandBody","DeleteAggregateCommand","RecoverAggregateCommand"],isTypeOnly:!0}),this.context.logger.info("Adding import from @ahoo-wang/fetcher-eventstream: JsonEventStreamResultExtractor"),he(t),this.context.logger.info("Adding import from @ahoo-wang/fetcher: ContentTypeValues"),C(t,"@ahoo-wang/fetcher",["ContentTypeValues"]),this.context.logger.info("Adding imports from @ahoo-wang/fetcher-decorator: ApiMetadata types and decorators"),me(t),this.context.logger.info("Generating standard command client class"),this.processCommandClient(t,e,o),this.context.logger.info("Generating stream command client class"),this.processStreamCommandClient(t,e),this.context.logger.success(`Command client generation completed for aggregate: ${e.aggregate.aggregateName}`)}resolveAggregateCommandEndpointPathsName(e){return x(e,this.commandEndpointPathsSuffix)}processCommandEndpointPaths(e,t){const o=this.resolveAggregateCommandEndpointPathsName(t.aggregate);this.context.logger.info(`Creating command endpoint paths enum: ${o}`);const r=e.addEnum({name:o,isExported:!0});return t.commands.forEach(i=>{this.context.logger.info(`Adding command endpoint: ${i.name.toUpperCase()} = '${i.path}'`),r.addMember({name:i.name.toUpperCase(),initializer:`'${i.path}'`})}),this.context.logger.success(`Command endpoint paths enum created with ${t.commands.size} entries`),o}resolveCommandTypeName(e){const t=l(e.schema.key);return[t,t.name+"Command"]}resolveCommandType(e,t){const[o,r]=this.resolveCommandTypeName(t);if(o.path===A)return;d(e,this.context.outputDir,o);let i=`${o.name}`;const s=De(t.schema.schema).map(a=>`'${a}'`).join(" | ");s!==""&&(i=`PartialBy<${i},${s}>`),i=`CommandBody<${i}>`,e.addTypeAlias({name:r,type:`${i}`,isExported:!0})}processCommandTypes(e,t){t.commands.forEach(o=>{this.resolveCommandType(e,o)})}getEndpointPath(e,t){return`${e}.${t.name.toUpperCase()}`}processCommandClient(e,t,o){const r=x(t.aggregate,"CommandClient"),i=j(r,e,[],["R = CommandResult"]);fe(i,this.defaultCommandClientOptionsName),t.commands.forEach(s=>{this.processCommandMethod(t,i,s,o)})}processStreamCommandClient(e,t){const o=x(t.aggregate,"CommandClient"),r=x(t.aggregate,"StreamCommandClient");j(r,e,["''",F],[],`${o}<CommandResultEventStream>`).addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",initializer:this.defaultCommandClientOptionsName}],statements:"super(apiMetadata);"})}resolveParameters(e,t){const[o,r]=this.resolveCommandTypeName(t);this.context.logger.info(`Adding import for command model: ${o.name} from path: ${o.path}`);const i=t.pathParameters.filter(s=>!this.context.isIgnoreCommandClientPathParameters(e.name,s.name)).map(s=>{const a=ae(s);return this.context.logger.info(`Adding path parameter: ${s.name} (type: ${a})`),{name:s.name,type:a,hasQuestionToken:!1,decorators:[{name:"path",arguments:[`'${s.name}'`]}]}});return this.context.logger.info(`Adding command request parameter: commandRequest (type: CommandRequest<${r}>)`),i.push({name:"commandRequest",hasQuestionToken:Re(t.schema.schema),type:`CommandRequest<${r}>`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: attributes (type: Record<string, any>)"),i.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),i}processCommandMethod(e,t,o,r){this.context.logger.info(`Generating command method: ${h(o.name)} for command: ${o.name}`),this.context.logger.info(`Command method details: HTTP ${o.method}, path: ${o.path}`);const i=this.resolveParameters(e.aggregate.tag,o),s=t.addMethod({name:h(o.name),decorators:[{name:_(o.method),arguments:[`${this.getEndpointPath(r,o)}`]}],parameters:i,returnType:"Promise<R>",statements:`throw autoGeneratedError(${i.map(a=>a.name).join(",")});`});this.context.logger.info(`Adding JSDoc documentation for method: ${h(o.name)}`),$(s,[o.summary,o.description,`- operationId: \`${o.operation.operationId}\``,`- path: \`${o.path}\``]),this.context.logger.success(`Command method generated: ${h(o.name)}`)}}class mt{constructor(e){this.context=e}domainEventTypeSuffix="DomainEventType";domainEventTypeMapTitleSuffix="DomainEventTypeMapTitle";generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((o,r)=>o+r.size,0);this.context.logger.info("--- Generating Query Clients ---"),this.context.logger.progress(`Generating query clients for ${e} aggregates`);let t=0;for(const[,o]of this.context.contextAggregates)o.forEach(r=>{t++,this.context.logger.progressWithCount(t,e,`Processing query client for aggregate: ${r.aggregate.aggregateName}`),this.processQueryClient(r)});this.context.logger.success("Query client generation completed")}createClientFilePath(e,t){return ye(this.context.project,this.context.outputDir,e,t)}processQueryClient(e){const t=this.createClientFilePath(e.aggregate,"queryClient");this.context.logger.info(`Processing query client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`),this.context.logger.info(`Adding imports from ${A}: QueryClientFactory, QueryClientOptions, ResourceAttributionPathSpec`),t.addImportDeclaration({moduleSpecifier:A,namedImports:["QueryClientFactory","QueryClientOptions","ResourceAttributionPathSpec"]});const o="DEFAULT_QUERY_CLIENT_OPTIONS";this.context.logger.info(`Creating default query client options: ${o}`),t.addVariableStatement({declarationKind:P.VariableDeclarationKind.Const,declarations:[{name:o,type:"QueryClientOptions",initializer:`{
16
+ }`}],isExported:!1}),this.context.logger.info(`Adding imports from ${A}: CommandRequest, CommandResult, CommandResultEventStream, CommandBody, DeleteAggregateCommand, RecoverAggregateCommand`),t.addImportDeclaration({moduleSpecifier:A,namedImports:["CommandRequest","CommandResult","CommandResultEventStream","CommandBody","DeleteAggregateCommand","RecoverAggregateCommand"],isTypeOnly:!0}),this.context.logger.info("Adding import from @ahoo-wang/fetcher-eventstream: JsonEventStreamResultExtractor"),he(t),this.context.logger.info("Adding import from @ahoo-wang/fetcher: ContentTypeValues"),C(t,"@ahoo-wang/fetcher",["ContentTypeValues"]),this.context.logger.info("Adding imports from @ahoo-wang/fetcher-decorator: ApiMetadata types and decorators"),me(t),this.context.logger.info("Generating standard command client class"),this.processCommandClient(t,e,o),this.context.logger.info("Generating stream command client class"),this.processStreamCommandClient(t,e),this.context.logger.success(`Command client generation completed for aggregate: ${e.aggregate.aggregateName}`)}resolveAggregateCommandEndpointPathsName(e){return x(e,this.commandEndpointPathsSuffix)}processCommandEndpointPaths(e,t){const o=this.resolveAggregateCommandEndpointPathsName(t.aggregate);this.context.logger.info(`Creating command endpoint paths enum: ${o}`);const r=e.addEnum({name:o,isExported:!0});return t.commands.forEach(i=>{this.context.logger.info(`Adding command endpoint: ${i.name.toUpperCase()} = '${i.path}'`),r.addMember({name:i.name.toUpperCase(),initializer:`'${i.path}'`})}),this.context.logger.success(`Command endpoint paths enum created with ${t.commands.size} entries`),o}resolveCommandTypeName(e){const t=l(e.schema.key);return[t,t.name+"Command"]}resolveCommandType(e,t){const[o,r]=this.resolveCommandTypeName(t);if(o.path===A)return;d(e,this.context.outputDir,o);let i=`${o.name}`;const s=Oe(t.schema.schema).map(a=>`'${a}'`).join(" | ");s!==""&&(i=`PartialBy<${i},${s}>`),i=`CommandBody<${i}>`,e.addTypeAlias({name:r,type:`${i}`,isExported:!0})}processCommandTypes(e,t){t.commands.forEach(o=>{this.resolveCommandType(e,o)})}getEndpointPath(e,t){return`${e}.${t.name.toUpperCase()}`}processCommandClient(e,t,o){const r=x(t.aggregate,"CommandClient"),i=j(r,e,[],["R = CommandResult"]);fe(i,this.defaultCommandClientOptionsName),t.commands.forEach(s=>{this.processCommandMethod(t,i,s,o)})}processStreamCommandClient(e,t){const o=x(t.aggregate,"CommandClient"),r=x(t.aggregate,"StreamCommandClient");j(r,e,["''",F],[],`${o}<CommandResultEventStream>`).addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",initializer:this.defaultCommandClientOptionsName}],statements:"super(apiMetadata);"})}resolveParameters(e,t){const[o,r]=this.resolveCommandTypeName(t);this.context.logger.info(`Adding import for command model: ${o.name} from path: ${o.path}`);const i=t.pathParameters.filter(s=>!this.context.isIgnoreCommandClientPathParameters(e.name,s.name)).map(s=>{const a=ae(s);return this.context.logger.info(`Adding path parameter: ${s.name} (type: ${a})`),{name:s.name,type:a,hasQuestionToken:!1,decorators:[{name:"path",arguments:[`'${s.name}'`]}]}});return this.context.logger.info(`Adding command request parameter: commandRequest (type: CommandRequest<${r}>)`),i.push({name:"commandRequest",hasQuestionToken:De(t.schema.schema),type:`CommandRequest<${r}>`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: attributes (type: Record<string, any>)"),i.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),i}processCommandMethod(e,t,o,r){this.context.logger.info(`Generating command method: ${h(o.name)} for command: ${o.name}`),this.context.logger.info(`Command method details: HTTP ${o.method}, path: ${o.path}`);const i=this.resolveParameters(e.aggregate.tag,o),s=t.addMethod({name:h(o.name),decorators:[{name:_(o.method),arguments:[`${this.getEndpointPath(r,o)}`]}],parameters:i,returnType:"Promise<R>",statements:`throw autoGeneratedError(${i.map(a=>a.name).join(",")});`});this.context.logger.info(`Adding JSDoc documentation for method: ${h(o.name)}`),T(s,[o.summary,o.description,`- operationId: \`${o.operation.operationId}\``,`- path: \`${o.path}\``]),this.context.logger.success(`Command method generated: ${h(o.name)}`)}}class ht{constructor(e){this.context=e}domainEventTypeSuffix="DomainEventType";domainEventTypeMapTitleSuffix="DomainEventTypeMapTitle";generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((o,r)=>o+r.size,0);this.context.logger.info("--- Generating Query Clients ---"),this.context.logger.progress(`Generating query clients for ${e} aggregates`);let t=0;for(const[,o]of this.context.contextAggregates)o.forEach(r=>{t++,this.context.logger.progressWithCount(t,e,`Processing query client for aggregate: ${r.aggregate.aggregateName}`),this.processQueryClient(r)});this.context.logger.success("Query client generation completed")}createClientFilePath(e,t){return ye(this.context.project,this.context.outputDir,e,t)}processQueryClient(e){const t=this.createClientFilePath(e.aggregate,"queryClient");this.context.logger.info(`Processing query client for aggregate: ${e.aggregate.aggregateName} in context: ${e.aggregate.contextAlias}`),this.context.logger.info(`Adding imports from ${A}: QueryClientFactory, QueryClientOptions, ResourceAttributionPathSpec`),t.addImportDeclaration({moduleSpecifier:A,namedImports:["QueryClientFactory","QueryClientOptions","ResourceAttributionPathSpec"]});const o="DEFAULT_QUERY_CLIENT_OPTIONS";this.context.logger.info(`Creating default query client options: ${o}`),t.addVariableStatement({declarationKind:P.VariableDeclarationKind.Const,declarations:[{name:o,type:"QueryClientOptions",initializer:`{
17
17
  contextAlias: ${N(e.aggregate.contextAlias)},
18
18
  aggregateName: '${e.aggregate.aggregateName}',
19
- resourceAttribution: ${pt(e)},
20
- }`}],isExported:!1}),this.processAggregateDomainEventTypes(e,t);const r=this.processAggregateDomainEventType(e,t),i=`${h(e.aggregate.aggregateName)}QueryClientFactory`,s=l(e.state.key),a=l(e.fields.key);this.context.logger.info(`Adding import for state model: ${s.name} from path: ${s.path}`),d(t,this.context.outputDir,s),this.context.logger.info(`Adding import for fields model: ${a.name} from path: ${a.path}`),d(t,this.context.outputDir,a),this.context.logger.info(`Creating query client factory: ${i}`),t.addVariableStatement({declarationKind:P.VariableDeclarationKind.Const,declarations:[{name:i,initializer:`new QueryClientFactory<${s.name}, ${a.name} | string, ${r}>(${o})`}],isExported:!0}),this.context.logger.success(`Query client generation completed for aggregate: ${e.aggregate.aggregateName}`)}processAggregateDomainEventType(e,t){const o=[];this.context.logger.info(`Processing ${e.events.size} domain events for aggregate: ${e.aggregate.aggregateName}`);for(const s of e.events.values()){const a=l(s.schema.key);this.context.logger.info(`Adding import for event model: ${a.name} from path: ${a.path}`),d(t,this.context.outputDir,a),o.push(a)}const r=x(e.aggregate,this.domainEventTypeSuffix),i=o.map(s=>s.name).join(" | ");return this.context.logger.info(`Creating domain event types union: ${r} = ${i}`),t.addTypeAlias({isExported:!0,name:r,type:i}),r}processAggregateDomainEventTypes(e,t){const o=x(e.aggregate,this.domainEventTypeMapTitleSuffix),r=t.addEnum({name:o,isExported:!0});for(const i of e.events.values())r.addMember({name:i.name,initializer:`'${i.title}'`})}}class ft{constructor(e){this.context=e,this.queryClientGenerator=new mt(e),this.commandClientGenerator=new dt(e),this.apiClientGenerator=new lt(e)}queryClientGenerator;commandClientGenerator;apiClientGenerator;generate(){this.context.logger.info("--- Generating Clients ---"),this.context.logger.progress(`Generating clients for ${this.context.contextAggregates.size} bounded contexts`);let e=0;for(const[t]of this.context.contextAggregates)e++,this.context.logger.progressWithCount(e,this.context.contextAggregates.size,`Processing bounded context: ${t}`,1);this.queryClientGenerator.generate(),this.commandClientGenerator.generate(),this.apiClientGenerator.generate(),this.context.logger.success("Client generation completed")}}class ht{project;openAPI;outputDir;contextAggregates;logger;config;defaultIgnorePathParameters=["tenantId","ownerId"];currentContextAlias;constructor(e){this.project=e.project,this.openAPI=e.openAPI,this.outputDir=e.outputDir,this.contextAggregates=e.contextAggregates,this.logger=e.logger,this.config=e.config??{},this.currentContextAlias=this.openAPI.info["x-wow-context-alias"]}getOrCreateSourceFile(e){return ue(this.project,this.outputDir,e)}isIgnoreApiClientPathParameters(e,t){return(this.config.apiClients?.[e]?.ignorePathParameters??this.defaultIgnorePathParameters).includes(t)}isIgnoreCommandClientPathParameters(e,t){return this.defaultIgnorePathParameters.includes(t)}}const xe="./fetcher-generator.config.json";class yt{constructor(e){this.options=e,this.project=new P.Project(e),this.options.logger.info(`Project instance created with tsConfigFilePath: ${this.options.tsConfigFilePath}`)}project;async generate(){this.options.logger.info("Starting code generation from OpenAPI specification");const e=process.cwd();this.options.logger.info(`Work directory: ${e}`),this.options.logger.info(`Input path: ${this.options.inputPath}`),this.options.logger.info(`Output directory: ${this.options.outputDir}`),this.options.logger.info("Parsing OpenAPI specification");const t=await Fe(this.options.inputPath);this.options.logger.info("OpenAPI specification parsed successfully"),this.options.logger.info("Resolving bounded context aggregates");const r=new Ze(t).resolve();this.options.logger.info(`Resolved ${r.size} bounded context aggregates`);const i=this.options.configPath??xe;let s={};try{this.options.logger.info(`Parsing configuration file: ${i}`),s=await je(i)}catch(f){this.options.logger.info(`Configuration file parsing failed: ${f}`)}const a=new ht({openAPI:t,project:this.project,outputDir:this.options.outputDir,contextAggregates:r,logger:this.options.logger,config:s});this.options.logger.info("Generating models"),new tt(a).generate(),this.options.logger.info("Models generated successfully"),this.options.logger.info("Generating clients"),new ft(a).generate(),this.options.logger.info("Clients generated successfully");const g=this.project.getDirectory(this.options.outputDir);if(!g){this.options.logger.info("Output directory not found.");return}this.options.logger.info("Generating index files"),this.generateIndex(g),this.options.logger.info("Index files generated successfully"),this.options.logger.info("Optimizing source files"),this.optimizeSourceFiles(g),this.options.logger.info("Source files optimized successfully"),this.options.logger.info("Saving project to disk"),await this.project.save(),this.options.logger.info("Code generation completed successfully")}generateIndex(e){this.options.logger.info(`Generating index files for output directory: ${this.options.outputDir}`),this.processDirectory(e),this.generateIndexForDirectory(e),this.options.logger.info("Index file generation completed")}processDirectory(e){const t=e.getDirectories();this.options.logger.info(`Processing ${t.length} subdirectories`);for(const o of t)this.options.logger.info(`Processing subdirectory: ${o.getPath()}`),this.generateIndexForDirectory(o),this.processDirectory(o)}generateIndexForDirectory(e){const t=e.getPath();this.options.logger.info(`Generating index for directory: ${t}`);const o=e.getSourceFiles().filter(a=>a.getBaseName().endsWith(".ts")&&a.getBaseName()!=="index.ts"),r=e.getDirectories();if(this.options.logger.info(`Found ${o.length} TypeScript files and ${r.length} subdirectories in ${t}`),o.length===0&&r.length===0){this.options.logger.info(`No files or subdirectories to export in ${t}, skipping index generation`);return}const i=`${t}/index.ts`,s=this.project.getSourceFile(i)||this.project.createSourceFile(i,"",{overwrite:!0});s.removeText();for(const a of o){const c=`./${a.getBaseNameWithoutExtension()}`;s.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}for(const a of r){const c=`./${a.getBaseName()}`;s.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}this.options.logger.info(`Index file generated for ${t} with ${o.length+r.length} exports`)}optimizeSourceFiles(e){const t=e.getDescendantSourceFiles();this.options.logger.info(`Optimizing ${t.length} source files in ${e.getPath()}`),t.forEach((o,r)=>{this.options.logger.info(`Optimizing file [${o.getFilePath()}] - ${r+1}/${t.length}`),o.formatText(),o.organizeImports(),o.fixMissingImports()}),this.options.logger.info("All source files optimized")}}exports.CodeGenerator=yt;exports.DEFAULT_CONFIG_PATH=xe;
19
+ resourceAttribution: ${ut(e)},
20
+ }`}],isExported:!1}),this.processAggregateDomainEventTypes(e,t);const r=this.processAggregateDomainEventType(e,t),i=`${h(e.aggregate.aggregateName)}QueryClientFactory`,s=l(e.state.key),a=l(e.fields.key);this.context.logger.info(`Adding import for state model: ${s.name} from path: ${s.path}`),d(t,this.context.outputDir,s),this.context.logger.info(`Adding import for fields model: ${a.name} from path: ${a.path}`),d(t,this.context.outputDir,a),this.context.logger.info(`Creating query client factory: ${i}`),t.addVariableStatement({declarationKind:P.VariableDeclarationKind.Const,declarations:[{name:i,initializer:`new QueryClientFactory<${s.name}, ${a.name} | string, ${r}>(${o})`}],isExported:!0}),this.context.logger.success(`Query client generation completed for aggregate: ${e.aggregate.aggregateName}`)}processAggregateDomainEventType(e,t){const o=[];this.context.logger.info(`Processing ${e.events.size} domain events for aggregate: ${e.aggregate.aggregateName}`);for(const s of e.events.values()){const a=l(s.schema.key);this.context.logger.info(`Adding import for event model: ${a.name} from path: ${a.path}`),d(t,this.context.outputDir,a),o.push(a)}const r=x(e.aggregate,this.domainEventTypeSuffix),i=o.map(s=>s.name).join(" | ");return this.context.logger.info(`Creating domain event types union: ${r} = ${i}`),t.addTypeAlias({isExported:!0,name:r,type:i}),r}processAggregateDomainEventTypes(e,t){const o=x(e.aggregate,this.domainEventTypeMapTitleSuffix),r=t.addEnum({name:o,isExported:!0});for(const i of e.events.values())r.addMember({name:i.name,initializer:`'${i.title}'`})}}class yt{constructor(e){this.context=e,this.queryClientGenerator=new ht(e),this.commandClientGenerator=new ft(e),this.apiClientGenerator=new mt(e)}queryClientGenerator;commandClientGenerator;apiClientGenerator;generate(){this.context.logger.info("--- Generating Clients ---"),this.context.logger.progress(`Generating clients for ${this.context.contextAggregates.size} bounded contexts`);let e=0;for(const[t]of this.context.contextAggregates)e++,this.context.logger.progressWithCount(e,this.context.contextAggregates.size,`Processing bounded context: ${t}`,1);this.queryClientGenerator.generate(),this.commandClientGenerator.generate(),this.apiClientGenerator.generate(),this.context.logger.success("Client generation completed")}}class xt{project;openAPI;outputDir;contextAggregates;logger;config;defaultIgnorePathParameters=["tenantId","ownerId"];currentContextAlias;constructor(e){this.project=e.project,this.openAPI=e.openAPI,this.outputDir=e.outputDir,this.contextAggregates=e.contextAggregates,this.logger=e.logger,this.config=e.config??{},this.currentContextAlias=this.openAPI.info["x-wow-context-alias"]}getOrCreateSourceFile(e){return ue(this.project,this.outputDir,e)}isIgnoreApiClientPathParameters(e,t){return(this.config.apiClients?.[e]?.ignorePathParameters??this.defaultIgnorePathParameters).includes(t)}isIgnoreCommandClientPathParameters(e,t){return this.defaultIgnorePathParameters.includes(t)}}const xe="./fetcher-generator.config.json";class At{constructor(e){this.options=e,this.project=new P.Project(e),this.options.logger.info(`Project instance created with tsConfigFilePath: ${this.options.tsConfigFilePath}`)}project;async generate(){this.options.logger.info("Starting code generation from OpenAPI specification");const e=process.cwd();this.options.logger.info(`Work directory: ${e}`),this.options.logger.info(`Input path: ${this.options.inputPath}`),this.options.logger.info(`Output directory: ${this.options.outputDir}`),this.options.logger.info("Parsing OpenAPI specification");const t=await _e(this.options.inputPath);this.options.logger.info("OpenAPI specification parsed successfully"),this.options.logger.info("Resolving bounded context aggregates");const r=new et(t).resolve();this.options.logger.info(`Resolved ${r.size} bounded context aggregates`);const i=this.options.configPath??xe;let s={};try{this.options.logger.info(`Parsing configuration file: ${i}`),s=await Ge(i)}catch(f){this.options.logger.info(`Configuration file parsing failed: ${f}`)}const a=new xt({openAPI:t,project:this.project,outputDir:this.options.outputDir,contextAggregates:r,logger:this.options.logger,config:s});this.options.logger.info("Generating models"),new ot(a).generate(),this.options.logger.info("Models generated successfully"),this.options.logger.info("Generating clients"),new yt(a).generate(),this.options.logger.info("Clients generated successfully");const g=this.project.getDirectory(this.options.outputDir);if(!g){this.options.logger.info("Output directory not found.");return}this.options.logger.info("Generating index files"),this.generateIndex(g),this.options.logger.info("Index files generated successfully"),this.options.logger.info("Optimizing source files"),this.optimizeSourceFiles(g),this.options.logger.info("Source files optimized successfully"),this.options.logger.info("Saving project to disk"),await this.project.save(),this.options.logger.info("Code generation completed successfully")}generateIndex(e){this.options.logger.info(`Generating index files for output directory: ${this.options.outputDir}`),this.processDirectory(e),this.generateIndexForDirectory(e),this.options.logger.info("Index file generation completed")}processDirectory(e){const t=e.getDirectories();this.options.logger.info(`Processing ${t.length} subdirectories`);for(const o of t)this.options.logger.info(`Processing subdirectory: ${o.getPath()}`),this.generateIndexForDirectory(o),this.processDirectory(o)}generateIndexForDirectory(e){const t=e.getPath();this.options.logger.info(`Generating index for directory: ${t}`);const o=e.getSourceFiles().filter(a=>a.getBaseName().endsWith(".ts")&&a.getBaseName()!=="index.ts"),r=e.getDirectories();if(this.options.logger.info(`Found ${o.length} TypeScript files and ${r.length} subdirectories in ${t}`),o.length===0&&r.length===0){this.options.logger.info(`No files or subdirectories to export in ${t}, skipping index generation`);return}const i=`${t}/index.ts`,s=this.project.getSourceFile(i)||this.project.createSourceFile(i,"",{overwrite:!0});s.removeText();for(const a of o){const c=`./${a.getBaseNameWithoutExtension()}`;s.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}for(const a of r){const c=`./${a.getBaseName()}`;s.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}this.options.logger.info(`Index file generated for ${t} with ${o.length+r.length} exports`)}optimizeSourceFiles(e){const t=e.getDescendantSourceFiles();this.options.logger.info(`Optimizing ${t.length} source files in ${e.getPath()}`),t.forEach((o,r)=>{this.options.logger.info(`Optimizing file [${o.getFilePath()}] - ${r+1}/${t.length}`),o.formatText(),o.organizeImports(),o.fixMissingImports()}),this.options.logger.info("All source files optimized")}}exports.CodeGenerator=At;exports.DEFAULT_CONFIG_PATH=xe;
21
21
  //# sourceMappingURL=index.cjs.map