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.
Files changed (2) hide show
  1. package/dist/cli.cjs +86 -37
  2. 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 import_fs_extra = __toESM(require("fs-extra"), 1);
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: OPENAPI_SPEC_URL or API_URL not found in .env file."));
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 tempOutputPath = "";
118
+ let ignoreFilePath = "";
109
119
  try {
110
- console.log("\n" + import_chalk.default.blue(`Step 1: Fetching OpenAPI spec from ${specUrl}...`));
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
- 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()}`);
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 @openapitools/openapi-generator-cli generate",
120
- `-i "${tempSpecPath}"`,
121
- `-g typescript-axios`,
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("\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."));
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
- import_fs_extra.default.ensureDirSync(modulesOutputPath);
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
- console.error(error.message);
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 (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."));
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-core-lib",
3
- "version": "12.0.45",
3
+ "version": "12.0.47",
4
4
  "description": "A flexible and powerful API client library for modern web applications.",
5
5
  "type": "module",
6
6
  "exports": {