api-core-lib 12.0.51 → 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 +88 -83
- 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,23 +69,28 @@ function parseSpecToModules(spec) {
|
|
|
69
69
|
}
|
|
70
70
|
return modules;
|
|
71
71
|
}
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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";
|
|
80
|
+
}
|
|
81
|
+
if (schema.$ref) {
|
|
82
|
+
return refToTypeName(schema.$ref);
|
|
83
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);
|
|
84
90
|
let inputType = "undefined";
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
} else if (requestBody.type === "object") {
|
|
91
|
+
if (requestBodySchema) {
|
|
92
|
+
inputType = extractTypeNameFromSchema(requestBodySchema);
|
|
93
|
+
if (inputType === "unknown" && requestBodySchema.type === "object") {
|
|
89
94
|
inputType = "any";
|
|
90
95
|
}
|
|
91
96
|
} else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
|
|
@@ -93,24 +98,6 @@ function getInputOutputTypes(endpoint) {
|
|
|
93
98
|
}
|
|
94
99
|
return { inputType, outputType };
|
|
95
100
|
}
|
|
96
|
-
function getAllReferencedTypes(initialTypes, allSchemas) {
|
|
97
|
-
const finalTypes = new Set(initialTypes);
|
|
98
|
-
const queue = [...initialTypes];
|
|
99
|
-
while (queue.length > 0) {
|
|
100
|
-
const typeName = queue.shift();
|
|
101
|
-
if (!typeName || !allSchemas[typeName]) continue;
|
|
102
|
-
const schemaString = JSON.stringify(allSchemas[typeName]);
|
|
103
|
-
const references = schemaString.match(/"\$ref":\s*"#\/components\/schemas\/([^"]+)"/g) || [];
|
|
104
|
-
for (const ref of references) {
|
|
105
|
-
const referencedTypeName = ref.split("/").pop()?.replace(/"/g, "") || "";
|
|
106
|
-
if (referencedTypeName && !finalTypes.has(referencedTypeName)) {
|
|
107
|
-
finalTypes.add(referencedTypeName);
|
|
108
|
-
queue.push(referencedTypeName);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return finalTypes;
|
|
113
|
-
}
|
|
114
101
|
function sanitizeTagName(tagName) {
|
|
115
102
|
return tagName.replace(/[^a-zA-Z0-9]/g, "").replace(/Central|Tenant/g, "");
|
|
116
103
|
}
|
|
@@ -127,44 +114,62 @@ function refToTypeName(ref) {
|
|
|
127
114
|
// src/generator/file-generator.ts
|
|
128
115
|
var import_fs = __toESM(require("fs"), 1);
|
|
129
116
|
var import_path = __toESM(require("path"), 1);
|
|
117
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
130
118
|
var import_json_schema_to_typescript = require("json-schema-to-typescript");
|
|
131
119
|
async function generateModuleFiles(moduleName, moduleData, spec, outputDir) {
|
|
120
|
+
console.log(import_chalk.default.cyan(`
|
|
121
|
+
Generating module: ${moduleName}`));
|
|
132
122
|
const moduleFolderPath = import_path.default.join(outputDir, moduleName);
|
|
133
123
|
if (!import_fs.default.existsSync(moduleFolderPath)) {
|
|
134
124
|
import_fs.default.mkdirSync(moduleFolderPath, { recursive: true });
|
|
135
125
|
}
|
|
136
|
-
|
|
137
|
-
await
|
|
138
|
-
await generateConfigFile(moduleFolderPath, moduleName, moduleData, allTypeNames);
|
|
126
|
+
await generateTypesFile(moduleFolderPath, moduleName, moduleData.types, spec);
|
|
127
|
+
await generateConfigFile(moduleFolderPath, moduleName, moduleData);
|
|
139
128
|
}
|
|
140
|
-
async function generateTypesFile(moduleFolderPath,
|
|
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
|
+
}
|
|
141
136
|
let typesContent = `// This file is auto-generated by the API generator. Do not edit.
|
|
142
137
|
|
|
143
138
|
`;
|
|
144
|
-
|
|
145
|
-
|
|
139
|
+
const allSchemas = spec.components?.schemas || {};
|
|
140
|
+
for (const typeName of typeNames) {
|
|
141
|
+
const schema = allSchemas[typeName];
|
|
146
142
|
if (schema) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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.`));
|
|
161
164
|
}
|
|
162
165
|
}
|
|
163
166
|
const typesFilePath = import_path.default.join(moduleFolderPath, "types.ts");
|
|
164
167
|
import_fs.default.writeFileSync(typesFilePath, typesContent);
|
|
165
168
|
}
|
|
166
|
-
async function generateConfigFile(moduleFolderPath, moduleName, moduleData
|
|
167
|
-
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...`));
|
|
168
173
|
const typesImportStatement = typeNamesArray.length > 0 ? `import type { ${typeNamesArray.join(", ")} } from './types';` : ``;
|
|
169
174
|
const actionsTypeParts = Object.entries(moduleData.actions).map(
|
|
170
175
|
([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`
|
|
@@ -196,35 +201,41 @@ export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
|
|
|
196
201
|
|
|
197
202
|
// src/generator/index.ts
|
|
198
203
|
async function runGenerator(options) {
|
|
199
|
-
console.log(
|
|
200
|
-
console.log(
|
|
201
|
-
console.log(
|
|
202
|
-
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..."));
|
|
203
208
|
import_dotenv.default.config({ path: options.envPath });
|
|
204
209
|
const specUrl = getSpecUrl();
|
|
205
|
-
console.log(
|
|
210
|
+
console.log(import_chalk2.default.green("\u2713 Environment variables loaded."));
|
|
206
211
|
try {
|
|
207
|
-
console.log("\n" +
|
|
212
|
+
console.log("\n" + import_chalk2.default.blue(`Step 2: Fetching OpenAPI spec from ${specUrl}...`));
|
|
208
213
|
const response = await import_axios.default.get(specUrl, { timeout: 15e3 });
|
|
209
214
|
let spec = response.data;
|
|
210
215
|
if (!spec.openapi || !spec.paths) {
|
|
211
216
|
throw new Error('Invalid OpenAPI specification file. "openapi" or "paths" property is missing.');
|
|
212
217
|
}
|
|
213
|
-
console.log(
|
|
214
|
-
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..."));
|
|
215
220
|
spec = await import_json_schema_ref_parser.default.dereference(spec);
|
|
216
|
-
console.log(
|
|
217
|
-
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..."));
|
|
218
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
|
+
}
|
|
219
229
|
const modulesOutputPath = import_path2.default.join(options.output, "modules");
|
|
220
230
|
for (const moduleName in modules) {
|
|
221
231
|
const moduleData = modules[moduleName];
|
|
222
232
|
await generateModuleFiles(moduleName, moduleData, spec, modulesOutputPath);
|
|
223
|
-
console.log(import_chalk.default.green(`\u2713 Module generated: ${moduleName}/ (config.ts, types.ts)`));
|
|
224
233
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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));
|
|
228
239
|
} catch (error) {
|
|
229
240
|
handleGenerationError(error);
|
|
230
241
|
}
|
|
@@ -232,23 +243,17 @@ async function runGenerator(options) {
|
|
|
232
243
|
function getSpecUrl() {
|
|
233
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);
|
|
234
245
|
if (!specUrl) {
|
|
235
|
-
console.error(
|
|
236
|
-
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."));
|
|
237
248
|
process.exit(1);
|
|
238
249
|
}
|
|
239
250
|
return specUrl;
|
|
240
251
|
}
|
|
241
252
|
function handleGenerationError(error) {
|
|
242
|
-
console.error(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
console.error(import_chalk.default.red(`Network Error: ${error.message} (Status: ${error.response.status})`));
|
|
247
|
-
} else if (error.stderr) {
|
|
248
|
-
console.error(import_chalk.default.red(`Command Execution Error: ${error.message}`));
|
|
249
|
-
console.error(import_chalk.default.gray(error.stderr.toString()));
|
|
250
|
-
} else {
|
|
251
|
-
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));
|
|
252
257
|
}
|
|
253
258
|
process.exit(1);
|
|
254
259
|
}
|