api-core-lib 12.0.52 → 12.0.53
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 +85 -66
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -30,7 +30,7 @@ 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
|
|
|
@@ -49,7 +49,7 @@ function parseSpecToModules(spec) {
|
|
|
49
49
|
}
|
|
50
50
|
const { inputType, outputType } = getInputOutputTypes(endpoint);
|
|
51
51
|
[inputType, outputType].forEach((t) => {
|
|
52
|
-
if (t && !["unknown", "undefined", "any", "QueryOptions"].includes(t)) {
|
|
52
|
+
if (t && !["unknown", "undefined", "any", "QueryOptions", "Promise"].includes(t)) {
|
|
53
53
|
modules[moduleName].types.add(t.replace("[]", ""));
|
|
54
54
|
}
|
|
55
55
|
});
|
|
@@ -69,27 +69,28 @@ function parseSpecToModules(spec) {
|
|
|
69
69
|
}
|
|
70
70
|
return modules;
|
|
71
71
|
}
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} else if (responseSchema.$ref) {
|
|
81
|
-
outputType = refToTypeName(responseSchema.$ref);
|
|
82
|
-
} else if (responseSchema.type === "array" && (responseSchema.items?.title || responseSchema.items?.$ref)) {
|
|
83
|
-
outputType = (responseSchema.items.title || refToTypeName(responseSchema.items.$ref)) + "[]";
|
|
84
|
-
}
|
|
72
|
+
function extractTypeNameFromSchema(schema) {
|
|
73
|
+
if (!schema) return "unknown";
|
|
74
|
+
if (schema.title && schema.type === "object") {
|
|
75
|
+
return schema.title;
|
|
76
|
+
}
|
|
77
|
+
if (schema.type === "array" && schema.items) {
|
|
78
|
+
const itemTypeName = extractTypeNameFromSchema(schema.items);
|
|
79
|
+
return itemTypeName !== "unknown" ? `${itemTypeName}[]` : "unknown";
|
|
85
80
|
}
|
|
81
|
+
if (schema.$ref) {
|
|
82
|
+
return refToTypeName(schema.$ref);
|
|
83
|
+
}
|
|
84
|
+
return "unknown";
|
|
85
|
+
}
|
|
86
|
+
function getInputOutputTypes(endpoint) {
|
|
87
|
+
const requestBodySchema = endpoint.requestBody?.content?.["application/json"]?.schema;
|
|
88
|
+
const successResponseSchema = endpoint.responses?.["200"]?.content?.["application/json"]?.schema || endpoint.responses?.["201"]?.content?.["application/json"]?.schema;
|
|
89
|
+
let outputType = extractTypeNameFromSchema(successResponseSchema);
|
|
86
90
|
let inputType = "undefined";
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} else if (requestBody.$ref) {
|
|
91
|
-
inputType = refToTypeName(requestBody.$ref);
|
|
92
|
-
} else if (requestBody.type === "object") {
|
|
91
|
+
if (requestBodySchema) {
|
|
92
|
+
inputType = extractTypeNameFromSchema(requestBodySchema);
|
|
93
|
+
if (inputType === "unknown" && requestBodySchema.type === "object") {
|
|
93
94
|
inputType = "any";
|
|
94
95
|
}
|
|
95
96
|
} else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
|
|
@@ -113,16 +114,25 @@ function refToTypeName(ref) {
|
|
|
113
114
|
// src/generator/file-generator.ts
|
|
114
115
|
var import_fs = __toESM(require("fs"), 1);
|
|
115
116
|
var import_path = __toESM(require("path"), 1);
|
|
117
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
116
118
|
var import_json_schema_to_typescript = require("json-schema-to-typescript");
|
|
117
119
|
async function generateModuleFiles(moduleName, moduleData, spec, outputDir) {
|
|
120
|
+
console.log(import_chalk.default.cyan(`
|
|
121
|
+
Generating module: ${moduleName}`));
|
|
118
122
|
const moduleFolderPath = import_path.default.join(outputDir, moduleName);
|
|
119
123
|
if (!import_fs.default.existsSync(moduleFolderPath)) {
|
|
120
124
|
import_fs.default.mkdirSync(moduleFolderPath, { recursive: true });
|
|
121
125
|
}
|
|
122
|
-
await generateTypesFile(moduleFolderPath, moduleData.types, spec);
|
|
123
|
-
await generateConfigFile(moduleFolderPath, moduleName, moduleData
|
|
126
|
+
await generateTypesFile(moduleFolderPath, moduleName, moduleData.types, spec);
|
|
127
|
+
await generateConfigFile(moduleFolderPath, moduleName, moduleData);
|
|
124
128
|
}
|
|
125
|
-
async function generateTypesFile(moduleFolderPath, typeNames, spec) {
|
|
129
|
+
async function generateTypesFile(moduleFolderPath, moduleName, typeNames, spec) {
|
|
130
|
+
const typesCount = typeNames.size;
|
|
131
|
+
if (typesCount === 0) {
|
|
132
|
+
console.log(import_chalk.default.yellow(` - Warning: No types found for this module. types.ts will be empty.`));
|
|
133
|
+
} else {
|
|
134
|
+
console.log(import_chalk.default.gray(` - Found ${typesCount} types to generate for types.ts...`));
|
|
135
|
+
}
|
|
126
136
|
let typesContent = `// This file is auto-generated by the API generator. Do not edit.
|
|
127
137
|
|
|
128
138
|
`;
|
|
@@ -130,27 +140,36 @@ async function generateTypesFile(moduleFolderPath, typeNames, spec) {
|
|
|
130
140
|
for (const typeName of typeNames) {
|
|
131
141
|
const schema = allSchemas[typeName];
|
|
132
142
|
if (schema) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
try {
|
|
144
|
+
const tsType = await (0, import_json_schema_to_typescript.compile)(schema, typeName, {
|
|
145
|
+
bannerComment: "",
|
|
146
|
+
additionalProperties: false,
|
|
147
|
+
style: {
|
|
148
|
+
bracketSpacing: true,
|
|
149
|
+
printWidth: 120,
|
|
150
|
+
semi: true,
|
|
151
|
+
singleQuote: true,
|
|
152
|
+
tabWidth: 2,
|
|
153
|
+
trailingComma: "es5",
|
|
154
|
+
useTabs: false
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
typesContent += tsType + "\n";
|
|
158
|
+
} catch (compileError) {
|
|
159
|
+
console.error(import_chalk.default.red(` - Error compiling type "${typeName}" for module "${moduleName}":`));
|
|
160
|
+
console.error(import_chalk.default.red(` ${compileError.message}`));
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
console.log(import_chalk.default.yellow(` - Warning: Schema not found for type "${typeName}", skipping.`));
|
|
147
164
|
}
|
|
148
165
|
}
|
|
149
166
|
const typesFilePath = import_path.default.join(moduleFolderPath, "types.ts");
|
|
150
167
|
import_fs.default.writeFileSync(typesFilePath, typesContent);
|
|
151
168
|
}
|
|
152
|
-
async function generateConfigFile(moduleFolderPath, moduleName, moduleData
|
|
153
|
-
const typeNamesArray = [...
|
|
169
|
+
async function generateConfigFile(moduleFolderPath, moduleName, moduleData) {
|
|
170
|
+
const typeNamesArray = [...moduleData.types];
|
|
171
|
+
const actionsCount = Object.keys(moduleData.actions).length;
|
|
172
|
+
console.log(import_chalk.default.gray(` - Found ${actionsCount} actions to generate for config.ts...`));
|
|
154
173
|
const typesImportStatement = typeNamesArray.length > 0 ? `import type { ${typeNamesArray.join(", ")} } from './types';` : ``;
|
|
155
174
|
const actionsTypeParts = Object.entries(moduleData.actions).map(
|
|
156
175
|
([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`
|
|
@@ -182,35 +201,41 @@ export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
|
|
|
182
201
|
|
|
183
202
|
// src/generator/index.ts
|
|
184
203
|
async function runGenerator(options) {
|
|
185
|
-
console.log(
|
|
186
|
-
console.log(
|
|
187
|
-
console.log(
|
|
188
|
-
console.log("\n" +
|
|
204
|
+
console.log(import_chalk2.default.cyan.bold("\u{1F680} Starting API Core Lib Code Generator..."));
|
|
205
|
+
console.log(import_chalk2.default.gray(`Output directory: ${options.output}`));
|
|
206
|
+
console.log(import_chalk2.default.gray(`.env path: ${options.envPath}`));
|
|
207
|
+
console.log("\n" + import_chalk2.default.blue("Step 1: Loading environment variables..."));
|
|
189
208
|
import_dotenv.default.config({ path: options.envPath });
|
|
190
209
|
const specUrl = getSpecUrl();
|
|
191
|
-
console.log(
|
|
210
|
+
console.log(import_chalk2.default.green("\u2713 Environment variables loaded."));
|
|
192
211
|
try {
|
|
193
|
-
console.log("\n" +
|
|
212
|
+
console.log("\n" + import_chalk2.default.blue(`Step 2: Fetching OpenAPI spec from ${specUrl}...`));
|
|
194
213
|
const response = await import_axios.default.get(specUrl, { timeout: 15e3 });
|
|
195
214
|
let spec = response.data;
|
|
196
215
|
if (!spec.openapi || !spec.paths) {
|
|
197
216
|
throw new Error('Invalid OpenAPI specification file. "openapi" or "paths" property is missing.');
|
|
198
217
|
}
|
|
199
|
-
console.log(
|
|
200
|
-
console.log(
|
|
218
|
+
console.log(import_chalk2.default.green("\u2713 OpenAPI spec fetched successfully."));
|
|
219
|
+
console.log(import_chalk2.default.blue("Step 2.5: Dereferencing all $refs in the spec..."));
|
|
201
220
|
spec = await import_json_schema_ref_parser.default.dereference(spec);
|
|
202
|
-
console.log(
|
|
203
|
-
console.log("\n" +
|
|
221
|
+
console.log(import_chalk2.default.green("\u2713 Spec dereferenced successfully."));
|
|
222
|
+
console.log("\n" + import_chalk2.default.blue("Step 3: Parsing spec and generating API modules..."));
|
|
204
223
|
const modules = parseSpecToModules(spec);
|
|
224
|
+
const modulesCount = Object.keys(modules).length;
|
|
225
|
+
console.log(import_chalk2.default.gray(`Found ${modulesCount} modules to generate...`));
|
|
226
|
+
if (modulesCount === 0) {
|
|
227
|
+
console.log(import_chalk2.default.yellow("Warning: No modules found based on tags in the OpenAPI spec. No files will be generated."));
|
|
228
|
+
}
|
|
205
229
|
const modulesOutputPath = import_path2.default.join(options.output, "modules");
|
|
206
230
|
for (const moduleName in modules) {
|
|
207
231
|
const moduleData = modules[moduleName];
|
|
208
232
|
await generateModuleFiles(moduleName, moduleData, spec, modulesOutputPath);
|
|
209
|
-
console.log(import_chalk.default.green(`\u2713 Module generated: ${moduleName}/ (config.ts, types.ts)`));
|
|
210
233
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
234
|
+
if (modulesCount > 0) {
|
|
235
|
+
console.log(import_chalk2.default.green("\u2713 All custom modules generated."));
|
|
236
|
+
}
|
|
237
|
+
console.log(import_chalk2.default.bold.green("\n\u{1F389} API generation complete! All files are located in:"));
|
|
238
|
+
console.log(import_chalk2.default.bold.cyan(options.output));
|
|
214
239
|
} catch (error) {
|
|
215
240
|
handleGenerationError(error);
|
|
216
241
|
}
|
|
@@ -218,23 +243,17 @@ async function runGenerator(options) {
|
|
|
218
243
|
function getSpecUrl() {
|
|
219
244
|
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);
|
|
220
245
|
if (!specUrl) {
|
|
221
|
-
console.error(
|
|
222
|
-
console.error(
|
|
246
|
+
console.error(import_chalk2.default.red.bold("\n\u274C Error: API specification URL not found."));
|
|
247
|
+
console.error(import_chalk2.default.red("Please define either OPENAPI_SPEC_URL or API_URL/NEXT_PUBLIC_API_URL in your .env file."));
|
|
223
248
|
process.exit(1);
|
|
224
249
|
}
|
|
225
250
|
return specUrl;
|
|
226
251
|
}
|
|
227
252
|
function handleGenerationError(error) {
|
|
228
|
-
console.error(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
console.error(import_chalk.default.red(`Network Error: ${error.message} (Status: ${error.response.status})`));
|
|
233
|
-
} else if (error.stderr) {
|
|
234
|
-
console.error(import_chalk.default.red(`Command Execution Error: ${error.message}`));
|
|
235
|
-
console.error(import_chalk.default.gray(error.stderr.toString()));
|
|
236
|
-
} else {
|
|
237
|
-
console.error(import_chalk.default.red(error.message));
|
|
253
|
+
console.error(import_chalk2.default.red.bold("\n\u274C An error occurred during generation:"));
|
|
254
|
+
console.error(import_chalk2.default.red(`Error Message: ${error.message}`));
|
|
255
|
+
if (error.stack) {
|
|
256
|
+
console.error(import_chalk2.default.gray(error.stack));
|
|
238
257
|
}
|
|
239
258
|
process.exit(1);
|
|
240
259
|
}
|