@prosopo/datasets 3.1.53 → 3.1.55

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/datasets@3.1.53 build:cjs
2
+ > @prosopo/datasets@3.1.55 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -23,20 +23,22 @@ ViteCommonJSConfig: .
23
23
  '@prosopo/util-crypto'
24
24
  ]
25
25
  }
26
- vite v6.4.1 building SSR bundle for production...
26
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
27
+ vite v8.1.5 building ssr environment for production...
27
28
  Bundle build started
28
- transforming...
29
- Build end
30
- ✓ 7 modules transformed.
29
+ 
30
+ ✓ 8 modules transformed.
31
31
  rendering chunks...
32
- dist/cjs/captcha/util.cjs  0.69 kB
33
- dist/cjs/captcha/index.cjs  1.48 kB
34
- dist/cjs/index.cjs  1.74 kB
35
- dist/cjs/captcha/dataset.cjs  3.41 kB
36
- dist/cjs/captcha/merkle.cjs  3.70 kB
37
- dist/cjs/captcha/captcha.cjs  6.76 kB
38
- dist/cjs/tests/mocks/data/captchas.cjs 45.41 kB
39
- ✓ built in 295ms
32
+ computing gzip size...
33
+ dist/cjs/captcha/util.cjs 0.59 kB │ gzip: 0.36 kB
34
+ dist/cjs/captcha/index.cjs 1.58 kB │ gzip: 0.40 kB
35
+ dist/cjs/index.cjs 1.92 kB │ gzip: 0.49 kB
36
+ dist/cjs/captcha/dataset.cjs 3.22 kB │ gzip: 1.03 kB
37
+ dist/cjs/captcha/merkle.cjs 3.44 kB │ gzip: 1.10 kB
38
+ dist/cjs/captcha/captcha.cjs 7.89 kB │ gzip: 2.27 kB
39
+ dist/cjs/tests/mocks/data/captchas.cjs 41.00 kB │ gzip: 5.46 kB
40
+
41
+ ✓ built in 74ms
40
42
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/datasets/src/tests/mocks/data/captchas.json to /home/runner/work/captcha/captcha/packages/datasets/dist/tests/mocks/data/captchas.json
41
43
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/datasets/src/tests/mocks/data/captchas1.json to /home/runner/work/captcha/captcha/packages/datasets/dist/tests/mocks/data/captchas1.json
42
44
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/datasets/src/tests/mocks/data/captchas2.json to /home/runner/work/captcha/captcha/packages/datasets/dist/tests/mocks/data/captchas2.json
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/datasets@3.1.53 build:tsc
2
+ > @prosopo/datasets@3.1.55 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 12:17:12 PM - Projects in this build:
5
+ 8:59:11 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -12,21 +12,21 @@
12
12
  * ../common/tsconfig.json
13
13
  * tsconfig.json
14
14
 
15
- 12:17:12 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/index.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
15
+ 8:59:11 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
16
16
 
17
- 12:17:12 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
17
+ 8:59:11 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
18
18
 
19
- 12:17:12 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
19
+ 8:59:11 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
20
20
 
21
- 12:17:12 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
21
+ 8:59:11 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
22
22
 
23
- 12:17:12 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
23
+ 8:59:11 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
24
24
 
25
- 12:17:12 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
25
+ 8:59:11 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
26
26
 
27
- 12:17:12 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
27
+ 8:59:11 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/batches.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
28
28
 
29
- 12:17:12 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
29
+ 8:59:11 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
30
30
 
31
- 12:17:12 PM - Building project '/home/runner/work/captcha/captcha/packages/datasets/tsconfig.json'...
31
+ 8:59:11 PM - Building project '/home/runner/work/captcha/captcha/packages/datasets/tsconfig.json'...
32
32
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/datasets@3.1.53 build
2
+ > @prosopo/datasets@3.1.55 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/datasets@3.1.53 build:cross-env
6
+ > @prosopo/datasets@3.1.55 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -27,20 +27,23 @@ ViteEsmConfig: .
27
27
  '@prosopo/util-crypto'
