@drodil/backstage-plugin-qeta-common 2.15.0 → 3.0.0

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.
@@ -0,0 +1,649 @@
1
+ 'use strict';
2
+
3
+ var errors = require('@backstage/errors');
4
+ var omitBy = require('lodash/omitBy');
5
+ var crossFetch = require('cross-fetch');
6
+ var qs = require('qs');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ var omitBy__default = /*#__PURE__*/_interopDefaultCompat(omitBy);
11
+ var crossFetch__default = /*#__PURE__*/_interopDefaultCompat(crossFetch);
12
+ var qs__default = /*#__PURE__*/_interopDefaultCompat(qs);
13
+
14
+ class QetaError extends errors.CustomErrorBase {
15
+ errors;
16
+ constructor(message, errors) {
17
+ super(message);
18
+ this.errors = errors;
19
+ }
20
+ }
21
+ class QetaClient {
22
+ fetchApi;
23
+ discoveryApi;
24
+ constructor(options) {
25
+ this.fetchApi = options.fetchApi ?? { fetch: crossFetch__default.default };
26
+ this.discoveryApi = options.discoveryApi;
27
+ }
28
+ async getBaseUrl() {
29
+ return this.discoveryApi.getBaseUrl("qeta");
30
+ }
31
+ async getPosts(options, requestOptions) {
32
+ const query = this.getQueryParameters(options);
33
+ let url = `${await this.getBaseUrl()}/posts`;
34
+ if (query) {
35
+ url += `?${query}`;
36
+ }
37
+ const headers = {};
38
+ if (requestOptions?.token) {
39
+ headers.Authorization = `Bearer ${requestOptions.token}`;
40
+ }
41
+ const response = await this.fetchApi.fetch(url, { method: "GET", headers });
42
+ if (response.status === 403) {
43
+ return { posts: [], total: 0 };
44
+ }
45
+ const data = await response.json();
46
+ if ("errors" in data) {
47
+ throw new QetaError("Failed to fetch", data.errors);
48
+ }
49
+ return data;
50
+ }
51
+ async getPostsList(type, options) {
52
+ const query = this.getQueryParameters(options);
53
+ let url = `${await this.getBaseUrl()}/posts/list/${type}`;
54
+ if (query) {
55
+ url += `?${query}`;
56
+ }
57
+ const response = await this.fetchApi.fetch(url);
58
+ if (response.status === 403) {
59
+ return { posts: [], total: 0 };
60
+ }
61
+ const data = await response.json();
62
+ if ("errors" in data) {
63
+ throw new QetaError("Failed to fetch", data.errors);
64
+ }
65
+ return data;
66
+ }
67
+ async createPost(question) {
68
+ const response = await this.fetchApi.fetch(
69
+ `${await this.getBaseUrl()}/posts`,
70
+ {
71
+ method: "POST",
72
+ body: JSON.stringify(question),
73
+ headers: { "Content-Type": "application/json" }
74
+ }
75
+ );
76
+ const data = await response.json();
77
+ if ("errors" in data) {
78
+ throw new QetaError("Failed to fetch", data.errors);
79
+ }
80
+ return data;
81
+ }
82
+ async commentPost(id, content) {
83
+ const response = await this.fetchApi.fetch(
84
+ `${await this.getBaseUrl()}/posts/${id}/comments`,
85
+ {
86
+ method: "POST",
87
+ body: JSON.stringify({ content }),
88
+ headers: { "Content-Type": "application/json" }
89
+ }
90
+ );
91
+ const data = await response.json();
92
+ if ("errors" in data) {
93
+ throw new QetaError("Failed to fetch", data.errors);
94
+ }
95
+ return data;
96
+ }
97
+ async deletePostComment(questionId, id) {
98
+ const response = await this.fetchApi.fetch(
99
+ `${await this.getBaseUrl()}/posts/${questionId}/comments/${id}`,
100
+ {
101
+ method: "DELETE"
102
+ }
103
+ );
104
+ const data = await response.json();
105
+ if ("errors" in data) {
106
+ throw new QetaError("Failed to fetch", data.errors);
107
+ }
108
+ return data;
109
+ }
110
+ async getPost(id) {
111
+ if (!id) {
112
+ throw new QetaError("Invalid id provided", void 0);
113
+ }
114
+ const response = await this.fetchApi.fetch(
115
+ `${await this.getBaseUrl()}/posts/${id}`
116
+ );
117
+ const data = await response.json();
118
+ if ("errors" in data) {
119
+ throw new QetaError("Failed to fetch", data.errors);
120
+ }
121
+ return data;
122
+ }
123
+ async getTags() {
124
+ const response = await this.fetchApi.fetch(
125
+ `${await this.getBaseUrl()}/tags`
126
+ );
127
+ return await response.json();
128
+ }
129
+ async getTag(tag) {
130
+ const response = await this.fetchApi.fetch(
131
+ `${await this.getBaseUrl()}/tags/${tag}`
132
+ );
133
+ if (!response.ok) {
134
+ return null;
135
+ }
136
+ return await response.json();
137
+ }
138
+ async updateTag(tag, description) {
139
+ const response = await this.fetchApi.fetch(
140
+ `${await this.getBaseUrl()}/tags/${tag}`,
141
+ {
142
+ method: "POST",
143
+ body: JSON.stringify({ description }),
144
+ headers: { "Content-Type": "application/json" }
145
+ }
146
+ );
147
+ if (!response.ok) {
148
+ return null;
149
+ }
150
+ return await response.json();
151
+ }
152
+ async getUsers() {
153
+ const response = await this.fetchApi.fetch(
154
+ `${await this.getBaseUrl()}/users`
155
+ );
156
+ return await response.json();
157
+ }
158
+ async getEntities() {
159
+ const response = await this.fetchApi.fetch(
160
+ `${await this.getBaseUrl()}/entities`
161
+ );
162
+ return await response.json();
163
+ }
164
+ async getEntity(entityRef) {
165
+ const response = await this.fetchApi.fetch(
166
+ `${await this.getBaseUrl()}/entities/${entityRef}`
167
+ );
168
+ if (!response.ok) {
169
+ return null;
170
+ }
171
+ return await response.json();
172
+ }
173
+ async votePostUp(id) {
174
+ if (!id) {
175
+ throw new QetaError("Invalid id provided", void 0);
176
+ }
177
+ const response = await this.fetchApi.fetch(
178
+ `${await this.getBaseUrl()}/posts/${id}/upvote`
179
+ );
180
+ const data = await response.json();
181
+ if ("errors" in data) {
182
+ throw new QetaError("Failed to fetch", data.errors);
183
+ }
184
+ return data;
185
+ }
186
+ async votePostDown(id) {
187
+ if (!id) {
188
+ throw new QetaError("Invalid id provided", void 0);
189
+ }
190
+ const response = await this.fetchApi.fetch(
191
+ `${await this.getBaseUrl()}/posts/${id}/downvote`
192
+ );
193
+ const data = await response.json();
194
+ if ("errors" in data) {
195
+ throw new QetaError("Failed to fetch", data.errors);
196
+ }
197
+ return data;
198
+ }
199
+ async favoritePost(id) {
200
+ if (!id) {
201
+ throw new QetaError("Invalid id provided", void 0);
202
+ }
203
+ const response = await this.fetchApi.fetch(
204
+ `${await this.getBaseUrl()}/posts/${id}/favorite`
205
+ );
206
+ const data = await response.json();
207
+ if ("errors" in data) {
208
+ throw new QetaError("Failed to fetch", data.errors);
209
+ }
210
+ return data;
211
+ }
212
+ async unfavoritePost(id) {
213
+ if (!id) {
214
+ throw new QetaError("Invalid id provided", void 0);
215
+ }
216
+ const response = await this.fetchApi.fetch(
217
+ `${await this.getBaseUrl()}/posts/${id}/unfavorite`
218
+ );
219
+ const data = await response.json();
220
+ if ("errors" in data) {
221
+ throw new QetaError("Failed to fetch", data.errors);
222
+ }
223
+ return data;
224
+ }
225
+ async postAnswer(answer) {
226
+ const response = await this.fetchApi.fetch(
227
+ `${await this.getBaseUrl()}/posts/${answer.postId}/answers`,
228
+ {
229
+ method: "POST",
230
+ body: JSON.stringify({
231
+ answer: answer.answer,
232
+ images: answer.images,
233
+ anonymous: answer.anonymous
234
+ }),
235
+ headers: { "Content-Type": "application/json" }
236
+ }
237
+ );
238
+ const data = await response.json();
239
+ if ("errors" in data) {
240
+ throw new QetaError("Failed to fetch", data.errors);
241
+ }
242
+ return data;
243
+ }
244
+ async commentAnswer(questionId, id, content) {
245
+ const response = await this.fetchApi.fetch(
246
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}/comments`,
247
+ {
248
+ method: "POST",
249
+ body: JSON.stringify({ content }),
250
+ headers: { "Content-Type": "application/json" }
251
+ }
252
+ );
253
+ const data = await response.json();
254
+ if ("errors" in data) {
255
+ throw new QetaError("Failed to fetch", data.errors);
256
+ }
257
+ return data;
258
+ }
259
+ async deleteAnswerComment(questionId, answerId, id) {
260
+ const response = await this.fetchApi.fetch(
261
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${answerId}/comments/${id}`,
262
+ {
263
+ method: "DELETE"
264
+ }
265
+ );
266
+ const data = await response.json();
267
+ if ("errors" in data) {
268
+ throw new QetaError("Failed to fetch", data.errors);
269
+ }
270
+ return data;
271
+ }
272
+ async voteAnswerUp(questionId, id) {
273
+ if (!id || !questionId) {
274
+ throw new QetaError("Invalid id provided", void 0);
275
+ }
276
+ const response = await this.fetchApi.fetch(
277
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}/upvote`
278
+ );
279
+ const data = await response.json();
280
+ if ("errors" in data) {
281
+ throw new QetaError("Failed to fetch", data.errors);
282
+ }
283
+ return data;
284
+ }
285
+ async voteAnswerDown(questionId, id) {
286
+ if (!id || !questionId) {
287
+ throw new QetaError("Invalid id provided", void 0);
288
+ }
289
+ const response = await this.fetchApi.fetch(
290
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}/downvote`
291
+ );
292
+ const data = await response.json();
293
+ if ("errors" in data) {
294
+ throw new QetaError("Failed to fetch", data.errors);
295
+ }
296
+ return data;
297
+ }
298
+ async markAnswerCorrect(questionId, id) {
299
+ if (!id || !questionId) {
300
+ throw new QetaError("Invalid id provided", void 0);
301
+ }
302
+ const response = await this.fetchApi.fetch(
303
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}/correct`
304
+ );
305
+ const data = await response;
306
+ return data.ok;
307
+ }
308
+ async markAnswerIncorrect(questionId, id) {
309
+ if (!id || !questionId) {
310
+ throw new QetaError("Invalid id provided", void 0);
311
+ }
312
+ const response = await this.fetchApi.fetch(
313
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}/incorrect`
314
+ );
315
+ const data = await response;
316
+ return data.ok;
317
+ }
318
+ async deletePost(questionId) {
319
+ if (!questionId) {
320
+ throw new QetaError("Invalid id provided", void 0);
321
+ }
322
+ const response = await this.fetchApi.fetch(
323
+ `${await this.getBaseUrl()}/posts/${questionId}`,
324
+ {
325
+ method: "DELETE"
326
+ }
327
+ );
328
+ const data = await response;
329
+ return data.ok;
330
+ }
331
+ async deleteAnswer(questionId, id) {
332
+ if (!questionId || !id) {
333
+ throw new QetaError("Invalid id provided", void 0);
334
+ }
335
+ const response = await this.fetchApi.fetch(
336
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}`,
337
+ {
338
+ method: "DELETE"
339
+ }
340
+ );
341
+ const data = await response;
342
+ return data.ok;
343
+ }
344
+ async updatePost(id, question) {
345
+ const response = await this.fetchApi.fetch(
346
+ `${await this.getBaseUrl()}/posts/${id}`,
347
+ {
348
+ method: "POST",
349
+ body: JSON.stringify(question),
350
+ headers: { "Content-Type": "application/json" }
351
+ }
352
+ );
353
+ const data = await response.json();
354
+ if ("errors" in data) {
355
+ throw new QetaError("Failed to update", data.errors);
356
+ }
357
+ return data;
358
+ }
359
+ async updateAnswer(id, answer) {
360
+ const response = await this.fetchApi.fetch(
361
+ `${await this.getBaseUrl()}/posts/${answer.postId}/answers/${id}`,
362
+ {
363
+ method: "POST",
364
+ body: JSON.stringify({ answer: answer.answer, images: answer.images }),
365
+ headers: { "Content-Type": "application/json" }
366
+ }
367
+ );
368
+ const data = await response.json();
369
+ if ("errors" in data) {
370
+ throw new QetaError("Failed to fetch", data.errors);
371
+ }
372
+ return data;
373
+ }
374
+ async getAnswers(options) {
375
+ const query = this.getQueryParameters(options);
376
+ let url = `${await this.getBaseUrl()}/answers`;
377
+ if (query) {
378
+ url += `?${query}`;
379
+ }
380
+ const response = await this.fetchApi.fetch(url);
381
+ if (response.status === 403) {
382
+ return { answers: [], total: 0 };
383
+ }
384
+ const data = await response.json();
385
+ if ("errors" in data) {
386
+ throw new QetaError("Failed to fetch", data.errors);
387
+ }
388
+ return data;
389
+ }
390
+ async getAnswer(questionId, id) {
391
+ if (!questionId || !id) {
392
+ throw new QetaError("Invalid id provided", void 0);
393
+ }
394
+ const response = await this.fetchApi.fetch(
395
+ `${await this.getBaseUrl()}/posts/${questionId}/answers/${id}`
396
+ );
397
+ const data = await response.json();
398
+ if ("errors" in data) {
399
+ throw new QetaError("Failed to fetch", data.errors);
400
+ }
401
+ return data;
402
+ }
403
+ async getFollowedTags() {
404
+ const response = await this.fetchApi.fetch(
405
+ `${await this.getBaseUrl()}/tags/followed`
406
+ );
407
+ return await response.json();
408
+ }
409
+ async followTag(tag) {
410
+ const response = await this.fetchApi.fetch(
411
+ `${await this.getBaseUrl()}/tags/follow/${tag}`,
412
+ {
413
+ method: "PUT"
414
+ }
415
+ );
416
+ return response.ok;
417
+ }
418
+ async unfollowTag(tag) {
419
+ const response = await this.fetchApi.fetch(
420
+ `${await this.getBaseUrl()}/tags/follow/${tag}`,
421
+ {
422
+ method: "DELETE"
423
+ }
424
+ );
425
+ return response.ok;
426
+ }
427
+ async getFollowedEntities() {
428
+ const response = await this.fetchApi.fetch(
429
+ `${await this.getBaseUrl()}/entities/followed`
430
+ );
431
+ return await response.json();
432
+ }
433
+ async followEntity(entityRef) {
434
+ const response = await this.fetchApi.fetch(
435
+ `${await this.getBaseUrl()}/entities/follow/${entityRef}`,
436
+ {
437
+ method: "PUT"
438
+ }
439
+ );
440
+ return response.ok;
441
+ }
442
+ async unfollowEntity(entityRef) {
443
+ const response = await this.fetchApi.fetch(
444
+ `${await this.getBaseUrl()}/entities/follow/${entityRef}`,
445
+ {
446
+ method: "DELETE"
447
+ }
448
+ );
449
+ return response.ok;
450
+ }
451
+ async postAttachment(file) {
452
+ const qetaUrl = `${await this.getBaseUrl()}/attachments`;
453
+ const formData = new FormData();
454
+ formData.append("image", file);
455
+ const requestOptions = {
456
+ method: "POST",
457
+ body: formData
458
+ };
459
+ const response = await this.fetchApi.fetch(qetaUrl, requestOptions);
460
+ return await response.json();
461
+ }
462
+ async getMostUpvotedAnswers(options) {
463
+ const query = this.getQueryParameters(options.options);
464
+ let url = `${await this.getBaseUrl()}/statistics/answers/top-upvoted-users`;
465
+ if (query) {
466
+ url += `?${query}`;
467
+ }
468
+ const response = await this.fetchApi.fetch(url);
469
+ return await response.json();
470
+ }
471
+ async getMostUpvotedCorrectAnswers(options) {
472
+ const query = this.getQueryParameters(options.options);
473
+ let url = `${await this.getBaseUrl()}/statistics/answers/top-correct-upvoted-users`;
474
+ if (query) {
475
+ url += `?${query}`;
476
+ }
477
+ const response = await this.fetchApi.fetch(url);
478
+ return await response.json();
479
+ }
480
+ async getMostUpvotedPosts(options) {
481
+ const query = this.getQueryParameters(options.options);
482
+ let url = `${await this.getBaseUrl()}/statistics/posts/top-upvoted-users`;
483
+ if (query) {
484
+ url += `?${query}`;
485
+ }
486
+ const response = await this.fetchApi.fetch(url);
487
+ return await response.json();
488
+ }
489
+ async getMostPosts(options) {
490
+ const query = this.getQueryParameters(options.options);
491
+ let url = `${await this.getBaseUrl()}/statistics/posts/most-questions`;
492
+ if (query) {
493
+ url += `?${query}`;
494
+ }
495
+ const response = await this.fetchApi.fetch(url);
496
+ return await response.json();
497
+ }
498
+ async getMostAnswers(options) {
499
+ const query = this.getQueryParameters(options.options);
500
+ let url = `${await this.getBaseUrl()}/statistics/answers/most-answers`;
501
+ if (query) {
502
+ url += `?${query}`;
503
+ }
504
+ const response = await this.fetchApi.fetch(url);
505
+ const data = await response.json();
506
+ return data;
507
+ }
508
+ async getTopStatisticsHomepage(options) {
509
+ const response = await Promise.all([
510
+ this.getMostPosts(options),
511
+ this.getMostAnswers(options),
512
+ this.getMostUpvotedPosts(options),
513
+ this.getMostUpvotedAnswers(options),
514
+ this.getMostUpvotedCorrectAnswers(options)
515
+ ]);
516
+ return response;
517
+ }
518
+ async getUserImpact() {
519
+ const response = await this.fetchApi.fetch(
520
+ `${await this.getBaseUrl()}/statistics/user/impact`
521
+ );
522
+ return await response.json();
523
+ }
524
+ async getGlobalStats() {
525
+ const response = await this.fetchApi.fetch(
526
+ `${await this.getBaseUrl()}/statistics/global`
527
+ );
528
+ return await response.json();
529
+ }
530
+ async getUserStats(userRef) {
531
+ const response = await this.fetchApi.fetch(
532
+ `${await this.getBaseUrl()}/statistics/user/${userRef}`
533
+ );
534
+ return await response.json();
535
+ }
536
+ async getCollections(options) {
537
+ const query = this.getQueryParameters(options);
538
+ let url = `${await this.getBaseUrl()}/collections`;
539
+ if (query) {
540
+ url += `?${query}`;
541
+ }
542
+ const response = await this.fetchApi.fetch(url);
543
+ if (response.status === 403) {
544
+ return { collections: [], total: 0 };
545
+ }
546
+ const data = await response.json();
547
+ if ("errors" in data) {
548
+ throw new QetaError("Failed to fetch", data.errors);
549
+ }
550
+ return data;
551
+ }
552
+ async getCollection(id) {
553
+ if (!id) {
554
+ throw new QetaError("Invalid id provided", void 0);
555
+ }
556
+ const response = await this.fetchApi.fetch(
557
+ `${await this.getBaseUrl()}/collections/${id}`
558
+ );
559
+ const data = await response.json();
560
+ if ("errors" in data) {
561
+ throw new QetaError("Failed to fetch", data.errors);
562
+ }
563
+ return data;
564
+ }
565
+ async createCollection(collection) {
566
+ const response = await this.fetchApi.fetch(
567
+ `${await this.getBaseUrl()}/collections`,
568
+ {
569
+ method: "POST",
570
+ body: JSON.stringify(collection),
571
+ headers: { "Content-Type": "application/json" }
572
+ }
573
+ );
574
+ const data = await response.json();
575
+ if ("errors" in data) {
576
+ throw new QetaError("Failed to fetch", data.errors);
577
+ }
578
+ return data;
579
+ }
580
+ async updateCollection(id, collection) {
581
+ const response = await this.fetchApi.fetch(
582
+ `${await this.getBaseUrl()}/collections/${id}`,
583
+ {
584
+ method: "POST",
585
+ body: JSON.stringify(collection),
586
+ headers: { "Content-Type": "application/json" }
587
+ }
588
+ );
589
+ const data = await response.json();
590
+ if ("errors" in data) {
591
+ throw new QetaError("Failed to update", data.errors);
592
+ }
593
+ return data;
594
+ }
595
+ async deleteCollection(id) {
596
+ if (!id) {
597
+ throw new QetaError("Invalid id provided", void 0);
598
+ }
599
+ const response = await this.fetchApi.fetch(
600
+ `${await this.getBaseUrl()}/collections/${id}`,
601
+ {
602
+ method: "DELETE"
603
+ }
604
+ );
605
+ const data = await response;
606
+ return data.ok;
607
+ }
608
+ async addPostToCollection(collectionId, postId) {
609
+ const response = await this.fetchApi.fetch(
610
+ `${await this.getBaseUrl()}/collections/${collectionId}/posts`,
611
+ {
612
+ method: "POST",
613
+ body: JSON.stringify({ postId }),
614
+ headers: { "Content-Type": "application/json" }
615
+ }
616
+ );
617
+ const data = await response.json();
618
+ if ("errors" in data) {
619
+ throw new QetaError("Failed to update", data.errors);
620
+ }
621
+ return data;
622
+ }
623
+ async removePostFromCollection(collectionId, postId) {
624
+ const response = await this.fetchApi.fetch(
625
+ `${await this.getBaseUrl()}/collections/${collectionId}/posts`,
626
+ {
627
+ method: "DELETE",
628
+ body: JSON.stringify({ postId }),
629
+ headers: { "Content-Type": "application/json" }
630
+ }
631
+ );
632
+ const data = await response.json();
633
+ if ("errors" in data) {
634
+ throw new QetaError("Failed to update", data.errors);
635
+ }
636
+ return data;
637
+ }
638
+ getQueryParameters(params) {
639
+ if (!params) {
640
+ return "";
641
+ }
642
+ const cleaned = omitBy__default.default(params, (v) => !Boolean(v));
643
+ return qs__default.default.stringify(cleaned);
644
+ }
645
+ }
646
+
647
+ exports.QetaClient = QetaClient;
648
+ exports.QetaError = QetaError;
649
+ //# sourceMappingURL=QetaClient.cjs.js.map