api-core-lib 12.0.55 → 12.0.56
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 +90 -48
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -30,12 +30,11 @@ var import_path3 = __toESM(require("path"), 1);
|
|
|
30
30
|
// src/generator/index.ts
|
|
31
31
|
var import_path2 = __toESM(require("path"), 1);
|
|
32
32
|
var import_axios = __toESM(require("axios"), 1);
|
|
33
|
-
var
|
|
33
|
+
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
34
34
|
var import_dotenv = __toESM(require("dotenv"), 1);
|
|
35
35
|
var import_json_schema_ref_parser = __toESM(require("@apidevtools/json-schema-ref-parser"), 1);
|
|
36
36
|
|
|
37
37
|
// src/generator/spec-parser.ts
|
|
38
|
-
var import_chalk = __toESM(require("chalk"), 1);
|
|
39
38
|
function parseSpecToModules(spec) {
|
|
40
39
|
const modules = {};
|
|
41
40
|
for (const apiPath in spec.paths) {
|
|
@@ -48,7 +47,7 @@ function parseSpecToModules(spec) {
|
|
|
48
47
|
const commonPath = apiPath.substring(0, apiPath.lastIndexOf("/"));
|
|
49
48
|
modules[moduleName] = { baseEndpoint: commonPath || "/", actions: {}, types: /* @__PURE__ */ new Set() };
|
|
50
49
|
}
|
|
51
|
-
const { inputType, outputType } = getInputOutputTypes(endpoint
|
|
50
|
+
const { inputType, outputType } = getInputOutputTypes(endpoint);
|
|
52
51
|
[inputType, outputType].forEach((t) => {
|
|
53
52
|
if (t && !["unknown", "undefined", "any", "QueryOptions", "Promise"].includes(t)) {
|
|
54
53
|
modules[moduleName].types.add(t.replace("[]", ""));
|
|
@@ -70,23 +69,9 @@ function parseSpecToModules(spec) {
|
|
|
70
69
|
}
|
|
71
70
|
return modules;
|
|
72
71
|
}
|
|
73
|
-
function getInputOutputTypes(endpoint
|
|
72
|
+
function getInputOutputTypes(endpoint) {
|
|
74
73
|
const requestBodySchema = endpoint.requestBody?.content?.["application/json"]?.schema;
|
|
75
74
|
const successResponseSchema = endpoint.responses?.["200"]?.content?.["application/json"]?.schema || endpoint.responses?.["201"]?.content?.["application/json"]?.schema;
|
|
76
|
-
const operationId = endpoint.operationId || `(unknown operation at ${apiPath})`;
|
|
77
|
-
console.log(import_chalk.default.magenta(`
|
|
78
|
-
--- DIAGNOSING Operation: ${operationId} ---`));
|
|
79
|
-
if (successResponseSchema) {
|
|
80
|
-
console.log(import_chalk.default.blue(" Response Schema Structure:"));
|
|
81
|
-
console.log(JSON.stringify(successResponseSchema, null, 2));
|
|
82
|
-
} else {
|
|
83
|
-
console.log(import_chalk.default.gray(" - No success response schema found."));
|
|
84
|
-
}
|
|
85
|
-
if (requestBodySchema) {
|
|
86
|
-
console.log(import_chalk.default.blue(" Request Body Schema Structure:"));
|
|
87
|
-
console.log(JSON.stringify(requestBodySchema, null, 2));
|
|
88
|
-
}
|
|
89
|
-
console.log(import_chalk.default.magenta("---------------------------------------------------\n"));
|
|
90
75
|
let outputType = "unknown";
|
|
91
76
|
if (successResponseSchema) {
|
|
92
77
|
if (successResponseSchema.$ref) {
|
|
@@ -123,10 +108,10 @@ function refToTypeName(ref) {
|
|
|
123
108
|
// src/generator/file-generator.ts
|
|
124
109
|
var import_fs = __toESM(require("fs"), 1);
|
|
125
110
|
var import_path = __toESM(require("path"), 1);
|
|
126
|
-
var
|
|
111
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
127
112
|
var import_json_schema_to_typescript = require("json-schema-to-typescript");
|
|
128
113
|
async function generateModuleFiles(moduleName, moduleData, spec, outputDir) {
|
|
129
|
-
console.log(
|
|
114
|
+
console.log(import_chalk.default.cyan(`
|
|
130
115
|
Generating module: ${moduleName}`));
|
|
131
116
|
const moduleFolderPath = import_path.default.join(outputDir, moduleName);
|
|
132
117
|
if (!import_fs.default.existsSync(moduleFolderPath)) {
|
|
@@ -138,9 +123,9 @@ Generating module: ${moduleName}`));
|
|
|
138
123
|
async function generateTypesFile(moduleFolderPath, moduleName, typeNames, spec) {
|
|
139
124
|
const typesCount = typeNames.size;
|
|
140
125
|
if (typesCount === 0) {
|
|
141
|
-
console.log(
|
|
126
|
+
console.log(import_chalk.default.yellow(` - No types found for this module. types.ts will be empty.`));
|
|
142
127
|
} else {
|
|
143
|
-
console.log(
|
|
128
|
+
console.log(import_chalk.default.gray(` - Found ${typesCount} types to generate for types.ts...`));
|
|
144
129
|
}
|
|
145
130
|
let typesContent = `// This file is auto-generated by the API generator. Do not edit.
|
|
146
131
|
|
|
@@ -165,11 +150,11 @@ async function generateTypesFile(moduleFolderPath, moduleName, typeNames, spec)
|
|
|
165
150
|
});
|
|
166
151
|
typesContent += tsType + "\n";
|
|
167
152
|
} catch (compileError) {
|
|
168
|
-
console.error(
|
|
169
|
-
console.error(
|
|
153
|
+
console.error(import_chalk.default.red(` - Error compiling type "${typeName}" for module "${moduleName}":`));
|
|
154
|
+
console.error(import_chalk.default.red(` ${compileError.message}`));
|
|
170
155
|
}
|
|
171
156
|
} else {
|
|
172
|
-
console.log(
|
|
157
|
+
console.log(import_chalk.default.yellow(` - Warning: Schema for type "${typeName}" not found in dereferenced spec, skipping.`));
|
|
173
158
|
}
|
|
174
159
|
}
|
|
175
160
|
const typesFilePath = import_path.default.join(moduleFolderPath, "types.ts");
|
|
@@ -178,7 +163,7 @@ async function generateTypesFile(moduleFolderPath, moduleName, typeNames, spec)
|
|
|
178
163
|
async function generateConfigFile(moduleFolderPath, moduleName, moduleData) {
|
|
179
164
|
const typeNamesArray = [...moduleData.types];
|
|
180
165
|
const actionsCount = Object.keys(moduleData.actions).length;
|
|
181
|
-
console.log(
|
|
166
|
+
console.log(import_chalk.default.gray(` - Found ${actionsCount} actions to generate for config.ts...`));
|
|
182
167
|
const typesImportStatement = typeNamesArray.length > 0 ? `import type { ${typeNamesArray.join(", ")} } from './types';` : ``;
|
|
183
168
|
const actionsTypeParts = Object.entries(moduleData.actions).map(
|
|
184
169
|
([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`
|
|
@@ -208,32 +193,90 @@ export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
|
|
|
208
193
|
import_fs.default.writeFileSync(configFilePath, configContent);
|
|
209
194
|
}
|
|
210
195
|
|
|
196
|
+
// src/generator/spec-preprocessor.ts
|
|
197
|
+
function toPascalCase(str) {
|
|
198
|
+
return str.replace(/_v\d+$/, "").split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
199
|
+
}
|
|
200
|
+
function normalizeSchema(schema, schemas, baseName, suffix) {
|
|
201
|
+
if (!schema) return schema;
|
|
202
|
+
if (schema.$ref) return schema;
|
|
203
|
+
if (schema.type === "object" && schema.properties) {
|
|
204
|
+
const typeName = `${toPascalCase(baseName)}${suffix}Dto`;
|
|
205
|
+
if (!schemas[typeName]) {
|
|
206
|
+
schemas[typeName] = schema;
|
|
207
|
+
}
|
|
208
|
+
return { $ref: `#/components/schemas/${typeName}` };
|
|
209
|
+
}
|
|
210
|
+
if (schema.type === "array" && schema.items) {
|
|
211
|
+
schema.items = normalizeSchema(schema.items, schemas, baseName, suffix.replace("[]", ""));
|
|
212
|
+
return schema;
|
|
213
|
+
}
|
|
214
|
+
return schema;
|
|
215
|
+
}
|
|
216
|
+
function preprocessSpec(spec) {
|
|
217
|
+
if (!spec.components) spec.components = {};
|
|
218
|
+
if (!spec.components.schemas) spec.components.schemas = {};
|
|
219
|
+
for (const apiPath in spec.paths) {
|
|
220
|
+
for (const method in spec.paths[apiPath]) {
|
|
221
|
+
const endpoint = spec.paths[apiPath][method];
|
|
222
|
+
const operationId = endpoint.operationId;
|
|
223
|
+
if (!operationId) continue;
|
|
224
|
+
const requestBodySchema = endpoint.requestBody?.content?.["application/json"]?.schema;
|
|
225
|
+
if (requestBodySchema) {
|
|
226
|
+
endpoint.requestBody.content["application/json"].schema = normalizeSchema(
|
|
227
|
+
requestBodySchema,
|
|
228
|
+
spec.components.schemas,
|
|
229
|
+
operationId,
|
|
230
|
+
"Request"
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
if (endpoint.responses) {
|
|
234
|
+
for (const statusCode in endpoint.responses) {
|
|
235
|
+
const responseSchema = endpoint.responses[statusCode]?.content?.["application/json"]?.schema;
|
|
236
|
+
if (responseSchema) {
|
|
237
|
+
endpoint.responses[statusCode].content["application/json"].schema = normalizeSchema(
|
|
238
|
+
responseSchema,
|
|
239
|
+
spec.components.schemas,
|
|
240
|
+
operationId,
|
|
241
|
+
"Response"
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return spec;
|
|
249
|
+
}
|
|
250
|
+
|
|
211
251
|
// src/generator/index.ts
|
|
212
252
|
async function runGenerator(options) {
|
|
213
|
-
console.log(
|
|
214
|
-
console.log(
|
|
215
|
-
console.log(
|
|
216
|
-
console.log("\n" +
|
|
253
|
+
console.log(import_chalk2.default.cyan.bold("\u{1F680} Starting API Core Lib Code Generator..."));
|
|
254
|
+
console.log(import_chalk2.default.gray(`Output directory: ${options.output}`));
|
|
255
|
+
console.log(import_chalk2.default.gray(`.env path: ${options.envPath}`));
|
|
256
|
+
console.log("\n" + import_chalk2.default.blue("Step 1: Loading environment variables..."));
|
|
217
257
|
import_dotenv.default.config({ path: options.envPath });
|
|
218
258
|
const specUrl = getSpecUrl();
|
|
219
|
-
console.log(
|
|
259
|
+
console.log(import_chalk2.default.green("\u2713 Environment variables loaded."));
|
|
220
260
|
try {
|
|
221
|
-
console.log("\n" +
|
|
261
|
+
console.log("\n" + import_chalk2.default.blue(`Step 2: Fetching OpenAPI spec from ${specUrl}...`));
|
|
222
262
|
const response = await import_axios.default.get(specUrl, { timeout: 15e3 });
|
|
223
263
|
const originalSpec = response.data;
|
|
224
264
|
if (!originalSpec.openapi || !originalSpec.paths) {
|
|
225
265
|
throw new Error('Invalid OpenAPI specification file. "openapi" or "paths" property is missing.');
|
|
226
266
|
}
|
|
227
|
-
console.log(
|
|
228
|
-
console.log(
|
|
229
|
-
const
|
|
230
|
-
console.log(
|
|
231
|
-
console.log(
|
|
232
|
-
const
|
|
267
|
+
console.log(import_chalk2.default.green("\u2713 OpenAPI spec fetched successfully."));
|
|
268
|
+
console.log(import_chalk2.default.blue("Step 2.2: Preprocessing spec to normalize schemas..."));
|
|
269
|
+
const normalizedSpec = preprocessSpec(originalSpec);
|
|
270
|
+
console.log(import_chalk2.default.green("\u2713 Spec has been normalized successfully."));
|
|
271
|
+
console.log(import_chalk2.default.blue("Step 2.5: Dereferencing all $refs in the spec..."));
|
|
272
|
+
const dereferencedSpec = await import_json_schema_ref_parser.default.dereference(normalizedSpec);
|
|
273
|
+
console.log(import_chalk2.default.green("\u2713 Spec dereferenced successfully."));
|
|
274
|
+
console.log("\n" + import_chalk2.default.blue("Step 3: Parsing spec and generating API modules..."));
|
|
275
|
+
const modules = parseSpecToModules(normalizedSpec);
|
|
233
276
|
const modulesCount = Object.keys(modules).length;
|
|
234
|
-
console.log(
|
|
277
|
+
console.log(import_chalk2.default.gray(`Found ${modulesCount} modules to generate...`));
|
|
235
278
|
if (modulesCount === 0) {
|
|
236
|
-
console.log(
|
|
279
|
+
console.log(import_chalk2.default.yellow("Warning: No modules found."));
|
|
237
280
|
}
|
|
238
281
|
const modulesOutputPath = import_path2.default.join(options.output, "modules");
|
|
239
282
|
for (const moduleName in modules) {
|
|
@@ -241,10 +284,10 @@ async function runGenerator(options) {
|
|
|
241
284
|
await generateModuleFiles(moduleName, moduleData, dereferencedSpec, modulesOutputPath);
|
|
242
285
|
}
|
|
243
286
|
if (modulesCount > 0) {
|
|
244
|
-
console.log(
|
|
287
|
+
console.log(import_chalk2.default.green("\u2713 All custom modules generated."));
|
|
245
288
|
}
|
|
246
|
-
console.log(
|
|
247
|
-
console.log(
|
|
289
|
+
console.log(import_chalk2.default.bold.green("\n\u{1F389} API generation complete! All files are located in:"));
|
|
290
|
+
console.log(import_chalk2.default.bold.cyan(options.output));
|
|
248
291
|
} catch (error) {
|
|
249
292
|
handleGenerationError(error);
|
|
250
293
|
}
|
|
@@ -252,17 +295,16 @@ async function runGenerator(options) {
|
|
|
252
295
|
function getSpecUrl() {
|
|
253
296
|
const specUrl = process.env.OPENAPI_SPEC_URL || (process.env.API_URL ? `${process.env.API_URL}/docs-json` : null) || (process.env.NEXT_PUBLIC_API_URL ? `${process.env.NEXT_PUBLIC_API_URL}/docs-json` : null);
|
|
254
297
|
if (!specUrl) {
|
|
255
|
-
console.error(
|
|
256
|
-
console.error(import_chalk3.default.red("Please define either OPENAPI_SPEC_URL or API_URL/NEXT_PUBLIC_API_URL in your .env file."));
|
|
298
|
+
console.error(import_chalk2.default.red.bold("\n\u274C Error: API specification URL not found."));
|
|
257
299
|
process.exit(1);
|
|
258
300
|
}
|
|
259
301
|
return specUrl;
|
|
260
302
|
}
|
|
261
303
|
function handleGenerationError(error) {
|
|
262
|
-
console.error(
|
|
263
|
-
console.error(
|
|
304
|
+
console.error(import_chalk2.default.red.bold("\n\u274C An error occurred during generation:"));
|
|
305
|
+
console.error(import_chalk2.default.red(`Error Message: ${error.message}`));
|
|
264
306
|
if (error.stack) {
|
|
265
|
-
console.error(
|
|
307
|
+
console.error(import_chalk2.default.gray(error.stack));
|
|
266
308
|
}
|
|
267
309
|
process.exit(1);
|
|
268
310
|
}
|