28
28
  ]
29
29
  }
30
- vite v6.4.1 building SSR bundle for production...
30
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
31
+ vite v8.1.5 building ssr environment for production...
31
32
  Bundle build started
32
- transforming...
33
- Build end
34
- ✓ 7 modules transformed.
33
+ 
34
+ ✓ 8 modules transformed.
35
35
  rendering chunks...
36
- dist/captcha/util.js  0.61 kB
37
- dist/captcha/index.js  1.05 kB
38
- dist/index.js  1.27 kB
39
- dist/captcha/dataset.js  3.17 kB
40
- dist/captcha/merkle.js  3.47 kB
41
- dist/captcha/captcha.js  6.25 kB
42
- dist/tests/mocks/data/captchas.js 45.27 kB
43
- ✓ built in 271ms
36
+ computing gzip size...
37
+ dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
38
+ dist/captcha/util.js 0.57 kB │ gzip: 0.36 kB
39
+ dist/captcha/index.js 1.00 kB │ gzip: 0.31 kB
40
+ dist/index.js 1.23 kB │ gzip: 0.37 kB
41
+ dist/captcha/dataset.js 2.99 kB │ gzip: 0.98 kB
42
+ dist/captcha/merkle.js 3.07 kB │ gzip: 1.06 kB
43
+ dist/captcha/captcha.js 7.19 kB │ gzip: 2.19 kB
44
+ dist/tests/mocks/data/captchas.js 40.94 kB │ gzip: 5.44 kB
45
+
46
+ ✓ built in 99ms
44
47
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/datasets/src/tests/mocks/data/captchas.json to /home/runner/work/captcha/captcha/packages/datasets/dist/tests/mocks/data/captchas.json
45
48
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/datasets/src/tests/mocks/data/captchas1.json to /home/runner/work/captcha/captcha/packages/datasets/dist/tests/mocks/data/captchas1.json
46
49
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/datasets/src/tests/mocks/data/captchas2.json to /home/runner/work/captcha/captcha/packages/datasets/dist/tests/mocks/data/captchas2.json
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @prosopo/datasets
2
2
 
3
+ ## 3.1.55
4
+ ### Patch Changes
5
+
6
+ - e14fce6: chore(deps): bump vite to 6.4.3 and mongoose to 8.24.1, and adjust types for the mongoose 8.24 Document/ObjectId changes
7
+ - Updated dependencies [2c47bb7]
8
+ - Updated dependencies [0e1171c]
9
+ - Updated dependencies [103318c]
10
+ - Updated dependencies [270a8d8]
11
+ - Updated dependencies [e14fce6]
12
+ - @prosopo/util@3.3.5
13
+ - @prosopo/types@4.10.0
14
+ - @prosopo/common@3.1.48
15
+ - @prosopo/logger@2.0.4
16
+
17
+ ## 3.1.54
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [a0cb39e]
21
+ - @prosopo/types@4.9.12
22
+
3
23
  ## 3.1.53
4
24
  ### Patch Changes
5
25
 
@@ -0,0 +1,3 @@
1
+ import "node:module";
2
+ //#endregion
3
+ export {};
@@ -1,195 +1,198 @@
1
+ import { downloadImage } from "./util.js";
1
2
  import { isHex } from "@polkadot/util";
2
3
  import { ProsopoDatasetError, ProsopoEnvError } from "@prosopo/common";
3
- import { DatasetWithNumericSolutionSchema, CaptchaSolutionArraySchema } from "@prosopo/types";
4
+ import { CaptchaSolutionArraySchema, DatasetWithNumericSolutionSchema } from "@prosopo/types";
4
5
  import { at } from "@prosopo/util";
