api-core-lib 12.0.70 → 12.0.73

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 +62 -32
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -82,8 +82,8 @@ var toCamelCase = (str) => {
82
82
  const s = toPascalCase(str);
83
83
  return s.charAt(0).toLowerCase() + s.slice(1);
84
84
  };
85
- var getModuleName = (opId) => `${opId.split("_")[0].replace(/Controller$/, "")}Api`;
86
- var getActionName = (opId) => toCamelCase(opId.split("_")[1] || opId).replace(/V\d+$/, "");
85
+ var sanitizeForModuleName = (tagName) => `${toPascalCase(tagName.replace(/[^a-zA-Z0-9]/g, " "))}Api`;
86
+ var getActionName = (opId) => toCamelCase(opId.replace(/^(central|tenant)/i, "").replace(/_v\d+$/, ""));
87
87
  var findCommonPath = (paths) => {
88
88
  if (!paths || paths.length === 0) return "/";
89
89
  const sorted = [...paths].sort();
@@ -94,7 +94,6 @@ var findCommonPath = (paths) => {
94
94
  const prefix = first.substring(0, i);
95
95
  return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
96
96
  };
97
- var generateFriendlyMessage = (fieldName) => `${fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase())} is required.`;
98
97
  function parseSchema(name, schema, allEnums) {
99
98
  const properties = [];
100
99
  const enums = {};
@@ -137,9 +136,7 @@ function parseSpecToModules(spec) {
137
136
  if (schema.type === "array" && schema.items) {
138
137
  const itemSchema = schema.items;
139
138
  const itemBaseName = `${baseName}Item`;
140
- if (itemSchema.properties || itemSchema.type === "object") {
141
- return `${registerSchema(itemSchema, itemBaseName)}[]`;
142
- }
139
+ if (itemSchema.properties || itemSchema.type === "object") return `${registerSchema(itemSchema, itemBaseName)}[]`;
143
140
  return `${itemSchema.type || "unknown"}[]`;
144
141
  }
145
142
  if (schema.type === "object" || schema.properties || schema.allOf || !schema.type) {
@@ -155,8 +152,9 @@ function parseSpecToModules(spec) {
155
152
  for (const method in pathItem) {
156
153
  if (!Object.values(import_openapi_types.OpenAPIV3.HttpMethods).includes(method)) continue;
157
154
  const endpoint = pathItem[method];
158
- if (!endpoint.operationId) continue;
159
- const moduleName = getModuleName(endpoint.operationId);
155
+ if (!endpoint.tags || endpoint.tags.length === 0 || !endpoint.operationId) continue;
156
+ const tagName = endpoint.tags[0];
157
+ const moduleName = sanitizeForModuleName(tagName);
160
158
  if (!modules.has(moduleName)) {
161
159
  modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set(), enums: /* @__PURE__ */ new Set() });
162
160
  modulePaths.set(moduleName, []);
@@ -178,7 +176,8 @@ function parseSpecToModules(spec) {
178
176
  if (schemaDef) Object.keys(schemaDef.enums).forEach((propName) => currentModule.enums.add(`${toPascalCase(cleanType)}${toPascalCase(propName)}Enum`));
179
177
  }
180
178
  });
181
- currentModule.actions[getActionName(endpoint.operationId)] = { name: getActionName(endpoint.operationId), method: method.toUpperCase(), path: apiPath, description: endpoint.summary || "", hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"), autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"), requiresAuth: !!endpoint.security && endpoint.security.length > 0, inputType, outputType };
179
+ const actionName = getActionName(endpoint.operationId);
180
+ currentModule.actions[actionName] = { name: actionName, method: method.toUpperCase(), path: apiPath, description: endpoint.summary || "", hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"), autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"), requiresAuth: !!endpoint.security && endpoint.security.length > 0, inputType, outputType };
182
181
  }
183
182
  }
