api-core-lib 12.0.66 → 12.0.67

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 (2) hide show
  1. package/dist/cli.cjs +221 -141
  2. package/package.json +7 -4
package/dist/cli.cjs CHANGED
@@ -69,17 +69,42 @@ var import_path2 = __toESM(require("path"), 1);
69
69
  // src/generator/index.ts
70
70
  var import_fs = __toESM(require("fs"), 1);
71
71
  var import_path = __toESM(require("path"), 1);
72
+ var import_util = __toESM(require("util"), 1);
72
73
  var import_chalk = __toESM(require("chalk"), 1);
73
74
  var import_dotenv = __toESM(require("dotenv"), 1);
74
75
  var import_swagger_parser = __toESM(require("@apidevtools/swagger-parser"), 1);
75
76
  var import_openapi_types = __toESM(require_dist(), 1);
76
77
  var import_json_schema_to_typescript = require("json-schema-to-typescript");
78
+ var DEBUG_MODE = process.env.DEBUG === "true";
79
+ var debugLog = (title, data) => {
80
+ if (DEBUG_MODE) {
81
+ console.log(import_chalk.default.yellow(`
82
+ [DEBUG: ${title}]`));
83
+ console.log(import_util.default.inspect(data, { depth: null, colors: true }));
84
+ }
85
+ };
86
+ var toPascalCase = (str) => str.replace(/[^a-zA-Z0-9_]/g, " ").replace(/(?:^\w|[A-Z]|\b\w)/g, (w) => w.toUpperCase()).replace(/\s+/g, "");
87
+ var getModuleNameFromOpId = (opId) => `${opId.split("_")[0].replace(/Controller$/, "")}Api`;
88
+ var getActionNameFromOpId = (opId) => (opId.split("_")[1] || opId).replace(/^\w/, (c) => c.toLowerCase());
89
+ var findCommonBasePath = (paths) => {
90
+ if (!paths || paths.length === 0) return "/";
91
+ const sorted = [...paths].sort();
92
+ const first = sorted[0];
93
+ const last = sorted[sorted.length - 1];
94
+ let i = 0;
95
+ while (i < first.length && first.charAt(i) === last.charAt(i)) i++;
96
+ const prefix = first.substring(0, i);
97
+ return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
98
+ };
77
99
  function parseSpecToModules(spec) {
78
- const modules = {};
79
- const modulePaths = {};
80
- if (!spec.components) spec.components = {};
81
- if (!spec.components.schemas) spec.components.schemas = {};
82
- const allSchemas = spec.components.schemas;
100
+ const modules = /* @__PURE__ */ new Map();
101
+ const allSchemas = /* @__PURE__ */ new Map();
102
+ const modulePaths = /* @__PURE__ */ new Map();
103
+ if (spec.components?.schemas) {
104
+ for (const schemaName in spec.components.schemas) {
105
+ allSchemas.set(schemaName, { name: schemaName, schema: spec.components.schemas[schemaName] });
106
+ }
107
+ }
83
108
  for (const apiPath in spec.paths) {
84
109
  const pathItem = spec.paths[apiPath];
85
110
  if (!pathItem) continue;
@@ -87,206 +112,261 @@ function parseSpecToModules(spec) {
87
112
  if (!Object.values(import_openapi_types.OpenAPIV3.HttpMethods).includes(method)) continue;
88
113
  const endpoint = pathItem[method];
89
114
  if (!endpoint.operationId) continue;
90
- const moduleName = _getModuleNameFromOperationId(endpoint.operationId);
91
- if (!modules[moduleName]) {
92
- modules[moduleName] = { baseEndpoint: "", actions: {}, types: /* @__PURE__ */ new Set() };
93
- modulePaths[moduleName] = [];
115
+ const moduleName = getModuleNameFromOpId(endpoint.operationId);
116
+ if (!modules.has(moduleName)) {
117
+ modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set() });
118
+ modulePaths.set(moduleName, []);
94
119
  }
95
- modulePaths[moduleName].push(apiPath);
96
- const { inputType, outputType } = _extractInputOutputTypes(endpoint, allSchemas);
120
+ const currentModule = modules.get(moduleName);
121
+ modulePaths.get(moduleName).push(apiPath);
122
+ const { inputType, outputType } = _extractAndRegisterTypes(endpoint, allSchemas);
97
123
  [inputType, outputType].forEach((t) => {
98
- if (t && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(t)) {
99
- modules[moduleName].types.add(t.replace("[]", ""));
124
+ const cleanType = t.replace("[]", "");
125
+ if (cleanType && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(cleanType)) {
126
+ currentModule.schemas.add(cleanType);
100
127
  }
101
128
  });
102
- const actionName = _sanitizeActionName(endpoint.operationId);
103
- modules[moduleName].actions[actionName] = {
129
+ const actionName = getActionNameFromOpId(endpoint.operationId);
130
+ currentModule.actions[actionName] = {
104
131
  method: method.toUpperCase(),
105
132
  path: apiPath,
106
- // سنقوم بتعديل هذا لاحقًا ليصبح نسبيًا
107
133
  description: endpoint.summary || "",
108
134
  hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"),
109
135
  autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"),
110
- invalidates: [],
136
+ requiresAuth: !!endpoint.security && endpoint.security.length > 0,
111
137
  _inputType: inputType,
112
138
  _outputType: outputType
113
139
  };
140
+ debugLog("Parsed Action", { moduleName, actionName, ...currentModule.actions[actionName] });
114
141
  }
115
142
  }
116
- for (const moduleName in modules) {
117
- const basePath = _findCommonBasePath(modulePaths[moduleName]);
118
- modules[moduleName].baseEndpoint = basePath;
119
- for (const actionName in modules[moduleName].actions) {
120
- const action = modules[moduleName].actions[actionName];
143
+ modules.forEach((mod, name) => {
144
+ const basePath = findCommonBasePath(modulePaths.get(name));
145
+ mod.baseEndpoint = basePath;
146
+ Object.values(mod.actions).forEach((action) => {
121
147
  const relativePath = action.path.replace(basePath, "").replace(/^\//, "");
122
148
  action.path = relativePath === "" ? "/" : relativePath;
123
- }
124
- }
125
- return modules;
149
+ });
150
+ });
151
+ return { modules, allSchemas };
126
152
  }
127
- function _extractInputOutputTypes(endpoint, schemas) {
128
- const operationId = endpoint.operationId || "UnnamedOperation";
129
- const successResponseKey = Object.keys(endpoint.responses).find((code) => code.startsWith("2"));
130
- const successResponse = successResponseKey ? endpoint.responses[successResponseKey] : void 0;
131
- const responseSchema = successResponse?.content?.["application/json"]?.schema;
132
- const outputType = successResponseKey === "204" ? "void" : _schemaToTypeName(responseSchema, `${operationId}Response`, schemas);
133
- const requestBody = endpoint.requestBody;
134
- const requestSchema = requestBody?.content?.["application/json"]?.schema;
153
+ function _extractAndRegisterTypes(endpoint, allSchemas) {
154
+ const opId = endpoint.operationId || "Unnamed";
155
+ const successKey = Object.keys(endpoint.responses).find((c) => c.startsWith("2"));
156
+ const successRes = successKey ? endpoint.responses[successKey] : void 0;
157
+ const resSchema = successRes?.content?.["application/json"]?.schema;
158
+ const outputType = successKey === "204" ? "void" : _schemaToTypeName(resSchema, `${opId}Response`, allSchemas);
159
+ const reqBody = endpoint.requestBody;
160
+ const reqSchema = reqBody?.content?.["application/json"]?.schema;
135
161
  let inputType = "undefined";
136
- if (requestSchema) {
137
- inputType = _schemaToTypeName(requestSchema, `${operationId}Request`, schemas);
162
+ if (reqSchema) {
163
+ inputType = _schemaToTypeName(reqSchema, `${opId}Request`, allSchemas);
138
164
  } else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
139
165
  inputType = "QueryOptions";
140
166
  }
141
167
  return { inputType, outputType };
142
168
  }
143
- function _schemaToTypeName(schema, name, schemas) {
169
+ function _schemaToTypeName(schema, name, allSchemas) {
144
170
  if (!schema) return "unknown";
145
171
  if (schema.type === "array" && schema.items) {
146
- const itemTypeName = _schemaToTypeName(schema.items, `${name}Item`, schemas);
172
+ const itemTypeName = _schemaToTypeName(schema.items, `${name}Item`, allSchemas);
147
173
  return `${itemTypeName}[]`;
148
174
  }
149
- if (schema.type === "object" || schema.properties || schema.allOf) {
150
- const typeName = _toPascalCase(name);
151
- if (!schemas[typeName]) {
152
- schemas[typeName] = schema;
175
+ if (schema.type === "object" || schema.properties || schema.allOf || !schema.type) {
176
+ const typeName = toPascalCase(name);
177
+ if (!allSchemas.has(typeName)) {
178
+ debugLog("Registering new inline schema", { assignedName: typeName, originalSchema: schema });
179
+ allSchemas.set(typeName, { name: typeName, schema });
153
180
  }
154
181
  return typeName;
155
182
  }
156
183
  if (schema.type && ["string", "number", "boolean", "integer"].includes(schema.type)) {
157
184
  return schema.type === "integer" ? "number" : schema.type;
158
185
  }
159
- if (Object.keys(schema).length === 0) {
160
- const typeName = _toPascalCase(name);
161
- if (!schemas[typeName]) {
162
- schemas[typeName] = { type: "object", properties: {}, description: "Represents a dynamic or empty object." };
163
- }
164
- return typeName;
165
- }
166
186
  return "unknown";
167
187
  }
168
- async function generateModuleFiles(moduleName, moduleData, allSchemas, outputDir) {
169
- console.log(import_chalk.default.gray(` Generating files for module: ${import_chalk.default.bold(moduleName)}...`));
170
- const moduleFolderPath = import_path.default.join(outputDir, moduleName);
171
- if (!import_fs.default.existsSync(moduleFolderPath)) import_fs.default.mkdirSync(moduleFolderPath, { recursive: true });
172
- await _generateTypesFile(moduleFolderPath, moduleName, moduleData.types, allSchemas);
173
- await _generateConfigFile(moduleFolderPath, moduleName, moduleData);
174
- }
175
- async function _generateTypesFile(moduleFolderPath, moduleName, typeNames, allSchemas) {
176
- if (typeNames.size === 0) {
177
- console.log(import_chalk.default.yellow(` - No types for module "${moduleName}". Skipping types.ts.`));
178
- return;
179
- }
180
- console.log(import_chalk.default.gray(` - Generating types.ts with ${typeNames.size} types...`));
181
- let typesContent = `// This file is auto-generated by the API generator. Do not edit.
188
+ async function generateModuleFiles(module2, allSchemas, outputDir) {
189
+ const moduleName = module2.moduleName;
190
+ const moduleOutputPath = import_path.default.join(outputDir, moduleName);
191
+ if (!import_fs.default.existsSync(moduleOutputPath)) import_fs.default.mkdirSync(moduleOutputPath, { recursive: true });
192
+ console.log(import_chalk.default.cyan(`
193
+ Generating module: ${import_chalk.default.bold(moduleName)}`));
194
+ const typesToImport = [...module2.schemas].sort();
195
+ let configContent = `/* eslint-disable */
196
+ // This file is auto-generated.
182
197
 
198
+ import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
183
199
  `;
184
- const compilationOptions = {
185
- bannerComment: "",
186
- style: { bracketSpacing: true, printWidth: 120, semi: true, singleQuote: true, tabWidth: 2, trailingComma: "es5", useTabs: false },
187
- additionalProperties: false
188
- };
189
- for (const typeName of Array.from(typeNames).sort()) {
190
- const schema = allSchemas[typeName];
191
- if (schema) {
200
+ if (typesToImport.length > 0) configContent += `import type { ${typesToImport.join(", ")} } from './types';
201
+ `;
202
+ const actionsType = Object.values(module2.actions).map((a) => ` ${getActionNameFromOpId(a.path)}: ActionConfigModule<${a._inputType}, ${a._outputType}>;`).join("\n");
203
+ const actionsValue = Object.values(module2.actions).map((a) => {
204
+ const { _inputType, _outputType, ...config } = a;
205
+ return ` ${getActionNameFromOpId(a.path)}: ${JSON.stringify(config, null, 2).replace(/\n/g, "\n ")}`;
206
+ }).join(",\n");
207
+ configContent += `
208
+ export const ${moduleName}Module: ApiModuleConfig<{
209
+ ${actionsType}
210
+ }> = {
211
+ baseEndpoint: '${module2.baseEndpoint}',
212
+ actions: {
213
+ ${actionsValue}
214
+ },
215
+ };
216
+ `;
217
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "config.ts"), configContent.trim(), { encoding: "utf-8" });
218
+ console.log(import_chalk.default.gray(` \u2713 config.ts`));
219
+ if (typesToImport.length === 0) return;
220
+ let typesContent = `// This file is auto-generated.
221
+
222
+ `;
223
+ const tsOptions = { bannerComment: "", style: { bracketSpacing: true, printWidth: 120, semi: true, singleQuote: true, tabWidth: 2 }, additionalProperties: false };
224
+ for (const typeName of typesToImport) {
225
+ const parsedSchema = allSchemas.get(typeName);
226
+ if (parsedSchema) {
192
227
  try {
193
- const tsType = await (0, import_json_schema_to_typescript.compile)(schema, typeName, compilationOptions);
228
+ const tsType = await (0, import_json_schema_to_typescript.compile)(parsedSchema.schema, typeName, tsOptions);
194
229
  typesContent += tsType + "\n";
195
- } catch (compileError) {
196
- console.error(import_chalk.default.red(` - Error compiling type "${typeName}": ${compileError.message}`));
230
+ } catch (e) {
231
+ console.error(import_chalk.default.red(` - Error compiling type "${typeName}": ${e.message}`));
197
232
  }
198
- } else {
199
- console.log(import_chalk.default.yellow(` - Warning: Schema for type "${typeName}" not found.`));
200
233
  }
201
234
  }
202
- const typesFilePath = import_path.default.join(moduleFolderPath, "types.ts");
203
- import_fs.default.writeFileSync(typesFilePath, typesContent, { encoding: "utf-8" });
204
- }
205
- async function _generateConfigFile(moduleFolderPath, moduleName, moduleData) {
206
- const actionsCount = Object.keys(moduleData.actions).length;
207
- console.log(import_chalk.default.gray(` - Generating config.ts with ${actionsCount} actions...`));
208
- const typeNamesArray = [...moduleData.types].sort();
209
- const typesImportStatement = typeNamesArray.length > 0 ? `import type { ${typeNamesArray.join(", ")} } from './types';` : ``;
210
- const actionsTypeParts = Object.entries(moduleData.actions).map(
211
- ([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`
212
- );
213
- const actionsTypeDefinition = `{
214
- ${actionsTypeParts.join("\n")}
215
- }`;
216
- const actionsValueParts = Object.entries(moduleData.actions).map(([actionName, actionData]) => {
217
- const { _inputType, _outputType, ...config } = actionData;
218
- return ` ${actionName}: ${JSON.stringify(config, null, 2).replace(/\n/g, "\n ")}`;
219
- });
220
- const actionsValueDefinition = `{
221
- ${actionsValueParts.join(",\n")}
222
- }`;
223
- const configContent = `/* eslint-disable */
224
- // This file is auto-generated...
235
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "types.ts"), typesContent, { encoding: "utf-8" });
236
+ console.log(import_chalk.default.gray(` \u2713 types.ts`));
237
+ let validationContent = `// This file is auto-generated.
238
+ import { z } from 'zod';
225
239
 
226
- import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
227
- ${typesImportStatement}
240
+ `;
241
+ for (const typeName of typesToImport) {
242
+ const parsedSchema = allSchemas.get(typeName);
243
+ if (parsedSchema?.schema.type === "object") {
244
+ validationContent += `export const ${typeName}Schema = ${_schemaToZod(parsedSchema.schema)};
228
245
 
229
- export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
230
- baseEndpoint: '${moduleData.baseEndpoint}',
231
- actions: ${actionsValueDefinition},
232
- };
233
246
  `;
234
- const configFilePath = import_path.default.join(moduleFolderPath, "config.ts");
235
- import_fs.default.writeFileSync(configFilePath, configContent.trim(), { encoding: "utf-8" });
236
- }
237
- function _toPascalCase(str) {
238
- return str.replace(/[^a-zA-Z0-9]/g, " ").replace(/(?:^\w|[A-Z]|\b\w)/g, (w) => w.toUpperCase()).replace(/\s+/g, "");
247
+ }
248
+ }
249
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "validation.ts"), validationContent, { encoding: "utf-8" });
250
+ console.log(import_chalk.default.gray(` \u2713 validation.ts`));
251
+ let mocksContent = `// This file is auto-generated.
252
+ import type { ${typesToImport.join(", ")} } from './types';
253
+
254
+ `;
255
+ for (const typeName of typesToImport) {
256
+ const parsedSchema = allSchemas.get(typeName);
257
+ if (parsedSchema) {
258
+ mocksContent += `export const mock${typeName}: ${typeName} = ${JSON.stringify(_schemaToMock(parsedSchema.schema), null, 2)};
259
+
260
+ `;
261
+ }
262
+ }
263
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "mocks.ts"), mocksContent, { encoding: "utf-8" });
264
+ console.log(import_chalk.default.gray(` \u2713 mocks.ts`));
265
+ let indexContent = `// This file is auto-generated.
266
+
267
+ export * from './config';
268
+ export * from './types';
269
+ export * from './validation';
270
+ export * from './mocks';
271
+ `;
272
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent, { encoding: "utf-8" });
273
+ console.log(import_chalk.default.gray(` \u2713 index.ts`));
239
274
  }
240
- function _getModuleNameFromOperationId(operationId) {
241
- const controllerName = operationId.split("_")[0].replace(/Controller$/, "");
242
- return `${controllerName}Api`;
275
+ function _schemaToZod(schema) {
276
+ const shape = [];
277
+ if (schema.properties) {
278
+ for (const [key, prop] of Object.entries(schema.properties)) {
279
+ shape.push(` ${key}: ${_propToZod(prop, (schema.required || []).includes(key))}`);
280
+ }
281
+ }
282
+ return `z.object({
283
+ ${shape.join(",\n")}
284
+ })`;
243
285
  }
244
- function _sanitizeActionName(operationId) {
245
- const nameParts = operationId.split("_");
246
- if (nameParts.length <= 1) return operationId;
247
- const actionPart = nameParts[1];
248
- return actionPart.charAt(0).toLowerCase() + actionPart.slice(1);
286
+ function _propToZod(prop, isRequired) {
287
+ let zodString = "z.any()";
288
+ switch (prop.type) {
289
+ case "string":
290
+ zodString = "z.string()";
291
+ if (prop.format === "email") zodString += ".email()";
292
+ if (prop.format === "uuid") zodString += ".uuid()";
293
+ if (prop.enum) zodString = `z.enum(${JSON.stringify(prop.enum)})`;
294
+ break;
295
+ case "integer":
296
+ case "number":
297
+ zodString = "z.number()";
298
+ if (prop.minimum !== void 0) zodString += `.min(${prop.minimum})`;
299
+ if (prop.maximum !== void 0) zodString += `.max(${prop.maximum})`;
300
+ break;
301
+ case "boolean":
302
+ zodString = "z.boolean()";
303
+ break;
304
+ case "array":
305
+ zodString = `z.array(${prop.items ? _propToZod(prop.items, true) : "z.any()"})`;
306
+ break;
307
+ case "object":
308
+ zodString = _schemaToZod(prop);
309
+ break;
310
+ }
311
+ return isRequired ? zodString : `${zodString}.optional().nullable()`;
249
312
  }
250
- function _findCommonBasePath(paths) {
251
- if (!paths || paths.length === 0) return "/";
252
- const sortedPaths = [...paths].sort();
253
- const first = sortedPaths[0];
254
- const last = sortedPaths[sortedPaths.length - 1];
255
- let i = 0;
256
- while (i < first.length && first.charAt(i) === last.charAt(i)) {
257
- i++;
313
+ function _schemaToMock(schema) {
314
+ if (schema.example) return schema.example;
315
+ switch (schema.type) {
316
+ case "string":
317
+ if (schema.format === "email") return "test@example.com";
318
+ if (schema.format === "uuid") return "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11";
319
+ if (schema.enum) return schema.enum[0];
320
+ return "Mock String";
321
+ case "integer":
322
+ case "number":
323
+ return 1;
324
+ case "boolean":
325
+ return true;
326
+ case "array":
327
+ return schema.items ? [_schemaToMock(schema.items)] : [];
328
+ case "object":
329
+ const mock = {};
330
+ if (schema.properties) {
331
+ for (const [key, prop] of Object.entries(schema.properties)) {
332
+ mock[key] = _schemaToMock(prop);
333
+ }
334
+ }
335
+ return mock;
336
+ default:
337
+ return null;
258
338
  }
259
- let prefix = first.substring(0, i);
260
- return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
261
339
  }
262
- async function runGenerator(options) {
263
- console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Core Lib Code Generator..."));
340
+ async function runGenerator() {
341
+ const options = {
342
+ output: "src/lib/api",
343
+ envPath: ".env"
344
+ };
345
+ console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator..."));
264
346
  import_dotenv.default.config({ path: options.envPath });
265
347
  const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
266
348
  console.log(import_chalk.default.blue("\u2713 Step 1: Environment variables loaded."));
267
349
  try {
268
350
  console.log(import_chalk.default.blue(`
269
351
  \u23F3 Step 2: Fetching and fully dereferencing spec from ${specUrl}...`));
270
- const dereferencedSpec = await import_swagger_parser.default.dereference(specUrl);
352
+ const spec = await import_swagger_parser.default.dereference(specUrl);
271
353
  console.log(import_chalk.default.green("\u2713 Spec fetched and fully dereferenced successfully."));
354
+ debugLog("Dereferenced Spec", spec);
272
355
  console.log(import_chalk.default.blue("\n\u23F3 Step 3: Parsing spec using intelligent grouping..."));
273
- const modules = parseSpecToModules(dereferencedSpec);
274
- const modulesCount = Object.keys(modules).length;
275
- console.log(import_chalk.default.green(`\u2713 Found and grouped ${modulesCount} logical modules.`));
276
- console.log(import_chalk.default.blue("\n\u23F3 Step 4: Generating module files..."));
277
- const modulesOutputPath = import_path.default.join(options.output, "modules");
278
- const allSchemas = dereferencedSpec.components?.schemas || {};
279
- for (const moduleName in modules) {
280
- const moduleData = modules[moduleName];
281
- await generateModuleFiles(moduleName, moduleData, allSchemas, modulesOutputPath);
356
+ const { modules, allSchemas } = parseSpecToModules(spec);
357
+ console.log(import_chalk.default.green(`\u2713 Found and grouped ${modules.size} logical modules.`));
358
+ debugLog("Parsed Modules", Object.fromEntries(modules));
359
+ console.log(import_chalk.default.blue("\n\u23F3 Step 4: Generating all module files..."));
360
+ for (const module2 of modules.values()) {
361
+ await generateModuleFiles(module2, allSchemas, options.output);
282
362
  }
283
- console.log(import_chalk.default.green("\u2713 All module files generated."));
363
+ console.log(import_chalk.default.green("\n\u2713 All module files generated successfully."));
284
364
  console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!"));
285
365
  console.log(import_chalk.default.bold.cyan(` Output directory: ${options.output}`));
286
366
  } catch (error) {
287
367
  console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
288
368
  console.error(import_chalk.default.red(`Error Message: ${error.message}`));
289
- if (error.stack) console.error(import_chalk.default.gray(error.stack));
369
+ if (error.stack && DEBUG_MODE) console.error(import_chalk.default.gray(error.stack));
290
370
  process.exit(1);
291
371
  }
292
372
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-core-lib",
3
- "version": "12.0.66",
3
+ "version": "12.0.67",
4
4
  "description": "A flexible and powerful API client library for modern web applications.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -42,24 +42,27 @@
42
42
  "chalk": "^4.1.2",
43
43
  "colorette": "^2.0.20",
44
44
  "commander": "^9.4.1",
45
- "dotenv": "^16.0.3",
45
+ "dotenv": "^16.6.1",
46
46
  "fast-deep-equal": "^3.1.3",
47
47
  "fs-extra": "^11.3.1",
48
48
  "json-schema-to-typescript": "^15.0.4",
49
49
  "openapi-typescript": "^6.2.4",
50
50
  "openapi-typescript-codegen": "^0.29.0",
51
51
  "path": "^0.12.7",
52
- "uuid": "^9.0.1"
52
+ "swagger-parser": "^10.0.3",
53
+ "uuid": "^9.0.1",
54
+ "zod": "^4.1.5"
53
55
  },
54
56
  "devDependencies": {
55
57
  "@openapitools/openapi-generator-cli": "^2.23.1",
56
58
  "@types/fs-extra": "^11.0.4",
57
59
  "@types/jest": "^30.0.0",
58
- "@types/node": "^24.2.1",
60
+ "@types/node": "^24.3.0",
59
61
  "@types/react": "^18.3.2",
60
62
  "@types/uuid": "^9.0.8",
61
63
  "javascript-obfuscator": "^4.1.1",
62
64
  "jest": "^30.0.5",
65
+ "openapi-types": "^12.1.3",
63
66
  "react": "19.1.0",
64
67
  "react-dom": "19.1.0",
65
68
  "ts-jest": "^29.4.1",