api-core-lib 12.0.66 → 12.0.68

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 +264 -175
  2. package/package.json +7 -4
package/dist/cli.cjs CHANGED
@@ -69,17 +69,82 @@ 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
- var import_json_schema_to_typescript = require("json-schema-to-typescript");
77
+ var DEBUG_MODE = process.env.DEBUG === "true";
78
+ var debugLog = (title, data) => DEBUG_MODE && console.log(import_chalk.default.yellow(`
79
+ [DEBUG: ${title}]`), import_util.default.inspect(data, { depth: 4, colors: true }));
80
+ var toPascalCase = (str) => str.replace(/[^a-zA-Z0-9_]/g, " ").replace(/(?:^\w|[A-Z]|\b\w)/g, (w) => w.toUpperCase()).replace(/\s+/g, "");
81
+ var toCamelCase = (str) => {
82
+ const s = toPascalCase(str);
83
+ return s.charAt(0).toLowerCase() + s.slice(1);
84
+ };
85
+ var getModuleName = (opId) => `${opId.split("_")[0].replace(/Controller$/, "")}Api`;
86
+ var getActionName = (opId) => toCamelCase(opId.split("_")[1] || opId);
87
+ var findCommonPath = (paths) => {
88
+ if (!paths || paths.length === 0) return "/";
89
+ const sorted = [...paths].sort();
90
+ const first = sorted[0];
91
+ const last = sorted[sorted.length - 1];
92
+ let i = 0;
93
+ while (i < first.length && first.charAt(i) === last.charAt(i)) i++;
94
+ const prefix = first.substring(0, i);
95
+ return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
96
+ };
97
+ var generateFriendlyMessage = (fieldName, validation) => {
98
+ const friendlyName = fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
99
+ switch (validation) {
100
+ case "required":
101
+ return `${friendlyName} is required.`;
102
+ case "email":
103
+ return `Please enter a valid email for ${friendlyName}.`;
104
+ default:
105
+ return `Invalid value for ${friendlyName}.`;
106
+ }
107
+ };
108
+ function parseSchema(name, schema) {
109
+ const properties = [];
110
+ if (schema.properties) {
111
+ for (const propName in schema.properties) {
112
+ const propSchema = schema.properties[propName];
113
+ let items = void 0;
114
+ if (propSchema.type === "array" && propSchema.items) {
115
+ items = parseSchema("item", propSchema.items).properties[0];
116
+ }
117
+ properties.push({
118
+ name: propName,
119
+ type: propSchema.type || "object",
120
+ isRequired: (schema.required || []).includes(propName),
121
+ isNullable: propSchema.nullable || false,
122
+ description: propSchema.description,
123
+ example: propSchema.example,
124
+ enum: propSchema.enum,
125
+ format: propSchema.format,
126
+ items,
127
+ // نستخدم المتغير الذي تم حسابه بأمان
128
+ properties: propSchema.properties ? parseSchema("sub-object", propSchema).properties : void 0
129
+ });
130
+ }
131
+ }
132
+ return { name, description: schema.description, properties };
133
+ }
77
134
  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;
135
+ const modules = /* @__PURE__ */ new Map();
136
+ const allSchemas = /* @__PURE__ */ new Map();
137
+ const modulePaths = /* @__PURE__ */ new Map();
138
+ const registerSchema = (schema, baseName) => {
139
+ if (!schema) return "unknown";
140
+ if (schema.type === "array" && schema.items) return `${registerSchema(schema.items, `${baseName}Item`)}[]`;
141
+ if (schema.type === "object" || schema.properties || schema.allOf || !schema.type) {
142
+ const typeName = toPascalCase(baseName.replace(/_v\d+(Request|Response)$/, "$1"));
143
+ if (!allSchemas.has(typeName)) allSchemas.set(typeName, parseSchema(typeName, schema));
144
+ return typeName;
145
+ }
146
+ return schema.type === "integer" ? "number" : schema.type || "unknown";
147
+ };
83
148
  for (const apiPath in spec.paths) {
84
149
  const pathItem = spec.paths[apiPath];
85
150
  if (!pathItem) continue;
@@ -87,206 +152,230 @@ function parseSpecToModules(spec) {
87
152
  if (!Object.values(import_openapi_types.OpenAPIV3.HttpMethods).includes(method)) continue;
88
153
  const endpoint = pathItem[method];
89
154
  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] = [];
155
+ const moduleName = getModuleName(endpoint.operationId);
156
+ if (!modules.has(moduleName)) {
157
+ modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set() });
158
+ modulePaths.set(moduleName, []);
94
159
  }
