@hieuzest/koishi-plugin-market 2.12.0

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.
Files changed (41) hide show
  1. package/dist/index.js +1 -0
  2. package/dist/style.css +1 -0
  3. package/lib/browser/index.d.ts +12 -0
  4. package/lib/browser/index.mjs +86 -0
  5. package/lib/browser/index.mjs.map +6 -0
  6. package/lib/browser/market.d.ts +12 -0
  7. package/lib/index.d.ts +1 -0
  8. package/lib/node/deps.d.ts +15 -0
  9. package/lib/node/index.d.ts +33 -0
  10. package/lib/node/index.js +715 -0
  11. package/lib/node/index.js.map +6 -0
  12. package/lib/node/installer.d.ts +108 -0
  13. package/lib/node/market.d.ts +40 -0
  14. package/lib/shared/index.d.ts +32 -0
  15. package/lib/shared/index.js +63 -0
  16. package/lib/shared/index.js.map +6 -0
  17. package/lib/shared/index.mjs +41 -0
  18. package/lib/shared/index.mjs.map +6 -0
  19. package/package.json +88 -0
  20. package/src/browser/index.ts +27 -0
  21. package/src/browser/market.ts +19 -0
  22. package/src/index.ts +2 -0
  23. package/src/node/deps.ts +26 -0
  24. package/src/node/index.ts +192 -0
  25. package/src/node/installer.ts +488 -0
  26. package/src/node/locales/message.de-DE.yml +25 -0
  27. package/src/node/locales/message.en-US.yml +25 -0
  28. package/src/node/locales/message.fr-FR.yml +25 -0
  29. package/src/node/locales/message.ja-JP.yml +25 -0
  30. package/src/node/locales/message.ru-RU.yml +25 -0
  31. package/src/node/locales/message.zh-CN.yml +28 -0
  32. package/src/node/locales/message.zh-TW.yml +25 -0
  33. package/src/node/locales/schema.de-DE.yml +9 -0
  34. package/src/node/locales/schema.en-US.yml +9 -0
  35. package/src/node/locales/schema.fr-FR.yml +9 -0
  36. package/src/node/locales/schema.ja-JP.yml +9 -0
  37. package/src/node/locales/schema.ru-RU.yml +9 -0
  38. package/src/node/locales/schema.zh-CN.yml +10 -0
  39. package/src/node/locales/schema.zh-TW.yml +9 -0
  40. package/src/node/market.ts +113 -0
  41. package/src/shared/index.ts +63 -0
@@ -0,0 +1,715 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name2 in all)
13
+ __defProp(target, name2, { get: all[name2], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
+
34
+ // src/node/locales/schema.zh-CN.yml
35
+ var require_schema_zh_CN = __commonJS({
36
+ "src/node/locales/schema.zh-CN.yml"(exports2, module2) {
37
+ module2.exports = { registry: { $description: "插件源设置", endpoint: "插件的下载源。默认跟随当前项目的 npm config。", timeout: "获取插件数据的超时时间。" }, search: { $description: "搜索设置", endpoint: "用于搜索插件市场的网址。默认跟随插件源设置。", timeout: "搜索插件市场的超时时间。", proxyAgent: "用于搜索插件市场的代理。" } };
38
+ }
39
+ });
40
+
41
+ // src/node/locales/message.zh-CN.yml
42
+ var require_message_zh_CN = __commonJS({
43
+ "src/node/locales/message.zh-CN.yml"(exports2, module2) {
44
+ module2.exports = { "commands.plugin": { description: "插件管理" }, "commands.plugin.install": { description: "安装插件", messages: { "expect-name": "请输入插件名。", "already-installed": "该插件已安装。", "not-found": "未找到该插件。", success: "安装成功!" } }, "commands.plugin.uninstall": { description: "卸载插件", messages: { "expect-name": "请输入插件名。", "not-installed": "该插件未安装。", success: "卸载成功!" } }, "commands.plugin.upgrade": { description: "升级插件", options: { self: "升级 Koishi 本体" }, messages: { "all-updated": "所有插件已是最新版本。", available: "有可用的依赖更新:", prompt: "输入「Y」升级全部依赖,输入「N」取消操作。", cancelled: "已取消操作。", success: "升级成功!" } } };
45
+ }
46
+ });
47
+
48
+ // src/node/index.ts
49
+ var node_exports = {};
50
+ __export(node_exports, {
51
+ Config: () => Config,
52
+ Installer: () => installer_default,
53
+ apply: () => apply,
54
+ inject: () => inject,
55
+ name: () => name,
56
+ usage: () => usage
57
+ });
58
+ module.exports = __toCommonJS(node_exports);
59
+ var import_koishi3 = require("koishi");
60
+ var import_semver2 = require("semver");
61
+ var import_path2 = require("path");
62
+
63
+ // src/node/deps.ts
64
+ var import_console = require("@koishijs/console");
65
+ var DependencyProvider = class extends import_console.DataService {
66
+ constructor(ctx) {
67
+ super(ctx, "dependencies", { authority: 4 });
68
+ this.ctx = ctx;
69
+ }
70
+ static {
71
+ __name(this, "DependencyProvider");
72
+ }
73
+ async get() {
74
+ return this.ctx.installer.getDeps();
75
+ }
76
+ };
77
+ var RegistryProvider = class extends import_console.DataService {
78
+ constructor(ctx) {
79
+ super(ctx, "registry", { authority: 4 });
80
+ this.ctx = ctx;
81
+ }
82
+ static {
83
+ __name(this, "RegistryProvider");
84
+ }
85
+ async get() {
86
+ return this.ctx.installer.fullCache;
87
+ }
88
+ };
89
+
90
+ // src/node/installer.ts
91
+ var import_koishi = require("koishi");
92
+ var import_registry = __toESM(require("@koishijs/registry"));
93
+ var import_path = require("path");
94
+ var import_simple_git = require("simple-git");
95
+ var import_fs = require("fs");
96
+ var import_semver = require("semver");
97
+ var import_get_registry = __toESM(require("get-registry"));
98
+ var import_which_pm_runs = __toESM(require("which-pm-runs"));
99
+ var import_execa = __toESM(require("execa"));
100
+ var import_p_map = __toESM(require("p-map"));
101
+ var logger = new import_koishi.Logger("market");
102
+ var Dependency;
103
+ ((Dependency2) => {
104
+ Dependency2.RESOLUTION_PREFIX = "▶";
105
+ function isResolution(name2) {
106
+ return name2.startsWith(Dependency2.RESOLUTION_PREFIX);
107
+ }
108
+ Dependency2.isResolution = isResolution;
109
+ __name(isResolution, "isResolution");
110
+ function asResolution(name2) {
111
+ return name2.startsWith(Dependency2.RESOLUTION_PREFIX) ? name2 : Dependency2.RESOLUTION_PREFIX + name2;
112
+ }
113
+ Dependency2.asResolution = asResolution;
114
+ __name(asResolution, "asResolution");
115
+ function asDependency(name2) {
116
+ return name2.startsWith(Dependency2.RESOLUTION_PREFIX) ? name2.slice(Dependency2.RESOLUTION_PREFIX.length) : name2;
117
+ }
118
+ Dependency2.asDependency = asDependency;
119
+ __name(asDependency, "asDependency");
120
+ function parse2(name2, request) {
121
+ const workspaceMatch = request.match(/^workspace:(.+)/);
122
+ if (workspaceMatch) {
123
+ return {
124
+ name: name2,
125
+ protocol: "workspace",
126
+ request,
127
+ invalid: true
128
+ };
129
+ }
130
+ const npmMatch = request.match(/^npm:(.+)/);
131
+ if (npmMatch) {
132
+ return {
133
+ name: name2,
134
+ protocol: "npm",
135
+ path: npmMatch[1].startsWith("@") ? "@" + npmMatch[1].split("@")[1] : npmMatch[1].split("@")[0],
136
+ request: npmMatch[1].split("@")[npmMatch[1].startsWith("@") ? 2 : 1]?.replace(/^[~^]/, "") ?? ""
137
+ };
138
+ }
139
+ const gitMatch = request.match(/^(git[@\+].+)/);
140
+ if (gitMatch) {
141
+ return {
142
+ name: name2,
143
+ protocol: "git",
144
+ path: gitMatch[1].split("#")[0],
145
+ request: gitMatch[1].split("#")[1]?.split("&").find((item) => item.startsWith("tag="))?.replace("tag=", "") || "",
146
+ workspaceName: gitMatch[1].split("#")[1]?.split("&").find((item) => item.startsWith("workspace="))?.replace("workspace=", "") || void 0
147
+ };
148
+ }
149
+ if ((0, import_semver.valid)(request.replace(/^[~^]/, ""))) {
150
+ return {
151
+ name: name2,
152
+ protocol: "npm",
153
+ request: request.replace(/^[~^]/, "")
154
+ };
155
+ }
156
+ return {
157
+ name: name2,
158
+ protocol: "invalid",
159
+ request,
160
+ invalid: true
161
+ };
162
+ }
163
+ Dependency2.parse = parse2;
164
+ __name(parse2, "parse");
165
+ function stringify(dep, target) {
166
+ if (!target) return "";
167
+ switch (dep.protocol) {
168
+ case "workspace":
169
+ return `workspace:${target}`;
170
+ case "npm":
171
+ if (dep.path) {
172
+ return `npm:${dep.path}@${target}`;
173
+ }
174
+ return target;
175
+ case "git":
176
+ return `${dep.path}#tag=${target}` + (dep.workspaceName ? `&workspace=${dep.workspaceName}` : "");
177
+ }
178
+ }
179
+ Dependency2.stringify = stringify;
180
+ __name(stringify, "stringify");
181
+ })(Dependency || (Dependency = {}));
182
+ var levelMap = {
183
+ "info": "info",
184
+ "warning": "debug",
185
+ "error": "warn"
186
+ };
187
+ function loadManifest(name2) {
188
+ const filename = require.resolve(name2 + "/package.json");
189
+ const meta = JSON.parse((0, import_fs.readFileSync)(filename, "utf8"));
190
+ meta.dependencies ||= {};
191
+ (0, import_koishi.defineProperty)(meta, "$workspace", !filename.includes("node_modules"));
192
+ return meta;
193
+ }
194
+ __name(loadManifest, "loadManifest");
195
+ function getVersions(versions) {
196
+ return Object.fromEntries(versions.map((item) => [item.version, (0, import_koishi.pick)(item, ["peerDependencies", "peerDependenciesMeta", "deprecated"])]).sort(([a], [b]) => (0, import_semver.compare)(b, a)));
197
+ }
198
+ __name(getVersions, "getVersions");
199
+ var Installer = class extends import_koishi.Service {
200
+ constructor(ctx, config) {
201
+ super(ctx, "installer");
202
+ this.ctx = ctx;
203
+ this.config = config;
204
+ this.manifest = loadManifest(this.cwd);
205
+ this.flushData = ctx.throttle(() => {
206
+ ctx.get("console")?.broadcast("market/registry", this.tempCache);
207
+ this.tempCache = {};
208
+ }, 500);
209
+ }
210
+ static {
211
+ __name(this, "Installer");
212
+ }
213
+ http;
214
+ endpoint;
215
+ fullCache = {};
216
+ tempCache = {};
217
+ pkgTasks = {};
218
+ agent = (0, import_which_pm_runs.default)();
219
+ manifest;
220
+ depTask;
221
+ flushData;
222
+ git = (0, import_simple_git.simpleGit)();
223
+ get cwd() {
224
+ return this.ctx.baseDir;
225
+ }
226
+ async start() {
227
+ const { endpoint, timeout } = this.config;
228
+ this.endpoint = endpoint || await (0, import_get_registry.default)();
229
+ this.http = this.ctx.http.extend({
230
+ endpoint: this.endpoint,
231
+ timeout
232
+ });
233
+ }
234
+ resolveName(name2) {
235
+ if (name2.startsWith("@koishijs/plugin-")) return [name2];
236
+ if (name2.match(/(^|\/)koishi-plugin-/)) return [name2];
237
+ if (name2[0] === "@") {
238
+ const [left, right] = name2.split("/");
239
+ return [`${left}/koishi-plugin-${right}`];
240
+ } else {
241
+ return [`@koishijs/plugin-${name2}`, `koishi-plugin-${name2}`];
242
+ }
243
+ }
244
+ async findVersion(names) {
245
+ const entries = await Promise.all(names.map(async (name2) => {
246
+ try {
247
+ const versions = Object.entries(await this.getPackage(name2));
248
+ if (!versions.length) return;
249
+ return { [name2]: versions[0][0] };
250
+ } catch (e) {
251
+ }
252
+ }));
253
+ return entries.find(Boolean);
254
+ }
255
+ async _getPackage(name2, path) {
256
+ try {
257
+ const registry = await this.http.get(`/${path}`);
258
+ this.fullCache[name2] = this.tempCache[name2] = getVersions(Object.values(registry.versions).filter((remote) => {
259
+ return !import_registry.default.isPlugin(path) || import_registry.default.isCompatible("4", remote);
260
+ }));
261
+ this.flushData();
262
+ return this.fullCache[name2];
263
+ } catch (e) {
264
+ logger.warn(`Cannot get package ${name2} with ${path}: ${e.message}`);
265
+ }
266
+ }
267
+ async _getGitPackage(name2, path) {
268
+ try {
269
+ const output = await this.git.raw([
270
+ "ls-remote",
271
+ "--tags",
272
+ "--sort=-version:refname",
273
+ // sort by semver descending
274
+ path.replace(/^git\+/, "")
275
+ ]);
276
+ const lines = output.trim().split("\n");
277
+ const tags = [];
278
+ for (const line of lines) {
279
+ if (!line || !line.includes("refs/tags/")) continue;
280
+ const [, ref] = line.split(" ");
281
+ if (ref && ref.startsWith("refs/tags/") && !ref.endsWith("^{}")) {
282
+ const tag = ref.replace("refs/tags/", "");
283
+ tags.push(tag);
284
+ }
285
+ }
286
+ const versions = Object.fromEntries(tags.map((tag) => [tag, {}]));
287
+ this.fullCache[name2] = this.tempCache[name2] = versions;
288
+ this.flushData();
289
+ return this.fullCache[name2];
290
+ } catch (e) {
291
+ logger.warn(e.message);
292
+ }
293
+ }
294
+ setPackage(name2, versions) {
295
+ this.fullCache[name2] = this.tempCache[name2] = getVersions(versions);
296
+ this.flushData();
297
+ this.pkgTasks[name2] = Promise.resolve(this.fullCache[name2]);
298
+ }
299
+ getPackage(name2, dep) {
300
+ switch (dep?.protocol) {
301
+ case "git":
302
+ return this.pkgTasks[name2] ||= this._getGitPackage(name2, dep.path);
303
+ default:
304
+ return this.pkgTasks[name2] ||= this._getPackage(name2, dep?.path ?? dep?.name ?? name2);
305
+ }
306
+ }
307
+ _loadManifest2(name2) {
308
+ const packagePath = (0, import_path.resolve)(process.cwd(), require.resolve(name2));
309
+ if (!packagePath.startsWith(process.cwd())) throw new Error(`Package ${name2} not in workspace`);
310
+ let currentDir = (0, import_path.dirname)(packagePath);
311
+ while (currentDir !== (0, import_path.parse)(currentDir).root) {
312
+ const filename = (0, import_path.join)(currentDir, "package.json");
313
+ if ((0, import_fs.existsSync)(filename)) {
314
+ try {
315
+ const meta = JSON.parse((0, import_fs.readFileSync)(filename, "utf8"));
316
+ meta.dependencies ||= {};
317
+ (0, import_koishi.defineProperty)(meta, "$workspace", !filename.includes("node_modules"));
318
+ return meta;
319
+ } catch (e) {
320
+ }
321
+ }
322
+ currentDir = (0, import_path.dirname)(currentDir);
323
+ }
324
+ throw new Error(`Cannot find package.json for ${name2}`);
325
+ }
326
+ async _getDeps(local = false) {
327
+ const deps = (0, import_koishi.valueMap)(this.manifest.dependencies ?? {}, (request, name2) => Dependency.parse(name2, request));
328
+ const resolutions = Object.fromEntries(Object.entries(this.manifest.resolutions ?? {}).map(([name2, request]) => [Dependency.asResolution(name2), Dependency.parse(name2, request)]));
329
+ const result = { ...deps, ...resolutions };
330
+ await (0, import_p_map.default)(Object.entries(result), async ([name2, dep]) => {
331
+ if (dep.protocol === "git") {
332
+ result[name2].resolved = result[name2].request;
333
+ } else {
334
+ try {
335
+ const meta = loadManifest(dep.name);
336
+ result[name2].resolved = meta.version;
337
+ result[name2].workspace = meta.$workspace;
338
+ if (meta.$workspace) return;
339
+ } catch {
340
+ try {
341
+ const meta = this._loadManifest2(dep.name);
342
+ result[name2].resolved = meta.version;
343
+ result[name2].workspace = meta.$workspace;
344
+ if (meta.$workspace) return;
345
+ } catch (e) {
346
+ logger.warn(`Cannot load local manifest for ${name2}: ${e.message}`);
347
+ }
348
+ }
349
+ }
350
+ if (!local) {
351
+ const versions = await this.getPackage(name2, dep);
352
+ if (versions) result[name2].latest = Object.keys(versions)[0];
353
+ }
354
+ }, { concurrency: 10 });
355
+ return result;
356
+ }
357
+ getDeps() {
358
+ return this.depTask ||= this._getDeps();
359
+ }
360
+ refreshData() {
361
+ this.ctx.get("console")?.refresh("registry");
362
+ this.ctx.get("console")?.refresh("packages");
363
+ }
364
+ refresh(refresh = false) {
365
+ this.pkgTasks = {};
366
+ this.fullCache = {};
367
+ this.tempCache = {};
368
+ this.depTask = this._getDeps();
369
+ if (!refresh) return;
370
+ this.refreshData();
371
+ }
372
+ async exec(args) {
373
+ const name2 = this.agent?.name ?? "npm";
374
+ const useJson = name2 === "yarn" && this.agent.version >= "2";
375
+ if (name2 !== "yarn") args.unshift("install");
376
+ return new Promise((resolve3) => {
377
+ if (useJson) args.push("--json");
378
+ const child = (0, import_execa.default)(name2, args, { cwd: this.cwd });
379
+ child.on("exit", (code) => resolve3(code));
380
+ child.on("error", () => resolve3(-1));
381
+ let stderr = "";
382
+ child.stderr.on("data", (data) => {
383
+ data = stderr + data.toString();
384
+ const lines = data.split("\n");
385
+ stderr = lines.pop();
386
+ for (const line of lines) {
387
+ logger.warn(line);
388
+ }
389
+ });
390
+ let stdout = "";
391
+ child.stdout.on("data", (data) => {
392
+ data = stdout + data.toString();
393
+ const lines = data.split("\n");
394
+ stdout = lines.pop();
395
+ for (const line of lines) {
396
+ if (!useJson || line[0] !== "{") {
397
+ logger.info(line);
398
+ continue;
399
+ }
400
+ try {
401
+ const { type, data: data2 } = JSON.parse(line);
402
+ logger[levelMap[type] ?? "info"](data2);
403
+ } catch (error) {
404
+ logger.warn(line);
405
+ logger.warn(error);
406
+ }
407
+ }
408
+ });
409
+ });
410
+ }
411
+ async override(deps) {
412
+ const filename = (0, import_path.resolve)(this.cwd, "package.json");
413
+ for (const key in deps) {
414
+ if (Dependency.isResolution(key)) {
415
+ const realKey = Dependency.asDependency(key);
416
+ this.manifest.resolutions ||= {};
417
+ if (deps[key]) {
418
+ this.manifest.resolutions[realKey] = deps[key];
419
+ } else {
420
+ delete this.manifest.resolutions[realKey];
421
+ }
422
+ } else {
423
+ if (deps[key]) {
424
+ this.manifest.dependencies[key] = deps[key];
425
+ } else {
426
+ delete this.manifest.dependencies[key];
427
+ }
428
+ }
429
+ }
430
+ this.manifest.dependencies = Object.fromEntries(Object.entries(this.manifest.dependencies).sort((a, b) => a[0].localeCompare(b[0])));
431
+ if (this.manifest.resolutions) {
432
+ this.manifest.resolutions = Object.fromEntries(Object.entries(this.manifest.resolutions ?? {}).sort((a, b) => a[0].localeCompare(b[0])));
433
+ }
434
+ await import_fs.promises.writeFile(filename, JSON.stringify(this.manifest, null, 2) + "\n");
435
+ }
436
+ _install() {
437
+ const args = [];
438
+ if (this.config.endpoint) {
439
+ args.push("--registry", this.endpoint);
440
+ }
441
+ return this.exec(args);
442
+ }
443
+ async install(deps, forced) {
444
+ const localDeps = await this._getDeps(true).then((res) => (0, import_koishi.filterKeys)(res, (name2) => Object.hasOwn(deps, name2)));
445
+ deps = (0, import_koishi.mapValues)(deps, (request, name2) => Object.hasOwn(localDeps, name2) ? Dependency.stringify(localDeps[name2], request) : request);
446
+ await this.override(deps);
447
+ for (const name2 in deps) {
448
+ const { resolved, workspace, protocol } = localDeps[name2] || {};
449
+ if (protocol !== "git" && workspace || deps[name2] && resolved && (0, import_semver.satisfies)(resolved, deps[name2], { includePrerelease: true })) continue;
450
+ forced = true;
451
+ break;
452
+ }
453
+ if (forced) {
454
+ const code = await this._install();
455
+ if (code) return code;
456
+ }
457
+ this.refresh();
458
+ const newDeps = await this.getDeps();
459
+ for (const key in localDeps) {
460
+ const { name: name2, resolved, workspace } = localDeps[key];
461
+ if (workspace || !newDeps[key]) continue;
462
+ if (newDeps[key].resolved === resolved) continue;
463
+ try {
464
+ if (!(require.resolve(name2) in require.cache)) continue;
465
+ } catch (error) {
466
+ logger.error(error);
467
+ }
468
+ this.ctx.loader.fullReload();
469
+ }
470
+ this.refreshData();
471
+ return 0;
472
+ }
473
+ };
474
+ ((Installer2) => {
475
+ Installer2.Config = import_koishi.Schema.object({
476
+ endpoint: import_koishi.Schema.string().role("link"),
477
+ timeout: import_koishi.Schema.number().role("time").default(import_koishi.Time.second * 5)
478
+ });
479
+ })(Installer || (Installer = {}));
480
+ var installer_default = Installer;
481
+
482
+ // src/node/market.ts
483
+ var import_koishi2 = require("koishi");
484
+ var import_registry2 = __toESM(require("@koishijs/registry"));
485
+ var import_shared = require("../shared");
486
+ var MarketProvider = class extends import_shared.MarketProvider {
487
+ constructor(ctx, config) {
488
+ super(ctx);
489
+ this.config = config;
490
+ if (config.endpoint) this.http = ctx.http.extend(config);
491
+ this.flushData = ctx.throttle(() => {
492
+ ctx.console.broadcast("market/patch", {
493
+ data: this.tempCache,
494
+ failed: this.failed.length,
495
+ total: this.scanner.total,
496
+ progress: this.scanner.progress
497
+ });
498
+ this.tempCache = {};
499
+ }, 500);
500
+ }
501
+ static {
502
+ __name(this, "MarketProvider");
503
+ }
504
+ http;
505
+ failed = [];
506
+ scanner;
507
+ fullCache = {};
508
+ tempCache = {};
509
+ flushData;
510
+ async start(refresh = false) {
511
+ this.failed = [];
512
+ this.fullCache = {};
513
+ this.tempCache = {};
514
+ if (refresh) this.ctx.installer.refresh(true);
515
+ await this.prepare();
516
+ super.start();
517
+ }
518
+ async collect() {
519
+ const { timeout } = this.config;
520
+ const registry = this.ctx.installer.http;
521
+ this.failed = [];
522
+ this.scanner = new import_registry2.default(registry.get);
523
+ if (this.http) {
524
+ const result = await this.http.get("");
525
+ this.scanner.objects = result.objects.filter((object) => !object.ignored);
526
+ this.scanner.total = this.scanner.objects.length;
527
+ this.scanner.version = result.version;
528
+ } else {
529
+ await this.scanner.collect({ timeout });
530
+ }
531
+ if (!this.scanner.version) {
532
+ this.scanner.analyze({
533
+ version: "4",
534
+ onFailure: /* @__PURE__ */ __name((name2, reason) => {
535
+ this.failed.push(name2);
536
+ if (registry.config.endpoint.startsWith("https://registry.npmmirror.com")) {
537
+ if (this.ctx.http.isError(reason) && reason.response?.status === 404) {
538
+ }
539
+ }
540
+ }, "onFailure"),
541
+ onRegistry: /* @__PURE__ */ __name((registry2, versions) => {
542
+ this.ctx.installer.setPackage(registry2.name, versions);
543
+ }, "onRegistry"),
544
+ onSuccess: /* @__PURE__ */ __name((object, versions) => {
545
+ object.package.links ||= {
546
+ npm: `${registry.config.endpoint.replace("registry.", "www.")}/package/${object.package.name}`
547
+ };
548
+ this.fullCache[object.package.name] = this.tempCache[object.package.name] = object;
549
+ }, "onSuccess"),
550
+ after: /* @__PURE__ */ __name(() => this.flushData(), "after")
551
+ });
552
+ }
553
+ return null;
554
+ }
555
+ async get() {
556
+ await this.prepare();
557
+ if (this._error) return { data: {}, failed: 0, total: 0, progress: 0 };
558
+ return this.scanner.version ? {
559
+ registry: this.ctx.installer.endpoint,
560
+ data: Object.fromEntries(this.scanner.objects.map((item) => [item.package.name, item])),
561
+ failed: 0,
562
+ total: this.scanner.total,
563
+ progress: this.scanner.total,
564
+ gravatar: process.env.GRAVATAR_MIRROR
565
+ } : {
566
+ registry: this.ctx.installer.endpoint,
567
+ data: this.fullCache,
568
+ failed: this.failed.length,
569
+ total: this.scanner.total,
570
+ progress: this.scanner.progress,
571
+ gravatar: process.env.GRAVATAR_MIRROR
572
+ };
573
+ }
574
+ };
575
+ ((MarketProvider2) => {
576
+ MarketProvider2.Config = import_koishi2.Schema.object({
577
+ endpoint: import_koishi2.Schema.string().role("link"),
578
+ timeout: import_koishi2.Schema.number().role("time").default(import_koishi2.Time.second * 30),
579
+ proxyAgent: import_koishi2.Schema.string().role("link")
580
+ });
581
+ })(MarketProvider || (MarketProvider = {}));
582
+ var market_default = MarketProvider;
583
+
584
+ // src/node/index.ts
585
+ __reExport(node_exports, require("../shared"), module.exports);
586
+ var name = "market";
587
+ var inject = ["http"];
588
+ var usage = `
589
+ 如果插件市场页面提示「无法连接到插件市场」,则可以选择一个 Koishi 社区提供的镜像地址,填入下方对应的配置项中。
590
+
591
+ ## 插件市场(填入 search.endpoint)
592
+
593
+ - [t4wefan](https://k.ilharp.cc/2611)(大陆):https://registry.koishi.t4wefan.pub/index.json
594
+ - [Lipraty](https://k.ilharp.cc/3530)(大陆):https://koi.nyan.zone/registry/index.json
595
+ - [itzdrli](https://k.ilharp.cc/9975)(全球):https://kp.itzdrli.cc
596
+ - [Q78KG](https://k.ilharp.cc/10042)(全球):https://koishi-registry.yumetsuki.moe/index.json
597
+ - Koishi(全球):https://registry.koishi.chat/index.json
598
+
599
+ 要浏览更多社区镜像,请访问 [Koishi 论坛上的镜像一览](https://k.ilharp.cc/4000)。`;
600
+ var Config = import_koishi3.Schema.object({
601
+ registry: installer_default.Config,
602
+ search: market_default.Config
603
+ }).i18n({
604
+ "zh-CN": require_schema_zh_CN()
605
+ });
606
+ function apply(ctx, config) {
607
+ if (!ctx.loader?.writable) {
608
+ return ctx.logger("app").warn("@koishijs/plugin-market is only available for json/yaml config file");
609
+ }
610
+ ctx.plugin(installer_default, config.registry);
611
+ ctx.inject(["installer"], (ctx2) => {
612
+ ctx2.i18n.define("zh-CN", require_message_zh_CN());
613
+ ctx2.command("plugin.install <name>", { authority: 4 }).alias(".i").action(async ({ session }, name2) => {
614
+ if (!name2) return session.text(".expect-name");
615
+ const names = ctx2.installer.resolveName(name2);
616
+ const deps = await ctx2.installer.getDeps();
617
+ name2 = names.find((name3) => deps[name3]);
618
+ if (name2) return session.text(".already-installed");
619
+ const result = await ctx2.installer.findVersion(names);
620
+ if (!result) return session.text(".not-found");
621
+ ctx2.loader.envData.message = {
622
+ ...(0, import_koishi3.pick)(session, ["sid", "channelId", "guildId", "isDirect"]),
623
+ content: session.text(".success")
624
+ };
625
+ await ctx2.installer.install(result);
626
+ ctx2.loader.envData.message = null;
627
+ return session.text(".success");
628
+ });
629
+ ctx2.command("plugin.uninstall <name>", { authority: 4 }).alias(".r").action(async ({ session }, name2) => {
630
+ if (!name2) return session.text(".expect-name");
631
+ const names = ctx2.installer.resolveName(name2);
632
+ const deps = await ctx2.installer.getDeps();
633
+ name2 = names.find((name3) => deps[name3]);
634
+ if (!name2) return session.text(".not-installed");
635
+ await ctx2.installer.install({ [name2]: null });
636
+ return session.text(".success");
637
+ });
638
+ ctx2.command("plugin.upgrade [name...]", { authority: 4 }).alias(".update", ".up").option("self", "-s, --koishi").action(async ({ session, options }, ...names) => {
639
+ async function getPackages(names2) {
640
+ if (!names2.length) return Object.keys(deps);
641
+ names2 = names2.map((name2) => {
642
+ const names3 = ctx2.installer.resolveName(name2);
643
+ return names3.find((name3) => deps[name3]);
644
+ }).filter(Boolean);
645
+ if (options.self) names2.push("koishi");
646
+ return names2;
647
+ }
648
+ __name(getPackages, "getPackages");
649
+ ctx2.installer.refresh(true);
650
+ const deps = await ctx2.installer.getDeps();
651
+ names = await getPackages(names);
652
+ names = names.filter((name2) => {
653
+ const { latest, resolved, invalid } = deps[name2];
654
+ try {
655
+ return !invalid && (0, import_semver2.gt)(latest, resolved);
656
+ } catch {
657
+ }
658
+ });
659
+ if (!names.length) return session.text(".all-updated");
660
+ const output = names.map((name2) => {
661
+ const { latest, resolved } = deps[name2];
662
+ return `${name2}: ${resolved} -> ${latest}`;
663
+ });
664
+ output.unshift(session.text(".available"));
665
+ output.push(session.text(".prompt"));
666
+ await session.send(output.join("\n"));
667
+ const result = await session.prompt();
668
+ if (!["Y", "y"].includes(result?.trim())) {
669
+ return session.text(".cancelled");
670
+ }
671
+ ctx2.loader.envData.message = {
672
+ ...(0, import_koishi3.pick)(session, ["sid", "channelId", "guildId", "isDirect"]),
673
+ content: session.text(".success")
674
+ };
675
+ await ctx2.installer.install(names.reduce((result2, name2) => {
676
+ result2[name2] = deps[name2].latest;
677
+ return result2;
678
+ }, {}));
679
+ ctx2.loader.envData.message = null;
680
+ return session.text(".success");
681
+ });
682
+ });
683
+ ctx.inject(["console", "installer"], (ctx2) => {
684
+ ctx2.plugin(DependencyProvider);
685
+ ctx2.plugin(RegistryProvider);
686
+ ctx2.plugin(market_default, config.search);
687
+ ctx2.console.addEntry({
688
+ dev: (0, import_path2.resolve)(__dirname, "../../client/index.ts"),
689
+ prod: (0, import_path2.resolve)(__dirname, "../../dist")
690
+ });
691
+ ctx2.console.addListener("market/install", async (deps, forced) => {
692
+ const code = await ctx2.installer.install(deps, forced);
693
+ ctx2.get("console")?.refresh("dependencies");
694
+ ctx2.get("console")?.refresh("registry");
695
+ ctx2.get("console")?.refresh("packages");
696
+ return code;
697
+ }, { authority: 4 });
698
+ ctx2.console.addListener("market/registry", async (names) => {
699
+ const meta = await Promise.all(names.map((name2) => ctx2.installer.getPackage(name2)));
700
+ return Object.fromEntries(meta.map((meta2, index) => [names[index], meta2]));
701
+ }, { authority: 4 });
702
+ });
703
+ }
704
+ __name(apply, "apply");
705
+ // Annotate the CommonJS export names for ESM import in node:
706
+ 0 && (module.exports = {
707
+ Config,
708
+ Installer,
709
+ apply,
710
+ inject,
711
+ name,
712
+ usage,
713
+ ...require("../shared")
714
+ });
715
+ //# sourceMappingURL=index.js.map