@ahoo-wang/fetcher-generator 2.5.2 → 2.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/aggregate/aggregateResolver.d.ts.map +1 -1
  2. package/dist/aggregate/index.d.ts +1 -1
  3. package/dist/aggregate/utils.d.ts +1 -1
  4. package/dist/aggregate/utils.d.ts.map +1 -1
  5. package/dist/cli.cjs +1 -1
  6. package/dist/cli.cjs.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +25 -26
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client/apiClientGenerator.d.ts.map +1 -1
  11. package/dist/client/commandClientGenerator.d.ts +1 -1
  12. package/dist/client/commandClientGenerator.d.ts.map +1 -1
  13. package/dist/client/decorators.d.ts +5 -0
  14. package/dist/client/decorators.d.ts.map +1 -1
  15. package/dist/client/index.d.ts +1 -1
  16. package/dist/client/index.d.ts.map +1 -1
  17. package/dist/client/queryClientGenerator.d.ts +1 -1
  18. package/dist/client/queryClientGenerator.d.ts.map +1 -1
  19. package/dist/generateContext.d.ts +2 -2
  20. package/dist/generateContext.d.ts.map +1 -1
  21. package/dist/index.cjs +8 -8
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +740 -749
  25. package/dist/index.js.map +1 -1
  26. package/dist/model/modelGenerator.d.ts +1 -1
  27. package/dist/model/modelGenerator.d.ts.map +1 -1
  28. package/dist/model/modelInfo.d.ts +1 -1
  29. package/dist/model/modelInfo.d.ts.map +1 -1
  30. package/dist/types.d.ts +1 -2
  31. package/dist/types.d.ts.map +1 -1
  32. package/dist/utils/clis.d.ts +1 -0
  33. package/dist/utils/clis.d.ts.map +1 -1
  34. package/dist/utils/index.d.ts +1 -1
  35. package/dist/utils/index.d.ts.map +1 -1
  36. package/dist/utils/parsers.d.ts.map +1 -1
  37. package/dist/utils/responses.d.ts +1 -1
  38. package/dist/utils/responses.d.ts.map +1 -1
  39. package/dist/utils/sourceFiles.d.ts.map +1 -1
  40. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"aggregateResolver.d.ts","sourceRoot":"","sources":["../../src/aggregate/aggregateResolver.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,OAAO,EACP,SAAS,EAKV,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,wBAAwB,EAGzB,MAAM,aAAa,CAAC;AAIrB,OAAO,EASL,eAAe,EAChB,MAAM,UAAU,CAAC;AAMlB;;;GAGG;AACH,qBAAa,iBAAiB;IAUhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAGzB;IAEF;;;OAGG;gBAC0B,OAAO,EAAE,OAAO;IAK7C;;;OAGG;IACH,OAAO,CAAC,KAAK;IAYb;;;OAGG;IACH,OAAO,IAAI,wBAAwB;IAoBnC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe;IAoEvD;;;OAGG;IACH,KAAK,CAAC,SAAS,EAAE,SAAS;IAqB1B;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,SAAS;IAkD3B;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;CA4BnC"}
