nodebb-plugin-integration 0.4.2 → 0.4.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/README.md +199 -320
- package/README.ru.md +199 -347
- package/library.js +93 -115
- package/package.json +60 -57
- package/plugin.json +50 -33
- package/public/js/admin.js +58 -45
- package/public/templates/admin/plugins/integration.tpl +213 -0
- package/src/ai/embeddings.js +46 -253
- package/src/ai/indexer.js +156 -343
- package/src/ai/openai.js +74 -330
- package/src/ai/qdrant.js +114 -517
- package/src/ai/search.js +138 -251
- package/src/config/index.js +176 -133
- package/src/config/validation.js +250 -0
- package/src/events/index.js +174 -324
- package/src/mcp/manager.js +396 -0
- package/src/mcp/server.js +338 -172
- package/src/mcp/tools.js +158 -617
- package/src/nodebb/categories.js +39 -0
- package/src/nodebb/index.js +72 -305
- package/src/nodebb/meta.js +24 -273
- package/src/nodebb/posts.js +93 -348
- package/src/nodebb/privileges.js +68 -0
- package/src/nodebb/topics.js +91 -355
- package/src/nodebb/users.js +62 -345
- package/src/routes/api.js +255 -97
- package/src/routes/index.js +64 -49
- package/templates/admin/plugins/integration.tpl +0 -130
package/src/nodebb/topics.js
CHANGED
|
@@ -1,356 +1,92 @@
|
|
|
1
|
-
"use strict";
|
|
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
|
-
if(
|
|
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
|
-
catch(error) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
nativeTopics = null;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return nativeTopics;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
async function getTopic(tid) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const topics =
|
|
135
|
-
|
|
136
|
-
loadNative();
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/*
|
|
146
|
-
* Native NodeBB mode
|
|
147
|
-
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if(
|
|
151
|
-
|
|
152
|
-
topics &&
|
|
153
|
-
|
|
154
|
-
typeof topics.getTopicFields === "function"
|
|
155
|
-
|
|
156
|
-
) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return await topics.getTopicFields(
|
|
161
|
-
|
|
162
|
-
tid,
|
|
163
|
-
|
|
164
|
-
[
|
|
165
|
-
|
|
166
|
-
"tid",
|
|
167
|
-
|
|
168
|
-
"uid",
|
|
169
|
-
|
|
170
|
-
"title",
|
|
171
|
-
|
|
172
|
-
"cid",
|
|
173
|
-
|
|
174
|
-
"timestamp",
|
|
175
|
-
|
|
176
|
-
"mainPid"
|
|
177
|
-
|
|
178
|
-
]
|
|
179
|
-
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
/*
|
|
193
|
-
* Standalone mode
|
|
194
|
-
*/
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
tid,
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
uid:
|
|
204
|
-
|
|
205
|
-
null,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
title:
|
|
210
|
-
|
|
211
|
-
"NodeBB unavailable",
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
cid:
|
|
216
|
-
|
|
217
|
-
null,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
timestamp:
|
|
222
|
-
|
|
223
|
-
Date.now(),
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
mainPid:
|
|
228
|
-
|
|
229
|
-
null
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
async function getTopics(tids = []) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const result = [];
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
for(const tid of tids) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
result.push(
|
|
271
|
-
|
|
272
|
-
await getTopic(tid)
|
|
273
|
-
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return result;
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
function info() {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
return {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
nodebb:
|
|
313
|
-
|
|
314
|
-
NodeBB.info(),
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
adapter:
|
|
319
|
-
|
|
320
|
-
"topics"
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
module.exports = {
|
|
344
|
-
|
|
345
|
-
getTopic,
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
getTopics,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
info
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const NodeBB = require("./index");
|
|
4
|
+
|
|
5
|
+
const FIELDS = [
|
|
6
|
+
"tid",
|
|
7
|
+
"uid",
|
|
8
|
+
"title",
|
|
9
|
+
"cid",
|
|
10
|
+
"timestamp",
|
|
11
|
+
"mainPid",
|
|
12
|
+
"deleted"
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
async function getTopic(tid) {
|
|
16
|
+
tid = Number(tid);
|
|
17
|
+
|
|
18
|
+
if (!Number.isSafeInteger(tid) || tid <= 0) {
|
|
19
|
+
throw new TypeError("Invalid topic ID");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const topics = NodeBB.get("topics");
|
|
23
|
+
|
|
24
|
+
if (typeof topics.getTopicFields !== "function") {
|
|
25
|
+
throw new Error("NodeBB topics.getTopicFields is unavailable");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return topics.getTopicFields(tid, FIELDS);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function getTopicPids(tid) {
|
|
32
|
+
tid = Number(tid);
|
|
33
|
+
|
|
34
|
+
if (!Number.isSafeInteger(tid) || tid <= 0) {
|
|
35
|
+
throw new TypeError("Invalid topic ID");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const topics = NodeBB.get("topics");
|
|
39
|
+
|
|
40
|
+
if (typeof topics.getPids !== "function") {
|
|
41
|
+
throw new Error("NodeBB topics.getPids is unavailable");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const pids = await topics.getPids(tid);
|
|
45
|
+
|
|
46
|
+
return [...new Set(
|
|
47
|
+
(Array.isArray(pids) ? pids : [])
|
|
48
|
+
.map(Number)
|
|
49
|
+
.filter(pid => Number.isSafeInteger(pid) && pid > 0)
|
|
50
|
+
)];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function getTopics(tids = []) {
|
|
54
|
+
if (!Array.isArray(tids)) {
|
|
55
|
+
throw new TypeError("Topic IDs must be an array");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const unique = [...new Set(
|
|
59
|
+
tids.map(Number).filter(
|
|
60
|
+
tid => Number.isSafeInteger(tid) && tid > 0
|
|
61
|
+
)
|
|
62
|
+
)];
|
|
63
|
+
|
|
64
|
+
if (!unique.length) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const topics = NodeBB.get("topics");
|
|
69
|
+
|
|
70
|
+
if (typeof topics.getTopicsFields === "function") {
|
|
71
|
+
return topics.getTopicsFields(unique, FIELDS);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const result = [];
|
|
75
|
+
|
|
76
|
+
for (const tid of unique) {
|
|
77
|
+
const topic = await getTopic(tid);
|
|
78
|
+
|
|
79
|
+
if (topic) {
|
|
80
|
+
result.push(topic);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
getTopic,
|
|
89
|
+
getTopics,
|
|
90
|
+
getTopicPids,
|
|
91
|
+
FIELDS
|
|
356
92
|
};
|