api-core-lib 12.0.67 → 12.0.69

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 +199 -172
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -74,19 +74,17 @@ var import_chalk = __toESM(require("chalk"), 1);
74
74
  var import_dotenv = __toESM(require("dotenv"), 1);
75
75
  var import_swagger_parser = __toESM(require("@apidevtools/swagger-parser"), 1);
76
76
  var import_openapi_types = __toESM(require_dist(), 1);
77
- var import_json_schema_to_typescript = require("json-schema-to-typescript");
78
77
  var DEBUG_MODE = process.env.DEBUG === "true";
79
- var debugLog = (title, data) => {
80
- if (DEBUG_MODE) {
81
- console.log(import_chalk.default.yellow(`
82
- [DEBUG: ${title}]`));
83
- console.log(import_util.default.inspect(data, { depth: null, colors: true }));
84
- }
85
- };
78
+ var debugLog = (title, data) => DEBUG_MODE && console.log(import_chalk.default.yellow(`
79
+ [DEBUG: ${title}]`), import_util.default.inspect(data, { depth, colors: true }));
86
80
  var toPascalCase = (str) => str.replace(/[^a-zA-Z0-9_]/g, " ").replace(/(?:^\w|[A-Z]|\b\w)/g, (w) => w.toUpperCase()).replace(/\s+/g, "");
