1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const config_1 = require("@anycli/config");
|
4 | const cli_ux_1 = require("cli-ux");
|
5 | const fs = require("fs-extra");
|
6 | const http_call_1 = require("http-call");
|
7 | const path = require("path");
|
8 | const manifest_1 = require("./manifest");
|
9 | const yarn_1 = require("./yarn");
|
10 | class Plugins {
|
11 | constructor(config) {
|
12 | this.config = config;
|
13 | this.manifest = new manifest_1.default(path.join(this.config.dataDir, 'plugins', 'user.json'));
|
14 | this.yarn = new yarn_1.default({ config, cwd: this.userPluginsDir });
|
15 | this.debug = require('debug')('@anycli/plugins');
|
16 | }
|
17 | async list() {
|
18 | const plugins = await this.manifest.list();
|
19 | return Object.entries(plugins);
|
20 | }
|
21 | async install(name, tag = 'latest') {
|
22 | try {
|
23 | const unfriendly = this.unfriendlyName(name);
|
24 | if (unfriendly) {
|
25 | let version = await this.fetchVersionFromNPM({ name: unfriendly, tag });
|
26 | if (version)
|
27 | name = unfriendly;
|
28 | }
|
29 | await this.createPJSON();
|
30 | await this.yarn.exec(['add', `${name}@${tag}`]);
|
31 | await this.loadPlugin(name, tag);
|
32 |
|
33 | await this.manifest.add(name, tag);
|
34 | }
|
35 | catch (err) {
|
36 | await this.uninstall(name).catch(err => this.debug(err));
|
37 | throw err;
|
38 | }
|
39 | }
|
40 | async uninstall(name) {
|
41 | await this.manifest.remove(name);
|
42 | try {
|
43 | await this.yarn.exec(['remove', name]);
|
44 | }
|
45 | catch (err) {
|
46 | cli_ux_1.cli.warn(err);
|
47 | }
|
48 | }
|
49 | async hasPlugin(name) {
|
50 | const list = await this.list();
|
51 | const plugin = list.find(([n]) => this.friendlyName(n) === this.friendlyName(name));
|
52 | if (plugin)
|
53 | return plugin[0];
|
54 | }
|
55 | unfriendlyName(name) {
|
56 | if (name.includes('@'))
|
57 | return;
|
58 | const defaultScope = this.config.pjson.anycli.pluginScope;
|
59 | if (!defaultScope)
|
60 | return;
|
61 | return `@${defaultScope}/plugin-${name}`;
|
62 | }
|
63 | friendlyName(name) {
|
64 | const defaultScope = this.config.pjson.anycli.pluginScope;
|
65 | if (!defaultScope)
|
66 | return name;
|
67 | const match = name.match(`@${defaultScope}/plugin-(.+)`);
|
68 | if (!match)
|
69 | return name;
|
70 | return match[1];
|
71 | }
|
72 | userPluginPath(name) {
|
73 | return path.join(this.userPluginsDir, 'node_modules', name);
|
74 | }
|
75 | async loadPlugin(name, _) {
|
76 | const config = await config_1.read({ root: this.userPluginPath(name) });
|
77 | return this.config.engine.load(config);
|
78 |
|
79 | }
|
80 | async createPJSON() {
|
81 | if (!await fs.pathExists(this.pjsonPath)) {
|
82 | await fs.outputJSON(this.pjsonPath, { private: true, anycli: { schema: 1 } }, { spaces: 2 });
|
83 | }
|
84 | }
|
85 | get userPluginsDir() {
|
86 | return path.join(this.config.dataDir, 'plugins');
|
87 | }
|
88 | get pjsonPath() {
|
89 | return path.join(this.userPluginsDir, 'package.json');
|
90 | }
|
91 | async fetchVersionFromNPM(plugin) {
|
92 | try {
|
93 | let url = `${this.config.npmRegistry}/-/package/${plugin.name.replace('/', '%2f')}/dist-tags`;
|
94 | const { body: pkg } = await http_call_1.default.get(url);
|
95 | return pkg[plugin.tag];
|
96 | }
|
97 | catch (err) {
|
98 | this.debug(err);
|
99 | }
|
100 | }
|
101 | }
|
102 | exports.default = Plugins;
|