5
- import { hexHashArray, hexHash } from "@prosopo/util-crypto";
6
- import { downloadImage } from "./util.js";
7
- const NO_SOLUTION_VALUE = "NO_SOLUTION";
6
+ import { hexHash, hexHashArray } from "@prosopo/util-crypto";
7
+ //#region src/captcha/captcha.ts
8
+ var NO_SOLUTION_VALUE = "NO_SOLUTION";
9
+ /**
10
+ * Parse a dataset
11
+ * @return {JSON} captcha dataset, stored in JSON
12
+ * @param datasetJSON
13
+ */
8
14
  function parseCaptchaDataset(datasetJSON) {
9
- try {
10
- const result = DatasetWithNumericSolutionSchema.parse(datasetJSON);
11
- const result2 = {
12
- format: result.format,
13
- captchas: result.captchas.map((captcha) => {
14
- return {
15
- ...captcha,
16
- solution: captcha.solution ? matchItemsToSolutions(captcha.solution, captcha.items) : [],
17
- unlabelled: captcha.unlabelled ? matchItemsToSolutions(captcha.unlabelled, captcha.items) : []
18
- };
19
- })
20
- };
21
- if (result.datasetId !== void 0) result2.datasetId = result.datasetId;
22
- if (result.contentTree !== void 0)
23
- result2.contentTree = result.contentTree;
24
- if (result.datasetContentId !== void 0)
25
- result2.datasetContentId = result.datasetContentId;
26
- if (result.solutionTree !== void 0)
27
- result2.solutionTree = result.solutionTree;
28
- return result2;
29
- } catch (err) {
30
- throw new ProsopoDatasetError("DATASET.DATASET_PARSE_ERROR", {
31
- context: { error: err }
32
- });
33
- }
15
+ try {
16
+ const result = DatasetWithNumericSolutionSchema.parse(datasetJSON);
17
+ const result2 = {
18
+ format: result.format,
19
+ captchas: result.captchas.map((captcha) => {
20
+ return {
21
+ ...captcha,
22
+ solution: captcha.solution ? matchItemsToSolutions(captcha.solution, captcha.items) : [],
23
+ unlabelled: captcha.unlabelled ? matchItemsToSolutions(captcha.unlabelled, captcha.items) : []
24
+ };
25
+ })
26
+ };
27
+ if (result.datasetId !== void 0) result2.datasetId = result.datasetId;
28
+ if (result.contentTree !== void 0) result2.contentTree = result.contentTree;
29
+ if (result.datasetContentId !== void 0) result2.datasetContentId = result.datasetContentId;
30
+ if (result.solutionTree !== void 0) result2.solutionTree = result.solutionTree;
31
+ return result2;
32
+ } catch (err) {
33
+ throw new ProsopoDatasetError("DATASET.DATASET_PARSE_ERROR", { context: { error: err } });
34
+ }
34
35
  }
36
+ /**
37
+ * Make sure captcha solutions are in the correct format
38
+ * @param {JSON} captchaJSON captcha solutions received from the api
39
+ * @return {CaptchaSolution[]} an array of parsed and sorted captcha solutions
40
+ */
35
41
  function parseAndSortCaptchaSolutions(captchaJSON) {
36
- try {
37
- return CaptchaSolutionArraySchema.parse(captchaJSON).map((captcha) => ({
38
- ...captcha,
39
- solution: captcha.solution.sort()
40
- }));
41
- } catch (err) {
42
- throw new ProsopoDatasetError("DATASET.SOLUTION_PARSE_ERROR", {
43
- context: { error: err }
44
- });
45
- }
42
+ try {
43
+ return CaptchaSolutionArraySchema.parse(captchaJSON).map((captcha) => ({
44
+ ...captcha,
45
+ solution: captcha.solution.sort()
46
+ }));
47
+ } catch (err) {
48
+ throw new ProsopoDatasetError("DATASET.SOLUTION_PARSE_ERROR", { context: { error: err } });
49
+ }
46
50
  }