184
183
  modules.forEach((mod, name) => {
@@ -265,9 +264,7 @@ ${prop.example ? ` * @example ${JSON.stringify(prop.example)}
265
264
  let propType = prop.type;
266
265
  if (prop.enum) propType = `${toPascalCase(typeName)}${toPascalCase(prop.name)}Enum`;
267
266
  else if (prop.items) propType = prop.items.name ? `${toPascalCase(prop.items.name)}[]` : `${prop.items.type || "unknown"}[]`;
268
- else if (prop.type === "object") propType = prop.properties && prop.properties.length > 0 ? `{
269
- ${prop.properties.map((p) => ` ${p.name}${p.isRequired ? "" : "?"}: ${p.type};
270
- `).join("")} }` : `Record<string, unknown>`;
267
+ else if (prop.type === "object") propType = prop.properties && prop.properties.length > 0 ? `Record<string, unknown>` : `Record<string, unknown>`;
271
268
  typesContent += ` ${prop.name}${prop.isRequired ? "" : "?"}: ${propType};
272
269
  `;
273
270
  }
@@ -288,7 +285,7 @@ import { z } from 'zod';
288
285
  for (const typeName of schemasToImport) {
289
286
  const parsedSchema = allSchemas.get(typeName);
290
287
  if (parsedSchema) {
291
- let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p, typeName)}`).join(",\n");
288
+ let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
292
289
  validationContent += `export const ${typeName}Schema = z.object({
293
290
  ${zodShape}
294
291
  });
@@ -324,37 +321,70 @@ import type { ${schemasToImport.join(", ")} } from './types';
324
321
  import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent.join("\n"));
325
322
  console.log(import_chalk.default.gray(` \u2713 index.ts`));
326
323
  }
327
- function _propToZod(prop, parentName) {
328
- let zodString = "z.any()";
329
- const errorParams = { required_error: prop.description || generateFriendlyMessage(prop.name) };
324
+ function _propToZod(prop) {
325
+ let chain;
326
+ const requiredErrorMessage = { required_error: `${prop.name} is required.` };
330
327
  switch (prop.type) {
331
328
  case "string":
332
- zodString = `z.string(${JSON.stringify(errorParams)})`;
333
- if (prop.format === "email") zodString += `.email({ message: "Invalid email address" })`;
334
- if (prop.format === "uuid") zodString += `.uuid()`;
335
- if (prop.enum) zodString = `z.enum(${toPascalCase(parentName)}${toPascalCase(prop.name)}Enum, ${JSON.stringify(errorParams)})`;
329
+ chain = `z.string({ ...requiredErrorMessage, invalid_type_error: "Expected a string for ${prop.name}" })`;
330
+ if (prop.format === "email") chain += `.email({ message: "Invalid email address for ${prop.name}" })`;
331
+ if (prop.format === "uuid") chain += `.uuid({ message: "Invalid UUID for ${prop.name}" })`;
332
+ if (prop.format === "url") chain += `.url({ message: "Invalid URL for ${prop.name}" })`;
333
+ if (prop.format === "datetime") chain += `.datetime({ message: "Invalid datetime format for ${prop.name}" })`;
334
+ if (prop.minLength !== void 0) chain += `.min(${prop.minLength}, { message: "${prop.name} must be at least ${prop.minLength} characters long" })`;
335
+ if (prop.maxLength !== void 0) chain += `.max(${prop.maxLength}, { message: "${prop.name} must be at most ${prop.maxLength} characters long" })`;
336
+ if (prop.pattern) chain += `.regex(/${prop.pattern}/, { message: "Invalid format for ${prop.name}" })`;
337
+ if (prop.enum) {
338
+ if (prop.enum.length > 0) {
339
+ chain = `z.enum(${JSON.stringify(prop.enum)})`;
340
+ } else {
341
+ chain = `z.string().refine(() => false, { message: "Enum for ${prop.name} is empty" })`;
342
+ }
343
+ }
336
344
  break;
337
345
  case "integer":
346
+ chain = `z.number({ ...requiredErrorMessage, invalid_type_error: "Expected a number for ${prop.name}" }).int({ message: "${prop.name} must be an integer" })`;
347
+ if (prop.minimum !== void 0) chain += `.min(${prop.minimum}, { message: "${prop.name} must be at least ${prop.minimum}" })`;
348
+ if (prop.maximum !== void 0) chain += `.max(${prop.maximum}, { message: "${prop.name} must be at most ${prop.maximum}" })`;
349
+ break;
338
350
  case "number":
339
- zodString = `z.number(${JSON.stringify(errorParams)})`;
351
+ chain = `z.number({ ...requiredErrorMessage, invalid_type_error: "Expected a number for ${prop.name}" })`;
352
+ if (prop.minimum !== void 0) chain += `.min(${prop.minimum}, { message: "${prop.name} must be at least ${prop.minimum}" })`;
353
+ if (prop.maximum !== void 0) chain += `.max(${prop.maximum}, { message: "${prop.name} must be at most ${prop.maximum}" })`;
340
354
  break;
341
355
  case "boolean":
342
- zodString = `z.boolean(${JSON.stringify(errorParams)})`;
356
+ chain = `z.boolean({ ...requiredErrorMessage, invalid_type_error: "Expected a boolean for ${prop.name}" })`;
343
357
  break;
344
358
  case "array":
345
- zodString = `z.array(${prop.items ? _propToZod(prop.items, `${parentName}${toPascalCase(prop.name)}Item`) : "z.any()"})`;
359
+ const itemSchema = prop.items ? _propToZod(prop.items) : "z.any()";
360
+ chain = `z.array(${itemSchema})`;
361
+ if (prop.minItems !== void 0) chain += `.min(${prop.minItems}, { message: "${prop.name} must contain at least ${prop.minItems} item(s)" })`;
362
+ if (prop.maxItems !== void 0) chain += `.max(${prop.maxItems}, { message: "${prop.name} must contain at most ${prop.maxItems} item(s)" })`;
346
363
  break;
347
364
  case "object":
348
- let shape = "z.record(z.unknown())";
349
- if (prop.properties) shape = `z.object({
350
- ${prop.properties.map((p) => ` ${p.name}: ${_propToZod(p, `${parentName}${toPascalCase(prop.name)}`)}`).join(",\n")}
351
- })`;
352
- zodString = shape;
365
+ if (prop.properties && prop.properties.length > 0) {
366
+ const shape = prop.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
367
+ chain = `z.object({
368
+ ${shape}
369
+ })`;
370
+ } else {
371
+ chain = "z.record(z.unknown())";
372
+ }
353
373
  break;
374
+ default:
375
+ chain = "z.any()";
376
+ break;
377
+ }
378
+ if (prop.description) {
379
+ chain += `.describe(${JSON.stringify(prop.description)})`;
380
+ }
381
+ if (!prop.isRequired) {
382
+ chain += ".optional()";
383
+ }
384
+ if (prop.isNullable) {
385
+ chain += ".nullable()";
354
386
  }
355
- if (!prop.isRequired) zodString = zodString.replace(/\(.*\)/, "").trim() + ".optional()";
356
- if (prop.isNullable) zodString += ".nullable()";
357
- return zodString;
387
+ return chain;
358
388
  }
359
389
  function _propToMock(prop) {
360
390
  if (prop.example) return prop.example;
@@ -383,7 +413,7 @@ function _propToMock(prop) {
383
413
  }
384
414
  }
385
415
  async function runGenerator(options) {
386
- console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (Diamond Edition)..."));
416
+ console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (Sapphire Edition)..."));
387
417
  import_dotenv.default.config({ path: options.envPath });
388
418
  const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
389
419
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-core-lib",
3
- "version": "12.0.70",
3
+ "version": "12.0.73",
4
4
  "description": "A flexible and powerful API client library for modern web applications.",
5
5
  "type": "module",
6
6
  "exports": {