# 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 - `MigrationStrategy` enum covering the eight common transforms (`ADD_FIELD`, `REMOVE_FIELD`, `RENAME_FIELD`, `CHANGE_FIELD_TYPE`, `MOVE_FIELD`, `SPLIT_FIELD`, `MERGE_FIELDS`, `CUSTOM`). - `MigrationOperation` descriptor — a serialisable record of one step. - `MigrationFunction` — a pure data transform, no side effects. - `SchemaTypeToDataType` helper — propagates inferred runtime types. - Pure functions; no state, no I/O. ## Usage: Basic Example ```ts 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), 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. ```ts import { MigrationStrategy, type MigrationFunction, type MigrationOperation, } from "@suaveplan/bitpacker-schema"; const renameUserId: MigrationFunction = (raw) => { const r = raw as Record; 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 optional `fromField` / `toField` / `fromType` / `toType` / `metadata`. - `type MigrationFunction` — `(data: T) => U`. - `type SchemaTypeToDataType` — placeholder for runtime data type inference; ported as `unknown` (upstream uses ad-hoc inference). ## Implementation Notes - This file deliberately avoids any reference to actual `BitPackerSchema` evaluation; it is shape-only metadata. Execution lives in `versioning.ts` where chains are walked. - Strategies map 1:1 with the upstream enum so that migrations authored against the old API port without modification. - The `CUSTOM` strategy is the escape hatch for transforms that don't fit the other seven; the consumer supplies an arbitrary `MigrationFunction` and a description.