forked from cvat-ai/cvat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugins.js
108 lines (91 loc) · 3.96 KB
/
plugins.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright (C) 2019-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
(() => {
const { PluginError } = require('./exceptions');
const plugins = [];
class PluginRegistry {
static async apiWrapper(wrappedFunc, ...args) {
// I have to optimize the wrapper
const pluginList = await PluginRegistry.list();
for (const plugin of pluginList) {
const pluginDecorators = plugin.functions.filter((obj) => obj.callback === wrappedFunc)[0];
if (pluginDecorators && pluginDecorators.enter) {
try {
await pluginDecorators.enter.call(this, plugin, ...args);
} catch (exception) {
if (exception instanceof PluginError) {
throw exception;
} else {
throw new PluginError(`Exception in plugin ${plugin.name}: ${exception.toString()}`);
}
}
}
}
let result = await wrappedFunc.implementation.call(this, ...args);
for (const plugin of pluginList) {
const pluginDecorators = plugin.functions.filter((obj) => obj.callback === wrappedFunc)[0];
if (pluginDecorators && pluginDecorators.leave) {
try {
result = await pluginDecorators.leave.call(this, plugin, result, ...args);
} catch (exception) {
if (exception instanceof PluginError) {
throw exception;
} else {
throw new PluginError(`Exception in plugin ${plugin.name}: ${exception.toString()}`);
}
}
}
}
return result;
}
// Called with cvat context
static async register(plug) {
const functions = [];
if (typeof plug !== 'object') {
throw new PluginError(`Plugin should be an object, but got "${typeof plug}"`);
}
if (!('name' in plug) || typeof plug.name !== 'string') {
throw new PluginError('Plugin must contain a "name" field and it must be a string');
}
if (!('description' in plug) || typeof plug.description !== 'string') {
throw new PluginError('Plugin must contain a "description" field and it must be a string');
}
if ('functions' in plug) {
throw new PluginError('Plugin must not contain a "functions" field');
}
function traverse(plugin, api) {
const decorator = {};
for (const key in plugin) {
if (Object.prototype.hasOwnProperty.call(plugin, key)) {
if (typeof plugin[key] === 'object') {
if (Object.prototype.hasOwnProperty.call(api, key)) {
traverse(plugin[key], api[key]);
}
} else if (
['enter', 'leave'].includes(key) &&
typeof api === 'function' &&
typeof (plugin[key] === 'function')
) {
decorator.callback = api;
decorator[key] = plugin[key];
}
}
}
if (Object.keys(decorator).length) {
functions.push(decorator);
}
}
traverse(plug, { cvat: this });
Object.defineProperty(plug, 'functions', {
value: functions,
writable: false,
});
plugins.push(plug);
}
static async list() {
return plugins;
}
}
module.exports = PluginRegistry;
})();