87
- var getModuleNameFromOpId = (opId) => `${opId.split("_")[0].replace(/Controller$/, "")}Api`;
88
- var getActionNameFromOpId = (opId) => (opId.split("_")[1] || opId).replace(/^\w/, (c) => c.toLowerCase());
89
- var findCommonBasePath = (paths) => {
81
+ var toCamelCase = (str) => {
82
+ const s = toPascalCase(str);
83
+ return s.charAt(0).toLowerCase() + s.slice(1);
84
+ };
85
+ var getModuleName = (opId) => `${opId.split("_")[0].replace(/Controller$/, "")}Api`;
86
+ var getActionName = (opId) => toCamelCase(opId.split("_")[1] || opId);
87
+ var findCommonPath = (paths) => {
90
88
  if (!paths || paths.length === 0) return "/";
91
89
  const sorted = [...paths].sort();
92
90
  const first = sorted[0];
@@ -96,15 +94,52 @@ var findCommonBasePath = (paths) => {
96
94
  const prefix = first.substring(0, i);
97
95
  return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
98
96
  };
97
+ var generateFriendlyMessage = (fieldName, validation) => {
98
+ const friendlyName = fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
99
+ return `${friendlyName} is required.`;
100
+ };
101
+ function parseSchema(name, schema, allEnums) {
102
+ const properties = [];
103
+ const enums = {};
104
+ if (schema.properties) {
105
+ for (const propName in schema.properties) {
106
+ const propSchema = schema.properties[propName];
107
+ if (propSchema.enum) {
108
+ const enumName = `${toPascalCase(name)}${toPascalCase(propName)}Enum`;
109
+ enums[propName] = propSchema.enum;
110
+ if (!allEnums.has(enumName)) allEnums.set(enumName, { name: enumName, values: propSchema.enum });
111
+ }
112
+ properties.push({
113
+ name: propName,
114
+ type: propSchema.type || "object",
115
+ isRequired: (schema.required || []).includes(propName),
116
+ isNullable: propSchema.nullable || false,
117
+ description: propSchema.description,
118
+ example: propSchema.example,
119
+ enum: propSchema.enum,
120
+ format: propSchema.format,
121
+ items: propSchema.type === "array" && propSchema.items ? parseSchema(`${name}${toPascalCase(propName)}Item`, propSchema.items, allEnums).properties[0] : void 0,
122
+ properties: propSchema.properties ? parseSchema(`${name}${toPascalCase(propName)}`, propSchema, allEnums).properties : void 0
123
+ });
124
+ }
125
+ }
126
+ return { name, description: schema.description, properties, enums };
127
+ }
99
128
  function parseSpecToModules(spec) {
100
129
  const modules = /* @__PURE__ */ new Map();
101
130
  const allSchemas = /* @__PURE__ */ new Map();
131
+ const allEnums = /* @__PURE__ */ new Map();
102
132
  const modulePaths = /* @__PURE__ */ new Map();
103
- if (spec.components?.schemas) {
104
- for (const schemaName in spec.components.schemas) {
105
- allSchemas.set(schemaName, { name: schemaName, schema: spec.components.schemas[schemaName] });
133
+ const registerSchema = (schema, baseName) => {
134
+ if (!schema) return "unknown";
135
+ if (schema.type === "array" && schema.items) return `${registerSchema(schema.items, `${baseName}Item`)}[]`;
136
+ if (schema.type === "object" || schema.properties || schema.allOf || !schema.type) {
137
+ const typeName = toPascalCase(baseName.replace(/_v\d+(Request|Response)$/, "$1"));
138
+ if (!allSchemas.has(typeName)) allSchemas.set(typeName, parseSchema(typeName, schema, allEnums));
139
+ return typeName;
106
140
  }
107
- }
141
+ return schema.type === "integer" ? "number" : schema.type || "unknown";
142
+ };
108
143
  for (const apiPath in spec.paths) {
109
144
  const pathItem = spec.paths[apiPath];
110
145
  if (!pathItem) continue;
@@ -112,100 +147,59 @@ function parseSpecToModules(spec) {
112
147
  if (!Object.values(import_openapi_types.OpenAPIV3.HttpMethods).includes(method)) continue;
113
148
  const endpoint = pathItem[method];
114
149
  if (!endpoint.operationId) continue;
115
- const moduleName = getModuleNameFromOpId(endpoint.operationId);
150
+ const moduleName = getModuleName(endpoint.operationId);
116
151
  if (!modules.has(moduleName)) {
117
- modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set() });
152
+ modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set(), enums: /* @__PURE__ */ new Set() });
118
153
  modulePaths.set(moduleName, []);
119
154
  }
120
155
  const currentModule = modules.get(moduleName);
121
156
  modulePaths.get(moduleName).push(apiPath);
122
- const { inputType, outputType } = _extractAndRegisterTypes(endpoint, allSchemas);
157
+ const successKey = Object.keys(endpoint.responses).find((c) => c.startsWith("2"));
158
+ const successRes = successKey ? endpoint.responses[successKey] : void 0;
159
+ const outputType = successKey === "204" ? "void" : registerSchema(successRes?.content?.["application/json"]?.schema, `${endpoint.operationId}Response`);
160
+ const reqBody = endpoint.requestBody;
161
+ let inputType = "undefined";
162
+ if (reqBody?.content?.["application/json"]?.schema) inputType = registerSchema(reqBody.content["application/json"].schema, `${endpoint.operationId}Request`);
163
+ else if ((endpoint.parameters || []).some((p) => p.in === "query")) inputType = "QueryOptions";
123
164
  [inputType, outputType].forEach((t) => {
124
165
  const cleanType = t.replace("[]", "");
125
166
  if (cleanType && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(cleanType)) {
126
167
  currentModule.schemas.add(cleanType);
168
+ const schemaDef = allSchemas.get(cleanType);
169
+ if (schemaDef) Object.keys(schemaDef.enums).forEach((propName) => currentModule.enums.add(`${toPascalCase(cleanType)}${toPascalCase(propName)}Enum`));
127
170
  }
128
171
  });
129
- const actionName = getActionNameFromOpId(endpoint.operationId);
130
- currentModule.actions[actionName] = {
131
- method: method.toUpperCase(),
132
- path: apiPath,
133
- description: endpoint.summary || "",
134
- hasQuery: (endpoint.parameters || []).some((p) => p.in === "query"),
135
- autoFetch: method.toUpperCase() === "GET" && !apiPath.includes("{"),
136
- requiresAuth: !!endpoint.security && endpoint.security.length > 0,
137
- _inputType: inputType,
138
- _outputType: outputType
139
- };
140
- debugLog("Parsed Action", { moduleName, actionName, ...currentModule.actions[actionName] });
172
+ 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 };
141
173
  }
