wxt 0.19.12 → 0.19.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.d.ts +1 -1
- package/dist/client/content-scripts/content-script-context.d.ts +7 -1
- package/dist/client/content-scripts/content-script-context.mjs +13 -13
- package/dist/client/content-scripts/ui/index.d.ts +1 -1
- package/dist/core/resolve-config.mjs +4 -1
- package/dist/core/runners/web-ext.mjs +4 -1
- package/dist/core/utils/building/find-entrypoints.mjs +2 -2
- package/dist/core/utils/content-scripts.mjs +0 -3
- package/dist/core/utils/env.d.ts +3 -2
- package/dist/core/utils/env.mjs +12 -2
- package/dist/storage.d.ts +40 -3
- package/dist/storage.mjs +129 -36
- package/dist/version.mjs +1 -1
- package/package.json +16 -16
package/dist/browser/index.d.ts
CHANGED
|
@@ -23,4 +23,4 @@ export interface WxtI18n {
|
|
|
23
23
|
export declare const browser: AugmentedBrowser;
|
|
24
24
|
/** @ignore */
|
|
25
25
|
export type { ActivityLog, Alarms, Bookmarks, Action, BrowserAction, BrowserSettings, BrowsingData, CaptivePortal, Clipboard, Commands, ContentScripts, ContextualIdentities, Cookies, DeclarativeNetRequest, Devtools, Dns, Downloads, Events, Experiments, Extension, ExtensionTypes, Find, GeckoProfiler, History, I18n, Identity, Idle, Management, Manifest, // TODO: Export custom manifest types that are valid for both Chrome and Firefox.
|
|
26
|
-
ContextMenus, Menus, NetworkStatus, NormandyAddonStudy, Notifications, Omnibox, PageAction, Permissions, Pkcs11, Privacy, Proxy, Runtime, Scripting, Search, Sessions, SidebarAction, Storage, Tabs, Theme, TopSites, Types,
|
|
26
|
+
ContextMenus, Menus, NetworkStatus, NormandyAddonStudy, Notifications, Omnibox, PageAction, Permissions, Pkcs11, Privacy, Proxy, Runtime, Scripting, Search, Sessions, SidebarAction, Storage, Tabs, Theme, TopSites, Types, UserScripts, WebNavigation, WebRequest, Windows, } from 'webextension-polyfill';
|
|
@@ -31,10 +31,12 @@ import { WxtLocationChangeEvent } from './custom-events';
|
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
33
|
export declare class ContentScriptContext implements AbortController {
|
|
34
|
-
#private;
|
|
35
34
|
private readonly contentScriptName;
|
|
36
35
|
readonly options?: Omit<ContentScriptDefinition, "main"> | undefined;
|
|
37
36
|
private static SCRIPT_STARTED_MESSAGE_TYPE;
|
|
37
|
+
private isTopFrame;
|
|
38
|
+
private abortController;
|
|
39
|
+
private locationWatcher;
|
|
38
40
|
constructor(contentScriptName: string, options?: Omit<ContentScriptDefinition, "main"> | undefined);
|
|
39
41
|
get signal(): AbortSignal;
|
|
40
42
|
abort(reason?: any): void;
|
|
@@ -107,6 +109,10 @@ export declare class ContentScriptContext implements AbortController {
|
|
|
107
109
|
* Abort the abort controller and execute all `onInvalidated` listeners.
|
|
108
110
|
*/
|
|
109
111
|
notifyInvalidated(): void;
|
|
112
|
+
stopOldScripts(): void;
|
|
113
|
+
listenForNewerScripts(options?: {
|
|
114
|
+
ignoreFirstEvent?: boolean;
|
|
115
|
+
}): void;
|
|
110
116
|
}
|
|
111
117
|
interface WxtContentScriptEventMap extends WindowEventMap {
|
|
112
118
|
'wxt:locationchange': WxtLocationChangeEvent;
|
|
@@ -6,23 +6,23 @@ export class ContentScriptContext {
|
|
|
6
6
|
constructor(contentScriptName, options) {
|
|
7
7
|
this.contentScriptName = contentScriptName;
|
|
8
8
|
this.options = options;
|
|
9
|
-
this
|
|
10
|
-
if (this
|
|
11
|
-
this
|
|
12
|
-
this
|
|
9
|
+
this.abortController = new AbortController();
|
|
10
|
+
if (this.isTopFrame) {
|
|
11
|
+
this.listenForNewerScripts({ ignoreFirstEvent: true });
|
|
12
|
+
this.stopOldScripts();
|
|
13
13
|
} else {
|
|
14
|
-
this
|
|
14
|
+
this.listenForNewerScripts();
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
static SCRIPT_STARTED_MESSAGE_TYPE = "wxt:content-script-started";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
isTopFrame = window.self === window.top;
|
|
19
|
+
abortController;
|
|
20
|
+
locationWatcher = createLocationWatcher(this);
|
|
21
21
|
get signal() {
|
|
22
|
-
return this
|
|
22
|
+
return this.abortController.signal;
|
|
23
23
|
}
|
|
24
24
|
abort(reason) {
|
|
25
|
-
return this
|
|
25
|
+
return this.abortController.abort(reason);
|
|
26
26
|
}
|
|
27
27
|
get isInvalid() {
|
|
28
28
|
if (browser.runtime.id == null) {
|
|
@@ -126,7 +126,7 @@ export class ContentScriptContext {
|
|
|
126
126
|
*/
|
|
127
127
|
addEventListener(target, type, handler, options) {
|
|
128
128
|
if (type === "wxt:locationchange") {
|
|
129
|
-
if (this.isValid) this
|
|
129
|
+
if (this.isValid) this.locationWatcher.run();
|
|
130
130
|
}
|
|
131
131
|
target.addEventListener?.(
|
|
132
132
|
type.startsWith("wxt:") ? getUniqueEventName(type) : type,
|
|
@@ -148,7 +148,7 @@ export class ContentScriptContext {
|
|
|
148
148
|
`Content script "${this.contentScriptName}" context invalidated`
|
|
149
149
|
);
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
stopOldScripts() {
|
|
152
152
|
window.postMessage(
|
|
153
153
|
{
|
|
154
154
|
type: ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE,
|
|
@@ -157,7 +157,7 @@ export class ContentScriptContext {
|
|
|
157
157
|
"*"
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
listenForNewerScripts(options) {
|
|
161
161
|
let isFirst = true;
|
|
162
162
|
const cb = (event) => {
|
|
163
163
|
if (event.data?.type === ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE && event.data?.contentScriptName === this.contentScriptName) {
|
|
@@ -18,6 +18,6 @@ export declare function createIframeUi<TMounted>(ctx: ContentScriptContext, opti
|
|
|
18
18
|
*
|
|
19
19
|
* > This function is async because it has to load the CSS via a network call.
|
|
20
20
|
*
|
|
21
|
-
* @see https://wxt.dev/guide/essentials/content-scripts.html#
|
|
21
|
+
* @see https://wxt.dev/guide/essentials/content-scripts.html#shadow-root
|
|
22
22
|
*/
|
|
23
23
|
export declare function createShadowRootUi<TMounted>(ctx: ContentScriptContext, options: ShadowRootContentScriptUiOptions<TMounted>): Promise<ShadowRootContentScriptUi<TMounted>>;
|
|
@@ -23,6 +23,9 @@ export async function resolveConfig(inlineConfig, command) {
|
|
|
23
23
|
esmResolve: true
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
|
+
if (inlineConfig.configFile && metadata.layers?.length === 0) {
|
|
27
|
+
throw Error(`Config file "${inlineConfig.configFile}" not found`);
|
|
28
|
+
}
|
|
26
29
|
userConfig = loadedConfig ?? {};
|
|
27
30
|
userConfigMetadata = metadata;
|
|
28
31
|
}
|
|
@@ -34,7 +37,7 @@ export async function resolveConfig(inlineConfig, command) {
|
|
|
34
37
|
const manifestVersion = mergedConfig.manifestVersion ?? (browser === "firefox" || browser === "safari" ? 2 : 3);
|
|
35
38
|
const mode = mergedConfig.mode ?? COMMAND_MODES[command];
|
|
36
39
|
const env = { browser, command, manifestVersion, mode };
|
|
37
|
-
loadEnv(mode);
|
|
40
|
+
loadEnv(mode, browser);
|
|
38
41
|
const root = path.resolve(
|
|
39
42
|
inlineConfig.root ?? userConfig.root ?? process.cwd()
|
|
40
43
|
);
|
|
@@ -34,7 +34,10 @@ export function createWebExtRunner() {
|
|
|
34
34
|
wxtUserConfig?.chromiumPref,
|
|
35
35
|
DEFAULT_CHROMIUM_PREFS
|
|
36
36
|
),
|
|
37
|
-
args:
|
|
37
|
+
args: [
|
|
38
|
+
"--unsafely-disable-devtools-self-xss-warnings",
|
|
39
|
+
...wxtUserConfig?.chromiumArgs ?? []
|
|
40
|
+
]
|
|
38
41
|
}
|
|
39
42
|
};
|
|
40
43
|
const finalConfig = {
|
|
@@ -176,7 +176,7 @@ async function getPopupEntrypoint(info) {
|
|
|
176
176
|
const options = await getHtmlEntrypointOptions(
|
|
177
177
|
info,
|
|
178
178
|
{
|
|
179
|
-
browserStyle: "
|
|
179
|
+
browserStyle: "browser_style",
|
|
180
180
|
exclude: "exclude",
|
|
181
181
|
include: "include",
|
|
182
182
|
defaultIcon: "default_icon",
|
|
@@ -204,7 +204,7 @@ async function getOptionsEntrypoint(info) {
|
|
|
204
204
|
const options = await getHtmlEntrypointOptions(
|
|
205
205
|
info,
|
|
206
206
|
{
|
|
207
|
-
browserStyle: "
|
|
207
|
+
browserStyle: "browser_style",
|
|
208
208
|
chromeStyle: "chrome_style",
|
|
209
209
|
exclude: "exclude",
|
|
210
210
|
include: "include",
|
|
@@ -15,7 +15,6 @@ export function hashContentScriptOptions(options) {
|
|
|
15
15
|
match_about_blank: false,
|
|
16
16
|
run_at: "document_idle",
|
|
17
17
|
all_frames: false,
|
|
18
|
-
// @ts-expect-error - not in type
|
|
19
18
|
match_origin_as_fallback: false,
|
|
20
19
|
world: "ISOLATED",
|
|
21
20
|
...simplifiedOptions
|
|
@@ -38,7 +37,6 @@ export function mapWxtOptionsToContentScript(options, js, css) {
|
|
|
38
37
|
run_at: options.runAt,
|
|
39
38
|
css,
|
|
40
39
|
js,
|
|
41
|
-
// @ts-expect-error: untyped chrome options
|
|
42
40
|
match_origin_as_fallback: options.matchOriginAsFallback,
|
|
43
41
|
world: options.world
|
|
44
42
|
};
|
|
@@ -51,7 +49,6 @@ export function mapWxtOptionsToRegisteredContentScript(options, js, css) {
|
|
|
51
49
|
runAt: options.runAt,
|
|
52
50
|
js,
|
|
53
51
|
css,
|
|
54
|
-
// @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript)
|
|
55
52
|
world: options.world
|
|
56
53
|
};
|
|
57
54
|
}
|
package/dist/core/utils/env.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import type { TargetBrowser } from '../../types';
|
|
1
2
|
/**
|
|
2
|
-
* Load environment files based on the current mode.
|
|
3
|
+
* Load environment files based on the current mode and browser.
|
|
3
4
|
*/
|
|
4
|
-
export declare function loadEnv(mode: string): import("dotenv").DotenvConfigOutput;
|
|
5
|
+
export declare function loadEnv(mode: string, browser: TargetBrowser): import("dotenv").DotenvConfigOutput;
|
package/dist/core/utils/env.mjs
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { config } from "dotenv";
|
|
2
|
-
export function loadEnv(mode) {
|
|
2
|
+
export function loadEnv(mode, browser) {
|
|
3
3
|
return config({
|
|
4
|
-
|
|
4
|
+
// Files on top override files below
|
|
5
|
+
path: [
|
|
6
|
+
`.env.${mode}.${browser}.local`,
|
|
7
|
+
`.env.${mode}.${browser}`,
|
|
8
|
+
`.env.${browser}.local`,
|
|
9
|
+
`.env.${browser}`,
|
|
10
|
+
`.env.${mode}.local`,
|
|
11
|
+
`.env.${mode}`,
|
|
12
|
+
`.env.local`,
|
|
13
|
+
`.env`
|
|
14
|
+
]
|
|
5
15
|
});
|
|
6
16
|
}
|
package/dist/storage.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface WxtStorage {
|
|
|
17
17
|
* @example
|
|
18
18
|
* await storage.getItems(["local:installDate", "session:someCounter"]);
|
|
19
19
|
*/
|
|
20
|
-
getItems(keys: Array<StorageItemKey | {
|
|
20
|
+
getItems(keys: Array<StorageItemKey | WxtStorageItem<any, any> | {
|
|
21
21
|
key: StorageItemKey;
|
|
22
22
|
options?: GetItemOptions<any>;
|
|
23
23
|
}>): Promise<Array<{
|
|
@@ -32,6 +32,16 @@ export interface WxtStorage {
|
|
|
32
32
|
* await storage.getMeta("local:installDate");
|
|
33
33
|
*/
|
|
34
34
|
getMeta<T extends Record<string, unknown>>(key: StorageItemKey): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Get the metadata of multiple storage items.
|
|
37
|
+
*
|
|
38
|
+
* @param items List of keys or items to get the metadata of.
|
|
39
|
+
* @returns An array containing storage keys and their metadata.
|
|
40
|
+
*/
|
|
41
|
+
getMetas(keys: Array<StorageItemKey | WxtStorageItem<any, any>>): Promise<Array<{
|
|
42
|
+
key: StorageItemKey;
|
|
43
|
+
meta: any;
|
|
44
|
+
}>>;
|
|
35
45
|
/**
|
|
36
46
|
* Set a value in storage. Setting a value to `null` or `undefined` is equivalent to calling
|
|
37
47
|
* `removeItem`.
|
|
@@ -52,6 +62,9 @@ export interface WxtStorage {
|
|
|
52
62
|
setItems(values: Array<{
|
|
53
63
|
key: StorageItemKey;
|
|
54
64
|
value: any;
|
|
65
|
+
} | {
|
|
66
|
+
item: WxtStorageItem<any, any>;
|
|
67
|
+
value: any;
|
|
55
68
|
}>): Promise<void>;
|
|
56
69
|
/**
|
|
57
70
|
* Sets metadata properties. If some properties are already set, but are not included in the
|
|
@@ -61,6 +74,18 @@ export interface WxtStorage {
|
|
|
61
74
|
* await storage.setMeta("local:installDate", { appVersion });
|
|
62
75
|
*/
|
|
63
76
|
setMeta<T extends Record<string, unknown>>(key: StorageItemKey, properties: T | null): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Set the metadata of multiple storage items.
|
|
79
|
+
*
|
|
80
|
+
* @param items List of storage keys or items and metadata to set for each.
|
|
81
|
+
*/
|
|
82
|
+
setMetas(metas: Array<{
|
|
83
|
+
key: StorageItemKey;
|
|
84
|
+
meta: Record<string, any>;
|
|
85
|
+
} | {
|
|
86
|
+
item: WxtStorageItem<any, any>;
|
|
87
|
+
meta: Record<string, any>;
|
|
88
|
+
}>): Promise<void>;
|
|
64
89
|
/**
|
|
65
90
|
* Removes an item from storage.
|
|
66
91
|
*
|
|
@@ -71,9 +96,12 @@ export interface WxtStorage {
|
|
|
71
96
|
/**
|
|
72
97
|
* Remove a list of keys from storage.
|
|
73
98
|
*/
|
|
74
|
-
removeItems(keys: Array<StorageItemKey | {
|
|
99
|
+
removeItems(keys: Array<StorageItemKey | WxtStorageItem<any, any> | {
|
|
75
100
|
key: StorageItemKey;
|
|
76
101
|
options?: RemoveItemOptions;
|
|
102
|
+
} | {
|
|
103
|
+
item: WxtStorageItem<any, any>;
|
|
104
|
+
options?: RemoveItemOptions;
|
|
77
105
|
}>): Promise<void>;
|
|
78
106
|
/**
|
|
79
107
|
* Remove the entire metadata for a key, or specific properties by name.
|
|
@@ -113,7 +141,11 @@ export interface WxtStorage {
|
|
|
113
141
|
}
|
|
114
142
|
export interface WxtStorageItem<TValue, TMetadata extends Record<string, unknown>> {
|
|
115
143
|
/**
|
|
116
|
-
*
|
|
144
|
+
* The storage key passed when creating the storage item.
|
|
145
|
+
*/
|
|
146
|
+
key: StorageItemKey;
|
|
147
|
+
/**
|
|
148
|
+
* @deprecated Renamed to fallback, use it instead.
|
|
117
149
|
*/
|
|
118
150
|
defaultValue: TValue;
|
|
119
151
|
/**
|
|
@@ -224,3 +256,8 @@ export type WatchCallback<T> = (newValue: T, oldValue: T) => void;
|
|
|
224
256
|
* Call to remove a watch listener
|
|
225
257
|
*/
|
|
226
258
|
export type Unwatch = () => void;
|
|
259
|
+
export declare class MigrationError extends Error {
|
|
260
|
+
key: string;
|
|
261
|
+
version: number;
|
|
262
|
+
constructor(key: string, version: number, options?: ErrorOptions);
|
|
263
|
+
}
|
package/dist/storage.mjs
CHANGED
|
@@ -34,6 +34,14 @@ function createStorage() {
|
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
36
|
const getMetaKey = (key) => key + "$";
|
|
37
|
+
const mergeMeta = (oldMeta, newMeta) => {
|
|
38
|
+
const newFields = { ...oldMeta };
|
|
39
|
+
Object.entries(newMeta).forEach(([key, value]) => {
|
|
40
|
+
if (value == null) delete newFields[key];
|
|
41
|
+
else newFields[key] = value;
|
|
42
|
+
});
|
|
43
|
+
return newFields;
|
|
44
|
+
};
|
|
37
45
|
const getValueOrFallback = (value, fallback) => value ?? fallback ?? null;
|
|
38
46
|
const getMetaValue = (properties) => typeof properties === "object" && !Array.isArray(properties) ? properties : {};
|
|
39
47
|
const getItem = async (driver, driverKey, opts) => {
|
|
@@ -51,15 +59,7 @@ function createStorage() {
|
|
|
51
59
|
const setMeta = async (driver, driverKey, properties) => {
|
|
52
60
|
const metaKey = getMetaKey(driverKey);
|
|
53
61
|
const existingFields = getMetaValue(await driver.getItem(metaKey));
|
|
54
|
-
|
|
55
|
-
Object.entries(properties).forEach(([key, value]) => {
|
|
56
|
-
if (value == null) {
|
|
57
|
-
delete newFields[key];
|
|
58
|
-
} else {
|
|
59
|
-
newFields[key] = value;
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
await driver.setItem(metaKey, newFields);
|
|
62
|
+
await driver.setItem(metaKey, mergeMeta(existingFields, properties));
|
|
63
63
|
};
|
|
64
64
|
const removeItem = async (driver, driverKey, opts) => {
|
|
65
65
|
await driver.removeItem(driverKey);
|
|
@@ -89,92 +89,171 @@ function createStorage() {
|
|
|
89
89
|
getItems: async (keys) => {
|
|
90
90
|
const areaToKeyMap = /* @__PURE__ */ new Map();
|
|
91
91
|
const keyToOptsMap = /* @__PURE__ */ new Map();
|
|
92
|
+
const orderedKeys = [];
|
|
92
93
|
keys.forEach((key) => {
|
|
93
94
|
let keyStr;
|
|
94
95
|
let opts;
|
|
95
96
|
if (typeof key === "string") {
|
|
96
97
|
keyStr = key;
|
|
98
|
+
} else if ("getValue" in key) {
|
|
99
|
+
keyStr = key.key;
|
|
100
|
+
opts = { fallback: key.fallback };
|
|
97
101
|
} else {
|
|
98
102
|
keyStr = key.key;
|
|
99
103
|
opts = key.options;
|
|
100
104
|
}
|
|
105
|
+
orderedKeys.push(keyStr);
|
|
101
106
|
const { driverArea, driverKey } = resolveKey(keyStr);
|
|
102
|
-
const
|
|
103
|
-
areaToKeyMap.set(driverArea,
|
|
107
|
+
const areaKeys = areaToKeyMap.get(driverArea) ?? [];
|
|
108
|
+
areaToKeyMap.set(driverArea, areaKeys.concat(driverKey));
|
|
104
109
|
keyToOptsMap.set(keyStr, opts);
|
|
105
110
|
});
|
|
106
|
-
const
|
|
111
|
+
const resultsMap = /* @__PURE__ */ new Map();
|
|
112
|
+
await Promise.all(
|
|
107
113
|
Array.from(areaToKeyMap.entries()).map(async ([driverArea, keys2]) => {
|
|
108
114
|
const driverResults = await drivers[driverArea].getItems(keys2);
|
|
109
|
-
|
|
115
|
+
driverResults.forEach((driverResult) => {
|
|
110
116
|
const key = `${driverArea}:${driverResult.key}`;
|
|
111
117
|
const opts = keyToOptsMap.get(key);
|
|
112
118
|
const value = getValueOrFallback(
|
|
113
119
|
driverResult.value,
|
|
114
120
|
opts?.fallback ?? opts?.defaultValue
|
|
115
121
|
);
|
|
116
|
-
|
|
122
|
+
resultsMap.set(key, value);
|
|
117
123
|
});
|
|
118
124
|
})
|
|
119
125
|
);
|
|
120
|
-
return
|
|
126
|
+
return orderedKeys.map((key) => ({
|
|
127
|
+
key,
|
|
128
|
+
value: resultsMap.get(key)
|
|
129
|
+
}));
|
|
121
130
|
},
|
|
122
131
|
getMeta: async (key) => {
|
|
123
132
|
const { driver, driverKey } = resolveKey(key);
|
|
124
133
|
return await getMeta(driver, driverKey);
|
|
125
134
|
},
|
|
135
|
+
getMetas: async (args) => {
|
|
136
|
+
const keys = args.map((arg) => {
|
|
137
|
+
const key = typeof arg === "string" ? arg : arg.key;
|
|
138
|
+
const { driverArea, driverKey } = resolveKey(key);
|
|
139
|
+
return {
|
|
140
|
+
key,
|
|
141
|
+
driverArea,
|
|
142
|
+
driverKey,
|
|
143
|
+
driverMetaKey: getMetaKey(driverKey)
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
const areaToDriverMetaKeysMap = keys.reduce((map, key) => {
|
|
147
|
+
map[key.driverArea] ??= [];
|
|
148
|
+
map[key.driverArea].push(key);
|
|
149
|
+
return map;
|
|
150
|
+
}, {});
|
|
151
|
+
const resultsMap = {};
|
|
152
|
+
await Promise.all(
|
|
153
|
+
Object.entries(areaToDriverMetaKeysMap).map(async ([area, keys2]) => {
|
|
154
|
+
const areaRes = await browser.storage[area].get(
|
|
155
|
+
keys2.map((key) => key.driverMetaKey)
|
|
156
|
+
);
|
|
157
|
+
keys2.forEach((key) => {
|
|
158
|
+
resultsMap[key.key] = areaRes[key.driverMetaKey] ?? {};
|
|
159
|
+
});
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
return keys.map((key) => ({
|
|
163
|
+
key: key.key,
|
|
164
|
+
meta: resultsMap[key.key]
|
|
165
|
+
}));
|
|
166
|
+
},
|
|
126
167
|
setItem: async (key, value) => {
|
|
127
168
|
const { driver, driverKey } = resolveKey(key);
|
|
128
169
|
await setItem(driver, driverKey, value);
|
|
129
170
|
},
|
|
130
|
-
setItems: async (
|
|
131
|
-
const areaToKeyValueMap =
|
|
132
|
-
|
|
133
|
-
const { driverArea, driverKey } = resolveKey(
|
|
134
|
-
|
|
135
|
-
areaToKeyValueMap.set(
|
|
136
|
-
driverArea,
|
|
137
|
-
values2.concat({ key: driverKey, value })
|
|
171
|
+
setItems: async (items) => {
|
|
172
|
+
const areaToKeyValueMap = {};
|
|
173
|
+
items.forEach((item) => {
|
|
174
|
+
const { driverArea, driverKey } = resolveKey(
|
|
175
|
+
"key" in item ? item.key : item.item.key
|
|
138
176
|
);
|
|
177
|
+
areaToKeyValueMap[driverArea] ??= [];
|
|
178
|
+
areaToKeyValueMap[driverArea].push({
|
|
179
|
+
key: driverKey,
|
|
180
|
+
value: item.value
|
|
181
|
+
});
|
|
139
182
|
});
|
|
140
183
|
await Promise.all(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
)
|
|
184
|
+
Object.entries(areaToKeyValueMap).map(async ([driverArea, values]) => {
|
|
185
|
+
const driver = getDriver(driverArea);
|
|
186
|
+
await driver.setItems(values);
|
|
187
|
+
})
|
|
147
188
|
);
|
|
148
189
|
},
|
|
149
190
|
setMeta: async (key, properties) => {
|
|
150
191
|
const { driver, driverKey } = resolveKey(key);
|
|
151
192
|
await setMeta(driver, driverKey, properties);
|
|
152
193
|
},
|
|
194
|
+
setMetas: async (items) => {
|
|
195
|
+
const areaToMetaUpdatesMap = {};
|
|
196
|
+
items.forEach((item) => {
|
|
197
|
+
const { driverArea, driverKey } = resolveKey(
|
|
198
|
+
"key" in item ? item.key : item.item.key
|
|
199
|
+
);
|
|
200
|
+
areaToMetaUpdatesMap[driverArea] ??= [];
|
|
201
|
+
areaToMetaUpdatesMap[driverArea].push({
|
|
202
|
+
key: driverKey,
|
|
203
|
+
properties: item.meta
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
await Promise.all(
|
|
207
|
+
Object.entries(areaToMetaUpdatesMap).map(
|
|
208
|
+
async ([storageArea, updates]) => {
|
|
209
|
+
const driver = getDriver(storageArea);
|
|
210
|
+
const metaKeys = updates.map(({ key }) => getMetaKey(key));
|
|
211
|
+
console.log(storageArea, metaKeys);
|
|
212
|
+
const existingMetas = await driver.getItems(metaKeys);
|
|
213
|
+
const existingMetaMap = Object.fromEntries(
|
|
214
|
+
existingMetas.map(({ key, value }) => [key, getMetaValue(value)])
|
|
215
|
+
);
|
|
216
|
+
const metaUpdates = updates.map(({ key, properties }) => {
|
|
217
|
+
const metaKey = getMetaKey(key);
|
|
218
|
+
return {
|
|
219
|
+
key: metaKey,
|
|
220
|
+
value: mergeMeta(existingMetaMap[metaKey] ?? {}, properties)
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
await driver.setItems(metaUpdates);
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
);
|
|
227
|
+
},
|
|
153
228
|
removeItem: async (key, opts) => {
|
|
154
229
|
const { driver, driverKey } = resolveKey(key);
|
|
155
230
|
await removeItem(driver, driverKey, opts);
|
|
156
231
|
},
|
|
157
232
|
removeItems: async (keys) => {
|
|
158
|
-
const areaToKeysMap =
|
|
233
|
+
const areaToKeysMap = {};
|
|
159
234
|
keys.forEach((key) => {
|
|
160
235
|
let keyStr;
|
|
161
236
|
let opts;
|
|
162
237
|
if (typeof key === "string") {
|
|
163
238
|
keyStr = key;
|
|
239
|
+
} else if ("getValue" in key) {
|
|
240
|
+
keyStr = key.key;
|
|
241
|
+
} else if ("item" in key) {
|
|
242
|
+
keyStr = key.item.key;
|
|
243
|
+
opts = key.options;
|
|
164
244
|
} else {
|
|
165
245
|
keyStr = key.key;
|
|
166
246
|
opts = key.options;
|
|
167
247
|
}
|
|
168
248
|
const { driverArea, driverKey } = resolveKey(keyStr);
|
|
169
|
-
|
|
170
|
-
|
|
249
|
+
areaToKeysMap[driverArea] ??= [];
|
|
250
|
+
areaToKeysMap[driverArea].push(driverKey);
|
|
171
251
|
if (opts?.removeMeta) {
|
|
172
|
-
|
|
252
|
+
areaToKeysMap[driverArea].push(getMetaKey(driverKey));
|
|
173
253
|
}
|
|
174
|
-
areaToKeysMap.set(driverArea, areaKeys);
|
|
175
254
|
});
|
|
176
255
|
await Promise.all(
|
|
177
|
-
|
|
256
|
+
Object.entries(areaToKeysMap).map(async ([driverArea, keys2]) => {
|
|
178
257
|
const driver = getDriver(driverArea);
|
|
179
258
|
await driver.removeItems(keys2);
|
|
180
259
|
})
|
|
@@ -236,7 +315,13 @@ function createStorage() {
|
|
|
236
315
|
);
|
|
237
316
|
let migratedValue = value;
|
|
238
317
|
for (const migrateToVersion of migrationsToRun) {
|
|
239
|
-
|
|
318
|
+
try {
|
|
319
|
+
migratedValue = await migrations?.[migrateToVersion]?.(migratedValue) ?? migratedValue;
|
|
320
|
+
} catch (err) {
|
|
321
|
+
throw Error(`v${migrateToVersion} migration failed for "${key}"`, {
|
|
322
|
+
cause: err
|
|
323
|
+
});
|
|
324
|
+
}
|
|
240
325
|
}
|
|
241
326
|
await driver.setItems([
|
|
242
327
|
{ key: driverKey, value: migratedValue },
|
|
@@ -261,6 +346,7 @@ function createStorage() {
|
|
|
261
346
|
});
|
|
262
347
|
migrationsDone.then(getOrInitValue);
|
|
263
348
|
return {
|
|
349
|
+
key,
|
|
264
350
|
get defaultValue() {
|
|
265
351
|
return getFallback();
|
|
266
352
|
},
|
|
@@ -388,3 +474,10 @@ function createDriver(storageArea) {
|
|
|
388
474
|
}
|
|
389
475
|
};
|
|
390
476
|
}
|
|
477
|
+
export class MigrationError extends Error {
|
|
478
|
+
constructor(key, version, options) {
|
|
479
|
+
super(`v${version} migration failed for "${key}"`, options);
|
|
480
|
+
this.key = key;
|
|
481
|
+
this.version = version;
|
|
482
|
+
}
|
|
483
|
+
}
|
package/dist/version.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "0.19.
|
|
1
|
+
export const version = "0.19.14";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.19.
|
|
4
|
+
"version": "0.19.14",
|
|
5
5
|
"description": "Next gen framework for developing web extensions",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@aklinker1/rollup-plugin-visualizer": "5.12.0",
|
|
74
|
-
"@types/chrome": "^0.0.
|
|
75
|
-
"@types/webextension-polyfill": "^0.
|
|
74
|
+
"@types/chrome": "^0.0.280",
|
|
75
|
+
"@types/webextension-polyfill": "^0.12.1",
|
|
76
76
|
"@webext-core/fake-browser": "^1.3.1",
|
|
77
77
|
"@webext-core/isolated-element": "^1.1.2",
|
|
78
78
|
"@webext-core/match-patterns": "^1.0.3",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"c12": "^1.11.2",
|
|
81
81
|
"cac": "^6.7.14",
|
|
82
82
|
"chokidar": "^3.6.0",
|
|
83
|
-
"ci-info": "^4.
|
|
83
|
+
"ci-info": "^4.1.0",
|
|
84
84
|
"consola": "^3.2.3",
|
|
85
85
|
"defu": "^6.1.4",
|
|
86
86
|
"dequal": "^2.0.3",
|
|
@@ -99,40 +99,40 @@
|
|
|
99
99
|
"linkedom": "^0.18.5",
|
|
100
100
|
"magicast": "^0.3.5",
|
|
101
101
|
"minimatch": "^10.0.1",
|
|
102
|
-
"nano-spawn": "^0.
|
|
102
|
+
"nano-spawn": "^0.2.0",
|
|
103
103
|
"normalize-path": "^3.0.0",
|
|
104
104
|
"nypm": "^0.3.12",
|
|
105
105
|
"ohash": "^1.1.4",
|
|
106
106
|
"open": "^10.1.0",
|
|
107
|
-
"ora": "^8.1.
|
|
107
|
+
"ora": "^8.1.1",
|
|
108
108
|
"perfect-debounce": "^1.0.0",
|
|
109
|
-
"picocolors": "^1.1.
|
|
109
|
+
"picocolors": "^1.1.1",
|
|
110
110
|
"prompts": "^2.4.2",
|
|
111
111
|
"publish-browser-extension": "^2.2.2",
|
|
112
112
|
"scule": "^1.3.0",
|
|
113
113
|
"unimport": "^3.13.1",
|
|
114
|
-
"vite": "^5.4.
|
|
115
|
-
"vite-node": "^2.1.
|
|
114
|
+
"vite": "^5.4.11",
|
|
115
|
+
"vite-node": "^2.1.4",
|
|
116
116
|
"web-ext-run": "^0.2.1",
|
|
117
117
|
"webextension-polyfill": "^0.12.0"
|
|
118
118
|
},
|
|
119
119
|
"devDependencies": {
|
|
120
120
|
"@aklinker1/check": "^1.4.5",
|
|
121
|
-
"@faker-js/faker": "^
|
|
121
|
+
"@faker-js/faker": "^9.2.0",
|
|
122
122
|
"@types/fs-extra": "^11.0.4",
|
|
123
123
|
"@types/lodash.merge": "^4.6.9",
|
|
124
|
-
"@types/node": "^20.
|
|
124
|
+
"@types/node": "^20.17.6",
|
|
125
125
|
"@types/normalize-path": "^3.0.2",
|
|
126
126
|
"@types/prompts": "^2.4.9",
|
|
127
127
|
"extract-zip": "^2.0.1",
|
|
128
|
-
"happy-dom": "^
|
|
128
|
+
"happy-dom": "^15.11.4",
|
|
129
129
|
"lodash.merge": "^4.6.2",
|
|
130
|
-
"oxlint": "^0.
|
|
131
|
-
"publint": "^0.2.
|
|
130
|
+
"oxlint": "^0.11.1",
|
|
131
|
+
"publint": "^0.2.12",
|
|
132
132
|
"tsx": "4.15.7",
|
|
133
|
-
"typescript": "^5.6.
|
|
133
|
+
"typescript": "^5.6.3",
|
|
134
134
|
"unbuild": "^2.0.0",
|
|
135
|
-
"vitest": "^2.1.
|
|
135
|
+
"vitest": "^2.1.4",
|
|
136
136
|
"vitest-plugin-random-seed": "^1.1.0"
|
|
137
137
|
},
|
|
138
138
|
"peerDependenciesMeta": {
|