Add an ID to Redirects.

This commit is contained in:
Bauke 2022-10-19 21:10:41 +02:00
parent e55c791386
commit d25a844fac
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
8 changed files with 39 additions and 7 deletions

View File

@ -20,6 +20,7 @@
"@holllo/preact-components": "^0.2.3", "@holllo/preact-components": "^0.2.3",
"htm": "^3.1.1", "htm": "^3.1.1",
"modern-normalize": "^1.1.0", "modern-normalize": "^1.1.0",
"nanoid": "^4.0.0",
"preact": "^10.11.0", "preact": "^10.11.0",
"webextension-polyfill": "^0.10.0" "webextension-polyfill": "^0.10.0"
}, },

View File

@ -10,6 +10,7 @@ specifiers:
c8: ^7.12.0 c8: ^7.12.0
htm: ^3.1.1 htm: ^3.1.1
modern-normalize: ^1.1.0 modern-normalize: ^1.1.0
nanoid: ^4.0.0
postcss: ^8.4.16 postcss: ^8.4.16
preact: ^10.11.0 preact: ^10.11.0
sass: ^1.55.0 sass: ^1.55.0
@ -29,6 +30,7 @@ dependencies:
'@holllo/preact-components': 0.2.3_htm@3.1.1+preact@10.11.0 '@holllo/preact-components': 0.2.3_htm@3.1.1+preact@10.11.0
htm: 3.1.1 htm: 3.1.1
modern-normalize: 1.1.0 modern-normalize: 1.1.0
nanoid: 4.0.0
preact: 10.11.0 preact: 10.11.0
webextension-polyfill: 0.10.0 webextension-polyfill: 0.10.0
@ -5197,6 +5199,12 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/nanoid/4.0.0:
resolution: {integrity: sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==}
engines: {node: ^14 || ^16 || >=18}
hasBin: true
dev: false
/natural-compare/1.4.0: /natural-compare/1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true dev: true
@ -7637,6 +7645,11 @@ packages:
resolution: {integrity: sha512-liCEteZ5z+QRyh3XzsYWQyxedBHBvx8CDlNvvi+BJz74L0E5/ID2v7JtoX3bD541AlMuOy4e/iWif6hhNGBFNw==} resolution: {integrity: sha512-liCEteZ5z+QRyh3XzsYWQyxedBHBvx8CDlNvvi+BJz74L0E5/ID2v7JtoX3bD541AlMuOy4e/iWif6hhNGBFNw==}
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
hasBin: true hasBin: true
peerDependencies:
webpack: '>=1.11.0'
peerDependenciesMeta:
webpack:
optional: true
dependencies: dependencies:
'@eslint/eslintrc': 1.3.2 '@eslint/eslintrc': 1.3.2
'@typescript-eslint/eslint-plugin': 5.36.2_q7mrctxvxoqtj4jpjqmbsyg2qy '@typescript-eslint/eslint-plugin': 5.36.2_q7mrctxvxoqtj4jpjqmbsyg2qy
@ -7677,7 +7690,6 @@ packages:
transitivePeerDependencies: transitivePeerDependencies:
- eslint-import-resolver-typescript - eslint-import-resolver-typescript
- supports-color - supports-color
- webpack
dev: true dev: true
bundledDependencies: bundledDependencies:
- '@typescript-eslint/eslint-plugin' - '@typescript-eslint/eslint-plugin'

View File

@ -21,8 +21,10 @@ browser.runtime.onInstalled.addListener(async () => {
browser.webNavigation.onBeforeNavigate.addListener(async (details) => { browser.webNavigation.onBeforeNavigate.addListener(async (details) => {
const url = new URL(details.url); const url = new URL(details.url);
for (const parameters of Object.values(await browser.storage.local.get())) { for (const [id, parameters] of Object.entries(
const redirect = parseRedirect(parameters); await browser.storage.local.get(),
)) {
const redirect = parseRedirect(parameters, id);
if (redirect === undefined) { if (redirect === undefined) {
continue; continue;
} }

View File

@ -1,3 +1,5 @@
import {customAlphabet} from 'nanoid';
export const matcherTypes = ['hostname'] as const; export const matcherTypes = ['hostname'] as const;
export const redirectTypes = ['hostname', 'simple'] as const; export const redirectTypes = ['hostname', 'simple'] as const;
@ -22,7 +24,17 @@ export type RedirectParameters = {
}; };
export abstract class Redirect<P extends RedirectParameters> { export abstract class Redirect<P extends RedirectParameters> {
constructor(public parameters: P & Matcher) {} public static generateId(): string {
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
const nanoid = customAlphabet(`${alphabet}${alphabet.toUpperCase()}`, 20);
return nanoid();
}
public id: string;
constructor(public parameters: P & Matcher, id?: string) {
this.id = id ?? Redirect.generateId();
}
public isMatch(url: URL): boolean { public isMatch(url: URL): boolean {
if (this.parameters.matcherType === 'hostname') { if (this.parameters.matcherType === 'hostname') {

View File

@ -9,14 +9,15 @@ export type Redirects = HostnameRedirect | SimpleRedirect;
export function parseRedirect<P extends Redirects['parameters']>( export function parseRedirect<P extends Redirects['parameters']>(
parameters: P, parameters: P,
id: string,
): Redirects | undefined { ): Redirects | undefined {
const redirectType = parameters?.redirectType; const redirectType = parameters?.redirectType;
if (redirectType === 'hostname') { if (redirectType === 'hostname') {
return new HostnameRedirect(parameters); return new HostnameRedirect(parameters, id);
} }
if (redirectType === 'simple') { if (redirectType === 'simple') {
return new SimpleRedirect(parameters); return new SimpleRedirect(parameters, id);
} }
} }

View File

@ -40,11 +40,13 @@ test('parseRedirect', (t) => {
]; ];
for (const sample of samples) { for (const sample of samples) {
const redirect = parseRedirect(sample); const redirect = parseRedirect(sample, Redirect.generateId());
if (redirect === undefined) { if (redirect === undefined) {
t.pass('parseRedirect returned undefined'); t.pass('parseRedirect returned undefined');
} else { } else {
t.regex(redirect.id, /^[a-z]{20}$/i);
redirect.id = 'id';
t.snapshot(redirect, `Class ${redirect.constructor.name}`); t.snapshot(redirect, `Class ${redirect.constructor.name}`);
} }
} }

View File

@ -9,6 +9,7 @@ Generated by [AVA](https://avajs.dev).
> Class HostnameRedirect > Class HostnameRedirect
HostnameRedirect { HostnameRedirect {
id: 'id',
parameters: { parameters: {
hostname: 'example.org', hostname: 'example.org',
matcherType: 'hostname', matcherType: 'hostname',
@ -20,6 +21,7 @@ Generated by [AVA](https://avajs.dev).
> Class SimpleRedirect > Class SimpleRedirect
SimpleRedirect { SimpleRedirect {
id: 'id',
parameters: { parameters: {
matcherType: 'hostname', matcherType: 'hostname',
redirectType: 'simple', redirectType: 'simple',