Enums

Enums() defines reusable fixed choices while preserving their literal values:

import {
  Enums,
  bd,
  collection,
  type InferEnumValues,
} from '@businessdash/sdk'

export const ProjectStatus = Enums([
  'planned',
  'inProgress',
  { value: 'on_hold', label: 'Paused' },
] as const)

export type ProjectStatusValue =
  InferEnumValues<typeof ProjectStatus>

The inferred union is:

type ProjectStatusValue =
  | 'planned'
  | 'inProgress'
  | 'on_hold'

Attach enum fields

const projects = collection('projects', {
  fields: {
    status: bd
      .enum(ProjectStatus)
      .default('planned')
      .formElement('dropdown'),
    labels: bd.multiEnum([
      'priority',
      'internal',
      'customerVisible',
    ] as const),
  },
})
  • bd.enum() stores SELECT.
  • bd.multiEnum() stores MULTI_SELECT.
  • Options are metadata rather than a native Postgres enum.

Labels

Enums() humanizes camelCase, PascalCase, snake_case, and kebab-case:

ValueGenerated label
inProgressIn Progress
NEEDS_REVIEWNeeds Review
on-holdOn Hold

Use an object when the displayed label should not be derived:

Enums([
  { value: 'sla_4h', label: 'Respond within four hours' },
] as const)

The stored value remains sla_4h.

Runtime helpers

An enum definition exposes:

ProjectStatus.entries
ProjectStatus.values
ProjectStatus.isValid(input)
ProjectStatus.getLabel('inProgress')

Use isValid() when parsing an untyped value before it enters application state.

Changing enum options

Records store the option's value, while labels are display metadata. Changing only a label preserves the stored value. Changing the value can appear as a removal plus addition in a fluent Enums() declaration.

The lower-level SelectOption artifact supports a universalIdentifier, but the 0.9.50 Enums() input does not expose that property. Adopt the promoted model and review the dry-run plan before changing values on a Live enum.

Next: Relationships and Extensions.