95
- modulePaths[moduleName].push(apiPath);
96
- const { inputType, outputType } = _extractInputOutputTypes(endpoint, allSchemas);
160
+ const currentModule = modules.get(moduleName);
161
+ modulePaths.get(moduleName).push(apiPath);
162
+ const successKey = Object.keys(endpoint.responses).find((c) => c.startsWith("2"));
163
+ const successRes = successKey ? endpoint.responses[successKey] : void 0;
164
+ const outputType = successKey === "204" ? "void" : registerSchema(successRes?.content?.["application/json"]?.schema, `${endpoint.operationId}Response`);
165
+ const reqBody = endpoint.requestBody;
166
+ let inputType = "undefined";
167
+ if (reqBody?.content?.["application/json"]?.schema) inputType = registerSchema(reqBody.content["application/json"].schema, `${endpoint.operationId}Request`);
168
+ else if ((endpoint.parameters || []).some((p) => p.in === "query")) inputType = "QueryOptions";
97
169
  [inputType, outputType].forEach((t) => {
98
- if (t && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(t)) {
99
- modules[moduleName].types.add(t.replace("[]", ""));
170
+ const cleanType = t.replace("[]", "");
171
+ if (cleanType && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(cleanType)) {
172
+ currentModule.schemas.add(cleanType);
100
173
  }
101
174
  });
102
- const actionName = _sanitizeActionName(endpoint.operationId);
103
- modules[moduleName].actions[actionName] = {
104
- method: method.toUpperCase(),
105
- path: apiPath,
106
- // سنقوم بتعديل هذا لاحقًا ليصبح نسبيًا
107
- description: endpoint.summary || "",
108
- hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"),
109
- autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"),
110
- invalidates: [],
111
- _inputType: inputType,
112
- _outputType: outputType
113
- };
175
+ const actionName = getActionName(endpoint.operationId);
176
+ currentModule.actions[actionName] = { name: actionName, method: method.toUpperCase(), path: apiPath, description: endpoint.summary || "", hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"), autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"), requiresAuth: !!endpoint.security && endpoint.security.length > 0, inputType, outputType };
114
177
  }
115
178
  }
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];
179
+ modules.forEach((mod, name) => {
180
+ const basePath = findCommonPath(modulePaths.get(name));
181
+ mod.baseEndpoint = basePath;
182
+ Object.values(mod.actions).forEach((action) => {
121
183
  const relativePath = action.path.replace(basePath, "").replace(/^\//, "");
122
184
  action.path = relativePath === "" ? "/" : relativePath;
123
- }
124
- }
125
- return modules;
126
- }
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;
135
- let inputType = "undefined";
136
- if (requestSchema) {
137
- inputType = _schemaToTypeName(requestSchema, `${operationId}Request`, schemas);
138
- } else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
139
- inputType = "QueryOptions";
140
- }
141
- return { inputType, outputType };
185
+ });
186
+ });
187
+ debugLog("Final Parsed Modules", Object.fromEntries(modules));
188
+ return { modules, allSchemas };
142
189
  }