47
51
  function captchaSort(a, b) {
48
- return a.captchaId.localeCompare(b.captchaId);
52
+ return a.captchaId.localeCompare(b.captchaId);
49
53
  }
50
54
  function sortAndComputeHashes(received, stored) {
51
- received.sort(captchaSort);
52
- stored.sort(captchaSort);
53
- return stored.map(
54
- ({ salt, items = [], target = "", captchaId, solved }, index) => {
55
- const item = at(received, index);
56
- if (captchaId !== item.captchaId) {
57
- throw new ProsopoEnvError("CAPTCHA.ID_MISMATCH");
58
- }
59
- return {
60
- hash: computeCaptchaHash(
61
- {
62
- solution: solved ? item.solution : [],
63
- salt,
64
- items,
65
- target
66
- },
67
- true,
68
- true,
69
- false
70
- ),
71
- captchaId
72
- };
73
- }
74
- );
55
+ received.sort(captchaSort);
56
+ stored.sort(captchaSort);
57
+ return stored.map(({ salt, items = [], target = "", captchaId, solved }, index) => {
58
+ const item = at(received, index);
59
+ if (captchaId !== item.captchaId) throw new ProsopoEnvError("CAPTCHA.ID_MISMATCH");
60
+ return {
61
+ hash: computeCaptchaHash({
62
+ solution: solved ? item.solution : [],
63
+ salt,
64
+ items,
65
+ target
66
+ }, true, true, false),
67
+ captchaId
68
+ };
69
+ });
75
70
  }
71
+ /**
72
+ * Take an array of CaptchaSolutions and Captchas and check if the solutions are the same for each pair
73
+ * @param {CaptchaSolution[]} received
74
+ * @param solutions
75
+ * @param totalImages
76
+ * @param {number} threshold the percentage of captchas that must be correct to return true
77
+ * @return {boolean}
78
+ */
76
79
  function compareCaptchaSolutions(received, solutions, totalImages, threshold) {
77
- received.sort(captchaSort);
78
- solutions.sort(captchaSort);
79
- if (received.length !== solutions.length) {
80
- return false;
81
- }
82
- if (received.length && solutions.length && received.length === solutions.length) {
83
- const captchaIdMismatch = received.some(
84
- (captcha, index) => solutions[index] && captcha.captchaId !== solutions[index].captchaId
85
- );
86
- if (captchaIdMismatch) {
87
- return false;
88
- }
89
- }
90
- return received.every((captcha, index) => {
91
- const sortedReceivedSolution = captcha.solution.sort();
92
- const targetSolution = solutions[index]?.solution.sort();
93
- if (!targetSolution) {
94
- return false;
95
- }
96
- const incorrectCount = sortedReceivedSolution.filter(
97
- (solution) => !targetSolution.includes(solution)
98
- ).length;
99
- const missingCount = targetSolution.filter(
100
- (solution) => !sortedReceivedSolution.includes(solution)
101
- ).length;
102
- const totalIncorrect = incorrectCount + missingCount;
103
- const percentageCorrect = 1 - totalIncorrect / totalImages;
104
- return percentageCorrect >= threshold;
105
- });
80
+ received.sort(captchaSort);
81
+ solutions.sort(captchaSort);
82
+ if (received.length !== solutions.length) return false;
83
+ if (received.length && solutions.length && received.length === solutions.length) {
84
+ if (received.some((captcha, index) => solutions[index] && captcha.captchaId !== solutions[index].captchaId)) return false;
85
+ }
86
+ return received.every((captcha, index) => {
87
+ const sortedReceivedSolution = captcha.solution.sort();
88
+ const targetSolution = solutions[index]?.solution.sort();
89
+ if (!targetSolution) return false;
90
+ return 1 - (sortedReceivedSolution.filter((solution) => !targetSolution.includes(solution)).length + targetSolution.filter((solution) => !sortedReceivedSolution.includes(solution)).length) / totalImages >= threshold;
91
+ });
106
92
  }
