mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-18 23:07:02 +08:00
feat(infra): orm f.enum() support (#9323)
This commit is contained in:
@@ -61,6 +61,7 @@ describe('Entity validations', () => {
|
||||
id: f.string().primaryKey().default(nanoid),
|
||||
name: f.string(),
|
||||
color: f.string(),
|
||||
status: f.enum('active', 'inactive').optional(),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -130,4 +131,15 @@ describe('Entity validations', () => {
|
||||
expect(tag.info).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
test('should throw when trying to create entity with invalid enum value', () => {
|
||||
const client = createTagsClient();
|
||||
|
||||
expect(() =>
|
||||
// @ts-expect-error test
|
||||
client.tags.create({ name: 'test', status: 'not-active' })
|
||||
).toThrow(
|
||||
"[Table(tags)]: Field 'status' value 'not-active' is not valid. Expected one of [active, inactive]."
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
export type FieldType = 'string' | 'number' | 'boolean' | 'json';
|
||||
export type FieldType = 'string' | 'number' | 'boolean' | 'json' | 'enum';
|
||||
|
||||
export interface FieldSchema<Type = unknown> {
|
||||
type: FieldType;
|
||||
optional: boolean;
|
||||
isPrimaryKey: boolean;
|
||||
default?: () => Type;
|
||||
values?: Type[];
|
||||
}
|
||||
|
||||
export type TableSchema = Record<string, FieldSchema>;
|
||||
@@ -28,10 +29,12 @@ export class FieldSchemaBuilder<
|
||||
optional: false,
|
||||
isPrimaryKey: false,
|
||||
default: undefined,
|
||||
values: undefined,
|
||||
};
|
||||
|
||||
constructor(type: FieldType) {
|
||||
constructor(type: FieldType, values?: string[]) {
|
||||
this.schema.type = type;
|
||||
this.schema.values = values;
|
||||
}
|
||||
|
||||
optional() {
|
||||
@@ -56,7 +59,9 @@ export const f = {
|
||||
number: () => new FieldSchemaBuilder<number>('number'),
|
||||
boolean: () => new FieldSchemaBuilder<boolean>('boolean'),
|
||||
json: <T = any>() => new FieldSchemaBuilder<T>('json'),
|
||||
} satisfies Record<FieldType, () => FieldSchemaBuilder<any>>;
|
||||
enum: <T extends string>(...values: T[]) =>
|
||||
new FieldSchemaBuilder<T>('enum', values),
|
||||
} as const;
|
||||
|
||||
export const t = {
|
||||
document: <T extends TableSchemaBuilder>(schema: T) => {
|
||||
|
||||
@@ -70,7 +70,14 @@ export const dataValidators = {
|
||||
}
|
||||
|
||||
const typeGet = inputType(val);
|
||||
if (!typeMatches(field.type, typeGet)) {
|
||||
|
||||
if (field.type === 'enum') {
|
||||
if (!field.values?.includes(val)) {
|
||||
throw new Error(
|
||||
`[Table(${table.name})]: Field '${key}' value '${val}' is not valid. Expected one of [${field.values?.join(', ')}].`
|
||||
);
|
||||
}
|
||||
} else if (!typeMatches(field.type, typeGet)) {
|
||||
throw new Error(
|
||||
`[Table(${table.name})]: Field '${key}' type mismatch. Expected ${field.type} got ${typeGet}.`
|
||||
);
|
||||
@@ -103,7 +110,13 @@ export const dataValidators = {
|
||||
}
|
||||
|
||||
const typeGet = inputType(val);
|
||||
if (!typeMatches(field.type, typeGet)) {
|
||||
if (field.type === 'enum') {
|
||||
if (!field.values?.includes(val)) {
|
||||
throw new Error(
|
||||
`[Table(${table.name})]: Field '${key}' value '${val}' is not valid. Expected one of [${field.values?.join(', ')}].`
|
||||
);
|
||||
}
|
||||
} else if (!typeMatches(field.type, typeGet)) {
|
||||
throw new Error(
|
||||
`[Table(${table.name})]: Field '${key}' type mismatch. Expected type '${field.type}' but got '${typeGet}'.`
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user