import { setupActions } from "../../actions/setupActions" import { EmVer } from "../../emverLite/mod" import { SDKManifest } from "../../manifest/ManifestTypes" import { ExpectedExports } from "../../types" import { once } from "../../util/once" import { Migration } from "./Migration" export class Migrations { private constructor( readonly manifest: SDKManifest, readonly migrations: Array>, ) {} private sortedMigrations = once(() => { const migrationsAsVersions = (this.migrations as Array>).map( (x) => [EmVer.parse(x.options.version), x] as const, ) migrationsAsVersions.sort((a, b) => a[0].compareForSort(b[0])) return migrationsAsVersions }) private currentVersion = once(() => EmVer.parse(this.manifest.version)) static of>>( manifest: SDKManifest, ...migrations: EnsureUniqueId ) { return new Migrations(manifest, migrations as Array>) } async init({ effects, previousVersion, }: Parameters[0]) { if (!!previousVersion) { const previousVersionEmVer = EmVer.parse(previousVersion) for (const [_, migration] of this.sortedMigrations() .filter((x) => x[0].greaterThan(previousVersionEmVer)) .filter((x) => x[0].lessThanOrEqual(this.currentVersion()))) { await migration.up({ effects }) } } } async uninit({ effects, nextVersion, }: Parameters[0]) { if (!!nextVersion) { const nextVersionEmVer = EmVer.parse(nextVersion) const reversed = [...this.sortedMigrations()].reverse() for (const [_, migration] of reversed .filter((x) => x[0].greaterThan(nextVersionEmVer)) .filter((x) => x[0].lessThanOrEqual(this.currentVersion()))) { await migration.down({ effects }) } } } } export function setupMigrations>>( manifest: SDKManifest, ...migrations: EnsureUniqueId ) { return Migrations.of(manifest, ...migrations) } // prettier-ignore export type EnsureUniqueId = B extends [] ? A : B extends [Migration, ...infer Rest] ? ( id extends ids ? "One of the ids are not unique"[] : EnsureUniqueId ) : "There exists a migration that is not a Migration"[]