zod-codegen 1.3.0 → 1.4.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 (80) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +61 -9
  3. package/dist/scripts/update-manifest.d.ts +14 -0
  4. package/dist/scripts/update-manifest.d.ts.map +1 -0
  5. package/dist/src/cli.d.ts +3 -0
  6. package/dist/src/cli.d.ts.map +1 -0
  7. package/dist/src/cli.js +31 -2
  8. package/dist/src/generator.d.ts +23 -0
  9. package/dist/src/generator.d.ts.map +1 -0
  10. package/dist/src/generator.js +3 -2
  11. package/dist/src/http/fetch-client.d.ts +15 -0
  12. package/dist/src/http/fetch-client.d.ts.map +1 -0
  13. package/dist/src/interfaces/code-generator.d.ts +20 -0
  14. package/dist/src/interfaces/code-generator.d.ts.map +1 -0
  15. package/dist/src/interfaces/file-reader.d.ts +13 -0
  16. package/dist/src/interfaces/file-reader.d.ts.map +1 -0
  17. package/dist/src/polyfills/fetch.d.ts +5 -0
  18. package/dist/src/polyfills/fetch.d.ts.map +1 -0
  19. package/dist/src/services/code-generator.service.d.ts +57 -0
  20. package/dist/src/services/code-generator.service.d.ts.map +1 -0
  21. package/dist/src/services/code-generator.service.js +38 -1
  22. package/dist/src/services/file-reader.service.d.ts +9 -0
  23. package/dist/src/services/file-reader.service.d.ts.map +1 -0
  24. package/dist/src/services/file-writer.service.d.ts +10 -0
  25. package/dist/src/services/file-writer.service.d.ts.map +1 -0
  26. package/dist/src/services/import-builder.service.d.ts +14 -0
  27. package/dist/src/services/import-builder.service.d.ts.map +1 -0
  28. package/dist/src/services/type-builder.service.d.ts +12 -0
  29. package/dist/src/services/type-builder.service.d.ts.map +1 -0
  30. package/dist/src/types/generator-options.d.ts +59 -0
  31. package/dist/src/types/generator-options.d.ts.map +1 -0
  32. package/dist/src/types/generator-options.js +1 -0
  33. package/dist/src/types/http.d.ts +25 -0
  34. package/dist/src/types/http.d.ts.map +1 -0
  35. package/dist/src/types/openapi.d.ts +1120 -0
  36. package/dist/src/types/openapi.d.ts.map +1 -0
  37. package/dist/src/utils/error-handler.d.ts +3 -0
  38. package/dist/src/utils/error-handler.d.ts.map +1 -0
  39. package/dist/src/utils/error-handler.js +2 -2
  40. package/dist/src/utils/execution-time.d.ts +2 -0
  41. package/dist/src/utils/execution-time.d.ts.map +1 -0
  42. package/dist/src/utils/manifest.d.ts +8 -0
  43. package/dist/src/utils/manifest.d.ts.map +1 -0
  44. package/dist/src/utils/naming-convention.d.ts +80 -0
  45. package/dist/src/utils/naming-convention.d.ts.map +1 -0
  46. package/dist/src/utils/naming-convention.js +135 -0
  47. package/dist/src/utils/reporter.d.ts +7 -0
  48. package/dist/src/utils/reporter.d.ts.map +1 -0
  49. package/dist/src/utils/signal-handler.d.ts +3 -0
  50. package/dist/src/utils/signal-handler.d.ts.map +1 -0
  51. package/dist/src/utils/signal-handler.js +2 -2
  52. package/dist/src/utils/tty.d.ts +2 -0
  53. package/dist/src/utils/tty.d.ts.map +1 -0
  54. package/dist/tests/integration/cli.test.d.ts +2 -0
  55. package/dist/tests/integration/cli.test.d.ts.map +1 -0
  56. package/dist/tests/integration/cli.test.js +2 -2
  57. package/dist/tests/unit/code-generator.test.d.ts +2 -0
  58. package/dist/tests/unit/code-generator.test.d.ts.map +1 -0
  59. package/dist/tests/unit/code-generator.test.js +170 -1
  60. package/dist/tests/unit/file-reader.test.d.ts +2 -0
  61. package/dist/tests/unit/file-reader.test.d.ts.map +1 -0
  62. package/dist/tests/unit/generator.test.d.ts +2 -0
  63. package/dist/tests/unit/generator.test.d.ts.map +1 -0
  64. package/dist/tests/unit/naming-convention.test.d.ts +2 -0
  65. package/dist/tests/unit/naming-convention.test.d.ts.map +1 -0
  66. package/dist/tests/unit/naming-convention.test.js +231 -0
  67. package/dist/vitest.config.d.ts +3 -0
  68. package/dist/vitest.config.d.ts.map +1 -0
  69. package/package.json +10 -5
  70. package/src/cli.ts +34 -3
  71. package/src/generator.ts +8 -1
  72. package/src/services/code-generator.service.ts +47 -1
  73. package/src/types/generator-options.ts +60 -0
  74. package/src/utils/error-handler.ts +2 -2
  75. package/src/utils/naming-convention.ts +214 -0
  76. package/src/utils/signal-handler.ts +2 -2
  77. package/tests/integration/cli.test.ts +2 -2
  78. package/tests/unit/code-generator.test.ts +189 -1
  79. package/tests/unit/naming-convention.test.ts +263 -0
  80. package/tsconfig.json +2 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/types/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,eAAO,MAAM,SAAS;;iBAEpB,CAAC;AA6CH,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAKxD,CAAC;AAcF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;iBAYpB,CAAC;AAkBH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;iBAKnB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;iBAKtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBASvB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAanB,CAAC;AA+CH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAStB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAC1D,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACpE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AACtD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AACpD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAC1D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAC5D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AACpD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const errorReceived: (process: NodeJS.Process, startTime: bigint) => () => void;
