Skip to content

Commit

Permalink
fix(reflection): only validate known types to allow using type aliases
Browse files Browse the repository at this point in the history
Closes #5221
  • Loading branch information
B4nan committed Feb 8, 2024
1 parent 7741b75 commit d6b93be
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 9 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/entity/EntityValidator.ts
Expand Up @@ -6,6 +6,8 @@ import { helper } from './wrap';

export class EntityValidator {

KNOWN_TYPES = new Set(['string', 'number', 'boolean', 'bigint', 'Uint8Array', 'Date', 'Buffer', 'RegExp']);

constructor(private strict: boolean) { }

validate<T extends object>(entity: T, payload: any, meta: EntityMetadata<T>): void {
Expand Down Expand Up @@ -81,7 +83,7 @@ export class EntityValidator {
throw ValidationError.fromWrongPropertyType(entity, prop.name, expectedType, givenType, givenValue);
}
} else {
if (givenType !== expectedType) {
if (givenType !== expectedType && this.KNOWN_TYPES.has(expectedType)) {
throw ValidationError.fromWrongPropertyType(entity, prop.name, expectedType, givenType, givenValue);
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/knex/src/query/QueryBuilder.ts
Expand Up @@ -888,10 +888,10 @@ export class QueryBuilder<T extends object = AnyEntity> {
* Executes the query, returning both array of results and total count query (without offset and limit).
*/
async getResultAndCount(): Promise<[T[], number]> {
return Promise.all([
this.getResultList(),
this.getCount(),
]);
return [
await this.getResultList(),
await this.getCount(),
];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/reflection/src/TsMorphMetadataProvider.ts
Expand Up @@ -136,7 +136,7 @@ export class TsMorphMetadataProvider extends MetadataProvider {

let type = typeName;
const union = type.split(' | ');
const optional = property.hasQuestionToken?.() || union.includes('null') || union.includes('undefined');
const optional = property.hasQuestionToken?.() || union.includes('null') || union.includes('undefined') || tsType.isNullable();
type = union.filter(t => !['null', 'undefined'].includes(t)).join(' | ');

prop.array ??= type.endsWith('[]') || !!type.match(/Array<(.*)>/);
Expand Down
12 changes: 9 additions & 3 deletions tests/features/reflection/GH5185.test.ts
Expand Up @@ -8,6 +8,8 @@ enum OrderState {
CLOSED = 'closed',
}

type Nullable<T> = T | null;

@Entity()
class User {

Expand All @@ -17,6 +19,9 @@ class User {
@Property()
username!: string;

@Property({ columnType: 'varchar' })
test!: Nullable<string>;

@Enum({ items: () => OrderState })
state: Opt<OrderState> = OrderState.NEW;

Expand All @@ -38,12 +43,13 @@ afterAll(async () => {
await orm.close(true);
});

test('#5185', async () => {
orm.em.create(User, { username: 'u' });
test('#5185 and #5221', async () => {
orm.em.create(User, { username: 'u', test: '123' });
await orm.em.flush();
orm.em.clear();
const u1 = await orm.em.fork().find(User, {});
expect(u1).toHaveLength(1);
const u2 = await orm.em.fork().qb(User).getResult();
const [u2, total] = await orm.em.fork().qb(User).getResultAndCount();
expect(u2).toHaveLength(1);
expect(total).toBe(1);
});

0 comments on commit d6b93be

Please sign in to comment.