api-core-lib 12.0.37 → 12.0.39

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 +66 -32
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -36,10 +36,14 @@ var import_dotenv = __toESM(require("dotenv"), 1);
36
36
  var import_child_process = require("child_process");
37
37
 
38
38
  // src/generator/module-parser.ts
39
+ function sanitizeActionName(operationId) {
40
+ if (!operationId) return `unnamedAction_${Date.now()}`;
41
+ const name = operationId.split("_").slice(1).join("_");
42
+ return name.charAt(0).toLowerCase() + name.slice(1).replace(/_v\d+$/, "");
43
+ }
39
44
  function refToTypeName(ref) {
40
45
  if (!ref) return "unknown";
41
- const parts = ref.replace(/^#\/components\//, "").split("/");
42
- return `components["${parts.join('"]["')}"]`;
46
+ return ref.split("/").pop() || "unknown";
43
47
  }
44
48
  function parseSpecToModules(spec) {
45
49
  const modules = {};
@@ -50,23 +54,37 @@ function parseSpecToModules(spec) {
50
54
  const tagName = endpoint.tags[0];
51
55
  const moduleName = tagName.replace(/[^a-zA-Z0-9]/g, "").replace(/Central|Tenant/g, "") + "Api";
52
56
  if (!modules[moduleName]) {
53
- modules[moduleName] = { actions: {} };
57
+ const commonPath = apiPath.substring(0, apiPath.lastIndexOf("/"));
58
+ modules[moduleName] = { baseEndpoint: commonPath || "/", actions: {} };
54
59
  }
55
- const requestBodyRef = endpoint.requestBody?.content["application/json"]?.schema?.$ref;
60
+ const requestBody = endpoint.requestBody?.content?.["application/json"]?.schema;
56
61
  const successResponse = endpoint.responses["200"] || endpoint.responses["201"];
57
- const responseRef = successResponse?.content?.["application/json"]?.schema?.$ref;
58
- const actionName = endpoint.operationId || `${method}${apiPath.replace(/[\/{}]+/g, "_")}`;
62
+ const responseSchema = successResponse?.content?.["application/json"]?.schema;
63
+ let outputType = "unknown";
64
+ if (responseSchema) {
65
+ if (responseSchema.$ref) {
66
+ outputType = refToTypeName(responseSchema.$ref);
67
+ } else if (responseSchema.type === "array" && responseSchema.items?.$ref) {
68
+ outputType = `${refToTypeName(responseSchema.items.$ref)}[]`;
69
+ }
70
+ }
71
+ let inputType = "undefined";
72
+ if (requestBody) {
73
+ inputType = refToTypeName(requestBody.$ref);
74
+ } else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
75
+ inputType = "QueryOptions";
76
+ }
77
+ const actionName = sanitizeActionName(endpoint.operationId);
78
+ const relativePath = apiPath.replace(modules[moduleName].baseEndpoint, "") || "/";
59
79
  modules[moduleName].actions[actionName] = {
60
80
  method: method.toUpperCase(),
61
- path: apiPath,
81
+ path: relativePath,
62
82
  description: endpoint.summary || "No description available.",
63
83
  hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"),
64
84
  autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"),
65
85
  invalidates: [],
66
- // [ميزة جديدة] إضافة الأنواع المستخرجة إلى الكائن
67
- // سنستخدمها لاحقًا لتوليد الكود الصحيح
68
- _inputType: refToTypeName(requestBodyRef),
69
- _outputType: refToTypeName(responseRef)
86
+ _inputType: inputType,
87
+ _outputType: outputType
70
88
  };
71
89
  }
72
90
  }
