Add the migrations back using new tests.
This commit is contained in:
parent
0ad7345a71
commit
dfc42535f0
|
@ -0,0 +1,29 @@
|
||||||
|
import {setup} from "@holllo/test";
|
||||||
|
|
||||||
|
import {dataMigrations, type QueueItemPre030} from "./migrations.js";
|
||||||
|
|
||||||
|
import snapshots from "./snapshots.json";
|
||||||
|
|
||||||
|
const queueItemSample: QueueItemPre030 = {
|
||||||
|
added: new Date("2022-03-02T16:00:00Z"),
|
||||||
|
id: 1,
|
||||||
|
text: "Sample",
|
||||||
|
url: "https://example.org",
|
||||||
|
};
|
||||||
|
|
||||||
|
await setup("Migrations", async (group) => {
|
||||||
|
group.test("Snapshots", async (test) => {
|
||||||
|
let data: Record<string, any> = {
|
||||||
|
latestVersion: "0.1.0",
|
||||||
|
queue: [queueItemSample],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [index, migration] of dataMigrations.entries()) {
|
||||||
|
data = (await migration.migrate(data)) as Record<string, any>;
|
||||||
|
test.equals(
|
||||||
|
JSON.stringify(data, null, 2),
|
||||||
|
JSON.stringify(snapshots[index], null, 2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,115 @@
|
||||||
|
import browser from "webextension-polyfill";
|
||||||
|
import {migrate, type Migration} from "@holllo/migration-helper";
|
||||||
|
import {createValue} from "@holllo/webextension-storage";
|
||||||
|
|
||||||
|
import type {ItemKeyPrefix} from "../item/item.js";
|
||||||
|
|
||||||
|
/** The Queue Item type for versions `<0.3.0`. */
|
||||||
|
export type QueueItemPre030 = {
|
||||||
|
added: Date;
|
||||||
|
id: number;
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The Queue Item type for versions `>=0.3.0 <1.0.0`. */
|
||||||
|
export type QueueItem030 = {
|
||||||
|
sortIndex: number;
|
||||||
|
} & QueueItemPre030;
|
||||||
|
|
||||||
|
/** The Queue Item type for versions `>=1.0.0`. */
|
||||||
|
export type QueueItem100 = {
|
||||||
|
dateAdded: Date;
|
||||||
|
id: number;
|
||||||
|
text: string | undefined;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** All migrations for Queue storage. */
|
||||||
|
export const dataMigrations: Array<Migration<string>> = [
|
||||||
|
{
|
||||||
|
version: "0.1.7",
|
||||||
|
async migrate(data: Record<string, any>) {
|
||||||
|
const migrated: Record<string, any> = {
|
||||||
|
version: "0.1.7",
|
||||||
|
};
|
||||||
|
|
||||||
|
const items = (data.queue as QueueItemPre030[]) ?? [];
|
||||||
|
for (const item of items) {
|
||||||
|
const key = `qi${item.id}`;
|
||||||
|
migrated[key] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return migrated;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: "0.3.0",
|
||||||
|
async migrate(data: Record<string, any>) {
|
||||||
|
const migrated: Record<string, any> = {
|
||||||
|
version: "0.3.0",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries<QueueItemPre030>(data)) {
|
||||||
|
if (key.startsWith("qi")) {
|
||||||
|
const item: QueueItem030 = {
|
||||||
|
sortIndex: value.id,
|
||||||
|
...value,
|
||||||
|
};
|
||||||
|
migrated[key] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return migrated;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: "1.0.0",
|
||||||
|
async migrate(data: Record<string, any>) {
|
||||||
|
const migrated: Record<string, any> = {
|
||||||
|
version: "1.0.0",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries<QueueItem030>(data)) {
|
||||||
|
if (key.startsWith("qi")) {
|
||||||
|
const item: QueueItem100 = {
|
||||||
|
dateAdded: new Date(value.added),
|
||||||
|
id: value.id,
|
||||||
|
text: value.text === "" ? undefined : value.text,
|
||||||
|
url: value.url,
|
||||||
|
};
|
||||||
|
const prefix: ItemKeyPrefix = "item-";
|
||||||
|
migrated[`${prefix}${item.id}`] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return migrated;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Run the migrations and apply the result to storage. */
|
||||||
|
export async function runMigrations(): Promise<void> {
|
||||||
|
const manifest = browser.runtime.getManifest();
|
||||||
|
|
||||||
|
const version = await createValue<string>({
|
||||||
|
deserialize: (input) => input,
|
||||||
|
serialize: (input) => input,
|
||||||
|
key: "version",
|
||||||
|
storage: browser.storage.sync,
|
||||||
|
value: manifest.version,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (manifest.version >= version.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const migrated = await migrate(
|
||||||
|
await browser.storage.sync.get(),
|
||||||
|
version.value,
|
||||||
|
dataMigrations,
|
||||||
|
);
|
||||||
|
|
||||||
|
await browser.storage.sync.clear();
|
||||||
|
await browser.storage.sync.set(migrated as Record<string, any>);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"version": "0.1.7",
|
||||||
|
"qi1": {
|
||||||
|
"added": "2022-03-02T16:00:00.000Z",
|
||||||
|
"id": 1,
|
||||||
|
"text": "Sample",
|
||||||
|
"url": "https://example.org"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.3.0",
|
||||||
|
"qi1": {
|
||||||
|
"sortIndex": 1,
|
||||||
|
"added": "2022-03-02T16:00:00.000Z",
|
||||||
|
"id": 1,
|
||||||
|
"text": "Sample",
|
||||||
|
"url": "https://example.org"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"item-1": {
|
||||||
|
"dateAdded": "2022-03-02T16:00:00.000Z",
|
||||||
|
"id": 1,
|
||||||
|
"text": "Sample",
|
||||||
|
"url": "https://example.org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue