@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.
@@ -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