diff --git a/packages/core/utils/src/dml/__tests__/enum-schema.spec.ts b/packages/core/utils/src/dml/__tests__/enum-schema.spec.ts index 7f5300d13f..98cf2ad4de 100644 --- a/packages/core/utils/src/dml/__tests__/enum-schema.spec.ts +++ b/packages/core/utils/src/dml/__tests__/enum-schema.spec.ts @@ -46,4 +46,52 @@ describe("Enum property", () => { relationships: [], }) }) + + test("use typescript enum as enum property options", () => { + enum Roles { + ADMIN, + WRITER, + EDITOR, + } + + const property = new EnumProperty(Roles) + expectTypeOf(property["$dataType"]).toEqualTypeOf() + + expect(property.parse("role")).toEqual({ + fieldName: "role", + dataType: { + name: "enum", + options: { + choices: ["ADMIN", "WRITER", "EDITOR", 0, 1, 2], + }, + }, + nullable: false, + indexes: [], + relationships: [], + }) + }) + + test("use typescript enum with key-value pair as enum property options", () => { + enum Roles { + ADMIN = "admin", + WRITER = "writer", + EDITOR = "editor", + } + + const property = new EnumProperty(Roles) + expectTypeOf(property["$dataType"]).toEqualTypeOf() + + expect(property.parse("role")).toEqual({ + fieldName: "role", + dataType: { + name: "enum", + options: { + choices: ["admin", "writer", "editor"], + }, + }, + nullable: false, + indexes: [], + relationships: [], + }) + }) }) diff --git a/packages/core/utils/src/dml/entity-builder.ts b/packages/core/utils/src/dml/entity-builder.ts index 7b74cc9d57..1acd00a43d 100644 --- a/packages/core/utils/src/dml/entity-builder.ts +++ b/packages/core/utils/src/dml/entity-builder.ts @@ -6,7 +6,7 @@ import { ArrayProperty } from "./properties/array" import { BigNumberProperty } from "./properties/big-number" import { BooleanProperty } from "./properties/boolean" import { DateTimeProperty } from "./properties/date-time" -import { EnumProperty } from "./properties/enum" +import { EnumLike, EnumProperty } from "./properties/enum" import { IdProperty } from "./properties/id" import { JSONProperty } from "./properties/json" import { NumberProperty } from "./properties/number" @@ -291,7 +291,7 @@ export class EntityBuilder { * * @customNamespace Property Types */ - enum(values: Values[]) { + enum(values: Values) { return new EnumProperty(values) } diff --git a/packages/core/utils/src/dml/properties/enum.ts b/packages/core/utils/src/dml/properties/enum.ts index 3eb79bda31..b606321d8d 100644 --- a/packages/core/utils/src/dml/properties/enum.ts +++ b/packages/core/utils/src/dml/properties/enum.ts @@ -1,19 +1,38 @@ import { BaseProperty } from "./base" +export type EnumLike = { + [K: string]: string | number + [number: number]: string +} + /** * The EnumProperty is used to define a property with pre-defined * list of choices. */ export class EnumProperty< - const Values extends unknown -> extends BaseProperty { + const Values extends unknown[] | EnumLike +> extends BaseProperty< + Values extends EnumLike ? Values[keyof Values] : Values[number] +> { protected dataType: { name: "enum" - options: { choices: Values[] } + options: { + choices: any[] + } } - constructor(values: Values[]) { + constructor(values: Values) { super() - this.dataType = { name: "enum", options: { choices: values } } + if (Array.isArray(values)) { + this.dataType = { + name: "enum", + options: { choices: values }, + } + } else { + this.dataType = { + name: "enum", + options: { choices: Object.values(values) }, + } + } } }