@prosopo/database 2.1.6 → 2.1.8

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.
Files changed (64) hide show
  1. package/package.json +5 -5
  2. package/dist/base/index.d.ts +0 -3
  3. package/dist/base/index.d.ts.map +0 -1
  4. package/dist/base/index.js +0 -3
  5. package/dist/base/index.js.map +0 -1
  6. package/dist/base/mongo.d.ts +0 -16
  7. package/dist/base/mongo.d.ts.map +0 -1
  8. package/dist/base/mongo.js +0 -89
  9. package/dist/base/mongo.js.map +0 -1
  10. package/dist/base/mongoMemory.d.ts +0 -11
  11. package/dist/base/mongoMemory.d.ts.map +0 -1
  12. package/dist/base/mongoMemory.js +0 -27
  13. package/dist/base/mongoMemory.js.map +0 -1
  14. package/dist/captchaDatabase/captchaDatabse.d.ts +0 -3
  15. package/dist/captchaDatabase/captchaDatabse.d.ts.map +0 -1
  16. package/dist/captchaDatabase/captchaDatabse.js +0 -22
  17. package/dist/captchaDatabase/captchaDatabse.js.map +0 -1
  18. package/dist/captchaDatabase/index.d.ts +0 -2
  19. package/dist/captchaDatabase/index.d.ts.map +0 -1
  20. package/dist/captchaDatabase/index.js +0 -2
  21. package/dist/captchaDatabase/index.js.map +0 -1
  22. package/dist/cjs/base/index.cjs +0 -6
  23. package/dist/cjs/base/mongo.cjs +0 -97
  24. package/dist/cjs/base/mongoMemory.cjs +0 -28
  25. package/dist/cjs/databases/captcha.cjs +0 -82
  26. package/dist/cjs/databases/client.cjs +0 -52
  27. package/dist/cjs/databases/index.cjs +0 -19
  28. package/dist/cjs/databases/provider.cjs +0 -983
  29. package/dist/cjs/index.cjs +0 -15
  30. package/dist/databases/captcha.d.ts +0 -16
  31. package/dist/databases/captcha.d.ts.map +0 -1
  32. package/dist/databases/captcha.js +0 -75
  33. package/dist/databases/captcha.js.map +0 -1
  34. package/dist/databases/client.d.ts +0 -12
  35. package/dist/databases/client.d.ts.map +0 -1
  36. package/dist/databases/client.js +0 -48
  37. package/dist/databases/client.js.map +0 -1
  38. package/dist/databases/index.d.ts +0 -16
  39. package/dist/databases/index.d.ts.map +0 -1
  40. package/dist/databases/index.js +0 -17
  41. package/dist/databases/index.js.map +0 -1
  42. package/dist/databases/mongo.d.ts +0 -58
  43. package/dist/databases/mongo.d.ts.map +0 -1
  44. package/dist/databases/mongo.js +0 -682
  45. package/dist/databases/mongo.js.map +0 -1
  46. package/dist/databases/mongoMemory.d.ts +0 -10
  47. package/dist/databases/mongoMemory.d.ts.map +0 -1
  48. package/dist/databases/mongoMemory.js +0 -30
  49. package/dist/databases/mongoMemory.js.map +0 -1
  50. package/dist/databases/provider.d.ts +0 -73
  51. package/dist/databases/provider.d.ts.map +0 -1
  52. package/dist/databases/provider.js +0 -823
  53. package/dist/databases/provider.js.map +0 -1
  54. package/dist/eventsDatabase/eventsDatabase.d.ts +0 -3
  55. package/dist/eventsDatabase/eventsDatabase.d.ts.map +0 -1
  56. package/dist/eventsDatabase/eventsDatabase.js +0 -46
  57. package/dist/eventsDatabase/eventsDatabase.js.map +0 -1
  58. package/dist/eventsDatabase/index.d.ts +0 -2
  59. package/dist/eventsDatabase/index.d.ts.map +0 -1
  60. package/dist/eventsDatabase/index.js +0 -2
  61. package/dist/eventsDatabase/index.js.map +0 -1
  62. package/dist/index.d.ts +0 -3
  63. package/dist/index.d.ts.map +0 -1
  64. package/dist/index.js.map +0 -1
