@delta-comic/plugin 3.0.0-next.7 → 3.0.0-next.9
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/lib/index.d.mts +945 -748
- package/dist/lib/index.mjs +2002 -126
- package/dist/lib/index.mjs.map +1 -1
- package/dist/vite/index.d.mts +2 -3
- package/dist/vite/index.mjs +1 -1
- package/dist/vite/index.mjs.map +1 -1
- package/package.json +18 -17
- package/dist/global-BSAsAv3E.mjs +0 -1443
- package/dist/global-BSAsAv3E.mjs.map +0 -1
- package/dist/native-CHH-Olpj.mjs +0 -63
- package/dist/native-CHH-Olpj.mjs.map +0 -1
- package/dist/runtime-Dk50hXwU.mjs +0 -663
- package/dist/runtime-Dk50hXwU.mjs.map +0 -1
- package/dist/storage-DMKDlPzl.mjs +0 -351
- package/dist/storage-DMKDlPzl.mjs.map +0 -1
|
@@ -1,663 +0,0 @@
|
|
|
1
|
-
import { A as pluginI18n, F as declareDepType, H as useConfig, O as usePluginStore, a as PluginLoader, g as registerLoader, h as registerInstaller, i as PluginInstaller, j as pluginMessageKey, m as registerBooter, r as PluginBooter, t as Global, z as provide } from "./global-BSAsAv3E.mjs";
|
|
2
|
-
import { a as installZipFile, c as readPluginText, i as installDevCode, n as createPluginModuleUrl, o as isTauriRuntime, s as listPluginFiles, t as createPluginAssetUrl } from "./storage-DMKDlPzl.mjs";
|
|
3
|
-
import { AwesomeRegistryClient, isPluginManifestCompatible, marketplaceDownloadToInstallInput, parsePluginManifest } from "./lib/index.mjs";
|
|
4
|
-
import { i as readLocalFile, r as prepareDevScript, t as decodeDevMeta } from "./native-CHH-Olpj.mjs";
|
|
5
|
-
import { isEmpty, sortBy } from "es-toolkit/compat";
|
|
6
|
-
import { defineComponent, h, markRaw, ref } from "vue";
|
|
7
|
-
import { UniComment, UniContentPage, UniItem, UniResource, UniUser } from "@delta-comic/model";
|
|
8
|
-
import { createForm } from "@delta-comic/ui";
|
|
9
|
-
import { PageWebviewAuth } from "@delta-comic/utils";
|
|
10
|
-
import { logger } from "@delta-comic/logger";
|
|
11
|
-
import JSZip from "jszip";
|
|
12
|
-
import { Mutex } from "es-toolkit";
|
|
13
|
-
import ky from "ky";
|
|
14
|
-
import { NModal, useDialog } from "naive-ui";
|
|
15
|
-
import { Downloader } from "@delta-comic/downloader";
|
|
16
|
-
import { Octokit } from "@octokit/rest";
|
|
17
|
-
//#region lib/features/core/booters/0_configSetter.ts
|
|
18
|
-
const configSetterLogger = logger.scoped("plugin:config-setter");
|
|
19
|
-
var _ConfigSetter = class extends PluginBooter {
|
|
20
|
-
name = pluginMessageKey("plugin.runtime.steps.presets.title");
|
|
21
|
-
async call(cfg, setMeta) {
|
|
22
|
-
configSetterLogger.debug("registering plugin capabilities", { plugin: cfg.name });
|
|
23
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.presets.applying"));
|
|
24
|
-
const { name: plugin, content, resource, search, user, subscribe, share } = cfg;
|
|
25
|
-
if (content) for (const [ct, { commentRow, contentPage, downloadProvider, itemCard, layout, itemTranslator }] of Object.entries(content)) {
|
|
26
|
-
if (layout) UniContentPage.layouts.set(ct, layout);
|
|
27
|
-
if (itemCard) UniItem.itemCards.set(ct, itemCard);
|
|
28
|
-
if (contentPage) UniContentPage.contentPages.set(ct, contentPage);
|
|
29
|
-
if (downloadProvider) UniContentPage.downloadProviders.set(ct, downloadProvider);
|
|
30
|
-
if (commentRow) UniComment.commentRow.set(ct, commentRow);
|
|
31
|
-
if (itemTranslator) UniItem.itemTranslator.set(ct, itemTranslator);
|
|
32
|
-
}
|
|
33
|
-
if (resource) {
|
|
34
|
-
if (resource.types) for (const type of resource.types) UniResource.fork.set([plugin, type.type], type);
|
|
35
|
-
if (resource.process) for (const [name, fn] of Object.entries(resource.process)) UniResource.processInstances.set([plugin, name], fn);
|
|
36
|
-
}
|
|
37
|
-
if (search) {
|
|
38
|
-
if (search.categories) for (const c of search.categories) Global.addCategories(plugin, c);
|
|
39
|
-
if (search.tabbar) for (const c of search.tabbar) Global.addTabbar(plugin, c);
|
|
40
|
-
if (search.hotPage) {
|
|
41
|
-
for (const mlc of search.hotPage.mainListCard ?? []) Global.addMainList(plugin, mlc);
|
|
42
|
-
for (const lb of search.hotPage.levelBoard ?? []) Global.addLevelboard(plugin, lb);
|
|
43
|
-
for (const tb of search.hotPage.topButton ?? []) Global.addTopButton(plugin, tb);
|
|
44
|
-
}
|
|
45
|
-
if (search.barcode) for (const barcode of search.barcode ?? []) Global.addBarcode(plugin, barcode);
|
|
46
|
-
if (search.hotSearch) for (const provider of search.hotSearch) Global.addHotSearch(plugin, provider);
|
|
47
|
-
}
|
|
48
|
-
if (user) {
|
|
49
|
-
if (user.card) UniUser.userCards.set(plugin, user.card);
|
|
50
|
-
if (user.edit) UniUser.userEditorBase.set(plugin, user.edit);
|
|
51
|
-
if (user.userActions) for (const [type, value] of Object.entries(user.userActions)) Global.userActions.set([plugin, type], value);
|
|
52
|
-
if (user.authorIcon) for (const [key, value] of Object.entries(user.authorIcon)) UniItem.authorIcon.set([plugin, key], value);
|
|
53
|
-
}
|
|
54
|
-
if (subscribe) for (const [key, value] of Object.entries(subscribe)) Global.subscribes.set([plugin, key], value);
|
|
55
|
-
if (cfg.config) for (const config of cfg.config) useConfig().$registerConfig(config);
|
|
56
|
-
if (share) {
|
|
57
|
-
for (const v of share.initiative ?? []) Global.share.set([plugin, v.key], v);
|
|
58
|
-
for (const v of share.tokenListen ?? []) Global.shareToken.set([plugin, v.key], v);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
var _0_configSetter_default = new _ConfigSetter();
|
|
63
|
-
//#endregion
|
|
64
|
-
//#region lib/features/core/booters/5_i18n.ts
|
|
65
|
-
var PluginI18nBooter = class extends PluginBooter {
|
|
66
|
-
name = pluginMessageKey("plugin.runtime.steps.language.title");
|
|
67
|
-
async call(cfg) {
|
|
68
|
-
if (cfg.i18n) pluginI18n.register(cfg.name, cfg.i18n);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
var _5_i18n_default = new PluginI18nBooter();
|
|
72
|
-
//#endregion
|
|
73
|
-
//#region lib/features/core/booters/utils.ts
|
|
74
|
-
const pluginProbeLogger = logger.scoped("plugin:probe");
|
|
75
|
-
const testApi = async (cfg) => {
|
|
76
|
-
const forks = await cfg.forks();
|
|
77
|
-
return await test(forks, cfg.test);
|
|
78
|
-
};
|
|
79
|
-
const testResourceApi = (cfg) => {
|
|
80
|
-
const forks = cfg.urls;
|
|
81
|
-
return test(forks, cfg.test);
|
|
82
|
-
};
|
|
83
|
-
const test = async (forks, test) => {
|
|
84
|
-
if (isEmpty(forks)) throw new Error("[plugin test] no fork found");
|
|
85
|
-
const record = [];
|
|
86
|
-
const abortController = new AbortController();
|
|
87
|
-
try {
|
|
88
|
-
await Promise.all(forks.map(async (_fork, index) => {
|
|
89
|
-
try {
|
|
90
|
-
const begin = Date.now();
|
|
91
|
-
const stopTimeout = setTimeout(() => {
|
|
92
|
-
abortController.abort();
|
|
93
|
-
}, 1e4);
|
|
94
|
-
await test(_fork, abortController.signal);
|
|
95
|
-
clearTimeout(stopTimeout);
|
|
96
|
-
const time = Date.now() - begin;
|
|
97
|
-
record.push([_fork, time]);
|
|
98
|
-
pluginProbeLogger.debug("plugin endpoint probe succeeded", {
|
|
99
|
-
index,
|
|
100
|
-
latencyMs: time
|
|
101
|
-
});
|
|
102
|
-
abortController.abort();
|
|
103
|
-
} catch {
|
|
104
|
-
record.push([_fork, false]);
|
|
105
|
-
pluginProbeLogger.debug("plugin endpoint probe failed", { index });
|
|
106
|
-
}
|
|
107
|
-
}));
|
|
108
|
-
} catch (err) {
|
|
109
|
-
pluginProbeLogger.debug("plugin endpoint probe aborted", err);
|
|
110
|
-
}
|
|
111
|
-
const result = sortBy(record.filter((v) => v[1] != false), (v) => v[1])[0];
|
|
112
|
-
pluginProbeLogger.debug("plugin endpoint probe completed", { found: Boolean(result) });
|
|
113
|
-
if (!result) return ["", false];
|
|
114
|
-
return result;
|
|
115
|
-
};
|
|
116
|
-
//#endregion
|
|
117
|
-
//#region lib/features/core/booters/10_apiTest.ts
|
|
118
|
-
var _TestPluginApi = class extends PluginBooter {
|
|
119
|
-
name = pluginMessageKey("plugin.runtime.steps.apiTest.title");
|
|
120
|
-
async call(cfg, setMeta, env) {
|
|
121
|
-
if (!cfg.api) return;
|
|
122
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.tests.starting"));
|
|
123
|
-
const namespaces = Object.keys(cfg.api);
|
|
124
|
-
const results = await Promise.all(namespaces.map((namespace) => testApi(cfg.api[namespace])));
|
|
125
|
-
const displayResult = new Array();
|
|
126
|
-
const api = {};
|
|
127
|
-
namespaces.forEach((namespace, i) => {
|
|
128
|
-
api[namespace] = results[i][0];
|
|
129
|
-
displayResult.push([namespace, results[i][1]]);
|
|
130
|
-
});
|
|
131
|
-
env.api = api;
|
|
132
|
-
if (Object.values(api).some((v) => v == false)) {
|
|
133
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.tests.unreachable"));
|
|
134
|
-
throw new Error("can not connect to server");
|
|
135
|
-
}
|
|
136
|
-
setMeta(pluginI18n.translate("plugin.runtime.steps.tests.complete", { results: displayResult.map((ent) => `${ent[0]} -> ${ent[1]} ms`).join("\n") }));
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
var _10_apiTest_default = new _TestPluginApi();
|
|
140
|
-
//#endregion
|
|
141
|
-
//#region lib/features/core/booters/20_resourceTest.ts
|
|
142
|
-
var _TestPluginResource$1 = class extends PluginBooter {
|
|
143
|
-
name = pluginMessageKey("plugin.runtime.steps.resourceTest.title");
|
|
144
|
-
async call(cfg, setMeta) {
|
|
145
|
-
if (!cfg.resource?.types?.length) return;
|
|
146
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.tests.starting"));
|
|
147
|
-
const types = cfg.resource.types.map((v) => ({
|
|
148
|
-
type: v.type,
|
|
149
|
-
val: v
|
|
150
|
-
}));
|
|
151
|
-
const results = await Promise.all(types.map((type) => testResourceApi(type.val)));
|
|
152
|
-
const displayResult = new Array();
|
|
153
|
-
types.forEach((type, i) => {
|
|
154
|
-
if (results[i][1]) UniResource.precedenceFork.set([cfg.name, type.type], results[i][0]);
|
|
155
|
-
displayResult.push([type, results[i][1]]);
|
|
156
|
-
});
|
|
157
|
-
if (results.some((v) => v[1] == false)) {
|
|
158
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.tests.unreachable"));
|
|
159
|
-
throw new Error("[plugin test] can not connect to server");
|
|
160
|
-
}
|
|
161
|
-
setMeta(pluginI18n.translate("plugin.runtime.steps.tests.complete", { results: displayResult.map((ent) => `${ent[0].type} -> ${ent[1]} ms`).join("\n") }));
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
var _20_resourceTest_default = new _TestPluginResource$1();
|
|
165
|
-
//#endregion
|
|
166
|
-
//#region lib/features/core/booters/30_boot.ts
|
|
167
|
-
var _ExposeBootPlugin = class extends PluginBooter {
|
|
168
|
-
name = pluginMessageKey("plugin.runtime.steps.customBoot.title");
|
|
169
|
-
async call(cfg, _, env) {
|
|
170
|
-
if (!cfg.onBooted) return;
|
|
171
|
-
const expose = await cfg.onBooted({ api: env.api });
|
|
172
|
-
if (expose) provide(declareDepType(cfg.name), expose);
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
var _30_boot_default = new _ExposeBootPlugin();
|
|
176
|
-
//#endregion
|
|
177
|
-
//#region lib/features/core/booters/40_auth.ts
|
|
178
|
-
const pluginAuthLogger = logger.scoped("plugin:auth");
|
|
179
|
-
const authPopupMutex = new Mutex();
|
|
180
|
-
var _PluginAuth = class extends PluginBooter {
|
|
181
|
-
name = pluginMessageKey("plugin.runtime.steps.auth.title");
|
|
182
|
-
async call(cfg, setMeta) {
|
|
183
|
-
if (!cfg.auth) return;
|
|
184
|
-
const pluginStore = usePluginStore();
|
|
185
|
-
let mutexAcquired = false;
|
|
186
|
-
try {
|
|
187
|
-
const pluginName = pluginStore.$getI18nName(cfg.name);
|
|
188
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.auth.checking"));
|
|
189
|
-
const isPass = await cfg.auth.passSelect();
|
|
190
|
-
const waitMethod = Promise.withResolvers();
|
|
191
|
-
pluginAuthLogger.info("plugin authentication state checked", {
|
|
192
|
-
authenticated: Boolean(isPass),
|
|
193
|
-
plugin: cfg.name
|
|
194
|
-
});
|
|
195
|
-
await authPopupMutex.acquire();
|
|
196
|
-
mutexAcquired = true;
|
|
197
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.auth.waiting"));
|
|
198
|
-
if (!isPass) {
|
|
199
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.auth.selecting"));
|
|
200
|
-
useDialog().create({
|
|
201
|
-
type: "default",
|
|
202
|
-
positiveText: pluginI18n.translate("plugin.runtime.steps.auth.logIn"),
|
|
203
|
-
negativeText: pluginI18n.translate("plugin.runtime.steps.auth.signUp"),
|
|
204
|
-
closable: false,
|
|
205
|
-
maskClosable: false,
|
|
206
|
-
content: pluginI18n.translate("plugin.runtime.steps.auth.selectMethod"),
|
|
207
|
-
title: pluginName,
|
|
208
|
-
onNegativeClick() {
|
|
209
|
-
waitMethod.resolve("signUp");
|
|
210
|
-
},
|
|
211
|
-
onPositiveClick() {
|
|
212
|
-
waitMethod.resolve("logIn");
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
} else {
|
|
216
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.auth.skipping"));
|
|
217
|
-
waitMethod.resolve(isPass);
|
|
218
|
-
}
|
|
219
|
-
const method = await waitMethod.promise;
|
|
220
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.auth.authenticating"));
|
|
221
|
-
const by = {
|
|
222
|
-
async form(form) {
|
|
223
|
-
const formInstance = createForm(form);
|
|
224
|
-
Global.addGlobalNode(markRaw(defineComponent(() => {
|
|
225
|
-
const show = ref(true);
|
|
226
|
-
formInstance.data.then(() => show.value = false);
|
|
227
|
-
return () => h(NModal, {
|
|
228
|
-
show: show.value,
|
|
229
|
-
position: "center",
|
|
230
|
-
preset: "dialog",
|
|
231
|
-
title: pluginName
|
|
232
|
-
}, formInstance.comp);
|
|
233
|
-
})), cfg.name);
|
|
234
|
-
return await formInstance.data;
|
|
235
|
-
},
|
|
236
|
-
async website(url, injectCode) {
|
|
237
|
-
return new PageWebviewAuth(url, injectCode, { title: pluginName }).mount();
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
if (method == "logIn") await cfg.auth.logIn(by);
|
|
241
|
-
else if (method == "signUp") await cfg.auth.signUp(by);
|
|
242
|
-
authPopupMutex.release();
|
|
243
|
-
mutexAcquired = false;
|
|
244
|
-
setMeta(pluginMessageKey("plugin.runtime.steps.auth.success"));
|
|
245
|
-
pluginAuthLogger.info("plugin authentication completed", { plugin: cfg.name });
|
|
246
|
-
} catch (error) {
|
|
247
|
-
if (mutexAcquired) authPopupMutex.release();
|
|
248
|
-
setMeta(pluginI18n.translate("plugin.runtime.steps.auth.failure", { error: String(error) }));
|
|
249
|
-
pluginAuthLogger.error("plugin authentication failed", { plugin: cfg.name }, error);
|
|
250
|
-
throw error;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
var _40_auth_default = new _PluginAuth();
|
|
255
|
-
//#endregion
|
|
256
|
-
//#region lib/plugin/otherProgress.ts
|
|
257
|
-
const runProgress = async (progress, setMeta) => {
|
|
258
|
-
setMeta({
|
|
259
|
-
name: progress.name,
|
|
260
|
-
description: ""
|
|
261
|
-
});
|
|
262
|
-
await progress.call((description) => setMeta({
|
|
263
|
-
name: progress.name,
|
|
264
|
-
description
|
|
265
|
-
}));
|
|
266
|
-
};
|
|
267
|
-
const runOtherProgress = async (progresses, { setMeta, onBackgroundError = (error) => otherProgressLogger.error("background plugin steps failed", error) }) => {
|
|
268
|
-
let parallelGroup = [];
|
|
269
|
-
for (const progress of progresses) {
|
|
270
|
-
if (progress.async) {
|
|
271
|
-
otherProgressLogger.debug("background plugin step started", { name: progress.name });
|
|
272
|
-
parallelGroup.push(runProgress(progress, setMeta));
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
if (parallelGroup.length > 0) {
|
|
276
|
-
await Promise.all(parallelGroup);
|
|
277
|
-
parallelGroup = [];
|
|
278
|
-
}
|
|
279
|
-
await runProgress(progress, setMeta);
|
|
280
|
-
otherProgressLogger.debug("plugin step completed", { name: progress.name });
|
|
281
|
-
}
|
|
282
|
-
if (parallelGroup.length === 0) return;
|
|
283
|
-
Promise.allSettled(parallelGroup).then((results) => {
|
|
284
|
-
const errors = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
285
|
-
if (errors.length > 0) onBackgroundError(new AggregateError(errors, "后台插件步骤执行失败"));
|
|
286
|
-
});
|
|
287
|
-
};
|
|
288
|
-
const otherProgressLogger = logger.scoped("plugin:background-progress");
|
|
289
|
-
//#endregion
|
|
290
|
-
//#region lib/features/core/booters/50_otherProcess.ts
|
|
291
|
-
var _TestPluginResource = class extends PluginBooter {
|
|
292
|
-
name = pluginMessageKey("plugin.runtime.steps.other.title");
|
|
293
|
-
async call(cfg, setMeta) {
|
|
294
|
-
if (!cfg.otherProgress?.length) return;
|
|
295
|
-
await runOtherProgress(cfg.otherProgress, { setMeta });
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
var _50_otherProcess_default = new _TestPluginResource();
|
|
299
|
-
const PLUGIN_DOWNLOAD_TIMEOUT_MS = 300 * 1e3;
|
|
300
|
-
const downloader = Downloader.get();
|
|
301
|
-
const assetLogger = logger.scoped("plugin:install:asset");
|
|
302
|
-
/**
|
|
303
|
-
* Managed downloads are intentionally bypassed here: installer assets are temporary and must
|
|
304
|
-
* never appear in the user's download queue or leave a task record behind.
|
|
305
|
-
*/
|
|
306
|
-
const downloadInstallerAsset = async (url, options) => {
|
|
307
|
-
assetLogger.info("installer asset download started", {
|
|
308
|
-
maxBytes: options.maxBytes ?? 134217728,
|
|
309
|
-
runtime: isTauriRuntime() ? "tauri" : "web"
|
|
310
|
-
});
|
|
311
|
-
if (isTauriRuntime()) {
|
|
312
|
-
const bytes = await downloader.downloadEphemeral(url, { maxBytes: options.maxBytes ?? 134217728 });
|
|
313
|
-
assetLogger.info("installer asset download completed", { bytes: bytes.byteLength });
|
|
314
|
-
return new Blob([bytes]);
|
|
315
|
-
}
|
|
316
|
-
const blob = await ky.get(url, {
|
|
317
|
-
retry: options.retry,
|
|
318
|
-
timeout: PLUGIN_DOWNLOAD_TIMEOUT_MS
|
|
319
|
-
}).blob();
|
|
320
|
-
assetLogger.info("installer asset download completed", { bytes: blob.size });
|
|
321
|
-
return blob;
|
|
322
|
-
};
|
|
323
|
-
//#endregion
|
|
324
|
-
//#region lib/features/core/installers/10_normalUrl.ts
|
|
325
|
-
const getFileName = (input) => {
|
|
326
|
-
const url = new URL(input);
|
|
327
|
-
const encoded = url.pathname.split("/").filter(Boolean).at(-1) ?? url.hostname;
|
|
328
|
-
let decoded = encoded;
|
|
329
|
-
try {
|
|
330
|
-
decoded = decodeURIComponent(encoded);
|
|
331
|
-
} catch {}
|
|
332
|
-
return [...decoded].map((character) => {
|
|
333
|
-
const code = character.charCodeAt(0);
|
|
334
|
-
return code < 32 || code === 127 ? "_" : character;
|
|
335
|
-
}).join("").replace(/[<>:"/\\|?*]/g, "_").trim() || "us.js";
|
|
336
|
-
};
|
|
337
|
-
var _PluginInstallByFallbackUrl = class extends PluginInstaller {
|
|
338
|
-
description = {
|
|
339
|
-
title: pluginMessageKey("plugin.install.methods.url.title"),
|
|
340
|
-
description: pluginMessageKey("plugin.install.methods.url.description")
|
|
341
|
-
};
|
|
342
|
-
name = "fallbackUrl";
|
|
343
|
-
async installer(input) {
|
|
344
|
-
const data = await downloadInstallerAsset(input, { retry: 3 });
|
|
345
|
-
return new File([data], getFileName(input));
|
|
346
|
-
}
|
|
347
|
-
async download(input) {
|
|
348
|
-
return await this.installer(input);
|
|
349
|
-
}
|
|
350
|
-
async update(pluginMeta) {
|
|
351
|
-
return await this.installer(pluginMeta.installInput);
|
|
352
|
-
}
|
|
353
|
-
async fetchPluginMetaFile(input) {
|
|
354
|
-
return await this.installer(input);
|
|
355
|
-
}
|
|
356
|
-
isMatched(input) {
|
|
357
|
-
return URL.canParse(input);
|
|
358
|
-
}
|
|
359
|
-
};
|
|
360
|
-
var _10_normalUrl_default = new _PluginInstallByFallbackUrl();
|
|
361
|
-
//#endregion
|
|
362
|
-
//#region lib/features/core/installers/20_local.ts
|
|
363
|
-
var _PluginInstallByLocal = class extends PluginInstaller {
|
|
364
|
-
description = {
|
|
365
|
-
title: pluginMessageKey("plugin.install.methods.local.title"),
|
|
366
|
-
description: pluginMessageKey("plugin.install.methods.local.description")
|
|
367
|
-
};
|
|
368
|
-
name = "local";
|
|
369
|
-
async installer(input) {
|
|
370
|
-
return await readLocalFile(decodeURIComponent(input.replace(/^local:/, "")));
|
|
371
|
-
}
|
|
372
|
-
async download(input) {
|
|
373
|
-
return await this.installer(input);
|
|
374
|
-
}
|
|
375
|
-
async update(pluginMeta) {
|
|
376
|
-
return await this.installer(pluginMeta.installInput);
|
|
377
|
-
}
|
|
378
|
-
async fetchPluginMetaFile(input) {
|
|
379
|
-
return await this.installer(input);
|
|
380
|
-
}
|
|
381
|
-
isMatched(input) {
|
|
382
|
-
return isTauriRuntime() && input.startsWith("local:");
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
var _20_local_default = new _PluginInstallByLocal();
|
|
386
|
-
//#endregion
|
|
387
|
-
//#region lib/features/core/installers/30_dev.ts
|
|
388
|
-
var _PluginInstallByDev = class extends PluginInstaller {
|
|
389
|
-
description = {
|
|
390
|
-
title: pluginMessageKey("plugin.install.methods.development.title"),
|
|
391
|
-
description: pluginMessageKey("plugin.install.methods.development.description")
|
|
392
|
-
};
|
|
393
|
-
name = "devUrl";
|
|
394
|
-
async installer(input) {
|
|
395
|
-
const processed = await prepareDevScript(input, await ky.get(`http://${/:\d+$/.test(input) ? input : input + ":6173"}/__vite-plugin-monkey.install.user.js?origin=http%3A%2F%2F${input}%3A6173`).text());
|
|
396
|
-
return new File([processed], "us.js");
|
|
397
|
-
}
|
|
398
|
-
async download(input) {
|
|
399
|
-
return await this.installer(input);
|
|
400
|
-
}
|
|
401
|
-
async update(pluginMeta) {
|
|
402
|
-
return await this.installer(pluginMeta.installInput);
|
|
403
|
-
}
|
|
404
|
-
async fetchPluginMetaFile(input) {
|
|
405
|
-
return await this.installer(input);
|
|
406
|
-
}
|
|
407
|
-
isMatched(input) {
|
|
408
|
-
return /^(((\d+\.?)+)|(localhost))(:\d+)?$/.test(input);
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
var _30_dev_default = new _PluginInstallByDev();
|
|
412
|
-
//#endregion
|
|
413
|
-
//#region lib/features/core/installers/40_github.ts
|
|
414
|
-
const defaultGitHubInstallerDependencies = {
|
|
415
|
-
coreVersion: "3.0.0-next.7",
|
|
416
|
-
downloadAsset: async (url) => await downloadInstallerAsset(url, { retry: 2 }),
|
|
417
|
-
getConfig: () => useConfig().$loadApp().data.value,
|
|
418
|
-
async *listReleasePages(owner, repo, token) {
|
|
419
|
-
const octokit = new Octokit({ auth: token });
|
|
420
|
-
const pages = octokit.paginate.iterator(octokit.rest.repos.listReleases, {
|
|
421
|
-
owner,
|
|
422
|
-
per_page: 100,
|
|
423
|
-
repo
|
|
424
|
-
});
|
|
425
|
-
for await (const page of pages) yield page.data;
|
|
426
|
-
}
|
|
427
|
-
};
|
|
428
|
-
const parseRepository = (input) => {
|
|
429
|
-
const [owner, repo, ...rest] = input.replace(/^gh:/, "").split("/");
|
|
430
|
-
if (!owner || !repo || rest.length > 0) throw new Error(pluginI18n.translate("plugin.install.errors.invalidGitHub", { input }));
|
|
431
|
-
return {
|
|
432
|
-
owner,
|
|
433
|
-
repo
|
|
434
|
-
};
|
|
435
|
-
};
|
|
436
|
-
const decodeManifest = async (blob) => {
|
|
437
|
-
try {
|
|
438
|
-
return parsePluginManifest(JSON.parse(await blob.text()));
|
|
439
|
-
} catch {
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
};
|
|
443
|
-
var _PluginInstallByNormalUrl = class extends PluginInstaller {
|
|
444
|
-
dependencies;
|
|
445
|
-
description = {
|
|
446
|
-
title: pluginMessageKey("plugin.install.methods.github.title"),
|
|
447
|
-
description: pluginMessageKey("plugin.install.methods.github.description")
|
|
448
|
-
};
|
|
449
|
-
name = "github";
|
|
450
|
-
constructor(dependencies = defaultGitHubInstallerDependencies) {
|
|
451
|
-
super();
|
|
452
|
-
this.dependencies = dependencies;
|
|
453
|
-
}
|
|
454
|
-
async findCompatibleRelease(input) {
|
|
455
|
-
const { githubToken, receivePerReleaseUpdate } = this.dependencies.getConfig();
|
|
456
|
-
const { owner, repo } = parseRepository(input);
|
|
457
|
-
const pages = this.dependencies.listReleasePages(owner, repo, githubToken || void 0);
|
|
458
|
-
for await (const releases of pages) for (const release of releases) {
|
|
459
|
-
if (release.draft || !receivePerReleaseUpdate && release.prerelease) continue;
|
|
460
|
-
const manifestAsset = release.assets.find((asset) => asset.name === "manifest.json");
|
|
461
|
-
const plugin = release.assets.find((asset) => asset.name === "plugin.zip");
|
|
462
|
-
if (!manifestAsset || !plugin) continue;
|
|
463
|
-
const manifest = await this.dependencies.downloadAsset(manifestAsset.browser_download_url);
|
|
464
|
-
const meta = await decodeManifest(manifest);
|
|
465
|
-
if (!meta || !isPluginManifestCompatible(meta, this.dependencies.coreVersion)) continue;
|
|
466
|
-
return {
|
|
467
|
-
manifest,
|
|
468
|
-
plugin
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
throw new Error(pluginI18n.translate("plugin.install.errors.noCompatibleRelease", { version: this.dependencies.coreVersion }));
|
|
472
|
-
}
|
|
473
|
-
async installer(input) {
|
|
474
|
-
const { plugin } = await this.findCompatibleRelease(input);
|
|
475
|
-
const data = await this.dependencies.downloadAsset(plugin.browser_download_url);
|
|
476
|
-
return new File([data], plugin.name);
|
|
477
|
-
}
|
|
478
|
-
async download(input) {
|
|
479
|
-
return await this.installer(input);
|
|
480
|
-
}
|
|
481
|
-
async update(pluginMeta) {
|
|
482
|
-
return await this.installer(pluginMeta.installInput);
|
|
483
|
-
}
|
|
484
|
-
async fetchPluginMetaFile(input) {
|
|
485
|
-
const { manifest } = await this.findCompatibleRelease(input);
|
|
486
|
-
return new File([manifest], "manifest.json");
|
|
487
|
-
}
|
|
488
|
-
isMatched(input) {
|
|
489
|
-
return input.startsWith("gh:") && input.split("/").length === 2;
|
|
490
|
-
}
|
|
491
|
-
};
|
|
492
|
-
var _40_github_default = new _PluginInstallByNormalUrl();
|
|
493
|
-
//#endregion
|
|
494
|
-
//#region lib/features/core/installers/9999_awesome.ts
|
|
495
|
-
var _PluginInstallByAwesome = class extends PluginInstaller {
|
|
496
|
-
registry;
|
|
497
|
-
description = {
|
|
498
|
-
title: pluginMessageKey("plugin.install.methods.marketplace.title"),
|
|
499
|
-
description: pluginMessageKey("plugin.install.methods.marketplace.description")
|
|
500
|
-
};
|
|
501
|
-
name = "awesome";
|
|
502
|
-
constructor(registry = new AwesomeRegistryClient()) {
|
|
503
|
-
super();
|
|
504
|
-
this.registry = registry;
|
|
505
|
-
}
|
|
506
|
-
async listing(input) {
|
|
507
|
-
const match = /^ap:([A-Za-z0-9][A-Za-z0-9_-]{0,63})$/.exec(input);
|
|
508
|
-
if (!match) throw new Error(pluginI18n.translate("plugin.install.errors.invalidMarketplaceId", { input }));
|
|
509
|
-
return await this.registry.findListing(match[1]);
|
|
510
|
-
}
|
|
511
|
-
async installer(input) {
|
|
512
|
-
return marketplaceDownloadToInstallInput((await this.listing(input)).download);
|
|
513
|
-
}
|
|
514
|
-
async download(input) {
|
|
515
|
-
return await this.installer(input);
|
|
516
|
-
}
|
|
517
|
-
async update(pluginMeta) {
|
|
518
|
-
return await this.installer(pluginMeta.installInput);
|
|
519
|
-
}
|
|
520
|
-
async fetchPluginMetaFile(input) {
|
|
521
|
-
const listing = await this.listing(input);
|
|
522
|
-
const manifest = await this.registry.loadManifest(listing);
|
|
523
|
-
if (!manifest) return marketplaceDownloadToInstallInput(listing.download);
|
|
524
|
-
return new File([JSON.stringify(manifest)], "manifest.json", { type: "application/json" });
|
|
525
|
-
}
|
|
526
|
-
isMatched(input) {
|
|
527
|
-
return /^ap:[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(input);
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
var _9999_awesome_default = new _PluginInstallByAwesome();
|
|
531
|
-
//#endregion
|
|
532
|
-
//#region lib/features/core/loaders/1_zip.ts
|
|
533
|
-
const zipLoaderLogger = logger.scoped("plugin:loader:zip");
|
|
534
|
-
const rewriteCssAssetUrls = async (cssPath, css, createAssetUrl) => {
|
|
535
|
-
const pattern = /url\(\s*(?:(["'])(.*?)\1|([^)'"\s][^)]*?))\s*\)/g;
|
|
536
|
-
let output = "";
|
|
537
|
-
let cursor = 0;
|
|
538
|
-
for (const match of css.matchAll(pattern)) {
|
|
539
|
-
const index = match.index;
|
|
540
|
-
const rawUrl = (match[2] ?? match[3] ?? "").trim();
|
|
541
|
-
if (!rawUrl || /^(?:#|blob:|data:|https?:|\/\/)/i.test(rawUrl)) continue;
|
|
542
|
-
const resolved = new URL(rawUrl, `https://plugin.local/${cssPath}`);
|
|
543
|
-
const assetUrl = await createAssetUrl(resolved.pathname.slice(1));
|
|
544
|
-
output += css.slice(cursor, index) + `url("${assetUrl}${resolved.search}${resolved.hash}")`;
|
|
545
|
-
cursor = index + match[0].length;
|
|
546
|
-
}
|
|
547
|
-
return output + css.slice(cursor);
|
|
548
|
-
};
|
|
549
|
-
var _1_zip_default = new class extends PluginLoader {
|
|
550
|
-
name = "zip";
|
|
551
|
-
async install(file, context) {
|
|
552
|
-
zipLoaderLogger.info("zip plugin installation started", { bytes: file.size });
|
|
553
|
-
return await installZipFile(file, (progress) => {
|
|
554
|
-
const percent = progress.total > 0 ? progress.current / progress.total * 90 : 0;
|
|
555
|
-
context?.report({
|
|
556
|
-
description: progress.path ? pluginI18n.translate("plugin.progress.extractingPath", { path: progress.path }) : pluginI18n.translate("plugin.progress.extracting"),
|
|
557
|
-
progress: percent
|
|
558
|
-
});
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
canInstall(file) {
|
|
562
|
-
return file.name.endsWith(".zip");
|
|
563
|
-
}
|
|
564
|
-
async load(pluginMeta) {
|
|
565
|
-
zipLoaderLogger.debug("zip plugin module load started", { plugin: pluginMeta.pluginName });
|
|
566
|
-
if (!pluginMeta.meta.entry) throw new Error("not found entry");
|
|
567
|
-
const files = await listPluginFiles(pluginMeta.pluginName);
|
|
568
|
-
const javascriptFiles = files.filter((path) => /\.(?:js|mjs)$/i.test(path));
|
|
569
|
-
if (!isTauriRuntime() && javascriptFiles.length > 1) throw new Error(pluginI18n.translate("plugin.install.errors.webSingleFile", { files: javascriptFiles.join(", ") }));
|
|
570
|
-
const src = await createPluginModuleUrl(pluginMeta.pluginName, pluginMeta.meta.entry.jsPath);
|
|
571
|
-
const result = (await import(
|
|
572
|
-
/* @vite-ignore */
|
|
573
|
-
src
|
|
574
|
-
).finally(() => {
|
|
575
|
-
if (src.startsWith("blob:")) URL.revokeObjectURL(src);
|
|
576
|
-
})).default;
|
|
577
|
-
if (!pluginMeta.meta.entry?.cssPath) return result;
|
|
578
|
-
const cssPath = pluginMeta.meta.entry.cssPath;
|
|
579
|
-
if (cssPath == "auto") {
|
|
580
|
-
const discovered = files.find((path) => path.endsWith(".css"));
|
|
581
|
-
if (!discovered) return result;
|
|
582
|
-
var filePath = discovered;
|
|
583
|
-
} else var filePath = cssPath;
|
|
584
|
-
const style = document.createElement("style");
|
|
585
|
-
style.dataset.plugin = pluginMeta.pluginName;
|
|
586
|
-
style.textContent = await rewriteCssAssetUrls(filePath, await readPluginText(pluginMeta.pluginName, filePath), (path) => createPluginAssetUrl(pluginMeta.pluginName, path));
|
|
587
|
-
document.head.appendChild(style);
|
|
588
|
-
zipLoaderLogger.debug("zip plugin stylesheet attached", { plugin: pluginMeta.pluginName });
|
|
589
|
-
return result;
|
|
590
|
-
}
|
|
591
|
-
async decodeMeta(file) {
|
|
592
|
-
const manifest = (await JSZip.loadAsync(file)).file("manifest.json");
|
|
593
|
-
if (!manifest) throw new Error("plugin archive does not contain manifest.json");
|
|
594
|
-
return JSON.parse(await manifest.async("text"));
|
|
595
|
-
}
|
|
596
|
-
isMetaFile(file) {
|
|
597
|
-
return file.name.endsWith(".zip") || file.name == "manifest.json";
|
|
598
|
-
}
|
|
599
|
-
async decodeMetaFile(file) {
|
|
600
|
-
if (file.name == "manifest.json") return JSON.parse(await file.text());
|
|
601
|
-
const mFile = await (await new JSZip().loadAsync(file)).filter((p) => p == "manifest.json")[0].async("text");
|
|
602
|
-
return JSON.parse(mFile);
|
|
603
|
-
}
|
|
604
|
-
}();
|
|
605
|
-
//#endregion
|
|
606
|
-
//#region lib/features/core/loaders/2_dev.ts
|
|
607
|
-
var _2_dev_default = new class extends PluginLoader {
|
|
608
|
-
name = "dev";
|
|
609
|
-
async install(file) {
|
|
610
|
-
return await installDevCode(await file.text());
|
|
611
|
-
}
|
|
612
|
-
canInstall(file) {
|
|
613
|
-
return file.name.endsWith(".js");
|
|
614
|
-
}
|
|
615
|
-
async load(pluginMeta) {
|
|
616
|
-
const code = await readPluginText(pluginMeta.pluginName, "us.js");
|
|
617
|
-
const lastIndex = code.lastIndexOf(";") + 1;
|
|
618
|
-
const blob = new Blob([code.slice(0, lastIndex)], { type: "text/javascript" });
|
|
619
|
-
const url = URL.createObjectURL(blob);
|
|
620
|
-
try {
|
|
621
|
-
return (await import(
|
|
622
|
-
/* @vite-ignore */
|
|
623
|
-
url
|
|
624
|
-
)).default;
|
|
625
|
-
} finally {
|
|
626
|
-
URL.revokeObjectURL(url);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
async decodeMeta(file) {
|
|
630
|
-
return await decodeDevMeta(await file.text());
|
|
631
|
-
}
|
|
632
|
-
isMetaFile(file) {
|
|
633
|
-
return file.name.endsWith(".js");
|
|
634
|
-
}
|
|
635
|
-
async decodeMetaFile(file) {
|
|
636
|
-
return this.decodeMeta(file);
|
|
637
|
-
}
|
|
638
|
-
}();
|
|
639
|
-
//#endregion
|
|
640
|
-
//#region lib/features/core/runtime.ts
|
|
641
|
-
let registered = false;
|
|
642
|
-
const registerCoreRuntimeExtensions = () => {
|
|
643
|
-
if (registered) return;
|
|
644
|
-
registered = true;
|
|
645
|
-
registerBooter(_0_configSetter_default, { order: 0 });
|
|
646
|
-
registerBooter(_5_i18n_default, { order: 5 });
|
|
647
|
-
registerBooter(_10_apiTest_default, { order: 10 });
|
|
648
|
-
registerBooter(_20_resourceTest_default, { order: 20 });
|
|
649
|
-
registerBooter(_30_boot_default, { order: 30 });
|
|
650
|
-
registerBooter(_40_auth_default, { order: 40 });
|
|
651
|
-
registerBooter(_50_otherProcess_default, { order: 50 });
|
|
652
|
-
registerLoader(_1_zip_default, { order: 1 });
|
|
653
|
-
registerLoader(_2_dev_default, { order: 2 });
|
|
654
|
-
registerInstaller(_10_normalUrl_default, { order: 10 });
|
|
655
|
-
registerInstaller(_20_local_default, { order: 20 });
|
|
656
|
-
registerInstaller(_30_dev_default, { order: 30 });
|
|
657
|
-
registerInstaller(_40_github_default, { order: 40 });
|
|
658
|
-
registerInstaller(_9999_awesome_default, { order: 9999 });
|
|
659
|
-
};
|
|
660
|
-
//#endregion
|
|
661
|
-
export { registerCoreRuntimeExtensions };
|
|
662
|
-
|
|
663
|
-
//# sourceMappingURL=runtime-Dk50hXwU.mjs.map
|