93
+ /**
94
+ * Compute the hash of various types of captcha
95
+ * @param {Captcha} captcha
96
+ * @param {boolean} includeSolution
97
+ * @param {boolean} includeSalt
98
+ * @param {boolean} sortItemHashes
99
+ * @return {string} the hex string hash
100
+ */
107
101
  function computeCaptchaHash(captcha, includeSolution, includeSalt, sortItemHashes) {
108
- try {
109
- const itemHashes = captcha.items.map((item, index) => {
110
- if (item.hash) {
111
- return item.hash;
112
- }
113
- throw new ProsopoDatasetError("CAPTCHA.MISSING_ITEM_HASH", {
114
- context: {
115
- computeCaptchaHashName: computeCaptchaHash.name,
116
- index
117
- }
118
- });
119
- });
120
- return hexHashArray([
121
- captcha.target,
122
- // empty array hashes as empty string, undefined solution results in the array [`NO_SOLUTION`]
123
- // [undefined] also hashes as empty string, which is why we don't use it
124
- ...includeSolution ? getSolutionValueToHash(captcha.solution) : [],
125
- includeSalt ? captcha.salt : "",
126
- sortItemHashes ? itemHashes.sort() : itemHashes
127
- ]);
128
- } catch (err) {
129
- throw new ProsopoDatasetError("DATASET.HASH_ERROR", {
130
- context: { error: err }
131
- });
132
- }
102
+ try {
103
+ const itemHashes = captcha.items.map((item, index) => {
104
+ if (item.hash) return item.hash;
105
+ throw new ProsopoDatasetError("CAPTCHA.MISSING_ITEM_HASH", { context: {
106
+ computeCaptchaHashName: computeCaptchaHash.name,
107
+ index
108
+ } });
109
+ });
110
+ return hexHashArray([
111
+ captcha.target,
112
+ ...includeSolution ? getSolutionValueToHash(captcha.solution) : [],
113
+ includeSalt ? captcha.salt : "",
114
+ sortItemHashes ? itemHashes.sort() : itemHashes
115
+ ]);
116
+ } catch (err) {
117
+ throw new ProsopoDatasetError("DATASET.HASH_ERROR", { context: { error: err } });
118
+ }
133
119
  }
120
+ /** Return the sorted solution value or ['NO_SOLUTION'] if there is no solution. Ensures that an empty array is a valid
121
+ * solution
122
+ * @param solution
123
+ */
134
124
  function getSolutionValueToHash(solution) {
135
- return solution !== void 0 ? solution.sort() : [NO_SOLUTION_VALUE];
125
+ return solution !== void 0 ? solution.sort() : [NO_SOLUTION_VALUE];
136
126
  }
127
+ /** Compute the hash of a captcha item, downloading the image if necessary
128
+ * @param {Item} item
129
+ * @return {Promise<HashedItem>} the hex string hash of the item
130
+ */
137
131
  async function computeItemHash(item) {
138
- if (item.type === "text") {
139
- return { ...item, hash: hexHash(item.data) };
140
- }
141
- if (item.type === "image") {
142
- return { ...item, hash: hexHash(await downloadImage(item.data)) };
143
- }
144
- throw new ProsopoDatasetError("CAPTCHA.INVALID_ITEM_FORMAT");
132
+ if (item.type === "text") return {
133
+ ...item,
134
+ hash: hexHash(item.data)
135
+ };
136
+ if (item.type === "image") return {
137
+ ...item,
138
+ hash: hexHash(await downloadImage(item.data))
139
+ };
140
+ throw new ProsopoDatasetError("CAPTCHA.INVALID_ITEM_FORMAT");
145
141
  }