143
- function _schemaToTypeName(schema, name, schemas) {
144
- if (!schema) return "unknown";
145
- if (schema.type === "array" && schema.items) {
146
- const itemTypeName = _schemaToTypeName(schema.items, `${name}Item`, schemas);
147
- return `${itemTypeName}[]`;
148
- }
149
- if (schema.type === "object" || schema.properties || schema.allOf) {
150
- const typeName = _toPascalCase(name);
151
- if (!schemas[typeName]) {
152
- schemas[typeName] = schema;
153
- }
154
- return typeName;
155
- }
156
- if (schema.type && ["string", "number", "boolean", "integer"].includes(schema.type)) {
157
- return schema.type === "integer" ? "number" : schema.type;
158
- }
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." };
190
+ async function generateModuleFiles(module2, allSchemas, outputDir) {
191
+ const moduleOutputPath = import_path.default.join(outputDir, module2.moduleName);
192
+ if (!import_fs.default.existsSync(moduleOutputPath)) import_fs.default.mkdirSync(moduleOutputPath, { recursive: true });
193
+ console.log(import_chalk.default.cyan(`
194
+ Generating module: ${import_chalk.default.bold(module2.moduleName)}`));
195
+ const typesToImport = [...module2.schemas].sort();
196
+ let configContent = `/* eslint-disable */
197
+ // This file is auto-generated.
198
+
199
+ import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
200
+ `;
201
+ if (typesToImport.length > 0) configContent += `import type { ${typesToImport.join(", ")} } from './types';
202
+ `;
203
+ const actionsType = Object.values(module2.actions).map((a) => ` ${a.name}: ActionConfigModule<${a.inputType}, ${a.outputType}>;`).join("\n");
204
+ const actionsValue = Object.values(module2.actions).map((a) => {
205
+ const { inputType, outputType, name, ...c } = a;
206
+ return ` ${name}: ${JSON.stringify(c, null, 2).replace(/\n/g, "\n ")}`;
207
+ }).join(",\n");
208
+ configContent += `
209
+ export const ${module2.moduleName}Module: ApiModuleConfig<{
210
+ ${actionsType}
211
+ }> = {
212
+ baseEndpoint: '${module2.baseEndpoint}',
213
+ actions: {
214
+ ${actionsValue}
215
+ },
216
+ };
217
+ `;
218
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "config.ts"), configContent.trim());
219
+ console.log(import_chalk.default.gray(` \u2713 config.ts`));
220
+ const indexContent = [`// This file is auto-generated.
221
+
222
+ export * from './config';`];
223
+ if (typesToImport.length > 0) {
224
+ let typesContent = `// This file is auto-generated.
225
+
226
+ `;
227
+ for (const typeName of typesToImport) {
228
+ const parsedSchema = allSchemas.get(typeName);
229
+ if (parsedSchema) {
230
+ if (parsedSchema.description) typesContent += `/**
231
+ * ${parsedSchema.description}
232
+ */
233
+ `;
234
+ typesContent += `export interface ${typeName} {
235
+ `;
236
+ for (const prop of parsedSchema.properties) {
237
+ if (prop.description) typesContent += ` /**
238
+ * ${prop.description}
239
+ ${prop.example ? ` * @example ${JSON.stringify(prop.example)}
240
+ ` : ""} */
241
+ `;
242
+ let propType = prop.type;
243
+ if (prop.enum) propType = prop.enum.map((e) => typeof e === "string" ? `'${e}'` : e).join(" | ");
244
+ else if (prop.items) propType = `${toPascalCase(prop.items.name)}[]`;
245
+ typesContent += ` ${prop.name}${prop.isRequired ? "" : "?"}: ${propType};
246
+ `;
247
+ }
248
+ typesContent += `}
249
+
250
+ `;
251
+ }
163
252
  }
164
- return typeName;
165
- }
166
- return "unknown";
167
- }
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.
253
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "types.ts"), typesContent);
254
+ console.log(import_chalk.default.gray(` \u2713 types.ts`));
255
+ indexContent.push(`export * from './types';`);
256
+ let validationContent = `// This file is auto-generated.
257
+ import { z } from 'zod';
258
+
259
+ `;
260
+ for (const typeName of typesToImport) {
261
+ const parsedSchema = allSchemas.get(typeName);
262
+ if (parsedSchema) {
263
+ let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
264
+ validationContent += `export const ${typeName}Schema = z.object({
265
+ ${zodShape}
266
+ });
182
267
 
183
268
  `;
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) {
192
- try {
193
- const tsType = await (0, import_json_schema_to_typescript.compile)(schema, typeName, compilationOptions);
194
- typesContent += tsType + "\n";
195
- } catch (compileError) {
196
- console.error(import_chalk.default.red(` - Error compiling type "${typeName}": ${compileError.message}`));
197
269
  }
198
- } else {
199
- console.log(import_chalk.default.yellow(` - Warning: Schema for type "${typeName}" not found.`));
200
270
  }
201
- }
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...
271
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "validation.ts"), validationContent);
272
+ console.log(import_chalk.default.gray(` \u2713 validation.ts`));
273
+ indexContent.push(`export * from './validation';`);
274
+ let mocksContent = `// This file is auto-generated.
275
+ import type { ${typesToImport.join(", ")} } from './types';
225
276
 
226
- import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
227
- ${typesImportStatement}
277
+ `;
278
+ for (const typeName of typesToImport) {
279
+ const parsedSchema = allSchemas.get(typeName);
280
+ if (parsedSchema) {
281
+ let mockObject = {};
282
+ parsedSchema.properties.forEach((p) => {
283
+ mockObject[p.name] = _propToMock(p);
284
+ });
285
+ mocksContent += `export const mock${typeName}: ${typeName} = ${JSON.stringify(mockObject, null, 2)};
228
286
 
229
- export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
230
- baseEndpoint: '${moduleData.baseEndpoint}',
231
- actions: ${actionsValueDefinition},
232
- };
233
287
  `;
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, "");
239
- }
240
- function _getModuleNameFromOperationId(operationId) {
241
- const controllerName = operationId.split("_")[0].replace(/Controller$/, "");
242
- return `${controllerName}Api`;
288
+ }
289
+ }
290
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "mocks.ts"), mocksContent);
291
+ console.log(import_chalk.default.gray(` \u2713 mocks.ts`));
292
+ indexContent.push(`export * from './mocks';`);
293
+ }
294
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent.join("\n"));
295
+ console.log(import_chalk.default.gray(` \u2713 index.ts`));
243
296
  }
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);
297
+ function _propToZod(prop) {
298
+ let zodString = "z.any()";
299
+ const requiredMsg = { required_error: prop.description || generateFriendlyMessage(prop.name, "required") };
300
+ switch (prop.type) {
301
+ case "string":
302
+ zodString = `z.string(${JSON.stringify(requiredMsg)})`;
303
+ if (prop.format === "email") zodString += `.email({ message: "${generateFriendlyMessage(prop.name, "email")}" })`;
304
+ if (prop.format === "uuid") zodString += `.uuid()`;
305
+ if (prop.enum) zodString = `z.enum(${JSON.stringify(prop.enum)}, ${JSON.stringify(requiredMsg)})`;
306
+ break;
307
+ case "integer":
308
+ case "number":
309
+ zodString = `z.number(${JSON.stringify(requiredMsg)})`;
310
+ break;
311
+ case "boolean":
312
+ zodString = `z.boolean(${JSON.stringify(requiredMsg)})`;
313
+ break;
314
+ case "array":
315
+ zodString = `z.array(${prop.items ? _propToZod(prop.items) : "z.any()"})`;
316
+ break;
317
+ case "object":
318
+ let shape = "z.any()";
319
+ if (prop.properties) shape = `z.object({
320
+ ${prop.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n")}
321
+ })`;
322
+ zodString = shape;
323
+ break;
324
+ }
325
+ if (!prop.isRequired) zodString += ".optional()";
326
+ if (prop.isNullable) zodString += ".nullable()";
327
+ return zodString;
249
328
  }
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++;
329
+ function _propToMock(prop) {
330
+ if (prop.example) return prop.example;
331
+ if (prop.name.match(/image|avatar|logo|url/i)) return "https://via.placeholder.com/150";
332
+ if (prop.enum) return prop.enum[0];
333
+ switch (prop.type) {
334
+ case "string":
335
+ if (prop.format === "email") return "test@example.com";
336
+ if (prop.format === "uuid") return "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11";
337
+ return `Mock ${toPascalCase(prop.name)}`;
338
+ case "integer":
339
+ case "number":
340
+ return 1;
341
+ case "boolean":
342
+ return true;
343
+ case "array":
344
+ return prop.items ? [_propToMock(prop.items)] : [];
345
+ case "object":
346
+ const mock = {};
347
+ if (prop.properties) prop.properties.forEach((p) => {
348
+ mock[p.name] = _propToMock(p);
349
+ });
350
+ return mock;
351
+ default:
352
+ return null;
258
353
  }
259
- let prefix = first.substring(0, i);
260
- return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
261
354
  }