2
+ export declare const handleErrors: (process: NodeJS.Process, startTime: bigint) => void;
3
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/error-handler.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,CAAC,OAAO,EAAE,WAAW,MAAM,WAAS,IAGhF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,CAAC,OAAO,EAAE,WAAW,MAAM,KAAG,IAKzE,CAAC"}
@@ -5,7 +5,7 @@ export const errorReceived = (process, startTime) => () => {
5
5
  };
6
6
  export const handleErrors = (process, startTime) => {
7
7
  const catchErrors = ['unhandledRejection', 'uncaughtException'];
8
- catchErrors.map((event) => {
9
- return process.on(event, errorReceived(process, startTime));
8
+ catchErrors.forEach((event) => {
9
+ process.on(event, errorReceived(process, startTime));
10
10
  });
11
11
  };
@@ -0,0 +1,2 @@
1
+ export declare function getExecutionTime(startTime: bigint): number;
2
+ //# sourceMappingURL=execution-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-time.d.ts","sourceRoot":"","sources":["../../../src/utils/execution-time.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE1D"}
@@ -0,0 +1,8 @@
1
+ interface Manifest {
2
+ readonly name: string;
3
+ readonly version: string;
4
+ readonly description: string;
5
+ }
6
+ export declare function isManifest(input: unknown): input is Manifest;
7
+ export {};
8
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/utils/manifest.ts"],"names":[],"mappings":"AAEA,UAAU,QAAQ;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAQD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Supported naming conventions for operation IDs.
3
+ * These conventions transform operation IDs to match common programming language styles.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * transformNamingConvention('get_user_by_id', 'camelCase') // 'getUserById'
8
+ * transformNamingConvention('getUserById', 'snake_case') // 'get_user_by_id'
9
+ * ```
10
+ */
11
+ export type NamingConvention = 'camelCase' | 'PascalCase' | 'snake_case' | 'kebab-case' | 'SCREAMING_SNAKE_CASE' | 'SCREAMING-KEBAB-CASE';
12
+ /**
13
+ * Operation details provided to custom transformers.
14
+ * Contains all available information about an OpenAPI operation.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const transformer: OperationNameTransformer = (details) => {
19
+ * return `${details.method.toUpperCase()}_${details.operationId}`;
20
+ * };
21
+ * ```
22
+ */
23
+ export interface OperationDetails {
24
+ /** Original operationId from OpenAPI spec */
25
+ operationId: string;
26
+ /** HTTP method (get, post, put, patch, delete, head, options) */
27
+ method: string;
28
+ /** API path (e.g., /users/{id}) */
29
+ path: string;
30
+ /** Tags associated with the operation */
31
+ tags?: string[];
32
+ /** Summary of the operation */
33
+ summary?: string;
34
+ /** Description of the operation */
35
+ description?: string;
36
+ }
37
+ /**
38
+ * Custom transformer function for operation names.
39
+ * Receives operation details and returns the transformed name.
40
+ *
41
+ * **Note:** The returned name will be sanitized to ensure it's a valid TypeScript identifier.
42
+ * Invalid characters will be replaced with underscores, and names starting with digits will be prefixed.
43
+ *
44
+ * @param details - Complete operation details from OpenAPI spec
45
+ * @returns The transformed operation name
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const transformer: OperationNameTransformer = (details) => {
50
+ * const tag = details.tags?.[0] || 'default';
51
+ * return `${details.method}_${tag}_${details.operationId}`;
52
+ * };
53
+ * ```
54
+ */
55
+ export type OperationNameTransformer = (details: OperationDetails) => string;
56
+ /**
57
+ * Transforms a string to the specified naming convention.
58
+ *
59
+ * Handles various input formats including camelCase, PascalCase, snake_case, kebab-case,
60
+ * and mixed delimiters. The function normalizes the input by splitting on common delimiters
61
+ * (underscores, hyphens, spaces, dots) and then applies the target convention.
62
+ *
63
+ * **Note:** This function does not sanitize the output. The caller should ensure the result
64
+ * is a valid identifier for the target language (e.g., using `sanitizeIdentifier`).
65
+ *
66
+ * @param input - The input string to transform (can be in any naming convention)
67
+ * @param convention - The target naming convention to apply
68
+ * @returns The transformed string in the target convention
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * transformNamingConvention('get_user_by_id', 'camelCase') // 'getUserById'
73
+ * transformNamingConvention('getUserById', 'snake_case') // 'get_user_by_id'
74
+ * transformNamingConvention('get-user-by-id', 'PascalCase') // 'GetUserById'
75
+ * ```
76
+ *
77
+ * @throws Will return empty string if input is empty (preserves empty input)
78
+ */
79
+ export declare function transformNamingConvention(input: string, convention: NamingConvention): string;
80
+ //# sourceMappingURL=naming-convention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming-convention.d.ts","sourceRoot":"","sources":["../../../src/utils/naming-convention.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,sBAAsB,GACtB,sBAAsB,CAAC;AAE3B;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC;AA0G7E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,MAAM,CAsB7F"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Capitalizes the first letter of a word
3
+ */
4
+ function capitalize(word) {
5
+ if (word.length === 0)
6
+ return word;
7
+ return word.charAt(0).toUpperCase() + word.slice(1);
8
+ }
9
+ /**
10
+ * Splits camelCase or PascalCase strings into words
11
+ */
12
+ function splitCamelCase(input) {
13
+ const words = [];
14
+ let currentWord = '';
15
+ for (const char of input) {
16
+ const isUpperCase = char === char.toUpperCase() && char !== char.toLowerCase();
17
+ const isDigit = /\d/.test(char);
18
+ const lastChar = currentWord[currentWord.length - 1];
19
+ // Start a new word if:
20
+ // 1. Current char is uppercase and we have a previous word
21
+ // 2. Current char is a digit and previous was not
22
+ if (currentWord.length > 0 && (isUpperCase || (isDigit && lastChar && !/\d/.test(lastChar)))) {
23
+ words.push(currentWord);
24
+ currentWord = '';
25
+ }
26
+ currentWord += char;
27
+ }
28
+ if (currentWord.length > 0) {
29
+ words.push(currentWord);
30
+ }
31
+ return words.length > 0 ? words : [input];
32
+ }
33
+ /**
34
+ * Normalizes input string into an array of words
35
+ * Handles camelCase, PascalCase, snake_case, kebab-case, SCREAMING_SNAKE_CASE, etc.
36
+ */
37
+ function normalizeToWords(input) {
38
+ // Handle empty or single character
39
+ if (input.length <= 1) {
40
+ return [input.toLowerCase()];
41
+ }
42
+ // Split by common delimiters: underscore, hyphen, space, dot
43
+ let words = input.split(/[-_\s.]+/).filter((w) => w.length > 0);
44
+ // If no delimiters found, try to split camelCase/PascalCase
45
+ if (words.length === 1) {
46
+ words = splitCamelCase(input);
47
+ }
48
+ // Normalize all words to lowercase
49
+ return words.map((w) => w.toLowerCase());
50
+ }
51
+ /**
52
+ * Converts words array to camelCase
53
+ */
54
+ function toCamelCase(words) {
55
+ if (words.length === 0)
56
+ return '';
57
+ const [first, ...rest] = words;
58
+ if (!first)
59
+ return '';
60
+ return first + rest.map((w) => capitalize(w)).join('');
61
+ }
62
+ /**
63
+ * Converts words array to PascalCase
64
+ */
65
+ function toPascalCase(words) {
66
+ return words.map((w) => capitalize(w)).join('');
67
+ }
68
+ /**
69
+ * Converts words array to snake_case
70
+ */
71
+ function toSnakeCase(words) {
72
+ return words.join('_');
73
+ }
74
+ /**
75
+ * Converts words array to kebab-case
76
+ */
77
+ function toKebabCase(words) {
78
+ return words.join('-');
79
+ }
80
+ /**
81
+ * Converts words array to SCREAMING_SNAKE_CASE
82
+ */
83
+ function toScreamingSnakeCase(words) {
84
+ return words.map((w) => w.toUpperCase()).join('_');
85
+ }
86
+ /**
87
+ * Converts words array to SCREAMING-KEBAB-CASE
88
+ */
89
+ function toScreamingKebabCase(words) {
90
+ return words.map((w) => w.toUpperCase()).join('-');
91
+ }
92
+ /**
93
+ * Transforms a string to the specified naming convention.
94
+ *
95
+ * Handles various input formats including camelCase, PascalCase, snake_case, kebab-case,
96
+ * and mixed delimiters. The function normalizes the input by splitting on common delimiters
97
+ * (underscores, hyphens, spaces, dots) and then applies the target convention.
98
+ *
99
+ * **Note:** This function does not sanitize the output. The caller should ensure the result
100
+ * is a valid identifier for the target language (e.g., using `sanitizeIdentifier`).
101
+ *
102
+ * @param input - The input string to transform (can be in any naming convention)
103
+ * @param convention - The target naming convention to apply
104
+ * @returns The transformed string in the target convention
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * transformNamingConvention('get_user_by_id', 'camelCase') // 'getUserById'
109
+ * transformNamingConvention('getUserById', 'snake_case') // 'get_user_by_id'
110
+ * transformNamingConvention('get-user-by-id', 'PascalCase') // 'GetUserById'
111
+ * ```
112
+ *
113
+ * @throws Will return empty string if input is empty (preserves empty input)
114
+ */
115
+ export function transformNamingConvention(input, convention) {
116
+ if (!input || input.length === 0) {
117
+ return input;
118
+ }
119
+ // Normalize input: split by common delimiters and convert to words
120
+ const words = normalizeToWords(input);
121
+ switch (convention) {
122
+ case 'camelCase':
123
+ return toCamelCase(words);
124
+ case 'PascalCase':
125
+ return toPascalCase(words);
126
+ case 'snake_case':
127
+ return toSnakeCase(words);
128
+ case 'kebab-case':
129
+ return toKebabCase(words);
130
+ case 'SCREAMING_SNAKE_CASE':
131
+ return toScreamingSnakeCase(words);
132
+ case 'SCREAMING-KEBAB-CASE':
133
+ return toScreamingKebabCase(words);
134
+ }
135
+ }
@@ -0,0 +1,7 @@
1
+ export declare class Reporter {
2
+ private readonly _stdout;
3
+ constructor(_stdout: NodeJS.WriteStream);
4
+ log(...args: readonly unknown[]): void;
5
+ error(...args: readonly unknown[]): void;
6
+ }
7
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../../src/utils/reporter.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM,CAAC,WAAW;IAKxD,GAAG,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI;IAItC,KAAK,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI;CAGzC"}
@@ -0,0 +1,3 @@
1
+ export declare const signalReceived: (process: NodeJS.Process, startTime: bigint, event: NodeJS.Signals) => () => void;
2
+ export declare const handleSignals: (process: NodeJS.Process, startTime: bigint) => void;
3
+ //# sourceMappingURL=signal-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/signal-handler.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,CAAC,OAAO,EAAE,WAAW,MAAM,EAAE,OAAO,MAAM,CAAC,OAAO,WAAS,IAIxG,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,CAAC,OAAO,EAAE,WAAW,MAAM,KAAG,IAK1E,CAAC"}
@@ -6,7 +6,7 @@ export const signalReceived = (process, startTime, event) => () => {
6
6
  };
7
7
  export const handleSignals = (process, startTime) => {
8
8
  const catchSignals = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
9
- catchSignals.map((event) => {
10
- return process.once(event, signalReceived(process, startTime, event));
9
+ catchSignals.forEach((event) => {
10
+ process.once(event, signalReceived(process, startTime, event));
11
11
  });
12
12
  };
@@ -0,0 +1,2 @@
1
+ export declare function isTTY(process: NodeJS.Process): boolean;
2
+ //# sourceMappingURL=tty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tty.d.ts","sourceRoot":"","sources":["../../../src/utils/tty.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../../../tests/integration/cli.test.ts"],"names":[],"mappings":""}
@@ -4,7 +4,7 @@ import { resolve } from 'node:path';
4
4
  describe('CLI Integration', () => {
5
5
  describe('--help', () => {
6
6
  it('should display help information', () => {
7
- const result = execSync('yarn build && node ./dist/src/cli.js --help', {
7
+ const result = execSync('npm run build && node ./dist/src/cli.js --help', {
8
8
  encoding: 'utf-8',
9
9
  cwd: resolve(__dirname, '../..'),
10
10
  });
@@ -15,7 +15,7 @@ describe('CLI Integration', () => {
15
15
  });
16
16
  describe('--version', () => {
17
17
  it('should display version information', () => {
18
- const result = execSync('yarn build && node ./dist/src/cli.js --version', {
18
+ const result = execSync('npm run build && node ./dist/src/cli.js --version', {
19
19
  encoding: 'utf-8',
20
20
  cwd: resolve(__dirname, '../..'),
21
21
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=code-generator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-generator.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/code-generator.test.ts"],"names":[],"mappings":""}
@@ -1,10 +1,179 @@
1
- import { describe, expect, it } from 'vitest';
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
2
  import { TypeScriptCodeGeneratorService } from '../../src/services/code-generator.service.js';
3
3
  describe('TypeScriptCodeGeneratorService', () => {
4
4
  let generator;
5
5
  beforeEach(() => {
6
6
  generator = new TypeScriptCodeGeneratorService();
7
7
  });
8
+ describe('naming conventions', () => {
9
+ it('should apply camelCase naming convention', () => {
10
+ const spec = {
11
+ openapi: '3.0.0',
12
+ info: {
13
+ title: 'Test API',
14
+ version: '1.0.0',
15
+ },
16
+ paths: {
17
+ '/users': {
18
+ get: {
19
+ operationId: 'get_user_by_id',
20
+ responses: {
21
+ '200': {
22
+ description: 'Success',
23
+ content: {
24
+ 'application/json': {
25
+ schema: { type: 'string' },
26
+ },
27
+ },
28
+ },
29
+ },
30
+ },
31
+ },
32
+ },
33
+ };
34
+ const generatorWithConvention = new TypeScriptCodeGeneratorService({
35
+ namingConvention: 'camelCase',
36
+ });
37
+ const code = generatorWithConvention.generate(spec);
38
+ expect(code).toContain('async getUserById');
39
+ expect(code).not.toContain('async get_user_by_id');
40
+ });
41
+ it('should apply PascalCase naming convention', () => {
42
+ const spec = {
43
+ openapi: '3.0.0',
44
+ info: {
45
+ title: 'Test API',
46
+ version: '1.0.0',
47
+ },
48
+ paths: {
49
+ '/users': {
50
+ get: {
51
+ operationId: 'get_user_by_id',
52
+ responses: {
53
+ '200': {
54
+ description: 'Success',
55
+ content: {
56
+ 'application/json': {
57
+ schema: { type: 'string' },
58
+ },
59
+ },
60
+ },
61
+ },
62
+ },
63
+ },
64
+ },
65
+ };
66
+ const generatorWithConvention = new TypeScriptCodeGeneratorService({
67
+ namingConvention: 'PascalCase',
68
+ });
69
+ const code = generatorWithConvention.generate(spec);
70
+ expect(code).toContain('async GetUserById');
71
+ expect(code).not.toContain('async get_user_by_id');
72
+ });
73
+ it('should apply snake_case naming convention', () => {
74
+ const spec = {
75
+ openapi: '3.0.0',
76
+ info: {
77
+ title: 'Test API',
78
+ version: '1.0.0',
79
+ },
80
+ paths: {
81
+ '/users': {
82
+ get: {
83
+ operationId: 'getUserById',
84
+ responses: {
85
+ '200': {
86
+ description: 'Success',
87
+ content: {
88
+ 'application/json': {
89
+ schema: { type: 'string' },
90
+ },
91
+ },
92
+ },
93
+ },
94
+ },
95
+ },
96
+ },
97
+ };
98
+ const generatorWithConvention = new TypeScriptCodeGeneratorService({
99
+ namingConvention: 'snake_case',
100
+ });
101
+ const code = generatorWithConvention.generate(spec);
102
+ expect(code).toContain('async get_user_by_id');
103
+ expect(code).not.toContain('async getUserById');
104
+ });
105
+ it('should use custom transformer when provided', () => {
106
+ const spec = {
107
+ openapi: '3.0.0',
108
+ info: {
109
+ title: 'Test API',
110
+ version: '1.0.0',
111
+ },
112
+ paths: {
113
+ '/users/{id}': {
114
+ get: {
115
+ operationId: 'getUserById',
116
+ tags: ['users'],
117
+ summary: 'Get user',
118
+ responses: {
119
+ '200': {
120
+ description: 'Success',
121
+ content: {
122
+ 'application/json': {
123
+ schema: { type: 'string' },
124
+ },
125
+ },
126
+ },
127
+ },
128
+ },
129
+ },
130
+ },
131
+ };
132
+ const customTransformer = (details) => {
133
+ return `${details.method.toUpperCase()}_${details.tags?.[0] || 'default'}_${details.operationId}`;
134
+ };
135
+ const generatorWithTransformer = new TypeScriptCodeGeneratorService({
136
+ operationNameTransformer: customTransformer,
137
+ });
138
+ const code = generatorWithTransformer.generate(spec);
139
+ expect(code).toContain('async GET_users_getUserById');
140
+ });
141
+ it('should prioritize custom transformer over naming convention', () => {
142
+ const spec = {
143
+ openapi: '3.0.0',
144
+ info: {
145
+ title: 'Test API',
146
+ version: '1.0.0',
147
+ },
148
+ paths: {
149
+ '/users': {
150
+ get: {
151
+ operationId: 'get_user_by_id',
152
+ responses: {
153
+ '200': {
154
+ description: 'Success',
155
+ content: {
156
+ 'application/json': {
157
+ schema: { type: 'string' },
158
+ },
159
+ },
160
+ },
161
+ },
162
+ },
163
+ },
164
+ },
165
+ };
166
+ const customTransformer = () => 'customName';
167
+ const generatorWithBoth = new TypeScriptCodeGeneratorService({
168
+ namingConvention: 'PascalCase',
169
+ operationNameTransformer: customTransformer,
170
+ });
171
+ const code = generatorWithBoth.generate(spec);
172
+ expect(code).toContain('async customName');
173
+ expect(code).not.toContain('GetUserById');
174
+ expect(code).not.toContain('get_user_by_id');
175
+ });
176
+ });
8
177
  describe('generate', () => {
9
178
  it('should generate code for a minimal OpenAPI spec', () => {
10
179
  const spec = {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=file-reader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-reader.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/file-reader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/generator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=naming-convention.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming-convention.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/naming-convention.test.ts"],"names":[],"mappings":""}