@@ -1,682 +0,0 @@
1
- import { AsyncFactory, ProsopoDBError, ProsopoEnvError, getLoggerDefault, } from "@prosopo/common";
2
- import { CaptchaStates, CaptchaStatus, DatasetWithIdsAndTreeSchema, ScheduledTaskNames, ScheduledTaskStatus, } from "@prosopo/types";
3
- import { CaptchaRecordSchema, DatasetRecordSchema, PendingRecordSchema, PowCaptchaRecordSchema, ScheduledTaskRecordSchema, ScheduledTaskSchema, SolutionRecordSchema, UserCommitmentRecordSchema, UserCommitmentSchema, UserSolutionRecordSchema, UserSolutionSchema, } from "@prosopo/types-database";
4
- import { ServerApiVersion } from "mongodb";
5
- import { isHex } from "@polkadot/util/is";
6
- import mongoose from "mongoose";
7
- mongoose.set("strictQuery", false);
8
- const DEFAULT_ENDPOINT = "mongodb://127.0.0.1:27017";
9
- export class ProsopoDatabase extends AsyncFactory {
10
- constructor() {
11
- super();
12
- this.url = "";
13
- this.dbname = "";
14
- this.logger = getLoggerDefault();
15
- }
16
- async init(url, dbname, logger, authSource) {
17
- const baseEndpoint = url || DEFAULT_ENDPOINT;
18
- const parsedUrl = new URL(baseEndpoint);
19
- parsedUrl.pathname = dbname;
20
- if (authSource) {
21
- parsedUrl.searchParams.set("authSource", authSource);
22
- }
23
- this.url = parsedUrl.toString();
24
- this.dbname = dbname;
25
- this.logger = logger;
26
- return this;
27
- }
28
- getTables() {
29
- if (!this.tables) {
30
- throw new ProsopoDBError("DATABASE.TABLES_UNDEFINED", {
31
- context: { failedFuncName: this.getTables.name },
32
- logger: this.logger,
33
- });
34
- }
35
- return this.tables;
36
- }
37
- getConnection() {
38
- if (!this.connection) {
39
- throw new ProsopoDBError("DATABASE.CONNECTION_UNDEFINED", {
40
- context: { failedFuncName: this.getConnection.name },
41
- logger: this.logger,
42
- });
43
- }
44
- return this.connection;
45
- }
46
- async connect() {
47
- this.logger.info(`Mongo url: ${this.url.replace(/\w+:\w+/, "<Credentials>")}`);
48
- this.connection = await new Promise((resolve, reject) => {
49
- const connection = mongoose.createConnection(this.url, {
50
- dbName: this.dbname,
51
- serverApi: ServerApiVersion.v1,
52
- });
53
- connection.on("open", () => {
54
- this.logger.info(`Database connection to ${this.url} opened`);
55
- resolve(connection);
56
- });
57
- connection.on("error", (err) => {
58
- this.logger.error(`Database error: ${err}`);
59
- reject(err);
60
- });
61
- connection.on("connected", () => {
62
- this.logger.info(`Database connected to ${this.url}`);
63
- resolve(connection);
64
- });
65
- connection.on("disconnected", () => {
66
- this.logger.info(`Database disconnected from ${this.url}`);
67
- });
68
- connection.on("reconnected", () => {
69
- this.logger.info(`Database reconnected to ${this.url}`);
70
- resolve(connection);
71
- });
72
- connection.on("reconnectFailed", () => {
73
- this.logger.error(`Database reconnect failed to ${this.url}`);
74
- });
75
- connection.on("close", () => {
76
- this.logger.info(`Database connection to ${this.url} closed`);
77
- });
78
- connection.on("fullsetup", () => {
79
- this.logger.info(`Database connection to ${this.url} is fully setup`);
80
- resolve(connection);
81
- });
82
- });
83
- this.tables = {
84
- captcha: this.connection.model("Captcha", CaptchaRecordSchema),
85
- powCaptcha: this.connection.model("PowCaptcha", PowCaptchaRecordSchema),
86
- dataset: this.connection.model("Dataset", DatasetRecordSchema),
87
- solution: this.connection.model("Solution", SolutionRecordSchema),
88
- commitment: this.connection.model("UserCommitment", UserCommitmentRecordSchema),
89
- usersolution: this.connection.model("UserSolution", UserSolutionRecordSchema),
90
- pending: this.connection.model("Pending", PendingRecordSchema),
91
- scheduler: this.connection.model("Scheduler", ScheduledTaskRecordSchema),
92
- };
93
- }
94
- async close() {
95
- this.logger.debug(`Closing connection to ${this.url}`);
96
- await this.connection?.close();
97
- }
98
- async storeDataset(dataset) {
99
- try {
100
- this.logger.debug("Storing dataset in database");
101
- const parsedDataset = DatasetWithIdsAndTreeSchema.parse(dataset);
102
- const datasetDoc = {
103
- datasetId: parsedDataset.datasetId,
104
- datasetContentId: parsedDataset.datasetContentId,
105
- format: parsedDataset.format,
106
- contentTree: parsedDataset.contentTree,
107
- solutionTree: parsedDataset.solutionTree,
108
- };
109
- await this.tables?.dataset.updateOne({ datasetId: parsedDataset.datasetId }, { $set: datasetDoc }, { upsert: true });
110
- const captchaDocs = parsedDataset.captchas.map(({ solution, ...captcha }, index) => ({
111
- ...captcha,
112
- datasetId: parsedDataset.datasetId,
113
- datasetContentId: parsedDataset.datasetContentId,
114
- index,
115
- solved: !!solution?.length,
116
- }));
117
- this.logger.debug("Inserting captcha records");
118
- if (captchaDocs.length) {
119
- await this.tables?.captcha.bulkWrite(captchaDocs.map((captchaDoc) => ({
120
- updateOne: {
121
- filter: { captchaId: captchaDoc.captchaId },
122
- update: { $set: captchaDoc },
123
- upsert: true,
124
- },
125
- })));
126
- }
127
- const captchaSolutionDocs = parsedDataset.captchas
128
- .filter(({ solution }) => solution?.length)
129
- .map((captcha) => ({
130
- captchaId: captcha.captchaId,
131
- captchaContentId: captcha.captchaContentId,
132
- solution: captcha.solution,
133
- salt: captcha.salt,
134
- datasetId: parsedDataset.datasetId,
135
- datasetContentId: parsedDataset.datasetContentId,
136
- }));
137
- this.logger.debug("Inserting solution records");
138
- if (captchaSolutionDocs.length) {
139
- await this.tables?.solution.bulkWrite(captchaSolutionDocs.map((captchaSolutionDoc) => ({
140
- updateOne: {
141
- filter: { captchaId: captchaSolutionDoc.captchaId },
142
- update: { $set: captchaSolutionDoc },
143
- upsert: true,
144
- },
145
- })));
146
- }
147
- this.logger.debug("Dataset stored in database");
148
- }
149
- catch (err) {
150
- throw new ProsopoDBError("DATABASE.DATASET_LOAD_FAILED", {
151
- context: { failedFuncName: this.storeDataset.name, error: err },
152
- logger: this.logger,
153
- });
154
- }
155
- }
156
- async getSolutions(datasetId) {
157
- const docs = await this.tables?.solution
158
- .find({ datasetId })
159
- .lean();
160
- return docs ? docs : [];
161
- }
162
- async getDataset(datasetId) {
163
- const datasetDoc = await this.tables?.dataset.findOne({ datasetId: datasetId }).lean();
164
- if (datasetDoc) {
165
- const { datasetContentId, format, contentTree, solutionTree } = datasetDoc;
166
- const captchas = (await this.tables?.captcha.find({ datasetId }).lean()) || [];
167
- const solutions = (await this.tables?.solution.find({ datasetId }).lean()) || [];
168
- const solutionsKeyed = {};
169
- for (const solution of solutions) {
170
- solutionsKeyed[solution.captchaId] = solution;
171
- }
172
- return {
173
- datasetId,
174
- datasetContentId,
175
- format,
176
- contentTree: contentTree || [],
177
- solutionTree: solutionTree || [],
178
- captchas: captchas.map((captchaDoc) => {
179
- const { captchaId, captchaContentId, items, target, salt, solved } = captchaDoc;
180
- const solution = solutionsKeyed[captchaId];
181
- return {
182
- captchaId,
183
- captchaContentId,
184
- solved: !!solved,
185
- salt,
186
- items,
187
- target,
188
- solution: solved && solution ? solution.solution : [],
189
- };
190
- }),
191
- };
192
- }
193
- throw new ProsopoDBError("DATABASE.DATASET_GET_FAILED", {
194
- context: { failedFuncName: this.getDataset.name, datasetId },
195
- });
196
- }
197
- async getRandomCaptcha(solved, datasetId, size) {
198
- if (!isHex(datasetId)) {
199
- throw new ProsopoDBError("DATABASE.INVALID_HASH", {
200
- context: { failedFuncName: this.getRandomCaptcha.name, datasetId },
201
- });
202
- }
203
- const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
204
- const cursor = this.tables?.captcha.aggregate([
205
- { $match: { datasetId, solved } },
206
- { $sample: { size: sampleSize } },
207
- {
208
- $project: {
209
- datasetId: 1,
210
- datasetContentId: 1,
211
- captchaId: 1,
212
- captchaContentId: 1,
213
- items: 1,
214
- target: 1,
215
- },
216
- },
217
- ]);
218
- const docs = await cursor;
219
- if (docs?.length) {
220
- return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
221
- }
222
- throw new ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
223
- context: {
224
- failedFuncName: this.getRandomCaptcha.name,
225
- solved,
226
- datasetId,
227
- size,
228
- },
229
- });
230
- }
231
- async getCaptchaById(captchaId) {
232
- const cursor = this.tables?.captcha
233
- .find({ captchaId: { $in: captchaId } })
234
- .lean();
235
- const docs = await cursor;
236
- if (docs?.length) {
237
- return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
238
- }
239
- throw new ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
240
- context: { failedFuncName: this.getCaptchaById.name, captchaId },
241
- });
242
- }
243
- async updateCaptcha(captcha, datasetId) {
244
- if (!isHex(datasetId)) {
245
- throw new ProsopoDBError("DATABASE.INVALID_HASH", {
246
- context: { failedFuncName: this.updateCaptcha.name, datasetId },
247
- });
248
- }
249
- try {
250
- await this.tables?.captcha.updateOne({ datasetId }, { $set: captcha }, { upsert: false });
251
- }
252
- catch (err) {
253
- throw new ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
254
- context: { failedFuncName: this.getDatasetDetails.name, error: err },
255
- });
256
- }
257
- }
258
- async removeCaptchas(captchaIds) {
259
- await this.tables?.captcha.deleteMany({ captchaId: { $in: captchaIds } });
260
- }
261
- async getDatasetDetails(datasetId) {
262
- if (!isHex(datasetId)) {
263
- throw new ProsopoDBError("DATABASE.INVALID_HASH", {
264
- context: { failedFuncName: this.getDatasetDetails.name, datasetId },
265
- });
266
- }
267
- const doc = await this.tables?.dataset
268
- .findOne({ datasetId })
269
- .lean();
270
- if (doc) {
271
- return doc;
272
- }
273
- throw new ProsopoDBError("DATABASE.DATASET_GET_FAILED", {
274
- context: {
275
- failedFuncName: this.getDatasetDetails.name,
276
- datasetId,
277
- },
278
- });
279
- }
280
- async storeDappUserSolution(captchas, commit) {
281
- const commitmentRecord = UserCommitmentSchema.parse(commit);
282
- if (captchas.length) {
283
- await this.tables?.commitment.updateOne({
284
- id: commit.id,
285
- }, commitmentRecord, { upsert: true });
286
- const ops = captchas.map((captcha) => ({
287
- updateOne: {
288
- filter: { commitmentId: commit.id, captchaId: captcha.captchaId },
289
- update: {
290
- $set: {
291
- captchaId: captcha.captchaId,
292
- captchaContentId: captcha.captchaContentId,
293
- salt: captcha.salt,
294
- solution: captcha.solution,
295
- commitmentId: commit.id,
296
- processed: false,
297
- },
298
- },
299
- upsert: true,
300
- },
301
- }));
302
- await this.tables?.usersolution.bulkWrite(ops);
303
- }
304
- }
305
- async storePowCaptchaRecord(challenge, checked) {
306
- const tables = this.getTables();
307
- const powCaptchaRecord = {
308
- challenge,
309
- checked,
310
- };
311
- try {
312
- await tables.powCaptcha.create(powCaptchaRecord);
313
- this.logger.info("PowCaptcha record added successfully", {
314
- challenge,
315
- checked,
316
- });
317
- }
318
- catch (error) {
319
- this.logger.error("Failed to add PowCaptcha record", {
320
- error,
321
- challenge,
322
- checked,
323
- });
324
- throw new ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
325
- context: { error, challenge, checked },
326
- logger: this.logger,
327
- });
328
- }
329
- }
330
- async getPowCaptchaRecordByChallenge(challenge) {
331
- if (!this.tables) {
332
- throw new ProsopoEnvError("DATABASE.DATABASE_UNDEFINED", {
333
- context: { failedFuncName: this.getPowCaptchaRecordByChallenge.name },
334
- logger: this.logger,
335
- });
336
- }
337
- try {
338
- const record = await this.tables.powCaptcha
339
- .findOne({ challenge })
340
- .lean();
341
- if (record) {
342
- this.logger.info("PowCaptcha record retrieved successfully", {
343
- challenge,
344
- });
345
- return record;
346
- }
347
- this.logger.info("No PowCaptcha record found", { challenge });
348
- return null;
349
- }
350
- catch (error) {
351
- this.logger.error("Failed to retrieve PowCaptcha record", {
352
- error,
353
- challenge,
354
- });
355
- throw new ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
356
- context: { error, challenge },
357
- logger: this.logger,
358
- });
359
- }
360
- }
361
- async updatePowCaptchaRecord(challenge, checked) {
362
- const tables = this.getTables();
363
- try {
364
- const updateResult = await tables.powCaptcha.updateOne({ challenge }, { $set: { checked } });
365
- if (updateResult.matchedCount === 0) {
366
- this.logger.info("No PowCaptcha record found to update", {
367
- challenge,
368
- checked,
369
- });
370
- throw new ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
371
- context: { challenge, checked },
372
- logger: this.logger,
373
- });
374
- }
375
- this.logger.info("PowCaptcha record updated successfully", {
376
- challenge,
377
- checked,
378
- });
379
- }
380
- catch (error) {
381
- this.logger.error("Failed to update PowCaptcha record", {
382
- error,
383
- challenge,
384
- checked,
385
- });
386
- throw new ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
387
- context: { error, challenge, checked },
388
- logger: this.logger,
389
- });
390
- }
391
- }
392
- async getProcessedDappUserSolutions() {
393
- const docs = await this.tables?.usersolution
394
- .find({ processed: true })
395
- .lean();
396
- return docs ? docs.map((doc) => UserSolutionSchema.parse(doc)) : [];
397
- }
398
- async getProcessedDappUserCommitments() {
399
- const docs = await this.tables?.commitment.find({ processed: true }).lean();
400
- return docs ? docs.map((doc) => UserCommitmentSchema.parse(doc)) : [];
401
- }
402
- async getUnbatchedDappUserCommitments() {
403
- const docs = await this.tables?.commitment.find({ batched: false }).lean();
404
- return docs ? docs.map((doc) => UserCommitmentSchema.parse(doc)) : [];
405
- }
406
- async getUnstoredDappUserCommitments() {
407
- const docs = await this.tables?.commitment
408
- .find({
409
- $or: [{ stored: false }, { stored: { $exists: false } }],
410
- })
411
- .lean();
412
- return docs ? docs.map((doc) => UserCommitmentSchema.parse(doc)) : [];
413
- }
414
- async markDappUserCommitmentsStored(commitmentIds) {
415
- await this.tables?.commitment.updateMany({ id: { $in: commitmentIds } }, { $set: { stored: true } }, { upsert: false });
416
- }
417
- async getBatchedDappUserCommitments() {
418
- const docs = await this.tables?.commitment.find({ batched: true }).lean();
419
- return docs ? docs.map((doc) => UserCommitmentSchema.parse(doc)) : [];
420
- }
421
- async removeProcessedDappUserSolutions(commitmentIds) {
422
- return await this.tables?.usersolution.deleteMany({
423
- processed: true,
424
- commitmentId: { $in: commitmentIds },
425
- });
426
- }
427
- async removeProcessedDappUserCommitments(commitmentIds) {
428
- return await this.tables?.commitment.deleteMany({
429
- processed: true,
430
- id: { $in: commitmentIds },
431
- });
432
- }
433
- async storeDappUserPending(userAccount, requestHash, salt, deadlineTimestamp, requestedAtBlock) {
434
- if (!isHex(requestHash)) {
435
- throw new ProsopoDBError("DATABASE.INVALID_HASH", {
436
- context: {
437
- failedFuncName: this.storeDappUserPending.name,
438
- requestHash,
439
- },
440
- });
441
- }
442
- const pendingRecord = {
443
- accountId: userAccount,
444
- pending: true,
445
- salt,
446
- requestHash,
447
- deadlineTimestamp,
448
- requestedAtBlock,
449
- };
450
- await this.tables?.pending.updateOne({ requestHash: requestHash }, { $set: pendingRecord }, { upsert: true });
451
- }
452
- async getDappUserPending(requestHash) {
453
- if (!isHex(requestHash)) {
454
- throw new ProsopoEnvError("DATABASE.INVALID_HASH", {
455
- context: { failedFuncName: this.getDappUserPending.name, requestHash },
456
- });
457
- }
458
- const doc = await this.tables?.pending.findOne({ requestHash: requestHash }).lean();
459
- if (doc) {
460
- return doc;
461
- }
462
- throw new ProsopoEnvError("DATABASE.PENDING_RECORD_NOT_FOUND", {
463
- context: { failedFuncName: this.getDappUserPending.name, requestHash },
464
- });
465
- }
466
- async updateDappUserPendingStatus(requestHash) {
467
- if (!isHex(requestHash)) {
468
- throw new ProsopoEnvError("DATABASE.INVALID_HASH", {
469
- context: {
470
- failedFuncName: this.updateDappUserPendingStatus.name,
471
- requestHash,
472
- },
473
- });
474
- }
475
- await this.tables?.pending.updateOne({ requestHash: requestHash }, {
476
- $set: {
477
- pending: false,
478
- },
479
- }, { upsert: true });
480
- }
481
- async getAllCaptchasByDatasetId(datasetId, state) {
482
- const cursor = this.tables?.captcha
483
- .find({
484
- datasetId,
485
- solved: state === CaptchaStates.Solved,
486
- })
487
- .lean();
488
- const docs = await cursor;
489
- if (docs) {
490
- return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
491
- }
492
- throw new ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED");
493
- }
494
- async getAllDappUserSolutions(captchaId) {
495
- const cursor = this.tables?.usersolution
496
- ?.find({ captchaId: { $in: captchaId } })
497
- .lean();
498
- const docs = await cursor;
499
- if (docs) {
500
- return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
501
- }
502
- throw new ProsopoEnvError("DATABASE.SOLUTION_GET_FAILED");
503
- }
504
- async getDatasetIdWithSolvedCaptchasOfSizeN(solvedCaptchaCount) {
505
- const cursor = this.tables?.solution.aggregate([
506
- {
507
- $match: {},
508
- },
509
- {
510
- $group: {
511
- _id: "$datasetId",
512
- count: { $sum: 1 },
513
- },
514
- },
515
- {
516
- $match: {
517
- count: { $gte: solvedCaptchaCount },
518
- },
519
- },
520
- {
521
- $sample: { size: 1 },
522
- },
523
- ]);
524
- const docs = await cursor;
525
- if (docs?.length) {
526
- return docs[0]._id;
527
- }
528
- throw new ProsopoDBError("DATABASE.DATASET_WITH_SOLUTIONS_GET_FAILED");
529
- }
530
- async getRandomSolvedCaptchasFromSingleDataset(datasetId, size) {
531
- if (!isHex(datasetId)) {
532
- throw new ProsopoDBError("DATABASE.INVALID_HASH", {
533
- context: {
534
- failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
535
- datasetId,
536
- },
537
- });
538
- }
539
- const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
540
- const cursor = this.tables?.solution.aggregate([
541
- { $match: { datasetId } },
542
- { $sample: { size: sampleSize } },
543
- {
544
- $project: {
545
- captchaId: 1,
546
- captchaContentId: 1,
547
- solution: 1,
548
- },
549
- },
550
- ]);
551
- const docs = await cursor;
552
- if (docs?.length) {
553
- return docs;
554
- }
555
- throw new ProsopoDBError("DATABASE.SOLUTION_GET_FAILED", {
556
- context: {
557
- failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
558
- datasetId,
559
- size,
560
- },
561
- });
562
- }
563
- async getDappUserSolutionById(commitmentId) {
564
- const cursor = this.tables?.usersolution
565
- ?.findOne({
566
- commitmentId: commitmentId,
567
- }, { projection: { _id: 0 } })
568
- .lean();
569
- const doc = await cursor;
570
- if (doc) {
571
- return doc;
572
- }
573
- throw new ProsopoDBError("DATABASE.SOLUTION_GET_FAILED", {
574
- context: { failedFuncName: this.getCaptchaById.name, commitmentId },
575
- });
576
- }
577
- async getDappUserCommitmentById(commitmentId) {
578
- const commitmentCursor = this.tables?.commitment
579
- ?.findOne({ id: commitmentId })
580
- .lean();
581
- const doc = await commitmentCursor;
582
- return doc ? UserCommitmentSchema.parse(doc) : undefined;
583
- }
584
- async getDappUserCommitmentByAccount(userAccount) {
585
- const docs = await this.tables?.commitment
586
- ?.find({ userAccount }, { _id: 0 }, { sort: { _id: -1 } })
587
- .lean();
588
- return docs ? docs : [];
589
- }
590
- async approveDappUserCommitment(commitmentId) {
591
- try {
592
- await this.tables?.commitment
593
- ?.findOneAndUpdate({ id: commitmentId }, { $set: { status: CaptchaStatus.approved } }, { upsert: false })
594
- .lean();
595
- }
596
- catch (err) {
597
- throw new ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", {
598
- context: { error: err, commitmentId },
599
- });
600
- }
601
- }
602
- async flagProcessedDappUserSolutions(captchaIds) {
603
- try {
604
- await this.tables?.usersolution
605
- ?.updateMany({ captchaId: { $in: captchaIds } }, { $set: { processed: true } }, { upsert: false })
606
- .lean();
607
- }
608
- catch (err) {
609
- throw new ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", {
610
- context: { error: err, captchaIds },
611
- });
612
- }
613
- }
614
- async flagProcessedDappUserCommitments(commitmentIds) {
615
- try {
616
- const distinctCommitmentIds = [...new Set(commitmentIds)];
617
- await this.tables?.commitment
618
- ?.updateMany({ id: { $in: distinctCommitmentIds } }, { $set: { processed: true } }, { upsert: false })
619
- .lean();
620
- }
621
- catch (err) {
622
- throw new ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
623
- context: { error: err, commitmentIds },
624
- });
625
- }
626
- }
627
- async flagBatchedDappUserCommitments(commitmentIds) {
628
- try {
629
- const distinctCommitmentIds = [...new Set(commitmentIds)];
630
- await this.tables?.commitment
631
- ?.updateMany({ id: { $in: distinctCommitmentIds } }, { $set: { batched: true } }, { upsert: false })
632
- .lean();
633
- }
634
- catch (err) {
635
- throw new ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
636
- context: { error: err, commitmentIds },
637
- });
638
- }
639
- }
640
- async getLastBatchCommitTime() {
641
- const cursor = this.tables?.scheduler
642
- ?.findOne({
643
- processName: ScheduledTaskNames.BatchCommitment,
644
- status: ScheduledTaskStatus.Completed,
645
- })
646
- .sort({ timestamp: -1 });
647
- const doc = await cursor?.lean();
648
- if (doc) {
649
- return doc.datetime;
650
- }
651
- return new Date(0);
652
- }
653
- async getScheduledTaskStatus(taskId, status) {
654
- const cursor = await this.tables?.scheduler
655
- ?.findOne({ taskId: taskId, status: status })
656
- .lean();
657
- return cursor ? cursor : undefined;
658
- }
659
- async getLastScheduledTaskStatus(task, status) {
660
- const lookup = { processName: task };
661
- if (status) {
662
- lookup.status = status;
663
- }
664
- const cursor = await this.tables?.scheduler
665
- ?.findOne(lookup)
666
- .sort({ datetime: -1 })
667
- .lean();
668
- return cursor ? cursor : undefined;
669
- }
670
- async storeScheduledTaskStatus(taskId, task, status, result) {
671
- const now = new Date();
672
- const doc = ScheduledTaskSchema.parse({
673
- taskId,
674
- processName: task,
675
- datetime: now,
676
- status,
677
- ...(result && { result }),
678
- });
679
- await this.tables?.scheduler.create(doc);
680
- }
681
- }
682
- //# sourceMappingURL=mongo.js.map