api-core-lib 12.0.45 → 12.0.47
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 +86 -37
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -28,7 +28,7 @@ var import_commander = require("commander");
|
|
|
28
28
|
var import_path2 = __toESM(require("path"), 1);
|
|
29
29
|
|
|
30
30
|
// src/generator/index.ts
|
|
31
|
-
var
|
|
31
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
32
32
|
var import_path = __toESM(require("path"), 1);
|
|
33
33
|
var import_axios = __toESM(require("axios"), 1);
|
|
34
34
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
@@ -55,7 +55,7 @@ function parseSpecToModules(spec) {
|
|
|
55
55
|
const moduleName = tagName.replace(/[^a-zA-Z0-9]/g, "").replace(/Central|Tenant/g, "") + "Api";
|
|
56
56
|
if (!modules[moduleName]) {
|
|
57
57
|
const commonPath = apiPath.substring(0, apiPath.lastIndexOf("/"));
|
|
58
|
-
modules[moduleName] = { baseEndpoint: commonPath || "/", actions: {} };
|
|
58
|
+
modules[moduleName] = { baseEndpoint: commonPath || "/", actions: {}, types: /* @__PURE__ */ new Set() };
|
|
59
59
|
}
|
|
60
60
|
const requestBody = endpoint.requestBody?.content?.["application/json"]?.schema;
|
|
61
61
|
const successResponse = endpoint.responses["200"] || endpoint.responses["201"];
|
|
@@ -78,6 +78,11 @@ function parseSpecToModules(spec) {
|
|
|
78
78
|
} else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
|
|
79
79
|
inputType = "QueryOptions";
|
|
80
80
|
}
|
|
81
|
+
[inputType, outputType].forEach((t) => {
|
|
82
|
+
if (t && t !== "unknown" && t !== "undefined" && t !== "any" && t !== "QueryOptions") {
|
|
83
|
+
modules[moduleName].types.add(t.replace("[]", ""));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
81
86
|
const actionName = sanitizeActionName(endpoint.operationId);
|
|
82
87
|
const relativePath = apiPath.replace(modules[moduleName].baseEndpoint, "") || "/";
|
|
83
88
|
modules[moduleName].actions[actionName] = {
|
|
@@ -98,61 +103,105 @@ function parseSpecToModules(spec) {
|
|
|
98
103
|
// src/generator/index.ts
|
|
99
104
|
async function runGenerator(options) {
|
|
100
105
|
console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Core Lib Code Generator..."));
|
|
106
|
+
console.log(import_chalk.default.gray(`Output directory: ${options.output}`));
|
|
107
|
+
console.log(import_chalk.default.gray(`.env path: ${options.envPath}`));
|
|
108
|
+
console.log("\n" + import_chalk.default.blue("Step 1: Loading environment variables..."));
|
|
101
109
|
import_dotenv.default.config({ path: options.envPath });
|
|
102
|
-
const specUrl = process.env.OPENAPI_SPEC_URL || (process.env.API_URL ? `${process.env.API_URL}/docs-json` : null);
|
|
110
|
+
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);
|
|
103
111
|
if (!specUrl) {
|
|
104
|
-
console.error(import_chalk.default.red.bold("\n\u274C Error:
|
|
112
|
+
console.error(import_chalk.default.red.bold("\n\u274C Error: API specification URL not found."));
|
|
113
|
+
console.error(import_chalk.default.red("Please define either OPENAPI_SPEC_URL (recommended) or API_URL/NEXT_PUBLIC_API_URL in your .env file."));
|
|
105
114
|
process.exit(1);
|
|
106
115
|
}
|
|
116
|
+
console.log(import_chalk.default.green("\u2713 Environment variables loaded."));
|
|
107
117
|
let tempSpecPath = "";
|
|
108
|
-
let
|
|
118
|
+
let ignoreFilePath = "";
|
|
109
119
|
try {
|
|
110
|
-
console.log("\n" + import_chalk.default.blue(`Step
|
|
120
|
+
console.log("\n" + import_chalk.default.blue(`Step 2: Fetching OpenAPI spec from ${specUrl}...`));
|
|
111
121
|
tempSpecPath = import_path.default.join(process.cwd(), `swagger-${Date.now()}.json`);
|
|
112
122
|
const response = await import_axios.default.get(specUrl, { timeout: 15e3 });
|
|
113
123
|
const spec = response.data;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
124
|
+
if (!spec.openapi || !spec.paths) {
|
|
125
|
+
throw new Error('Invalid OpenAPI specification file. "openapi" or "paths" property is missing.');
|
|
126
|
+
}
|
|
127
|
+
import_fs.default.writeFileSync(tempSpecPath, JSON.stringify(spec, null, 2));
|
|
128
|
+
console.log(import_chalk.default.green(`\u2713 OpenAPI spec saved temporarily to ${tempSpecPath}`));
|
|
129
|
+
console.log("\n" + import_chalk.default.blue("Step 3: Generating organized TypeScript types..."));
|
|
130
|
+
const typesOutputPath = import_path.default.join(options.output, "types");
|
|
118
131
|
const generatorCommand = [
|
|
119
|
-
"npx --yes
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
`-o "${tempOutputPath}"`,
|
|
123
|
-
`--additional-properties=supportsES6=true,withInterfaces=true,modelPropertyNaming=original`
|
|
132
|
+
"npx --yes openapi-typescript",
|
|
133
|
+
`"${tempSpecPath}"`,
|
|
134
|
+
`--output "${import_path.default.join(typesOutputPath, "schema.d.ts")}"`
|
|
124
135
|
].join(" ");
|
|
136
|
+
console.log(import_chalk.default.gray(`Executing command: npx openapi-typescript...`));
|
|
125
137
|
(0, import_child_process.execSync)(generatorCommand, { stdio: "inherit" });
|
|
126
|
-
console.log(import_chalk.default.green(
|
|
127
|
-
console.log("\n" + import_chalk.default.blue("Step 3: Restructuring and copying necessary files..."));
|
|
128
|
-
const finalTypesPath = import_path.default.join(options.output, "types");
|
|
129
|
-
const tempModelsPath = import_path.default.join(tempOutputPath, "models");
|
|
130
|
-
const tempIndexPath = import_path.default.join(tempOutputPath, "index.ts");
|
|
131
|
-
import_fs_extra.default.ensureDirSync(finalTypesPath);
|
|
132
|
-
import_fs_extra.default.emptyDirSync(finalTypesPath);
|
|
133
|
-
if (import_fs_extra.default.existsSync(tempModelsPath)) {
|
|
134
|
-
import_fs_extra.default.copySync(tempModelsPath, import_path.default.join(finalTypesPath, "models"));
|
|
135
|
-
console.log(import_chalk.default.gray("\u2713 Copied models directory."));
|
|
136
|
-
}
|
|
137
|
-
if (import_fs_extra.default.existsSync(tempIndexPath)) {
|
|
138
|
-
import_fs_extra.default.copySync(tempIndexPath, import_path.default.join(finalTypesPath, "index.ts"));
|
|
139
|
-
console.log(import_chalk.default.gray("\u2713 Copied main index file."));
|
|
140
|
-
}
|
|
141
|
-
console.log(import_chalk.default.green("\u2713 Necessary type files have been structured."));
|
|
138
|
+
console.log(import_chalk.default.green(`\u2713 Types generated successfully at ${typesOutputPath}`));
|
|
142
139
|
console.log("\n" + import_chalk.default.blue("Step 4: Generating custom API modules..."));
|
|
143
140
|
const modules = parseSpecToModules(spec);
|
|
144
141
|
const modulesOutputPath = import_path.default.join(options.output, "modules");
|
|
145
|
-
|
|
142
|
+
if (!import_fs.default.existsSync(modulesOutputPath)) {
|
|
143
|
+
import_fs.default.mkdirSync(modulesOutputPath, { recursive: true });
|
|
144
|
+
}
|
|
145
|
+
for (const moduleName in modules) {
|
|
146
|
+
const moduleData = modules[moduleName];
|
|
147
|
+
const moduleFolderPath = import_path.default.join(modulesOutputPath, moduleName);
|
|
148
|
+
if (!import_fs.default.existsSync(moduleFolderPath)) {
|
|
149
|
+
import_fs.default.mkdirSync(moduleFolderPath, { recursive: true });
|
|
150
|
+
}
|
|
151
|
+
const typesFilePath = import_path.default.join(moduleFolderPath, "types.ts");
|
|
152
|
+
const typesContent = moduleData.types.size ? `export type { ${[...moduleData.types].join(", ")} } from '../../types';` : `// No types used in this module`;
|
|
153
|
+
import_fs.default.writeFileSync(typesFilePath, typesContent);
|
|
154
|
+
const actionsTypeParts = Object.entries(moduleData.actions).map(
|
|
155
|
+
([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`
|
|
156
|
+
);
|
|
157
|
+
const actionsTypeDefinition = `{
|
|
158
|
+
${actionsTypeParts.join("\n")}
|
|
159
|
+
}`;
|
|
160
|
+
const actionsValueParts = Object.entries(moduleData.actions).map(
|
|
161
|
+
([actionName, actionData]) => {
|
|
162
|
+
const { _inputType, _outputType, ...config } = actionData;
|
|
163
|
+
return ` ${actionName}: ${JSON.stringify(config, null, 2).replace(/\n/g, "\n ")}`;
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
const actionsValueDefinition = `{
|
|
167
|
+
${actionsValueParts.join(",\n")}
|
|
168
|
+
}`;
|
|
169
|
+
const configFilePath = import_path.default.join(moduleFolderPath, "config.ts");
|
|
170
|
+
const configContent = `
|
|
171
|
+
import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
|
|
172
|
+
import type { ${[...moduleData.types].join(", ")} } from './types';
|
|
173
|
+
|
|
174
|
+
export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
|
|
175
|
+
baseEndpoint: '${moduleData.baseEndpoint}',
|
|
176
|
+
actions: ${actionsValueDefinition},
|
|
177
|
+
};
|
|
178
|
+
`;
|
|
179
|
+
import_fs.default.writeFileSync(configFilePath, configContent);
|
|
180
|
+
console.log(import_chalk.default.green(`\u2713 Module generated: ${moduleName}/`));
|
|
181
|
+
}
|
|
146
182
|
console.log(import_chalk.default.green("\u2713 All custom modules generated."));
|
|
147
|
-
console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!"));
|
|
183
|
+
console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete! All files are located in:"));
|
|
184
|
+
console.log(import_chalk.default.bold.cyan(options.output));
|
|
148
185
|
} catch (error) {
|
|
149
186
|
console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
|
|
150
|
-
|
|
187
|
+
if (error.response) {
|
|
188
|
+
console.error(import_chalk.default.red(`Network Error: ${error.message} (Status: ${error.response.status})`));
|
|
189
|
+
} else if (error.stderr) {
|
|
190
|
+
console.error(import_chalk.default.red(`Command Execution Error: ${error.message}`));
|
|
191
|
+
console.error(import_chalk.default.gray(error.stderr.toString()));
|
|
192
|
+
} else {
|
|
193
|
+
console.error(import_chalk.default.red(error.message));
|
|
194
|
+
}
|
|
151
195
|
process.exit(1);
|
|
152
196
|
} finally {
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
197
|
+
if (tempSpecPath && import_fs.default.existsSync(tempSpecPath)) {
|
|
198
|
+
import_fs.default.unlinkSync(tempSpecPath);
|
|
199
|
+
console.log(import_chalk.default.gray("\nTemporary spec file cleaned up."));
|
|
200
|
+
}
|
|
201
|
+
if (ignoreFilePath && import_fs.default.existsSync(ignoreFilePath)) {
|
|
202
|
+
import_fs.default.unlinkSync(ignoreFilePath);
|
|
203
|
+
console.log(import_chalk.default.gray("Temporary ignore file cleaned up."));
|
|
204
|
+
}
|
|
156
205
|
}
|
|
157
206
|
}
|
|
158
207
|
|