@raytio/decrypt-helper 6.1.0 → 6.2.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.
- package/dist/api/authedFetch.d.ts +1 -0
- package/dist/api/authedFetch.js +33 -0
- package/dist/api/fetchAA.d.ts +3 -0
- package/dist/api/fetchAA.js +22 -0
- package/dist/api/fetchEnvConfig.d.ts +6 -0
- package/dist/api/fetchEnvConfig.js +39 -0
- package/dist/api/fetchInstanceData.d.ts +3 -0
- package/dist/api/fetchInstanceData.js +21 -0
- package/dist/api/getFiles.d.ts +6 -0
- package/dist/api/getFiles.js +92 -0
- package/dist/api/getLookupOption.d.ts +2 -0
- package/dist/api/getLookupOption.js +32 -0
- package/dist/api/getSchema.d.ts +3 -0
- package/dist/api/getSchema.js +23 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/index.js +25 -0
- package/dist/api/resolveVerificationDetails.d.ts +11 -0
- package/dist/api/resolveVerificationDetails.js +36 -0
- package/dist/api/signIn.d.ts +7 -0
- package/dist/api/signIn.js +56 -0
- package/dist/api/updateInstanceData.d.ts +2 -0
- package/dist/api/updateInstanceData.js +19 -0
- package/dist/api/uploadToObjectStore.d.ts +5 -0
- package/dist/api/uploadToObjectStore.js +42 -0
- package/dist/api/videoToImage.d.ts +3 -0
- package/dist/api/videoToImage.js +30 -0
- package/dist/configureEnv.d.ts +1 -0
- package/dist/configureEnv.js +30 -0
- package/dist/constants.d.ts +23 -0
- package/dist/constants.js +45 -0
- package/dist/helpers/file.d.ts +13 -0
- package/dist/helpers/file.js +17 -0
- package/dist/helpers/formatOutput.d.ts +28 -0
- package/dist/helpers/formatOutput.js +93 -0
- package/dist/helpers/index.d.ts +6 -0
- package/dist/helpers/index.js +22 -0
- package/dist/helpers/json2csv.d.ts +2 -0
- package/dist/helpers/json2csv.js +24 -0
- package/dist/helpers/lookup.d.ts +2 -0
- package/dist/helpers/lookup.js +22 -0
- package/dist/helpers/setupMaxcryptor.d.ts +4 -0
- package/dist/helpers/setupMaxcryptor.js +28 -0
- package/dist/helpers/splitPOAndVers.d.ts +2 -0
- package/dist/helpers/splitPOAndVers.js +12 -0
- package/dist/helpers/types.d.ts +1 -0
- package/dist/helpers/types.js +9 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +18 -0
- package/dist/locales/index.d.ts +44 -0
- package/dist/locales/index.js +22 -0
- package/dist/locales/translations/en.json +33 -0
- package/dist/pdf/components/FieldVerificationBadge.d.ts +6 -0
- package/dist/pdf/components/FieldVerificationBadge.js +19 -0
- package/dist/pdf/components/Images.d.ts +6 -0
- package/dist/pdf/components/Images.js +20 -0
- package/dist/pdf/components/InnerTableRows.d.ts +11 -0
- package/dist/pdf/components/InnerTableRows.js +37 -0
- package/dist/pdf/components/POVerificationBadge.d.ts +8 -0
- package/dist/pdf/components/POVerificationBadge.js +41 -0
- package/dist/pdf/components/Report.d.ts +13 -0
- package/dist/pdf/components/Report.js +98 -0
- package/dist/pdf/components/Subheader.d.ts +2 -0
- package/dist/pdf/components/Subheader.js +28 -0
- package/dist/pdf/components/Table.d.ts +9 -0
- package/dist/pdf/components/Table.js +47 -0
- package/dist/pdf/components/TableTitle.d.ts +5 -0
- package/dist/pdf/components/TableTitle.js +17 -0
- package/dist/pdf/components/ValidationDisplay.d.ts +5 -0
- package/dist/pdf/components/ValidationDisplay.js +29 -0
- package/dist/pdf/components/VerifyBox.d.ts +9 -0
- package/dist/pdf/components/VerifyBox.js +19 -0
- package/dist/pdf/components/pieChart.d.ts +6 -0
- package/dist/pdf/components/pieChart.js +27 -0
- package/dist/pdf/constants.d.ts +3 -0
- package/dist/pdf/constants.js +12 -0
- package/dist/pdf/helpers/general.d.ts +8 -0
- package/dist/pdf/helpers/general.js +37 -0
- package/dist/pdf/helpers/transform.d.ts +4 -0
- package/dist/pdf/helpers/transform.js +39 -0
- package/dist/pdf/style.d.ts +10 -0
- package/dist/pdf/style.js +24 -0
- package/dist/public-methods/generatePDF.d.ts +4 -0
- package/dist/public-methods/generatePDF.js +60 -0
- package/dist/public-methods/getAndValidateConfig.d.ts +8 -0
- package/dist/public-methods/getAndValidateConfig.js +20 -0
- package/dist/public-methods/processSubmission.d.ts +49 -0
- package/dist/public-methods/processSubmission.js +128 -0
- package/dist/public-methods/saveToS3Bucket.d.ts +2 -0
- package/dist/public-methods/saveToS3Bucket.js +60 -0
- package/dist/public-methods/version.d.ts +2 -0
- package/dist/public-methods/version.js +15 -0
- package/package.json +12 -12
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AId, IId, Instance, RealVer } from "@raytio/types";
|
|
2
|
+
import { Config, InstanceDataToPassOn } from "../constants";
|
|
3
|
+
import { FlatPO } from "../helpers";
|
|
4
|
+
import { EnvConfig } from "../api";
|
|
5
|
+
import { ApplicationEncryptorLike } from "../types";
|
|
6
|
+
type DecryptData = {
|
|
7
|
+
apiToken: string;
|
|
8
|
+
instance: Instance;
|
|
9
|
+
encryptedInstance: Instance;
|
|
10
|
+
applicationDecryptor: ApplicationEncryptorLike;
|
|
11
|
+
realVers?: RealVer[];
|
|
12
|
+
};
|
|
13
|
+
export interface ProcessSubmissionInput {
|
|
14
|
+
/** The a_id of the application */
|
|
15
|
+
applicationId: AId;
|
|
16
|
+
/** The i_id of this submission */
|
|
17
|
+
instanceId: IId;
|
|
18
|
+
/** whether to enable extra logging. Default = false */
|
|
19
|
+
verbose?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* the configuration options. You can extract these from the environment
|
|
22
|
+
* variables by using @see getAndValidateConfig
|
|
23
|
+
*/
|
|
24
|
+
config: Config;
|
|
25
|
+
/** You can optionally supply Instance data and an API token - for Raytio internal use */
|
|
26
|
+
_supliedConfig?: DecryptData;
|
|
27
|
+
}
|
|
28
|
+
export interface ProcessSubmissionOutput {
|
|
29
|
+
/** details of the submission, included the decrypted profile objects */
|
|
30
|
+
json: InstanceDataToPassOn & {
|
|
31
|
+
profile_objects: {
|
|
32
|
+
[schemaName: string]: FlatPO[];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** A string of a CSV file containing the same data as in `json` */
|
|
36
|
+
csv: string;
|
|
37
|
+
/** an object of files that were attached to the submission, such as images */
|
|
38
|
+
files: {
|
|
39
|
+
[nId: string]: [dataUrl: string, fileExtension: string];
|
|
40
|
+
};
|
|
41
|
+
/** the a_id is passed on */
|
|
42
|
+
a_id: AId;
|
|
43
|
+
/** passed down so that pdf generation has access to it */
|
|
44
|
+
client_url: string;
|
|
45
|
+
/** passed down so that pdf generation has access to it */
|
|
46
|
+
envConfig: EnvConfig;
|
|
47
|
+
}
|
|
48
|
+
export declare function processSubmission({ applicationId, instanceId, verbose, config, _supliedConfig, }: ProcessSubmissionInput): Promise<ProcessSubmissionOutput>;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.processSubmission = void 0;
|
|
13
|
+
const ramda_1 = require("ramda");
|
|
14
|
+
const core_1 = require("@raytio/core");
|
|
15
|
+
const constants_1 = require("../constants");
|
|
16
|
+
const helpers_1 = require("../helpers");
|
|
17
|
+
const api_1 = require("../api");
|
|
18
|
+
const constants_2 = require("../pdf/constants");
|
|
19
|
+
function decryptStage(log, config, envConfig, instanceId) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
log("Authenticating...");
|
|
22
|
+
const { apiToken, cognitoAttributes } = yield (0, api_1.signIn)(config, envConfig);
|
|
23
|
+
log("Initializing decryptor...");
|
|
24
|
+
const maxcryptor = yield (0, helpers_1.setupMaxcryptor)(config, cognitoAttributes);
|
|
25
|
+
log("Fetching submission details...");
|
|
26
|
+
const apiResp = yield (0, api_1.fetchInstanceData)(apiToken, envConfig, instanceId);
|
|
27
|
+
log("Decrypting submission details...");
|
|
28
|
+
const { instance, applicationDecryptor } = yield (0, core_1.decryptSharedData)({
|
|
29
|
+
apiToken,
|
|
30
|
+
apiUrl: envConfig.api_url,
|
|
31
|
+
instanceData: apiResp,
|
|
32
|
+
maxcryptor,
|
|
33
|
+
onCorruptedData: () => "🔒 Corrupted Data 🔒",
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
apiToken,
|
|
37
|
+
instance,
|
|
38
|
+
applicationDecryptor,
|
|
39
|
+
encryptedInstance: apiResp,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function processSubmission({ applicationId, instanceId, verbose, config, _supliedConfig, }) {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const log = verbose ? console.log : () => undefined;
|
|
46
|
+
try {
|
|
47
|
+
log("Fetching config...");
|
|
48
|
+
const envConfig = yield (0, api_1.fetchEnvConfig)(config.CLIENT_URL);
|
|
49
|
+
const { instance, apiToken, applicationDecryptor, encryptedInstance } = _supliedConfig ||
|
|
50
|
+
(yield decryptStage(log, config, envConfig, instanceId));
|
|
51
|
+
log("Checking verifications...");
|
|
52
|
+
const [profileObjects, verifications] = (0, helpers_1.splitPOAndVers)(instance.profile_objects);
|
|
53
|
+
const realVers = (_supliedConfig === null || _supliedConfig === void 0 ? void 0 : _supliedConfig.realVers) ||
|
|
54
|
+
(yield (0, core_1.getSomeoneElsesRealVerifications)({
|
|
55
|
+
aId: instance.a_id,
|
|
56
|
+
apiUrl: envConfig.api_url,
|
|
57
|
+
profileObjects,
|
|
58
|
+
verifications,
|
|
59
|
+
}));
|
|
60
|
+
log("Fetching relevant schema...");
|
|
61
|
+
const allSchemas = yield (0, api_1.getAllSchema)(envConfig);
|
|
62
|
+
log("Fetching access application...");
|
|
63
|
+
const AA = instance.i_id === constants_2.NULL_I_ID
|
|
64
|
+
? undefined
|
|
65
|
+
: yield (0, api_1.fetchAA)(apiToken, envConfig, instance.a_id);
|
|
66
|
+
let score;
|
|
67
|
+
if (AA && (0, core_1.isScoreConfigValid)(AA.ruleset)) {
|
|
68
|
+
const ruleInputData = yield (0, core_1.convertInstanceToRuleInput)(instance.profile_objects, realVers, (schemaName) => __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
const schema = allSchemas.find((x) => x.name === schemaName);
|
|
70
|
+
if (!schema) {
|
|
71
|
+
throw new Error(`Could not find schema “${schemaName}”`);
|
|
72
|
+
}
|
|
73
|
+
return schema;
|
|
74
|
+
}));
|
|
75
|
+
try {
|
|
76
|
+
// decrypt helper never uses a stored score. We always re-calculate it.
|
|
77
|
+
log("Calculating score...");
|
|
78
|
+
score = yield (0, core_1.calculateScore)(AA.ruleset, ruleInputData);
|
|
79
|
+
if (!(0, ramda_1.equals)(instance.score, score)) {
|
|
80
|
+
// the score we calculated is different to the one that's saved on the instance.
|
|
81
|
+
// So we save the new score.
|
|
82
|
+
log("Saving score to instance...");
|
|
83
|
+
// this can happen silently in the background, but we await it since so that we
|
|
84
|
+
// abort if this fails.
|
|
85
|
+
yield (0, api_1.updateInstanceData)(apiToken, Object.assign(Object.assign({}, encryptedInstance), { score }));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (ex) {
|
|
89
|
+
log(`Score calculation failed (${ex})`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
log("No score rules configured on the AA.");
|
|
94
|
+
}
|
|
95
|
+
log("Fetching verification providers...");
|
|
96
|
+
const PODetails = yield (0, helpers_1.formatOutput)(profileObjects, allSchemas, realVers, apiToken, envConfig);
|
|
97
|
+
log("Fetching attached files...");
|
|
98
|
+
const files = yield (0, api_1.getFiles)(profileObjects, instance, apiToken, envConfig, applicationDecryptor);
|
|
99
|
+
const instanceDataToPassOn = (0, ramda_1.omit)(constants_1.INSTANCE_FIELDS_TO_REMOVE, instance);
|
|
100
|
+
// final outputs
|
|
101
|
+
const csv = (0, helpers_1.deepJsonToCsv)(Object.assign(Object.assign({}, instanceDataToPassOn), (0, ramda_1.mapObjIndexed)((POList) => POList.map((flatPO) => {
|
|
102
|
+
// this is a bit weird, but it prevents an even bigger breaking change for the csv format
|
|
103
|
+
const object = Object.entries(flatPO.$properties).flatMap(([fieldName, field]) => [
|
|
104
|
+
[fieldName, field.value],
|
|
105
|
+
[
|
|
106
|
+
`${fieldName}.verification`,
|
|
107
|
+
constants_1.FIELD_VER_TEXT_MAP[field.verification],
|
|
108
|
+
],
|
|
109
|
+
]);
|
|
110
|
+
return Object.assign(Object.assign({}, flatPO), Object.fromEntries(object));
|
|
111
|
+
}), PODetails)));
|
|
112
|
+
log("Success!");
|
|
113
|
+
return {
|
|
114
|
+
json: Object.assign(Object.assign({}, instanceDataToPassOn), { score, profile_objects: PODetails }),
|
|
115
|
+
csv,
|
|
116
|
+
files,
|
|
117
|
+
a_id: applicationId,
|
|
118
|
+
client_url: config.CLIENT_URL,
|
|
119
|
+
envConfig,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
log("Processing submission failed:", error);
|
|
124
|
+
throw error; // pass on error
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
exports.processSubmission = processSubmission;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.saveToS3Bucket = void 0;
|
|
16
|
+
const aws_sdk_1 = __importDefault(require("aws-sdk"));
|
|
17
|
+
function upload(s3, { bucketName, fileName, fileContent }) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
s3.upload({
|
|
21
|
+
Bucket: bucketName,
|
|
22
|
+
Key: fileName,
|
|
23
|
+
Body: fileContent,
|
|
24
|
+
}, (error, data) => {
|
|
25
|
+
if (error)
|
|
26
|
+
return reject(error);
|
|
27
|
+
console.log(`Uploaded ${data.Location}`);
|
|
28
|
+
return resolve(data);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const saveToS3Bucket = () =>
|
|
34
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping -- deliberately to future proof the SDK for options
|
|
35
|
+
(input) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
console.log("Uploading data to S3...");
|
|
37
|
+
const bucketName = process.env.S3_BUCKET;
|
|
38
|
+
if (!bucketName)
|
|
39
|
+
throw new Error("S3_BUCKET is not specified");
|
|
40
|
+
const s3 = new aws_sdk_1.default.S3();
|
|
41
|
+
yield upload(s3, {
|
|
42
|
+
bucketName,
|
|
43
|
+
fileName: `${input.json.i_id}/${input.json.i_id}.csv`,
|
|
44
|
+
fileContent: input.csv,
|
|
45
|
+
});
|
|
46
|
+
yield upload(s3, {
|
|
47
|
+
bucketName,
|
|
48
|
+
fileName: `${input.json.i_id}/${input.json.i_id}.json`,
|
|
49
|
+
fileContent: JSON.stringify(input.json),
|
|
50
|
+
});
|
|
51
|
+
yield Promise.all(Object.entries(input.files).map(([nId, [dataUrl, fileExtension]]) => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
yield upload(s3, {
|
|
53
|
+
bucketName,
|
|
54
|
+
fileName: `${input.json.i_id}/${nId}.${fileExtension}`,
|
|
55
|
+
fileContent: Buffer.from(dataUrl.split(",")[1], "base64"),
|
|
56
|
+
});
|
|
57
|
+
})));
|
|
58
|
+
console.log("Finished uploading data to S3.");
|
|
59
|
+
});
|
|
60
|
+
exports.saveToS3Bucket = saveToS3Bucket;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.version = exports.packageDotJson = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
exports.packageDotJson = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "../../package.json"), "utf8"));
|
|
7
|
+
exports.version = Object.entries({
|
|
8
|
+
LANG: process.env.PDF_LANGUAGE || "default",
|
|
9
|
+
N: process.version.slice(1),
|
|
10
|
+
DH: exports.packageDotJson.version,
|
|
11
|
+
C: exports.packageDotJson.dependencies["@raytio/core"].slice(1),
|
|
12
|
+
T: exports.packageDotJson.dependencies["@raytio/types"].slice(1),
|
|
13
|
+
})
|
|
14
|
+
.map((kv) => kv.join("="))
|
|
15
|
+
.join(" ");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raytio/decrypt-helper",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"author": "Raytio",
|
|
5
5
|
"description": "A helper to decrypt data shared by Raytio users",
|
|
6
6
|
"main": "dist",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@aws-amplify/auth": "3.4.25",
|
|
25
|
-
"@raytio/core": "^11.
|
|
25
|
+
"@raytio/core": "^11.2.0",
|
|
26
26
|
"@raytio/maxcryptor": "^3.1.0",
|
|
27
|
-
"@raytio/types": "^7.
|
|
27
|
+
"@raytio/types": "^7.2.0",
|
|
28
28
|
"aws-sdk": "^2.754.0",
|
|
29
29
|
"jsx-pdf": "^2.3.0",
|
|
30
30
|
"localstorage-polyfill": "^1.0.1",
|
|
@@ -34,24 +34,24 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@raytio/react-intl-manager": "^6.3.1",
|
|
37
|
-
"@types/jest": "^29.5.
|
|
37
|
+
"@types/jest": "^29.5.3",
|
|
38
38
|
"@types/jest-image-snapshot": "^6.1.0",
|
|
39
39
|
"@types/jsx-pdf": "^2.2.2",
|
|
40
40
|
"@types/mime-types": "^2.1.1",
|
|
41
|
-
"@types/node": "^18.
|
|
41
|
+
"@types/node": "^18.16.19",
|
|
42
42
|
"@types/pdfmake": "^0.2.2",
|
|
43
|
-
"@types/ramda": "^0.29.
|
|
43
|
+
"@types/ramda": "^0.29.3",
|
|
44
44
|
"babel-preset-react-app": "^10.0.1",
|
|
45
|
-
"dotenv": "^16.
|
|
46
|
-
"eslint": "^8.
|
|
47
|
-
"eslint-config-kyle": "^11.
|
|
48
|
-
"jest": "^29.
|
|
45
|
+
"dotenv": "^16.3.1",
|
|
46
|
+
"eslint": "^8.45.0",
|
|
47
|
+
"eslint-config-kyle": "^11.19.0",
|
|
48
|
+
"jest": "^29.6.1",
|
|
49
49
|
"jest-image-snapshot": "^6.1.0",
|
|
50
50
|
"jest-junit": "^16.0.0",
|
|
51
51
|
"pdf-to-img": "^2.1.1",
|
|
52
|
-
"ts-jest": "^29.1.
|
|
52
|
+
"ts-jest": "^29.1.1",
|
|
53
53
|
"ts-node": "^10.9.1",
|
|
54
|
-
"typescript": "^5.
|
|
54
|
+
"typescript": "^5.1.6"
|
|
55
55
|
},
|
|
56
56
|
"eslintConfig": {
|
|
57
57
|
"extends": "kyle",
|