142
174
  }
143
175
  modules.forEach((mod, name) => {
144
- const basePath = findCommonBasePath(modulePaths.get(name));
145
- mod.baseEndpoint = basePath;
146
- Object.values(mod.actions).forEach((action) => {
147
- const relativePath = action.path.replace(basePath, "").replace(/^\//, "");
148
- action.path = relativePath === "" ? "/" : relativePath;
149
- });
176
+ mod.baseEndpoint = findCommonPath(modulePaths.get(name));
177
+ Object.values(mod.actions).forEach((action) => action.path = action.path.replace(mod.baseEndpoint, "").replace(/^\//, "") || "/");
150
178
  });
151
- return { modules, allSchemas };
152
- }
153
- function _extractAndRegisterTypes(endpoint, allSchemas) {
154
- const opId = endpoint.operationId || "Unnamed";
155
- const successKey = Object.keys(endpoint.responses).find((c) => c.startsWith("2"));
156
- const successRes = successKey ? endpoint.responses[successKey] : void 0;
157
- const resSchema = successRes?.content?.["application/json"]?.schema;
158
- const outputType = successKey === "204" ? "void" : _schemaToTypeName(resSchema, `${opId}Response`, allSchemas);
159
- const reqBody = endpoint.requestBody;
160
- const reqSchema = reqBody?.content?.["application/json"]?.schema;
161
- let inputType = "undefined";
162
- if (reqSchema) {
163
- inputType = _schemaToTypeName(reqSchema, `${opId}Request`, allSchemas);
164
- } else if ((endpoint.parameters || []).some((p) => p.in === "query")) {
165
- inputType = "QueryOptions";
166
- }
167
- return { inputType, outputType };
179
+ debugLog("Final Parsed Modules", Object.fromEntries(modules));
180
+ return { modules, allSchemas, allEnums };
168
181
  }
169
- function _schemaToTypeName(schema, name, allSchemas) {
170
- if (!schema) return "unknown";
171
- if (schema.type === "array" && schema.items) {
172
- const itemTypeName = _schemaToTypeName(schema.items, `${name}Item`, allSchemas);
173
- return `${itemTypeName}[]`;
174
- }
175
- if (schema.type === "object" || schema.properties || schema.allOf || !schema.type) {
176
- const typeName = toPascalCase(name);
177
- if (!allSchemas.has(typeName)) {
178
- debugLog("Registering new inline schema", { assignedName: typeName, originalSchema: schema });
179
- allSchemas.set(typeName, { name: typeName, schema });
180
- }
181
- return typeName;
182
- }
183
- if (schema.type && ["string", "number", "boolean", "integer"].includes(schema.type)) {
184
- return schema.type === "integer" ? "number" : schema.type;
185
- }
186
- return "unknown";
187
- }
188
- async function generateModuleFiles(module2, allSchemas, outputDir) {
189
- const moduleName = module2.moduleName;
190
- const moduleOutputPath = import_path.default.join(outputDir, moduleName);
182
+ async function generateModuleFiles(module2, allSchemas, allEnums, outputDir) {
183
+ const moduleOutputPath = import_path.default.join(outputDir, module2.moduleName);
191
184
  if (!import_fs.default.existsSync(moduleOutputPath)) import_fs.default.mkdirSync(moduleOutputPath, { recursive: true });
192
185
  console.log(import_chalk.default.cyan(`
193
- Generating module: ${import_chalk.default.bold(moduleName)}`));
194
- const typesToImport = [...module2.schemas].sort();
186
+ Generating module: ${import_chalk.default.bold(module2.moduleName)}`));
187
+ const schemasToImport = [...module2.schemas].sort();
188
+ const enumsToImport = [...module2.enums].sort();
195
189
  let configContent = `/* eslint-disable */
196
190
  // This file is auto-generated.
197
191
 
198
192
  import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
199
193
  `;
200
- if (typesToImport.length > 0) configContent += `import type { ${typesToImport.join(", ")} } from './types';
194
+ if (schemasToImport.length > 0) configContent += `import type { ${schemasToImport.join(", ")} } from './types';
201
195
  `;
202
- const actionsType = Object.values(module2.actions).map((a) => ` ${getActionNameFromOpId(a.path)}: ActionConfigModule<${a._inputType}, ${a._outputType}>;`).join("\n");
196
+ const actionsType = Object.values(module2.actions).map((a) => ` ${a.name}: ActionConfigModule<${a.inputType}, ${a.outputType}>;`).join("\n");
203
197
  const actionsValue = Object.values(module2.actions).map((a) => {
204
- const { _inputType, _outputType, ...config } = a;
205
- return ` ${getActionNameFromOpId(a.path)}: ${JSON.stringify(config, null, 2).replace(/\n/g, "\n ")}`;
198
+ const { inputType, outputType, name, ...c } = a;
199
+ return ` ${name}: ${JSON.stringify(c, null, 2).replace(/\n/g, "\n ")}`;
206
200
  }).join(",\n");
207
201
  configContent += `
208
- export const ${moduleName}Module: ApiModuleConfig<{
202
+ export const ${module2.moduleName}Module: ApiModuleConfig<{
209
203
  ${actionsType}
210
204
  }> = {
211
205
  baseEndpoint: '${module2.baseEndpoint}',
@@ -214,154 +208,187 @@ ${actionsValue}
214
208
  },
215
209
  };
216
210
  `;
217
- import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "config.ts"), configContent.trim(), { encoding: "utf-8" });
211
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "config.ts"), configContent.trim());
218
212
  console.log(import_chalk.default.gray(` \u2713 config.ts`));
