api-core-lib 12.0.65 → 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.
- package/dist/cli.cjs +227 -154
- package/package.json +7 -4
package/dist/cli.cjs
CHANGED
|
@@ -69,76 +69,114 @@ 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
|
-
|
|
80
|
-
|
|
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
|
+
}
|
|
81
108
|
for (const apiPath in spec.paths) {
|
|
82
109
|
const pathItem = spec.paths[apiPath];
|
|
83
110
|
if (!pathItem) continue;
|
|
84
111
|
for (const method in pathItem) {
|
|
85
112
|
if (!Object.values(import_openapi_types.OpenAPIV3.HttpMethods).includes(method)) continue;
|
|
86
113
|
const endpoint = pathItem[method];
|
|
87
|
-
if (!endpoint.
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
if (!endpoint.operationId) continue;
|
|
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, []);
|
|
92
119
|
}
|
|
93
|
-
const currentModule = modules
|
|
94
|
-
|
|
120
|
+
const currentModule = modules.get(moduleName);
|
|
121
|
+
modulePaths.get(moduleName).push(apiPath);
|
|
122
|
+
const { inputType, outputType } = _extractAndRegisterTypes(endpoint, allSchemas);
|
|
95
123
|
[inputType, outputType].forEach((t) => {
|
|
96
|
-
|
|
97
|
-
|
|
124
|
+
const cleanType = t.replace("[]", "");
|
|
125
|
+
if (cleanType && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(cleanType)) {
|
|
126
|
+
currentModule.schemas.add(cleanType);
|
|
98
127
|
}
|
|
99
128
|
});
|
|
100
|
-
const actionName =
|
|
101
|
-
const relativePath = apiPath.replace(currentModule.baseEndpoint, "").replace(/^\//, "");
|
|
129
|
+
const actionName = getActionNameFromOpId(endpoint.operationId);
|
|
102
130
|
currentModule.actions[actionName] = {
|
|
103
131
|
method: method.toUpperCase(),
|
|
104
|
-
path:
|
|
132
|
+
path: apiPath,
|
|
105
133
|
description: endpoint.summary || "",
|
|
106
134
|
hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"),
|
|
107
135
|
autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"),
|
|
108
|
-
|
|
136
|
+
requiresAuth: !!endpoint.security && endpoint.security.length > 0,
|
|
109
137
|
_inputType: inputType,
|
|
110
138
|
_outputType: outputType
|
|
111
139
|
};
|
|
140
|
+
debugLog("Parsed Action", { moduleName, actionName, ...currentModule.actions[actionName] });
|
|
112
141
|
}
|
|
113
142
|
}
|
|
114
|
-
|
|
143
|
+
modules.forEach((mod, name) => {
|
|
144
|
+
const basePath = findCommonBasePath(modulePaths.get(name));
|
|
145
|
+
mod.baseEndpoint = basePath;
|
|
146
|
+
Object.values(mod.actions).forEach((action) => {
|
|
147
|
+
const relativePath = action.path.replace(basePath, "").replace(/^\//, "");
|
|
148
|
+
action.path = relativePath === "" ? "/" : relativePath;
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
return { modules, allSchemas };
|
|
115
152
|
}
|
|
116
|
-
function
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
const outputType =
|
|
122
|
-
const
|
|
123
|
-
const
|
|
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;
|
|
124
161
|
let inputType = "undefined";
|
|
125
|
-
if (
|
|
126
|
-
inputType = _schemaToTypeName(
|
|
162
|
+
if (reqSchema) {
|
|
163
|
+
inputType = _schemaToTypeName(reqSchema, `${opId}Request`, allSchemas);
|
|
127
164
|
} else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
|
|
128
165
|
inputType = "QueryOptions";
|
|
129
166
|
}
|
|
130
167
|
return { inputType, outputType };
|
|
131
168
|
}
|
|
132
|
-
function _schemaToTypeName(schema, name,
|
|
169
|
+
function _schemaToTypeName(schema, name, allSchemas) {
|
|
133
170
|
if (!schema) return "unknown";
|
|
134
171
|
if (schema.type === "array" && schema.items) {
|
|
135
|
-
const itemTypeName = _schemaToTypeName(schema.items, `${name}Item`,
|
|
172
|
+
const itemTypeName = _schemaToTypeName(schema.items, `${name}Item`, allSchemas);
|
|
136
173
|
return `${itemTypeName}[]`;
|
|
137
174
|
}
|
|
138
|
-
if (schema.type === "object" || schema.properties || schema.allOf) {
|
|
139
|
-
const typeName =
|
|
140
|
-
if (!
|
|
141
|
-
|
|
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 });
|
|
142
180
|
}
|
|
143
181
|
return typeName;
|
|
144
182
|
}
|
|
@@ -147,155 +185,190 @@ function _schemaToTypeName(schema, name, schemas) {
|
|
|
147
185
|
}
|
|
148
186
|
return "unknown";
|
|
149
187
|
}
|
|
150
|
-
async function generateModuleFiles(
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
if (!import_fs.default.existsSync(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
console.log(import_chalk.default.yellow(` - No types found for module "${moduleName}". Skipping types.ts generation.`));
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
console.log(import_chalk.default.gray(` - Generating types.ts with ${typeNames.size} types...`));
|
|
163
|
-
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.
|
|
164
197
|
|
|
198
|
+
import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
|
|
165
199
|
`;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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) {
|
|
174
227
|
try {
|
|
175
|
-
const tsType = await (0, import_json_schema_to_typescript.compile)(schema, typeName,
|
|
228
|
+
const tsType = await (0, import_json_schema_to_typescript.compile)(parsedSchema.schema, typeName, tsOptions);
|
|
176
229
|
typesContent += tsType + "\n";
|
|
177
|
-
} catch (
|
|
178
|
-
console.error(import_chalk.default.red(` - Error compiling type "${typeName}": ${
|
|
230
|
+
} catch (e) {
|
|
231
|
+
console.error(import_chalk.default.red(` - Error compiling type "${typeName}": ${e.message}`));
|
|
179
232
|
}
|
|
180
|
-
} else {
|
|
181
|
-
console.log(import_chalk.default.yellow(` - Warning: Schema for type "${typeName}" not found, skipping.`));
|
|
182
233
|
}
|
|
183
234
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const actionsCount = Object.keys(moduleData.actions).length;
|
|
189
|
-
console.log(import_chalk.default.gray(` - Generating config.ts with ${actionsCount} actions...`));
|
|
190
|
-
const typeNamesArray = [...moduleData.types].sort();
|
|
191
|
-
const typesImportStatement = typeNamesArray.length > 0 ? `import type { ${typeNamesArray.join(", ")} } from './types';` : ``;
|
|
192
|
-
const actionsTypeParts = Object.entries(moduleData.actions).map(
|
|
193
|
-
([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`
|
|
194
|
-
);
|
|
195
|
-
const actionsTypeDefinition = `{
|
|
196
|
-
${actionsTypeParts.join("\n")}
|
|
197
|
-
}`;
|
|
198
|
-
const actionsValueParts = Object.entries(moduleData.actions).map(([actionName, actionData]) => {
|
|
199
|
-
const { _inputType, _outputType, ...config } = actionData;
|
|
200
|
-
return ` ${actionName}: ${JSON.stringify(config, null, 2).replace(/\n/g, "\n ")}`;
|
|
201
|
-
});
|
|
202
|
-
const actionsValueDefinition = `{
|
|
203
|
-
${actionsValueParts.join(",\n")}
|
|
204
|
-
}`;
|
|
205
|
-
const configContent = `/* eslint-disable */
|
|
206
|
-
// 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';
|
|
207
239
|
|
|
208
|
-
|
|
209
|
-
|
|
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)};
|
|
210
245
|
|
|
211
|
-
export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
|
|
212
|
-
baseEndpoint: '${moduleData.baseEndpoint}',
|
|
213
|
-
actions: ${actionsValueDefinition},
|
|
214
|
-
};
|
|
215
246
|
`;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
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`));
|
|
221
274
|
}
|
|
222
|
-
function
|
|
223
|
-
|
|
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
|
+
})`;
|
|
224
285
|
}
|
|
225
|
-
function
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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;
|
|
230
310
|
}
|
|
231
|
-
|
|
232
|
-
return `${method.toLowerCase()}_${pathPart}`;
|
|
311
|
+
return isRequired ? zodString : `${zodString}.optional().nullable()`;
|
|
233
312
|
}
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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;
|
|
250
338
|
}
|
|
251
|
-
return commonPrefix.substring(0, commonPrefix.lastIndexOf("/") + 1) || "/";
|
|
252
339
|
}
|
|
253
|
-
async function runGenerator(
|
|
254
|
-
|
|
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..."));
|
|
255
346
|
import_dotenv.default.config({ path: options.envPath });
|
|
256
|
-
const specUrl =
|
|
347
|
+
const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
|
|
257
348
|
console.log(import_chalk.default.blue("\u2713 Step 1: Environment variables loaded."));
|
|
258
349
|
try {
|
|
259
350
|
console.log(import_chalk.default.blue(`
|
|
260
351
|
\u23F3 Step 2: Fetching and fully dereferencing spec from ${specUrl}...`));
|
|
261
|
-
const
|
|
352
|
+
const spec = await import_swagger_parser.default.dereference(specUrl);
|
|
262
353
|
console.log(import_chalk.default.green("\u2713 Spec fetched and fully dereferenced successfully."));
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
console.log(import_chalk.default.green(`\u2713 Found ${
|
|
267
|
-
|
|
268
|
-
|
|
354
|
+
debugLog("Dereferenced Spec", spec);
|
|
355
|
+
console.log(import_chalk.default.blue("\n\u23F3 Step 3: Parsing spec using intelligent grouping..."));
|
|
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);
|
|
269
362
|
}
|
|
270
|
-
console.log(import_chalk.default.
|
|
271
|
-
const modulesOutputPath = import_path.default.join(options.output, "modules");
|
|
272
|
-
const allSchemas = dereferencedSpec.components?.schemas || {};
|
|
273
|
-
for (const moduleName in modules) {
|
|
274
|
-
const moduleData = modules[moduleName];
|
|
275
|
-
await generateModuleFiles(moduleName, moduleData, allSchemas, modulesOutputPath);
|
|
276
|
-
}
|
|
277
|
-
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."));
|
|
278
364
|
console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!"));
|
|
279
365
|
console.log(import_chalk.default.bold.cyan(` Output directory: ${options.output}`));
|
|
280
366
|
} catch (error) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
function getSpecUrl() {
|
|
285
|
-
const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
|
|
286
|
-
if (!specUrl) {
|
|
287
|
-
console.error(import_chalk.default.red.bold("\n\u274C Error: API specification URL not found."));
|
|
367
|
+
console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
|
|
368
|
+
console.error(import_chalk.default.red(`Error Message: ${error.message}`));
|
|
369
|
+
if (error.stack && DEBUG_MODE) console.error(import_chalk.default.gray(error.stack));
|
|
288
370
|
process.exit(1);
|
|
289
371
|
}
|
|
290
|
-
return specUrl;
|
|
291
|
-
}
|
|
292
|
-
function handleGenerationError(error) {
|
|
293
|
-
console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
|
|
294
|
-
console.error(import_chalk.default.red(`Error Message: ${error.message}`));
|
|
295
|
-
if (error.stack) {
|
|
296
|
-
console.error(import_chalk.default.gray(error.stack));
|
|
297
|
-
}
|
|
298
|
-
process.exit(1);
|
|
299
372
|
}
|
|
300
373
|
|
|
301
374
|
// src/cli.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-core-lib",
|
|
3
|
-
"version": "12.0.
|
|
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.
|
|
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
|
-
"
|
|
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.
|
|
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",
|