Files
openapi-clean-arch-gen/src/utils/mock-value-resolver.ts

71 lines
2.4 KiB
TypeScript

/**
* Resolves a TypeScript literal string to use as a mock value for a single schema property.
*
* Priority chain:
* $ref mock call → array $ref mock call → enum[0] → example → format fallback → type default
*
* @param propName Property name (used for format heuristics such as "email").
* @param prop Raw OpenAPI property definition.
* @param context 'dto' generates `mockFooDto()`, 'model' generates `mockFooModel()`.
*/
export function resolveMockValue(
propName: string,
prop: {
type?: string;
format?: string;
example?: unknown;
enum?: unknown[];
$ref?: string;
items?: { $ref?: string; type?: string };
},
context: 'dto' | 'model' = 'dto'
): string {
const suffix = context === 'dto' ? 'Dto' : 'Model';
// 1. Direct $ref → call the referenced mock factory
if (prop.$ref) {
const refName = prop.$ref.split('/').pop()!;
return `mock${refName}${suffix}()`;
}
// 2. Array of $ref → wrap referenced mock in an array
if (prop.type === 'array' && prop.items?.$ref) {
const refName = prop.items.$ref.split('/').pop()!;
return `[mock${refName}${suffix}()]`;
}
// 3. Array of primitives
if (prop.type === 'array') return '[]';
// 4. Enum → first declared value
if (prop.enum?.length) {
const first = prop.enum[0];
return typeof first === 'string' ? `'${first}'` : String(first);
}
// 5. Example value from the swagger spec (highest fidelity)
if (prop.example !== undefined) return formatLiteral(prop.example);
// 6. Format-aware fallbacks (when no example is provided)
if (prop.format === 'date-time') return `'2024-01-01T00:00:00.000Z'`;
if (prop.format === 'date') return `'2024-01-01'`;
if (prop.format === 'uuid') return `'00000000-0000-0000-0000-000000000000'`;
if (prop.format === 'uri') return `'https://example.com'`;
if (prop.format === 'email' || propName.toLowerCase().includes('email'))
return `'user@example.com'`;
// 7. Type defaults
if (prop.type === 'string') return `'value'`;
if (prop.type === 'integer' || prop.type === 'number') return `0`;
if (prop.type === 'boolean') return `false`;
return 'undefined';
}
function formatLiteral(value: unknown): string {
if (typeof value === 'string') return `'${value}'`;
if (typeof value === 'number') return `${value}`;
if (typeof value === 'boolean') return `${value}`;
return `'${String(value)}'`;
}