diff --git a/dist/index.js b/dist/index.js index 2b117b2efff32c0c9fe02f52ec27e38f5ea9d814..51087b584ddf8bf3f5e6862bfcb501948d81bae0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9,28 +9,31 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); exports.SigningService = exports.RKAUtility = exports.QrCodeTemplate = exports.VerificationError = exports.CryptoService = exports.QrCodeDataService = exports.CommonUtils = exports.StatusesService = exports.VerificationService = exports.CloudflareService = void 0; __exportStar(require("./types"), exports); __exportStar(require("./services/SigningService/types"), exports); __exportStar(require("./utils/common"), exports); var CloudflareService_1 = require("./services/CloudflareService"); -Object.defineProperty(exports, "CloudflareService", { enumerable: true, get: function () { return CloudflareService_1.default; } }); +Object.defineProperty(exports, "CloudflareService", { enumerable: true, get: function () { return __importDefault(CloudflareService_1).default; } }); var VerificationService_1 = require("./services/VerificationService"); -Object.defineProperty(exports, "VerificationService", { enumerable: true, get: function () { return VerificationService_1.default; } }); +Object.defineProperty(exports, "VerificationService", { enumerable: true, get: function () { return __importDefault(VerificationService_1).default; } }); var StatusesService_1 = require("./services/StatusesService"); -Object.defineProperty(exports, "StatusesService", { enumerable: true, get: function () { return StatusesService_1.default; } }); +Object.defineProperty(exports, "StatusesService", { enumerable: true, get: function () { return __importDefault(StatusesService_1).default; } }); var common_1 = require("./utils/common"); -Object.defineProperty(exports, "CommonUtils", { enumerable: true, get: function () { return common_1.default; } }); +Object.defineProperty(exports, "CommonUtils", { enumerable: true, get: function () { return __importDefault(common_1).default; } }); var QrCodeDataService_1 = require("./services/QrCodeDataService"); -Object.defineProperty(exports, "QrCodeDataService", { enumerable: true, get: function () { return QrCodeDataService_1.default; } }); +Object.defineProperty(exports, "QrCodeDataService", { enumerable: true, get: function () { return __importDefault(QrCodeDataService_1).default; } }); var CryptoService_1 = require("./services/CryptoService"); -Object.defineProperty(exports, "CryptoService", { enumerable: true, get: function () { return CryptoService_1.default; } }); +Object.defineProperty(exports, "CryptoService", { enumerable: true, get: function () { return __importDefault(CryptoService_1).default; } }); var VerificationError_1 = require("./services/VerificationService/VerificationError"); -Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return VerificationError_1.default; } }); +Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return __importDefault(VerificationError_1).default; } }); var qrCodeTemplateUtils_1 = require("./utils/qrCodeTemplateUtils"); -Object.defineProperty(exports, "QrCodeTemplate", { enumerable: true, get: function () { return qrCodeTemplateUtils_1.default; } }); +Object.defineProperty(exports, "QrCodeTemplate", { enumerable: true, get: function () { return __importDefault(qrCodeTemplateUtils_1).default; } }); var rka_1 = require("./utils/rka"); -Object.defineProperty(exports, "RKAUtility", { enumerable: true, get: function () { return rka_1.default; } }); +Object.defineProperty(exports, "RKAUtility", { enumerable: true, get: function () { return __importDefault(rka_1).default; } }); var SigningService_1 = require("./services/SigningService"); -Object.defineProperty(exports, "SigningService", { enumerable: true, get: function () { return SigningService_1.default; } }); +Object.defineProperty(exports, "SigningService", { enumerable: true, get: function () { return __importDefault(SigningService_1).default; } }); diff --git a/dist/services/AeternityService.js b/dist/services/AeternityService.js index fca65706bfce2d197e36e03ecdefe314ccc7fd6e..bd3a3106941d837813dbdd043dbbfad4a96c0c39 100644 --- a/dist/services/AeternityService.js +++ b/dist/services/AeternityService.js @@ -8,8 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const axios_1 = require("axios"); +const axios_1 = __importDefault(require("axios")); class AeternityService { constructor(nodeUrl, compilerUrl, contractBytecode) { this._nodeUrl = ""; diff --git a/dist/services/CloudflareService.js b/dist/services/CloudflareService.js index 030480634d537fb310ea72ec9d667ea3dc02d404..1f4dd9c67fd94a7e410b25b178044bcffae9b9f2 100644 --- a/dist/services/CloudflareService.js +++ b/dist/services/CloudflareService.js @@ -8,9 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const axios_1 = require("axios"); -const StatusesService_1 = require("./StatusesService"); +const axios_1 = __importDefault(require("axios")); +const StatusesService_1 = __importDefault(require("./StatusesService")); const common_1 = require("../utils/common"); const STATUS_FILE_PREFIX = "bs"; class CloudflareService { diff --git a/dist/services/CryptoService/CryptoServiceNode.js b/dist/services/CryptoService/CryptoServiceNode.js index 2e13a114c2a9d3bfea1bc5221c807ddefbb50856..6cb225c8493a47c9ae583c8b2f4d1734d85342a4 100644 --- a/dist/services/CryptoService/CryptoServiceNode.js +++ b/dist/services/CryptoService/CryptoServiceNode.js @@ -1,4 +1,23 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -8,10 +27,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); // All functions are async in order to be compatible with the ICryptoService API -const js_md5_1 = require("js-md5"); -const crypto = require("crypto"); +const js_md5_1 = __importDefault(require("js-md5")); +const crypto = __importStar(require("crypto")); const common_1 = require("../../utils/common"); const AES_GCM_ALGO = "aes-256-gcm"; const encryptAESGCM = (data) => __awaiter(void 0, void 0, void 0, function* () { diff --git a/dist/services/CryptoService/CryptoServiceWeb.js b/dist/services/CryptoService/CryptoServiceWeb.js index 762144298f03e36b7012b4ea278dba2111dbd8cf..7e77c6e8d5650d69b8cfa3a27b5c1f9047b98ce4 100644 --- a/dist/services/CryptoService/CryptoServiceWeb.js +++ b/dist/services/CryptoService/CryptoServiceWeb.js @@ -8,9 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyRSASignature = void 0; -const js_md5_1 = require("js-md5"); +const js_md5_1 = __importDefault(require("js-md5")); const common_1 = require("../../utils/common"); function exportKey(key) { return __awaiter(this, void 0, void 0, function* () { @@ -31,7 +34,7 @@ const convertPemToBinary = (pem) => { } return common_1.base64ToArrayBuffer(encoded); }; -exports.verifyRSASignature = (publicKeyPEM, data, signature) => __awaiter(void 0, void 0, void 0, function* () { +const verifyRSASignature = (publicKeyPEM, data, signature) => __awaiter(void 0, void 0, void 0, function* () { const publicKey = yield crypto.subtle.importKey("spki", convertPemToBinary(publicKeyPEM), { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256", @@ -41,6 +44,7 @@ exports.verifyRSASignature = (publicKeyPEM, data, signature) => __awaiter(void 0 hash: "SHA-256", }, publicKey, signature, data); }); +exports.verifyRSASignature = verifyRSASignature; const encryptAESGCM = (data) => __awaiter(void 0, void 0, void 0, function* () { const key = yield crypto.subtle.generateKey({ name: "AES-GCM", diff --git a/dist/services/CryptoService/index.js b/dist/services/CryptoService/index.js index 7166789d24364d957ede7760d163da5b1eb6329c..ce863013f23d371a28f88872926e9ac1b53f39f1 100644 --- a/dist/services/CryptoService/index.js +++ b/dist/services/CryptoService/index.js @@ -1,7 +1,10 @@ "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const CryptoServiceNode_1 = require("./CryptoServiceNode"); -const CryptoServiceWeb_1 = require("./CryptoServiceWeb"); +const CryptoServiceNode_1 = __importDefault(require("./CryptoServiceNode")); +const CryptoServiceWeb_1 = __importDefault(require("./CryptoServiceWeb")); const service = typeof crypto !== "undefined" && crypto.subtle ? CryptoServiceWeb_1.default : CryptoServiceNode_1.default; diff --git a/dist/services/QrCodeDataService.js b/dist/services/QrCodeDataService.js index 272cddad5f772c8a129b3495a3c508e9361caf47..34a1c5c1dc96939fce94d3e6a31ae35aa60fbd74 100644 --- a/dist/services/QrCodeDataService.js +++ b/dist/services/QrCodeDataService.js @@ -8,11 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const axios_1 = require("axios"); +const axios_1 = __importDefault(require("axios")); const qrcode_data_pb_1 = require("../generated/qrcode_data_pb"); const common_1 = require("../utils/common"); -const CryptoService_1 = require("./CryptoService"); +const CryptoService_1 = __importDefault(require("./CryptoService")); const index_1 = require("../index"); const EmailDataMessageV1 = qrcode_data_pb_1.vereign.protobuf.qrcode_data.EmailData_V1; const KeyDataMessageV1 = qrcode_data_pb_1.vereign.protobuf.qrcode_data.KeyData_V1; diff --git a/dist/services/SigningService/SigningService.js b/dist/services/SigningService/SigningService.js index c9e46c2e73c82a68181b706e16810dfc7fff0abd..9c172c917cab9ae575368a6a57b7e80134950774 100644 --- a/dist/services/SigningService/SigningService.js +++ b/dist/services/SigningService/SigningService.js @@ -1,4 +1,23 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -8,11 +27,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); const mime_normalizer_1 = require("@vereign/mime-normalizer"); -const png_1 = require("@vereign/png"); -const mime_parser_1 = require("@vereign/mime-parser"); -const rka_1 = require("../../utils/rka"); +const png_1 = __importStar(require("@vereign/png")); +const mime_parser_1 = __importDefault(require("@vereign/mime-parser")); +const rka_1 = __importDefault(require("../../utils/rka")); const index_1 = require("../../index"); const severityLevels_1 = require("./severityLevels"); class SigningService { diff --git a/dist/services/SigningService/index.js b/dist/services/SigningService/index.js index 950ad0266b5748df05b9fe2d87aeff5bade18887..29fd2e01694ebc3e935595563177035c03cb17a4 100644 --- a/dist/services/SigningService/index.js +++ b/dist/services/SigningService/index.js @@ -1,4 +1,7 @@ "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const SigningService_1 = require("./SigningService"); +const SigningService_1 = __importDefault(require("./SigningService")); exports.default = SigningService_1.default; diff --git a/dist/services/SigningService/severityLevels.js b/dist/services/SigningService/severityLevels.js index a0047837f28dc4035b5652c760963e9660af4696..c437cc203490337fb6de8c7a97ade80d62db5e25 100644 --- a/dist/services/SigningService/severityLevels.js +++ b/dist/services/SigningService/severityLevels.js @@ -45,7 +45,7 @@ exports.SEVERITY_MESSAGE_PER_STATE = [ "CAUTION! This message has been tampered with. Do not click on any links, do not rely on its information. Contact the sender.", "The message is authentic, but at least one attachment appears to have been altered. Caution advised for the attachments, do not open!", ]; -exports.findSeverityStateIndex = (htmlValid, plainValid, pseudoPlainValid, attachmentsValid) => { +const findSeverityStateIndex = (htmlValid, plainValid, pseudoPlainValid, attachmentsValid) => { let index = -1; const verificationState = [ +htmlValid, @@ -70,3 +70,4 @@ exports.findSeverityStateIndex = (htmlValid, plainValid, pseudoPlainValid, attac } return index; }; +exports.findSeverityStateIndex = findSeverityStateIndex; diff --git a/dist/services/VerificationService/VerificationService.js b/dist/services/VerificationService/VerificationService.js index 104b8107e9dd875cd7d3f4943e5e7da22985672f..bbe98bc604133f5487ef2e78ba1e4ae1d64ca1ba 100644 --- a/dist/services/VerificationService/VerificationService.js +++ b/dist/services/VerificationService/VerificationService.js @@ -8,14 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); exports.BLOCK_DATA_RETRIEVED = exports.MERKLE_TREE_VERIFIED = exports.TRANSACTION_RETRIEVED = void 0; const index_1 = require("../../index"); const EventEmitter = require("eventemitter2"); const merkletreejs_1 = require("merkletreejs"); -const AeternityService_1 = require("../AeternityService"); -const CloudflareService_1 = require("../CloudflareService"); -const VerificationError_1 = require("./VerificationError"); +const AeternityService_1 = __importDefault(require("../AeternityService")); +const CloudflareService_1 = __importDefault(require("../CloudflareService")); +const VerificationError_1 = __importDefault(require("./VerificationError")); exports.TRANSACTION_RETRIEVED = "TRANSACTION_RETRIEVED"; exports.MERKLE_TREE_VERIFIED = "MERKLE_TREE_VERIFIED"; exports.BLOCK_DATA_RETRIEVED = "BLOCK_DATA_RETRIEVED"; diff --git a/dist/services/VerificationService/index.js b/dist/services/VerificationService/index.js index 303dd41f6f5aa8677ef8bf5b9d6d8d15b4f88128..23f5fc63eff5fc7e83bdcc242d05c011d1d22f38 100644 --- a/dist/services/VerificationService/index.js +++ b/dist/services/VerificationService/index.js @@ -1,4 +1,7 @@ "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const VerificationService_1 = require("./VerificationService"); +const VerificationService_1 = __importDefault(require("./VerificationService")); exports.default = VerificationService_1.default; diff --git a/dist/utils/common.js b/dist/utils/common.js index b288c65816312209127ff0c473b9ec0627c31418..580fef358ff96a4597afbc811802090e4f94d119 100644 --- a/dist/utils/common.js +++ b/dist/utils/common.js @@ -2,19 +2,23 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.arrayBufferToHex = exports.decompressData = exports.compressData = exports.ensureUint8Array = exports.ensureArrayBuffer = exports.ensureBase64 = exports.base64ToArrayBuffer = exports.arrayBufferToBase64 = void 0; const zlib_min_1 = require("zlibjs/bin/zlib.min"); -exports.arrayBufferToBase64 = (buffer) => { +const arrayBufferToBase64 = (buffer) => { return Buffer.from(buffer).toString("base64"); }; -exports.base64ToArrayBuffer = (base64) => { +exports.arrayBufferToBase64 = arrayBufferToBase64; +const base64ToArrayBuffer = (base64) => { return Buffer.from(base64, "base64"); }; -exports.ensureBase64 = (data) => { +exports.base64ToArrayBuffer = base64ToArrayBuffer; +const ensureBase64 = (data) => { return typeof data === "string" ? data : exports.arrayBufferToBase64(data); }; -exports.ensureArrayBuffer = (data) => { +exports.ensureBase64 = ensureBase64; +const ensureArrayBuffer = (data) => { return typeof data === "string" ? exports.base64ToArrayBuffer(data) : data; }; -exports.ensureUint8Array = (data) => { +exports.ensureArrayBuffer = ensureArrayBuffer; +const ensureUint8Array = (data) => { return data instanceof Uint8Array ? data : typeof data === "string" @@ -23,19 +27,23 @@ exports.ensureUint8Array = (data) => { ? new Uint8Array(data) : data; }; -exports.compressData = (binary) => { +exports.ensureUint8Array = ensureUint8Array; +const compressData = (binary) => { const deflate = new zlib_min_1.Zlib.Deflate(exports.ensureUint8Array(binary)); return deflate.compress(); }; -exports.decompressData = (binary) => { +exports.compressData = compressData; +const decompressData = (binary) => { const inflate = new zlib_min_1.Zlib.Inflate(exports.ensureUint8Array(binary)); return inflate.decompress(); }; -exports.arrayBufferToHex = (buffer) => { +exports.decompressData = decompressData; +const arrayBufferToHex = (buffer) => { return [...new Uint8Array(buffer)] .map((b) => b.toString(16).padStart(2, "0")) .join(""); }; +exports.arrayBufferToHex = arrayBufferToHex; exports.default = { compressData: exports.compressData, decompressData: exports.decompressData, diff --git a/dist/utils/qrCodeTemplateUtils.d.ts b/dist/utils/qrCodeTemplateUtils.d.ts index 26ba313037201c52bb286870952ee60625eabbfe..e3e8c4fcc2b5ddb72a24040ff3d69733076846f0 100644 --- a/dist/utils/qrCodeTemplateUtils.d.ts +++ b/dist/utils/qrCodeTemplateUtils.d.ts @@ -1,4 +1,21 @@ +interface TemplateOptions { + src: string; + placeholderSize: number; +} +/** + * https://www.qrcode.com/en/about/error_correction.html#:~:text=QR%20Code%20has%20error%20correction,of%20data%20QR%20Code%20size. + */ +declare type CorrectionLevels = "L" | "M" | "Q" | "H"; +interface QrCodeOptions { + width?: number; + height?: number; + logoSrc?: string; + logoWidth?: number; + logoHeight?: number; + correctionLevel?: CorrectionLevels; +} declare const _default: { putQrCodeOnChromakeyTemplate: (qrCodeImageBase64: string, templateImageBase64: string, placeholderWidth: number, placeholderHeight: number, scale?: number) => Promise<string>; + generateQrCode: (text: string, qrCodeOptions?: QrCodeOptions, templateOptions?: TemplateOptions) => Promise<string>; }; export default _default; diff --git a/dist/utils/qrCodeTemplateUtils.js b/dist/utils/qrCodeTemplateUtils.js index d5c8821ed1ae55f137c1494245aee8861d2fd671..d406abcba39d09ba8dd0571a8e15394289f8ee4c 100644 --- a/dist/utils/qrCodeTemplateUtils.js +++ b/dist/utils/qrCodeTemplateUtils.js @@ -8,7 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); +const easyqrcodejs_1 = __importDefault(require("easyqrcodejs")); +const DEFAULT_TEMPLATE = "data:image/png;base64,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"; +const DEFAULT_LOGO = "data:image/png;base64,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"; const findChromakeyBoundaries = (width, height, imageData, chromakeyWidth, chromakeyHeight) => { const maskSizeX = chromakeyWidth; const maskSizeY = chromakeyHeight; @@ -87,6 +93,55 @@ const findChromakeyBoundaries = (width, height, imageData, chromakeyWidth, chrom } return { fromL: -1, fromT: -1, toL: -1, toT: -1 }; }; +const generateQrCode = (text, qrCodeOptions, templateOptions) => __awaiter(void 0, void 0, void 0, function* () { + if (typeof document === "undefined") { + throw new Error("QR Code generation is not supported in non-browser environments"); + } + const defaultOptions = { + width: 256, + height: 256, + logoSrc: DEFAULT_LOGO, + logoWidth: 75, + logoHeight: 66, + // Use "L" level as we don't need a redundancy + correctionLevel: "L", + }; + qrCodeOptions = qrCodeOptions + ? Object.assign(defaultOptions, qrCodeOptions) + : defaultOptions; + const defaultTemplateOptions = { + placeholderSize: 260, + src: DEFAULT_TEMPLATE, + }; + templateOptions = templateOptions + ? Object.assign(defaultTemplateOptions, templateOptions) + : defaultTemplateOptions; + const container = document.createElement("div"); + const options = { + text, + width: qrCodeOptions.width, + height: qrCodeOptions.height, + colorDark: "#000000", + colorLight: "#ffffff", + dotScale: 1, + PO: "#d51d32", + PI: "#d51d32", + correctLevel: easyqrcodejs_1.default.CorrectLevel[qrCodeOptions.correctionLevel], + }; + if (qrCodeOptions.logoSrc) { + Object.assign(options, { + logo: qrCodeOptions.logoSrc, + logoBackgroundTransparent: true, + logoWidth: qrCodeOptions.logoWidth, + logoHeight: qrCodeOptions.logoHeight, + }); + } + new easyqrcodejs_1.default(container, options); + const canvas = container.getElementsByTagName("canvas")[0]; + // Add short async action because of the bug with logo not appearing in the resulting image. + yield new Promise((resolve) => setTimeout(resolve, 10)); + return yield putQrCodeOnChromakeyTemplate(canvas.toDataURL(), templateOptions.src, templateOptions.placeholderSize, templateOptions.placeholderSize); +}); const putQrCodeOnChromakeyTemplate = (qrCodeImageBase64, templateImageBase64, placeholderWidth, placeholderHeight, scale = 1) => __awaiter(void 0, void 0, void 0, function* () { const qrCodeImage = yield loadImage(qrCodeImageBase64); const templateImage = yield loadImage(templateImageBase64); @@ -128,4 +183,5 @@ const loadImage = (imageSrc) => { }; exports.default = { putQrCodeOnChromakeyTemplate, + generateQrCode, }; diff --git a/dist/utils/rka.js b/dist/utils/rka.js index f4b20a1f5135bc1d6de3a3af33c0d14803f2f23f..6a51a43f7cbdfe34eec2d18ea200a2c55ab185de 100644 --- a/dist/utils/rka.js +++ b/dist/utils/rka.js @@ -50,7 +50,7 @@ const searchFingerprintInText = (text, keywordHashHexString, size) => { } return -1; }; -exports.findRKASubstring = (string, rabinFingerprint, substringSize) => { +const findRKASubstring = (string, rabinFingerprint, substringSize) => { if (!string.length) { return ""; } @@ -60,6 +60,7 @@ exports.findRKASubstring = (string, rabinFingerprint, substringSize) => { } return string.slice(startingIndex, startingIndex + substringSize); }; +exports.findRKASubstring = findRKASubstring; /** * @deprecated Will be deleted in version 1.0.1. Use getRabinFingerprint instead. */ diff --git a/package.json b/package.json index 9968eed5c353fd720a113d8db45cfccba0c50d67..6a037af77368c9b70909565d81990c10354ce686 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@vereign/mime-parser": "git+ssh://git@code.vereign.com:code/js-toolbox/mime-parser.git", "@vereign/png": "git+ssh://git@code.vereign.com:code/js-toolbox/png.git", "axios": "^0.20.0", + "easyqrcodejs": "^4.3.1", "eventemitter2": "^6.4.3", "google-protobuf": "^3.13.0", "js-md5": "^0.7.3", diff --git a/src/utils/qrCodeTemplateUtils.ts b/src/utils/qrCodeTemplateUtils.ts index c2058afc743df5858e81a39bb0d065cbf307818a..5d0c12882ac1a155bf2e029e81dd165cf86bc643 100644 --- a/src/utils/qrCodeTemplateUtils.ts +++ b/src/utils/qrCodeTemplateUtils.ts @@ -1,3 +1,10 @@ +import QRCode from "easyqrcodejs"; + +const DEFAULT_TEMPLATE = + "data:image/png;base64,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"; +const DEFAULT_LOGO = + "data:image/png;base64,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"; + interface ChromakeyBoundaries { fromL: number; fromT: number; @@ -108,6 +115,98 @@ const findChromakeyBoundaries = ( return { fromL: -1, fromT: -1, toL: -1, toT: -1 }; }; +interface TemplateOptions { + src: string; + placeholderSize: number; +} + +/** + * https://www.qrcode.com/en/about/error_correction.html#:~:text=QR%20Code%20has%20error%20correction,of%20data%20QR%20Code%20size. + */ +type CorrectionLevels = "L" | "M" | "Q" | "H"; + +interface QrCodeOptions { + width?: number; + height?: number; + logoSrc?: string; + logoWidth?: number; + logoHeight?: number; + correctionLevel?: CorrectionLevels; +} + +const generateQrCode = async ( + text: string, + qrCodeOptions?: QrCodeOptions, + templateOptions?: TemplateOptions +): Promise<string> => { + if (typeof document === "undefined") { + throw new Error( + "QR Code generation is not supported in non-browser environments" + ); + } + + const defaultOptions: QrCodeOptions = { + width: 256, + height: 256, + logoSrc: DEFAULT_LOGO, + logoWidth: 75, + logoHeight: 66, + // Use "L" level as we don't need a redundancy + correctionLevel: "L", + }; + + qrCodeOptions = qrCodeOptions + ? Object.assign(defaultOptions, qrCodeOptions) + : defaultOptions; + + const defaultTemplateOptions: TemplateOptions = { + placeholderSize: 260, + src: DEFAULT_TEMPLATE, + }; + + templateOptions = templateOptions + ? Object.assign(defaultTemplateOptions, templateOptions) + : defaultTemplateOptions; + + const container = document.createElement("div"); + + const options = { + text, + width: qrCodeOptions.width, + height: qrCodeOptions.height, + colorDark: "#000000", + colorLight: "#ffffff", + dotScale: 1, + + PO: "#d51d32", + PI: "#d51d32", + + correctLevel: QRCode.CorrectLevel[qrCodeOptions.correctionLevel], // L, M, Q, H + }; + + if (qrCodeOptions.logoSrc) { + Object.assign(options, { + logo: qrCodeOptions.logoSrc, + logoBackgroundTransparent: true, + logoWidth: qrCodeOptions.logoWidth, + logoHeight: qrCodeOptions.logoHeight, + }); + } + + new QRCode(container, options); + const canvas = container.getElementsByTagName("canvas")[0]; + + // Add short async action because of the bug with logo not appearing in the resulting image. + await new Promise((resolve) => setTimeout(resolve, 10)); + + return await putQrCodeOnChromakeyTemplate( + canvas.toDataURL(), + templateOptions.src, + templateOptions.placeholderSize, + templateOptions.placeholderSize + ); +}; + const putQrCodeOnChromakeyTemplate = async ( qrCodeImageBase64: string, templateImageBase64: string, @@ -203,4 +302,5 @@ const loadImage = (imageSrc: string): Promise<HTMLImageElement> => { export default { putQrCodeOnChromakeyTemplate, + generateQrCode, }; diff --git a/tsconfig.json b/tsconfig.json index e880418b6314b5810989ea19b7e21fbe4241ce79..c8ea31ebbc2ed30d3d86c994d0ff45136164a80d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "target": "es2015", "declaration": true, "outDir": "./dist", - "allowJs": true + "allowJs": true, + "esModuleInterop": true }, "include": ["src/**/*"] } diff --git a/yarn.lock b/yarn.lock index 0d7cbb9f0b7794f27471da3e1e4ef52abb80ddbd..6b579f8ee76c32a2a405722911f536059de9510c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -866,10 +866,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@eslint/eslintrc@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" - integrity sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ== +"@eslint/eslintrc@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" + integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -878,7 +878,7 @@ ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" - lodash "^4.17.19" + lodash "^4.17.20" minimatch "^3.0.4" strip-json-comments "^3.1.1" @@ -1123,9 +1123,9 @@ integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@sinonjs/commons@^1.7.0": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" - integrity sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw== + version "1.8.2" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.2.tgz#858f5c4b48d80778fde4b9d541f27edc0d56488b" + integrity sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw== dependencies: type-detect "4.0.8" @@ -1201,9 +1201,9 @@ "@types/istanbul-lib-report" "*" "@types/jsdom@^16.2.4": - version "16.2.5" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.5.tgz#74ebad438741d249ecb416c5486dcde4217eb66c" - integrity sha512-k/ZaTXtReAjwWu0clU0KLS53dyqZnA8mm+jwKFeFrvufXgICp+VNbskETFxKKAguv0pkaEKTax5MaRmvalM+TA== + version "16.2.6" + resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.6.tgz#9ddf0521e49be5365797e690c3ba63148e562c29" + integrity sha512-yQA+HxknGtW9AkRTNyiSH3OKW5V+WzO8OPTdne99XwJkYC+KYxfNIcoJjeiSqP3V00PUUpFP6Myoo9wdIu78DQ== dependencies: "@types/node" "*" "@types/parse5" "*" @@ -1220,14 +1220,14 @@ integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== "@types/node@*": - version "14.14.20" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340" - integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A== + version "14.14.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.21.tgz#d934aacc22424fe9622ebf6857370c052eae464e" + integrity sha512-cHYfKsnwllYhjOzuC5q1VpguABBeecUp24yFluHpn/BQaVxB1CuQ1FSRZCzrPxrkIfWISXV2LbeoBthLWg0+0A== "@types/node@^13.7.0": - version "13.13.39" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.39.tgz#237d071fb593d3aaa96f655a8eb2f91e0fb1480c" - integrity sha512-wct+WgRTTkBm2R3vbrFOqyZM5w0g+D8KnhstG9463CJBVC3UVZHMToge7iMBR1vDl/I+NWFHUeK9X+JcF0rWKw== + version "13.13.40" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.40.tgz#f655ef327362cc83912f2e69336ddc62a24a9f88" + integrity sha512-eKaRo87lu1yAXrzEJl0zcJxfUMDT5/mZalFyOkT44rnQps41eS2pfWzbaulSPpQLFNy29bFqn+Y5lOTL8ATlEQ== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1240,9 +1240,9 @@ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/parse5@*": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + version "6.0.0" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.0.tgz#38590dc2c3cf5717154064e3ee9b6947ee21b299" + integrity sha512-oPwPSj4a1wu9rsXTEGIJz91ISU725t0BmSnUhb57sI+M8XEmvUop84lzuiYdq0Y5M6xLY8DBPg0C2xEQKLyvBA== "@types/prettier@^2.0.0": version "2.1.6" @@ -1668,7 +1668,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.14.5, browserslist@^4.16.0: +browserslist@^4.14.5, browserslist@^4.16.1: version "4.16.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766" integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA== @@ -1712,12 +1712,12 @@ cache-base@^1.0.1: unset-value "^1.0.0" call-bind@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" - integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" - get-intrinsic "^1.0.0" + get-intrinsic "^1.0.2" callsites@^3.0.0: version "3.1.0" @@ -1735,9 +1735,9 @@ camelcase@^6.0.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001173: - version "1.0.30001173" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001173.tgz#3c47bbe3cd6d7a9eda7f50ac016d158005569f56" - integrity sha512-R3aqmjrICdGCTAnSXtNyvWYMK3YtV5jwudbq0T7nN9k4kmE4CBuwPqyJ+KBzepSTh0huivV2gLbSMEzTTmfeYw== + version "1.0.30001178" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001178.tgz#3ad813b2b2c7d585b0be0a2440e1e233c6eabdbc" + integrity sha512-VtdZLC0vsXykKni8Uztx45xynytOi71Ufx9T8kHptSw9AL4dpqailUJJHavttuzUe1KYuBYtChiWv+BAb7mPmQ== capture-exit@^2.0.0: version "2.0.0" @@ -1914,11 +1914,11 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.8.0: - version "3.8.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.2.tgz#3717f51f6c3d2ebba8cbf27619b57160029d1d4c" - integrity sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ== + version "3.8.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.3.tgz#9123fb6b9cad30f0651332dc77deba48ef9b0b3f" + integrity sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog== dependencies: - browserslist "^4.16.0" + browserslist "^4.16.1" semver "7.0.0" core-util-is@1.0.2: @@ -2097,6 +2097,11 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +easyqrcodejs@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/easyqrcodejs/-/easyqrcodejs-4.3.1.tgz#52eb768824dfbbad09131a515287474a2c3f1aa1" + integrity sha512-/1QbzGZr60zjGmOyry5ZxXyNMFxVpjEHyU1nirKqy/YhfiztODb9nP+ev7EO70xjm/KoviE8rVTbHY96QryUMA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -2106,9 +2111,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.3.634: - version "1.3.634" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.634.tgz#82ea400f520f739c4f6ff00c1f7524827a917d25" - integrity sha512-QPrWNYeE/A0xRvl/QP3E0nkaEvYUvH3gM04ZWYtIa6QlSpEetRlRI1xvQ7hiMIySHHEV+mwDSX8Kj4YZY6ZQAw== + version "1.3.641" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.641.tgz#03f14efd70a7971eff2efc947b3c1d0f717c82b9" + integrity sha512-b0DLhsHSHESC1I+Nx6n4w4Lr61chMd3m/av1rZQhS2IXTzaS5BMM5N+ldWdMIlni9CITMRM09m8He4+YV/92TA== emittery@^0.7.1: version "0.7.2" @@ -2199,12 +2204,12 @@ eslint-visitor-keys@^2.0.0: integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== eslint@^7.7.0: - version "7.17.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.17.0.tgz#4ccda5bf12572ad3bf760e6f195886f50569adb0" - integrity sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ== + version "7.18.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.18.0.tgz#7fdcd2f3715a41fe6295a16234bd69aed2c75e67" + integrity sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ== dependencies: "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.2.2" + "@eslint/eslintrc" "^0.3.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2228,7 +2233,7 @@ eslint@^7.7.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.19" + lodash "^4.17.20" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -2457,12 +2462,20 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-versions@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" - integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: - semver-regex "^2.0.0" + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-versions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" + integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== + dependencies: + semver-regex "^3.1.2" flat-cache@^3.0.4: version "3.0.4" @@ -2543,7 +2556,7 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.0: +get-intrinsic@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== @@ -2732,17 +2745,17 @@ human-signals@^1.1.1: integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== husky@^4.2.5: - version "4.3.6" - resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.6.tgz#ebd9dd8b9324aa851f1587318db4cccb7665a13c" - integrity sha512-o6UjVI8xtlWRL5395iWq9LKDyp/9TE7XMOTvIpEVzW638UcGxTmV5cfel6fsk/jbZSTlvfGVJf2svFtybcIZag== + version "4.3.8" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" + integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== dependencies: chalk "^4.0.0" ci-info "^2.0.0" compare-versions "^3.6.0" cosmiconfig "^7.0.0" - find-versions "^3.2.0" + find-versions "^4.0.0" opencollective-postinstall "^2.0.2" - pkg-dir "^4.2.0" + pkg-dir "^5.0.0" please-upgrade-node "^3.2.0" slash "^3.0.0" which-pm-runs "^1.0.0" @@ -3660,6 +3673,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -3870,9 +3890,9 @@ node-notifier@^8.0.0: which "^2.0.2" node-releases@^1.1.69: - version "1.1.69" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6" - integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA== + version "1.1.70" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" + integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== normalize-package-data@^2.5.0: version "2.5.0" @@ -4018,6 +4038,13 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -4025,6 +4052,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" @@ -4045,9 +4079,9 @@ parent-module@^1.0.0: callsites "^3.0.0" parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" @@ -4126,6 +4160,13 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -4307,9 +4348,9 @@ regjsgen@^0.5.1: integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + version "0.6.6" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.6.tgz#6d8c939d1a654f78859b08ddcc4aa777f3fa800a" + integrity sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ== dependencies: jsesc "~0.5.0" @@ -4501,10 +4542,10 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" - integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== +semver-regex@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" + integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0: version "5.7.1" @@ -4951,9 +4992,9 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tsutils@^3.17.1: - version "3.18.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.18.0.tgz#38add50a28ec97e988cb43c5b32e55d1ff4a222a" - integrity sha512-D9Tu8nE3E7D1Bsf/V29oMHceMf+gnVO+pDguk/A5YRo1cLpkiQ48ZnbbS57pvvHeY+OIeNQx1vf4ASPlEtRpcA== + version "3.19.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.19.1.tgz#d8566e0c51c82f32f9c25a4d367cd62409a547a9" + integrity sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw== dependencies: tslib "^1.8.1" @@ -5057,9 +5098,9 @@ unset-value@^1.0.0: isobject "^3.0.0" uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -5282,6 +5323,11 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zlibjs@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/zlibjs/-/zlibjs-0.3.1.tgz#50197edb28a1c42ca659cc8b4e6a9ddd6d444554"