api-core-lib 12.0.43 → 12.0.45
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 +38 -110
- package/package.json +3 -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_extra = __toESM(require("fs-extra"), 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);
|
|
@@ -70,7 +70,11 @@ function parseSpecToModules(spec) {
|
|
|
70
70
|
}
|
|
71
71
|
let inputType = "undefined";
|
|
72
72
|
if (requestBody) {
|
|
73
|
-
|
|
73
|
+
if (requestBody.$ref) {
|
|
74
|
+
inputType = refToTypeName(requestBody.$ref);
|
|
75
|
+
} else if (requestBody.type === "object") {
|
|
76
|
+
inputType = "any";
|
|
77
|
+
}
|
|
74
78
|
} else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
|
|
75
79
|
inputType = "QueryOptions";
|
|
76
80
|
}
|
|
@@ -94,137 +98,61 @@ function parseSpecToModules(spec) {
|
|
|
94
98
|
// src/generator/index.ts
|
|
95
99
|
async function runGenerator(options) {
|
|
96
100
|
console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Core Lib Code Generator..."));
|
|
97
|
-
console.log(import_chalk.default.gray(`Output directory: ${options.output}`));
|
|
98
|
-
console.log(import_chalk.default.gray(`.env path: ${options.envPath}`));
|
|
99
|
-
console.log("\n" + import_chalk.default.blue("Step 1: Loading environment variables..."));
|
|
100
101
|
import_dotenv.default.config({ path: options.envPath });
|
|
101
|
-
const specUrl = process.env.OPENAPI_SPEC_URL || (process.env.API_URL ? `${process.env.API_URL}/docs-json` : null)
|
|
102
|
+
const specUrl = process.env.OPENAPI_SPEC_URL || (process.env.API_URL ? `${process.env.API_URL}/docs-json` : null);
|
|
102
103
|
if (!specUrl) {
|
|
103
|
-
console.error(import_chalk.default.red.bold("\n\u274C Error:
|
|
104
|
-
console.error(import_chalk.default.red("Please define either OPENAPI_SPEC_URL (recommended) or API_URL/NEXT_PUBLIC_API_URL in your .env file."));
|
|
104
|
+
console.error(import_chalk.default.red.bold("\n\u274C Error: OPENAPI_SPEC_URL or API_URL not found in .env file."));
|
|
105
105
|
process.exit(1);
|
|
106
106
|
}
|
|
107
|
-
console.log(import_chalk.default.green("\u2713 Environment variables loaded."));
|
|
108
107
|
let tempSpecPath = "";
|
|
109
|
-
let
|
|
108
|
+
let tempOutputPath = "";
|
|
110
109
|
try {
|
|
111
|
-
console.log("\n" + import_chalk.default.blue(`Step
|
|
110
|
+
console.log("\n" + import_chalk.default.blue(`Step 1: Fetching OpenAPI spec from ${specUrl}...`));
|
|
112
111
|
tempSpecPath = import_path.default.join(process.cwd(), `swagger-${Date.now()}.json`);
|
|
113
112
|
const response = await import_axios.default.get(specUrl, { timeout: 15e3 });
|
|
114
113
|
const spec = response.data;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
console.log(import_chalk.default.green(`\u2713 OpenAPI spec saved temporarily to ${tempSpecPath}`));
|
|
120
|
-
console.log("\n" + import_chalk.default.blue("Step 3: Generating organized TypeScript types..."));
|
|
121
|
-
const typesOutputPath = import_path.default.join(options.output, "types");
|
|
122
|
-
ignoreFilePath = import_path.default.join(process.cwd(), `.openapi-generator-ignore-${Date.now()}`);
|
|
123
|
-
const ignoreContent = `
|
|
124
|
-
# Main generator metadata
|
|
125
|
-
.openapi-generator/
|
|
126
|
-
# Documentation files
|
|
127
|
-
docs/
|
|
128
|
-
# Git helper files
|
|
129
|
-
.gitignore
|
|
130
|
-
git_push.sh
|
|
131
|
-
# NPM helper files
|
|
132
|
-
.npmignore
|
|
133
|
-
README.md
|
|
134
|
-
`;
|
|
135
|
-
import_fs.default.writeFileSync(ignoreFilePath, ignoreContent);
|
|
136
|
-
console.log(import_chalk.default.gray("\u2713 Created temporary .openapi-generator-ignore file."));
|
|
114
|
+
import_fs_extra.default.writeFileSync(tempSpecPath, JSON.stringify(spec, null, 2));
|
|
115
|
+
console.log(import_chalk.default.green("\u2713 OpenAPI spec saved temporarily."));
|
|
116
|
+
console.log("\n" + import_chalk.default.blue("Step 2: Generating full API client in a temporary location..."));
|
|
117
|
+
tempOutputPath = import_path.default.join(process.cwd(), `api-temp-${Date.now()}`);
|
|
137
118
|
const generatorCommand = [
|
|
138
119
|
"npx --yes @openapitools/openapi-generator-cli generate",
|
|
139
120
|
`-i "${tempSpecPath}"`,
|
|
140
121
|
`-g typescript-axios`,
|
|
141
|
-
`-o "${
|
|
142
|
-
`--
|
|
143
|
-
// ==========================================================
|
|
144
|
-
// ## البداية: التعديل النهائي والنهج الصحيح ##
|
|
145
|
-
// ==========================================================
|
|
146
|
-
// [إصلاح] هذا هو النهج الصحيح لتوليد النماذج فقط.
|
|
147
|
-
// نحن نحدد بالضبط ما نريد توليده (Models) وما لا نريده (APIs, Supporting Files).
|
|
148
|
-
"--global-property models,apis=false,supportingFiles=false",
|
|
149
|
-
// ==========================================================
|
|
150
|
-
// ## النهاية: التعديل النهائي والنهج الصحيح ##
|
|
151
|
-
// ==========================================================
|
|
152
|
-
`--additional-properties=supportsES6=true,useSingleRequestParameter=true,withInterfaces=true,modelPropertyNaming=original`
|
|
122
|
+
`-o "${tempOutputPath}"`,
|
|
123
|
+
`--additional-properties=supportsES6=true,withInterfaces=true,modelPropertyNaming=original`
|
|
153
124
|
].join(" ");
|
|
154
|
-
console.log(import_chalk.default.gray(`Executing command: npx @openapitools/openapi-generator-cli...`));
|
|
155
125
|
(0, import_child_process.execSync)(generatorCommand, { stdio: "inherit" });
|
|
156
|
-
console.log(import_chalk.default.green(
|
|
126
|
+
console.log(import_chalk.default.green("\u2713 Full client generated successfully."));
|
|
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."));
|
|
157
142
|
console.log("\n" + import_chalk.default.blue("Step 4: Generating custom API modules..."));
|
|
158
143
|
const modules = parseSpecToModules(spec);
|
|
159
144
|
const modulesOutputPath = import_path.default.join(options.output, "modules");
|
|
160
|
-
|
|
161
|
-
import_fs.default.mkdirSync(modulesOutputPath, { recursive: true });
|
|
162
|
-
}
|
|
163
|
-
const allModelTypes = /* @__PURE__ */ new Set();
|
|
164
|
-
Object.values(modules).forEach((mod) => {
|
|
165
|
-
Object.values(mod.actions).forEach((action) => {
|
|
166
|
-
if (action._inputType && !["unknown", "undefined", "QueryOptions"].includes(action._inputType)) allModelTypes.add(action._inputType.replace("[]", ""));
|
|
167
|
-
if (action._outputType && !["unknown"].includes(action._outputType)) allModelTypes.add(action._outputType.replace("[]", ""));
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
for (const moduleName in modules) {
|
|
171
|
-
const moduleData = modules[moduleName];
|
|
172
|
-
const fileName = `${moduleName}.module.ts`;
|
|
173
|
-
const filePath = import_path.default.join(modulesOutputPath, fileName);
|
|
174
|
-
const actionsTypeParts = Object.entries(moduleData.actions).map(([actionName, actionData]) => ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`);
|
|
175
|
-
const actionsTypeDefinition = `{
|
|
176
|
-
${actionsTypeParts.join("\n")}
|
|
177
|
-
}`;
|
|
178
|
-
const actionsValueParts = Object.entries(moduleData.actions).map(([actionName, actionData]) => {
|
|
179
|
-
const { _inputType, _outputType, ...config } = actionData;
|
|
180
|
-
return ` ${actionName}: ${JSON.stringify(config, null, 2).replace(/\n/g, "\n ")}`;
|
|
181
|
-
});
|
|
182
|
-
const actionsValueDefinition = `{
|
|
183
|
-
${actionsValueParts.join(",\n")}
|
|
184
|
-
}`;
|
|
185
|
-
const fileContent = `/**
|
|
186
|
-
* This file is auto-generated by api-core-lib.
|
|
187
|
-
* Do not edit this file directly.
|
|
188
|
-
* @module ${moduleName}
|
|
189
|
-
*/
|
|
190
|
-
|
|
191
|
-
import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
|
|
192
|
-
import type { ${[...allModelTypes].join(", ")} } from '../types';
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Defines the configuration for the ${moduleName} API module.
|
|
196
|
-
*/
|
|
197
|
-
export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
|
|
198
|
-
baseEndpoint: '${moduleData.baseEndpoint}',
|
|
199
|
-
actions: ${actionsValueDefinition},
|
|
200
|
-
};
|
|
201
|
-
`;
|
|
202
|
-
import_fs.default.writeFileSync(filePath, fileContent);
|
|
203
|
-
console.log(import_chalk.default.green(`\u2713 Module generated: ${fileName}`));
|
|
204
|
-
}
|
|
145
|
+
import_fs_extra.default.ensureDirSync(modulesOutputPath);
|
|
205
146
|
console.log(import_chalk.default.green("\u2713 All custom modules generated."));
|
|
206
|
-
console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!
|
|
207
|
-
console.log(import_chalk.default.bold.cyan(options.output));
|
|
147
|
+
console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!"));
|
|
208
148
|
} catch (error) {
|
|
209
149
|
console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
|
|
210
|
-
|
|
211
|
-
console.error(import_chalk.default.red(`Network Error: ${error.message} (Status: ${error.response.status})`));
|
|
212
|
-
} else if (error.stderr) {
|
|
213
|
-
console.error(import_chalk.default.red(`Command Execution Error: ${error.message}`));
|
|
214
|
-
console.error(import_chalk.default.gray(error.stderr.toString()));
|
|
215
|
-
} else {
|
|
216
|
-
console.error(import_chalk.default.red(error.message));
|
|
217
|
-
}
|
|
150
|
+
console.error(error.message);
|
|
218
151
|
process.exit(1);
|
|
219
152
|
} finally {
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
if (ignoreFilePath && import_fs.default.existsSync(ignoreFilePath)) {
|
|
225
|
-
import_fs.default.unlinkSync(ignoreFilePath);
|
|
226
|
-
console.log(import_chalk.default.gray("Temporary ignore file cleaned up."));
|
|
227
|
-
}
|
|
153
|
+
if (import_fs_extra.default.existsSync(tempSpecPath)) import_fs_extra.default.unlinkSync(tempSpecPath);
|
|
154
|
+
if (import_fs_extra.default.existsSync(tempOutputPath)) import_fs_extra.default.rmSync(tempOutputPath, { recursive: true, force: true });
|
|
155
|
+
console.log(import_chalk.default.gray("\nTemporary files and folders cleaned up."));
|
|
228
156
|
}
|
|
229
157
|
}
|
|
230
158
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-core-lib",
|
|
3
|
-
"version": "12.0.
|
|
3
|
+
"version": "12.0.45",
|
|
4
4
|
"description": "A flexible and powerful API client library for modern web applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -42,12 +42,14 @@
|
|
|
42
42
|
"commander": "^9.4.1",
|
|
43
43
|
"dotenv": "^16.0.3",
|
|
44
44
|
"fast-deep-equal": "^3.1.3",
|
|
45
|
+
"fs-extra": "^11.3.1",
|
|
45
46
|
"openapi-typescript": "^6.2.4",
|
|
46
47
|
"path": "^0.12.7",
|
|
47
48
|
"uuid": "^9.0.1"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@openapitools/openapi-generator-cli": "^2.23.1",
|
|
52
|
+
"@types/fs-extra": "^11.0.4",
|
|
51
53
|
"@types/jest": "^30.0.0",
|
|
52
54
|
"@types/node": "^24.2.1",
|
|
53
55
|
"@types/react": "^18.3.2",
|