219
- if (typesToImport.length === 0) return;
220
- let typesContent = `// This file is auto-generated.
213
+ const indexContent = [`// This file is auto-generated.
214
+
215
+ export * from './config';`];
216
+ if (schemasToImport.length > 0) {
217
+ if (enumsToImport.length > 0) {
218
+ let enumsContent = `// This file is auto-generated.
221
219
 
222
220
  `;
223
- const tsOptions = { bannerComment: "", style: { bracketSpacing: true, printWidth: 120, semi: true, singleQuote: true, tabWidth: 2 }, additionalProperties: false };
224
- for (const typeName of typesToImport) {
225
- const parsedSchema = allSchemas.get(typeName);
226
- if (parsedSchema) {
227
- try {
228
- const tsType = await (0, import_json_schema_to_typescript.compile)(parsedSchema.schema, typeName, tsOptions);
229
- typesContent += tsType + "\n";
230
- } catch (e) {
231
- console.error(import_chalk.default.red(` - Error compiling type "${typeName}": ${e.message}`));
221
+ for (const enumName of enumsToImport) {
222
+ const enumDef = allEnums.get(enumName);
223
+ if (enumDef) {
224
+ enumsContent += `export const ${enumName} = ${JSON.stringify(enumDef.values)} as const;
225
+ `;
226
+ enumsContent += `export type ${enumName} = typeof ${enumName}[number];
227
+
228
+ `;
229
+ }
232
230
  }
231
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "enums.ts"), enumsContent);
232
+ console.log(import_chalk.default.gray(` \u2713 enums.ts`));
233
+ indexContent.push(`export * from './enums';`);
233
234
  }
234
- }
235
- import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "types.ts"), typesContent, { encoding: "utf-8" });
236
- console.log(import_chalk.default.gray(` \u2713 types.ts`));
237
- let validationContent = `// This file is auto-generated.
238
- import { z } from 'zod';
235
+ let typesContent = `// This file is auto-generated.
239
236
 
240
237
  `;
