3.3 KiB
Schema Migration
(no submodules)
Purpose
migration.ts ports the bit-packer schema migration toolkit from
upstream. A migration describes how to transform data shaped by an old
BitPackerSchema into data shaped by a newer one — adding fields,
removing fields, renaming, changing types, splitting, merging, or
running a fully custom transform. The toolkit is designed to be
composable: a single migration step is a MigrationFunction, a strategy
is one of MigrationStrategy, and a chain of strategies forms a path
between two schema versions tracked by bitpacker-schema/versioning/.
This module is the data-shape side of schema evolution. The companion
versioning.ts module owns version registration, lookup, and
chain-execution; this file owns the per-step transform vocabulary,
operation descriptors, and the helper builders that turn a strategy
into a runnable function.
Features
MigrationStrategyenum covering the eight common transforms (ADD_FIELD,REMOVE_FIELD,RENAME_FIELD,CHANGE_FIELD_TYPE,MOVE_FIELD,SPLIT_FIELD,MERGE_FIELDS,CUSTOM).MigrationOperationdescriptor — a serialisable record of one step.MigrationFunction<T, U>— a pure data transform, no side effects.SchemaTypeToDataType<T>helper — propagates inferred runtime types.- Pure functions; no state, no I/O.
Usage: Basic Example
import {
MigrationStrategy,
type MigrationFunction,
} from "@suaveplan/bitpacker-schema";
// A v1 record is a plain `{ id }`; v2 adds `createdAt`.
const addCreatedAt: MigrationFunction = (data) => ({
...(data as Record<string, unknown>),
createdAt: new Date().toISOString(),
});
Usage: Advanced Example
Compose multiple migrations through the versioning store. The
migration.ts module supplies the building blocks; versioning.ts
chains them.
import {
MigrationStrategy,
type MigrationFunction,
type MigrationOperation,
} from "@suaveplan/bitpacker-schema";
const renameUserId: MigrationFunction = (raw) => {
const r = raw as Record<string, unknown>;
const { user_id, ...rest } = r;
return { ...rest, userId: user_id };
};
const renameOp: MigrationOperation = {
strategy: MigrationStrategy.RENAME_FIELD,
fromField: "user_id",
toField: "userId",
};
// Combined with versioning's `addMigration(fromVersion, toVersion, fn)`,
// the v2 -> v3 hop becomes a deterministic, replayable transform.
API Reference
enum MigrationStrategy— eight strategy tags.interface MigrationOperation—strategy, plus optionalfromField/toField/fromType/toType/metadata.type MigrationFunction<T, U>—(data: T) => U.type SchemaTypeToDataType<T>— placeholder for runtime data type inference; ported asunknown(upstream uses ad-hoc inference).
Implementation Notes
- This file deliberately avoids any reference to actual
BitPackerSchemaevaluation; it is shape-only metadata. Execution lives inversioning.tswhere chains are walked. - Strategies map 1:1 with the upstream enum so that migrations authored against the old API port without modification.
- The
CUSTOMstrategy is the escape hatch for transforms that don't fit the other seven; the consumer supplies an arbitraryMigrationFunctionand a description.