142
+ /**
143
+ * Converts an indexed captcha solution to a hashed captcha solution or simply returns the hash if it is already hashed
144
+ * @return {HashedSolution[]}
145
+ * @param {RawSolution[] | HashedSolution[]} solutions
146
+ * @param {Item[]} items
147
+ */
146
148
  function matchItemsToSolutions(solutions, items) {
147
- if (!items) {
148
- return [];
149
- }
150
- return solutions.map((solution) => {
151
- if (typeof solution === "string" && isHex(solution)) {
152
- if (!items?.some((item) => item.hash === solution)) {
153
- throw new ProsopoDatasetError("CAPTCHA.INVALID_ITEM_HASH");
154
- }
155
- return solution;
156
- }
157
- if (typeof solution === "number") {
158
- const item = at(items, solution);
159
- return item.hash;
160
- }
161
- throw new ProsopoDatasetError("CAPTCHA.INVALID_SOLUTION_TYPE");
162
- });
149
+ if (!items) return [];
150
+ return solutions.map((solution) => {
151
+ if (typeof solution === "string" && isHex(solution)) {
152
+ if (!items?.some((item) => item.hash === solution)) throw new ProsopoDatasetError("CAPTCHA.INVALID_ITEM_HASH");
153
+ return solution;
154
+ }
155
+ if (typeof solution === "number") return at(items, solution).hash;
156
+ throw new ProsopoDatasetError("CAPTCHA.INVALID_SOLUTION_TYPE");
157
+ });
163
158
  }
159
+ /**
160
+ * Create a unique solution commitment
161
+ * @param {CaptchaSolution} captcha
162
+ * @return {string} the hex string hash
163
+ */
164
164
  function computeCaptchaSolutionHash(captcha) {
165
- return hexHashArray([
166
- captcha.captchaId,
167
- captcha.captchaContentId,
168
- [...captcha.solution].sort(),
169
- captcha.salt
170
- ]);
165
+ return hexHashArray([
166
+ captcha.captchaId,
167
+ captcha.captchaContentId,
168
+ [...captcha.solution].sort(),
169
+ captcha.salt
170
+ ]);
171
171
  }
172
+ /**
173
+ * Compute hash for an array of captcha ids, userAccount, and salt, which serves as the identifier for a pending request
174
+ * @param {string[]} captchaIds
175
+ * @param {string} userAccount
176
+ * @param {string} salt
177
+ * @return {string}
178
+ */
172
179
  function computePendingRequestHash(captchaIds, userAccount, salt) {
173
- return hexHashArray([...captchaIds.sort(), userAccount, salt]);
180
+ return hexHashArray([
181
+ ...captchaIds.sort(),
182
+ userAccount,
183
+ salt
184
+ ]);
174
185
  }
186
+ /**
187
+ * Parse the image items in a captcha and pass back a URI if they exist
188
+ * @param {Item} item
189
+ * @param {AssetsResolver} assetsResolver
190
+ */
175
191
  function parseCaptchaAssets(item, assetsResolver) {
176
- return {
177
- ...item,
178
- data: assetsResolver?.resolveAsset(item.data).getURL() || item.data
179
- };
192
+ return {
193
+ ...item,
194
+ data: assetsResolver?.resolveAsset(item.data).getURL() || item.data
195
+ };
180
196
  }
181
- export {
182
- NO_SOLUTION_VALUE,
183
- captchaSort,
184
- compareCaptchaSolutions,
185
- computeCaptchaHash,
186
- computeCaptchaSolutionHash,
187
- computeItemHash,
188
- computePendingRequestHash,
189
- getSolutionValueToHash,
190
- matchItemsToSolutions,
191
- parseAndSortCaptchaSolutions,
192
- parseCaptchaAssets,
193
- parseCaptchaDataset,
194
- sortAndComputeHashes
195
- };
197
+ //#endregion
198
+ export { NO_SOLUTION_VALUE, captchaSort, compareCaptchaSolutions, computeCaptchaHash, computeCaptchaSolutionHash, computeItemHash, computePendingRequestHash, getSolutionValueToHash, matchItemsToSolutions, parseAndSortCaptchaSolutions, parseCaptchaAssets, parseCaptchaDataset, sortAndComputeHashes };