241
- for (const typeName of typesToImport) {
242
- const parsedSchema = allSchemas.get(typeName);
243
- if (parsedSchema?.schema.type === "object") {
244
- validationContent += `export const ${typeName}Schema = ${_schemaToZod(parsedSchema.schema)};
238
+ if (enumsToImport.length > 0) typesContent += `import type { ${enumsToImport.join(", ")} } from './enums';
245
239
 
246
240
  `;
241
+ for (const typeName of schemasToImport) {
242
+ const parsedSchema = allSchemas.get(typeName);
243
+ if (parsedSchema) {
244
+ if (parsedSchema.description) typesContent += `/**
245
+ * ${parsedSchema.description}
246
+ */
247
+ `;
248
+ typesContent += `export interface ${typeName} {
249
+ `;
250
+ for (const prop of parsedSchema.properties) {
251
+ if (prop.description) typesContent += ` /**
252
+ * ${prop.description}
253
+ ${prop.example ? ` * @example ${JSON.stringify(prop.example)}
254
+ ` : ""} */
255
+ `;
256
+ let propType = prop.type;
257
+ if (prop.enum) propType = `${toPascalCase(typeName)}${toPascalCase(prop.name)}Enum`;
258
+ else if (prop.items) propType = prop.items.properties ? `${toPascalCase(`${typeName}${toPascalCase(prop.name)}Item`)}[]` : `${prop.items.type}[]`;
259
+ else if (prop.properties) propType = `Record<string, unknown>`;
260
+ typesContent += ` ${prop.name}${prop.isRequired ? "" : "?"}: ${propType};
261
+ `;
262
+ }
263
+ typesContent += `}
264
+
265
+ `;
266
+ }
247
267
  }
248
- }
249
- import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "validation.ts"), validationContent, { encoding: "utf-8" });
250
- console.log(import_chalk.default.gray(` \u2713 validation.ts`));
251
- let mocksContent = `// This file is auto-generated.
252
- import type { ${typesToImport.join(", ")} } from './types';
268
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "types.ts"), typesContent);
269
+ console.log(import_chalk.default.gray(` \u2713 types.ts`));
270
+ indexContent.push(`export * from './types';`);
271
+ let validationContent = `// This file is auto-generated.
272
+ import { z } from 'zod';
273
+ `;
274
+ if (enumsToImport.length > 0) validationContent += `import { ${enumsToImport.join(", ")} } from './enums';
253
275
 
254
276
  `;
255
- for (const typeName of typesToImport) {
256
- const parsedSchema = allSchemas.get(typeName);
257
- if (parsedSchema) {
258
- mocksContent += `export const mock${typeName}: ${typeName} = ${JSON.stringify(_schemaToMock(parsedSchema.schema), null, 2)};
277
+ for (const typeName of schemasToImport) {
278
+ const parsedSchema = allSchemas.get(typeName);
279
+ if (parsedSchema) {
280
+ let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p, typeName)}`).join(",\n");
281
+ validationContent += `export const ${typeName}Schema = z.object({
282
+ ${zodShape}
283
+ });
259
284
 
260
285
  `;
286
+ }
261
287
  }
262
- }
263
- import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "mocks.ts"), mocksContent, { encoding: "utf-8" });
264
- console.log(import_chalk.default.gray(` \u2713 mocks.ts`));
265
- let indexContent = `// This file is auto-generated.
288
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "validation.ts"), validationContent);
289
+ console.log(import_chalk.default.gray(` \u2713 validation.ts`));
290
+ indexContent.push(`export * from './validation';`);
291
+ let mocksContent = `// This file is auto-generated.
292
+ import type { ${schemasToImport.join(", ")} } from './types';
293
+ `;
294
+ if (enumsToImport.length > 0) mocksContent += `import { ${enumsToImport.map((e) => e.replace(/Enum$/, "")).join(", ")} } from './enums';
266
295
 
