diff --git a/.eslintrc.js b/.eslintrc.js index c31a62c..843d136 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,18 +7,38 @@ module.exports = { }, extends: [ 'airbnb-base', + 'airbnb-typescript/base', 'plugin:jest/recommended', 'plugin:jsdoc/recommended', ], + parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 13, + project: './tsconfig.eslint.json', }, - plugins: ['jest', 'jsdoc'], + plugins: ['jest', 'jsdoc', '@typescript-eslint'], + ignorePatterns: ['coverage/**/*', 'dist/**/*'], rules: { camelcase: 0, 'compat/compat': 0, + 'no-restricted-imports': 'off', + 'import/prefer-default-export': 'off', 'no-console': ['error', { allow: ['warn', 'error', 'info'], }], + '@typescript-eslint/naming-convention': [ // TODO:remove custom convention in future versions + 'warn', + { + selector: 'variable', + format: ['camelCase', 'PascalCase', 'snake_case', 'UPPER_CASE'], + }, + ], + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.ts'], + }, + }, }, }; diff --git a/babel.config.js b/babel.config.js index cc367d9..f9a42ff 100644 --- a/babel.config.js +++ b/babel.config.js @@ -6,5 +6,8 @@ const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.jso const nodeVersionNumber = packageJson.engines.node.replace(/^>=v/, ''); module.exports = { - presets: [['@babel/preset-env', { targets: { node: nodeVersionNumber } }]], + presets: [ + ['@babel/preset-env', { targets: { node: nodeVersionNumber } }], + '@babel/preset-typescript', + ], }; diff --git a/examples/example-project/README.md b/examples/README.md similarity index 100% rename from examples/example-project/README.md rename to examples/README.md diff --git a/examples/biometric_kyc.js b/examples/biometric_kyc.ts similarity index 97% rename from examples/biometric_kyc.js rename to examples/biometric_kyc.ts index eec76bc..108f94b 100644 --- a/examples/biometric_kyc.js +++ b/examples/biometric_kyc.ts @@ -4,7 +4,8 @@ */ // Change to smile-identity-core if you're using this snippet in your project. -const { WebApi } = require('..'); +/* eslint-disable import/no-relative-packages */ +import { WebApi } from '..'; // Initialize // Login to the Smile Identity Portal to view your partner id. diff --git a/examples/document_verification.js b/examples/document_verification.ts similarity index 97% rename from examples/document_verification.js rename to examples/document_verification.ts index 3be70f5..e18ebbd 100644 --- a/examples/document_verification.js +++ b/examples/document_verification.ts @@ -4,7 +4,8 @@ */ // Change to smile-identity-core if you're using this snippet in your project. -const { WebApi } = require('..'); +/* eslint-disable import/no-relative-packages */ +import { WebApi } from '..'; // Initialize // login to the Smile Identity portal to view your partner id. diff --git a/examples/enhanced_kyc.js b/examples/enhanced_kyc.ts similarity index 93% rename from examples/enhanced_kyc.js rename to examples/enhanced_kyc.ts index 95e0d1f..52236f5 100644 --- a/examples/enhanced_kyc.js +++ b/examples/enhanced_kyc.ts @@ -1,5 +1,6 @@ // Change to smile-identity-core if you're using this snippet in your project. -const { IDApi } = require('..'); +/* eslint-disable import/no-relative-packages */ +import { IDApi } from '..'; // Initialize // login to the Smile Identity Portal to view your partner id. diff --git a/examples/example-project/package.json b/examples/example-project/package.json deleted file mode 100644 index 2de2666..0000000 --- a/examples/example-project/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "smile-identity-server-integration-demo", - "version": "0.0.1", - "description": "A Full-Stack JavaScript application built to demo the Smile Identity server Integration", - "main": "server.js", - "scripts": { - "start": "node server.js", - "debug": "NODE_ENV='development' node --inspect server.js" - }, - "dependencies": { - "dotenv": "^16.0.3", - "express": "^4.17.1", - "smile-identity-core": "latest", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=12.x" - }, - "repository": { - "url": "https://smileidentity.com/" - }, - "license": "MIT", - "keywords": [ - "node", - "glitch", - "express", - "Smile Identity" - ] -} diff --git a/examples/package.json b/examples/package.json index e1743fa..c0fd17a 100644 --- a/examples/package.json +++ b/examples/package.json @@ -5,7 +5,9 @@ "main": "server.js", "scripts": {}, "dependencies": { - "smile-identity-core": "latest", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "smile-identity-core": "file:../", "uuid": "^9.0.0" }, "engines": { @@ -20,5 +22,9 @@ "glitch", "express", "Smile Identity" - ] + ], + "devDependencies": { + "@types/express": "^4.17.15", + "@types/uuid": "^9.0.0" + } } diff --git a/examples/example-project/public/css/styles.css b/examples/public/css/styles.css similarity index 100% rename from examples/example-project/public/css/styles.css rename to examples/public/css/styles.css diff --git a/examples/example-project/public/index.html b/examples/public/index.html similarity index 100% rename from examples/example-project/public/index.html rename to examples/public/index.html diff --git a/examples/example-project/sample.env b/examples/sample.env similarity index 100% rename from examples/example-project/sample.env rename to examples/sample.env diff --git a/examples/example-project/server.js b/examples/server.js similarity index 94% rename from examples/example-project/server.js rename to examples/server.js index 6b1694c..6aa9c95 100644 --- a/examples/example-project/server.js +++ b/examples/server.js @@ -68,7 +68,6 @@ app.post('/', async (req, res) => { // NOTE: This can be used to process responses. Don't forget to add it as a // callback option in the `connection` config on L22. -// eslint-disable-next-line no-unused-vars -app.post('/callback', (_req, _res, _next) => { }); +app.post('/callback'); app.listen(process.env.PORT || 4000); diff --git a/examples/smart_selfie_authentication.js b/examples/smart_selfie_authentication.ts similarity index 97% rename from examples/smart_selfie_authentication.js rename to examples/smart_selfie_authentication.ts index a74e8db..6c3ea84 100644 --- a/examples/smart_selfie_authentication.js +++ b/examples/smart_selfie_authentication.ts @@ -2,7 +2,8 @@ // how to setup and retrieve configuration values for the WebApi class. // Change to smile-identity-core if you're using this snippet in your project. -const { WebApi } = require('..'); +/* eslint-disable import/no-relative-packages */ +import { WebApi } from '..'; // Initialize const partner_id = ''; // login to the Smile Identity portal to view your partner id diff --git a/index.js b/index.js deleted file mode 100644 index b7efbc0..0000000 --- a/index.js +++ /dev/null @@ -1,18 +0,0 @@ -const IDApi = require('./src/id-api'); -const Signature = require('./src/signature'); -const Utilities = require('./src/utilities'); -const WebApi = require('./src/web-api'); -const { JOB_TYPE, IMAGE_TYPE } = require('./src/constants'); - -if ((typeof process === 'undefined' && typeof process.versions.node === 'undefined') || typeof window !== 'undefined') { - console.error('This is a server-side library meant for a node.js (or compatible) runtime, and is not meant to work in the browser.'); -} - -module.exports = { - IDApi, - Signature, - Utilities, - WebApi, - JOB_TYPE, - IMAGE_TYPE, -}; diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..edf181c --- /dev/null +++ b/index.ts @@ -0,0 +1,13 @@ +import { IDApi } from './src/id-api'; +import Signature from './src/signature'; +import { Utilities } from './src/utilities'; +import { WebApi } from './src/web-api'; +import { JOB_TYPE, IMAGE_TYPE } from './src/constants'; + +if ((typeof process === 'undefined' && typeof (process as NodeJS.Process).versions.node === 'undefined') || typeof window !== 'undefined') { + console.warn('This is a server-side library meant for a node.js (or compatible) runtime, and is not meant to work in the browser.'); +} + +export { + IDApi, Signature, Utilities, WebApi, JOB_TYPE, IMAGE_TYPE, +}; diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..9b8da00 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,9 @@ +import type { Config } from 'jest'; +import { defaults } from 'jest-config'; + +const config: Config = { + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'], + modulePathIgnorePatterns: ['/dist'], +}; + +export default config; diff --git a/package-lock.json b/package-lock.json index 5e8e6a7..745bb8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,30 +1,40 @@ { "name": "smile-identity-core", - "version": "2.0.0", + "version": "3.0.0-pre", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "smile-identity-core", - "version": "2.0.0", + "version": "3.0.0-pre", "license": "MIT", "dependencies": { "axios": "^1.2.2", "jszip": "^3.10.1" }, "devDependencies": { + "@babel/cli": "^7.20.7", "@babel/core": "^7.20.7", "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/jest": "^29.2.4", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", "babel-jest": "^29.3.1", "eslint": "^8.31.0", "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.2.0", "eslint-plugin-jsdoc": "^39.6.4", "jest": "^29.3.1", + "jest-config": "^29.3.1", "jest-environment-jsdom": "^29.3.1", "keypair": "^1.0.4", - "nock": "^13.2.9" + "nock": "^13.2.9", + "ts-jest": "^29.0.3", + "ts-node": "^10.9.1", + "typescript": "^4.9.4" }, "engines": { "node": ">=v12.0.0" @@ -43,6 +53,66 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/cli": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.20.7.tgz", + "integrity": "sha512-WylgcELHB66WwQqItxNILsMlaTd8/SO6SgTTjMp4uCI7P4QyH1r3nqgFmO3BfM4AtfniHgFMH3EpYFj/zynBkQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/cli/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/cli/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/cli/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -94,6 +164,133 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-module-transforms": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz", + "integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/parser": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/traverse": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.10.tgz", + "integrity": "sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/core/node_modules/json5": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", @@ -106,6 +303,21 @@ "node": ">=6" } }, + "node_modules/@babel/core/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/core/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/@babel/generator": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", @@ -483,6 +695,95 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helpers/node_modules/@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/parser": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/traverse": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.10.tgz", + "integrity": "sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/highlight": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", @@ -1582,6 +1883,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", + "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", @@ -1718,6 +2036,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", @@ -1785,6 +2120,28 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.36.1", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", @@ -2253,6 +2610,13 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "optional": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2321,6 +2685,30 @@ "node": ">= 10" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, "node_modules/@types/babel__core": { "version": "7.1.20", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", @@ -2395,6 +2783,16 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "29.2.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.4.tgz", + "integrity": "sha512-PipFB04k2qTRPePduVLTRiPzQfvMeLwUN3Z21hsAKaB/W9IIzgB2pizCL466ftJlcyZqnHoC9ZHpxLGl3fS86A==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, "node_modules/@types/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", @@ -2463,14 +2861,108 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz", + "integrity": "sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/type-utils": "5.47.0", + "@typescript-eslint/utils": "5.47.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.0.tgz", + "integrity": "sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/typescript-estree": "5.47.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz", - "integrity": "sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", + "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.0.tgz", + "integrity": "sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.42.0", - "@typescript-eslint/visitor-keys": "5.42.0" + "@typescript-eslint/typescript-estree": "5.47.0", + "@typescript-eslint/utils": "5.47.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2478,12 +2970,20 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/types": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.0.tgz", - "integrity": "sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", + "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2494,13 +2994,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz", - "integrity": "sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", + "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.42.0", - "@typescript-eslint/visitor-keys": "5.42.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2536,16 +3036,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.0.tgz", - "integrity": "sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.0.tgz", + "integrity": "sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.42.0", - "@typescript-eslint/types": "5.42.0", - "@typescript-eslint/typescript-estree": "5.42.0", + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/typescript-estree": "5.47.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -2599,12 +3099,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz", - "integrity": "sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", + "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/types": "5.47.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2753,6 +3253,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2959,6 +3465,16 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3009,6 +3525,18 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -3096,6 +3624,47 @@ "node": ">=10" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", @@ -3170,6 +3739,15 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/comment-parser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", @@ -3215,6 +3793,12 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3344,6 +3928,15 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", @@ -3700,6 +4293,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/eslint-config-airbnb-typescript": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.0.0.tgz", + "integrity": "sha512-elNiuzD0kPAPTXjFWg+lE24nMdHMtuxgYoD30OyMD6yrW1AhFZPAg27VX7d3tzOErw+dgJTNWfRSDqEcXb4V0g==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -4283,6 +4891,12 @@ "node": ">= 6" } }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4718,6 +5332,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -5841,6 +6468,12 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5874,6 +6507,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -5972,6 +6611,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/nock": { "version": "13.2.9", "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.9.tgz", @@ -6274,6 +6919,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -6423,6 +7077,19 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -7023,6 +7690,119 @@ "node": ">=12" } }, + "node_modules/ts-jest": { + "version": "29.0.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz", + "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/json5": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -7094,7 +7874,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7217,6 +7996,12 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", @@ -7449,6 +8234,15 @@ "node": ">=12" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -7473,6 +8267,47 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@babel/cli": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.20.7.tgz", + "integrity": "sha512-WylgcELHB66WwQqItxNILsMlaTd8/SO6SgTTjMp4uCI7P4QyH1r3nqgFmO3BfM4AtfniHgFMH3EpYFj/zynBkQ==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.8", + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, "@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -7511,11 +8346,123 @@ "semver": "^6.3.0" }, "dependencies": { + "@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz", + "integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/parser": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "dev": true + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.10.tgz", + "integrity": "sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "json5": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true } } }, @@ -7805,6 +8752,76 @@ "@babel/template": "^7.20.7", "@babel/traverse": "^7.20.7", "@babel/types": "^7.20.7" + }, + "dependencies": { + "@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + } + }, + "@babel/parser": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "dev": true + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.10.tgz", + "integrity": "sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } } }, "@babel/highlight": { @@ -8527,6 +9544,17 @@ "@babel/helper-plugin-utils": "^7.18.9" } }, + "@babel/plugin-transform-typescript": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", + "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" + } + }, "@babel/plugin-transform-unicode-escapes": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", @@ -8642,6 +9670,17 @@ "esutils": "^2.0.2" } }, + "@babel/preset-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" + } + }, "@babel/runtime": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", @@ -8697,6 +9736,27 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@es-joy/jsdoccomment": { "version": "0.36.1", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", @@ -9067,6 +10127,13 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "optional": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -9123,6 +10190,30 @@ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, "@types/babel__core": { "version": "7.1.20", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", @@ -9197,6 +10288,16 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "29.2.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.4.tgz", + "integrity": "sha512-PipFB04k2qTRPePduVLTRiPzQfvMeLwUN3Z21hsAKaB/W9IIzgB2pizCL466ftJlcyZqnHoC9ZHpxLGl3fS86A==", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, "@types/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", @@ -9265,30 +10366,82 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz", + "integrity": "sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/type-utils": "5.47.0", + "@typescript-eslint/utils": "5.47.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.0.tgz", + "integrity": "sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/typescript-estree": "5.47.0", + "debug": "^4.3.4" + } + }, "@typescript-eslint/scope-manager": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz", - "integrity": "sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", + "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.0.tgz", + "integrity": "sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.42.0", - "@typescript-eslint/visitor-keys": "5.42.0" + "@typescript-eslint/typescript-estree": "5.47.0", + "@typescript-eslint/utils": "5.47.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.0.tgz", - "integrity": "sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", + "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz", - "integrity": "sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", + "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.42.0", - "@typescript-eslint/visitor-keys": "5.42.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9308,16 +10461,16 @@ } }, "@typescript-eslint/utils": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.0.tgz", - "integrity": "sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.0.tgz", + "integrity": "sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.42.0", - "@typescript-eslint/types": "5.42.0", - "@typescript-eslint/typescript-estree": "5.42.0", + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/typescript-estree": "5.47.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -9351,12 +10504,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz", - "integrity": "sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", + "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/types": "5.47.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -9458,6 +10611,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -9619,6 +10778,13 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "optional": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -9650,6 +10816,15 @@ "update-browserslist-db": "^1.0.9" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -9709,6 +10884,35 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "ci-info": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", @@ -9767,6 +10971,12 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, "comment-parser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", @@ -9805,6 +11015,12 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -9904,6 +11120,12 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "diff-sequences": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", @@ -10235,6 +11457,15 @@ } } }, + "eslint-config-airbnb-typescript": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.0.0.tgz", + "integrity": "sha512-elNiuzD0kPAPTXjFWg+lE24nMdHMtuxgYoD30OyMD6yrW1AhFZPAg27VX7d3tzOErw+dgJTNWfRSDqEcXb4V0g==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^15.0.0" + } + }, "eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -10599,6 +11830,12 @@ "mime-types": "^2.1.12" } }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -10910,6 +12147,16 @@ "has-bigints": "^1.0.1" } }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -11754,6 +13001,12 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -11778,6 +13031,12 @@ "semver": "^6.0.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -11855,6 +13114,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "nock": { "version": "13.2.9", "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.9.tgz", @@ -12078,6 +13343,12 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, "pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -12188,6 +13459,16 @@ "util-deprecate": "~1.0.1" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -12645,6 +13926,60 @@ "punycode": "^2.1.1" } }, + "ts-jest": { + "version": "29.0.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz", + "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "dependencies": { + "json5": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "dev": true + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -12697,8 +14032,7 @@ "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true, - "peer": true + "dev": true }, "unbox-primitive": { "version": "1.0.2", @@ -12780,6 +14114,12 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", @@ -12947,6 +14287,12 @@ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 6f3d97f..286fc20 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,52 @@ { "name": "smile-identity-core", - "version": "2.0.0", + "version": "3.0.0-pre", "description": "The official Smile Identity Node SDK", - "main": "index.js", + "main": "./dist/index.js", + "types": "./dist/types.d.ts", "scripts": { - "lint": "eslint $(git ls-files '*.js')", - "start": "node index.js", + "prepublish": "tsc && tsc --project tsconfig.declarations.json", + "lint": "eslint $(git ls-files '*.js' '*.ts')", + "start": "node dist/index.js", "test": "jest --coverage" }, "author": "Chris DeLauder ", + "contributors": ["Barnabas A nsoh "], "license": "MIT", "dependencies": { "axios": "^1.2.2", "jszip": "^3.10.1" }, "devDependencies": { + "@babel/cli": "^7.20.7", "@babel/core": "^7.20.7", "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/jest": "^29.2.4", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", "babel-jest": "^29.3.1", "eslint": "^8.31.0", "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.2.0", "eslint-plugin-jsdoc": "^39.6.4", "jest": "^29.3.1", + "jest-config": "^29.3.1", "jest-environment-jsdom": "^29.3.1", "keypair": "^1.0.4", - "nock": "^13.2.9" + "nock": "^13.2.9", + "ts-jest": "^29.0.3", + "ts-node": "^10.9.1", + "typescript": "^4.9.4" }, "directories": { "test": "test" }, + "files": [ + "dist/**/*" + ], "repository": { "type": "git", "url": "git+https://github.com/smileidentity/smile-identity-core-js.git" diff --git a/src/constants.js b/src/constants.ts similarity index 94% rename from src/constants.js rename to src/constants.ts index 1913897..2d131d5 100644 --- a/src/constants.js +++ b/src/constants.ts @@ -4,7 +4,7 @@ * @readonly * @enum {number} */ -const IMAGE_TYPE = { +export const IMAGE_TYPE = { /** SELFIE_IMAGE_FILE Selfie image in .png or .jpg file format */ SELFIE_IMAGE_FILE: 0, /** ID_CARD_IMAGE_FILE ID card image in .png or .jpg file format */ @@ -29,7 +29,7 @@ const IMAGE_TYPE = { * @readonly * @enum {number} */ -const JOB_TYPE = { +export const JOB_TYPE = { /** BIOMETRIC_KYC Verify the ID information of your users using facial biometrics */ BIOMETRIC_KYC: 1, /** SMART_SELFIE_AUTHENTICATION Used to identify your existing users. */ @@ -59,9 +59,7 @@ const JOB_TYPE = { COMPARE_USER_INFO: 9, }; -const sidServerMapping = { +export const sidServerMapping : { [k:number]: string } = { 0: 'testapi.smileidentity.com/v1', 1: 'api.smileidentity.com/v1', }; - -module.exports = { IMAGE_TYPE, JOB_TYPE, sidServerMapping }; diff --git a/src/helpers.js b/src/helpers.ts similarity index 70% rename from src/helpers.js rename to src/helpers.ts index 3b48a4a..f356f54 100644 --- a/src/helpers.js +++ b/src/helpers.ts @@ -1,5 +1,6 @@ -const packageJson = require('../package.json'); -const { sidServerMapping } = require('./constants'); +import * as packageJson from '../package.json'; +import { sidServerMapping } from './constants'; +import { PartnerParams } from './shared'; /** * Converts a numeric key to a smile server URI, or @@ -9,15 +10,15 @@ const { sidServerMapping } = require('./constants'); * numeric key that represents it. * @returns {string} URI of smile server if in map, original input if URI. */ -const mapServerUri = (uriOrKey) => { +export const mapServerUri = (uriOrKey: string | number): string => { if (uriOrKey in sidServerMapping) { - return sidServerMapping[uriOrKey]; + return sidServerMapping[uriOrKey as number]; } - return uriOrKey; + return uriOrKey as string; }; /** @type {{source_sdk: string, source_sdk_version: string}} */ -const sdkVersionInfo = { +export const sdkVersionInfo: { source_sdk: string; source_sdk_version: string; } = { source_sdk: 'javascript', source_sdk_version: packageJson.version, }; @@ -32,7 +33,7 @@ const sdkVersionInfo = { * @throws {Error} if partnerParams is not an object or is missing required keys. * @returns {void} */ -const validatePartnerParams = (partnerParams) => { +export const validatePartnerParams = (partnerParams: PartnerParams): void => { if (!partnerParams) { throw new Error('Please ensure that you send through partner params'); } @@ -42,14 +43,9 @@ const validatePartnerParams = (partnerParams) => { } ['user_id', 'job_id', 'job_type'].forEach((key) => { - if (!partnerParams[key]) { + const partnerKey = key as keyof PartnerParams; + if (!partnerParams[partnerKey]) { throw new Error(`Please make sure that ${key} is included in the partner params`); } }); }; - -module.exports = { - mapServerUri, - sdkVersionInfo, - validatePartnerParams, -}; diff --git a/src/id-api.js b/src/id-api.ts similarity index 58% rename from src/id-api.js rename to src/id-api.ts index 77f2f6a..dfb4030 100644 --- a/src/id-api.js +++ b/src/id-api.ts @@ -1,8 +1,9 @@ -const axios = require('axios'); -const Signature = require('./signature'); -const { mapServerUri, sdkVersionInfo, validatePartnerParams } = require('./helpers'); +import axios from 'axios'; +import Signature from './signature'; +import { mapServerUri, sdkVersionInfo, validatePartnerParams } from './helpers'; +import { IdInfo, PartnerParams } from './shared'; -const validateIdInfo = (idInfo) => { +const validateIdInfo = (idInfo: IdInfo) => { if (typeof idInfo !== 'object') { throw new Error('ID Info needs to be an object'); } @@ -18,31 +19,39 @@ const validateIdInfo = (idInfo) => { const configurePayload = ({ api_key, id_info, partner_id, partner_params, -}) => ({ +}: { api_key: string, id_info: IdInfo, partner_id: string, partner_params: PartnerParams }) => ({ language: 'javascript', partner_id, partner_params: { ...partner_params, - job_type: parseInt(partner_params.job_type, 10), + job_type: partner_params.job_type, }, ...id_info, ...new Signature(partner_id, api_key).generate_signature(), ...sdkVersionInfo, }); -class IDApi { - constructor(partner_id, api_key, sid_server) { +export class IDApi { + partner_id: string; + + sid_server: string | number; + + api_key: string; + + url: string; + + constructor(partner_id: string, api_key: string, sid_server: string | number) { this.partner_id = partner_id; this.sid_server = sid_server; this.api_key = api_key; this.url = mapServerUri(sid_server); } - submit_job(partner_params, id_info) { + async submit_job(partner_params: PartnerParams, id_info: IdInfo) : Promise { try { validatePartnerParams(partner_params); - if (parseInt(partner_params.job_type, 10) !== 5) { + if (parseInt(partner_params.job_type.toString(), 10) !== 5) { throw new Error('Please ensure that you are setting your job_type to 5 to query ID Api'); } @@ -56,11 +65,10 @@ class IDApi { sid_server: this.sid_server, }; - return axios.post(`https://${this.url}/id_verification`, configurePayload(data)).then((response) => response.data); + const response = await axios.post(`https://${this.url}/id_verification`, configurePayload(data)); + return response.data; } catch (err) { return Promise.reject(err); } } } - -module.exports = IDApi; diff --git a/src/shared.ts b/src/shared.ts new file mode 100644 index 0000000..3a21201 --- /dev/null +++ b/src/shared.ts @@ -0,0 +1,33 @@ +export interface OptionsParam { + return_history?: boolean; + return_images?: boolean; + return_image_links?: boolean; + return_job_status?: boolean; + use_enrolled_image?: boolean; + optional_callback?: string +} + +export interface PartnerParams { + user_id: string | number; + job_id: string | number; + job_type: number; +} + +export interface IdInfo { + entered?: boolean | string; + country?: string, + id_type?: string, + id_number?: string, + first_name?: string, + middle_name?: string, + last_name?: string, + dob?: string, + phone_number?: string, +} + +export type TokenRequestParams = { + user_id: string; + job_id: string; + product: string; + callback_url: string; +}; diff --git a/src/signature.js b/src/signature.ts similarity index 79% rename from src/signature.js rename to src/signature.ts index 507eb6e..139b99d 100644 --- a/src/signature.js +++ b/src/signature.ts @@ -1,4 +1,4 @@ -const crypto = require('crypto'); +import crypto from 'crypto'; /** * Generate a signature for the given input. @@ -9,7 +9,7 @@ const crypto = require('crypto'); * @param {string|number} timestamp - ISO 8601 timestamp or unix timestamp. * @returns {string} the calculated signature. */ -const generate_signature = (partnerID, apiKey, timestamp) => { +const generate_signature = (partnerID: string, apiKey: string, timestamp: string | number) => { const isoTimestamp = typeof timestamp === 'number' ? new Date(timestamp).toISOString() : timestamp; // validates that the timestamp is a valid ISO 8601 timestamp. new Date(isoTimestamp).toISOString(); // eslint-disable-line no-new @@ -21,7 +21,7 @@ const generate_signature = (partnerID, apiKey, timestamp) => { }; /* A class to generate signatures for a given partner ID and API key. */ -class Signature { +export default class Signature { /** * Instantiates a new Signature object. * @@ -29,7 +29,11 @@ class Signature { * for your Smile account. * @param {string} apiKey - Smile API Key. Found in the Smile Dashboard. */ - constructor(partnerID, apiKey) { + partnerID: string; + + apiKey: string; + + constructor(partnerID: string, apiKey: string) { this.partnerID = partnerID; this.apiKey = apiKey; } @@ -45,16 +49,15 @@ class Signature { * }} - An object containing the signature and timestamp. * @throws {Error} - If the timestamp is invalid. */ - generate_signature(timestamp = new Date().toISOString()) { + generate_signature(timestamp: (string | number) = new Date().toISOString()): + { signature: string, timestamp: number | string } { return { signature: generate_signature(this.partnerID, this.apiKey, timestamp), timestamp, }; } - confirm_signature(timestamp, signature) { + confirm_signature(timestamp: string | number, signature: string) { return generate_signature(this.partnerID, this.apiKey, timestamp) === signature; } } - -module.exports = Signature; diff --git a/src/utilities.js b/src/utilities.ts similarity index 51% rename from src/utilities.js rename to src/utilities.ts index d57eb35..2a93de8 100644 --- a/src/utilities.js +++ b/src/utilities.ts @@ -1,14 +1,16 @@ -const axios = require('axios'); -const Signature = require('./signature'); -const { mapServerUri } = require('./helpers'); +import axios from 'axios'; +import Signature from './signature'; +import { OptionsParam } from './shared'; -const get_job_status = ( - partnerId, - apiKey, - url, - userId, - jobId, - { return_history, return_images }, +import { mapServerUri } from './helpers'; + +export const get_job_status = ( + partnerId: string, + apiKey: string, + url: string, + userId: string | number, + jobId: string | number, + { return_history, return_images } : OptionsParam, ) => axios.post(`https://${url}/job_status`, { user_id: userId, job_id: jobId, @@ -30,16 +32,21 @@ const get_job_status = ( return data; }); -class Utilities { - constructor(partner_id, api_key, sid_server) { +export class Utilities { + partnerId: string; + + apiKey: string; + + url: string; + + constructor(partner_id: string, api_key: string, sid_server: string | number) { this.partnerId = partner_id; this.apiKey = api_key; this.url = mapServerUri(sid_server); } - get_job_status(userId, jobId, options = { return_history: false, return_images: false }) { + get_job_status(userId: string | number, jobId: string | number, options: + OptionsParam = { return_history: false, return_images: false }) { return get_job_status(this.partnerId, this.apiKey, this.url, userId, jobId, options); } } - -module.exports = Utilities; diff --git a/src/web-api.js b/src/web-api.ts similarity index 72% rename from src/web-api.js rename to src/web-api.ts index d9b5e82..2d109dd 100644 --- a/src/web-api.js +++ b/src/web-api.ts @@ -1,12 +1,31 @@ -const fs = require('fs'); -const path = require('path'); -const axios = require('axios'); -const JSzip = require('jszip'); -const Signature = require('./signature'); -const Utilities = require('./utilities'); -const IDApi = require('./id-api'); -const { mapServerUri, sdkVersionInfo, validatePartnerParams } = require('./helpers'); -const { getWebToken } = require('./web-token'); +import fs from 'fs'; +import path from 'path'; +import axios from 'axios'; +import JSzip from 'jszip'; +import Signature from './signature'; +import { Utilities } from './utilities'; +import { IDApi } from './id-api'; +import { mapServerUri, sdkVersionInfo, validatePartnerParams } from './helpers'; +import { getWebToken } from './web-token'; +import { + IdInfo, PartnerParams, OptionsParam, TokenRequestParams, +} from './shared'; + +type PayloadData = { + + [k: string]: string | number | Array<{ [k: string]: number | string }>; +}; + +type ServerInformation = { [k: string]: string | number }; + +type QueryPayload = { + api_key: string; + partner_id: string; + partner_params: PartnerParams; + url: string; + return_history: boolean; + return_images: boolean; +}; /** * Validates if the information required to submit a job is present. @@ -20,19 +39,22 @@ const { getWebToken } = require('./web-token'); * @param {number} jobType - Smile Job Type * @returns {string} value representing if `entered` is true or false. */ -const validateIdInfo = (idInfo, jobType) => { - if (!('entered' in idInfo) || idInfo.entered.toString() === 'false') { +const validateIdInfo = (idInfo: IdInfo, jobType: number): string => { + const entered = idInfo.entered === undefined ? 'false' : idInfo.entered.toString(); + if (!('entered' in idInfo) || entered === 'false') { if (jobType === 6) { // NOTE: document verification does not check for `country` and `id_type`. ['country', 'id_type'].forEach((key) => { - if (!idInfo[key] || idInfo[key].length === 0) { + const idKey = key as keyof IdInfo; + if (!idInfo[idKey] || (idInfo[idKey] as string).length === 0) { throw new Error(`Please make sure that ${key} is included in the id_info`); } }); } return 'false'; - } if ('entered' in idInfo && idInfo.entered.toString() === 'true') { + } if ('entered' in idInfo && entered === 'true') { ['country', 'id_type', 'id_number'].forEach((key) => { - if (!idInfo[key] || idInfo[key].length === 0) { + const idKey = key as keyof IdInfo; + if (!idInfo[idKey] || (idInfo[idKey] as string).length === 0) { throw new Error(`Please make sure that ${key} is included in the id_info`); } }); @@ -49,7 +71,7 @@ const validateIdInfo = (idInfo, jobType) => { * @returns {boolean} - true if bool is true, false if bool is falsy. * @throws {Error} - if bool is not a boolean. */ -const checkBoolean = (key, value) => { +const checkBoolean = (key: string, value: boolean | null): boolean => { if (!value) { return false; } @@ -76,11 +98,12 @@ const checkBoolean = (key, value) => { * }} The options object with each key value coerced to a boolean. * @throws {Error} - if any keys are not booleans. */ -const validateBooleans = (options) => { - const obj = {}; +const validateBooleans = (options: OptionsParam): OptionsParam => { + const obj: { [k:string]:boolean } = {}; const booleanKeys = ['return_job_status', 'return_history', 'return_images', 'use_enrolled_image']; booleanKeys.forEach((key) => { - obj[key] = checkBoolean(key, options[key]); + const optionKey = key as keyof OptionsParam; + obj[key] = checkBoolean(key, options[optionKey] as boolean); }); return obj; }; @@ -91,7 +114,7 @@ const validateBooleans = (options) => { * @param {string|undefined} callbackUrl - The callback URL. * @param {boolean} returnJobStatus - Whether to return job status. */ -const validateReturnData = (callbackUrl, returnJobStatus) => { +const validateReturnData = (callbackUrl: string | undefined, returnJobStatus?: boolean) => { if ((typeof callbackUrl !== 'string' || callbackUrl.length === 0) && !returnJobStatus) { throw new Error('Please choose to either get your response via the callback or job status query'); } @@ -102,18 +125,26 @@ const validateReturnData = (callbackUrl, returnJobStatus) => { * * @param {object} image - image object * @param {number} image.image_type_id - smile image type. + * @param {string} image.image - base64 image or full path to file * @returns {boolean} - true if image is a ID card front image, false otherwise. */ -const hasIdImage = ({ image_type_id }) => [1, 3].includes(image_type_id); +const hasIdImage = ({ image_type_id }: { + image_type_id: number; + image: string; +}): boolean => [1, 3].includes(image_type_id); /** * Checks to see if an image is a selfie image. * * @param {object} image - image object * @param {number} image.image_type_id - smile image type. + * @param {string} image.image - base64 image or full path to file * @returns {boolean} - true if image is a ID card front image, false otherwise. */ -const hasSelfieImage = ({ image_type_id }) => [0, 2].includes(image_type_id); +const hasSelfieImage = ({ image_type_id }: { + image_type_id: number, + image: string +}) => [0, 2].includes(image_type_id); /** * Checks to ensure required images for job type 1 are present. @@ -121,11 +152,14 @@ const hasSelfieImage = ({ image_type_id }) => [0, 2].includes(image_type_id); * @param {Array<{ * image_type_id: number * }>} images - Array of images to be uploaded to smile. - * @param {boolean|undefined} entered - Whether to use a previously uploaded selfie image. - * @returns {undefined} + * @param {boolean} entered - Whether to use a previously uploaded selfie image. + * @returns {void} * @throws {Error} - if images does not contain an image of the front of an id card. */ -const validateEnrollWithId = (images, entered) => { +const validateEnrollWithId = (images: Array<{ + image_type_id: number; + image: string; +}>, entered?: boolean | string): void => { if (!images.some(hasIdImage) && (!entered || entered.toString() !== 'true')) { throw new Error('You are attempting to complete a job type 1 without providing an id card image or id info'); } @@ -137,10 +171,13 @@ const validateEnrollWithId = (images, entered) => { * @param {Array<{ * image_type_id: number * }>} images - Array of images to be uploaded to smile. - * @returns {undefined} + * @returns {void} * @throws {Error} - if images does not contain an image of the front of an id card. */ -const validateDocumentVerification = (images) => { +const validateDocumentVerification = (images: Array<{ + image_type_id: number; + image: string; +}>): void => { if (!images.some(hasIdImage)) { throw new Error('You are attempting to complete a Document Verification job without providing an id card image'); } @@ -155,10 +192,13 @@ const validateDocumentVerification = (images) => { * }>} images - Array of images to be uploaded to smile. * @param {boolean|undefined} useEnrolledImage - Whether to use a previously uploaded selfie image. * @param {number} jobType - The job type. - * @returns {undefined} + * @returns {void} * @throws {Error} - if images does not contain a selfie image. */ -const validateImages = (images, useEnrolledImage, jobType) => { +const validateImages = (images: Array<{ + image_type_id: number, + image: string +}>, useEnrolledImage: boolean | undefined, jobType: number): void => { if (!images) { throw new Error('Please ensure that you send through image details'); } @@ -187,11 +227,18 @@ const validateImages = (images, useEnrolledImage, jobType) => { * @returns {Array<{ * image_type_id: number, * image: string, - * image_file: string, + * file_name: string, * }>} - Array of images with image split by file_name and base64. */ -const configureImagePayload = (images) => images.map(({ image, image_type_id }) => { - const imageTypeId = parseInt(image_type_id, 10); +const configureImagePayload = (images: Array<{ + image_type_id: number; + image: string; +}>): Array<{ + image_type_id: number; + image: string; + file_name: string; +}> => images.map(({ image, image_type_id }) => { + const imageTypeId = parseInt(image_type_id.toString(), 10); if ([0, 1].includes(image_type_id)) { return { image_type_id: imageTypeId, @@ -228,15 +275,15 @@ const configurePrepUploadPayload = ({ partner_params, timestamp, use_enrolled_image, -}) => ({ +}: { [k:string]:string | object }): object => ({ callback_url, file_name: 'selfie.zip', model_parameters: {}, partner_params, smile_client_id: partner_id, use_enrolled_image, - ...idInfo, - ...new Signature(partner_id, api_key).generate_signature(timestamp), + ...idInfo as object, + ...new Signature(partner_id as string, api_key as string).generate_signature(timestamp as string), ...sdkVersionInfo, }); @@ -247,7 +294,7 @@ const configurePrepUploadPayload = ({ * @param {object} serverInformation - server information. * @returns {object} - formatted payload. */ -const configureInfoJson = (data, serverInformation) => ({ +const configureInfoJson = (data: PayloadData, serverInformation: ServerInformation) : object => ({ package_information: { apiVersion: { buildNumber: 0, @@ -278,7 +325,10 @@ const configureInfoJson = (data, serverInformation) => ({ }, }, id_info: data.idInfo, - images: configureImagePayload(data.images), + images: configureImagePayload(data.images as Array<{ + image_type_id: number, + image: string + }>), server_information: serverInformation, }); @@ -304,12 +354,13 @@ const queryJobStatus = ({ url: sidUrl, return_history, return_images, -}, counter = 0) => new Promise((resolve, reject) => { +}: QueryPayload, counter: number | undefined = 0): +Promise => new Promise((resolve, reject) => { // call job status for the result of the job const timeout = counter < 4 ? 2000 : 4000; const updatedCounter = counter + 1; - const retryFunc = (c) => { + const retryFunc = (currentCounter: number) => { setTimeout( () => { queryJobStatus({ @@ -319,7 +370,7 @@ const queryJobStatus = ({ url: sidUrl, return_history, return_images, - }, c).then(resolve).catch(reject); + }, currentCounter).then(resolve).catch(reject); }, timeout, ); @@ -352,11 +403,11 @@ const queryJobStatus = ({ * @throws {Error} - if the request fails or times out. */ const uploadFile = ( - data, - zipFile, - signedUrl, - smile_job_id, -) => axios.put( + data: { [k: string]: string | number | Array | PartnerParams | boolean }, + zipFile: Uint8Array, + signedUrl: string, + smile_job_id: string, +): Promise => axios.put( signedUrl, zipFile, { @@ -368,7 +419,7 @@ const uploadFile = ( ).then((resp) => { if (resp.status === 200) { if (data.return_job_status) { - return queryJobStatus(data); + return queryJobStatus(data as QueryPayload); } return Promise.resolve({ success: true, smile_job_id }); } @@ -386,7 +437,11 @@ const uploadFile = ( * @param {object} infoJson - metadata associated with the job. * @returns {Promise} - the zip file. */ -const zipUpFile = (images, infoJson) => { +const zipUpFile = (images: Array<{ + image_type_id: number; + image: string; + file_name: string; +}>, infoJson: object): Promise => { // create zip file in memory const zip = new JSzip(); zip.file('info.json', JSON.stringify(infoJson)); @@ -402,16 +457,24 @@ const zipUpFile = (images, infoJson) => { * @param {object} payload - data required to upload the zip file to s3. * @returns {Promise} the job status response. */ -const setupRequests = (payload) => axios.post( +const setupRequests = (payload: { [k: string]: unknown }): Promise => axios.post( `https://${payload.url}/upload`, - configurePrepUploadPayload(payload), + configurePrepUploadPayload(payload as { + [k: string]: string | object; + }), ).then(({ data }) => Promise.all([ - zipUpFile(payload.images, configureInfoJson(payload, data)), + zipUpFile(payload.images as Array<{ + image_type_id: number; + image: string; + file_name: string; + }>, configureInfoJson(payload as PayloadData, data)), Promise.resolve(data), ])).then(([zipFile, - { upload_url, smile_job_id }]) => uploadFile(payload, zipFile, upload_url, smile_job_id)); + { upload_url, smile_job_id }]) => uploadFile(payload as { + [k: string]: string | number | object[]; +}, zipFile, upload_url, smile_job_id)); -class WebApi { +export class WebApi { /** * Creates an instance of WebApi. * @@ -421,7 +484,20 @@ class WebApi { * @param {string|number} sid_server - The server to use for the SID API. 0 for * staging and 1 for production. */ - constructor(partner_id, default_callback, api_key, sid_server) { + partner_id: string; + + default_callback: string | null | undefined; + + api_key: string; + + url: string; + + constructor( + partner_id: string, + default_callback: string | null | undefined, + api_key: string, + sid_server: string | number, + ) { this.partner_id = partner_id; this.default_callback = default_callback; this.api_key = api_key; @@ -443,7 +519,7 @@ class WebApi { * @throws {Error} If any of the required parameters are missing or if the request fails. * @memberof WebApi */ - get_job_status(partner_params, options) { + get_job_status(partner_params: PartnerParams, options: OptionsParam) { return new Utilities(this.partner_id, this.api_key, this.url).get_job_status( partner_params.user_id, partner_params.job_id, @@ -466,13 +542,15 @@ class WebApi { * @throws {Error} If any of the required parameters are missing or if the request fails. * @memberof WebApi */ - get_web_token(requestParams) { + get_web_token(requestParams: TokenRequestParams): Promise<{ + token: string; + }> { return getWebToken( this.partner_id, this.api_key, this.url, requestParams, - this.default_callback, + this.default_callback as string, ); } @@ -508,16 +586,21 @@ class WebApi { * @throws {Error} If any of the required parameters are missing or if the request fails. * @memberof WebApi */ - submit_job(partner_params, image_details, id_info, options = {}) { - if (parseInt(partner_params && partner_params.job_type, 10) === 5) { - return new IDApi(this.partner_id, this.api_key, this.url).submit_job(partner_params, id_info); - } - + submit_job(partner_params: PartnerParams, image_details: Array<{ + image_type_id: number; + image: string; + }>, id_info: IdInfo, options: OptionsParam = {}): Promise { try { validatePartnerParams(partner_params); + + if (parseInt(partner_params && partner_params.job_type.toString(), 10) === 5) { + return new IDApi(this.partner_id, this.api_key, this.url) + .submit_job(partner_params, id_info); + } + const callbackUrl = (options && options.optional_callback) || this.default_callback; - const jobType = parseInt(partner_params.job_type, 10); - const data = { + const jobType = parseInt(partner_params.job_type.toString(), 10); + const data : { [k:string]:unknown } = { partner_id: this.partner_id, api_key: this.api_key, url: this.url, @@ -536,10 +619,10 @@ class WebApi { }; validateImages(image_details, options.use_enrolled_image, jobType); - validateReturnData(callbackUrl, data.return_job_status); + validateReturnData(callbackUrl as string, data.return_job_status as boolean); if (jobType === 1) { - validateEnrollWithId(image_details, data.idInfo.entered); + validateEnrollWithId(image_details, (data.idInfo as IdInfo).entered); } else if (jobType === 6) { validateDocumentVerification(image_details); } @@ -550,5 +633,3 @@ class WebApi { } } } - -module.exports = WebApi; diff --git a/src/web-token.js b/src/web-token.ts similarity index 80% rename from src/web-token.js rename to src/web-token.ts index 6755a99..6498de4 100644 --- a/src/web-token.js +++ b/src/web-token.ts @@ -1,6 +1,7 @@ -const axios = require('axios'); -const Signature = require('./signature'); -const { mapServerUri } = require('./helpers'); +import axios from 'axios'; +import Signature from './signature'; +import { mapServerUri } from './helpers'; +import { TokenRequestParams } from './shared'; /** * Gets an authorization token from Smile. Used in Hosted Web Integration. @@ -20,13 +21,15 @@ const { mapServerUri } = require('./helpers'); * }>} - The authorization token. * @throws {Error} - if the request fails. */ -const getWebToken = ( - partner_id, - api_key, - url, - requestParams, - defaultCallback, -) => { +export const getWebToken = ( + partner_id: string, + api_key: string, + url: string, + requestParams: TokenRequestParams, + defaultCallback: string, +): Promise<{ + token: string; +}> => { if (!requestParams) { return Promise.reject(new Error('Please ensure that you send through request params')); } @@ -40,7 +43,7 @@ const getWebToken = ( return Promise.reject(new Error('Callback URL is required for this method')); } - const missingKey = ['user_id', 'job_id', 'product'].find((key) => !requestParams[key]); + const missingKey = ['user_id', 'job_id', 'product'].find((key) => !requestParams[key as keyof TokenRequestParams]); if (missingKey) { return Promise.reject(new Error(`${missingKey} is required to get a web token`)); } @@ -59,5 +62,3 @@ const getWebToken = ( return axios.post(`https://${mapServerUri(url)}/token`, body).then((response) => response.data); }; - -module.exports = { getWebToken }; diff --git a/test/constant.test.js b/test/constant.test.ts similarity index 93% rename from test/constant.test.js rename to test/constant.test.ts index 1bb0689..8dbcd7a 100644 --- a/test/constant.test.js +++ b/test/constant.test.ts @@ -1,4 +1,4 @@ -const { JOB_TYPE } = require('..'); +import { JOB_TYPE } from '..'; describe('Constant', () => { it('should have correct jobtypes', () => { diff --git a/test/helpers.test.js b/test/helpers.test.ts similarity index 90% rename from test/helpers.test.js rename to test/helpers.test.ts index c81c00e..55f50b4 100644 --- a/test/helpers.test.js +++ b/test/helpers.test.ts @@ -1,4 +1,4 @@ -const { mapServerUri, sdkVersionInfo, validatePartnerParams } = require('../src/helpers'); +import { mapServerUri, sdkVersionInfo, validatePartnerParams } from '../src/helpers'; describe('helpers', () => { it('mapServerUri', () => { @@ -17,6 +17,7 @@ describe('helpers', () => { ]; testCases.forEach((testCase) => { + // @ts-ignore expect(mapServerUri(testCase.input)).toEqual(testCase.expected); }); }); @@ -24,8 +25,8 @@ describe('helpers', () => { it('sdkVersionInfo', () => { expect(typeof sdkVersionInfo).toEqual('object'); expect(sdkVersionInfo.source_sdk).toEqual('javascript'); - expect(sdkVersionInfo.source_sdk_version).toMatch(/^\d+\.\d+\.\d+$/); - expect(sdkVersionInfo.source_sdk_version).toMatch(/^2\./); // assert that we are at version 2 + expect(sdkVersionInfo.source_sdk_version).toMatch(/^\d+\.\d+\.\d+(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)$/); + expect(sdkVersionInfo.source_sdk_version).toMatch(/^3\./); // assert that we are at version 2 expect(Object.keys(sdkVersionInfo).length).toEqual(2); }); @@ -44,6 +45,7 @@ describe('helpers', () => { testCases.forEach((testCase) => { let error = { message: null }; try { + // @ts-ignore validatePartnerParams(testCase.input); } catch (err) { error = err; diff --git a/test/id-api.test.js b/test/id-api.test.ts similarity index 91% rename from test/id-api.test.js rename to test/id-api.test.ts index 3de1168..ed4ae2f 100755 --- a/test/id-api.test.js +++ b/test/id-api.test.ts @@ -1,8 +1,8 @@ -const keypair = require('keypair'); -const nock = require('nock'); -const packageJson = require('../package.json'); +import keypair from 'keypair'; +import nock from 'nock'; +import * as packageJson from '../package.json'; -const { IDApi, Signature } = require('..'); +import { IDApi, Signature } from '..'; const pair = keypair(); @@ -34,12 +34,14 @@ describe('IDapi', () => { it('should ensure that the partner_params are present', async () => { expect.assertions(1); const instance = new IDApi('001', Buffer.from(pair.public).toString('base64'), 0); + // @ts-ignore await expect(instance.submit_job(null, {})).rejects.toThrow(new Error('Please ensure that you send through partner params')); }); it('should ensure that the partner_params are an object', async () => { expect.assertions(1); const instance = new IDApi('001', Buffer.from(pair.public).toString('base64'), 0); + // @ts-ignore await expect(instance.submit_job('not partner params', {})).rejects.toThrow(new Error('Partner params needs to be an object')); }); @@ -50,19 +52,20 @@ describe('IDapi', () => { it(`should ensure that partner_params contains ${key}`, async () => { expect.assertions(1); const instance = new IDApi('001', Buffer.from(pair.public).toString('base64'), 0); - await expect(instance.submit_job(partner_params, {}, {}, { return_job_status: true })).rejects.toThrow(new Error(`Please make sure that ${key} is included in the partner params`)); + await expect(instance.submit_job(partner_params, {})).rejects.toThrow(new Error(`Please make sure that ${key} is included in the partner params`)); }); it(`should ensure that in partner_params, ${key} is not an empty string`, async () => { expect.assertions(1); const instance = new IDApi('001', Buffer.from(pair.public).toString('base64'), 0); - await expect(instance.submit_job(partner_params, {}, {}, { return_job_status: true })).rejects.toThrow(new Error(`Please make sure that ${key} is included in the partner params`)); + await expect(instance.submit_job(partner_params, {})).rejects.toThrow(new Error(`Please make sure that ${key} is included in the partner params`)); }); }); it('should ensure that the id_info is an object', async () => { expect.assertions(1); const instance = new IDApi('001', Buffer.from(pair.public).toString('base64'), 0); + // @ts-ignore await expect(instance.submit_job({ user_id: '1', job_id: '1', job_type: 5 }, '')).rejects.toThrow(new Error('ID Info needs to be an object')); }); @@ -82,6 +85,7 @@ describe('IDapi', () => { expect.assertions(1); const instance = new IDApi('001', Buffer.from(pair.public).toString('base64'), 0); const partner_params = { user_id: '1', job_id: '1', job_type: 4 }; + // @ts-ignore await expect(instance.submit_job(partner_params, null)).rejects.toThrow(new Error('Please ensure that you are setting your job_type to 5 to query ID Api')); }); @@ -123,7 +127,6 @@ describe('IDapi', () => { FullName: 'some person', DOB: 'NaN-NaN-NaN', Photo: 'Not Available', - signature: 'RKYX2ZVpvNTFW8oXdN3iTvQcefV93VMo18LQ/Uco0=|7f0b0d5ebc3e5499c224f2db478e210d1860f01368ebc045c7bbe6969f1c08ba', ...new Signature('001', mockApiKey).generate_signature(timestamp), }; diff --git a/test/index.test.js b/test/index.test.ts similarity index 77% rename from test/index.test.js rename to test/index.test.ts index febc9e0..8fb06e4 100644 --- a/test/index.test.js +++ b/test/index.test.ts @@ -1,8 +1,9 @@ -const smileIdentityCore = require('..'); +import * as smileIdentityCore from '..'; describe('smile-identity-core', () => { it('should export an object', () => { - expect(smileIdentityCore).toBeInstanceOf(Object); + expect(typeof smileIdentityCore).toBe('object'); + expect(smileIdentityCore).not.toBeNull(); }); it('should export four classes', () => { @@ -26,12 +27,12 @@ describe('smile-identity-core', () => { beforeAll(() => { jest.resetModules(); global.window = {}; - console.error = jest.fn(); + console.warn = jest.fn(); require('..'); // eslint-disable-line global-require }); it('should throw an error when run in a browser', () => { - expect(console.error).toHaveBeenCalledWith('This is a server-side library meant for a node.js (or compatible) runtime, and is not meant to work in the browser.'); + expect(console.warn).toHaveBeenCalledWith('This is a server-side library meant for a node.js (or compatible) runtime, and is not meant to work in the browser.'); }); }); }); diff --git a/test/signature.test.js b/test/signature.test.ts similarity index 96% rename from test/signature.test.js rename to test/signature.test.ts index 9eea935..4f6abcf 100644 --- a/test/signature.test.js +++ b/test/signature.test.ts @@ -1,7 +1,7 @@ -const crypto = require('crypto'); -const keypair = require('keypair'); +import crypto from 'crypto'; +import keypair from 'keypair'; -const { Signature } = require('..'); +import { Signature } from '..'; const pair = keypair(); diff --git a/test/utilities.test.js b/test/utilities.test.ts similarity index 97% rename from test/utilities.test.js rename to test/utilities.test.ts index 3800ac8..abb891a 100755 --- a/test/utilities.test.js +++ b/test/utilities.test.ts @@ -1,7 +1,7 @@ -const keypair = require('keypair'); -const nock = require('nock'); +import keypair from 'keypair'; +import nock from 'nock'; -const { Utilities, Signature } = require('..'); +import { Utilities, Signature } from '..'; const pair = keypair(); const mockApiKey = Buffer.from(pair.public).toString('base64'); diff --git a/test/web-api.test.js b/test/web-api.test.ts old mode 100755 new mode 100644 similarity index 99% rename from test/web-api.test.js rename to test/web-api.test.ts index 30aa48a..4a05a82 --- a/test/web-api.test.js +++ b/test/web-api.test.ts @@ -1,11 +1,11 @@ -const path = require('path'); -const keypair = require('keypair'); -const nock = require('nock'); -const packageJson = require('../package.json'); +import path from 'path'; +import keypair from 'keypair'; +import nock from 'nock'; +import packageJson from '../package.json'; -const { +import { WebApi, Signature, IMAGE_TYPE, JOB_TYPE, -} = require('..'); +} from '..'; const pair = keypair(); const fixturePath = path.join(__dirname, 'fixtures', '1pixel.jpg'); diff --git a/test/web-token.test.js b/test/web-token.test.ts similarity index 96% rename from test/web-token.test.js rename to test/web-token.test.ts index 22517ec..7b8626e 100644 --- a/test/web-token.test.js +++ b/test/web-token.test.ts @@ -1,9 +1,7 @@ -const keypair = require('keypair'); -const nock = require('nock'); +import keypair from 'keypair'; +import nock, { disableNetConnect, cleanAll, enableNetConnect } from 'nock'; -const { - getWebToken, -} = require('../src/web-token'); +import { getWebToken } from '../src/web-token'; const pair = keypair(); @@ -11,16 +9,16 @@ const mockApiKey = Buffer.from(pair.public).toString('base64'); describe('web-token', () => { beforeAll(() => { - nock.disableNetConnect(); + disableNetConnect(); }); afterEach(() => { - nock.cleanAll(); + cleanAll(); jest.clearAllMocks(); }); afterAll(() => { - nock.enableNetConnect(); + enableNetConnect(); }); describe('#get_web_token', () => { diff --git a/tsconfig.declarations.json b/tsconfig.declarations.json new file mode 100644 index 0000000..23a14f2 --- /dev/null +++ b/tsconfig.declarations.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "skipDefaultLibCheck": true, + "outFile": "./dist/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true, + } +} diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 0000000..e96c3a4 --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["**/*.ts", "**/*.js", "examples", ".eslintrc.js", "babel.config.js"], + "exclude": ["dist"], + "compilerOptions": { + "noEmit": true, + "skipDefaultLibCheck": true, + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..69fbb9b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "include": [ + "index.ts", + "src/**/*"], + "compilerOptions": { + "target": "ES2021", + "module": "commonjs", + "rootDir": "./", + "moduleResolution": "node", + "resolveJsonModule": true, + "allowJs": true, + "outDir": "./dist", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "sourceMap": true, + } +}