Skip to content

Commit 1bb3ff3

Browse files
authored
Merge pull request #30 from firefliesai/feat/improve-array-support
2 parents 7832dc4 + c451a27 commit 1bb3ff3

3 files changed

Lines changed: 20 additions & 13 deletions

File tree

src/lib/class-validator-integration.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ interface ClassValidatorMetadata {
4343
*/
4444
export interface InferredArrayItems {
4545
type?: 'string' | 'number' | 'integer' | 'boolean';
46-
enum?: (string | number)[];
46+
enum?: (string | number | boolean)[];
4747
minimum?: number;
4848
maximum?: number;
4949
minLength?: number;
@@ -74,19 +74,21 @@ export interface InferredSchemaProperties {
7474
* Tries to get the class-validator metadata storage if available
7575
*/
7676
function getClassValidatorMetadataStorage(): any | null {
77+
const getGlobalStorage = () => {
78+
const g = globalThis as any;
79+
return g.classValidatorMetadataStorage || null;
80+
};
81+
7782
try {
7883
// Prefer getMetadataStorage() if class-validator is loaded - ensures same instance
7984
// eslint-disable-next-line @typescript-eslint/no-require-imports
8085
const cv = require('class-validator');
8186
if (typeof cv.getMetadataStorage === 'function') {
8287
return cv.getMetadataStorage();
8388
}
84-
// Fallback to global storage (populated when class-validator decorators run)
85-
const global = globalThis as any;
86-
return global.classValidatorMetadataStorage || null;
89+
return getGlobalStorage();
8790
} catch {
88-
const global = globalThis as any;
89-
return global.classValidatorMetadataStorage || null;
91+
return getGlobalStorage();
9092
}
9193
}
9294

@@ -186,10 +188,13 @@ export function inferClassValidatorProperties(
186188
typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean',
187189
);
188190
if (allPrimitive && values.length > 0) {
189-
const firstType = typeof values[0];
190-
items.type =
191-
firstType === 'string' ? 'string' : firstType === 'number' ? 'number' : 'boolean';
192-
items.enum = values as (string | number)[];
191+
const allSameType = values.every((v: unknown) => typeof v === typeof values[0]);
192+
if (allSameType) {
193+
const firstType = typeof values[0];
194+
items.type =
195+
firstType === 'string' ? 'string' : firstType === 'number' ? 'number' : 'boolean';
196+
}
197+
items.enum = values as (string | number | boolean)[];
193198
}
194199
}
195200
break;

src/lib/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export type Constructor<T> = new (...args: any[]) => T;
2121

2222
// Schema types
2323
export interface SchemaItemType {
24-
type?: 'string' | 'number' | 'boolean' | Constructor<any>;
25-
enum?: (string | number)[];
24+
type?: 'string' | 'number' | 'boolean' | 'integer' | Constructor<any>;
25+
enum?: (string | number | boolean)[];
2626
format?: 'date-time' | 'uri' | 'email' | string;
2727
minimum?: number;
2828
maximum?: number;

src/lib/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ export function normalizeItemsType(items: any): any {
230230

231231
if (items.type === Date) {
232232
normalizedItems.type = 'string';
233-
normalizedItems.format = 'date-time';
233+
if (!normalizedItems.format) {
234+
normalizedItems.format = 'date-time';
235+
}
234236
return normalizedItems;
235237
} else if (items.type === String) {
236238
normalizedItems.type = 'string';

0 commit comments

Comments
 (0)