267
- export * from './config';
268
- export * from './types';
269
- export * from './validation';
270
- export * from './mocks';
271
296
  `;
272
- import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent, { encoding: "utf-8" });
273
- console.log(import_chalk.default.gray(` \u2713 index.ts`));
274
- }
275
- function _schemaToZod(schema) {
276
- const shape = [];
277
- if (schema.properties) {
278
- for (const [key, prop] of Object.entries(schema.properties)) {
279
- shape.push(` ${key}: ${_propToZod(prop, (schema.required || []).includes(key))}`);
297
+ for (const typeName of schemasToImport) {
298
+ const parsedSchema = allSchemas.get(typeName);
299
+ if (parsedSchema) {
300
+ let mockObject = {};
301
+ parsedSchema.properties.forEach((p) => {
302
+ mockObject[p.name] = _propToMock(p);
303
+ });
304
+ mocksContent += `export const mock${typeName}: ${typeName} = ${JSON.stringify(mockObject, null, 2)};
305
+
306
+ `;
307
+ }
280
308
  }
309
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "mocks.ts"), mocksContent);
310
+ console.log(import_chalk.default.gray(` \u2713 mocks.ts`));
311
+ indexContent.push(`export * from './mocks';`);
281
312
  }
282
- return `z.object({
283
- ${shape.join(",\n")}
284
- })`;
313
+ import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent.join("\n"));
314
+ console.log(import_chalk.default.gray(` \u2713 index.ts`));
285
315
  }
286
- function _propToZod(prop, isRequired) {
316
+ function _propToZod(prop, parentName) {
287
317
  let zodString = "z.any()";
318
+ const errorMapParams = { errorMap: () => ({ message: prop.description || generateFriendlyMessage(prop.name, "required") }) };
288
319
  switch (prop.type) {
289
320
  case "string":
290
- zodString = "z.string()";
291
- if (prop.format === "email") zodString += ".email()";
292
- if (prop.format === "uuid") zodString += ".uuid()";
293
- if (prop.enum) zodString = `z.enum(${JSON.stringify(prop.enum)})`;
321
+ zodString = `z.string(${JSON.stringify(errorMapParams)})`;
322
+ if (prop.format === "email") zodString += `.email({ message: "${generateFriendlyMessage(prop.name, "email")}" })`;
323
+ if (prop.format === "uuid") zodString += `.uuid()`;
324
+ if (prop.enum) zodString = `z.enum(${toPascalCase(parentName)}${toPascalCase(prop.name)}Enum)`;
294
325
  break;
295
326
  case "integer":
296
327
  case "number":
297
- zodString = "z.number()";
298
- if (prop.minimum !== void 0) zodString += `.min(${prop.minimum})`;
299
- if (prop.maximum !== void 0) zodString += `.max(${prop.maximum})`;
328
+ zodString = `z.number(${JSON.stringify(errorMapParams)})`;
300
329
  break;
301
330
  case "boolean":
302
- zodString = "z.boolean()";
331
+ zodString = `z.boolean(${JSON.stringify(errorMapParams)})`;
303
332
  break;
304
333
  case "array":
305
- zodString = `z.array(${prop.items ? _propToZod(prop.items, true) : "z.any()"})`;
334
+ zodString = `z.array(${prop.items ? _propToZod(prop.items, `${parentName}${toPascalCase(prop.name)}Item`) : "z.any()"})`;
306
335
  break;
307
336
  case "object":
308
- zodString = _schemaToZod(prop);
337
+ let shape = "z.record(z.unknown())";
338
+ if (prop.properties) shape = `z.object({
339
+ ${prop.properties.map((p) => ` ${p.name}: ${_propToZod(p, `${parentName}${toPascalCase(prop.name)}`)}`).join(",\n")}
340
+ })`;
341
+ zodString = shape;
309
342
  break;
310
343
  }
311
- return isRequired ? zodString : `${zodString}.optional().nullable()`;
344
+ if (!prop.isRequired) zodString += ".optional()";
345
+ if (prop.isNullable) zodString += ".nullable()";
346
+ return zodString;
312
347
  }
313
- function _schemaToMock(schema) {
314
- if (schema.example) return schema.example;
315
- switch (schema.type) {
348
+ function _propToMock(prop) {
349
+ if (prop.example) return prop.example;
350
+ if (prop.name.match(/image|avatar|logo|url/i)) return "https://via.placeholder.com/150";
351
+ if (prop.enum) return prop.enum[0];
352
+ switch (prop.type) {
316
353
  case "string":
317
- if (schema.format === "email") return "test@example.com";
318
- if (schema.format === "uuid") return "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11";
319
- if (schema.enum) return schema.enum[0];
320
- return "Mock String";
354
+ if (prop.format === "email") return "test@example.com";
355
+ if (prop.format === "uuid") return "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11";
356
+ return `Mock ${toPascalCase(prop.name)}`;
321
357
  case "integer":
322
358
  case "number":
323
359
  return 1;
324
360
  case "boolean":
325
361
  return true;
326
362
  case "array":
327
- return schema.items ? [_schemaToMock(schema.items)] : [];
363
+ return prop.items ? [_propToMock(prop.items)] : [];
328
364
  case "object":
329
365
  const mock = {};
330
- if (schema.properties) {
331
- for (const [key, prop] of Object.entries(schema.properties)) {
332
- mock[key] = _schemaToMock(prop);
333
- }
334
- }
366
+ if (prop.properties) prop.properties.forEach((p) => {
367
+ mock[p.name] = _propToMock(p);
368
+ });
335
369
  return mock;
336
370
  default:
337
371
  return null;
338
372
  }
339
373
  }
340
- async function runGenerator() {
341
- const options = {
342
- output: "src/lib/api",
343
- envPath: ".env"
344
- };
345
- console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator..."));
374
+ async function runGenerator(options) {
375
+ console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (Diamond Edition)..."));
346
376
  import_dotenv.default.config({ path: options.envPath });
347
377
  const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
348
- console.log(import_chalk.default.blue("\u2713 Step 1: Environment variables loaded."));
349
378
  try {
350
379
  console.log(import_chalk.default.blue(`
