api-core-lib 12.0.77 → 12.0.78
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 +57 -269
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -78,72 +78,44 @@ var import_openapi_types = __toESM(require_dist(), 1);
|
|
|
78
78
|
// src/generator/core/_propToZod.ts
|
|
79
79
|
function _propToZod(prop) {
|
|
80
80
|
let zodChain;
|
|
81
|
-
const
|
|
82
|
-
const customMessages = prop.errorMessages;
|
|
83
|
-
const message = customMessages?.[rule] || defaultKey;
|
|
84
|
-
return `{ "message": "${message}" }`;
|
|
85
|
-
};
|
|
81
|
+
const getMsg = (key) => `{ "message": "validation.${key}" }`;
|
|
86
82
|
switch (prop.type) {
|
|
87
|
-
case "string":
|
|
88
|
-
if (prop.
|
|
89
|
-
zodChain = `z.enum(${
|
|
83
|
+
case "string":
|
|
84
|
+
if (prop.enumName) {
|
|
85
|
+
zodChain = `z.enum(${prop.enumName})`;
|
|
90
86
|
} else {
|
|
91
87
|
zodChain = "z.string()";
|
|
92
88
|
if (prop.isRequired) {
|
|
93
|
-
zodChain += `.min(1, ${
|
|
94
|
-
}
|
|
95
|
-
if (prop.maxLength !== void 0) {
|
|
96
|
-
zodChain += `.max(${prop.maxLength}, ${getRuleMessage("maxLength", "validation.string.max")})`;
|
|
97
|
-
}
|
|
98
|
-
if (prop.pattern) {
|
|
99
|
-
zodChain += `.regex(/${prop.pattern}/, ${getRuleMessage("pattern", "validation.string.regex")})`;
|
|
100
|
-
}
|
|
101
|
-
if (prop.format) {
|
|
102
|
-
const msg = getRuleMessage("format", `validation.string.${prop.format}`);
|
|
103
|
-
if (prop.format === "email") zodChain += `.email(${msg})`;
|
|
104
|
-
if (prop.format === "url") zodChain += `.url(${msg})`;
|
|
105
|
-
if (prop.format === "uuid") zodChain += `.uuid(${msg})`;
|
|
106
|
-
if (prop.format === "datetime") zodChain += `.datetime(${msg})`;
|
|
89
|
+
zodChain += `.min(1, ${getMsg("string.nonempty")})`;
|
|
107
90
|
}
|
|
91
|
+
if (prop.maxLength !== void 0) zodChain += `.max(${prop.maxLength}, ${getMsg("string.max")})`;
|
|
92
|
+
if (prop.pattern) zodChain += `.regex(/${prop.pattern}/, ${getMsg("string.regex")})`;
|
|
93
|
+
if (prop.format === "email") zodChain += `.email(${getMsg("string.email")})`;
|
|
94
|
+
if (prop.format === "url") zodChain += `.url(${getMsg("string.url")})`;
|
|
95
|
+
if (prop.format === "uuid") zodChain += `.uuid(${getMsg("string.uuid")})`;
|
|
96
|
+
if (prop.format === "datetime") zodChain += `.datetime(${getMsg("string.datetime")})`;
|
|
108
97
|
}
|
|
109
98
|
break;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
zodChain
|
|
113
|
-
if (prop.
|
|
114
|
-
zodChain += `.min(${prop.minimum}, ${getRuleMessage("minimum", "validation.number.min")})`;
|
|
115
|
-
}
|
|
116
|
-
if (prop.maximum !== void 0) {
|
|
117
|
-
zodChain += `.max(${prop.maximum}, ${getRuleMessage("maximum", "validation.number.max")})`;
|
|
118
|
-
}
|
|
99
|
+
case "integer":
|
|
100
|
+
zodChain = `z.number().int(${getMsg("number.integer")})`;
|
|
101
|
+
if (prop.minimum !== void 0) zodChain += `.min(${prop.minimum}, ${getMsg("number.min")})`;
|
|
102
|
+
if (prop.maximum !== void 0) zodChain += `.max(${prop.maximum}, ${getMsg("number.max")})`;
|
|
119
103
|
break;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
zodChain
|
|
123
|
-
if (prop.
|
|
124
|
-
zodChain += `.min(${prop.minimum}, ${getRuleMessage("minimum", "validation.number.min")})`;
|
|
125
|
-
}
|
|
126
|
-
if (prop.maximum !== void 0) {
|
|
127
|
-
zodChain += `.max(${prop.maximum}, ${getRuleMessage("maximum", "validation.number.max")})`;
|
|
128
|
-
}
|
|
104
|
+
case "number":
|
|
105
|
+
zodChain = `z.number()`;
|
|
106
|
+
if (prop.minimum !== void 0) zodChain += `.min(${prop.minimum}, ${getMsg("number.min")})`;
|
|
107
|
+
if (prop.maximum !== void 0) zodChain += `.max(${prop.maximum}, ${getMsg("number.max")})`;
|
|
129
108
|
break;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
zodChain = "z.boolean()";
|
|
109
|
+
case "boolean":
|
|
110
|
+
zodChain = `z.boolean()`;
|
|
133
111
|
break;
|
|
134
|
-
|
|
135
|
-
case "array": {
|
|
112
|
+
case "array":
|
|
136
113
|
const itemSchema = prop.items ? _propToZod(prop.items) : "z.any()";
|
|
137
114
|
zodChain = `z.array(${itemSchema})`;
|
|
138
|
-
if (prop.minItems !== void 0) {
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
if (prop.maxItems !== void 0) {
|
|
142
|
-
zodChain += `.max(${prop.maxItems}, ${getRuleMessage("maxItems", "validation.array.max")})`;
|
|
143
|
-
}
|
|
115
|
+
if (prop.minItems !== void 0) zodChain += `.min(${prop.minItems}, ${getMsg("array.min")})`;
|
|
116
|
+
if (prop.maxItems !== void 0) zodChain += `.max(${prop.maxItems}, ${getMsg("array.max")})`;
|
|
144
117
|
break;
|
|
145
|
-
|
|
146
|
-
case "object": {
|
|
118
|
+
case "object":
|
|
147
119
|
if (prop.properties && prop.properties.length > 0) {
|
|
148
120
|
const shape = prop.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
|
|
149
121
|
zodChain = `z.object({
|
|
@@ -153,7 +125,6 @@ ${shape}
|
|
|
153
125
|
zodChain = "z.record(z.unknown())";
|
|
154
126
|
}
|
|
155
127
|
break;
|
|
156
|
-
}
|
|
157
128
|
default:
|
|
158
129
|
zodChain = "z.any()";
|
|
159
130
|
break;
|
|
@@ -167,9 +138,6 @@ ${shape}
|
|
|
167
138
|
if (prop.isNullable) {
|
|
168
139
|
zodChain += ".nullable()";
|
|
169
140
|
}
|
|
170
|
-
if (prop.defaultValue !== void 0) {
|
|
171
|
-
zodChain += `.default(${JSON.stringify(prop.defaultValue)})`;
|
|
172
|
-
}
|
|
173
141
|
return zodChain;
|
|
174
142
|
}
|
|
175
143
|
|
|
@@ -201,6 +169,7 @@ function parseSchema(name, schema, allEnums) {
|
|
|
201
169
|
for (const propName in schema.properties) {
|
|
202
170
|
const propSchema = schema.properties[propName];
|
|
203
171
|
let itemSchema;
|
|
172
|
+
let generatedEnumName;
|
|
204
173
|
if (propSchema.type === "array" && propSchema.items) {
|
|
205
174
|
const itemTypeName = `${toPascalCase(name)}${toPascalCase(propName)}Item`;
|
|
206
175
|
itemSchema = parseSchema(itemTypeName, propSchema.items, allEnums).properties[0];
|
|
@@ -208,7 +177,10 @@ function parseSchema(name, schema, allEnums) {
|
|
|
208
177
|
if (propSchema.enum) {
|
|
209
178
|
const enumName = `${toPascalCase(name)}${toPascalCase(propName)}Enum`;
|
|
210
179
|
enums[propName] = propSchema.enum;
|
|
211
|
-
if (!allEnums.has(enumName))
|
|
180
|
+
if (!allEnums.has(enumName)) {
|
|
181
|
+
allEnums.set(enumName, { name: enumName, values: propSchema.enum });
|
|
182
|
+
}
|
|
183
|
+
generatedEnumName = enumName;
|
|
212
184
|
}
|
|
213
185
|
properties.push({
|
|
214
186
|
name: propName,
|
|
@@ -218,9 +190,18 @@ function parseSchema(name, schema, allEnums) {
|
|
|
218
190
|
description: propSchema.description,
|
|
219
191
|
example: propSchema.example,
|
|
220
192
|
enum: propSchema.enum,
|
|
193
|
+
enumName: generatedEnumName,
|
|
194
|
+
// <-- Pass the enum name to the property
|
|
221
195
|
format: propSchema.format,
|
|
222
196
|
items: itemSchema,
|
|
223
|
-
properties: propSchema.properties ? parseSchema(`${name}${toPascalCase(propName)}`, propSchema, allEnums).properties : void 0
|
|
197
|
+
properties: propSchema.properties ? parseSchema(`${name}${toPascalCase(propName)}`, propSchema, allEnums).properties : void 0,
|
|
198
|
+
minLength: propSchema.minLength,
|
|
199
|
+
maxLength: propSchema.maxLength,
|
|
200
|
+
pattern: propSchema.pattern,
|
|
201
|
+
minimum: propSchema.minimum,
|
|
202
|
+
maximum: propSchema.maximum,
|
|
203
|
+
minItems: propSchema.minItems,
|
|
204
|
+
maxItems: propSchema.maxItems
|
|
224
205
|
});
|
|
225
206
|
}
|
|
226
207
|
}
|
|
@@ -294,243 +275,50 @@ async function generateModuleFiles(module2, allSchemas, allEnums, outputDir) {
|
|
|
294
275
|
Generating module: ${import_chalk.default.bold(module2.moduleName)}`));
|
|
295
276
|
const schemasToImport = [...module2.schemas].sort();
|
|
296
277
|
const enumsToImport = [...module2.enums].sort();
|
|
297
|
-
const indexContent = [`// This file is auto-generated.
|
|
278
|
+
const indexContent = [`// This file is auto-generated. Do not edit directly.
|
|
298
279
|
|
|
299
280
|
export * from './config';`];
|
|
300
|
-
let configContent = `/* eslint-disable */
|
|
301
|
-
// This file is auto-generated.
|
|
302
|
-
|
|
303
|
-
import type { ApiModuleConfig, ActionConfigModule, QueryOptions } from 'api-core-lib';
|
|
304
|
-
`;
|
|
305
|
-
if (schemasToImport.length > 0) configContent += `import type { ${schemasToImport.join(", ")} } from './types';
|
|
306
|
-
`;
|
|
307
|
-
const actionsType = Object.values(module2.actions).map((a) => ` ${a.name}: ActionConfigModule<${a.inputType}, ${a.outputType}>;`).join("\n");
|
|
308
|
-
const actionsValue = Object.values(module2.actions).map((a) => {
|
|
309
|
-
const { inputType, outputType, name, ...c } = a;
|
|
310
|
-
return ` ${name}: ${JSON.stringify(c, null, 2).replace(/\n/g, "\n ")}`;
|
|
311
|
-
}).join(",\n");
|
|
312
|
-
configContent += `
|
|
313
|
-
export const ${module2.moduleName}Module: ApiModuleConfig<{
|
|
314
|
-
${actionsType}
|
|
315
|
-
}> = {
|
|
316
|
-
baseEndpoint: '${module2.baseEndpoint}',
|
|
317
|
-
actions: {
|
|
318
|
-
${actionsValue}
|
|
319
|
-
},
|
|
320
|
-
};
|
|
321
|
-
`;
|
|
322
|
-
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "config.ts"), configContent.trim());
|
|
323
|
-
console.log(import_chalk.default.gray(` \u2713 config.ts`));
|
|
324
281
|
if (schemasToImport.length > 0) {
|
|
325
|
-
|
|
326
|
-
|
|
282
|
+
indexContent.push(`export * from './types';`);
|
|
283
|
+
indexContent.push(`export * from './enums';`);
|
|
284
|
+
let validationContent = `// This file is auto-generated by the API generator. Do not edit directly.
|
|
327
285
|
|
|
286
|
+
import { z } from 'zod';
|
|
328
287
|
`;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
if (enumDef) {
|
|
332
|
-
enumsContent += `export const ${enumName} = ${JSON.stringify(enumDef.values)} as const;
|
|
333
|
-
`;
|
|
334
|
-
enumsContent += `export type ${enumName} = typeof ${enumName}[number];
|
|
335
|
-
|
|
288
|
+
if (enumsToImport.length > 0) {
|
|
289
|
+
validationContent += `import { ${enumsToImport.join(", ")} } from './enums';
|
|
336
290
|
`;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "enums.ts"), enumsContent);
|
|
340
|
-
console.log(import_chalk.default.gray(` \u2713 enums.ts`));
|
|
341
|
-
indexContent.push(`export * from './enums';`);
|
|
342
291
|
}
|
|
343
|
-
let typesContent = `// This file is auto-generated.
|
|
344
|
-
|
|
345
|
-
`;
|
|
346
|
-
if (enumsToImport.length > 0) typesContent += `import type { ${enumsToImport.join(", ")} } from './enums';
|
|
347
|
-
|
|
348
|
-
`;
|
|
349
292
|
for (const typeName of schemasToImport) {
|
|
350
293
|
const parsedSchema = allSchemas.get(typeName);
|
|
351
294
|
if (parsedSchema) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
typesContent += `export interface ${typeName} {
|
|
357
|
-
`;
|
|
358
|
-
for (const prop of parsedSchema.properties) {
|
|
359
|
-
if (prop.description) typesContent += ` /**
|
|
360
|
-
* ${prop.description}
|
|
361
|
-
${prop.example ? ` * @example ${JSON.stringify(prop.example)}
|
|
362
|
-
` : ""} */
|
|
295
|
+
const zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
|
|
296
|
+
validationContent += `
|
|
297
|
+
/**
|
|
298
|
+
* Zod schema for {@link ${typeName}}.
|
|
363
299
|
`;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
else if (prop.items) propType = prop.items.name ? `${toPascalCase(prop.items.name)}[]` : `${prop.items.type || "unknown"}[]`;
|
|
367
|
-
else if (prop.type === "object") propType = prop.properties && prop.properties.length > 0 ? `Record<string, unknown>` : `Record<string, unknown>`;
|
|
368
|
-
typesContent += ` ${prop.name}${prop.isRequired ? "" : "?"}: ${propType};
|
|
300
|
+
if (parsedSchema.description) {
|
|
301
|
+
validationContent += ` * @description ${parsedSchema.description.replace(/\*\//g, "*\\/")}
|
|
369
302
|
`;
|
|
370
303
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
`;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "types.ts"), typesContent);
|
|
377
|
-
console.log(import_chalk.default.gray(` \u2713 types.ts`));
|
|
378
|
-
indexContent.push(`export * from './types';`);
|
|
379
|
-
const validationFileHeader = `// This file is auto-generated.
|
|
380
|
-
import { z, ZodIssueCode, ZodError } from 'zod';
|
|
381
|
-
${enumsToImport.length > 0 ? `import { ${enumsToImport.join(", ")} } from './enums';
|
|
382
|
-
` : ""}
|
|
383
|
-
// =============================================================================
|
|
384
|
-
// I. \u0625\u0639\u062F\u0627\u062F \u062E\u0631\u064A\u0637\u0629 \u0623\u062E\u0637\u0627\u0621 \u0639\u0627\u0644\u0645\u064A\u0629 (Global Error Map) \u0644\u062F\u0639\u0645 \u0627\u0644\u062A\u0631\u062C\u0645\u0629
|
|
385
|
-
// =============================================================================
|
|
386
|
-
//
|
|
387
|
-
// \u0645\u0644\u0627\u062D\u0638\u0629 \u0647\u0627\u0645\u0629: \u0641\u064A \u062A\u0637\u0628\u064A\u0642 \u062D\u0642\u064A\u0642\u064A\u060C \u064A\u062C\u0628 \u062A\u0639\u0631\u064A\u0641 \u0647\u0630\u0647 \u0627\u0644\u062E\u0631\u064A\u0637\u0629 \u0645\u0631\u0629 \u0648\u0627\u062D\u062F\u0629 \u0641\u0642\u0637
|
|
388
|
-
// \u0641\u064A \u0646\u0642\u0637\u0629 \u0627\u0644\u062F\u062E\u0648\u0644 \u0644\u062A\u0637\u0628\u064A\u0642\u0643 (entry-point). \u062A\u0645 \u0648\u0636\u0639\u0647\u0627 \u0647\u0646\u0627 \u0644\u0644\u062A\u0648\u0636\u064A\u062D.
|
|
389
|
-
//
|
|
390
|
-
// \u0627\u0644\u0647\u062F\u0641: \u0631\u0628\u0637 \u0645\u0641\u0627\u062A\u064A\u062D \u0627\u0644\u062A\u0631\u062C\u0645\u0629 (\u0645\u062B\u0644 "validation.required") \u0627\u0644\u062A\u064A \u062A\u0645 \u062A\u0648\u0644\u064A\u062F\u0647\u0627
|
|
391
|
-
// \u0641\u064A \u0627\u0644\u0645\u062E\u0637\u0637\u0627\u062A \u0623\u062F\u0646\u0627\u0647 \u0628\u0631\u0633\u0627\u0626\u0644 \u062D\u0642\u064A\u0642\u064A\u0629 \u064A\u0645\u0643\u0646 \u0639\u0631\u0636\u0647\u0627 \u0644\u0644\u0645\u0633\u062A\u062E\u062F\u0645.
|
|
392
|
-
|
|
393
|
-
// 1. \u0645\u062B\u0627\u0644 \u0628\u0633\u064A\u0637 \u0644\u062F\u0627\u0644\u0629 \u062A\u0631\u062C\u0645\u0629 (\u0641\u064A \u062A\u0637\u0628\u064A\u0642\u0643 \u0633\u062A\u0633\u062A\u062E\u062F\u0645 \u0645\u0643\u062A\u0628\u0629 \u0645\u062B\u0644 i18next)
|
|
394
|
-
const t = (key: string, args?: any): string => {
|
|
395
|
-
// \u0647\u0646\u0627 \u062A\u0636\u0639 \u0645\u0646\u0637\u0642 \u0627\u0644\u062A\u0631\u062C\u0645\u0629 \u0627\u0644\u062D\u0642\u064A\u0642\u064A \u0627\u0644\u062E\u0627\u0635 \u0628\u0643.
|
|
396
|
-
// \u0647\u0630\u0627 \u0645\u062C\u0631\u062F \u0645\u062B\u0627\u0644 \u0628\u0633\u064A\u0637.
|
|
397
|
-
if (key === 'validation.string.nonempty') return '\u0647\u0630\u0627 \u0627\u0644\u062D\u0642\u0644 \u0645\u0637\u0644\u0648\u0628 \u0648\u0644\u0627 \u064A\u0645\u0643\u0646 \u0623\u0646 \u064A\u0643\u0648\u0646 \u0641\u0627\u0631\u063A\u064B\u0627.';
|
|
398
|
-
if (key === 'validation.string.email') return '\u0627\u0644\u0631\u062C\u0627\u0621 \u0625\u062F\u062E\u0627\u0644 \u0628\u0631\u064A\u062F \u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A \u0635\u0627\u0644\u062D.';
|
|
399
|
-
if (key === 'validation.required') return '\u0647\u0630\u0627 \u0627\u0644\u062D\u0642\u0644 \u0625\u0644\u0632\u0627\u0645\u064A.';
|
|
400
|
-
// \u0631\u0633\u0627\u0644\u0629 \u0627\u062D\u062A\u064A\u0627\u0637\u064A\u0629
|
|
401
|
-
return key.split('.').pop()?.replace(/_/g, ' ') || key;
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
// 2. \u062A\u0639\u0631\u064A\u0641 \u062E\u0631\u064A\u0637\u0629 \u0627\u0644\u0623\u062E\u0637\u0627\u0621 \u0627\u0644\u0645\u062E\u0635\u0635\u0629
|
|
405
|
-
const customErrorMap: z.ZodErrorMap = (issue, ctx) => {
|
|
406
|
-
if (issue.message) {
|
|
407
|
-
// \u0625\u0630\u0627 \u0643\u0627\u0646\u062A \u0627\u0644\u0631\u0633\u0627\u0644\u0629 \u0647\u064A \u0645\u0641\u062A\u0627\u062D \u062A\u0631\u062C\u0645\u0629\u060C \u0642\u0645 \u0628\u062A\u0631\u062C\u0645\u062A\u0647\u0627
|
|
408
|
-
if (issue.message.startsWith('validation.')) {
|
|
409
|
-
return { message: t(issue.message) };
|
|
410
|
-
}
|
|
411
|
-
// \u0648\u0625\u0644\u0627\u060C \u0641\u0647\u064A \u0631\u0633\u0627\u0644\u0629 \u0645\u062E\u0635\u0635\u0629 \u0645\u0628\u0627\u0634\u0631\u0629
|
|
412
|
-
return { message: issue.message };
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// \u062A\u0631\u062C\u0645\u0629 \u0627\u0644\u0623\u062E\u0637\u0627\u0621 \u0627\u0644\u0627\u0641\u062A\u0631\u0627\u0636\u064A\u0629 \u0627\u0644\u0639\u0627\u0645\u0629
|
|
416
|
-
if (issue.code === ZodIssueCode.invalid_type) {
|
|
417
|
-
return { message: t('validation.required') };
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
return { message: ctx.defaultError };
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
// 3. \u0642\u0645 \u0628\u062A\u0639\u064A\u064A\u0646 \u0627\u0644\u062E\u0631\u064A\u0637\u0629 \u0627\u0644\u0645\u062E\u0635\u0635\u0629 \u0639\u0627\u0644\u0645\u064A\u064B\u0627 (\u064A\u062C\u0628 \u0639\u0645\u0644 \u0630\u0644\u0643 \u0645\u0631\u0629 \u0648\u0627\u062D\u062F\u0629 \u0641\u064A \u0627\u0644\u062A\u0637\u0628\u064A\u0642)
|
|
424
|
-
z.setErrorMap(customErrorMap);
|
|
425
|
-
|
|
426
|
-
// =============================================================================
|
|
427
|
-
// II. \u0645\u062E\u0637\u0637\u0627\u062A \u0627\u0644\u062A\u062D\u0642\u0642 \u0627\u0644\u0645\u0648\u0644\u062F\u0629 \u062A\u0644\u0642\u0627\u0626\u064A\u064B\u0627 (Generated Validation Schemas)
|
|
428
|
-
// =============================================================================
|
|
429
|
-
`;
|
|
430
|
-
let validationContent = validationFileHeader;
|
|
431
|
-
for (const typeName of schemasToImport) {
|
|
432
|
-
const parsedSchema = allSchemas.get(typeName);
|
|
433
|
-
if (parsedSchema) {
|
|
434
|
-
let zodShape = parsedSchema.properties.map((p) => ` ${p.name}: ${_propToZod(p)}`).join(",\n");
|
|
435
|
-
validationContent += `
|
|
436
|
-
/**
|
|
437
|
-
* Schema for validating ${typeName} objects.
|
|
438
|
-
* @description ${parsedSchema.description || ""}
|
|
439
|
-
*/
|
|
304
|
+
validationContent += ` */
|
|
440
305
|
`;
|
|
441
306
|
validationContent += `export const ${typeName}Schema = z.object({
|
|
442
307
|
${zodShape}
|
|
443
308
|
});
|
|
309
|
+
|
|
444
310
|
`;
|
|
445
|
-
validationContent += `export type ${typeName}
|
|
311
|
+
validationContent += `export type ${typeName}Validated = z.infer<typeof ${typeName}Schema>;
|
|
446
312
|
`;
|
|
447
313
|
}
|
|
448
314
|
}
|
|
449
|
-
if (schemasToImport.length > 0) {
|
|
450
|
-
const firstSchemaName = schemasToImport[0];
|
|
451
|
-
validationContent += `
|
|
452
|
-
// =============================================================================
|
|
453
|
-
// III. \u0645\u062B\u0627\u0644 \u0639\u0644\u0649 \u0643\u064A\u0641\u064A\u0629 \u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0627\u0644\u0645\u062E\u0637\u0637 \u0641\u064A \u0627\u0644\u0643\u0648\u062F
|
|
454
|
-
// =============================================================================
|
|
455
|
-
/*
|
|
456
|
-
function
|
|
457
|
-
|
|
458
|
-
validate${firstSchemaName}(data: unknown) {
|
|
459
|
-
try {
|
|
460
|
-
const validatedData = ${firstSchemaName}Schema.parse(data);
|
|
461
|
-
console.log("\u2705 Validation successful:", validatedData);
|
|
462
|
-
return { success: true, data: validatedData };
|
|
463
|
-
} catch (error) {
|
|
464
|
-
if (error instanceof ZodError) {
|
|
465
|
-
console.error("\u274C Validation failed:");
|
|
466
|
-
// .format() is great for getting a structured error object
|
|
467
|
-
console.log(JSON.stringify(error.format(), null, 2));
|
|
468
|
-
return { success: false, errors: error.format() };
|
|
469
|
-
}
|
|
470
|
-
throw error; // Rethrow other unexpected errors
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// Example usage with invalid data:
|
|
475
|
-
const invalidData = { /* ... \u0628\u064A\u0627\u0646\u0627\u062A \u063A\u064A\u0631 \u0643\u0627\u0645\u0644\u0629 \u0623\u0648 \u062E\u0627\u0637\u0626\u0629 ... */ };
|
|
476
|
-
// validate${firstSchemaName}(invalidData);
|
|
477
|
-
*/
|
|
478
|
-
`;
|
|
479
|
-
}
|
|
480
315
|
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "validation.ts"), validationContent);
|
|
481
|
-
console.log(import_chalk.default.gray(` \u2713 validation.ts
|
|
316
|
+
console.log(import_chalk.default.gray(` \u2713 validation.ts`));
|
|
482
317
|
indexContent.push(`export * from './validation';`);
|
|
483
|
-
let mocksContent = `// This file is auto-generated.
|
|
484
|
-
import type { ${schemasToImport.join(", ")} } from './types';
|
|
485
|
-
`;
|
|
486
|
-
if (enumsToImport.length > 0) mocksContent += `import { ${enumsToImport.join(", ")} } from './enums';
|
|
487
|
-
|
|
488
|
-
`;
|
|
489
|
-
for (const typeName of schemasToImport) {
|
|
490
|
-
const parsedSchema = allSchemas.get(typeName);
|
|
491
|
-
if (parsedSchema) {
|
|
492
|
-
let mockObject = {};
|
|
493
|
-
parsedSchema.properties.forEach((p) => {
|
|
494
|
-
mockObject[p.name] = _propToMock(p);
|
|
495
|
-
});
|
|
496
|
-
mocksContent += `export const mock${typeName}: ${typeName} = ${JSON.stringify(mockObject, null, 2)};
|
|
497
|
-
|
|
498
|
-
`;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "mocks.ts"), mocksContent);
|
|
502
|
-
console.log(import_chalk.default.gray(` \u2713 mocks.ts`));
|
|
503
|
-
indexContent.push(`export * from './mocks';`);
|
|
504
318
|
}
|
|
505
319
|
import_fs.default.writeFileSync(import_path.default.join(moduleOutputPath, "index.ts"), indexContent.join("\n"));
|
|
506
320
|
console.log(import_chalk.default.gray(` \u2713 index.ts`));
|
|
507
321
|
}
|
|
508
|
-
function _propToMock(prop) {
|
|
509
|
-
if (prop.example) return prop.example;
|
|
510
|
-
if (prop.name.match(/image|avatar|logo|url/i)) return "https://via.placeholder.com/150";
|
|
511
|
-
if (prop.enum) return prop.enum[0];
|
|
512
|
-
switch (prop.type) {
|
|
513
|
-
case "string":
|
|
514
|
-
if (prop.format === "email") return "test@example.com";
|
|
515
|
-
if (prop.format === "uuid") return "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11";
|
|
516
|
-
return `Mock ${toPascalCase(prop.name)}`;
|
|
517
|
-
case "integer":
|
|
518
|
-
case "number":
|
|
519
|
-
return 1;
|
|
520
|
-
case "boolean":
|
|
521
|
-
return true;
|
|
522
|
-
case "array":
|
|
523
|
-
return prop.items ? [_propToMock(prop.items)] : [];
|
|
524
|
-
case "object":
|
|
525
|
-
const mock = {};
|
|
526
|
-
if (prop.properties) prop.properties.forEach((p) => {
|
|
527
|
-
mock[p.name] = _propToMock(p);
|
|
528
|
-
});
|
|
529
|
-
return mock;
|
|
530
|
-
default:
|
|
531
|
-
return null;
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
322
|
async function runGenerator(options) {
|
|
535
323
|
console.log(import_chalk.default.cyan.bold("\u{1F680} Starting API Development Platform Generator (Sapphire Edition)..."));
|
|
536
324
|
import_dotenv.default.config({ path: options.envPath });
|