first commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Schema Migration
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## 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<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
|
||||
|
||||
```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<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.
|
||||
|
||||
```ts
|
||||
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 optional
|
||||
`fromField` / `toField` / `fromType` / `toType` / `metadata`.
|
||||
- `type MigrationFunction<T, U>` — `(data: T) => U`.
|
||||
- `type SchemaTypeToDataType<T>` — 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.
|
||||
Reference in New Issue
Block a user