351
- \u23F3 Step 2: Fetching and fully dereferencing spec from ${specUrl}...`));
380
+ \u23F3 Step 1: Dereferencing spec from ${specUrl}...`));
352
381
  const spec = await import_swagger_parser.default.dereference(specUrl);
353
- console.log(import_chalk.default.green("\u2713 Spec fetched and fully dereferenced successfully."));
354
- debugLog("Dereferenced Spec", spec);
355
- console.log(import_chalk.default.blue("\n\u23F3 Step 3: Parsing spec using intelligent grouping..."));
356
- const { modules, allSchemas } = parseSpecToModules(spec);
382
+ console.log(import_chalk.default.green("\u2713 Spec fully dereferenced."));
383
+ console.log(import_chalk.default.blue("\n\u23F3 Step 2: Parsing spec with intelligent grouping..."));
384
+ const { modules, allSchemas, allEnums } = parseSpecToModules(spec);
357
385
  console.log(import_chalk.default.green(`\u2713 Found and grouped ${modules.size} logical modules.`));
358
- debugLog("Parsed Modules", Object.fromEntries(modules));
359
- console.log(import_chalk.default.blue("\n\u23F3 Step 4: Generating all module files..."));
386
+ console.log(import_chalk.default.blue("\n\u23F3 Step 3: Generating all module files..."));
360
387
  for (const module2 of modules.values()) {
361
- await generateModuleFiles(module2, allSchemas, options.output);
388
+ await generateModuleFiles(module2, allSchemas, allEnums, options.output);
362
389
  }
363
390
  console.log(import_chalk.default.green("\n\u2713 All module files generated successfully."));
364
- console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete!"));
391
+ console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete! Your development platform is ready."));
365
392
  console.log(import_chalk.default.bold.cyan(` Output directory: ${options.output}`));
366
393
  } catch (error) {
367
394
  console.error(import_chalk.default.red.bold("\n\u274C An error occurred during generation:"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-core-lib",
3
- "version": "12.0.67",
3
+ "version": "12.0.69",
4
4
  "description": "A flexible and powerful API client library for modern web applications.",
5
5
  "type": "module",
6
6
  "exports": {