api-core-lib 12.0.70 → 12.0.72
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 +145 -109
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -76,14 +76,14 @@ var import_swagger_parser = __toESM(require("@apidevtools/swagger-parser"), 1);
|
|
|
76
76
|
var import_openapi_types = __toESM(require_dist(), 1);
|
|
77
77
|
var DEBUG_MODE = process.env.DEBUG === "true";
|
|
78
78
|
var debugLog = (title, data) => DEBUG_MODE && console.log(import_chalk.default.yellow(`
|
|
79
|
-
[DEBUG: ${title}]`), import_util.default.inspect(data, { depth:
|
|
79
|
+
[DEBUG: ${title}]`), import_util.default.inspect(data, { depth: 4, colors: true }));
|
|
80
80
|
var toPascalCase = (str) => str.replace(/[^a-zA-Z0-9_]/g, " ").replace(/(?:^\w|[A-Z]|\b\w)/g, (w) => w.toUpperCase()).replace(/\s+/g, "");
|
|
81
81
|
var toCamelCase = (str) => {
|
|
82
82
|
const s = toPascalCase(str);
|
|
83
83
|
return s.charAt(0).toLowerCase() + s.slice(1);
|
|
84
84
|
};
|
|
85
85
|
var getModuleName = (opId) => `${opId.split("_")[0].replace(/Controller$/, "")}Api`;
|
|
86
|
-
var getActionName = (opId) => toCamelCase(opId.split("_")[1] || opId)
|
|
86
|
+
var getActionName = (opId) => toCamelCase(opId.split("_")[1] || opId);
|
|
87
87
|
var findCommonPath = (paths) => {
|
|
88
88
|
if (!paths || paths.length === 0) return "/";
|
|
89
89
|
const sorted = [...paths].sort();
|
|
@@ -94,22 +94,14 @@ var findCommonPath = (paths) => {
|
|
|
94
94
|
const prefix = first.substring(0, i);
|
|
95
95
|
return prefix.substring(0, prefix.lastIndexOf("/") + 1) || "/";
|
|
96
96
|
};
|
|
97
|
-
|
|
98
|
-
function parseSchema(name, schema, allEnums) {
|
|
97
|
+
function parseSchema(name, schema) {
|
|
99
98
|
const properties = [];
|
|
100
|
-
const enums = {};
|
|
101
99
|
if (schema.properties) {
|
|
102
100
|
for (const propName in schema.properties) {
|
|
103
101
|
const propSchema = schema.properties[propName];
|
|
104
|
-
let
|
|
102
|
+
let items = void 0;
|
|
105
103
|
if (propSchema.type === "array" && propSchema.items) {
|
|
106
|
-
|
|
107
|
-
itemSchema = parseSchema(itemTypeName, propSchema.items, allEnums).properties[0];
|
|
108
|
-
}
|
|
109
|
-
if (propSchema.enum) {
|
|
110
|
-
const enumName = `${toPascalCase(name)}${toPascalCase(propName)}Enum`;
|
|
111
|
-
enums[propName] = propSchema.enum;
|
|
112
|
-
if (!allEnums.has(enumName)) allEnums.set(enumName, { name: enumName, values: propSchema.enum });
|
|
104
|
+
items = parseSchema("item", propSchema.items).properties[0];
|
|
113
105
|
}
|
|
114
106
|
properties.push({
|
|
115
107
|
name: propName,
|
|
@@ -120,31 +112,24 @@ function parseSchema(name, schema, allEnums) {
|
|
|
120
112
|
example: propSchema.example,
|
|
121
113
|
enum: propSchema.enum,
|
|
122
114
|
format: propSchema.format,
|
|
123
|
-
items
|
|
124
|
-
|
|
115
|
+
items,
|
|
116
|
+
// نستخدم المتغير الذي تم حسابه بأمان
|
|
117
|
+
properties: propSchema.properties ? parseSchema("sub-object", propSchema).properties : void 0
|
|
125
118
|
});
|
|
126
119
|
}
|
|
127
120
|
}
|
|
128
|
-
return { name, description: schema.description, properties
|
|
121
|
+
return { name, description: schema.description, properties };
|
|
129
122
|
}
|
|
130
123
|
function parseSpecToModules(spec) {
|
|
131
124
|
const modules = /* @__PURE__ */ new Map();
|
|
132
125
|
const allSchemas = /* @__PURE__ */ new Map();
|
|
133
|
-
const allEnums = /* @__PURE__ */ new Map();
|
|
134
126
|
const modulePaths = /* @__PURE__ */ new Map();
|
|
135
127
|
const registerSchema = (schema, baseName) => {
|
|
136
128
|
if (!schema) return "unknown";
|
|
137
|
-
if (schema.type === "array" && schema.items) {
|
|
138
|
-
const itemSchema = schema.items;
|
|
139
|
-
const itemBaseName = `${baseName}Item`;
|
|
140
|
-
if (itemSchema.properties || itemSchema.type === "object") {
|
|
141
|
-
return `${registerSchema(itemSchema, itemBaseName)}[]`;
|
|
142
|
-
}
|
|
143
|
-
return `${itemSchema.type || "unknown"}[]`;
|
|
144
|
-
}
|
|
129
|
+
if (schema.type === "array" && schema.items) return `${registerSchema(schema.items, `${baseName}Item`)}[]`;
|
|
145
130
|
if (schema.type === "object" || schema.properties || schema.allOf || !schema.type) {
|
|
146
131
|
const typeName = toPascalCase(baseName.replace(/_v\d+(Request|Response)$/, "$1"));
|
|
147
|
-
if (!allSchemas.has(typeName)) allSchemas.set(typeName, parseSchema(typeName, schema
|
|
132
|
+
if (!allSchemas.has(typeName)) allSchemas.set(typeName, parseSchema(typeName, schema));
|
|
148
133
|
return typeName;
|
|
149
134
|
}
|
|
150
135
|
return schema.type === "integer" ? "number" : schema.type || "unknown";
|
|
@@ -158,7 +143,7 @@ function parseSpecToModules(spec) {
|
|
|
158
143
|
if (!endpoint.operationId) continue;
|
|
159
144
|
const moduleName = getModuleName(endpoint.operationId);
|
|
160
145
|
if (!modules.has(moduleName)) {
|
|
161
|
-
modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set()
|
|
146
|
+
modules.set(moduleName, { moduleName, baseEndpoint: "", actions: {}, schemas: /* @__PURE__ */ new Set() });
|
|
162
147
|
modulePaths.set(moduleName, []);
|
|
163
148
|
}
|
|
164
149
|
const currentModule = modules.get(moduleName);
|
|
@@ -174,36 +159,35 @@ function parseSpecToModules(spec) {
|
|
|
174
159
|
const cleanType = t.replace("[]", "");
|
|
175
160
|
if (cleanType && !["unknown", "undefined", "void", "any", "QueryOptions", "Promise"].includes(cleanType)) {
|
|
176
161
|
currentModule.schemas.add(cleanType);
|
|
177
|
-
const schemaDef = allSchemas.get(cleanType);
|
|
178
|
-
if (schemaDef) Object.keys(schemaDef.enums).forEach((propName) => currentModule.enums.add(`${toPascalCase(cleanType)}${toPascalCase(propName)}Enum`));
|
|
179
162
|
}
|
|
180
163
|
});
|
|
181
|
-
|
|
164
|
+
const actionName = getActionName(endpoint.operationId);
|
|
165
|
+
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
166
|
}
|
|
183
167
|
}
|
|
184
168
|
modules.forEach((mod, name) => {
|
|
185
|
-
|
|
186
|
-
|
|
169
|
+
const basePath = findCommonPath(modulePaths.get(name));
|
|
170
|
+
mod.baseEndpoint = basePath;
|
|
171
|
+
Object.values(mod.actions).forEach((action) => {
|
|
172
|
+
const relativePath = action.path.replace(basePath, "").replace(/^\//, "");
|
|
173
|
+
action.path = relativePath === "" ? "/" : relativePath;
|
|
174
|
+
});
|
|
187
175
|
});
|
|
188
176
|
debugLog("Final Parsed Modules", Object.fromEntries(modules));
|
|
189
|
-
return { modules, allSchemas
|
|
177
|
+
return { modules, allSchemas };
|
|
190
178
|
}
|
|
191
|
-
async function generateModuleFiles(module2, allSchemas,
|
|
179
|
+
async function generateModuleFiles(module2, allSchemas, outputDir) {
|
|
192
180
|
const moduleOutputPath = import_path.default.join(outputDir, module2.moduleName);
|
|
193
181
|
if (!import_fs.default.existsSync(moduleOutputPath)) import_fs.default.mkdirSync(moduleOutputPath, { recursive: true });
|
|
194
182
|
console.log(import_chalk.default.cyan(`
|
|
195
183
|
Generating module: ${import_chalk.default.bold(module2.moduleName)}`));
|
|
196
|
-
const
|
|
197
|
-
const enumsToImport = [...module2.enums].sort();
|
|
198
|
-
const indexContent = [`// This file is auto-generated.
|
|
199
|
-
|
|
200
|
-
export * from './config';`];
|
|
184
|
+
const typesToImport = [...module2.schemas].sort();
|
|
201
185
|
let configContent = `/* eslint-disable */
|
|
202
186
|
// This file is auto-generated.
|
|
203
187
|
|
|
204
188
|
import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
|
|
205
189
|
`;
|
|
206
|
-
if (
|
|
190
|
+
if (typesToImport.length > 0) configContent += `import type { ${typesToImport.join(", ")} } from './types';
|
|
207
191
|
`;
|
|
208
192
|
const actionsType = Object.values(module2.actions).map((a) => ` ${a.name}: ActionConfigModule<${a.inputType}, ${a.outputType}>;`).join("\n");
|
|
209
193
|
const actionsValue = Object.values(module2.actions).map((a) => {
|
|
@@ -222,32 +206,14 @@ ${actionsValue}
|
|
|
222
206
|
`;
|
|
223
207
|
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "config.ts"), configContent.trim());
|
|
224
208
|
console.log(import_chalk.default.gray(` \u2713 config.ts`));
|
|
225
|
-
|
|
226
|
-
if (enumsToImport.length > 0) {
|
|
227
|
-
let enumsContent = `// This file is auto-generated.
|
|
228
|
-
|
|
229
|
-
`;
|
|
230
|
-
for (const enumName of enumsToImport) {
|
|
231
|
-
const enumDef = allEnums.get(enumName);
|
|
232
|
-
if (enumDef) {
|
|
233
|
-
enumsContent += `export const ${enumName} = ${JSON.stringify(enumDef.values)} as const;
|
|
234
|
-
`;
|
|
235
|
-
enumsContent += `export type ${enumName} = typeof ${enumName}[number];
|
|
209
|
+
const indexContent = [`// This file is auto-generated.
|
|
236
210
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "enums.ts"), enumsContent);
|
|
241
|
-
console.log(import_chalk.default.gray(` \u2713 enums.ts`));
|
|
242
|
-
indexContent.push(`export * from './enums';`);
|
|
243
|
-
}
|
|
211
|
+
export * from './config';`];
|
|
212
|
+
if (typesToImport.length > 0) {
|
|
244
213
|
let typesContent = `// This file is auto-generated.
|
|
245
214
|
|
|
246
215
|
`;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
`;
|
|
250
|
-
for (const typeName of schemasToImport) {
|
|
216
|
+
for (const typeName of typesToImport) {
|
|
251
217
|
const parsedSchema = allSchemas.get(typeName);
|
|
252
218
|
if (parsedSchema) {
|
|
253
219
|
if (parsedSchema.description) typesContent += `/**
|
|
@@ -262,12 +228,7 @@ ${actionsValue}
|
|
|
262
228
|
${prop.example ? ` * @example ${JSON.stringify(prop.example)}
|
|
263
229
|
` : ""} */
|
|
264
230
|
`;
|
|
265
|
-
|
|
266
|
-
if (prop.enum) propType = `${toPascalCase(typeName)}${toPascalCase(prop.name)}Enum`;
|
|
267
|
-
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>`;
|
|
231
|
+
const propType = prop.enum ? prop.enum.map((e) => typeof e === "string" ? `'${e}'` : e).join(" | ") : prop.items ? `${toPascalCase(prop.items.name)}[]` : prop.type;
|
|
271
232
|
typesContent += ` ${prop.name}${prop.isRequired ? "" : "?"}: ${propType};
|
|
272
233
|
`;
|
|
273
234
|
}
|
|
@@ -281,14 +242,12 @@ ${prop.properties.map((p) => ` ${p.name}${p.isRequired ? "" : "?"}: ${p.type}
|
|
|
281
242
|
indexContent.push(`export * from './types';`);
|
|
282
243
|
let validationContent = `// This file is auto-generated.
|
|
283
244
|
import { z } from 'zod';
|
|
284
|
-
`;
|
|
285
|
-
if (enumsToImport.length > 0) validationContent += `import { ${enumsToImport.join(", ")} } from './enums';
|
|
286
245
|
|
|
287
246
|
`;
|
|
288
|
-
for (const typeName of
|
|
247
|
+
for (const typeName of typesToImport) {
|
|
289
248
|
const parsedSchema = allSchemas.get(typeName);
|
|
290
249
|
if (parsedSchema) {
|
|
291
|
-
let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p
|
|
250
|
+
let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
|
|
292
251
|
validationContent += `export const ${typeName}Schema = z.object({
|
|
293
252
|
${zodShape}
|
|
294
253
|
});
|
|
@@ -300,12 +259,10 @@ ${zodShape}
|
|
|
300
259
|
console.log(import_chalk.default.gray(` \u2713 validation.ts`));
|
|
301
260
|
indexContent.push(`export * from './validation';`);
|
|
302
261
|
let mocksContent = `// This file is auto-generated.
|
|
303
|
-
import type { ${
|
|
304
|
-
`;
|
|
305
|
-
if (enumsToImport.length > 0) mocksContent += `import { ${enumsToImport.join(", ")} } from './enums';
|
|
262
|
+
import type { ${typesToImport.join(", ")} } from './types';
|
|
306
263
|
|
|
307
264
|
`;
|
|
308
|
-
for (const typeName of
|
|
265
|
+
for (const typeName of typesToImport) {
|
|
309
266
|
const parsedSchema = allSchemas.get(typeName);
|
|
310
267
|
if (parsedSchema) {
|
|
311
268
|
let mockObject = {};
|
|
@@ -324,66 +281,144 @@ import type { ${schemasToImport.join(", ")} } from './types';
|
|
|
324
281
|
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent.join("\n"));
|
|
325
282
|
console.log(import_chalk.default.gray(` \u2713 index.ts`));
|
|
326
283
|
}
|
|
327
|
-
function _propToZod(prop
|
|
328
|
-
let
|
|
329
|
-
const
|
|
284
|
+
function _propToZod(prop) {
|
|
285
|
+
let chain;
|
|
286
|
+
const requiredErrorMessage = { required_error: `${prop.name} is required.` };
|
|
330
287
|
switch (prop.type) {
|
|
331
288
|
case "string":
|
|
332
|
-
|
|
333
|
-
if (prop.format === "email")
|
|
334
|
-
if (prop.format === "uuid")
|
|
335
|
-
if (prop.
|
|
289
|
+
chain = `z.string({ ...requiredErrorMessage, invalid_type_error: "Expected a string for ${prop.name}" })`;
|
|
290
|
+
if (prop.format === "email") chain += `.email({ message: "Invalid email address for ${prop.name}" })`;
|
|
291
|
+
if (prop.format === "uuid") chain += `.uuid({ message: "Invalid UUID for ${prop.name}" })`;
|
|
292
|
+
if (prop.format === "url") chain += `.url({ message: "Invalid URL for ${prop.name}" })`;
|
|
293
|
+
if (prop.format === "datetime") chain += `.datetime({ message: "Invalid datetime format for ${prop.name}" })`;
|
|
294
|
+
if (prop.minLength !== void 0) chain += `.min(${prop.minLength}, { message: "${prop.name} must be at least ${prop.minLength} characters long" })`;
|
|
295
|
+
if (prop.maxLength !== void 0) chain += `.max(${prop.maxLength}, { message: "${prop.name} must be at most ${prop.maxLength} characters long" })`;
|
|
296
|
+
if (prop.pattern) chain += `.regex(/${prop.pattern}/, { message: "Invalid format for ${prop.name}" })`;
|
|
297
|
+
if (prop.enum) {
|
|
298
|
+
if (prop.enum.length > 0) {
|
|
299
|
+
chain = `z.enum(${JSON.stringify(prop.enum)})`;
|
|
300
|
+
} else {
|
|
301
|
+
chain = `z.string().refine(() => false, { message: "Enum for ${prop.name} is empty" })`;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
336
304
|
break;
|
|
337
305
|
case "integer":
|
|
306
|
+
chain = `z.number({ ...requiredErrorMessage, invalid_type_error: "Expected a number for ${prop.name}" }).int({ message: "${prop.name} must be an integer" })`;
|
|
307
|
+
if (prop.minimum !== void 0) chain += `.min(${prop.minimum}, { message: "${prop.name} must be at least ${prop.minimum}" })`;
|
|
308
|
+
if (prop.maximum !== void 0) chain += `.max(${prop.maximum}, { message: "${prop.name} must be at most ${prop.maximum}" })`;
|
|
309
|
+
break;
|
|
338
310
|
case "number":
|
|
339
|
-
|
|
311
|
+
chain = `z.number({ ...requiredErrorMessage, invalid_type_error: "Expected a number for ${prop.name}" })`;
|
|
312
|
+
if (prop.minimum !== void 0) chain += `.min(${prop.minimum}, { message: "${prop.name} must be at least ${prop.minimum}" })`;
|
|
313
|
+
if (prop.maximum !== void 0) chain += `.max(${prop.maximum}, { message: "${prop.name} must be at most ${prop.maximum}" })`;
|
|
340
314
|
break;
|
|
341
315
|
case "boolean":
|
|
342
|
-
|
|
316
|
+
chain = `z.boolean({ ...requiredErrorMessage, invalid_type_error: "Expected a boolean for ${prop.name}" })`;
|
|
343
317
|
break;
|
|
344
318
|
case "array":
|
|
345
|
-
|
|
319
|
+
const itemSchema = prop.items ? _propToZod(prop.items) : "z.any()";
|
|
320
|
+
chain = `z.array(${itemSchema})`;
|
|
321
|
+
if (prop.minItems !== void 0) chain += `.min(${prop.minItems}, { message: "${prop.name} must contain at least ${prop.minItems} item(s)" })`;
|
|
322
|
+
if (prop.maxItems !== void 0) chain += `.max(${prop.maxItems}, { message: "${prop.name} must contain at most ${prop.maxItems} item(s)" })`;
|
|
346
323
|
break;
|
|
347
324
|
case "object":
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
325
|
+
if (prop.properties && prop.properties.length > 0) {
|
|
326
|
+
const shape = prop.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
|
|
327
|
+
chain = `z.object({
|
|
328
|
+
${shape}
|
|
329
|
+
})`;
|
|
330
|
+
} else {
|
|
331
|
+
chain = "z.record(z.unknown())";
|
|
332
|
+
}
|
|
353
333
|
break;
|
|
334
|
+
default:
|
|
335
|
+
chain = "z.any()";
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
if (prop.description) {
|
|
339
|
+
chain += `.describe(${JSON.stringify(prop.description)})`;
|
|
340
|
+
}
|
|
341
|
+
if (!prop.isRequired) {
|
|
342
|
+
chain += ".optional()";
|
|
343
|
+
}
|
|
344
|
+
if (prop.isNullable) {
|
|
345
|
+
chain += ".nullable()";
|
|
354
346
|
}
|
|
355
|
-
|
|
356
|
-
if (prop.isNullable) zodString += ".nullable()";
|
|
357
|
-
return zodString;
|
|
347
|
+
return chain;
|
|
358
348
|
}
|
|
349
|
+
function _generateUUID() {
|
|
350
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
351
|
+
const r = Math.random() * 16 | 0;
|
|
352
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
353
|
+
return v.toString(16);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
function _getRandomInt(min, max) {
|
|
357
|
+
min = Math.ceil(min);
|
|
358
|
+
max = Math.floor(max);
|
|
359
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
360
|
+
}
|
|
361
|
+
var _firstNames = ["Ahmed", "Fatima", "Mohammed", "Zainab", "Ali", "Nour"];
|
|
362
|
+
var _lastNames = ["Al-Masri", "Khan", "Hassan", "Abbas", "Said"];
|
|
359
363
|
function _propToMock(prop) {
|
|
360
|
-
if (prop.example)
|
|
361
|
-
|
|
362
|
-
|
|
364
|
+
if (prop.example !== void 0) {
|
|
365
|
+
return prop.example;
|
|
366
|
+
}
|
|
367
|
+
if (prop.enum && prop.enum.length > 0) {
|
|
368
|
+
return prop.enum[_getRandomInt(0, prop.enum.length - 1)];
|
|
369
|
+
}
|
|
363
370
|
switch (prop.type) {
|
|
364
371
|
case "string":
|
|
365
|
-
if (prop.format === "email") return
|
|
366
|
-
if (prop.format === "uuid") return
|
|
367
|
-
|
|
372
|
+
if (prop.format === "email") return `user${_getRandomInt(1, 1e3)}@example.com`;
|
|
373
|
+
if (prop.format === "uuid") return _generateUUID();
|
|
374
|
+
if (prop.format === "url") return "https://www.example.com";
|
|
375
|
+
if (prop.format === "datetime") return (/* @__PURE__ */ new Date()).toISOString();
|
|
376
|
+
const name = prop.name.toLowerCase();
|
|
377
|
+
if (name.includes("image") || name.includes("avatar") || name.includes("logo") || name.includes("picture")) return `https://via.placeholder.com/${_getRandomInt(150, 400)}`;
|
|
378
|
+
if (name.includes("firstname")) return _firstNames[_getRandomInt(0, _firstNames.length - 1)];
|
|
379
|
+
if (name.includes("lastname")) return _lastNames[_getRandomInt(0, _lastNames.length - 1)];
|
|
380
|
+
if (name.includes("name")) return `${_firstNames[_getRandomInt(0, _firstNames.length - 1)]} ${_lastNames[_getRandomInt(0, _lastNames.length - 1)]}`;
|
|
381
|
+
if (name.includes("city")) return "Riyadh";
|
|
382
|
+
if (name.includes("country")) return "Saudi Arabia";
|
|
383
|
+
if (name.includes("phone")) return `+1-${_getRandomInt(100, 999)}-${_getRandomInt(100, 999)}-${_getRandomInt(1e3, 9999)}`;
|
|
384
|
+
if (name.includes("description") || name.includes("comment")) return "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
|
|
385
|
+
const minLen = prop.minLength || 8;
|
|
386
|
+
const maxLen = prop.maxLength || 16;
|
|
387
|
+
return `Mock${toPascalCase(prop.name)}`.padEnd(_getRandomInt(minLen, maxLen), "x");
|
|
368
388
|
case "integer":
|
|
369
389
|
case "number":
|
|
370
|
-
|
|
390
|
+
const min = prop.minimum === void 0 ? 1 : prop.minimum;
|
|
391
|
+
const max = prop.maximum === void 0 ? 1e3 : prop.maximum;
|
|
392
|
+
const randomNum = _getRandomInt(min, max);
|
|
393
|
+
return prop.type === "integer" ? Math.floor(randomNum) : randomNum + Math.random();
|
|
371
394
|
case "boolean":
|
|
372
|
-
return
|
|
395
|
+
return Math.random() > 0.5;
|
|
373
396
|
case "array":
|
|
374
|
-
|
|
397
|
+
const minItems = prop.minItems || 1;
|
|
398
|
+
const maxItems = prop.maxItems || 3;
|
|
399
|
+
const count = _getRandomInt(minItems, maxItems);
|
|
400
|
+
if (!prop.items) return [];
|
|
401
|
+
const items = [];
|
|
402
|
+
for (let i = 0; i < count; i++) {
|
|
403
|
+
items.push(_propToMock(prop.items));
|
|
404
|
+
}
|
|
405
|
+
return items;
|
|
375
406
|
case "object":
|
|
376
407
|
const mock = {};
|
|
377
|
-
if (prop.properties)
|
|
378
|
-
|
|
379
|
-
|
|
408
|
+
if (prop.properties) {
|
|
409
|
+
prop.properties.forEach((p) => {
|
|
410
|
+
if (p.isRequired || Math.random() > 0.3) {
|
|
411
|
+
mock[p.name] = _propToMock(p);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
380
415
|
return mock;
|
|
381
416
|
default:
|
|
382
417
|
return null;
|
|
383
418
|
}
|
|
384
419
|
}
|
|
385
420
|
async function runGenerator(options) {
|
|
386
|
-
console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (
|
|
421
|
+
console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (Phoenix Edition)..."));
|
|
387
422
|
import_dotenv.default.config({ path: options.envPath });
|
|
388
423
|
const specUrl = process.env.OPENAPI_SPEC_URL || "./swagger.json";
|
|
389
424
|
try {
|
|
@@ -391,12 +426,13 @@ async function runGenerator(options) {
|
|
|
391
426
|
\u23F3 Step 1: Dereferencing spec from ${specUrl}...`));
|
|
392
427
|
const spec = await import_swagger_parser.default.dereference(specUrl);
|
|
393
428
|
console.log(import_chalk.default.green("\u2713 Spec fully dereferenced."));
|
|
429
|
+
debugLog("Dereferenced Spec", spec);
|
|
394
430
|
console.log(import_chalk.default.blue("\n\u23F3 Step 2: Parsing spec with intelligent grouping..."));
|
|
395
|
-
const { modules, allSchemas
|
|
431
|
+
const { modules, allSchemas } = parseSpecToModules(spec);
|
|
396
432
|
console.log(import_chalk.default.green(`\u2713 Found and grouped ${modules.size} logical modules.`));
|
|
397
433
|
console.log(import_chalk.default.blue("\n\u23F3 Step 3: Generating all module files..."));
|
|
398
434
|
for (const module2 of modules.values()) {
|
|
399
|
-
await generateModuleFiles(module2, allSchemas,
|
|
435
|
+
await generateModuleFiles(module2, allSchemas, options.output);
|
|
400
436
|
}
|
|
401
437
|
console.log(import_chalk.default.green("\n\u2713 All module files generated successfully."));
|
|
402
438
|
console.log(import_chalk.default.bold.green("\n\u{1F389} API generation complete! Your development platform is ready."));
|