Add the 1.1.2 to 2.0.0 data migration and testing for it.
This commit is contained in:
parent
5fb151807e
commit
2e58f23239
|
@ -15,6 +15,7 @@
|
|||
"@bauke/eslint-config": "^0.1.2",
|
||||
"@bauke/prettier-config": "^0.1.2",
|
||||
"@bauke/stylelint-config": "^0.1.2",
|
||||
"@holllo/test": "^0.2.1",
|
||||
"@types/debounce": "^1.2.1",
|
||||
"@types/node": "^20.3.1",
|
||||
"@types/platform": "^1.3.4",
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@holllo/migration-helper':
|
||||
specifier: ^0.1.4
|
||||
|
@ -36,6 +40,9 @@ devDependencies:
|
|||
'@bauke/stylelint-config':
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2(stylelint-config-standard-scss@6.1.0)(stylelint@15.9.0)
|
||||
'@holllo/test':
|
||||
specifier: ^0.2.1
|
||||
version: 0.2.1
|
||||
'@types/debounce':
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
|
@ -713,6 +720,10 @@ packages:
|
|||
resolution: {integrity: sha512-4XMYlIOSFzTDWSFizKRSYUHWEfQBNZbPI/Tc5Qhef4lhxZBCAzJt1+RutB5TpCdR6sllJN+Dt5WblCmZXCaoLw==}
|
||||
dev: false
|
||||
|
||||
/@holllo/test@0.2.1:
|
||||
resolution: {integrity: sha512-QlIvEqvuEfu8vapnwai8A+1TmZGkPObgU32VEXHBc3XEKhupHZRFB778oLPYlJVuSsi4TT99890iSR3nlvVwtQ==}
|
||||
dev: true
|
||||
|
||||
/@holllo/webextension-storage@0.2.0(webextension-polyfill@0.10.0):
|
||||
resolution: {integrity: sha512-WiSkkY/Jg3PhlHOH8eGvRBBtvZwHrJ0FD/LF8lNZAc3uaRdonF79o/Xt9CefYUjV6FSbHl/vsccXyAoitvkRIQ==}
|
||||
peerDependencies:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import browser from "webextension-polyfill";
|
||||
import {migrations} from "../storage/migrations/migrations.js";
|
||||
import {log} from "../utilities/logging.js";
|
||||
|
||||
if ($browser === "firefox") {
|
||||
browser.browserAction.onClicked.addListener(openOptionsPage);
|
||||
|
@ -7,6 +9,14 @@ if ($browser === "firefox") {
|
|||
}
|
||||
|
||||
browser.runtime.onInstalled.addListener(async () => {
|
||||
const existingStorage = await browser.storage.sync.get();
|
||||
if (existingStorage.version === "1.1.2") {
|
||||
log("Running 1.1.2 to 2.0.0 data migration.", true);
|
||||
await browser.storage.local.set({backup: JSON.stringify(existingStorage)});
|
||||
await browser.storage.sync.clear();
|
||||
await migrations[0].migrate(existingStorage);
|
||||
}
|
||||
|
||||
if ($dev) {
|
||||
await openOptionsPage();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,11 @@ import {type Feature, Data, fromStorage} from "../storage/common.js";
|
|||
import {AppContext} from "./context.js";
|
||||
import {features} from "./features.js";
|
||||
|
||||
window.addEventListener("load", async () => {
|
||||
window.addEventListener("DOMContentLoaded", async () => {
|
||||
if ($test) {
|
||||
await import("../storage/migrations/migrations.test.js");
|
||||
}
|
||||
|
||||
initializeGlobals();
|
||||
const manifest = browser.runtime.getManifest();
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {type Value, createValue} from "@holllo/webextension-storage";
|
||||
import {createValue} from "@holllo/webextension-storage";
|
||||
import browser from "webextension-polyfill";
|
||||
|
||||
export enum Feature {
|
||||
AnonymizeUsernames = "anonymize-users",
|
||||
AnonymizeUsernames = "anonymize-usernames",
|
||||
Autocomplete = "autocomplete",
|
||||
BackToTop = "back-to-top",
|
||||
Debug = "debug",
|
||||
|
@ -18,6 +18,7 @@ export enum Data {
|
|||
EnabledFeatures = "enabled-features",
|
||||
KnownGroups = "known-groups",
|
||||
LatestActiveFeatureTab = "latest-active-feature-tab",
|
||||
Version = "data-version",
|
||||
}
|
||||
|
||||
export type HideVotesData = {
|
||||
|
@ -111,6 +112,13 @@ export const storageValues = {
|
|||
value: Feature.Debug,
|
||||
storage: browser.storage.sync,
|
||||
}),
|
||||
[Data.Version]: createValue({
|
||||
deserialize: (input) => JSON.parse(input) as string,
|
||||
serialize: (input) => JSON.stringify(input),
|
||||
key: Data.Version,
|
||||
value: "2.0.0",
|
||||
storage: browser.storage.sync,
|
||||
}),
|
||||
[Feature.HideVotes]: createValue({
|
||||
deserialize: (input) => JSON.parse(input) as HideVotesData,
|
||||
serialize: (input) => JSON.stringify(input),
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
import browser from "webextension-polyfill";
|
||||
import {setup} from "@holllo/test";
|
||||
import {Data, Feature} from "../common.js";
|
||||
import {migrations} from "./migrations.js";
|
||||
import {v112Sample} from "./v1-1-2.js";
|
||||
|
||||
await setup("Migrations", async (group) => {
|
||||
group.test("2.0.0", async (test) => {
|
||||
await browser.storage.sync.clear();
|
||||
|
||||
await migrations[0].migrate(v112Sample);
|
||||
const storage = await browser.storage.sync.get();
|
||||
for (const [key, value] of Object.entries(storage)) {
|
||||
switch (key) {
|
||||
case Data.EnabledFeatures: {
|
||||
test.equals(
|
||||
value,
|
||||
'["autocomplete","back-to-top","debug","hide-votes","jump-to-new-comment","markdown-toolbar","themed-logo","user-labels"]',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case Data.KnownGroups: {
|
||||
test.equals(value, '["~group","~group.subgroup","~test"]');
|
||||
break;
|
||||
}
|
||||
|
||||
case Data.Version: {
|
||||
test.equals(value, '"2.0.0"');
|
||||
break;
|
||||
}
|
||||
|
||||
case Feature.HideVotes: {
|
||||
test.equals(
|
||||
value,
|
||||
'{"otherComments":true,"otherTopics":true,"ownComments":true,"ownTopics":false}',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case Feature.UsernameColors: {
|
||||
test.equals(
|
||||
value,
|
||||
'[{"color":"red","id":4,"username":"Test"},{"color":"green","id":18,"username":"AnotherTest"}]',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case `${Feature.UserLabels}-1`: {
|
||||
test.equals(
|
||||
value,
|
||||
'{"color":"#ff00ff","id":1,"priority":0,"text":"Test Label","username":"Test"}',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case `${Feature.UserLabels}-15`: {
|
||||
test.equals(
|
||||
value,
|
||||
'{"id":15,"color":"var(--syntax-string-color)","priority":0,"text":"Another Label","username":"AnotherTest"}',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
console.log(key, JSON.stringify(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,52 @@
|
|||
import {setup} from "@holllo/test";
|
||||
import {type Migration} from "@holllo/migration-helper";
|
||||
import browser from "webextension-polyfill";
|
||||
import {Data, Feature, fromStorage, saveUserLabels} from "../common.js";
|
||||
import {v112DeserializeData, v112Sample, type V112Settings} from "./v1-1-2.js";
|
||||
|
||||
export const migrations: Array<Migration<string>> = [
|
||||
{
|
||||
version: "2.0.0",
|
||||
async migrate(data: V112Settings): Promise<void> {
|
||||
const deserialized = v112DeserializeData(data);
|
||||
data.data.userLabels = deserialized.userLabels;
|
||||
data.data.usernameColors = deserialized.usernameColors;
|
||||
await saveUserLabels(data.data.userLabels);
|
||||
|
||||
const hideVotes = await fromStorage(Feature.HideVotes);
|
||||
hideVotes.value = {
|
||||
otherComments: data.data.hideVotes.comments,
|
||||
otherTopics: data.data.hideVotes.topics,
|
||||
ownComments: data.data.hideVotes.ownComments,
|
||||
ownTopics: data.data.hideVotes.ownTopics,
|
||||
};
|
||||
await hideVotes.save();
|
||||
|
||||
const knownGroups = await fromStorage(Data.KnownGroups);
|
||||
knownGroups.value = new Set(data.data.knownGroups);
|
||||
await knownGroups.save();
|
||||
|
||||
const version = await fromStorage(Data.Version);
|
||||
version.value = "2.0.0";
|
||||
await version.save();
|
||||
|
||||
const usernameColors = await fromStorage(Feature.UsernameColors);
|
||||
usernameColors.value = data.data.usernameColors;
|
||||
await usernameColors.save();
|
||||
|
||||
const enabledFeatures = await fromStorage(Data.EnabledFeatures);
|
||||
for (const [key, value] of Object.entries(data.features)) {
|
||||
if (value) {
|
||||
const snakeCasedKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
||||
if (Object.values(Feature).includes(snakeCasedKey as Feature)) {
|
||||
enabledFeatures.value.add(snakeCasedKey as Feature);
|
||||
} else {
|
||||
throw new Error(`Unknown key: ${key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await enabledFeatures.save();
|
||||
},
|
||||
},
|
||||
];
|
|
@ -0,0 +1,114 @@
|
|||
export function v112DeserializeData(data: Record<string, any>): {
|
||||
userLabels: V112Settings["data"]["userLabels"];
|
||||
usernameColors: V112Settings["data"]["usernameColors"];
|
||||
} {
|
||||
const deserialized: ReturnType<typeof v112DeserializeData> = {
|
||||
userLabels: [],
|
||||
usernameColors: [],
|
||||
};
|
||||
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
if (key.startsWith("userLabel")) {
|
||||
deserialized.userLabels.push(
|
||||
value as (typeof deserialized)["userLabels"][number],
|
||||
);
|
||||
} else if (key.startsWith("usernameColor")) {
|
||||
deserialized.usernameColors.push(
|
||||
value as (typeof deserialized)["usernameColors"][number],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return deserialized;
|
||||
}
|
||||
|
||||
export type V112Settings = {
|
||||
[index: string]: any;
|
||||
data: {
|
||||
hideVotes: {
|
||||
comments: boolean;
|
||||
topics: boolean;
|
||||
ownComments: boolean;
|
||||
ownTopics: boolean;
|
||||
};
|
||||
knownGroups: string[];
|
||||
latestActiveFeatureTab: string;
|
||||
userLabels: Array<{
|
||||
color: string;
|
||||
id: number;
|
||||
priority: number;
|
||||
text: string;
|
||||
username: string;
|
||||
}>;
|
||||
usernameColors: Array<{
|
||||
color: string;
|
||||
id: number;
|
||||
username: string;
|
||||
}>;
|
||||
};
|
||||
features: {
|
||||
anonymizeUsernames: boolean;
|
||||
autocomplete: boolean;
|
||||
backToTop: boolean;
|
||||
debug: boolean;
|
||||
hideVotes: boolean;
|
||||
jumpToNewComment: boolean;
|
||||
markdownToolbar: boolean;
|
||||
themedLogo: boolean;
|
||||
userLabels: boolean;
|
||||
usernameColors: boolean;
|
||||
};
|
||||
version: string;
|
||||
};
|
||||
|
||||
export const v112Sample: V112Settings = {
|
||||
data: {
|
||||
hideVotes: {
|
||||
comments: true,
|
||||
ownComments: true,
|
||||
ownTopics: false,
|
||||
topics: true,
|
||||
},
|
||||
knownGroups: ["~group", "~group.subgroup", "~test"],
|
||||
latestActiveFeatureTab: "userLabels",
|
||||
userLabels: [],
|
||||
usernameColors: [],
|
||||
},
|
||||
features: {
|
||||
anonymizeUsernames: false,
|
||||
autocomplete: true,
|
||||
backToTop: true,
|
||||
debug: true,
|
||||
hideVotes: true,
|
||||
jumpToNewComment: true,
|
||||
markdownToolbar: true,
|
||||
themedLogo: true,
|
||||
userLabels: true,
|
||||
usernameColors: false,
|
||||
},
|
||||
version: "1.1.2",
|
||||
userLabel1: {
|
||||
color: "#ff00ff",
|
||||
id: 1,
|
||||
priority: 0,
|
||||
text: "Test Label",
|
||||
username: "Test",
|
||||
},
|
||||
userLabel15: {
|
||||
id: 15,
|
||||
color: "var(--syntax-string-color)",
|
||||
priority: 0,
|
||||
text: "Another Label",
|
||||
username: "AnotherTest",
|
||||
},
|
||||
usernameColor4: {
|
||||
color: "red",
|
||||
id: 4,
|
||||
username: "Test",
|
||||
},
|
||||
usernameColor18: {
|
||||
color: "green",
|
||||
id: 18,
|
||||
username: "AnotherTest",
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue