zod-codegen 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +93 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.yml +70 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +87 -0
  4. package/.github/dependabot.yml +76 -0
  5. package/.github/workflows/ci.yml +143 -0
  6. package/.github/workflows/release.yml +65 -0
  7. package/.husky/commit-msg +2 -0
  8. package/.husky/pre-commit +5 -0
  9. package/.lintstagedrc.json +4 -0
  10. package/.nvmrc +1 -0
  11. package/.prettierrc.json +7 -0
  12. package/.releaserc.json +159 -0
  13. package/CHANGELOG.md +24 -0
  14. package/CONTRIBUTING.md +274 -0
  15. package/LICENCE +201 -0
  16. package/README.md +263 -0
  17. package/SECURITY.md +108 -0
  18. package/codecov.yml +29 -0
  19. package/commitlint.config.mjs +28 -0
  20. package/dist/scripts/update-manifest.js +31 -0
  21. package/dist/src/assets/manifest.json +5 -0
  22. package/dist/src/cli.js +60 -0
  23. package/dist/src/generator.js +55 -0
  24. package/dist/src/http/fetch-client.js +141 -0
  25. package/dist/src/interfaces/code-generator.js +1 -0
  26. package/dist/src/interfaces/file-reader.js +1 -0
  27. package/dist/src/polyfills/fetch.js +18 -0
  28. package/dist/src/services/code-generator.service.js +419 -0
  29. package/dist/src/services/file-reader.service.js +25 -0
  30. package/dist/src/services/file-writer.service.js +32 -0
  31. package/dist/src/services/import-builder.service.js +45 -0
  32. package/dist/src/services/type-builder.service.js +42 -0
  33. package/dist/src/types/http.js +10 -0
  34. package/dist/src/types/openapi.js +173 -0
  35. package/dist/src/utils/error-handler.js +11 -0
  36. package/dist/src/utils/execution-time.js +3 -0
  37. package/dist/src/utils/manifest.js +9 -0
  38. package/dist/src/utils/reporter.js +15 -0
  39. package/dist/src/utils/signal-handler.js +12 -0
  40. package/dist/src/utils/tty.js +3 -0
  41. package/dist/tests/integration/cli.test.js +25 -0
  42. package/dist/tests/unit/generator.test.js +29 -0
  43. package/dist/vitest.config.js +38 -0
  44. package/eslint.config.mjs +33 -0
  45. package/package.json +102 -0
  46. package/samples/openapi.json +1 -0
  47. package/samples/saris-openapi.json +7122 -0
  48. package/samples/swagger-petstore.yaml +802 -0
  49. package/samples/swagger-saris.yaml +3585 -0
  50. package/samples/test-logical.yaml +50 -0
  51. package/scripts/update-manifest.js +31 -0
  52. package/scripts/update-manifest.ts +47 -0
  53. package/src/assets/manifest.json +5 -0
  54. package/src/cli.ts +68 -0
  55. package/src/generator.ts +61 -0
  56. package/src/http/fetch-client.ts +181 -0
  57. package/src/interfaces/code-generator.ts +25 -0
  58. package/src/interfaces/file-reader.ts +15 -0
  59. package/src/polyfills/fetch.ts +26 -0
  60. package/src/services/code-generator.service.ts +775 -0
  61. package/src/services/file-reader.service.ts +29 -0
  62. package/src/services/file-writer.service.ts +36 -0
  63. package/src/services/import-builder.service.ts +64 -0
  64. package/src/services/type-builder.service.ts +77 -0
  65. package/src/types/http.ts +35 -0
  66. package/src/types/openapi.ts +202 -0
  67. package/src/utils/error-handler.ts +13 -0
  68. package/src/utils/execution-time.ts +3 -0
  69. package/src/utils/manifest.ts +17 -0
  70. package/src/utils/reporter.ts +16 -0
  71. package/src/utils/signal-handler.ts +14 -0
  72. package/src/utils/tty.ts +3 -0
  73. package/tests/integration/cli.test.ts +29 -0
  74. package/tests/unit/generator.test.ts +36 -0
  75. package/tsconfig.json +44 -0
  76. package/vitest.config.ts +39 -0
