Compare commits

...

4 Commits

7 changed files with 178 additions and 620 deletions

View File

@ -17,8 +17,6 @@
"@bauke/stylelint-config": "^0.1.2",
"@types/node": "^18.15.11",
"@types/webextension-polyfill": "^0.10.0",
"ava": "^5.2.0",
"c8": "^7.13.0",
"concurrently": "^8.0.1",
"cssnano": "^6.0.0",
"esbuild": "^0.17.15",
@ -29,48 +27,16 @@
"stylelint": "^15.3.0",
"stylelint-config-standard-scss": "^7.0.1",
"trash-cli": "^5.0.0",
"ts-node": "^10.9.1",
"tsx": "^3.12.6",
"typescript": "^5.0.2",
"web-ext": "^7.6.0",
"xo": "^0.53.1"
},
"ava": {
"extensions": {
"ts": "module"
},
"files": [
"tests/**/*.test.ts"
],
"nodeArguments": [
"--loader=ts-node/esm"
],
"snapshotDir": "tests/snapshots"
},
"c8": {
"include": [
"source",
"tests"
],
"reportDir": "coverage",
"reporter": [
"text",
"html"
]
},
"prettier": "@bauke/prettier-config",
"stylelint": {
"extends": "@bauke/stylelint-config"
},
"xo": {
"overrides": [
{
"files": "tests/**/*.test.ts",
"rules": {
"@typescript-eslint/triple-slash-reference": "off"
}
}
],
"extends": "@bauke/eslint-config",
"prettier": true,
"rules": {

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@
import browser from "webextension-polyfill";
import {runMigrations} from "../migrations/migrations.js";
import {
clearHistory,
openNextItemOrOptionsPage,
@ -30,6 +32,7 @@ browser.runtime.onStartup.addListener(async () => {
});
browser.runtime.onInstalled.addListener(async () => {
await runMigrations();
await initializeContextMenus();
await setBadgeText();

View File

@ -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),
);
}
});
});

View File

@ -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>);
}

View File

@ -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"
}
}
]

View File

@ -14,9 +14,6 @@
"target": "ES2022"
},
"include": [
"*.ts",
"source",
"tests",
"vite.config.ts"
"source"
]
}