@oas-tools/oas-telemetry 0.7.0-alpha.2 → 0.7.0-alpha.4
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.
- package/.env.example +50 -17
- package/README.md +244 -239
- package/dist/cjs/config/bootConfig.cjs +18 -0
- package/dist/cjs/config/config.cjs +145 -0
- package/dist/cjs/config/config.types.cjs +5 -0
- package/dist/cjs/index.cjs +19 -25
- package/dist/cjs/{tlmRoutes.cjs → routesManager.cjs} +28 -21
- package/dist/cjs/{exporters/InMemoryLogRecordExporter.cjs → telemetry/custom-implementations/exporters/InMemoryDbLogExporter.cjs} +42 -19
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.cjs +97 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.cjs +118 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/PluginLogExporter.cjs +45 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/PluginMetricExporter.cjs +46 -0
- package/dist/cjs/telemetry/custom-implementations/exporters/PluginSpanExporter.cjs +61 -0
- package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.cjs +70 -0
- package/dist/cjs/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.cjs +70 -0
- package/dist/cjs/{utils → telemetry/custom-implementations/utils}/circular.cjs +39 -49
- package/dist/cjs/telemetry/custom-implementations/wrappers.cjs +175 -0
- package/dist/cjs/telemetry/initializeTelemetry.cjs +74 -0
- package/dist/cjs/telemetry/telemetryConfigurator.cjs +84 -0
- package/dist/cjs/telemetry/telemetryRegistry.cjs +40 -0
- package/dist/cjs/tlm-ai/agent.cjs +82 -63
- package/dist/cjs/tlm-ai/aiController.cjs +5 -4
- package/dist/cjs/tlm-ai/aiRoutes.cjs +9 -6
- package/dist/cjs/tlm-ai/tools.cjs +16 -9
- package/dist/cjs/tlm-auth/authController.cjs +14 -15
- package/dist/cjs/tlm-auth/authMiddleware.cjs +11 -10
- package/dist/cjs/tlm-auth/authRoutes.cjs +9 -7
- package/dist/cjs/tlm-log/logController.cjs +45 -18
- package/dist/cjs/tlm-log/logRoutes.cjs +16 -11
- package/dist/cjs/tlm-metric/metricsController.cjs +37 -12
- package/dist/cjs/tlm-metric/metricsRoutes.cjs +16 -11
- package/dist/cjs/tlm-plugin/pluginController.cjs +114 -75
- package/dist/cjs/tlm-plugin/pluginProcess.cjs +108 -0
- package/dist/cjs/tlm-plugin/pluginRoutes.cjs +11 -6
- package/dist/cjs/tlm-plugin/pluginService.cjs +79 -0
- package/dist/cjs/tlm-trace/traceController.cjs +54 -45
- package/dist/cjs/tlm-trace/traceRoutes.cjs +16 -11
- package/dist/cjs/tlm-ui/uiRoutes.cjs +26 -20
- package/dist/cjs/tlm-util/utilController.cjs +8 -9
- package/dist/cjs/tlm-util/utilRoutes.cjs +22 -19
- package/dist/cjs/types/index.cjs +0 -1
- package/dist/cjs/utils/logger.cjs +3 -5
- package/dist/cjs/utils/regexUtils.cjs +27 -0
- package/dist/esm/config/bootConfig.js +11 -0
- package/dist/esm/config/config.js +126 -0
- package/dist/esm/index.js +18 -29
- package/dist/esm/{tlmRoutes.js → routesManager.js} +27 -22
- package/dist/esm/{exporters/InMemoryLogRecordExporter.js → telemetry/custom-implementations/exporters/InMemoryDbLogExporter.js} +31 -17
- package/dist/esm/{exporters/InMemoryDBMetricsExporter.js → telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.js} +31 -17
- package/dist/esm/telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.js +105 -0
- package/dist/esm/telemetry/custom-implementations/exporters/PluginLogExporter.js +36 -0
- package/dist/esm/telemetry/custom-implementations/exporters/PluginMetricExporter.js +35 -0
- package/dist/esm/telemetry/custom-implementations/exporters/PluginSpanExporter.js +52 -0
- package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.js +64 -0
- package/dist/esm/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.js +64 -0
- package/dist/esm/telemetry/custom-implementations/utils/circular.js +76 -0
- package/dist/esm/telemetry/custom-implementations/wrappers.js +163 -0
- package/dist/esm/telemetry/initializeTelemetry.js +71 -0
- package/dist/esm/telemetry/telemetryConfigurator.js +74 -0
- package/dist/esm/telemetry/telemetryRegistry.js +34 -0
- package/dist/esm/tlm-ai/agent.js +77 -59
- package/dist/esm/tlm-ai/aiController.js +5 -4
- package/dist/esm/tlm-ai/aiRoutes.js +7 -5
- package/dist/esm/tlm-ai/tools.js +18 -9
- package/dist/esm/tlm-auth/authController.js +9 -10
- package/dist/esm/tlm-auth/authMiddleware.js +10 -9
- package/dist/esm/tlm-auth/authRoutes.js +8 -6
- package/dist/esm/tlm-log/logController.js +36 -16
- package/dist/esm/tlm-log/logRoutes.js +15 -11
- package/dist/esm/tlm-metric/metricsController.js +29 -10
- package/dist/esm/tlm-metric/metricsRoutes.js +15 -11
- package/dist/esm/tlm-plugin/pluginController.js +112 -77
- package/dist/esm/tlm-plugin/pluginProcess.js +101 -0
- package/dist/esm/tlm-plugin/pluginRoutes.js +10 -6
- package/dist/esm/tlm-plugin/pluginService.js +73 -0
- package/dist/esm/tlm-trace/traceController.js +40 -35
- package/dist/esm/tlm-trace/traceRoutes.js +15 -11
- package/dist/esm/tlm-ui/uiRoutes.js +24 -19
- package/dist/esm/tlm-util/utilController.js +8 -9
- package/dist/esm/tlm-util/utilRoutes.js +17 -15
- package/dist/esm/types/index.js +0 -1
- package/dist/esm/utils/logger.js +3 -4
- package/dist/esm/utils/regexUtils.js +23 -0
- package/dist/types/config/bootConfig.d.ts +5 -0
- package/dist/types/config/config.d.ts +858 -0
- package/dist/types/config/config.types.d.ts +34 -0
- package/dist/types/index.d.ts +5 -4
- package/dist/types/routesManager.d.ts +3 -0
- package/dist/types/{exporters/InMemoryLogRecordExporter.d.ts → telemetry/custom-implementations/exporters/InMemoryDbLogExporter.d.ts} +6 -6
- package/dist/types/{exporters/InMemoryDBMetricsExporter.d.ts → telemetry/custom-implementations/exporters/InMemoryDbMetricExporter.d.ts} +7 -7
- package/dist/types/{exporters/InMemoryDbExporter.d.ts → telemetry/custom-implementations/exporters/InMemoryDbSpanExporter.d.ts} +9 -9
- package/dist/types/telemetry/custom-implementations/exporters/PluginLogExporter.d.ts +8 -0
- package/dist/types/telemetry/custom-implementations/exporters/PluginMetricExporter.d.ts +12 -0
- package/dist/types/telemetry/custom-implementations/exporters/PluginSpanExporter.d.ts +14 -0
- package/dist/types/telemetry/custom-implementations/processors/dynamicMultiLogProcessor.d.ts +32 -0
- package/dist/types/telemetry/custom-implementations/processors/dynamicMultiSpanProcessor.d.ts +34 -0
- package/dist/types/telemetry/custom-implementations/utils/circular.d.ts +27 -0
- package/dist/types/telemetry/custom-implementations/wrappers.d.ts +52 -0
- package/dist/types/telemetry/initializeTelemetry.d.ts +1 -0
- package/dist/types/telemetry/telemetryConfigurator.d.ts +2 -0
- package/dist/types/telemetry/telemetryRegistry.d.ts +20 -0
- package/dist/types/tlm-ai/agent.d.ts +2 -1
- package/dist/types/tlm-ai/aiController.d.ts +4 -3
- package/dist/types/tlm-ai/aiRoutes.d.ts +2 -2
- package/dist/types/tlm-ai/tools.d.ts +3 -1
- package/dist/types/tlm-auth/authController.d.ts +4 -3
- package/dist/types/tlm-auth/authMiddleware.d.ts +2 -1
- package/dist/types/tlm-auth/authRoutes.d.ts +2 -2
- package/dist/types/tlm-log/logController.d.ts +1 -0
- package/dist/types/tlm-log/logRoutes.d.ts +2 -2
- package/dist/types/tlm-metric/metricsController.d.ts +1 -0
- package/dist/types/tlm-metric/metricsRoutes.d.ts +2 -2
- package/dist/types/tlm-plugin/pluginController.d.ts +4 -1
- package/dist/types/tlm-plugin/pluginProcess.d.ts +1 -0
- package/dist/types/tlm-plugin/pluginRoutes.d.ts +1 -2
- package/dist/types/tlm-plugin/pluginService.d.ts +24 -0
- package/dist/types/tlm-trace/traceController.d.ts +7 -6
- package/dist/types/tlm-trace/traceRoutes.d.ts +2 -2
- package/dist/types/tlm-ui/uiRoutes.d.ts +1 -2
- package/dist/types/tlm-util/utilController.d.ts +2 -1
- package/dist/types/tlm-util/utilRoutes.d.ts +2 -2
- package/dist/types/types/index.d.ts +17 -47
- package/dist/types/utils/regexUtils.d.ts +1 -0
- package/dist/ui/assets/index-BzIdRox6.js +1733 -0
- package/dist/ui/assets/index-CkoHzrrt.css +1 -0
- package/dist/ui/index.html +3 -3
- package/dist/ui/oas-tlm.svg +185 -0
- package/package.json +12 -7
- package/dist/cjs/config.cjs +0 -31
- package/dist/cjs/exporters/InMemoryDBMetricsExporter.cjs +0 -74
- package/dist/cjs/exporters/InMemoryDbExporter.cjs +0 -102
- package/dist/cjs/exporters/consoleExporter.cjs +0 -47
- package/dist/cjs/exporters/dynamicExporter.cjs +0 -57
- package/dist/cjs/instrumentation/index.cjs +0 -28
- package/dist/cjs/instrumentation/logs.cjs +0 -46
- package/dist/cjs/instrumentation/metrics.cjs +0 -27
- package/dist/cjs/instrumentation/traces.cjs +0 -19
- package/dist/esm/config.js +0 -20
- package/dist/esm/exporters/InMemoryDbExporter.js +0 -102
- package/dist/esm/exporters/consoleExporter.js +0 -38
- package/dist/esm/exporters/dynamicExporter.js +0 -50
- package/dist/esm/instrumentation/index.js +0 -26
- package/dist/esm/instrumentation/logs.js +0 -34
- package/dist/esm/instrumentation/metrics.js +0 -18
- package/dist/esm/instrumentation/traces.js +0 -12
- package/dist/esm/utils/circular.js +0 -84
- package/dist/types/config.d.ts +0 -6
- package/dist/types/exporters/consoleExporter.d.ts +0 -13
- package/dist/types/exporters/dynamicExporter.d.ts +0 -25
- package/dist/types/instrumentation/logs.d.ts +0 -1
- package/dist/types/instrumentation/metrics.d.ts +0 -1
- package/dist/types/instrumentation/traces.d.ts +0 -1
- package/dist/types/tlmRoutes.d.ts +0 -2
- package/dist/types/utils/circular.d.ts +0 -31
- package/dist/ui/assets/index-BNhZBPi2.css +0 -1
- package/dist/ui/assets/index-DxGAMrAl.js +0 -401
- package/dist/ui/vite.svg +0 -1
- /package/dist/{types/instrumentation/index.d.ts → esm/config/config.types.js} +0 -0
|
@@ -3,20 +3,23 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.stopLogs = exports.statusLogs = exports.startLogs = exports.resetLogs = exports.listLogs = exports.insertLogsToDb = exports.findLogs = void 0;
|
|
7
|
-
var
|
|
6
|
+
exports.stopLogs = exports.statusLogs = exports.startLogs = exports.setRetentionTimeLogs = exports.resetLogs = exports.listLogs = exports.insertLogsToDb = exports.findLogs = void 0;
|
|
7
|
+
var _telemetryRegistry = require("../telemetry/telemetryRegistry.cjs");
|
|
8
|
+
var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
|
|
9
|
+
var _regexUtils = require("../utils/regexUtils.cjs");
|
|
8
10
|
const _excluded = ["_id"];
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
12
|
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
10
13
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
11
14
|
const listLogs = async (req, res) => {
|
|
12
15
|
try {
|
|
13
|
-
const logs =
|
|
16
|
+
const logs = _telemetryRegistry.inMemoryDbLogExporter.getFinishedLogs();
|
|
14
17
|
res.send({
|
|
15
18
|
logsCount: logs.length,
|
|
16
19
|
logs: logs
|
|
17
20
|
});
|
|
18
21
|
} catch (err) {
|
|
19
|
-
|
|
22
|
+
_logger.default.error(err);
|
|
20
23
|
res.status(500).send({
|
|
21
24
|
error: 'Failed to list log data'
|
|
22
25
|
});
|
|
@@ -25,14 +28,24 @@ const listLogs = async (req, res) => {
|
|
|
25
28
|
exports.listLogs = listLogs;
|
|
26
29
|
const findLogs = async (req, res) => {
|
|
27
30
|
const body = req.body;
|
|
28
|
-
const messageSearch = body?.
|
|
29
|
-
const findQuery = body?.
|
|
30
|
-
|
|
31
|
+
const messageSearch = body?.textSearch || null; // Search term for MiniSearch
|
|
32
|
+
const findQuery = body?.query || {}; // Query for NeDB
|
|
33
|
+
_logger.default.debug(`findLogs called with query: ${JSON.stringify(findQuery)} and search ${messageSearch}`, {
|
|
31
34
|
depth: 3
|
|
32
35
|
});
|
|
36
|
+
let processedQuery;
|
|
37
|
+
try {
|
|
38
|
+
processedQuery = (0, _regexUtils.convertRegexRecursively)(findQuery);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
_logger.default.error(error.message);
|
|
41
|
+
res.status(400).send({
|
|
42
|
+
error: error.message
|
|
43
|
+
});
|
|
44
|
+
return; // Exit if invalid regex was encountered
|
|
45
|
+
}
|
|
33
46
|
try {
|
|
34
47
|
const results = await new Promise((resolve, reject) => {
|
|
35
|
-
|
|
48
|
+
_telemetryRegistry.inMemoryDbLogExporter.find(processedQuery, messageSearch, (err, docs) => {
|
|
36
49
|
if (err) return reject(err);
|
|
37
50
|
resolve(docs);
|
|
38
51
|
});
|
|
@@ -43,7 +56,7 @@ const findLogs = async (req, res) => {
|
|
|
43
56
|
logs: typedResults
|
|
44
57
|
});
|
|
45
58
|
} catch (err) {
|
|
46
|
-
|
|
59
|
+
_logger.default.error(err);
|
|
47
60
|
res.status(500).send({
|
|
48
61
|
error: 'Failed to find logs',
|
|
49
62
|
details: err.message
|
|
@@ -52,7 +65,7 @@ const findLogs = async (req, res) => {
|
|
|
52
65
|
};
|
|
53
66
|
exports.findLogs = findLogs;
|
|
54
67
|
const resetLogs = (req, res) => {
|
|
55
|
-
|
|
68
|
+
_telemetryRegistry.inMemoryDbLogExporter.reset();
|
|
56
69
|
res.send('Logs reset');
|
|
57
70
|
};
|
|
58
71
|
exports.resetLogs = resetLogs;
|
|
@@ -76,13 +89,13 @@ const insertLogsToDb = async (req, res) => {
|
|
|
76
89
|
try {
|
|
77
90
|
let message = '';
|
|
78
91
|
if (resetData) {
|
|
79
|
-
|
|
92
|
+
_telemetryRegistry.inMemoryDbLogExporter.reset();
|
|
80
93
|
message += 'Logs Database reset. ';
|
|
81
94
|
}
|
|
82
95
|
await new Promise((resolve, reject) => {
|
|
83
|
-
|
|
96
|
+
_telemetryRegistry.inMemoryDbLogExporter.insert(cleanedLogs, (err, newDocs) => {
|
|
84
97
|
if (err) {
|
|
85
|
-
|
|
98
|
+
_logger.default.error('Error inserting logs:', err);
|
|
86
99
|
return reject(err);
|
|
87
100
|
}
|
|
88
101
|
resolve(newDocs);
|
|
@@ -94,7 +107,7 @@ const insertLogsToDb = async (req, res) => {
|
|
|
94
107
|
InsertedLogsCount: cleanedLogs.length
|
|
95
108
|
});
|
|
96
109
|
} catch (err) {
|
|
97
|
-
|
|
110
|
+
_logger.default.error(err);
|
|
98
111
|
res.status(500).send({
|
|
99
112
|
error: 'Failed to reset and insert data',
|
|
100
113
|
details: err.message
|
|
@@ -103,19 +116,33 @@ const insertLogsToDb = async (req, res) => {
|
|
|
103
116
|
};
|
|
104
117
|
exports.insertLogsToDb = insertLogsToDb;
|
|
105
118
|
const startLogs = (req, res) => {
|
|
106
|
-
|
|
119
|
+
_telemetryRegistry.inMemoryDbLogExporter.enable();
|
|
107
120
|
res.send('Log collection started');
|
|
108
121
|
};
|
|
109
122
|
exports.startLogs = startLogs;
|
|
110
123
|
const stopLogs = (req, res) => {
|
|
111
|
-
|
|
124
|
+
_telemetryRegistry.inMemoryDbLogExporter.disable();
|
|
112
125
|
res.send('Log collection stopped');
|
|
113
126
|
};
|
|
114
127
|
exports.stopLogs = stopLogs;
|
|
115
128
|
const statusLogs = (req, res) => {
|
|
116
|
-
const isRunning =
|
|
129
|
+
const isRunning = _telemetryRegistry.inMemoryDbLogExporter.isEnabled() || false;
|
|
117
130
|
res.send({
|
|
118
131
|
active: isRunning
|
|
119
132
|
});
|
|
120
133
|
};
|
|
121
|
-
exports.statusLogs = statusLogs;
|
|
134
|
+
exports.statusLogs = statusLogs;
|
|
135
|
+
const setRetentionTimeLogs = (req, res) => {
|
|
136
|
+
const retentionTime = req.body.retentionTime;
|
|
137
|
+
if (typeof retentionTime !== 'number' || retentionTime <= 0) {
|
|
138
|
+
res.status(400).send({
|
|
139
|
+
error: 'Invalid retention time. Must be a positive number.'
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
_telemetryRegistry.inMemoryDbLogExporter.retentionTimeInSeconds = retentionTime;
|
|
144
|
+
res.send({
|
|
145
|
+
message: `Retention time set to ${retentionTime} seconds.`
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
exports.setRetentionTimeLogs = setRetentionTimeLogs;
|
|
@@ -3,16 +3,21 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.getLogRoutes = exports.default = void 0;
|
|
7
7
|
var _express = require("express");
|
|
8
8
|
var _logController = require("./logController.cjs");
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
const getLogRoutes = () => {
|
|
10
|
+
const router = (0, _express.Router)();
|
|
11
|
+
// Logs Control
|
|
12
|
+
router.post('/start', _logController.startLogs);
|
|
13
|
+
router.post('/stop', _logController.stopLogs);
|
|
14
|
+
router.get('/status', _logController.statusLogs);
|
|
15
|
+
router.post('/reset', _logController.resetLogs);
|
|
16
|
+
router.post('/retention-time', _logController.setRetentionTimeLogs);
|
|
17
|
+
router.get('/', _logController.listLogs);
|
|
18
|
+
router.post('/', _logController.insertLogsToDb);
|
|
19
|
+
router.post('/find', _logController.findLogs);
|
|
20
|
+
return router;
|
|
21
|
+
};
|
|
22
|
+
exports.getLogRoutes = getLogRoutes;
|
|
23
|
+
var _default = exports.default = getLogRoutes;
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.stopMetrics = exports.statusMetrics = exports.startMetrics = exports.resetMetrics = exports.listMetrics = exports.insertMetricsToDb = exports.findMetrics = void 0;
|
|
7
|
-
var
|
|
6
|
+
exports.stopMetrics = exports.statusMetrics = exports.startMetrics = exports.setRetentionTimeMetrics = exports.resetMetrics = exports.listMetrics = exports.insertMetricsToDb = exports.findMetrics = void 0;
|
|
7
|
+
var _telemetryRegistry = require("../telemetry/telemetryRegistry.cjs");
|
|
8
|
+
var _regexUtils = require("../utils/regexUtils.cjs");
|
|
8
9
|
const _excluded = ["_id"];
|
|
9
10
|
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
10
11
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
11
12
|
const listMetrics = async (req, res) => {
|
|
12
13
|
try {
|
|
13
|
-
const metrics =
|
|
14
|
+
const metrics = _telemetryRegistry.inMemoryDbMetricExporter.getFinishedMetrics();
|
|
14
15
|
res.send({
|
|
15
16
|
metricsCount: metrics.length,
|
|
16
17
|
metrics: metrics
|
|
@@ -25,8 +26,18 @@ const listMetrics = async (req, res) => {
|
|
|
25
26
|
exports.listMetrics = listMetrics;
|
|
26
27
|
const findMetrics = (req, res) => {
|
|
27
28
|
const body = req.body;
|
|
28
|
-
const
|
|
29
|
-
|
|
29
|
+
const query = body?.query ? body.query : {};
|
|
30
|
+
let processedQuery;
|
|
31
|
+
try {
|
|
32
|
+
processedQuery = (0, _regexUtils.convertRegexRecursively)(query);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error(error.message);
|
|
35
|
+
res.status(400).send({
|
|
36
|
+
error: error.message
|
|
37
|
+
});
|
|
38
|
+
return; // Exit if invalid regex was encountered
|
|
39
|
+
}
|
|
40
|
+
_telemetryRegistry.inMemoryDbMetricExporter.find(processedQuery, (err, docs) => {
|
|
30
41
|
if (err) {
|
|
31
42
|
console.error(err);
|
|
32
43
|
res.status(404).send({
|
|
@@ -45,7 +56,7 @@ const findMetrics = (req, res) => {
|
|
|
45
56
|
};
|
|
46
57
|
exports.findMetrics = findMetrics;
|
|
47
58
|
const resetMetrics = (req, res) => {
|
|
48
|
-
|
|
59
|
+
_telemetryRegistry.inMemoryDbMetricExporter.reset();
|
|
49
60
|
res.send('Metrics reset');
|
|
50
61
|
};
|
|
51
62
|
exports.resetMetrics = resetMetrics;
|
|
@@ -69,11 +80,11 @@ const insertMetricsToDb = async (req, res) => {
|
|
|
69
80
|
try {
|
|
70
81
|
let message = '';
|
|
71
82
|
if (resetData) {
|
|
72
|
-
|
|
83
|
+
_telemetryRegistry.inMemoryDbMetricExporter.reset();
|
|
73
84
|
message += 'Metrics Database reset. ';
|
|
74
85
|
}
|
|
75
86
|
await new Promise((resolve, reject) => {
|
|
76
|
-
|
|
87
|
+
_telemetryRegistry.inMemoryDbMetricExporter.insert(cleanedMetrics, (err, newDocs) => {
|
|
77
88
|
if (err) {
|
|
78
89
|
console.error('Error inserting metrics:', err);
|
|
79
90
|
return reject(err);
|
|
@@ -96,19 +107,33 @@ const insertMetricsToDb = async (req, res) => {
|
|
|
96
107
|
};
|
|
97
108
|
exports.insertMetricsToDb = insertMetricsToDb;
|
|
98
109
|
const startMetrics = (req, res) => {
|
|
99
|
-
|
|
110
|
+
_telemetryRegistry.inMemoryDbMetricExporter.enable();
|
|
100
111
|
res.send('Metrics collection started');
|
|
101
112
|
};
|
|
102
113
|
exports.startMetrics = startMetrics;
|
|
103
114
|
const stopMetrics = (req, res) => {
|
|
104
|
-
|
|
115
|
+
_telemetryRegistry.inMemoryDbMetricExporter.disable();
|
|
105
116
|
res.send('Metrics collection stopped');
|
|
106
117
|
};
|
|
107
118
|
exports.stopMetrics = stopMetrics;
|
|
108
119
|
const statusMetrics = (req, res) => {
|
|
109
|
-
const isRunning =
|
|
120
|
+
const isRunning = _telemetryRegistry.inMemoryDbMetricExporter.isEnabled() || false;
|
|
110
121
|
res.send({
|
|
111
122
|
active: isRunning
|
|
112
123
|
});
|
|
113
124
|
};
|
|
114
|
-
exports.statusMetrics = statusMetrics;
|
|
125
|
+
exports.statusMetrics = statusMetrics;
|
|
126
|
+
const setRetentionTimeMetrics = (req, res) => {
|
|
127
|
+
const retentionTime = req.body.retentionTime;
|
|
128
|
+
if (typeof retentionTime !== 'number' || retentionTime <= 0) {
|
|
129
|
+
res.status(400).send({
|
|
130
|
+
error: 'Invalid retention time. Must be a positive number.'
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
_telemetryRegistry.inMemoryDbMetricExporter.retentionTimeInSeconds = retentionTime;
|
|
135
|
+
res.send({
|
|
136
|
+
message: `Retention time set to ${retentionTime} seconds.`
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
exports.setRetentionTimeMetrics = setRetentionTimeMetrics;
|
|
@@ -3,16 +3,21 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.getMetricsRoutes = exports.default = void 0;
|
|
7
7
|
var _express = require("express");
|
|
8
8
|
var _metricsController = require("./metricsController.cjs");
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
const getMetricsRoutes = () => {
|
|
10
|
+
const router = (0, _express.Router)();
|
|
11
|
+
// Metrics Control
|
|
12
|
+
router.post('/start', _metricsController.startMetrics);
|
|
13
|
+
router.post('/stop', _metricsController.stopMetrics);
|
|
14
|
+
router.get('/status', _metricsController.statusMetrics);
|
|
15
|
+
router.post('/reset', _metricsController.resetMetrics);
|
|
16
|
+
router.post('/retention-time', _metricsController.setRetentionTimeMetrics);
|
|
17
|
+
router.get('/', _metricsController.listMetrics);
|
|
18
|
+
router.post('/', _metricsController.insertMetricsToDb);
|
|
19
|
+
router.post('/find', _metricsController.findMetrics);
|
|
20
|
+
return router;
|
|
21
|
+
};
|
|
22
|
+
exports.getMetricsRoutes = getMetricsRoutes;
|
|
23
|
+
var _default = exports.default = getMetricsRoutes;
|
|
@@ -3,106 +3,145 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.registerPlugin = exports.listPlugins = void 0;
|
|
7
|
-
var _config = require("../config.cjs");
|
|
6
|
+
exports.registerPlugin = exports.listPlugins = exports.deletePlugin = exports.deactivatePlugin = exports.activatePlugin = void 0;
|
|
8
7
|
var _axios = _interopRequireDefault(require("axios"));
|
|
9
|
-
var
|
|
10
|
-
var
|
|
8
|
+
var _child_process = require("child_process");
|
|
9
|
+
var _path = _interopRequireDefault(require("path"));
|
|
11
10
|
var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
|
|
11
|
+
var _pluginService = require("./pluginService.cjs");
|
|
12
|
+
var _url = require("url");
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
-
// @ts-expect-error: import-from-string does not have proper type declarations
|
|
14
|
-
|
|
15
|
-
// @ts-expect-error: dynamic-installer does not have proper type declarations
|
|
16
|
-
|
|
17
14
|
const listPlugins = (req, res) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
active: plugin.active
|
|
24
|
-
};
|
|
25
|
-
}));
|
|
15
|
+
const plugins = _pluginService.pluginService.getPlugins();
|
|
16
|
+
res.send({
|
|
17
|
+
pluginsCount: plugins.length,
|
|
18
|
+
plugins
|
|
19
|
+
});
|
|
26
20
|
};
|
|
27
21
|
exports.listPlugins = listPlugins;
|
|
28
22
|
const registerPlugin = async (req, res) => {
|
|
29
23
|
const pluginResource = req.body;
|
|
30
|
-
_logger.default.
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
_logger.default.debug(`Plugin Registration Request: ${JSON.stringify(req.body, null, 2)}...`);
|
|
25
|
+
// Validate id
|
|
26
|
+
if (!pluginResource.id || typeof pluginResource.id !== "string") {
|
|
27
|
+
res.status(400).send("Plugin id must be provided and must be a string");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Check duplicate
|
|
31
|
+
if (_pluginService.pluginService.getPlugins().find(p => p.id === pluginResource.id)) {
|
|
32
|
+
res.status(400).send(`Plugin with id "${pluginResource.id}" already exists.`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Validate inputs
|
|
33
36
|
if (!pluginResource.url && !pluginResource.code) {
|
|
34
|
-
res.status(400).send(
|
|
37
|
+
res.status(400).send("Plugin code or URL must be provided");
|
|
35
38
|
return;
|
|
36
39
|
}
|
|
37
|
-
|
|
40
|
+
if (!pluginResource.moduleFormat) {
|
|
41
|
+
res.status(400).send("Plugin moduleFormat must be provided (cjs|esm)");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Fetch code
|
|
45
|
+
let pluginCode;
|
|
38
46
|
try {
|
|
39
47
|
if (pluginResource.code) {
|
|
40
48
|
pluginCode = pluginResource.code;
|
|
41
49
|
} else {
|
|
50
|
+
console.log(pluginResource.url);
|
|
42
51
|
const response = await _axios.default.get(pluginResource.url);
|
|
43
52
|
pluginCode = response.data;
|
|
44
53
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
if (pluginResource.install) {
|
|
50
|
-
const dependenciesStatus = await (0, _dynamicInstaller.installDependencies)(pluginResource.install);
|
|
51
|
-
if (!dependenciesStatus.success) {
|
|
52
|
-
if (pluginResource.install.ignoreErrors === true) {
|
|
53
|
-
_logger.default.warn(`Warning: Error installing dependencies: ${JSON.stringify(dependenciesStatus.details)}`);
|
|
54
|
-
} else {
|
|
55
|
-
res.status(400).send(`Error installing dependencies: ${JSON.stringify(dependenciesStatus.details)}`);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
_logger.default.info("Plugin size: " + pluginCode?.length);
|
|
61
|
-
_logger.default.info("Plugin format: " + pluginResource?.moduleFormat);
|
|
62
|
-
if (pluginResource?.moduleFormat && pluginResource.moduleFormat.toUpperCase() == "ESM") {
|
|
63
|
-
_logger.default.info("ESM detected");
|
|
64
|
-
module = await (0, _importFromString.importFromString)(pluginCode);
|
|
65
|
-
} else {
|
|
66
|
-
_logger.default.info("CJS detected (default)");
|
|
67
|
-
module = await (0, _importFromString.requireFromString)(pluginCode);
|
|
68
|
-
_logger.default.info(module);
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
_logger.default.error(`Error loading plugin: ${error}`);
|
|
72
|
-
res.status(400).send(`Error loading plugin: ${error}`);
|
|
54
|
+
pluginResource.sourceCode = pluginCode;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
res.status(400).send(`Error fetching plugin code: ${err}`);
|
|
73
57
|
return;
|
|
74
58
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
res.status(400).send(`Plugin code should export a "plugin" object`);
|
|
78
|
-
_logger.default.info("Error in plugin code: no plugin object exported");
|
|
59
|
+
if (!pluginCode) {
|
|
60
|
+
res.status(400).send("Plugin code could not be loaded");
|
|
79
61
|
return;
|
|
80
62
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
63
|
+
const isCjs = typeof __filename !== "undefined" && typeof __dirname !== "undefined";
|
|
64
|
+
const __filenameUniversal = isCjs ? __filename : (0, _url.fileURLToPath)(require('url').pathToFileURL(__filename).toString());
|
|
65
|
+
const __dirnameUniversal = isCjs ? __dirname : _path.default.dirname(__filenameUniversal);
|
|
66
|
+
const pluginProcessFile = isCjs ? "pluginProcess.cjs" : "pluginProcess.js";
|
|
67
|
+
const child = (0, _child_process.fork)(_path.default.resolve(__dirnameUniversal, pluginProcessFile), [], {
|
|
68
|
+
stdio: ["pipe", "pipe", "pipe", "ipc"]
|
|
69
|
+
});
|
|
70
|
+
child.stdout?.on("data", data => {
|
|
71
|
+
_logger.default.info(`[Plugin ${pluginResource.id}] STDOUT: ${data.toString().trim()}`);
|
|
72
|
+
});
|
|
73
|
+
child.stderr?.on("data", data => {
|
|
74
|
+
_logger.default.error(`[Plugin ${pluginResource.id}] STDERR: ${data.toString().trim()}`);
|
|
75
|
+
});
|
|
76
|
+
child.on("message", msg => {
|
|
77
|
+
if (msg.event === "loaded") {
|
|
78
|
+
pluginResource.name = msg.name;
|
|
79
|
+
pluginResource.active = true;
|
|
80
|
+
pluginResource.process = child;
|
|
81
|
+
_pluginService.pluginService.pushPlugin(pluginResource);
|
|
82
|
+
res.status(201).send(`Plugin ${msg.name} registered`);
|
|
83
|
+
} else if (msg.event === "error") {
|
|
84
|
+
res.status(400).send(`Error loading plugin: ${msg.error}`);
|
|
86
85
|
}
|
|
86
|
+
});
|
|
87
|
+
child.on("exit", code => {
|
|
88
|
+
pluginResource.active = false;
|
|
89
|
+
pluginResource.process = undefined;
|
|
90
|
+
_logger.default.warn(`Plugin ${pluginResource.id} exited (code: ${code})`);
|
|
91
|
+
});
|
|
92
|
+
child.on("disconnect", () => {
|
|
93
|
+
pluginResource.active = false;
|
|
94
|
+
pluginResource.process = undefined;
|
|
95
|
+
_logger.default.warn(`Plugin ${pluginResource.id} disconnected`);
|
|
96
|
+
});
|
|
97
|
+
child.on("error", err => {
|
|
98
|
+
pluginResource.active = false;
|
|
99
|
+
pluginResource.process = undefined;
|
|
100
|
+
_logger.default.error(`Plugin ${pluginResource.id} error: ${err.message}`);
|
|
101
|
+
});
|
|
102
|
+
// Send data to child
|
|
103
|
+
child.send({
|
|
104
|
+
type: "load",
|
|
105
|
+
pluginResource
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
exports.registerPlugin = registerPlugin;
|
|
109
|
+
const activatePlugin = (req, res) => {
|
|
110
|
+
const {
|
|
111
|
+
id
|
|
112
|
+
} = req.params;
|
|
113
|
+
const plugin = _pluginService.pluginService.getPlugins().find(p => p.id === id);
|
|
114
|
+
if (!plugin) {
|
|
115
|
+
res.status(404).send(`Plugin with id "${id}" not found.`);
|
|
116
|
+
return;
|
|
87
117
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
118
|
+
_pluginService.pluginService.activatePlugin(id);
|
|
119
|
+
res.status(200).send(`Plugin "${id}" activated.`);
|
|
120
|
+
};
|
|
121
|
+
exports.activatePlugin = activatePlugin;
|
|
122
|
+
const deactivatePlugin = (req, res) => {
|
|
123
|
+
const {
|
|
124
|
+
id
|
|
125
|
+
} = req.params;
|
|
126
|
+
const plugin = _pluginService.pluginService.getPlugins().find(p => p.id === id);
|
|
127
|
+
if (!plugin) {
|
|
128
|
+
res.status(404).send(`Plugin with id "${id}" not found.`);
|
|
93
129
|
return;
|
|
94
130
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
res.status(
|
|
131
|
+
_pluginService.pluginService.deactivatePlugin(id); // This only sets active to false
|
|
132
|
+
res.status(200).send(`Plugin "${id}" deactivated.`);
|
|
133
|
+
};
|
|
134
|
+
exports.deactivatePlugin = deactivatePlugin;
|
|
135
|
+
const deletePlugin = (req, res) => {
|
|
136
|
+
const {
|
|
137
|
+
id
|
|
138
|
+
} = req.params;
|
|
139
|
+
const plugin = _pluginService.pluginService.getPlugins().find(p => p.id === id);
|
|
140
|
+
if (!plugin) {
|
|
141
|
+
res.status(404).send(`Plugin with id "${id}" not found.`);
|
|
142
|
+
return;
|
|
106
143
|
}
|
|
144
|
+
_pluginService.pluginService.deletePlugin(id); // kills child inside service
|
|
145
|
+
res.status(200).send(`Plugin "${id}" deleted.`);
|
|
107
146
|
};
|
|
108
|
-
exports.
|
|
147
|
+
exports.deletePlugin = deletePlugin;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _importFromString = require("import-from-string");
|
|
4
|
+
var _dynamicInstaller = require("dynamic-installer");
|
|
5
|
+
// pluginProcess.js
|
|
6
|
+
// Runs inside a child process, isolated from the main app
|
|
7
|
+
// @ts-expect-error no types
|
|
8
|
+
|
|
9
|
+
let plugin;
|
|
10
|
+
const log = (...args) => {
|
|
11
|
+
console.log(`[PluginProcess:${process.pid}]`, ...args);
|
|
12
|
+
};
|
|
13
|
+
process.on("message", async msg => {
|
|
14
|
+
if (msg.type === "load") {
|
|
15
|
+
try {
|
|
16
|
+
const pluginResource = normalizePluginResource(msg.pluginResource);
|
|
17
|
+
if (pluginResource.install && Array.isArray(pluginResource.install.dependencies) && pluginResource.install.dependencies.length > 0) {
|
|
18
|
+
log("Installing dependencies for plugin: " + pluginResource.name);
|
|
19
|
+
const dependenciesStatus = await (0, _dynamicInstaller.installDependencies)(pluginResource.install);
|
|
20
|
+
if (!dependenciesStatus.success) {
|
|
21
|
+
if (pluginResource.install.ignoreErrors === true) {
|
|
22
|
+
log(`Warning: Error installing dependencies: ${JSON.stringify(dependenciesStatus.details)}`);
|
|
23
|
+
} else {
|
|
24
|
+
process.send?.({
|
|
25
|
+
event: "error",
|
|
26
|
+
error: `Error installing dependencies: ${JSON.stringify(dependenciesStatus.details)}`
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let module;
|
|
33
|
+
if (pluginResource?.moduleFormat?.toLowerCase() === "esm") {
|
|
34
|
+
module = await (0, _importFromString.importFromString)(pluginResource.sourceCode);
|
|
35
|
+
} else {
|
|
36
|
+
module = await (0, _importFromString.requireFromString)(pluginResource.sourceCode);
|
|
37
|
+
}
|
|
38
|
+
plugin = module.default?.plugin ?? module.plugin;
|
|
39
|
+
if (!plugin) throw new Error("Plugin must export a valid 'plugin' object");
|
|
40
|
+
for (const fn of ["load", "isConfigured"]) {
|
|
41
|
+
if (typeof plugin[fn] !== "function") {
|
|
42
|
+
throw new Error(`Plugin is missing required function "${fn}"`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await plugin.load(pluginResource.config);
|
|
46
|
+
if (!plugin.isConfigured()) {
|
|
47
|
+
throw new Error("Plugin could not be configured");
|
|
48
|
+
}
|
|
49
|
+
process.send?.({
|
|
50
|
+
event: "loaded",
|
|
51
|
+
name: pluginResource.name || pluginResource.id || "unknown"
|
|
52
|
+
});
|
|
53
|
+
} catch (err) {
|
|
54
|
+
process.send?.({
|
|
55
|
+
event: "error",
|
|
56
|
+
error: err.message
|
|
57
|
+
});
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Forward log/metric/trace calls
|
|
62
|
+
if (msg.type === "newLog" && plugin?.newLog) {
|
|
63
|
+
plugin.newLog(msg.payload);
|
|
64
|
+
}
|
|
65
|
+
if (msg.type === "newMetric" && plugin?.newMetric) {
|
|
66
|
+
plugin.newMetric(msg.payload);
|
|
67
|
+
}
|
|
68
|
+
if (msg.type === "newTrace" && plugin?.newTrace) {
|
|
69
|
+
plugin.newTrace(msg.payload);
|
|
70
|
+
}
|
|
71
|
+
if (msg.type === "unload") {
|
|
72
|
+
if (plugin && typeof plugin.unload === "function") {
|
|
73
|
+
await plugin.unload();
|
|
74
|
+
}
|
|
75
|
+
process.send?.({
|
|
76
|
+
event: "unloaded"
|
|
77
|
+
});
|
|
78
|
+
process.exit(0);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
function normalizePluginResource(raw) {
|
|
82
|
+
let resource = raw;
|
|
83
|
+
// case: received as stringified JSON
|
|
84
|
+
if (typeof raw === "string") {
|
|
85
|
+
try {
|
|
86
|
+
resource = JSON.parse(raw);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
throw new Error("Invalid pluginResource JSON: " + err.message);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// normalize install
|
|
92
|
+
if (typeof resource.install === "string") {
|
|
93
|
+
try {
|
|
94
|
+
resource.install = JSON.parse(resource.install);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
throw new Error("Invalid install JSON: " + err.message);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// normalize config
|
|
100
|
+
if (typeof resource.config === "string") {
|
|
101
|
+
try {
|
|
102
|
+
resource.config = JSON.parse(resource.config);
|
|
103
|
+
} catch (err) {
|
|
104
|
+
throw new Error("Invalid config JSON: " + err.message);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return resource;
|
|
108
|
+
}
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.getPluginRoutes = void 0;
|
|
7
7
|
var _express = require("express");
|
|
8
8
|
var _pluginController = require("./pluginController.cjs");
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const getPluginRoutes = () => {
|
|
10
|
+
const router = (0, _express.Router)();
|
|
11
|
+
router.get('/', _pluginController.listPlugins);
|
|
12
|
+
router.post('/', _pluginController.registerPlugin);
|
|
13
|
+
router.post('/:id/activate', _pluginController.activatePlugin);
|
|
14
|
+
router.post('/:id/deactivate', _pluginController.deactivatePlugin);
|
|
15
|
+
router.delete('/:id', _pluginController.deletePlugin);
|
|
16
|
+
return router;
|
|
17
|
+
};
|
|
18
|
+
exports.getPluginRoutes = getPluginRoutes;
|