262
355
  async function runGenerator(options) {
263
- console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Core Lib Code Generator..."));
356
+ console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (Phoenix Edition)..."));
264
357
  import_dotenv.default.config({ path: options.envPath });
265
358
  const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
266
- console.log(import_chalk.default.blue("\u2713 Step 1: Environment variables loaded."));
267
359
  try {
268
360
  console.log(import_chalk.default.blue(`
269
- \u23F3 Step 2: Fetching and fully dereferencing spec from ${specUrl}...`));
270
- const dereferencedSpec = await import_swagger_parser.default.dereference(specUrl);
271
- console.log(import_chalk.default.green("\u2713 Spec fetched and fully dereferenced successfully."));
272
- 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);
361
+ \u23F3 Step 1: Dereferencing spec from ${specUrl}...`));
362
+ const spec = await import_swagger_parser.default.dereference(specUrl);
363
+ console.log(import_chalk.default.green("\u2713 Spec fully dereferenced."));
364
+ debugLog("Dereferenced Spec", spec);
365
+ console.log(import_chalk.default.blue("\n\u23F3 Step 2: Parsing spec with intelligent grouping..."));
366
+ const { modules, allSchemas } = parseSpecToModules(spec);
367
+ console.log(import_chalk.default.green(`\u2713 Found and grouped ${modules.size} logical modules.`));
368
+ console.log(import_chalk.default.blue("\n\u23F3 Step 3: Generating all module files..."));
369
+ for (const module2 of modules.values()) {
370
+ await generateModuleFiles(module2, allSchemas, options.output);
282
371
  }
283
- console.log(import_chalk.default.green("\u2713 All module files generated."));
284
- console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!"));
372
+ console.log(import_chalk.default.green("\n\u2713 All module files generated successfully."));
373
+ console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete! Your development platform is ready."));
285
374
  console.log(import_chalk.default.bold.cyan(` Output directory: ${options.output}`));
286
375
  } catch (error) {
287
376
  console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
288
377
  console.error(import_chalk.default.red(`Error Message: ${error.message}`));
289
- if (error.stack) console.error(import_chalk.default.gray(error.stack));
378
+ if (error.stack && DEBUG_MODE) console.error(import_chalk.default.gray(error.stack));
290
379
  process.exit(1);
291
380
  }
292
381
  }
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.68",
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",