1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.PluginManager = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const plugin_api_1 = require("@remixproject/plugin-api");
|
6 | const abstract_1 = require("./abstract");
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | function catchAllPromises(promises) {
|
12 | return new Promise((res, rej) => {
|
13 | const resolved = [];
|
14 | const rejected = [];
|
15 | let ended = 0;
|
16 | const settle = (value, err) => {
|
17 | if (err)
|
18 | rejected.push(err);
|
19 | if (value)
|
20 | resolved.push(value);
|
21 | if (++ended === promises.length) {
|
22 | rejected.length ? rej(resolved) : res(rejected);
|
23 | }
|
24 | };
|
25 | for (const promise of promises) {
|
26 | promise
|
27 | .then(value => settle(value, null))
|
28 | .catch(err => settle(null, err));
|
29 | }
|
30 | });
|
31 | }
|
32 | class PluginManager extends abstract_1.Plugin {
|
33 | constructor(profile = plugin_api_1.pluginManagerProfile) {
|
34 | super(profile);
|
35 | this.profiles = {};
|
36 | this.actives = [];
|
37 | }
|
38 |
|
39 | get requestFrom() {
|
40 | var _a;
|
41 | return ((_a = this.currentRequest) === null || _a === void 0 ? void 0 : _a.from) || 'manager';
|
42 | }
|
43 |
|
44 | engineActivatePlugin(name) {
|
45 | const error = `You cannot activate plugin "${name}", manager plugin is not register yet. `;
|
46 | const solution = 'Run "engine.register(manager)" first';
|
47 | throw new Error(error + solution);
|
48 | }
|
49 |
|
50 | engineDeactivatePlugin(name) {
|
51 | const error = `You cannot deactivate plugin "${name}", manager plugin is not register yet. `;
|
52 | const solution = 'Run "engine.register(manager)" first';
|
53 | throw new Error(error + solution);
|
54 | }
|
55 | |
56 |
|
57 |
|
58 |
|
59 |
|
60 | getProfile(name) {
|
61 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
62 | return this.profiles[name];
|
63 | });
|
64 | }
|
65 |
|
66 | getProfiles() {
|
67 | return Object.values(this.profiles);
|
68 | }
|
69 |
|
70 | getActiveProfiles() {
|
71 | return this.actives.map(name => this.profiles[name]);
|
72 | }
|
73 | |
74 |
|
75 |
|
76 |
|
77 |
|
78 | updateProfile(to) {
|
79 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
80 | if (!to)
|
81 | return;
|
82 | if (!this.profiles[to.name]) {
|
83 | throw new Error(`Plugin ${to.name} is not register, you cannot update it's profile.`);
|
84 | }
|
85 | const from = yield this.getProfile(this.requestFrom);
|
86 | yield this.canUpdateProfile(from, to);
|
87 | this.profiles[to.name] = Object.assign(Object.assign({}, this.profiles[to.name]), to);
|
88 | this.emit('profileUpdated', this.profiles[to.name]);
|
89 | });
|
90 | }
|
91 | |
92 |
|
93 |
|
94 |
|
95 |
|
96 | addProfile(profiles) {
|
97 | const add = (profile) => {
|
98 | if (this.profiles[profile.name]) {
|
99 | throw new Error(`Plugin ${profile.name} already exist`);
|
100 | }
|
101 | this.profiles[profile.name] = profile;
|
102 |
|
103 | if (this.actives.includes('manager')) {
|
104 | this.emit('profileAdded', profile);
|
105 | }
|
106 | if (this.onProfileAdded) {
|
107 | this.onProfileAdded(profile);
|
108 | }
|
109 | };
|
110 | return Array.isArray(profiles) ? profiles.map(add) : add(profiles);
|
111 | }
|
112 | |
113 |
|
114 |
|
115 |
|
116 | isActive(name) {
|
117 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
118 | return this.actives.includes(name);
|
119 | });
|
120 | }
|
121 | |
122 |
|
123 |
|
124 |
|
125 | activatePlugin(names) {
|
126 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
127 | if (!this.actives.includes('manager')) {
|
128 | yield this.toggleActive('manager');
|
129 | }
|
130 | const activate = (name) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
131 | const isActive = yield this.isActive(name);
|
132 | if (isActive)
|
133 | return;
|
134 | const [to, from] = yield Promise.all([
|
135 | this.getProfile(name),
|
136 | this.getProfile(this.requestFrom)
|
137 | ]);
|
138 | const canActivate = yield this.canActivatePlugin(from, to);
|
139 | if (canActivate) {
|
140 | yield this.toggleActive(name);
|
141 | }
|
142 | else {
|
143 | throw new Error(`Plugin ${this.requestFrom} has no right to activate plugin ${name}`);
|
144 | }
|
145 | });
|
146 | return Array.isArray(names) ? catchAllPromises(names.map(activate)) : activate(names);
|
147 | });
|
148 | }
|
149 | |
150 |
|
151 |
|
152 |
|
153 | deactivatePlugin(names) {
|
154 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
155 | const deactivate = (name) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
156 | const isActive = yield this.isActive(name);
|
157 | if (!isActive)
|
158 | return;
|
159 | const [to, from] = yield Promise.all([
|
160 | this.getProfile(name),
|
161 | this.getProfile(this.requestFrom)
|
162 | ]);
|
163 |
|
164 | if (from.name === 'manager') {
|
165 | return this.toggleActive(name);
|
166 | }
|
167 |
|
168 | const managerCanDeactivate = yield this.canDeactivatePlugin(from, to);
|
169 | if (!managerCanDeactivate) {
|
170 | throw new Error(`Plugin ${this.requestFrom} has no right to deactivate plugin ${name}`);
|
171 | }
|
172 |
|
173 | const pluginCanDeactivate = from.name !== to.name ? yield this.call(to.name, 'canDeactivate', from) : true;
|
174 | if (!pluginCanDeactivate) {
|
175 | throw new Error(`Plugin ${this.requestFrom} has no right to deactivate plugin ${name}`);
|
176 | }
|
177 | return this.toggleActive(name);
|
178 | });
|
179 | return Array.isArray(names) ? catchAllPromises(names.map(deactivate)) : deactivate(names);
|
180 | });
|
181 | }
|
182 | |
183 |
|
184 |
|
185 |
|
186 |
|
187 | toggleActive(names) {
|
188 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
189 | const toggle = (name) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
190 | const [isActive, profile] = yield Promise.all([
|
191 | this.isActive(name),
|
192 | this.getProfile(name)
|
193 | ]);
|
194 | if (isActive) {
|
195 | yield this.engineDeactivatePlugin(name);
|
196 | this.actives = this.actives.filter(pluginName => pluginName !== name);
|
197 | this.emit('pluginDeactivated', profile);
|
198 | if (this.onPluginDeactivated) {
|
199 | this.onPluginDeactivated(profile);
|
200 | }
|
201 | }
|
202 | else {
|
203 | yield this.engineActivatePlugin(name);
|
204 | this.actives.push(name);
|
205 | this.emit('pluginActivated', profile);
|
206 | if (this.onPluginActivated) {
|
207 | this.onPluginActivated(profile);
|
208 | }
|
209 | }
|
210 | });
|
211 | return Array.isArray(names) ? Promise.all(names.map(toggle)) : toggle(names);
|
212 | });
|
213 | }
|
214 | |
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 | canActivatePlugin(from, to) {
|
221 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
222 | return true;
|
223 | });
|
224 | }
|
225 | |
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 | canDeactivatePlugin(from, to) {
|
232 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
233 | if (from.name === 'manager' || from.name === to.name) {
|
234 | return true;
|
235 | }
|
236 | return false;
|
237 | });
|
238 | }
|
239 | |
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 | canCall(from, to, method, message) {
|
247 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
248 | return true;
|
249 | });
|
250 | }
|
251 | |
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 | canUpdateProfile(from, to) {
|
258 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
259 | if (to.name && from.name !== to.name) {
|
260 | throw new Error('A plugin cannot change its name.');
|
261 | }
|
262 | if (to['url'] && to['url'] !== this.profiles[to.name]['url']) {
|
263 | throw new Error('Url from Profile cannot be updated.');
|
264 | }
|
265 | return true;
|
266 | });
|
267 | }
|
268 | }
|
269 | exports.PluginManager = PluginManager;
|
270 |
|
\ | No newline at end of file |