1
+ {"version":3,"file":"aggregateResolver.d.ts","sourceRoot":"","sources":["../../src/aggregate/aggregateResolver.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,OAAO,EACP,SAAS,EAKV,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,wBAAwB,EAGzB,MAAM,aAAa,CAAC;AAGrB,OAAO,EASL,eAAe,EAChB,MAAM,UAAU,CAAC;AAOlB;;;GAGG;AACH,qBAAa,iBAAiB;IAUhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAGzB;IAEF;;;OAGG;gBAC0B,OAAO,EAAE,OAAO;IAK7C;;;OAGG;IACH,OAAO,CAAC,KAAK;IAYb;;;OAGG;IACH,OAAO,IAAI,wBAAwB;IAoBnC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe;IAoEvD;;;OAGG;IACH,KAAK,CAAC,SAAS,EAAE,SAAS;IAqB1B;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,SAAS;IAkD3B;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;CA4BnC"}
@@ -1,5 +1,5 @@
1
1
  export * from './aggregate';
2
2
  export * from './aggregateResolver';
3
- export * from './utils';
4
3
  export * from './types';
4
+ export * from './utils';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
- import { Tag } from '@ahoo-wang/fetcher-openapi';
2
1
  import { PartialBy } from '@ahoo-wang/fetcher';
2
+ import { Tag } from '@ahoo-wang/fetcher-openapi';
3
3
  import { AggregateDefinition, TagAliasAggregate } from './aggregate';
4
4
  /**
5
5
  * Checks if a tag name follows the alias aggregate pattern and extracts its components.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/aggregate/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAMzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,iBAAiB,GAAG,IAAI,CAWjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,CAAC,EAAE,GAAG,EAAE,GACX,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,mBAAmB,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC,CAmBjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS5E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/aggregate/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAMzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,iBAAiB,GAAG,IAAI,CAWjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,CAAC,EAAE,GAAG,EAAE,GACX,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,mBAAmB,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC,CAmBjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS5E"}
package/dist/cli.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("commander"),l=require("./index.cjs"),d=require("ts-morph");require("yaml");require("fs");require("@ahoo-wang/fetcher");require("path");class f{getTimestamp(){return new Date().toISOString().slice(11,19)}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 n=this.getTimestamp(),i=" ".repeat(t);o.length>0?console.log(`[${n}] 🔄 ${i}${e}`,...o):console.log(`[${n}] 🔄 ${i}${e}`)}progressWithCount(e,t,o,n=0,...i){const s=this.getTimestamp(),p=" ".repeat(n),a=`[${e}/${t}]`;i.length>0?console.log(`[${s}] 🔄 ${p}${a} ${o}`,...i):console.log(`[${s}] 🔄 ${p}${a} ${o}`)}}function h(r){if(!r)return!1;try{const e=new URL(r);return e.protocol==="http:"||e.protocol==="https:"}catch{return r.length>0}}async function $(r){const e=new f;process.on("SIGINT",()=>{e.error("Generation interrupted by user"),process.exit(130)}),h(r.input)||(e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"),process.exit(2));try{e.info("Starting code generation...");const t=new d.Project,o={inputPath:r.input,outputDir:r.output,configPath:r.config,project:t,logger:e};await new l.CodeGenerator(o).generate(),e.success(`Code generation completed successfully! Files generated in: ${r.output}`)}catch(t){e.error(`Error during code generation: ${t}`),process.exit(1)}}const m="2.5.2",T={version:m};function u(){return c.program.name("fetcher-generator").description("OpenAPI Specification TypeScript code generator for Wow").version(T.version),c.program.command("generate").description("Generate TypeScript code from OpenAPI specification").requiredOption("-i, --input <path>","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("-v, --verbose","Enable verbose logging").option("--dry-run","Show what would be generated without writing files").action($),c.program}function g(){u().parse()}g();exports.runCLI=g;exports.setupCLI=u;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("commander"),a=require("./index.cjs");require("@ahoo-wang/fetcher");require("yaml");require("fs");require("path");class f{getTimestamp(){return new Date().toISOString().slice(11,19)}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 s=this.getTimestamp(),p=" ".repeat(i),l=`[${e}/${t}]`;r.length>0?console.log(`[${s}] 🔄 ${p}${l} ${o}`,...r):console.log(`[${s}] 🔄 ${p}${l} ${o}`)}}function h(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 d(n){const e=new f;process.on("SIGINT",()=>{e.error("Generation interrupted by user"),process.exit(130)}),h(n.input)||(e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"),process.exit(2));try{e.info("Starting code generation...");const t={inputPath:n.input,outputDir:n.output,configPath:n.config,tsConfigFilePath:n.tsConfigFilePath,logger:e};await new a.CodeGenerator(t).generate(),e.success(`Code generation completed successfully! Files generated in: ${n.output}`)}catch(t){e.error(`Error during code generation: ${t}`),process.exit(1)}}const $="2.5.5",m={version:$};function u(){return c.program.name("fetcher-generator").description("OpenAPI Specification TypeScript code generator for Wow").version(m.version),c.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",a.DEFAULT_CONFIG_PATH).option("-t, --ts-config-file-path <file>","TypeScript configuration file path").option("-v, --verbose","Enable verbose logging").option("--dry-run","Show what would be generated without writing files").action(d),c.program}function g(){u().parse()}g();exports.runCLI=g;exports.setupCLI=u;
3
3
  //# sourceMappingURL=cli.cjs.map
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.cjs","sources":["../src/utils/logger.ts","../src/utils/clis.ts","../src/cli.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '../types';\n\n/**\n * Default console-based logger implementation.\n * Provides friendly colored output for different log levels.\n */\nexport class ConsoleLogger implements Logger {\n private getTimestamp(): string {\n return new Date().toISOString().slice(11, 19); // HH:MM:SS format\n }\n\n info(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ℹ️ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ℹ️ ${message}`);\n }\n }\n\n success(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ✅ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ✅ ${message}`);\n }\n }\n\n error(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.error(`[${timestamp}] ❌ ${message}`, ...params);\n } else {\n console.error(`[${timestamp}] ❌ ${message}`);\n }\n }\n\n progress(message: string, level = 0, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n if (params.length > 0) {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`, ...params);\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`);\n }\n }\n\n progressWithCount(\n current: number,\n total: number,\n message: string,\n level = 0,\n ...params: any[]\n ): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n const countStr = `[${current}/${total}]`;\n if (params.length > 0) {\n console.log(\n `[${timestamp}] 🔄 ${indent}${countStr} ${message}`,\n ...params,\n );\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${countStr} ${message}`);\n }\n }\n}\n\n/**\n * Silent logger that suppresses all output.\n */\nexport class SilentLogger implements Logger {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n info(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n success(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n error(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n progress(_message: string, ...params: any[]): void {\n }\n\n /* eslint-disable @typescript-eslint/no-unused-vars */\n progressWithCount(\n _current: number,\n _total: number,\n _message: string,\n _level = 0,\n ..._params: any[]\n ): void {\n }\n\n /* eslint-enable @typescript-eslint/no-unused-vars */\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ConsoleLogger } from './logger';\nimport { GeneratorOptions } from '../types';\nimport { CodeGenerator } from '../index';\nimport { Project } from 'ts-morph';\n\n/**\n * Validates the input path or URL.\n * @param input - Input path or URL\n * @returns true if valid\n */\nexport function validateInput(input: string): boolean {\n if (!input) return false;\n\n // Check if it's a URL\n try {\n const url = new URL(input);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n // Not a URL, check if it's a file path\n // For file paths, we'll let parseOpenAPI handle it\n return input.length > 0;\n }\n}\n\n/**\n * Action handler for the generate command.\n * @param options - Command options\n */\nexport async function generateAction(options: {\n input: string;\n output: string;\n config?: string,\n verbose?: boolean;\n dryRun?: boolean;\n}) {\n const logger = new ConsoleLogger();\n\n // Handle signals\n process.on('SIGINT', () => {\n logger.error('Generation interrupted by user');\n process.exit(130);\n });\n\n // Validate input\n if (!validateInput(options.input)) {\n logger.error('Invalid input: must be a valid file path or HTTP/HTTPS URL');\n process.exit(2);\n }\n\n try {\n logger.info('Starting code generation...');\n const project = new Project();\n const generatorOptions: GeneratorOptions = {\n inputPath: options.input,\n outputDir: options.output,\n configPath: options.config,\n project,\n logger,\n };\n const codeGenerator = new CodeGenerator(generatorOptions);\n await codeGenerator.generate();\n logger.success(\n `Code generation completed successfully! Files generated in: ${options.output}`,\n );\n } catch (error) {\n logger.error(`Error during code generation: ${error}`);\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n\n/**\n * CLI entry point for the Fetcher OpenAPI code generator.\n * Sets up the commander program with generate command and handles execution.\n */\n\nimport { program } from 'commander';\nimport { generateAction } from './utils';\nimport packageJson from '../package.json';\nimport { DEFAULT_CONFIG_PATH } from './index';\n\n/**\n * Sets up the CLI program with all commands and options.\n * @returns The configured commander program instance\n */\nexport function setupCLI() {\n program\n .name('fetcher-generator')\n .description('OpenAPI Specification TypeScript code generator for Wow')\n .version(packageJson.version);\n\n program\n .command('generate')\n .description('Generate TypeScript code from OpenAPI specification')\n .requiredOption(\n '-i, --input <path>',\n 'Input OpenAPI specification file path or URL (http/https)',\n )\n .option('-o, --output <path>', 'Output directory path', 'src/generated')\n .option('-c, --config <file>', 'Configuration file path', DEFAULT_CONFIG_PATH)\n .option('-v, --verbose', 'Enable verbose logging')\n .option('--dry-run', 'Show what would be generated without writing files')\n .action(generateAction);\n\n return program;\n}\n\n/**\n * Runs the CLI program by parsing command line arguments.\n * Only executes when this file is run directly (not imported).\n */\nexport function runCLI() {\n setupCLI().parse();\n}\n\nrunCLI();\n"],"names":["ConsoleLogger","message","params","timestamp","level","indent","current","total","countStr","validateInput","input","url","generateAction","options","logger","project","Project","generatorOptions","CodeGenerator","error","setupCLI","program","packageJson","DEFAULT_CONFIG_PATH","runCLI"],"mappings":"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"}
1
+ {"version":3,"file":"cli.cjs","sources":["../src/utils/logger.ts","../src/utils/clis.ts","../src/cli.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '../types';\n\n/**\n * Default console-based logger implementation.\n * Provides friendly colored output for different log levels.\n */\nexport class ConsoleLogger implements Logger {\n private getTimestamp(): string {\n return new Date().toISOString().slice(11, 19); // HH:MM:SS format\n }\n\n info(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ℹ️ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ℹ️ ${message}`);\n }\n }\n\n success(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ✅ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ✅ ${message}`);\n }\n }\n\n error(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.error(`[${timestamp}] ❌ ${message}`, ...params);\n } else {\n console.error(`[${timestamp}] ❌ ${message}`);\n }\n }\n\n progress(message: string, level = 0, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n if (params.length > 0) {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`, ...params);\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`);\n }\n }\n\n progressWithCount(\n current: number,\n total: number,\n message: string,\n level = 0,\n ...params: any[]\n ): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n const countStr = `[${current}/${total}]`;\n if (params.length > 0) {\n console.log(\n `[${timestamp}] 🔄 ${indent}${countStr} ${message}`,\n ...params,\n );\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${countStr} ${message}`);\n }\n }\n}\n\n/**\n * Silent logger that suppresses all output.\n */\nexport class SilentLogger implements Logger {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n info(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n success(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n error(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n progress(_message: string, ...params: any[]): void {\n }\n\n /* eslint-disable @typescript-eslint/no-unused-vars */\n progressWithCount(\n _current: number,\n _total: number,\n _message: string,\n _level = 0,\n ..._params: any[]\n ): void {\n }\n\n /* eslint-enable @typescript-eslint/no-unused-vars */\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CodeGenerator } from '../index';\nimport { GeneratorOptions } from '../types';\nimport { ConsoleLogger } from './logger';\n\n/**\n * Validates the input path or URL.\n * @param input - Input path or URL\n * @returns true if valid\n */\nexport function validateInput(input: string): boolean {\n if (!input) return false;\n\n // Check if it's a URL\n try {\n const url = new URL(input);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n // Not a URL, check if it's a file path\n // For file paths, we'll let parseOpenAPI handle it\n return input.length > 0;\n }\n}\n\n/**\n * Action handler for the generate command.\n * @param options - Command options\n */\nexport async function generateAction(options: {\n input: string;\n output: string;\n config?: string;\n tsConfigFilePath?: string;\n verbose?: boolean;\n dryRun?: boolean;\n}) {\n const logger = new ConsoleLogger();\n\n // Handle signals\n process.on('SIGINT', () => {\n logger.error('Generation interrupted by user');\n process.exit(130);\n });\n\n // Validate input\n if (!validateInput(options.input)) {\n logger.error('Invalid input: must be a valid file path or HTTP/HTTPS URL');\n process.exit(2);\n }\n\n try {\n logger.info('Starting code generation...');\n const generatorOptions: GeneratorOptions = {\n inputPath: options.input,\n outputDir: options.output,\n configPath: options.config,\n tsConfigFilePath: options.tsConfigFilePath,\n logger,\n };\n const codeGenerator = new CodeGenerator(generatorOptions);\n await codeGenerator.generate();\n logger.success(\n `Code generation completed successfully! Files generated in: ${options.output}`,\n );\n } catch (error) {\n logger.error(`Error during code generation: ${error}`);\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n\n/**\n * CLI entry point for the Fetcher OpenAPI code generator.\n * Sets up the commander program with generate command and handles execution.\n */\n\nimport { program } from 'commander';\nimport packageJson from '../package.json';\nimport { DEFAULT_CONFIG_PATH } from './index';\nimport { generateAction } from './utils';\n\n/**\n * Sets up the CLI program with all commands and options.\n * @returns The configured commander program instance\n */\nexport function setupCLI() {\n program\n .name('fetcher-generator')\n .description('OpenAPI Specification TypeScript code generator for Wow')\n .version(packageJson.version);\n\n program\n .command('generate')\n .description('Generate TypeScript code from OpenAPI specification')\n .requiredOption(\n '-i, --input <file>',\n 'Input OpenAPI specification file path or URL (http/https)',\n )\n .option('-o, --output <path>', 'Output directory path', 'src/generated')\n .option('-c, --config <file>', 'Configuration file path', DEFAULT_CONFIG_PATH)\n .option('-t, --ts-config-file-path <file>', 'TypeScript configuration file path')\n .option('-v, --verbose', 'Enable verbose logging')\n .option('--dry-run', 'Show what would be generated without writing files')\n .action(generateAction);\n\n return program;\n}\n\n/**\n * Runs the CLI program by parsing command line arguments.\n * Only executes when this file is run directly (not imported).\n */\nexport function runCLI() {\n setupCLI().parse();\n}\n\nrunCLI();\n"],"names":["ConsoleLogger","message","params","timestamp","level","indent","current","total","countStr","validateInput","input","url","generateAction","options","logger","generatorOptions","CodeGenerator","error","setupCLI","program","packageJson","DEFAULT_CONFIG_PATH","runCLI"],"mappings":"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"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAOH;;;GAGG;AACH,wBAAgB,QAAQ,gCAoBvB;AAED;;;GAGG;AACH,wBAAgB,MAAM,SAErB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAOH;;;GAGG;AACH,wBAAgB,QAAQ,gCAqBvB;AAED;;;GAGG;AACH,wBAAgB,MAAM,SAErB"}
package/dist/cli.js CHANGED
@@ -1,12 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { program as c } from "commander";
3
3
  import { CodeGenerator as a, DEFAULT_CONFIG_PATH as g } from "./index.js";
4
- import { Project as u } from "ts-morph";
4
+ import "@ahoo-wang/fetcher";
5
5
  import "yaml";
6
6
  import "fs";
7
- import "@ahoo-wang/fetcher";
8
7
  import "path";
9
- class f {
8
+ class u {
10
9
  getTimestamp() {
11
10
  return (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
12
11
  }
@@ -23,18 +22,18 @@ class f {
23
22
  t.length > 0 ? console.error(`[${o}] ❌ ${e}`, ...t) : console.error(`[${o}] ❌ ${e}`);
24
23
  }
25
24
  progress(e, t = 0, ...o) {
26
- const r = this.getTimestamp(), i = " ".repeat(t);
27
- o.length > 0 ? console.log(`[${r}] 🔄 ${i}${e}`, ...o) : console.log(`[${r}] 🔄 ${i}${e}`);
25
+ const i = this.getTimestamp(), r = " ".repeat(t);
26
+ o.length > 0 ? console.log(`[${i}] 🔄 ${r}${e}`, ...o) : console.log(`[${i}] 🔄 ${r}${e}`);
28
27
  }
29
- progressWithCount(e, t, o, r = 0, ...i) {
30
- const s = this.getTimestamp(), p = " ".repeat(r), l = `[${e}/${t}]`;
31
- i.length > 0 ? console.log(
28
+ progressWithCount(e, t, o, i = 0, ...r) {
29
+ const s = this.getTimestamp(), p = " ".repeat(i), l = `[${e}/${t}]`;
30
+ r.length > 0 ? console.log(
32
31
  `[${s}] 🔄 ${p}${l} ${o}`,
33
- ...i
32
+ ...r
34
33
  ) : console.log(`[${s}] 🔄 ${p}${l} ${o}`);
35
34
  }
36
35
  }
37
- function h(n) {
36
+ function f(n) {
38
37
  if (!n) return !1;
39
38
  try {
40
39
  const e = new URL(n);
@@ -43,42 +42,42 @@ function h(n) {
43
42
  return n.length > 0;
44
43
  }
45
44
  }
46
- async function $(n) {
47
- const e = new f();
45
+ async function h(n) {
46
+ const e = new u();
48
47
  process.on("SIGINT", () => {
49
48
  e.error("Generation interrupted by user"), process.exit(130);
50
- }), h(n.input) || (e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"), process.exit(2));
49
+ }), f(n.input) || (e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"), process.exit(2));
51
50
  try {
52
51
  e.info("Starting code generation...");
53
- const t = new u(), o = {
52
+ const t = {
54
53
  inputPath: n.input,
55
54
  outputDir: n.output,
56
55
  configPath: n.config,
57
- project: t,
56
+ tsConfigFilePath: n.tsConfigFilePath,
58
57
  logger: e
59
58
  };
60
- await new a(o).generate(), e.success(
59
+ await new a(t).generate(), e.success(
61
60
  `Code generation completed successfully! Files generated in: ${n.output}`
62
61
  );
63
62
  } catch (t) {
64
63
  e.error(`Error during code generation: ${t}`), process.exit(1);
65
64
  }
66
65
  }
67
- const m = "2.5.2", d = {
68
- version: m
66
+ const $ = "2.5.5", d = {
67
+ version: $
69
68
  };
70
- function T() {
69
+ function m() {
71
70
  return c.name("fetcher-generator").description("OpenAPI Specification TypeScript code generator for Wow").version(d.version), c.command("generate").description("Generate TypeScript code from OpenAPI specification").requiredOption(
72
- "-i, --input <path>",
71
+ "-i, --input <file>",
73
72
  "Input OpenAPI specification file path or URL (http/https)"
74
- ).option("-o, --output <path>", "Output directory path", "src/generated").option("-c, --config <file>", "Configuration file path", g).option("-v, --verbose", "Enable verbose logging").option("--dry-run", "Show what would be generated without writing files").action($), c;
73
+ ).option("-o, --output <path>", "Output directory path", "src/generated").option("-c, --config <file>", "Configuration file path", g).option("-t, --ts-config-file-path <file>", "TypeScript configuration file path").option("-v, --verbose", "Enable verbose logging").option("--dry-run", "Show what would be generated without writing files").action(h), c;
75
74
  }
76
- function w() {
77
- T().parse();
75
+ function T() {
76
+ m().parse();
78
77
  }
79
- w();
78
+ T();
80
79
  export {
81
- w as runCLI,
82
- T as setupCLI
80
+ T as runCLI,
81
+ m as setupCLI
83
82
  };
84
83
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/utils/logger.ts","../src/utils/clis.ts","../src/cli.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '../types';\n\n/**\n * Default console-based logger implementation.\n * Provides friendly colored output for different log levels.\n */\nexport class ConsoleLogger implements Logger {\n private getTimestamp(): string {\n return new Date().toISOString().slice(11, 19); // HH:MM:SS format\n }\n\n info(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ℹ️ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ℹ️ ${message}`);\n }\n }\n\n success(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ✅ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ✅ ${message}`);\n }\n }\n\n error(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.error(`[${timestamp}] ❌ ${message}`, ...params);\n } else {\n console.error(`[${timestamp}] ❌ ${message}`);\n }\n }\n\n progress(message: string, level = 0, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n if (params.length > 0) {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`, ...params);\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`);\n }\n }\n\n progressWithCount(\n current: number,\n total: number,\n message: string,\n level = 0,\n ...params: any[]\n ): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n const countStr = `[${current}/${total}]`;\n if (params.length > 0) {\n console.log(\n `[${timestamp}] 🔄 ${indent}${countStr} ${message}`,\n ...params,\n );\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${countStr} ${message}`);\n }\n }\n}\n\n/**\n * Silent logger that suppresses all output.\n */\nexport class SilentLogger implements Logger {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n info(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n success(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n error(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n progress(_message: string, ...params: any[]): void {\n }\n\n /* eslint-disable @typescript-eslint/no-unused-vars */\n progressWithCount(\n _current: number,\n _total: number,\n _message: string,\n _level = 0,\n ..._params: any[]\n ): void {\n }\n\n /* eslint-enable @typescript-eslint/no-unused-vars */\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ConsoleLogger } from './logger';\nimport { GeneratorOptions } from '../types';\nimport { CodeGenerator } from '../index';\nimport { Project } from 'ts-morph';\n\n/**\n * Validates the input path or URL.\n * @param input - Input path or URL\n * @returns true if valid\n */\nexport function validateInput(input: string): boolean {\n if (!input) return false;\n\n // Check if it's a URL\n try {\n const url = new URL(input);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n // Not a URL, check if it's a file path\n // For file paths, we'll let parseOpenAPI handle it\n return input.length > 0;\n }\n}\n\n/**\n * Action handler for the generate command.\n * @param options - Command options\n */\nexport async function generateAction(options: {\n input: string;\n output: string;\n config?: string,\n verbose?: boolean;\n dryRun?: boolean;\n}) {\n const logger = new ConsoleLogger();\n\n // Handle signals\n process.on('SIGINT', () => {\n logger.error('Generation interrupted by user');\n process.exit(130);\n });\n\n // Validate input\n if (!validateInput(options.input)) {\n logger.error('Invalid input: must be a valid file path or HTTP/HTTPS URL');\n process.exit(2);\n }\n\n try {\n logger.info('Starting code generation...');\n const project = new Project();\n const generatorOptions: GeneratorOptions = {\n inputPath: options.input,\n outputDir: options.output,\n configPath: options.config,\n project,\n logger,\n };\n const codeGenerator = new CodeGenerator(generatorOptions);\n await codeGenerator.generate();\n logger.success(\n `Code generation completed successfully! Files generated in: ${options.output}`,\n );\n } catch (error) {\n logger.error(`Error during code generation: ${error}`);\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n\n/**\n * CLI entry point for the Fetcher OpenAPI code generator.\n * Sets up the commander program with generate command and handles execution.\n */\n\nimport { program } from 'commander';\nimport { generateAction } from './utils';\nimport packageJson from '../package.json';\nimport { DEFAULT_CONFIG_PATH } from './index';\n\n/**\n * Sets up the CLI program with all commands and options.\n * @returns The configured commander program instance\n */\nexport function setupCLI() {\n program\n .name('fetcher-generator')\n .description('OpenAPI Specification TypeScript code generator for Wow')\n .version(packageJson.version);\n\n program\n .command('generate')\n .description('Generate TypeScript code from OpenAPI specification')\n .requiredOption(\n '-i, --input <path>',\n 'Input OpenAPI specification file path or URL (http/https)',\n )\n .option('-o, --output <path>', 'Output directory path', 'src/generated')\n .option('-c, --config <file>', 'Configuration file path', DEFAULT_CONFIG_PATH)\n .option('-v, --verbose', 'Enable verbose logging')\n .option('--dry-run', 'Show what would be generated without writing files')\n .action(generateAction);\n\n return program;\n}\n\n/**\n * Runs the CLI program by parsing command line arguments.\n * Only executes when this file is run directly (not imported).\n */\nexport function runCLI() {\n setupCLI().parse();\n}\n\nrunCLI();\n"],"names":["ConsoleLogger","message","params","timestamp","level","indent","current","total","countStr","validateInput","input","url","generateAction","options","logger","project","Project","generatorOptions","CodeGenerator","error","setupCLI","program","packageJson","DEFAULT_CONFIG_PATH","runCLI"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sources":["../src/utils/logger.ts","../src/utils/clis.ts","../src/cli.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '../types';\n\n/**\n * Default console-based logger implementation.\n * Provides friendly colored output for different log levels.\n */\nexport class ConsoleLogger implements Logger {\n private getTimestamp(): string {\n return new Date().toISOString().slice(11, 19); // HH:MM:SS format\n }\n\n info(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ℹ️ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ℹ️ ${message}`);\n }\n }\n\n success(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.log(`[${timestamp}] ✅ ${message}`, ...params);\n } else {\n console.log(`[${timestamp}] ✅ ${message}`);\n }\n }\n\n error(message: string, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n if (params.length > 0) {\n console.error(`[${timestamp}] ❌ ${message}`, ...params);\n } else {\n console.error(`[${timestamp}] ❌ ${message}`);\n }\n }\n\n progress(message: string, level = 0, ...params: any[]): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n if (params.length > 0) {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`, ...params);\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${message}`);\n }\n }\n\n progressWithCount(\n current: number,\n total: number,\n message: string,\n level = 0,\n ...params: any[]\n ): void {\n const timestamp = this.getTimestamp();\n const indent = ' '.repeat(level);\n const countStr = `[${current}/${total}]`;\n if (params.length > 0) {\n console.log(\n `[${timestamp}] 🔄 ${indent}${countStr} ${message}`,\n ...params,\n );\n } else {\n console.log(`[${timestamp}] 🔄 ${indent}${countStr} ${message}`);\n }\n }\n}\n\n/**\n * Silent logger that suppresses all output.\n */\nexport class SilentLogger implements Logger {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n info(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n success(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n error(_message: string, ...params: any[]): void {\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n progress(_message: string, ...params: any[]): void {\n }\n\n /* eslint-disable @typescript-eslint/no-unused-vars */\n progressWithCount(\n _current: number,\n _total: number,\n _message: string,\n _level = 0,\n ..._params: any[]\n ): void {\n }\n\n /* eslint-enable @typescript-eslint/no-unused-vars */\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CodeGenerator } from '../index';\nimport { GeneratorOptions } from '../types';\nimport { ConsoleLogger } from './logger';\n\n/**\n * Validates the input path or URL.\n * @param input - Input path or URL\n * @returns true if valid\n */\nexport function validateInput(input: string): boolean {\n if (!input) return false;\n\n // Check if it's a URL\n try {\n const url = new URL(input);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n // Not a URL, check if it's a file path\n // For file paths, we'll let parseOpenAPI handle it\n return input.length > 0;\n }\n}\n\n/**\n * Action handler for the generate command.\n * @param options - Command options\n */\nexport async function generateAction(options: {\n input: string;\n output: string;\n config?: string;\n tsConfigFilePath?: string;\n verbose?: boolean;\n dryRun?: boolean;\n}) {\n const logger = new ConsoleLogger();\n\n // Handle signals\n process.on('SIGINT', () => {\n logger.error('Generation interrupted by user');\n process.exit(130);\n });\n\n // Validate input\n if (!validateInput(options.input)) {\n logger.error('Invalid input: must be a valid file path or HTTP/HTTPS URL');\n process.exit(2);\n }\n\n try {\n logger.info('Starting code generation...');\n const generatorOptions: GeneratorOptions = {\n inputPath: options.input,\n outputDir: options.output,\n configPath: options.config,\n tsConfigFilePath: options.tsConfigFilePath,\n logger,\n };\n const codeGenerator = new CodeGenerator(generatorOptions);\n await codeGenerator.generate();\n logger.success(\n `Code generation completed successfully! Files generated in: ${options.output}`,\n );\n } catch (error) {\n logger.error(`Error during code generation: ${error}`);\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n\n/**\n * CLI entry point for the Fetcher OpenAPI code generator.\n * Sets up the commander program with generate command and handles execution.\n */\n\nimport { program } from 'commander';\nimport packageJson from '../package.json';\nimport { DEFAULT_CONFIG_PATH } from './index';\nimport { generateAction } from './utils';\n\n/**\n * Sets up the CLI program with all commands and options.\n * @returns The configured commander program instance\n */\nexport function setupCLI() {\n program\n .name('fetcher-generator')\n .description('OpenAPI Specification TypeScript code generator for Wow')\n .version(packageJson.version);\n\n program\n .command('generate')\n .description('Generate TypeScript code from OpenAPI specification')\n .requiredOption(\n '-i, --input <file>',\n 'Input OpenAPI specification file path or URL (http/https)',\n )\n .option('-o, --output <path>', 'Output directory path', 'src/generated')\n .option('-c, --config <file>', 'Configuration file path', DEFAULT_CONFIG_PATH)\n .option('-t, --ts-config-file-path <file>', 'TypeScript configuration file path')\n .option('-v, --verbose', 'Enable verbose logging')\n .option('--dry-run', 'Show what would be generated without writing files')\n .action(generateAction);\n\n return program;\n}\n\n/**\n * Runs the CLI program by parsing command line arguments.\n * Only executes when this file is run directly (not imported).\n */\nexport function runCLI() {\n setupCLI().parse();\n}\n\nrunCLI();\n"],"names":["ConsoleLogger","message","params","timestamp","level","indent","current","total","countStr","validateInput","input","url","generateAction","options","logger","generatorOptions","CodeGenerator","error","setupCLI","program","packageJson","DEFAULT_CONFIG_PATH","runCLI"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"apiClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/apiClientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAoDhE;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,SAAS;aAUtB,OAAO,EAAE,eAAe;IATpD,OAAO,CAAC,2BAA2B,CAAsB;IACzD,OAAO,CAAC,iBAAiB,CAA4B;IAErD,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAqB;IAEhE;;;OAGG;gBACyB,OAAO,EAAE,eAAe;IAMpD;;;OAGG;IACH,QAAQ;IAgBR;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAuD1B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA6DzB;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAgC/B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAqEzB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IA8CxB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA4CvB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,cAAc;CAUvB"}
1
+ {"version":3,"file":"apiClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/apiClientGenerator.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAyChE;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,SAAS;aAUtB,OAAO,EAAE,eAAe;IATpD,OAAO,CAAC,2BAA2B,CAAsB;IACzD,OAAO,CAAC,iBAAiB,CAAuB;IAEhD,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAqB;IAEhE;;;OAGG;gBACyB,OAAO,EAAE,eAAe;IAMpD;;;OAGG;IACH,QAAQ;IAgBR;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAuD1B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA6DzB;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAiC/B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAyDzB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IA8CxB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA4CvB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,cAAc;CAUvB"}
@@ -1,6 +1,6 @@
1
- import { GenerateContext, Generator } from '../generateContext';
2
1
  import { ClassDeclaration, SourceFile } from 'ts-morph';
3
2
  import { AggregateDefinition, CommandDefinition } from '../aggregate';
3
+ import { GenerateContext, Generator } from '../generateContext';
4
4
  /**
5
5
  * Generates TypeScript command client classes for aggregates.
6
6
  * Creates command clients that can send commands to aggregates.
@@ -1 +1 @@
1
- {"version":3,"file":"commandClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/commandClientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,gBAAgB,EAChB,UAAU,EAEX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAiBtE;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,SAAS;aAS1B,OAAO,EAAE,eAAe;IARpD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA4B;IACrE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CACb;IAEnC;;;OAGG;gBACyB,OAAO,EAAE,eAAe;IAGpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAwBhB;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,mBAAmB;IA6E/C,2BAA2B,CACzB,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB;IAsB1C,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM;IAInD,oBAAoB,CAClB,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB,EACxC,QAAQ,GAAE,OAAe;IAyB3B,OAAO,CAAC,iBAAiB;IAiEzB,oBAAoB,CAClB,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,iBAAiB,EAC7B,UAAU,EAAE,MAAM;CAmCrB"}
1
+ {"version":3,"file":"commandClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/commandClientGenerator.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,gBAAgB,EAChB,UAAU,EAEX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAgBhE;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,SAAS;aAS1B,OAAO,EAAE,eAAe;IARpD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA4B;IACrE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CACb;IAEnC;;;OAGG;gBACyB,OAAO,EAAE,eAAe;IAGpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAwBhB;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,mBAAmB;IA6E/C,2BAA2B,CACzB,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB;IAsB1C,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM;IAInD,oBAAoB,CAClB,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB,EACxC,QAAQ,GAAE,OAAe;IAyB3B,OAAO,CAAC,iBAAiB;IAiEzB,oBAAoB,CAClB,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,iBAAiB,EAC7B,UAAU,EAAE,MAAM;CAmCrB"}
@@ -7,6 +7,11 @@ export declare const DECORATOR_MODULE_SPECIFIER = "@ahoo-wang/fetcher-decorator"
7
7
  * Named imports from the fetcher-decorator package.
8
8
  */
9
9
  export declare const DECORATOR_NAMED_IMPORTS: string[];
10
+ export interface MethodReturnType {
11
+ type: string;
12
+ metadata?: string;
13
+ }
14
+ export declare const DEFAULT_RETURN_TYPE: MethodReturnType;
10
15
  /**
11
16
  * Metadata configuration for stream result extraction.
12
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/client/decorators.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,gBAAgB,EAIhB,UAAU,EACX,MAAM,UAAU,CAAC;AAGlB;;GAEG;AACH,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAYnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gCAAgC,0HAG3C,CAAC;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,QAExD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,MAAM,EAAO,GACrB,gBAAgB,CAWlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,CAAC,EAAE,MAAM,QAerB"}
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/client/decorators.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,gBAAgB,EAIhB,UAAU,EACX,MAAM,UAAU,CAAC;AAGlB;;GAEG;AACH,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAYnC,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,EAAE,gBAGjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gCAAgC,0HAG3C,CAAC;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,QAExD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,MAAM,EAAO,GACrB,gBAAgB,CAWlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,CAAC,EAAE,MAAM,QAerB"}
@@ -1,5 +1,5 @@
1
- export * from './clientGenerator';
2
1
  export * from './apiClientGenerator';
2
+ export * from './clientGenerator';
3
3
  export * from './commandClientGenerator';
4
4
  export * from './decorators';
5
5
  export * from './queryClientGenerator';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAaA,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAaA,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,SAAS,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { SourceFile } from 'ts-morph';
2
- import { GenerateContext, Generator } from '../generateContext';
3
2
  import { AggregateDefinition, TagAliasAggregate } from '../aggregate';
3
+ import { GenerateContext, Generator } from '../generateContext';
4
4
  /**
5
5
  * Generates TypeScript query client classes for aggregates.
6
6
  * Creates query clients that can perform state queries and event streaming.
@@ -1 +1 @@
1
- {"version":3,"file":"queryClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/queryClientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAA2B,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAKtE;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,SAAS;aAKxB,OAAO,EAAE,eAAe;IAJpD;;;OAGG;gBACyB,OAAO,EAAE,eAAe;IAGpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAwBhB;;;;;OAKG;IACH,oBAAoB,CAClB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU;IASb;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,mBAAmB;CA6FlD"}
1
+ {"version":3,"file":"queryClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/queryClientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAA2B,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKhE;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,SAAS;aAKxB,OAAO,EAAE,eAAe;IAJpD;;;OAGG;gBACyB,OAAO,EAAE,eAAe;IAGpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAwBhB;;;;;OAKG;IACH,oBAAoB,CAClB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU;IASb;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,mBAAmB;CA6FlD"}
@@ -1,7 +1,7 @@
1
- import { Project, SourceFile } from 'ts-morph';
2
1
  import { OpenAPI } from '@ahoo-wang/fetcher-openapi';
3
- import { GenerateContextInit, GeneratorConfiguration, Logger } from './types';
2
+ import { Project, SourceFile } from 'ts-morph';
4
3
  import { BoundedContextAggregates } from './aggregate';
4
+ import { GenerateContextInit, GeneratorConfiguration, Logger } from './types';
5
5
  export declare class GenerateContext implements GenerateContextInit {
6
6
  /** The ts-morph project instance used for code generation */
7
7
  readonly project: Project;
@@ -1 +1 @@
1
- {"version":3,"file":"generateContext.d.ts","sourceRoot":"","sources":["../src/generateContext.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAGvD,qBAAa,eAAgB,YAAW,mBAAmB;IACzD,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;IACrD,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAA2B;IACvE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAErC,OAAO,EAAE,mBAAmB;IAUxC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAInD,+BAA+B,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;IAKhF,mCAAmC,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;CAGrF;AAED,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,QAAQ,IAAI,IAAI,CAAC;CAClB"}
1
+ {"version":3,"file":"generateContext.d.ts","sourceRoot":"","sources":["../src/generateContext.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAG9E,qBAAa,eAAgB,YAAW,mBAAmB;IACzD,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;IACrD,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAA2B;IACvE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAErC,OAAO,EAAE,mBAAmB;IAUxC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAInD,+BAA+B,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;IAKhF,mCAAmC,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;CAGrF;AAED,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,QAAQ,IAAI,IAAI,CAAC;CAClB"}
package/dist/index.cjs CHANGED
@@ -1,12 +1,12 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("@ahoo-wang/fetcher"),w=require("ts-morph"),M=require("@ahoo-wang/fetcher-wow"),B=require("yaml"),ce=require("fs"),j=require("path");function ge(r){const e=r.split(".");return e.length!=2||e[0].length===0||e[1].length===0?null:e}function le(r){const e=ge(r.name);return e?{tag:r,contextAlias:e[0],aggregateName:e[1]}:null}function pe(r){const e=r?.map(n=>le(n)).filter(n=>n!==null);if(!e)return new Map;const t=new Map;return e.forEach(n=>{t.set(n.tag.name,{aggregate:n,commands:new Map,events:new Map})}),t}function ue(r){if(!r)return null;const e=r.split(".");return e.length!=3?null:e[2]}function T(r){return r.$ref.split("/").pop()}function R(r,e){const t=T(r);return e.schemas?.[t]}function k(r,e){const t=T(r);return e.requestBodies?.[t]}function L(r,e){const t=T(r);return e.parameters?.[t]}function I(r,e){return{key:T(r),schema:R(r,e)}}const G=/[-_\s.]+/;function Q(r){return Array.isArray(r)?r.flatMap(e=>_(e.split(G))):_(r.split(G))}function _(r){return r.flatMap(e=>{if(e.length===0)return[];const t=[];let n="";for(let o=0;o<e.length;o++){const s=e[o],i=/[A-Z]/.test(s),a=o>0&&/[a-z]/.test(e[o-1]);i&&a&&n?(t.push(n),n=s):n+=s}return n&&t.push(n),t})}function C(r){return r===""||r.length===0?"":Q(r).filter(t=>t.length>0).map(t=>{const n=t.charAt(0),o=t.slice(1);return(/[a-zA-Z]/.test(n)?n.toUpperCase():n)+o.toLowerCase()}).join("")}function y(r){const e=C(r);return e.charAt(0).toLowerCase()+e.slice(1)}function de(r){return r===""||Array.isArray(r)&&r.length===0?"":Q(r).filter(t=>t.length>0).map(t=>t.toUpperCase()).join("_")}function U(r){return r.startsWith("http://")||r.startsWith("https://")?me(r):fe(r)}async function me(r){return await(await fetch(r)).text()}function fe(r){return new Promise((e,t)=>{ce.readFile(r,"utf-8",(n,o)=>{n?t(n):e(o)})})}async function he(r){const e=await U(r);switch(V(e)){case"json":return JSON.parse(e);case"yaml":return B.parse(e);default:throw new Error(`Unsupported file format: ${r}`)}}async function ye(r){const e=await U(r);switch(V(e)){case"json":return JSON.parse(e);case"yaml":return B.parse(e);default:throw new Error(`Unsupported file format: ${r}`)}}function V(r){const e=r.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")}function l(r){return!!(r&&typeof r=="object"&&"$ref"in r)}function N(r,e){if(e&&!l(e)&&e.content)return e.content[r]?.schema}function J(r){return N(h.ContentTypeValues.APPLICATION_JSON,r)}function xe(r){return N(h.ContentTypeValues.TEXT_EVENT_STREAM,r)}function Ae(r){return N("*/*",r)}const Ce=["string","number","integer","boolean","null"];function D(r){return Array.isArray(r)?!0:Ce.includes(r)}function v(r){return r.type==="array"}function Pe(r){return Array.isArray(r.enum)&&r.enum.length>0}function K(r){return Array.isArray(r.anyOf)&&r.anyOf.length>0}function H(r){return Array.isArray(r.oneOf)&&r.oneOf.length>0}function $e(r){return K(r)||H(r)}function Te(r){return Array.isArray(r.allOf)&&r.allOf.length>0}function F(r){return K(r)||H(r)||Te(r)}function W(r){return r.includes("|")||r.includes("&")?`(${r})[]`:`${r}[]`}function Ie(r){return r.type!=="object"?!1:r.properties?Object.keys(r.properties).length===0:!0}function P(r){if(Array.isArray(r))return r.map(e=>P(e)).join(" | ");switch(r){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"null":return"null";default:return"any"}}function Y(r){return[{method:"get",operation:r.get},{method:"put",operation:r.put},{method:"post",operation:r.post},{method:"delete",operation:r.delete},{method:"options",operation:r.options},{method:"head",operation:r.head},{method:"patch",operation:r.patch},{method:"trace",operation:r.trace}].filter(({operation:e})=>e!==void 0)}function b(r){return r.responses[200]}function z(r){const e=b(r);return J(e)}function Se(r,e){return r.parameters?r.parameters.map(t=>l(t)?L(t,e):t).filter(t=>t.in==="path"):[]}const we="string";function X(r){return!r.schema||l(r.schema)||!r.schema.type||!D(r.schema.type)?we:P(r.schema.type)}const Z="types.ts",Re="@";function Ee(r){return h.combineURLs(r.path,Z)}function ee(r,e,t){const n=h.combineURLs(e,t),o=r.getSourceFile(n);return o||r.createSourceFile(n,"",{overwrite:!0})}function E(r,e,t){let n=r.getImportDeclaration(o=>o.getModuleSpecifierValue()===e);n||(n=r.addImportDeclaration({moduleSpecifier:e})),t.forEach(o=>{n.getNamedImports().some(i=>i.getName()===o)||n.addNamedImport(o)})}function f(r,e,t){if(t.path.startsWith(Re)){E(r,t.path,[t.name]);return}const n=r.getDirectoryPath(),o=j.join(e,t.path,Z);let s=j.relative(n,o);s=s.replace(/\.ts$/,""),s.startsWith(".")||(s="./"+s),E(r,s,[t.name])}function S(r,e,t,n){r.path!==n.path&&f(e,t,n)}function ve(r,e){const t=[r,e].filter(n=>n!==void 0&&n.length>0);return t.length>0?t.join(`
2
- `):void 0}function A(r,e,t){const n=ve(e,t);n&&r.addJsDoc({description:n})}const Oe="#/components/responses/wow.CommandOk",Ne="#/components/parameters/wow.id";class De{constructor(e){this.openAPI=e,this.aggregates=pe(e.tags),this.build()}aggregates;build(){for(const[e,t]of Object.entries(this.openAPI.paths)){const n=Y(t);for(const o of n)this.commands(e,o),this.state(o.operation),this.events(o.operation),this.fields(o.operation)}}resolve(){const e=new Map;for(const t of this.aggregates.values()){if(!t.state||!t.fields)continue;const n=t.aggregate.contextAlias;let o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(t)}return e}commands(e,t){const n=t.operation;if(n.operationId==="wow.command.send")return;const o=ue(n.operationId);if(!o)return;const s=b(n);if(!s||!l(s)||s.$ref!==Oe||!n.requestBody)return;const i=n.parameters??[],a=i.filter(d=>l(d)&&d.$ref===Ne).at(0),c=i.filter(d=>!l(d)&&d.in==="path");if(a){const d=L(a,this.openAPI.components);c.push(d)}const u=n.requestBody.content[h.ContentTypeValues.APPLICATION_JSON].schema,p=I(u,this.openAPI.components);p.schema.title=p.schema.title||n.summary,p.schema.description=p.schema.description||n.description;const ae={name:o,method:t.method,path:e,pathParameters:c,summary:n.summary,description:n.description,schema:p,operation:n};n.tags?.forEach(d=>{const q=this.aggregates.get(d);q&&q.commands.set(o,ae)})}state(e){if(!e.operationId?.endsWith(".snapshot_state.single"))return;const t=z(e);if(!l(t))return;const n=I(t,this.openAPI.components);e.tags?.forEach(o=>{const s=this.aggregates.get(o);s&&(s.state=n)})}events(e){if(!this.openAPI.components||!e.operationId?.endsWith(".event.list_query"))return;const t=z(e);if(l(t))return;const n=t?.items;if(!l(n))return;const s=R(n,this.openAPI.components).properties.body.items.anyOf.map(i=>{const a=i.title,c=i.properties.name.const,g=i.properties.body,u=I(g,this.openAPI.components);return u.schema.title=u.schema.title||i.title,{title:a,name:c,schema:u}});e.tags?.forEach(i=>{const a=this.aggregates.get(i);a&&s.forEach(c=>{a.events.set(c.name,c)})})}fields(e){if(!this.openAPI.components||!e.operationId?.endsWith(".snapshot.count"))return;const n=k(e.requestBody,this.openAPI.components).content[h.ContentTypeValues.APPLICATION_JSON].schema,s=R(n,this.openAPI.components).properties?.field,i=I(s,this.openAPI.components);e.tags?.forEach(a=>{const c=this.aggregates.get(a);c&&(c.fields=i)})}}const $="@ahoo-wang/fetcher-wow",be={"wow.command.CommandResult":"CommandResult","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.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 m(r){if(!r)return{name:"",path:"/"};const e=be[r];if(e)return{name:e,path:$};const t=r.split(".");let n=-1;for(let c=0;c<t.length;c++)if(t[c]&&/^[A-Z]/.test(t[c])){n=c;break}if(n===-1)return{name:r,path:"/"};const o=t.slice(0,n),s=o.length>0?`/${o.join("/")}`:"/",i=t.slice(n);return{name:C(i),path:s}}function x(r){const e=T(r);return m(e)}class qe{constructor(e){this.context=e}getOrCreateSourceFile(e){const t=Ee(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(),n=this.filterSchemas(e,t);this.context.logger.progress(`Generating models for ${n.length} schemas`),n.forEach((o,s)=>{this.context.logger.progressWithCount(s+1,n.length,`Processing schema: ${o.key}`,2),this.generateKeyedSchema(o)}),this.context.logger.success("Model generation completed")}filterSchemas(e,t){return Object.entries(e).map(([n,o])=>({key:n,schema:o})).filter(n=>!this.isWowSchema(n.key,t))}isWowSchema(e,t){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 n=m(e);return t.has(n.name)}aggregatedSchemaSuffix=["MaterializedSnapshot","MaterializedSnapshotPagedList","MaterializedSnapshotServerSentEventNonNullData","PagedList","ServerSentEventNonNullData","Snapshot","StateEvent"];stateAggregatedTypeNames(){const e=new Set;for(const t of this.context.contextAggregates.values())for(const n of t)this.aggregatedSchemaSuffix.forEach(o=>{const s=m(n.state.key),i=C(s.name)+o;e.add(i)});return e}generateKeyedSchema({key:e,schema:t}){const n=m(e),o=this.getOrCreateSourceFile(n),s=this.process(n,o,t);s&&A(s,t.title,t.description)}process(e,t,n){if(Pe(n))return t.addEnum({name:e.name,isExported:!0,members:n.enum.filter(s=>typeof s=="string"&&s.length>0).map(s=>({name:de(s),initializer:`'${s}'`}))});if(v(n)&&l(n.items)){const s=x(n.items);return S(e,t,this.context.outputDir,s),t.addTypeAlias({name:e.name,type:W(s.name),isExported:!0})}const o=t.addInterface({name:e.name,isExported:!0});return n.type==="object"&&n.properties?this.processInterface(t,e,n,o):(F(n)&&(n.anyOf||n.oneOf||n.allOf).forEach(i=>{if(l(i)){const a=x(i);S(e,t,this.context.outputDir,a),o.addExtends(a.name);return}this.processInterface(t,e,i,o)}),o)}processObject(e,t,n){const o=e.addInterface({name:t.name,isExported:!0});return this.processInterface(e,t,n,o)}processInterface(e,t,n,o){for(const[s,i]of Object.entries(n.properties)){const a=this.resolvePropertyType(t,e,s,i);let c=o.getProperty(s);c?c.setType(a):c=o.addProperty({name:s,type:a}),l(i)||A(c,i.title,i.description)}return o}resolvePropertyType(e,t,n,o){if(l(o)){const s=x(o);return S(e,t,this.context.outputDir,s),s.name}if(o.const)return`'${o.const}'`;if(v(o)){const s=this.resolvePropertyType(e,t,n,o.items);return W(s)}if(o.type&&D(o.type))return P(o.type);if(F(o))return this.resolvePropertyCompositionType(e,t,o);if(o.type==="object"&&o.properties){const s={path:e.path,name:`${e.name}${C(n)}`},i=this.processObject(t,s,o);return A(i,o.title,o.description),s.name}return"any"}resolvePropertyCompositionType(e,t,n){const o=n.anyOf||n.oneOf||n.allOf,s=new Set;o.forEach(a=>{if(l(a)){const c=x(a);S(e,t,this.context.outputDir,c),s.add(c.name);return}s.add(P(a.type??"string"))});const i=$e(n)?"|":"&";return Array.from(s).join(i)}}function Me(r){let e=0,t=0;return r.commands.forEach(n=>{n.path.startsWith(M.ResourceAttributionPathSpec.TENANT)&&(e+=1),n.path.startsWith(M.ResourceAttributionPathSpec.OWNER)&&(t+=1)}),e===0&&t===0?"ResourceAttributionPathSpec.NONE":e>t?"ResourceAttributionPathSpec.TENANT":"ResourceAttributionPathSpec.OWNER"}function te(r,e,t,n){const o=`${t.contextAlias}/${t.aggregateName}/${n}.ts`;return ee(r,e,o)}function je(r,e){return`${C(r.aggregateName)}${e}`}function O(r){return r==="delete"?"del":r}class Ge{constructor(e){this.context=e}generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((n,o)=>n+o.size,0);this.context.logger.info("--- Generating Query Clients ---"),this.context.logger.progress(`Generating query clients for ${e} aggregates`);let t=0;for(const[,n]of this.context.contextAggregates)n.forEach(o=>{t++,this.context.logger.progressWithCount(t,e,`Processing query client for aggregate: ${o.aggregate.aggregateName}`),this.processQueryClient(o)});this.context.logger.success("Query client generation completed")}createClientFilePath(e,t){return te(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 ${$}: QueryClientFactory, QueryClientOptions, ResourceAttributionPathSpec`),t.addImportDeclaration({moduleSpecifier:$,namedImports:["QueryClientFactory","QueryClientOptions","ResourceAttributionPathSpec"]});const n="DEFAULT_QUERY_CLIENT_OPTIONS";this.context.logger.info(`Creating default query client options: ${n}`),t.addVariableStatement({declarationKind:w.VariableDeclarationKind.Const,declarations:[{name:n,type:"QueryClientOptions",initializer:`{
3
- contextAlias: '${e.aggregate.contextAlias}',
4
- aggregateName: '${e.aggregate.aggregateName}',
5
- resourceAttribution: ${Me(e)},
6
- }`}],isExported:!1});const o=[];this.context.logger.info(`Processing ${e.events.size} domain events for aggregate: ${e.aggregate.aggregateName}`);for(const u of e.events.values()){const p=m(u.schema.key);this.context.logger.info(`Adding import for event model: ${p.name} from path: ${p.path}`),f(t,this.context.outputDir,p),o.push(p)}const s="DOMAIN_EVENT_TYPES",i=o.map(u=>u.name).join(" | ");this.context.logger.info(`Creating domain event types union: ${s} = ${i}`),t.addTypeAlias({name:s,type:i});const a=`${y(e.aggregate.aggregateName)}QueryClientFactory`,c=m(e.state.key),g=m(e.fields.key);this.context.logger.info(`Adding import for state model: ${c.name} from path: ${c.path}`),f(t,this.context.outputDir,c),this.context.logger.info(`Adding import for fields model: ${g.name} from path: ${g.path}`),f(t,this.context.outputDir,g),this.context.logger.info(`Creating query client factory: ${a}`),t.addVariableStatement({declarationKind:w.VariableDeclarationKind.Const,declarations:[{name:a,initializer:`new QueryClientFactory<${c.name}, ${g.name} | string, ${s}>(${n})`}],isExported:!0}),this.context.logger.success(`Query client generation completed for aggregate: ${e.aggregate.aggregateName}`)}}const _e="@ahoo-wang/fetcher-decorator",Fe=["type ApiMetadata","type ApiMetadataCapable","api","post","put","patch","del","request","attribute","path","autoGeneratedError"],ne=`{
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("ts-morph"),h=require("@ahoo-wang/fetcher"),j=require("@ahoo-wang/fetcher-wow"),L=require("yaml"),ce=require("fs"),F=require("path");function I(r){return r.$ref.split("/").pop()}function E(r,e){const t=I(r);return e.schemas?.[t]}function k(r,e){const t=I(r);return e.requestBodies?.[t]}function U(r,e){const t=I(r);return e.parameters?.[t]}function S(r,e){return{key:I(r),schema:E(r,e)}}const G=/[-_\s.]+/;function Q(r){return Array.isArray(r)?r.flatMap(e=>_(e.split(G))):_(r.split(G))}function _(r){return r.flatMap(e=>{if(e.length===0)return[];const t=[];let n="";for(let o=0;o<e.length;o++){const s=e[o],i=/[A-Z]/.test(s),a=o>0&&/[a-z]/.test(e[o-1]);i&&a&&n?(t.push(n),n=s):n+=s}return n&&t.push(n),t})}function P(r){return r===""||r.length===0?"":Q(r).filter(t=>t.length>0).map(t=>{const n=t.charAt(0),o=t.slice(1);return(/[a-zA-Z]/.test(n)?n.toUpperCase():n)+o.toLowerCase()}).join("")}function y(r){const e=P(r);return e.charAt(0).toLowerCase()+e.slice(1)}function ge(r){return r===""||Array.isArray(r)&&r.length===0?"":Q(r).filter(t=>t.length>0).map(t=>t.toUpperCase()).join("_")}function g(r){return!!(r&&typeof r=="object"&&"$ref"in r)}function D(r,e){if(e&&!g(e)&&e.content)return e.content[r]?.schema}function V(r){return D(h.ContentTypeValues.APPLICATION_JSON,r)}function le(r){return D(h.ContentTypeValues.TEXT_EVENT_STREAM,r)}function pe(r){return D("*/*",r)}const ue=["string","number","integer","boolean","null"];function b(r){return Array.isArray(r)?!0:ue.includes(r)}function v(r){return r.type==="array"}function de(r){return Array.isArray(r.enum)&&r.enum.length>0}function J(r){return Array.isArray(r.anyOf)&&r.anyOf.length>0}function K(r){return Array.isArray(r.oneOf)&&r.oneOf.length>0}function me(r){return J(r)||K(r)}function fe(r){return Array.isArray(r.allOf)&&r.allOf.length>0}function W(r){return J(r)||K(r)||fe(r)}function z(r){return r.includes("|")||r.includes("&")?`(${r})[]`:`${r}[]`}function he(r){return r.type!=="object"?!1:r.properties?Object.keys(r.properties).length===0:!0}function $(r){if(Array.isArray(r))return r.map(e=>$(e)).join(" | ");switch(r){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"null":return"null";default:return"any"}}function H(r){return[{method:"get",operation:r.get},{method:"put",operation:r.put},{method:"post",operation:r.post},{method:"delete",operation:r.delete},{method:"options",operation:r.options},{method:"head",operation:r.head},{method:"patch",operation:r.patch},{method:"trace",operation:r.trace}].filter(({operation:e})=>e!==void 0)}function q(r){return r.responses[200]}function B(r){const e=q(r);return V(e)}function ye(r,e){return r.parameters?r.parameters.map(t=>g(t)?U(t,e):t).filter(t=>t.in==="path"):[]}const xe="string";function Y(r){return!r.schema||g(r.schema)||!r.schema.type||!b(r.schema.type)?xe:$(r.schema.type)}function X(r){return r.startsWith("http://")||r.startsWith("https://")?Ae(r):Ce(r)}async function Ae(r){return await(await fetch(r)).text()}function Ce(r){return new Promise((e,t)=>{ce.readFile(r,"utf-8",(n,o)=>{n?t(n):e(o)})})}async function Pe(r){const e=await X(r);switch(Z(e)){case"json":return JSON.parse(e);case"yaml":return L.parse(e);default:throw new Error(`Unsupported file format: ${r}`)}}async function $e(r){const e=await X(r);switch(Z(e)){case"json":return JSON.parse(e);case"yaml":return L.parse(e);default:throw new Error(`Unsupported file format: ${r}`)}}function Z(r){const e=r.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 ee="types.ts",Te="@";function Ie(r){return h.combineURLs(r.path,ee)}function te(r,e,t){const n=h.combineURLs(e,t),o=r.getSourceFile(n);return o||r.createSourceFile(n,"",{overwrite:!0})}function R(r,e,t){let n=r.getImportDeclaration(o=>o.getModuleSpecifierValue()===e);n||(n=r.addImportDeclaration({moduleSpecifier:e})),t.forEach(o=>{n.getNamedImports().some(i=>i.getName()===o)||n.addNamedImport(o)})}function f(r,e,t){if(t.path.startsWith(Te)){R(r,t.path,[t.name]);return}const n=r.getDirectoryPath(),o=F.join(e,t.path,ee);let s=F.relative(n,o);s=s.replace(/\.ts$/,""),s.startsWith(".")||(s="./"+s),R(r,s,[t.name])}function w(r,e,t,n){r.path!==n.path&&f(e,t,n)}function Se(r,e){const t=[r,e].filter(n=>n!==void 0&&n.length>0);return t.length>0?t.join(`
2
+ `):void 0}function A(r,e,t){const n=Se(e,t);n&&r.addJsDoc({description:n})}function we(r){const e=r.split(".");return e.length!=2||e[0].length===0||e[1].length===0?null:e}function Ee(r){const e=we(r.name);return e?{tag:r,contextAlias:e[0],aggregateName:e[1]}:null}function Re(r){const e=r?.map(n=>Ee(n)).filter(n=>n!==null);if(!e)return new Map;const t=new Map;return e.forEach(n=>{t.set(n.tag.name,{aggregate:n,commands:new Map,events:new Map})}),t}function ve(r){if(!r)return null;const e=r.split(".");return e.length!=3?null:e[2]}const Oe="#/components/responses/wow.CommandOk",Ne="#/components/parameters/wow.id";class De{constructor(e){this.openAPI=e,this.aggregates=Re(e.tags),this.build()}aggregates;build(){for(const[e,t]of Object.entries(this.openAPI.paths)){const n=H(t);for(const o of n)this.commands(e,o),this.state(o.operation),this.events(o.operation),this.fields(o.operation)}}resolve(){const e=new Map;for(const t of this.aggregates.values()){if(!t.state||!t.fields)continue;const n=t.aggregate.contextAlias;let o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(t)}return e}commands(e,t){const n=t.operation;if(n.operationId==="wow.command.send")return;const o=ve(n.operationId);if(!o)return;const s=q(n);if(!s||!g(s)||s.$ref!==Oe||!n.requestBody)return;const i=n.parameters??[],a=i.filter(d=>g(d)&&d.$ref===Ne).at(0),c=i.filter(d=>!g(d)&&d.in==="path");if(a){const d=U(a,this.openAPI.components);c.push(d)}const p=n.requestBody.content[h.ContentTypeValues.APPLICATION_JSON].schema,u=S(p,this.openAPI.components);u.schema.title=u.schema.title||n.summary,u.schema.description=u.schema.description||n.description;const ae={name:o,method:t.method,path:e,pathParameters:c,summary:n.summary,description:n.description,schema:u,operation:n};n.tags?.forEach(d=>{const M=this.aggregates.get(d);M&&M.commands.set(o,ae)})}state(e){if(!e.operationId?.endsWith(".snapshot_state.single"))return;const t=B(e);if(!g(t))return;const n=S(t,this.openAPI.components);e.tags?.forEach(o=>{const s=this.aggregates.get(o);s&&(s.state=n)})}events(e){if(!this.openAPI.components||!e.operationId?.endsWith(".event.list_query"))return;const t=B(e);if(g(t))return;const n=t?.items;if(!g(n))return;const s=E(n,this.openAPI.components).properties.body.items.anyOf.map(i=>{const a=i.title,c=i.properties.name.const,l=i.properties.body,p=S(l,this.openAPI.components);return p.schema.title=p.schema.title||i.title,{title:a,name:c,schema:p}});e.tags?.forEach(i=>{const a=this.aggregates.get(i);a&&s.forEach(c=>{a.events.set(c.name,c)})})}fields(e){if(!this.openAPI.components||!e.operationId?.endsWith(".snapshot.count"))return;const n=k(e.requestBody,this.openAPI.components).content[h.ContentTypeValues.APPLICATION_JSON].schema,s=E(n,this.openAPI.components).properties?.field,i=S(s,this.openAPI.components);e.tags?.forEach(a=>{const c=this.aggregates.get(a);c&&(c.fields=i)})}}const T="@ahoo-wang/fetcher-wow",be={"wow.command.CommandResult":"CommandResult","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.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 m(r){if(!r)return{name:"",path:"/"};const e=be[r];if(e)return{name:e,path:T};const t=r.split(".");let n=-1;for(let c=0;c<t.length;c++)if(t[c]&&/^[A-Z]/.test(t[c])){n=c;break}const o=t.slice(0,n),s=o.length>0?`/${o.join("/")}`:"/",i=t.slice(n);return{name:P(i),path:s}}function x(r){const e=I(r);return m(e)}class qe{constructor(e){this.context=e}getOrCreateSourceFile(e){const t=Ie(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(),n=this.filterSchemas(e,t);this.context.logger.progress(`Generating models for ${n.length} schemas`),n.forEach((o,s)=>{this.context.logger.progressWithCount(s+1,n.length,`Processing schema: ${o.key}`,2),this.generateKeyedSchema(o)}),this.context.logger.success("Model generation completed")}filterSchemas(e,t){return Object.entries(e).map(([n,o])=>({key:n,schema:o})).filter(n=>!this.isWowSchema(n.key,t))}isWowSchema(e,t){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 n=m(e);return t.has(n.name)}aggregatedSchemaSuffix=["MaterializedSnapshot","MaterializedSnapshotPagedList","MaterializedSnapshotServerSentEventNonNullData","PagedList","ServerSentEventNonNullData","Snapshot","StateEvent"];stateAggregatedTypeNames(){const e=new Set;for(const t of this.context.contextAggregates.values())for(const n of t)this.aggregatedSchemaSuffix.forEach(o=>{const s=m(n.state.key),i=P(s.name)+o;e.add(i)});return e}generateKeyedSchema({key:e,schema:t}){const n=m(e),o=this.getOrCreateSourceFile(n),s=this.process(n,o,t);s&&A(s,t.title,t.description)}process(e,t,n){if(de(n))return t.addEnum({name:e.name,isExported:!0,members:n.enum.filter(s=>typeof s=="string"&&s.length>0).map(s=>({name:ge(s),initializer:`'${s}'`}))});if(v(n)&&g(n.items)){const s=x(n.items);return w(e,t,this.context.outputDir,s),t.addTypeAlias({name:e.name,type:z(s.name),isExported:!0})}const o=t.addInterface({name:e.name,isExported:!0});return n.type==="object"&&n.properties?this.processInterface(t,e,n,o):(W(n)&&(n.anyOf||n.oneOf||n.allOf).forEach(i=>{if(g(i)){const a=x(i);w(e,t,this.context.outputDir,a),o.addExtends(a.name);return}this.processInterface(t,e,i,o)}),o)}processObject(e,t,n){const o=e.addInterface({name:t.name,isExported:!0});return this.processInterface(e,t,n,o)}processInterface(e,t,n,o){for(const[s,i]of Object.entries(n.properties)){const a=this.resolvePropertyType(t,e,s,i);let c=o.getProperty(s);c?c.setType(a):c=o.addProperty({name:s,type:a}),g(i)||A(c,i.title,i.description)}return o}resolvePropertyType(e,t,n,o){if(g(o)){const s=x(o);return w(e,t,this.context.outputDir,s),s.name}if(o.const)return`'${o.const}'`;if(v(o)){const s=this.resolvePropertyType(e,t,n,o.items);return z(s)}if(o.type&&b(o.type))return $(o.type);if(W(o))return this.resolvePropertyCompositionType(e,t,o);if(o.type==="object"&&o.properties){const s={path:e.path,name:`${e.name}${P(n)}`},i=this.processObject(t,s,o);return A(i,o.title,o.description),s.name}return"any"}resolvePropertyCompositionType(e,t,n){const o=n.anyOf||n.oneOf||n.allOf,s=new Set;o.forEach(a=>{if(g(a)){const c=x(a);w(e,t,this.context.outputDir,c),s.add(c.name);return}s.add($(a.type??"string"))});const i=me(n)?"|":"&";return Array.from(s).join(i)}}const Me="@ahoo-wang/fetcher-decorator",je=["type ApiMetadata","type ApiMetadataCapable","api","post","put","patch","del","request","attribute","path","autoGeneratedError"],Fe={type:"Promise<Response>",metadata:"{resultExtractor: ResultExtractors.Response }"},O=`{
7
3
  headers: { Accept: ContentTypeValues.TEXT_EVENT_STREAM },
8
4
  resultExtractor: JsonEventStreamResultExtractor,
9
- }`;function oe(r){E(r,_e,Fe)}function re(r,e,t=[]){return e.addClass({name:r,isExported:!0,decorators:[{name:"api",arguments:t}]})}function se(r,e){r.addImplements("ApiMetadataCapable"),r.addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",hasQuestionToken:e===void 0,scope:w.Scope.Public,isReadonly:!0,initializer:e}]})}class We{constructor(e){this.context=e}commandEndpointPathsName="COMMAND_ENDPOINT_PATHS";defaultCommandClientOptionsName="DEFAULT_COMMAND_CLIENT_OPTIONS";generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((n,o)=>n+o.size,0);this.context.logger.info("--- Generating Command Clients ---"),this.context.logger.progress(`Generating command clients for ${e} aggregates`);let t=0;for(const[,n]of this.context.contextAggregates)n.forEach(o=>{t++,this.context.logger.progressWithCount(t,e,`Processing command client for aggregate: ${o.aggregate.aggregateName}`),this.processAggregate(o)});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=te(this.context.project,this.context.outputDir,e.aggregate,"commandClient");this.context.logger.info(`Processing command endpoint paths for ${e.commands.size} commands`),this.processCommandEndpointPaths(t,e),this.context.logger.info(`Creating default command client options: ${this.defaultCommandClientOptionsName}`),t.addVariableStatement({declarationKind:w.VariableDeclarationKind.Const,declarations:[{name:this.defaultCommandClientOptionsName,type:"ApiMetadata",initializer:`{
5
+ }`;function ne(r){R(r,Me,je)}function oe(r,e,t=[]){return e.addClass({name:r,isExported:!0,decorators:[{name:"api",arguments:t}]})}function re(r,e){r.addImplements("ApiMetadataCapable"),r.addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",hasQuestionToken:e===void 0,scope:C.Scope.Public,isReadonly:!0,initializer:e}]})}function Ge(r){let e=0,t=0;return r.commands.forEach(n=>{n.path.startsWith(j.ResourceAttributionPathSpec.TENANT)&&(e+=1),n.path.startsWith(j.ResourceAttributionPathSpec.OWNER)&&(t+=1)}),e===0&&t===0?"ResourceAttributionPathSpec.NONE":e>t?"ResourceAttributionPathSpec.TENANT":"ResourceAttributionPathSpec.OWNER"}function se(r,e,t,n){const o=`${t.contextAlias}/${t.aggregateName}/${n}.ts`;return te(r,e,o)}function _e(r,e){return`${P(r.aggregateName)}${e}`}function N(r){return r==="delete"?"del":r}class We{constructor(e){this.context=e,this.apiMetadataCtorInitializer=this.context.currentContextAlias?`{basePath:'${this.context.currentContextAlias}'}`:void 0}defaultParameterRequestType="ParameterRequest";defaultReturnType=Fe;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 n=0;for(const[o,s]of t){n++,this.context.logger.progressWithCount(n,t.size,`Generating API client for tag: ${o}`);const i=e.get(o);this.generateApiClient(i,s)}}createApiClientFile(e){let t=e.path;return this.context.currentContextAlias&&(t=h.combineURLs(this.context.currentContextAlias,t)),t=h.combineURLs(t,`${e.name}ApiClient.ts`),this.context.logger.info(`Creating API client file: ${t}`),this.context.getOrCreateSourceFile(t)}generateApiClient(e,t){const n=m(e.name);this.context.logger.info(`Generating API client class: ${n.name}ApiClient with ${t.size} operations`);const o=this.createApiClientFile(n);ne(o);const s=oe(n.name+"ApiClient",o);A(s,e.description),re(s,this.apiMetadataCtorInitializer),this.context.logger.info(`Processing ${t.size} operations for ${n.name}ApiClient`),t.forEach(i=>{this.processOperation(e,o,s,i)}),this.context.logger.success(`Completed API client: ${n.name}ApiClient`)}getMethodName(e,t){const n=t.operationId.split(".");for(let o=n.length-1;o>=0;o--){const s=y(n.slice(o));if(!e.getMethod(s))return s}return y(n)}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 n;if(g(t.requestBody)?(this.context.logger.info(`Extracting request body from reference for operation: ${t.operationId}`),n=k(t.requestBody,this.context.openAPI.components)):n=t.requestBody,!n)return this.context.logger.info(`Request body extraction failed for operation ${t.operationId}, using default: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType;if(n.content["multipart/form-data"])return this.context.logger.info(`Detected multipart/form-data content for operation ${t.operationId}, using ParameterRequest<FormData>`),"ParameterRequest<FormData>";if(n.content["application/json"]){const o=n.content["application/json"].schema;if(g(o)){const s=x(o);this.context.logger.info(`Adding import for request body model: ${s.name} from ${s.path}`),f(e,this.context.outputDir,s);const i=`ParameterRequest<${s.name}>`;return this.context.logger.info(`Resolved request type for operation ${t.operationId}: ${i}`),i}}return this.context.logger.info(`Using default request type for operation ${t.operationId}: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType}resolveParameters(e,t,n){const o=ye(n,this.context.openAPI.components).filter(a=>!this.context.isIgnoreApiClientPathParameters(e.name,a.name));this.context.logger.info(`Found ${o.length} path parameters for operation ${n.operationId}`);const s=o.map(a=>{const c=Y(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}'`]}]}}),i=this.resolveRequestType(t,n);return this.context.logger.info(`Adding httpRequest parameter: ${i}`),s.push({name:"httpRequest",hasQuestionToken:i===this.defaultParameterRequestType,type:`${i}`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: Record<string, any>"),s.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),s}resolveSchemaReturnType(e,t){const n="Promise<any>";if(g(t)){const o=x(t);this.context.logger.info(`Adding import for response model: ${o.name} from ${o.path}`),f(e,this.context.outputDir,o);const s=`Promise<${o.name}>`;return this.context.logger.info(`Resolved reference return type: ${s}`),s}if(!t.type)return this.context.logger.info(`Schema has no type, using default return type: ${n}`),n;if(b(t.type)){const s=`Promise<${$(t.type)}>`;return this.context.logger.info(`Resolved primitive return type: ${s}`),s}return this.context.logger.info(`Using default return type: ${n}`),n}resolveReturnType(e,t){const n=q(t);if(!n)return this.context.logger.info(`No OK response found for operation ${t.operationId}, using default return type: ${this.defaultReturnType.type}`),this.defaultReturnType;const o=V(n)||pe(n);if(o){const i=this.resolveSchemaReturnType(e,o);return this.context.logger.info(`Resolved JSON/wildcard response return type for operation ${t.operationId}: ${i}`),{type:i}}const s=le(n);if(s){if(g(s)){const a=E(s,this.context.openAPI.components);if(v(a)&&g(a.items)){const c=x(a.items);this.context.logger.info(`Adding import for event stream model: ${c.name} from ${c.path}`),f(e,this.context.outputDir,c);const p=`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}: ${p}`),{type:p,metadata:O}}}const i="Promise<JsonServerSentEventStream<any>>";return this.context.logger.info(`Resolved generic event stream return type for operation ${t.operationId}: ${i}`),{type:i,metadata:O}}return this.context.logger.info(`Using default return type for operation ${t.operationId}: ${this.defaultReturnType.type}`),this.defaultReturnType}processOperation(e,t,n,o){this.context.logger.info(`Processing operation: ${o.operation.operationId} (${o.method} ${o.path})`);const s=this.getMethodName(n,o.operation);this.context.logger.info(`Generated method name: ${s}`);const i=this.resolveParameters(e,t,o.operation),a=this.resolveReturnType(t,o.operation),c=a.metadata?{name:N(o.method),arguments:[`'${o.path}'`,a.metadata]}:{name:N(o.method),arguments:[`'${o.path}'`]};this.context.logger.info(`Creating method with ${i.length} parameters, return type: ${a.type}`);const l=n.addMethod({name:s,decorators:[c],parameters:i,returnType:a.type,statements:[`throw autoGeneratedError(${i.map(p=>p.name).join(",")});`]});A(l,o.operation.summary,o.operation.description),this.context.logger.success(`Operation method generated: ${s}`)}groupOperations(e){this.context.logger.info("Grouping operations by API client tags");const t=new Map;let n=0;for(const[o,s]of Object.entries(this.context.openAPI.paths)){const i=H(s).filter(a=>{if(!a.operation.operationId)return!1;const c=a.operation.tags;return!c||c.length==0?!1:c.every(l=>e.has(l))});this.context.logger.info(`Path ${o}: found ${i.length} valid operations`);for(const a of i)a.operation.tags.forEach(c=>{const l={...a,path:o};t.has(c)||t.set(c,new Set),t.get(c).add(l),n++})}return this.context.logger.info(`Grouped ${n} operations into ${t.size} tag groups`),t}resolveApiTags(){this.context.logger.info("Resolving API client tags from OpenAPI specification");const e=new Map,t=this.context.openAPI.tags?.length||0;let n=0;return this.context.openAPI.tags?.forEach(o=>{o.name!="wow"&&o.name!="Actuator"&&!this.isAggregateTag(o)?(e.set(o.name,o),n++,this.context.logger.info(`Included API client tag: ${o.name}`)):this.context.logger.info(`Excluded tag: ${o.name} (wow/Actuator/aggregate)`)}),this.context.logger.info(`Resolved ${n} API client tags from ${t} total tags`),e}isAggregateTag(e){for(const t of this.context.contextAggregates.values())for(const n of t)if(n.aggregate.tag.name===e.name)return!0;return!1}}class ze{constructor(e){this.context=e}commandEndpointPathsName="COMMAND_ENDPOINT_PATHS";defaultCommandClientOptionsName="DEFAULT_COMMAND_CLIENT_OPTIONS";generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((n,o)=>n+o.size,0);this.context.logger.info("--- Generating Command Clients ---"),this.context.logger.progress(`Generating command clients for ${e} aggregates`);let t=0;for(const[,n]of this.context.contextAggregates)n.forEach(o=>{t++,this.context.logger.progressWithCount(t,e,`Processing command client for aggregate: ${o.aggregate.aggregateName}`),this.processAggregate(o)});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=se(this.context.project,this.context.outputDir,e.aggregate,"commandClient");this.context.logger.info(`Processing command endpoint paths for ${e.commands.size} commands`),this.processCommandEndpointPaths(t,e),this.context.logger.info(`Creating default command client options: ${this.defaultCommandClientOptionsName}`),t.addVariableStatement({declarationKind:C.VariableDeclarationKind.Const,declarations:[{name:this.defaultCommandClientOptionsName,type:"ApiMetadata",initializer:`{
10
6
  basePath: '${e.aggregate.contextAlias}'
11
- }`}],isExported:!1}),this.context.logger.info(`Adding imports from ${$}: CommandRequest, CommandResult, CommandResultEventStream, DeleteAggregate, RecoverAggregate`),t.addImportDeclaration({moduleSpecifier:$,namedImports:["CommandRequest","CommandResult","CommandResultEventStream","DeleteAggregate","RecoverAggregate"],isTypeOnly:!0}),this.context.logger.info("Adding import from @ahoo-wang/fetcher-eventstream: JsonEventStreamResultExtractor"),t.addImportDeclaration({moduleSpecifier:"@ahoo-wang/fetcher-eventstream",namedImports:["JsonEventStreamResultExtractor"]}),this.context.logger.info("Adding import from @ahoo-wang/fetcher: ContentTypeValues"),E(t,"@ahoo-wang/fetcher",["ContentTypeValues"]),this.context.logger.info("Adding imports from @ahoo-wang/fetcher-decorator: ApiMetadata types and decorators"),oe(t),this.context.logger.info("Generating standard command client class"),this.processCommandClient(t,e),this.context.logger.info("Generating stream command client class"),this.processCommandClient(t,e,!0),this.context.logger.success(`Command client generation completed for aggregate: ${e.aggregate.aggregateName}`)}processCommandEndpointPaths(e,t){this.context.logger.info(`Creating command endpoint paths enum: ${this.commandEndpointPathsName}`);const n=e.addEnum({name:this.commandEndpointPathsName});t.commands.forEach(o=>{this.context.logger.info(`Adding command endpoint: ${o.name.toUpperCase()} = '${o.path}'`),n.addMember({name:o.name.toUpperCase(),initializer:`'${o.path}'`})}),this.context.logger.success(`Command endpoint paths enum created with ${t.commands.size} entries`)}getEndpointPath(e){return`${this.commandEndpointPathsName}.${e.name.toUpperCase()}`}processCommandClient(e,t,n=!1){let o="CommandClient",s=[],i="Promise<CommandResult>";n&&(o="Stream"+o,s=["''",ne],i="Promise<CommandResultEventStream>");const a=je(t.aggregate,o),c=re(a,e,s);se(c,this.defaultCommandClientOptionsName),t.commands.forEach(g=>{this.processCommandMethod(t,e,c,g,i)})}resolveParameters(e,t,n){const o=m(n.schema.key);this.context.logger.info(`Adding import for command model: ${o.name} from path: ${o.path}`),f(t,this.context.outputDir,o);const s=n.pathParameters.filter(i=>!this.context.isIgnoreCommandClientPathParameters(e.name,i.name)).map(i=>{const a=X(i);return this.context.logger.info(`Adding path parameter: ${i.name} (type: ${a})`),{name:i.name,type:a,hasQuestionToken:!1,decorators:[{name:"path",arguments:[`'${i.name}'`]}]}});return this.context.logger.info(`Adding command request parameter: commandRequest (type: CommandRequest<${o.name}>)`),s.push({name:"commandRequest",hasQuestionToken:Ie(n.schema.schema),type:`CommandRequest<${o.name}>`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: attributes (type: Record<string, any>)"),s.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),s}processCommandMethod(e,t,n,o,s){this.context.logger.info(`Generating command method: ${y(o.name)} for command: ${o.name}`),this.context.logger.info(`Command method details: HTTP ${o.method}, path: ${o.path}, return type: ${s}`);const i=this.resolveParameters(e.aggregate.tag,t,o),a=n.addMethod({name:y(o.name),decorators:[{name:O(o.method),arguments:[`${this.getEndpointPath(o)}`]}],parameters:i,returnType:s,statements:[`throw autoGeneratedError(${i.map(c=>c.name).join(",")});`]});(o.summary||o.description)&&this.context.logger.info(`Adding JSDoc documentation for method: ${y(o.name)}`),A(a,o.summary,o.description),this.context.logger.success(`Command method generated: ${y(o.name)}`)}}class ze{constructor(e){this.context=e,this.apiMetadataCtorInitializer=this.context.currentContextAlias?`{basePath:'${this.context.currentContextAlias}'}`:void 0}defaultParameterRequestType="ParameterRequest";defaultReturnType={type:"Promise<any>"};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 n=0;for(const[o,s]of t){n++,this.context.logger.progressWithCount(n,t.size,`Generating API client for tag: ${o}`);const i=e.get(o);this.generateApiClient(i,s)}}createApiClientFile(e){let t=e.path;return this.context.currentContextAlias&&(t=h.combineURLs(this.context.currentContextAlias,t)),t=h.combineURLs(t,`${e.name}ApiClient.ts`),this.context.logger.info(`Creating API client file: ${t}`),this.context.getOrCreateSourceFile(t)}generateApiClient(e,t){const n=m(e.name);this.context.logger.info(`Generating API client class: ${n.name}ApiClient with ${t.size} operations`);const o=this.createApiClientFile(n);oe(o);const s=re(n.name+"ApiClient",o);A(s,e.description),se(s,this.apiMetadataCtorInitializer),this.context.logger.info(`Processing ${t.size} operations for ${n.name}ApiClient`),t.forEach(i=>{this.processOperation(e,o,s,i)}),this.context.logger.success(`Completed API client: ${n.name}ApiClient`)}getMethodName(e,t){const n=t.operationId.split(".");for(let o=n.length-1;o>=0;o--){const s=y(n.slice(o));if(!e.getMethod(s))return s}return y(n)}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 n;if(l(t.requestBody)?(this.context.logger.info(`Extracting request body from reference for operation: ${t.operationId}`),n=k(t.requestBody,this.context.openAPI.components)):n=t.requestBody,!n)return this.context.logger.info(`Request body extraction failed for operation ${t.operationId}, using default: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType;if(n.content["multipart/form-data"])return this.context.logger.info(`Detected multipart/form-data content for operation ${t.operationId}, using ParameterRequest<FormData>`),"ParameterRequest<FormData>";if(n.content["application/json"]){const o=n.content["application/json"].schema;if(l(o)){const s=x(o);this.context.logger.info(`Adding import for request body model: ${s.name} from ${s.path}`),f(e,this.context.outputDir,s);const i=`ParameterRequest<${s.name}>`;return this.context.logger.info(`Resolved request type for operation ${t.operationId}: ${i}`),i}}return this.context.logger.info(`Using default request type for operation ${t.operationId}: ${this.defaultParameterRequestType}`),this.defaultParameterRequestType}resolveParameters(e,t,n){const o=Se(n,this.context.openAPI.components).filter(a=>!this.context.isIgnoreApiClientPathParameters(e.name,a.name));this.context.logger.info(`Found ${o.length} path parameters for operation ${n.operationId}`);const s=o.map(a=>{const c=X(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}'`]}]}}),i=this.resolveRequestType(t,n);return this.context.logger.info(`Adding httpRequest parameter: ${i}`),s.push({name:"httpRequest",hasQuestionToken:i===this.defaultParameterRequestType,type:`${i}`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: Record<string, any>"),s.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),s}resolveSchemaReturnType(e,t){if(l(t)){const n=x(t);this.context.logger.info(`Adding import for response model: ${n.name} from ${n.path}`),f(e,this.context.outputDir,n);const o=`Promise<${n.name}>`;return this.context.logger.info(`Resolved reference return type: ${o}`),o}if(!t.type)return this.context.logger.info(`Schema has no type, using default return type: ${this.defaultReturnType.type}`),this.defaultReturnType.type;if(D(t.type)){const o=`Promise<${P(t.type)}>`;return this.context.logger.info(`Resolved primitive return type: ${o}`),o}return this.context.logger.info(`Using default return type: ${this.defaultReturnType.type}`),this.defaultReturnType.type}resolveReturnType(e,t){const n=b(t);if(!n)return this.context.logger.info(`No OK response found for operation ${t.operationId}, using default return type: ${this.defaultReturnType.type}`),this.defaultReturnType;const o=J(n);if(o){const a=this.resolveSchemaReturnType(e,o);return this.context.logger.info(`Resolved JSON response return type for operation ${t.operationId}: ${a}`),{stream:!1,type:a}}const s=xe(n);if(s){if(l(s)){const c=R(s,this.context.openAPI.components);if(v(c)&&l(c.items)){const g=x(c.items);this.context.logger.info(`Adding import for event stream model: ${g.name} from ${g.path}`),f(e,this.context.outputDir,g);const p=`Promise<JsonServerSentEventStream<${g.name.includes("ServerSentEvent")?`${g.name}['data']`:g.name}>>`;return this.context.logger.info(`Resolved event stream return type for operation ${t.operationId}: ${p}`),{stream:!0,type:p}}}const a="Promise<JsonServerSentEventStream<any>>";return this.context.logger.info(`Resolved generic event stream return type for operation ${t.operationId}: ${a}`),{stream:!0,type:a}}const i=Ae(n);if(i){const a=this.resolveSchemaReturnType(e,i);return this.context.logger.info(`Resolved wildcard response return type for operation ${t.operationId}: ${a}`),{type:a}}return this.context.logger.info(`Using default return type for operation ${t.operationId}: ${this.defaultReturnType.type}`),this.defaultReturnType}processOperation(e,t,n,o){this.context.logger.info(`Processing operation: ${o.operation.operationId} (${o.method} ${o.path})`);const s=this.getMethodName(n,o.operation);this.context.logger.info(`Generated method name: ${s}`);const i=this.resolveParameters(e,t,o.operation),a=this.resolveReturnType(t,o.operation),c=a.stream?{name:O(o.method),arguments:[`'${o.path}'`,ne]}:{name:O(o.method),arguments:[`'${o.path}'`]};this.context.logger.info(`Creating method with ${i.length} parameters, return type: ${a.type}, stream: ${a.stream||!1}`);const g=n.addMethod({name:s,decorators:[c],parameters:i,returnType:a.type,statements:[`throw autoGeneratedError(${i.map(u=>u.name).join(",")});`]});A(g,o.operation.summary,o.operation.description),this.context.logger.success(`Operation method generated: ${s}`)}groupOperations(e){this.context.logger.info("Grouping operations by API client tags");const t=new Map;let n=0;for(const[o,s]of Object.entries(this.context.openAPI.paths)){const i=Y(s).filter(a=>{if(!a.operation.operationId)return!1;const c=a.operation.tags;return!c||c.length==0?!1:c.every(g=>e.has(g))});this.context.logger.info(`Path ${o}: found ${i.length} valid operations`);for(const a of i)a.operation.tags.forEach(c=>{const g={...a,path:o};t.has(c)||t.set(c,new Set),t.get(c).add(g),n++})}return this.context.logger.info(`Grouped ${n} operations into ${t.size} tag groups`),t}resolveApiTags(){this.context.logger.info("Resolving API client tags from OpenAPI specification");const e=new Map,t=this.context.openAPI.tags?.length||0;let n=0;return this.context.openAPI.tags?.forEach(o=>{o.name!="wow"&&o.name!="Actuator"&&!this.isAggregateTag(o)?(e.set(o.name,o),n++,this.context.logger.info(`Included API client tag: ${o.name}`)):this.context.logger.info(`Excluded tag: ${o.name} (wow/Actuator/aggregate)`)}),this.context.logger.info(`Resolved ${n} API client tags from ${t} total tags`),e}isAggregateTag(e){for(const t of this.context.contextAggregates.values())for(const n of t)if(n.aggregate.tag.name===e.name)return!0;return!1}}class Be{constructor(e){this.context=e,this.queryClientGenerator=new Ge(e),this.commandClientGenerator=new We(e),this.apiClientGenerator=new ze(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.processBoundedContext(t);this.queryClientGenerator.generate(),this.commandClientGenerator.generate(),this.apiClientGenerator.generate(),this.context.logger.success("Client generation completed")}processBoundedContext(e){const t=`${e}/boundedContext.ts`;this.context.logger.info(`Creating bounded context file: ${t}`);const n=this.context.getOrCreateSourceFile(t);this.context.logger.info(`Adding bounded context alias constant: BOUNDED_CONTEXT_ALIAS = '${e}'`),n.addStatements(`export const BOUNDED_CONTEXT_ALIAS = '${e}';`),this.context.logger.success(`Bounded context file created successfully: ${t}`)}}class ke{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 ee(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 ie="./fetcher-generator.config.json";class Le{constructor(e){this.options=e,this.project=e.project,this.options.logger.info("CodeGenerator instance created")}project;async generate(){this.options.logger.info("Starting code generation from OpenAPI specification"),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 e=await he(this.options.inputPath);this.options.logger.info("OpenAPI specification parsed successfully"),this.options.logger.info("Resolving bounded context aggregates");const n=new De(e).resolve();this.options.logger.info(`Resolved ${n.size} bounded context aggregates`);const o=this.options.configPath??ie;let s={};try{this.options.logger.info("Parsing configuration file:",o),s=await ye(o)}catch(g){this.options.logger.info("Configuration file parsing failed ",g)}const i=new ke({openAPI:e,project:this.project,outputDir:this.options.outputDir,contextAggregates:n,logger:this.options.logger,config:s});this.options.logger.info("Generating models"),new qe(i).generate(),this.options.logger.info("Models generated successfully"),this.options.logger.info("Generating clients"),new Be(i).generate(),this.options.logger.info("Clients generated successfully"),this.options.logger.info("Generating index files"),this.generateIndex(),this.options.logger.info("Index files generated successfully"),this.options.logger.info("Optimizing source files"),this.optimizeSourceFiles(),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(){this.options.logger.info(`Generating index files for output directory: ${this.options.outputDir}`);const e=this.project.getDirectory(this.options.outputDir);if(!e){this.options.logger.info("Output directory not found, skipping index generation");return}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 n of t)this.options.logger.info(`Processing subdirectory: ${n.getPath()}`),this.generateIndexForDirectory(n),this.processDirectory(n)}generateIndexForDirectory(e){const t=e.getPath();this.options.logger.info(`Generating index for directory: ${t}`);const n=e.getSourceFiles().filter(a=>a.getBaseName().endsWith(".ts")&&a.getBaseName()!=="index.ts"),o=e.getDirectories();if(this.options.logger.info(`Found ${n.length} TypeScript files and ${o.length} subdirectories in ${t}`),n.length===0&&o.length===0){this.options.logger.info(`No files or subdirectories to export in ${t}, skipping index generation`);return}const s=`${t}/index.ts`;this.options.logger.info(`Creating/updating index file: ${s}`);const i=this.project.getSourceFile(s)||this.project.createSourceFile(s,"",{overwrite:!0});i.removeText();for(const a of n){const c=`./${a.getBaseNameWithoutExtension()}`;this.options.logger.info(`Adding export for file: ${c}`),i.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}for(const a of o){const c=`./${a.getBaseName()}`;this.options.logger.info(`Adding export for subdirectory: ${c}`),i.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}this.options.logger.info(`Index file generated for ${t} with ${n.length+o.length} exports`)}optimizeSourceFiles(){const e=this.project.getSourceFiles();this.options.logger.info(`Optimizing ${e.length} source files`),e.forEach((t,n)=>{this.options.logger.info(`Optimizing file ${n+1}/${e.length}`),t.formatText(),t.organizeImports(),t.fixMissingImports()}),this.options.logger.info("All source files optimized")}}exports.CodeGenerator=Le;exports.DEFAULT_CONFIG_PATH=ie;
7
+ }`}],isExported:!1}),this.context.logger.info(`Adding imports from ${T}: CommandRequest, CommandResult, CommandResultEventStream, DeleteAggregate, RecoverAggregate`),t.addImportDeclaration({moduleSpecifier:T,namedImports:["CommandRequest","CommandResult","CommandResultEventStream","DeleteAggregate","RecoverAggregate"],isTypeOnly:!0}),this.context.logger.info("Adding import from @ahoo-wang/fetcher-eventstream: JsonEventStreamResultExtractor"),t.addImportDeclaration({moduleSpecifier:"@ahoo-wang/fetcher-eventstream",namedImports:["JsonEventStreamResultExtractor"]}),this.context.logger.info("Adding import from @ahoo-wang/fetcher: ContentTypeValues"),R(t,"@ahoo-wang/fetcher",["ContentTypeValues"]),this.context.logger.info("Adding imports from @ahoo-wang/fetcher-decorator: ApiMetadata types and decorators"),ne(t),this.context.logger.info("Generating standard command client class"),this.processCommandClient(t,e),this.context.logger.info("Generating stream command client class"),this.processCommandClient(t,e,!0),this.context.logger.success(`Command client generation completed for aggregate: ${e.aggregate.aggregateName}`)}processCommandEndpointPaths(e,t){this.context.logger.info(`Creating command endpoint paths enum: ${this.commandEndpointPathsName}`);const n=e.addEnum({name:this.commandEndpointPathsName});t.commands.forEach(o=>{this.context.logger.info(`Adding command endpoint: ${o.name.toUpperCase()} = '${o.path}'`),n.addMember({name:o.name.toUpperCase(),initializer:`'${o.path}'`})}),this.context.logger.success(`Command endpoint paths enum created with ${t.commands.size} entries`)}getEndpointPath(e){return`${this.commandEndpointPathsName}.${e.name.toUpperCase()}`}processCommandClient(e,t,n=!1){let o="CommandClient",s=[],i="Promise<CommandResult>";n&&(o="Stream"+o,s=["''",O],i="Promise<CommandResultEventStream>");const a=_e(t.aggregate,o),c=oe(a,e,s);re(c,this.defaultCommandClientOptionsName),t.commands.forEach(l=>{this.processCommandMethod(t,e,c,l,i)})}resolveParameters(e,t,n){const o=m(n.schema.key);this.context.logger.info(`Adding import for command model: ${o.name} from path: ${o.path}`),f(t,this.context.outputDir,o);const s=n.pathParameters.filter(i=>!this.context.isIgnoreCommandClientPathParameters(e.name,i.name)).map(i=>{const a=Y(i);return this.context.logger.info(`Adding path parameter: ${i.name} (type: ${a})`),{name:i.name,type:a,hasQuestionToken:!1,decorators:[{name:"path",arguments:[`'${i.name}'`]}]}});return this.context.logger.info(`Adding command request parameter: commandRequest (type: CommandRequest<${o.name}>)`),s.push({name:"commandRequest",hasQuestionToken:he(n.schema.schema),type:`CommandRequest<${o.name}>`,decorators:[{name:"request",arguments:[]}]}),this.context.logger.info("Adding attributes parameter: attributes (type: Record<string, any>)"),s.push({name:"attributes",hasQuestionToken:!0,type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]}),s}processCommandMethod(e,t,n,o,s){this.context.logger.info(`Generating command method: ${y(o.name)} for command: ${o.name}`),this.context.logger.info(`Command method details: HTTP ${o.method}, path: ${o.path}, return type: ${s}`);const i=this.resolveParameters(e.aggregate.tag,t,o),a=n.addMethod({name:y(o.name),decorators:[{name:N(o.method),arguments:[`${this.getEndpointPath(o)}`]}],parameters:i,returnType:s,statements:[`throw autoGeneratedError(${i.map(c=>c.name).join(",")});`]});(o.summary||o.description)&&this.context.logger.info(`Adding JSDoc documentation for method: ${y(o.name)}`),A(a,o.summary,o.description),this.context.logger.success(`Command method generated: ${y(o.name)}`)}}class Be{constructor(e){this.context=e}generate(){const e=Array.from(this.context.contextAggregates.values()).reduce((n,o)=>n+o.size,0);this.context.logger.info("--- Generating Query Clients ---"),this.context.logger.progress(`Generating query clients for ${e} aggregates`);let t=0;for(const[,n]of this.context.contextAggregates)n.forEach(o=>{t++,this.context.logger.progressWithCount(t,e,`Processing query client for aggregate: ${o.aggregate.aggregateName}`),this.processQueryClient(o)});this.context.logger.success("Query client generation completed")}createClientFilePath(e,t){return se(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 ${T}: QueryClientFactory, QueryClientOptions, ResourceAttributionPathSpec`),t.addImportDeclaration({moduleSpecifier:T,namedImports:["QueryClientFactory","QueryClientOptions","ResourceAttributionPathSpec"]});const n="DEFAULT_QUERY_CLIENT_OPTIONS";this.context.logger.info(`Creating default query client options: ${n}`),t.addVariableStatement({declarationKind:C.VariableDeclarationKind.Const,declarations:[{name:n,type:"QueryClientOptions",initializer:`{
8
+ contextAlias: '${e.aggregate.contextAlias}',
9
+ aggregateName: '${e.aggregate.aggregateName}',
10
+ resourceAttribution: ${Ge(e)},
11
+ }`}],isExported:!1});const o=[];this.context.logger.info(`Processing ${e.events.size} domain events for aggregate: ${e.aggregate.aggregateName}`);for(const p of e.events.values()){const u=m(p.schema.key);this.context.logger.info(`Adding import for event model: ${u.name} from path: ${u.path}`),f(t,this.context.outputDir,u),o.push(u)}const s="DOMAIN_EVENT_TYPES",i=o.map(p=>p.name).join(" | ");this.context.logger.info(`Creating domain event types union: ${s} = ${i}`),t.addTypeAlias({name:s,type:i});const a=`${y(e.aggregate.aggregateName)}QueryClientFactory`,c=m(e.state.key),l=m(e.fields.key);this.context.logger.info(`Adding import for state model: ${c.name} from path: ${c.path}`),f(t,this.context.outputDir,c),this.context.logger.info(`Adding import for fields model: ${l.name} from path: ${l.path}`),f(t,this.context.outputDir,l),this.context.logger.info(`Creating query client factory: ${a}`),t.addVariableStatement({declarationKind:C.VariableDeclarationKind.Const,declarations:[{name:a,initializer:`new QueryClientFactory<${c.name}, ${l.name} | string, ${s}>(${n})`}],isExported:!0}),this.context.logger.success(`Query client generation completed for aggregate: ${e.aggregate.aggregateName}`)}}class Le{constructor(e){this.context=e,this.queryClientGenerator=new Be(e),this.commandClientGenerator=new ze(e),this.apiClientGenerator=new We(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.processBoundedContext(t);this.queryClientGenerator.generate(),this.commandClientGenerator.generate(),this.apiClientGenerator.generate(),this.context.logger.success("Client generation completed")}processBoundedContext(e){const t=`${e}/boundedContext.ts`;this.context.logger.info(`Creating bounded context file: ${t}`);const n=this.context.getOrCreateSourceFile(t);this.context.logger.info(`Adding bounded context alias constant: BOUNDED_CONTEXT_ALIAS = '${e}'`),n.addStatements(`export const BOUNDED_CONTEXT_ALIAS = '${e}';`),this.context.logger.success(`Bounded context file created successfully: ${t}`)}}class ke{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 te(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 ie="./fetcher-generator.config.json";class Ue{constructor(e){this.options=e,this.project=new C.Project({tsConfigFilePath:this.options.tsConfigFilePath}),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"),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 e=await Pe(this.options.inputPath);this.options.logger.info("OpenAPI specification parsed successfully"),this.options.logger.info("Resolving bounded context aggregates");const n=new De(e).resolve();this.options.logger.info(`Resolved ${n.size} bounded context aggregates`);const o=this.options.configPath??ie;let s={};try{this.options.logger.info("Parsing configuration file:",o),s=await $e(o)}catch(l){this.options.logger.info("Configuration file parsing failed ",l)}const i=new ke({openAPI:e,project:this.project,outputDir:this.options.outputDir,contextAggregates:n,logger:this.options.logger,config:s});this.options.logger.info("Generating models"),new qe(i).generate(),this.options.logger.info("Models generated successfully"),this.options.logger.info("Generating clients"),new Le(i).generate(),this.options.logger.info("Clients generated successfully"),this.options.logger.info("Generating index files"),this.generateIndex(),this.options.logger.info("Index files generated successfully"),this.options.logger.info("Optimizing source files"),this.optimizeSourceFiles(),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(){this.options.logger.info(`Generating index files for output directory: ${this.options.outputDir}`);const e=this.project.getDirectory(this.options.outputDir);if(!e){this.options.logger.info("Output directory not found, skipping index generation");return}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 n of t)this.options.logger.info(`Processing subdirectory: ${n.getPath()}`),this.generateIndexForDirectory(n),this.processDirectory(n)}generateIndexForDirectory(e){const t=e.getPath();this.options.logger.info(`Generating index for directory: ${t}`);const n=e.getSourceFiles().filter(a=>a.getBaseName().endsWith(".ts")&&a.getBaseName()!=="index.ts"),o=e.getDirectories();if(this.options.logger.info(`Found ${n.length} TypeScript files and ${o.length} subdirectories in ${t}`),n.length===0&&o.length===0){this.options.logger.info(`No files or subdirectories to export in ${t}, skipping index generation`);return}const s=`${t}/index.ts`;this.options.logger.info(`Creating/updating index file: ${s}`);const i=this.project.getSourceFile(s)||this.project.createSourceFile(s,"",{overwrite:!0});i.removeText();for(const a of n){const c=`./${a.getBaseNameWithoutExtension()}`;this.options.logger.info(`Adding export for file: ${c}`),i.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}for(const a of o){const c=`./${a.getBaseName()}`;this.options.logger.info(`Adding export for subdirectory: ${c}`),i.addExportDeclaration({moduleSpecifier:c,isTypeOnly:!1,namedExports:[]})}this.options.logger.info(`Index file generated for ${t} with ${n.length+o.length} exports`)}optimizeSourceFiles(){const e=this.project.getSourceFiles();this.options.logger.info(`Optimizing ${e.length} source files`),e.forEach((t,n)=>{this.options.logger.info(`Optimizing file ${n+1}/${e.length}`),t.formatText(),t.organizeImports(),t.fixMissingImports()}),this.options.logger.info("All source files optimized")}}exports.CodeGenerator=Ue;exports.DEFAULT_CONFIG_PATH=ie;
12
12
  //# sourceMappingURL=index.cjs.map