more utility functions

This commit is contained in:
Aiden McClelland
2022-07-18 15:08:54 -06:00
parent 47cf6de393
commit 3a7e0989b9
8 changed files with 241 additions and 98 deletions

View File

@@ -2,19 +2,21 @@ import { types as T } from "./mod.ts";
import { EmVer } from "./emver-lite/mod.ts";
import { matches } from "./dependencies.ts";
export type MigrationFn = (effects: T.Effects) => Promise<T.MigrationRes>;
export type MigrationFn<version extends string, type extends "up" | "down"> = (
effects: T.Effects,
) => Promise<T.MigrationRes>;
export interface Migration {
up: MigrationFn;
down: MigrationFn;
export interface Migration<version extends string> {
up: MigrationFn<version, "up">;
down: MigrationFn<version, "down">;
}
export interface MigrationMapping {
[version: string]: Migration;
}
export type MigrationMapping<versions extends string> = {
[version in versions]: Migration<version>;
};
export function fromMapping(
migrations: MigrationMapping,
export function fromMapping<versions extends string>(
migrations: MigrationMapping<versions>,
currentVersion: string,
): T.ExpectedExports.migration {
const directionShape = matches.literals("from", "to");
@@ -32,24 +34,26 @@ export function fromMapping(
const current = EmVer.parse(currentVersion);
const other = EmVer.parse(version);
const filteredMigrations =
(Object.entries(migrations) as [
keyof MigrationMapping<string>,
Migration<string>,
][])
.map(([version, migration]) => ({
version: EmVer.parse(version),
migration,
})).filter(({ version }) =>
version.greaterThan(other) && version.lessThanOrEqual(current)
);
const migrationsToRun = matches.matches(direction)
.when("from", () =>
Object.entries(migrations)
.map(([version, migration]) => ({
version: EmVer.parse(version),
migration,
})).filter(({ version }) =>
version.greaterThan(other) && version.lessThanOrEqual(current)
).sort((a, b) => a.version.compareForSort(b.version))
filteredMigrations
.sort((a, b) => a.version.compareForSort(b.version)) // low to high
.map(({ migration }) => migration.up))
.when("to", () =>
Object.entries(migrations)
.map(([version, migration]) => ({
version: EmVer.parse(version),
migration,
})).filter(({ version }) =>
version.lessThanOrEqual(other) && version.greaterThan(current)
).sort((a, b) => b.version.compareForSort(a.version))
filteredMigrations
.sort((a, b) => b.version.compareForSort(a.version)) // high to low
.map(({ migration }) => migration.down))
.unwrap();