@@ -99,20 +117,31 @@ async function runGenerator(options) {
99
117
  console.log(import_chalk.default.green(`\u2713 OpenAPI spec saved temporarily to ${tempSpecPath}`));
100
118
  console.log("\n" + import_chalk.default.blue("Step 3: Generating organized TypeScript types..."));
101
119
  const typesOutputPath = import_path.default.join(options.output, "types");
102
- const generatorCommand = [
103
- "npx",
104
- "@openapitools/openapi-generator-cli",
105
- "generate",
106
- "-i",
107
- `"${tempSpecPath}"`,
108
- "-g",
109
- "typescript-axios",
110
- "-o",
111
- `"${typesOutputPath}"`,
112
- "--additional-properties=supportsES6=true,useSingleRequestParameter=true,withInterfaces=true,modelPropertyNaming=original"
113
- ].join(" ");
114
- console.log(import_chalk.default.gray(`Executing: ${generatorCommand}`));
115
- (0, import_child_process.execSync)(generatorCommand, { stdio: "inherit" });
120
+ const ignoreFilePath = import_path.default.join(typesOutputPath, ".openapi-generator-ignore");
121
+ const ignoreContent = `
122
+ # Ignore helper files and documentation that we don't need in a TypeScript project.
123
+
124
+ # Main generator metadata
125
+ .openapi-generator/
126
+
127
+ # Documentation files
128
+ docs/
129
+
130
+ # Git helper files
131
+ .gitignore
132
+ git_push.sh
133
+
134
+ # NPM helper files
135
+ .npmignore
136
+ README.md
137
+ `;
138
+ if (!import_fs.default.existsSync(typesOutputPath)) {
139
+ import_fs.default.mkdirSync(typesOutputPath, { recursive: true });
140
+ }
141
+ import_fs.default.writeFileSync(ignoreFilePath, ignoreContent);
142
+ console.log(import_chalk.default.gray("\u2713 Created .openapi-generator-ignore to ensure clean output."));
143
+ console.log(import_chalk.default.gray(`Executing: ${ignoreContent}`));
144
+ (0, import_child_process.execSync)(ignoreContent, { stdio: "inherit" });
116
145
  console.log(import_chalk.default.green(`\u2713 Types generated successfully at ${typesOutputPath}`));
117
146
  console.log("\n" + import_chalk.default.blue("Step 4: Generating custom API modules..."));
118
147
  const modules = parseSpecToModules(spec);
@@ -120,14 +149,19 @@ async function runGenerator(options) {
120
149
  if (!import_fs.default.existsSync(modulesOutputPath)) {
121
150
  import_fs.default.mkdirSync(modulesOutputPath, { recursive: true });
122
151
  }
152
+ const allModelTypes = /* @__PURE__ */ new Set();
153
+ Object.values(modules).forEach((mod) => {
154
+ Object.values(mod.actions).forEach((action) => {
155
+ if (action._inputType && !["unknown", "undefined", "QueryOptions"].includes(action._inputType)) allModelTypes.add(action._inputType.replace("[]", ""));
156
+ if (action._outputType && !["unknown"].includes(action._outputType)) allModelTypes.add(action._outputType.replace("[]", ""));
157
+ });
158
+ });
123
159
  for (const moduleName in modules) {
124
160
  const moduleData = modules[moduleName];
125
161
  const fileName = `${moduleName}.module.ts`;
126
162
  const filePath = import_path.default.join(modulesOutputPath, fileName);
127
163
  const actionsTypeParts = Object.entries(moduleData.actions).map(([actionName, actionData]) => {
128
- const inputType = actionData._inputType !== "unknown" ? actionData._inputType : actionData.hasQuery ? "QueryOptions" : "undefined";
129
- const outputType = actionData._outputType;
130
- return ` ${actionName}: ActionConfigModule<${inputType}, ${outputType}>;`;
164
+ return ` ${actionName}: ActionConfigModule<${actionData._inputType}, ${actionData._outputType}>;`;
131
165
  });
132
166
  const actionsTypeDefinition = `{
133
167
  ${actionsTypeParts.join("\n")}
@@ -146,14 +180,14 @@ ${actionsValueParts.join(",\n")}
146
180
  */
147
181
 
148
182
  import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
149
- import type { components } from '../types/api-types.generated';
183
+ // [\u0625\u0635\u0644\u0627\u062D] \u0627\u0633\u062A\u064A\u0631\u0627\u062F \u0627\u0644\u0623\u0646\u0648\u0627\u0639 \u0645\u0646 \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0631\u0626\u064A\u0633\u064A \u0627\u0644\u0645\u0646\u0638\u0645
184
+ import type { ${[...allModelTypes].join(", ")} } from '../types';
150
185
 
151
186
  /**
152
187
  * Defines the configuration for the ${moduleName} API module.
153
- * This is a strongly-typed configuration object that ensures type safety.
154
188
  */
155
- export const ${moduleName}Module: ApiModuleCodeConfig<${actionsTypeDefinition}> = {
156
- baseEndpoint: '/api/v1', // \u064A\u0645\u0643\u0646\u0643 \u062C\u0639\u0644\u0647 \u062F\u064A\u0646\u0627\u0645\u064A\u0643\u064A\u064B\u0627
189
+ export const ${moduleName}Module: ApiModuleConfig<${actionsTypeDefinition}> = {
190
+ baseEndpoint: '${moduleData.baseEndpoint}',
157
191
  actions: ${actionsValueDefinition},
158
192
  };
159
193
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-core-lib",
3
- "version": "12.0.37",
3
+ "version": "12.0.39",
4
4
  "description": "A flexible and powerful API client library for modern web applications.",
5
5
  "type": "module",
6
6
  "exports": {