package/README.md ADDED
@@ -0,0 +1,263 @@
1
+ # zod-codegen
2
+
3
+ [![npm version](https://img.shields.io/npm/v/zod-codegen.svg)](https://www.npmjs.com/package/zod-codegen)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
6
+ [![CI](https://github.com/julienandreu/zod-codegen/workflows/CI/badge.svg)](https://github.com/julienandreu/zod-codegen/actions)
7
+ [![Coverage](https://img.shields.io/codecov/c/github/julienandreu/zod-codegen)](https://codecov.io/gh/julienandreu/zod-codegen)
8
+
9
+ A powerful TypeScript code generator that creates **Zod schemas** and **type-safe clients** from OpenAPI specifications.
10
+
11
+ ## 🚀 Features
12
+
13
+ - **🔥 Zod Schema Generation**: Automatically generate Zod validation schemas from OpenAPI specs
14
+ - **🎯 Type-Safe**: Full TypeScript support with generated types
15
+ - **📡 Multiple Formats**: Support for OpenAPI 3.x, Swagger 2.0, JSON, and YAML
16
+ - **🌐 Remote Files**: Fetch OpenAPI specs from URLs
17
+ - **⚡ Fast**: Optimized for performance with minimal dependencies
18
+ - **🔧 Configurable**: Flexible output options and customization
19
+ - **📦 CLI & Programmatic**: Use as a CLI tool or integrate into your build process
20
+
21
+ ## 📦 Installation
22
+
23
+ ### Global Installation (CLI)
24
+
25
+ ```bash
26
+ npm install -g zod-codegen
27
+ ```
28
+
29
+ ### Project Installation
30
+
31
+ ```bash
32
+ npm install --save-dev zod-codegen
33
+ ```
34
+
35
+ ## 🔧 Usage
36
+
37
+ ### Command Line Interface
38
+
39
+ ```bash
40
+ # Generate from local file
41
+ zod-codegen --input ./openapi.json --output ./generated
42
+
43
+ # Generate from URL
44
+ zod-codegen --input https://api.example.com/openapi.json --output ./api
45
+
46
+ # Generate with custom output directory
47
+ zod-codegen -i ./swagger.yaml -o ./src/generated
48
+ ```
49
+
50
+ #### CLI Options
51
+
52
+ | Option | Alias | Description | Default |
53
+ | ----------- | ----- | ----------------------------------- | ----------- |
54
+ | `--input` | `-i` | Path or URL to OpenAPI file | Required |
55
+ | `--output` | `-o` | Directory to output generated files | `generated` |
56
+ | `--help` | `-h` | Show help | |
57
+ | `--version` | `-v` | Show version | |
58
+
59
+ ### Programmatic Usage
60
+
61
+ ```typescript
62
+ import {Generator} from 'zod-codegen';
63
+
64
+ const generator = new Generator();
65
+
66
+ // Generate from local file
67
+ await generator.generate({
68
+ input: './openapi.json',
69
+ output: './generated',
70
+ });
71
+
72
+ // Generate from URL
73
+ await generator.generate({
74
+ input: 'https://api.example.com/openapi.json',
75
+ output: './api',
76
+ });
77
+ ```
78
+
79
+ ## 📁 Generated Output
80
+
81
+ The generator creates the following structure:
82
+
83
+ ```
84
+ generated/
85
+ ├── schemas/ # Zod validation schemas
86
+ │ ├── user.schema.ts
87
+ │ └── product.schema.ts
88
+ ├── types/ # TypeScript type definitions
89
+ │ ├── user.types.ts
90
+ │ └── product.types.ts
91
+ └── client/ # Type-safe API client
92
+ └── api.client.ts
93
+ ```
94
+
95
+ ## 🎯 Example
96
+
97
+ Given this OpenAPI specification:
98
+
99
+ ```yaml
100
+ openapi: 3.0.0
101
+ info:
102
+ title: User API
103
+ version: 1.0.0
104
+ paths:
105
+ /users:
106
+ get:
107
+ responses:
108
+ '200':
109
+ content:
110
+ application/json:
111
+ schema:
112
+ type: object
113
+ properties:
114
+ id:
115
+ type: integer
116
+ name:
117
+ type: string
118
+ email:
119
+ type: string
120
+ format: email
121
+ required: [id, name, email]
122
+ ```
123
+
124
+ **Generated Zod Schema** (`schemas/user.schema.ts`):
125
+
126
+ ```typescript
127
+ import {z} from 'zod';
128
+
129
+ export const UserSchema = z.object({
130
+ id: z.number().int(),
131
+ name: z.string(),
132
+ email: z.string().email(),
133
+ });
134
+
135
+ export type User = z.infer<typeof UserSchema>;
136
+ ```
137
+
138
+ **Generated Types** (`types/user.types.ts`):
139
+
140
+ ```typescript
141
+ export interface User {
142
+ id: number;
143
+ name: string;
144
+ email: string;
145
+ }
146
+ ```
147
+
148
+ **Generated Client** (`client/api.client.ts`):
149
+
150
+ ```typescript
151
+ import {UserSchema, type User} from '../schemas/user.schema.js';
152
+
153
+ export class ApiClient {
154
+ async getUsers(): Promise<User[]> {
155
+ const response = await fetch('/api/users');
156
+ const data = await response.json();
157
+ return UserSchema.array().parse(data);
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## 🛠️ Development
163
+
164
+ ### Prerequisites
165
+
166
+ - Node.js ≥ 18.0.0
167
+ - npm or yarn
168
+
169
+ ### Setup
170
+
171
+ ```bash
172
+ # Clone the repository
173
+ git clone https://github.com/julienandreu/zod-codegen.git
174
+ cd zod-codegen
175
+
176
+ # Install dependencies
177
+ npm install
178
+
179
+ # Build the project
180
+ npm run build
181
+
182
+ # Run tests
183
+ npm test
184
+
185
+ # Run linting
186
+ npm run lint
187
+
188
+ # Format code
189
+ npm run format
190
+ ```
191
+
192
+ ### Testing
193
+
194
+ ```bash
195
+ # Run all tests
196
+ npm test
197
+
198
+ # Run tests in watch mode
199
+ npm run test:watch
200
+
201
+ # Run tests with coverage
202
+ npm run test:coverage
203
+
204
+ # Run tests with UI
205
+ npm run test:ui
206
+ ```
207
+
208
+ ### Available Scripts
209
+
210
+ | Script | Description |
211
+ | ----------------------- | ----------------------------------------------- |
212
+ | `npm run build` | Build the project |
213
+ | `npm run build:watch` | Build in watch mode |
214
+ | `npm run dev` | Development mode with example |
215
+ | `npm test` | Run tests |
216
+ | `npm run test:watch` | Run tests in watch mode |
217
+ | `npm run test:coverage` | Run tests with coverage |
218
+ | `npm run lint` | Lint and fix code |
219
+ | `npm run format` | Format code with Prettier |
220
+ | `npm run type-check` | Type check without emitting |
221
+ | `npm run validate` | Run all checks (lint, format, type-check, test) |
222
+ | `npm run clean` | Clean build artifacts |
223
+
224
+ ## 📋 Requirements
225
+
226
+ - **Node.js**: ≥ 18.0.0
227
+ - **TypeScript**: ≥ 5.0.0
228
+ - **Zod**: ≥ 3.20.0
229
+
230
+ ## 🤝 Contributing
231
+
232
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
233
+
234
+ ### Quick Start for Contributors
235
+
236
+ 1. Fork the repository
237
+ 2. Create your feature branch: `git checkout -b feature/amazing-feature`
238
+ 3. Make your changes
239
+ 4. Run tests: `npm test`
240
+ 5. Run validation: `npm run validate`
241
+ 6. Commit your changes: `git commit -m 'feat: add amazing feature'`
242
+ 7. Push to the branch: `git push origin feature/amazing-feature`
243
+ 8. Open a Pull Request
244
+
245
+ ## 📝 License
246
+
247
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
248
+
249
+ ## 🙏 Acknowledgments
250
+
251
+ - [Zod](https://zod.dev/) - TypeScript-first schema validation
252
+ - [OpenAPI Specification](https://www.openapis.org/) - API specification standard
253
+ - [TypeScript](https://www.typescriptlang.org/) - Typed JavaScript
254
+
255
+ ## 📞 Support
256
+
257
+ - 🐛 **Bug reports**: [GitHub Issues](https://github.com/julienandreu/zod-codegen/issues)
258
+ - 💬 **Questions**: [GitHub Discussions](https://github.com/julienandreu/zod-codegen/discussions)
259
+ - 📧 **Email**: [julienandreu@me.com](mailto:julienandreu@me.com)
260
+
261
+ ---
262
+
263
+ Made with ❤️ by [Julien Andreu](https://github.com/julienandreu)
package/SECURITY.md ADDED
@@ -0,0 +1,108 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We actively support the following versions of zod-codegen:
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 1.x.x | :white_check_mark: |
10
+ | 0.1.x | :white_check_mark: |
11
+
12
+ ## Reporting a Vulnerability
13
+
14
+ The zod-codegen team takes security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
15
+
16
+ ### How to Report Security Issues
17
+
18
+ **Please do not report security vulnerabilities through public GitHub issues.**
19
+
20
+ Instead, please report them via email to: [julienandreu@me.com](mailto:julienandreu@me.com)
21
+
22
+ Please include the following information in your report:
23
+
24
+ - Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
25
+ - Full paths of source file(s) related to the manifestation of the issue
26
+ - The location of the affected source code (tag/branch/commit or direct URL)
27
+ - Any special configuration required to reproduce the issue
28
+ - Step-by-step instructions to reproduce the issue
29
+ - Proof-of-concept or exploit code (if possible)
30
+ - Impact of the issue, including how an attacker might exploit the issue
31
+
32
+ This information will help us triage your report more quickly.
33
+
34
+ ### Response Timeline
35
+
36
+ - **Initial Response**: We will acknowledge receipt of your vulnerability report within 48 hours.
37
+ - **Progress Updates**: We will send you regular updates about our progress, at least every 7 days.
38
+ - **Resolution**: We aim to resolve critical vulnerabilities within 30 days of the initial report.
39
+
40
+ ### Disclosure Policy
41
+
42
+ When we receive a security bug report, we will:
43
+
44
+ 1. Confirm the problem and determine the affected versions
45
+ 2. Audit code to find any potential similar problems
46
+ 3. Prepare fixes for all supported versions
47
+ 4. Release new versions as soon as possible
48
+ 5. Prominently announce the issue in the release notes
49
+
50
+ ### Bug Bounty Program
51
+
52
+ Currently, we do not offer a paid bug bounty program. We express our gratitude to security researchers through:
53
+
54
+ - Public acknowledgment in our security advisories (if desired)
55
+ - Recognition in our project documentation
56
+ - Direct communication and thanks from our team
57
+
58
+ ## Security Best Practices
59
+
60
+ When using zod-codegen, please follow these security best practices:
61
+
62
+ ### Input Validation
63
+
64
+ - Always validate OpenAPI specifications from untrusted sources
65
+ - Be cautious when processing large or complex OpenAPI files
66
+ - Consider file size limits and timeout mechanisms
67
+
68
+ ### Output Security
69
+
70
+ - Review generated code before using in production
71
+ - Ensure generated validation schemas are appropriate for your use case
72
+ - Test generated code thoroughly
73
+
74
+ ### Dependencies
75
+
76
+ - Keep zod-codegen and its dependencies up to date
77
+ - Regularly audit your dependency tree for known vulnerabilities
78
+ - Use tools like `npm audit` to check for security issues
79
+
80
+ ## Known Security Considerations
81
+
82
+ ### OpenAPI Processing
83
+
84
+ - **File Size**: Very large OpenAPI files may consume significant memory
85
+ - **Circular References**: Complex schemas with circular references are handled but may impact performance
86
+ - **Remote Files**: When fetching OpenAPI specs from URLs, ensure the sources are trusted
87
+
88
+ ### Generated Code
89
+
90
+ - **Validation Logic**: Generated Zod schemas provide runtime validation but should be part of a broader security strategy
91
+ - **Type Safety**: While generated TypeScript types provide compile-time safety, always validate runtime data
92
+
93
+ ## Security Updates
94
+
95
+ Security updates will be clearly marked in our release notes and will be given priority in our release schedule. We recommend:
96
+
97
+ - Subscribing to release notifications
98
+ - Keeping your installation up to date
99
+ - Testing updates in a development environment before production deployment
100
+
101
+ ## Contact
102
+
103
+ For questions about this security policy, please contact:
104
+
105
+ - Email: [julienandreu@me.com](mailto:julienandreu@me.com)
106
+ - GitHub: [@julienandreu](https://github.com/julienandreu)
107
+
108
+ Thank you for helping keep zod-codegen and our users safe!
package/codecov.yml ADDED
@@ -0,0 +1,29 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: 80%
6
+ threshold: 2%
7
+ base: auto
8
+ patch:
9
+ default:
10
+ target: 80%
11
+ threshold: 2%
12
+ base: auto
13
+
14
+ ignore:
15
+ - 'dist/'
16
+ - 'coverage/'
17
+ - 'node_modules/'
18
+ - '**/*.d.ts'
19
+ - '**/*.config.*'
20
+ - '**/*.test.*'
21
+ - '**/*.spec.*'
22
+ - 'scripts/'
23
+ - 'samples/'
24
+ - '.github/'
25
+
26
+ comment:
27
+ layout: 'reach,diff,flags,tree'
28
+ behavior: default
29
+ require_changes: false
@@ -0,0 +1,28 @@
1
+ export default {
2
+ extends: ['@commitlint/config-conventional'],
3
+ rules: {
4
+ 'type-enum': [
5
+ 2,
6
+ 'always',
7
+ [
8
+ 'feat',
9
+ 'fix',
10
+ 'docs',
11
+ 'style',
12
+ 'refactor',
13
+ 'perf',
14
+ 'test',
15
+ 'build',
16
+ 'ci',
17
+ 'chore',
18
+ 'revert',
19
+ ],
20
+ ],
21
+ 'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
22
+ 'subject-empty': [2, 'never'],
23
+ 'subject-full-stop': [2, 'never', '.'],
24
+ 'header-max-length': [2, 'always', 100],
25
+ 'footer-max-line-length': [0],
26
+ 'footer-leading-blank': [0],
27
+ },
28
+ };
@@ -0,0 +1,31 @@
1
+ import { readFileSync, writeFileSync } from 'fs';
2
+ import { resolve } from 'path';
3
+ import { z } from 'zod';
4
+ /**
5
+ * Type guard for the package.json object
6
+ *
7
+ * @param input Unknown input
8
+ * @returns true if the input is an event object
9
+ */
10
+ export function isPackageJson(input) {
11
+ const event = z
12
+ .object({
13
+ name: z.string(),
14
+ version: z.string(),
15
+ description: z.string(),
16
+ })
17
+ .strict()
18
+ .catchall(z.any())
19
+ .required();
20
+ const { success } = event.safeParse(input);
21
+ return success;
22
+ }
23
+ const sourcePath = resolve(__dirname, '..', 'package.json');
24
+ const data = JSON.parse(readFileSync(sourcePath, 'utf8'));
25
+ if (!isPackageJson(data)) {
26
+ process.exit(1);
27
+ }
28
+ const { name, version, description } = data;
29
+ const targetPath = resolve(__dirname, '..', 'src', 'assets', 'manifest.json');
30
+ writeFileSync(targetPath, JSON.stringify({ name, version, description }, null, 2));
31
+ process.exit(0);
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "zod-codegen",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Zod code generator"
5
+ }
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import yargs from 'yargs';
3
+ import { hideBin } from 'yargs/helpers';
4
+ import { Generator } from './generator.js';
5
+ import { readFileSync } from 'node:fs';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { dirname, join } from 'node:path';
8
+ import loudRejection from 'loud-rejection';
9
+ import { handleErrors } from './utils/error-handler.js';
10
+ import { handleSignals } from './utils/signal-handler.js';
11
+ import debug from 'debug';
12
+ import { isManifest } from './utils/manifest.js';
13
+ import { Reporter } from './utils/reporter.js';
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ const manifestData = JSON.parse(readFileSync(join(__dirname, 'assets', 'manifest.json'), 'utf-8'));
16
+ if (!isManifest(manifestData)) {
17
+ process.exit(1);
18
+ }
19
+ const { name, description, version } = manifestData;
20
+ const reporter = new Reporter(process.stdout);
21
+ const startTime = process.hrtime.bigint();
22
+ debug(`${name}:${String(process.pid)}`);
23
+ loudRejection();
24
+ handleSignals(process, startTime);
25
+ handleErrors(process, startTime);
26
+ const argv = yargs(hideBin(process.argv))
27
+ .scriptName(name)
28
+ .usage(`${description}\n\nUsage: $0 [options]`)
29
+ .version(version)
30
+ .option('input', {
31
+ alias: 'i',
32
+ type: 'string',
33
+ description: 'Path or URL to OpenAPI file',
34
+ demandOption: true,
35
+ })
36
+ .option('output', {
37
+ alias: 'o',
38
+ type: 'string',
39
+ description: 'Directory to output the generated files',
40
+ default: 'generated',
41
+ })
42
+ .help()
43
+ .parseSync();
44
+ const { input, output } = argv;
45
+ void (async () => {
46
+ try {
47
+ const generator = new Generator(name, version, reporter, input, output);
48
+ const exitCode = await generator.run();
49
+ process.exit(exitCode);
50
+ }
51
+ catch (error) {
52
+ if (error instanceof Error) {
53
+ reporter.error(`Fatal error: ${error.message}`);
54
+ }
55
+ else {
56
+ reporter.error('An unknown fatal error occurred');
57
+ }
58
+ process.exit(1);
59
+ }
60
+ })();
@@ -0,0 +1,55 @@
1
+ import { OpenApiFileParserService, SyncFileReaderService } from './services/file-reader.service.js';
2
+ import { TypeScriptCodeGeneratorService } from './services/code-generator.service.js';
3
+ import { SyncFileWriterService } from './services/file-writer.service.js';
4
+ export class Generator {
5
+ _name;
6
+ _version;
7
+ reporter;
8
+ inputPath;
9
+ _outputDir;
10
+ fileReader = new SyncFileReaderService();
11
+ fileParser = new OpenApiFileParserService();
12
+ codeGenerator = new TypeScriptCodeGeneratorService();
13
+ fileWriter;
14
+ outputPath;
15
+ constructor(_name, _version, reporter, inputPath, _outputDir) {
16
+ this._name = _name;
17
+ this._version = _version;
18
+ this.reporter = reporter;
19
+ this.inputPath = inputPath;
20
+ this._outputDir = _outputDir;
21
+ this.fileWriter = new SyncFileWriterService(this._name, this._version, inputPath);
22
+ this.outputPath = this.fileWriter.resolveOutputPath(this._outputDir);
23
+ }
24
+ async run() {
25
+ try {
26
+ const rawSource = this.readFile();
27
+ const openApiSpec = this.parseFile(rawSource);
28
+ const generatedCode = this.generateCode(openApiSpec);
29
+ this.writeFile(generatedCode);
30
+ this.reporter.log(`✅ Generated types successfully at: ${this.outputPath}`);
31
+ return 0;
32
+ }
33
+ catch (error) {
34
+ if (error instanceof Error) {
35
+ this.reporter.error(`❌ Error: ${error.message}`);
36
+ }
37
+ else {
38
+ this.reporter.error('❌ An unknown error occurred');
39
+ }
40
+ return Promise.resolve(1);
41
+ }
42
+ }
43
+ readFile() {
44
+ return this.fileReader.readFile(this.inputPath);
45
+ }
46
+ parseFile(source) {
47
+ return this.fileParser.parse(source);
48
+ }
49
+ generateCode(spec) {
50
+ return this.codeGenerator.generate(spec);
51
+ }
52
+ writeFile(content) {
53
+ this.fileWriter.writeFile(this.outputPath, content);
54
+ }
55
+ }