diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..3ebc903 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,18 @@ +name: Test +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 12 + cache: 'yarn' + - run: yarn install --production=false + - run: yarn test \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5ea0d00..b0eb8cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: - name: node setup uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 12 cache: 'yarn' - name: install dependencies @@ -39,7 +39,7 @@ jobs: - name: node setup uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 12 registry-url: https://registry.npmjs.org cache: 'yarn' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 94e08af..0000000 --- a/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: node_js -node_js: - - "node" -cache: - directories: - - "node_modules" -script: - - npm test -after_success: - - npm run coverage - - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT diff --git a/README.md b/README.md index 2f4cfe4..cfa9b92 100644 --- a/README.md +++ b/README.md @@ -6,25 +6,17 @@ **_NcryptJs_** is a light weight javascript data encryption and decryption library. This library implements the nodejs default crypto functionality as a mid-channel cipher in addition to a simple and elegant custom data encoding and encryption algorithm. - - ## Contents * [NcryptJs](#NcryptJs) * [Contents](#contents) - * [Getting Started](#getting-started) * [Installation](#installation) * [Documentation](#documentation) - * [NcryptJs Functions](#ncryptjs-functions) - * [Using `encrypt()` and `decrypt()`](#using-encrypt-and-decrypt) - * [Using default imports](#Using-default-imports) - + * [NcryptJs Methods](#ncryptjs-methods) + * [Using the `randomString()` methods](#using-randomstring-method) + * [Using `encrypt()` and `decrypt()` methods](#using-encrypt-and-decrypt-methods) + * [Using default imports](#using-default-imports) * [Built With](#built-with) * [Contribution](#contribution) * [Version Management](#version-management) @@ -82,23 +74,38 @@ However, if you are using ECMAScript 5 and older, use the require statement: **_NcryptJs_** is a simple library with only two two exposed functions. This is all intentional mainly to keep everything simple. This is a complete documentation of the library and how to use it in your project. All examples work on both ECMAScript 6 (and later) and ECMAScript 5 (and older). -### NcryptJs Functions +### NcryptJs Methods -### List of **_NcryptJs_** functions. +### List of **_NcryptJs_** Methods. -| Functions | Description | Parameters | Return | +| Methods | Description | Parameters | Return | | ------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| [_static_] **randomString()** | Random String. |**size**: _number_ - An optional size of the generated `randomBytes`.
**enc:** _base64/hex_ - Encoding used for encoding the `randomBytes` defaults to _`base64`_ |**encoded**: _string_ - encoded string. | | **encrypt()** | Encrypts data. |**data**: _object/string/number/boolean_ - The data to be encrypted.
|**ciphered**: _string_ - encrypted data. | | **decrypt()** | Decrypts the encrypted or ciphered data | **encodedData**: string - The encrypted data: _string_ to be decrypted. | **data**: _string/object/number/boolean_ - The decrypted or original data (it might be string or object, depends on the initial input data type). +### Using randomString method + +The `randomString()` static method can generate [random bytes](https://nodejs.org/api/crypto.html#cryptorandombytessize-callback) encoded into a `hexadecimal` or `base64` strings. This string can be useful in a variety of use cases e.g to generate database ids, to generate a unique string for a list, a unique serial strings etc. + +```ts +var ncrypt = require('ncrypt-js'); + +var randomStr = ncrypt.randomString(8, 'base64'); +console.log(randomStr) // t78WcmYAFOY= -#### Using `encrypt()` and `decrypt()` functons - As of version 2.0.0 directly importing or invoking these functions is deprecated, an object must be created with a secret first, before the methods can now be invoked on the created object. +// signature +ncrypt.randomString(size?: number, enc?: 'base64' | 'hex'); +``` -To encrypt and decrypt data, simply use `encrypt()` and `decrypt()` functions respectively. This will use `AES-256-CBC` encryption algorithm as the mid-channel cipher. +### Using encrypt() and decrypt() methods +The `encrypt()` and `decrypt()` methods as of version 2.0.0 directly importing or invoking these methods is deprecated, an object must be created with a secret first, before the methods can now be invoked on the created object. + +To `encrypt` and `decrypt` data, simply use `encrypt()` and `decrypt()` methods respectively. This will use `AES-256-CBC` encryption algorithm as the mid-channel cipher. ```diff - var { encrypt, decrypt } = require("ncrypt-js"); @@ -108,7 +115,7 @@ To encrypt and decrypt data, simply use `encrypt()` and `decrypt()` functions re var data = "Hello World!"; var _secretKey = "some-super-secret-key"; -+ var { encodeData, decodeData } = new ncrypt(_secretKey); ++ var { encrypt, decrypt } = new ncrypt(_secretKey); // encrypting super sensitive data here - var encryptedData = encrypt(data, _secretKey); @@ -180,11 +187,16 @@ console.log("...done."); ```` If you are using any sort of environmental key-value store, e.g `.env` and for additional security, you can add the following to your environment. -```diff -// .env +```bash +# .env + +# used internally to set the `key` +KEY='sshhhh this is a super secret key' + +# used internally to set the `encoding` - ['base64' | 'binary' | 'hex' | 'ucs-2' | 'ucs2' | 'utf16le'] +NCRPT_ENC='hex' -KEY=sshhhh this is a super secret key -SECRET=this is our hashing secret +SECRET='this is our hashing secret' ``` Then when creating your object, you can use the SECRET from your environment e.g: ``` diff --git a/package.json b/package.json index c1974b1..52a006d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ncrypt-js", - "version": "2.0.1", + "version": "2.1.0", "description": "a light weight javascript data encryption and decryption library", "main": "dist/index.js", "scripts": { @@ -28,7 +28,7 @@ "decryption", "javascript-library" ], - "author": "meeky", + "author": "ajimae", "license": "MIT", "bugs": { "url": "https://github.com/ajimae/ncrypt-js/issues" @@ -46,7 +46,7 @@ "mocha-lcov-reporter": "^1.3.0", "nyc": "^14.1.1", "ts-node": "^8.6.2", - "typescript": "^3.8.3" + "typescript": "3.8.3" }, "files": [ "dist", diff --git a/src/ncrypt.d.ts b/src/ncrypt.d.ts deleted file mode 100644 index 7829c04..0000000 --- a/src/ncrypt.d.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export interface INcrypt { - convertTextToDecimal(text: string): number[]; - applySecretToCharacters(charCodes: number[] | number): number; - convertByteToHexadecimal(number: number): string; - encrypt(text: object | string | number | boolean): string; - decrypt(data: string): string; -} diff --git a/src/ncrypt.ts b/src/ncrypt.ts index c67714e..f45146d 100644 --- a/src/ncrypt.ts +++ b/src/ncrypt.ts @@ -1,64 +1,147 @@ -import { INcrypt } from './ncrypt.d'; -import { encode, decode } from './utils'; +import * as crypto from 'crypto'; -export default class Ncrypt implements INcrypt { +type TNCRYPT_ENC = 'base64' | 'binary' | 'hex' | 'ucs-2' | 'ucs2' | 'utf16le'; +/** + * @class Ncrypt + * @type {Ncrypt.} + */ +export default class Ncrypt { /** - * ncrypt namespace. - * @type {string.<*>} + * encryption secret. + * @type {secret.} secret */ private secret: string; /** - * ncrypt namespace. - * @type {string.<*>} + * algorithm used for encoding message */ - private text: string; + private readonly algorithm = 'aes-256-cbc'; + + /** + * ecoding for encrypted stirng + */ + private readonly enc = (process.env.NCRYPT_ENC) as TNCRYPT_ENC || 'hex'; + + /** + * crypto random initial vector generated from core node {crypto} module + */ + private readonly initialVector: Buffer = crypto.randomBytes(16); + + /** + * crypto random key generated from core node {crypto} module + * {note}: please read the value for KEY from your app's environment + */ + private readonly key: Buffer = crypto.scryptSync( + process.env.KEY || 'please provide a KEY in your .env file or config', + 'salt', + 32 + ); + /** * object constructor - * @param text - * @param secret + * @param {secret.} secret */ constructor(secret: string) { this.secret = secret; + + // bind public instnace methods + this.encrypt = this.encrypt.bind(this); + this.decrypt = this.decrypt.bind(this); } /** * convert all entered text to decimal equivalent character codes - * @param {data.} data to be converted + * @param {text.} text to be converted * @return {Array.} array of character codes */ - convertTextToDecimal = (data: string) => data.split('').map((value) => value.charCodeAt(0)); + private convertTextToDecimal = (text: string): number[] => { + return text.split('').map((value) => value.charCodeAt(0)); + } /** * encode provided secret on decimal character codes - * @param {charCode} character codes + * @param {charCode.} charCodes + * @returns {*.} decimal string */ - applySecretToCharacters = (charCodes: number[] | number | string) => this.convertTextToDecimal(this.secret) - .reduce((firstValue: any, secondValue: any) => (firstValue ^ secondValue), charCodes) + private applySecretToCharacters = (charCodes: number | number[]): number => { + return this.convertTextToDecimal(this.secret) + .reduce((firstValue: number, secondValue: number) => (firstValue ^ secondValue), charCodes as number) + } /** * convert character bytes to hexadecimal equivalent - * @param {number.} - * @returns {string} hexadecimal string + * @param {number.} number + * @returns {*.} hexadecimal string */ - convertByteToHexadecimal = (number: number) => { - return ("0" + Number(number).toString(16)).substr(-2); + private convertByteToHexadecimal = (number: number): string => { + return ('0' + Number(number).toString(16)).substr(-2); } /** - * process data to be encrypted - * @param {} - * @returns {string.} encoded string data + * intermediate data encoder function + * @param {string.} text + * @param secret + * @returns {string} encrypted or cipher text */ - encrypt = (data: object | string | number | boolean) => { + private encode = (text: string): string => { + let cipher = crypto.createCipheriv(this.algorithm, Buffer.from(this.key), this.initialVector); + let encrypted = cipher.update(text); + + encrypted = Buffer.concat([encrypted, cipher.final()]); + return `${this.initialVector.toString(this.enc)}.${encrypted.toString(this.enc)}`; + } + + /** + * intermediate data decoder function + * @param {string.} text + * @returns {string.} decrypted data + */ + private decode = (text: string): string => { + if (typeof text !== 'string') { + throw new TypeError('argument must be a string, or a string-like object'); + } + + const iv = text.split('.')[0]; + const encryptedData = text.split('.')[1]; + + let _iv = Buffer.from(iv, this.enc); + let encryptedText = Buffer.from(encryptedData, this.enc); + let decipher = crypto.createDecipheriv(this.algorithm, Buffer.from(this.key), _iv); + let decrypted = decipher.update(encryptedText); + + decrypted = Buffer.concat([decrypted, decipher.final()]); + return decrypted.toString(); + } + + /** + * generate random strings + * @example + * + * var fs = require('fs'); + * var ncrypt = require('ncrypt-js'); + * + * console.log(ncrypt.randomString(8, 'base64')); // g3lzZ48TW6w== + * + * @param {size.} size + * @param {enc.} enc + * @returns {*.} string + */ + public static randomString(size?: number, enc: 'hex' | 'base64' = 'base64'): string { + return crypto.randomBytes(size || 64).toString(enc); + } + + /** + * data to be encrypted + * @param {data.} data + * @returns {*.} encrypted text + */ + public encrypt(data: string | number | boolean | object): string { /** * this does the actual processing return a string - * resulting from charCode conversion, salting and + * resulting from charCode conversion, salting and * hexadecimal mapping - * */ - // if (data == void 0) throw new Error('invalid data was entered, enter data of type object, number, string or boolean to be encrypted.'); try { const encodedMessage = JSON.stringify(data).split('') .map(this.convertTextToDecimal) @@ -66,29 +149,26 @@ export default class Ncrypt implements INcrypt { .map(this.convertByteToHexadecimal) .join(''); - return encode(encodedMessage); - } catch (error) { - throw new Error('invalid data was entered, enter data of type object, number, string or boolean to be encrypted.'); + return this.encode(encodedMessage); + } catch (e) { + throw new Error('invalid data was entered, enter data of type object, number, string or boolean to be encrypted.' + e); } } /** - * decodes encoded string resulting from util encryption - * @param {string.} encodeData - * @returns {decodedData.} decoded data + * text be decrypted + * @param {text.} text + * @returns {*.} decrypted data */ - decrypt = (text: string) => { - const encodeData = decode(text); - - const data = encodeData.match(/.{1,2}/g) - .map((hex: any) => parseInt(hex, 16)) - .map(this.applySecretToCharacters) - .map((charCode: any) => String.fromCharCode(charCode)) - .join(''); + public decrypt(text: string): string | number | boolean | object { + const encodeData = this.decode(text); - const arr = []; - arr.push(data); + const data = (encodeData).match(/.{1,2}/g) + .map((hex: string) => parseInt(hex, 16)) + .map(this.applySecretToCharacters) + .map((charCode: number | number[]) => String.fromCharCode(charCode as number)) + .join(''); - return JSON.parse(data); + return JSON.parse(data); } } diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 4e3fce1..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,53 +0,0 @@ -import crypto from 'crypto'; // this is necessary for some version of nodejs without crypto module - -const algorithm = 'aes-256-cbc'; - -/** - * crypto random initial vector generated from core node {crypto} module - */ -const initialVector: Buffer = crypto.randomBytes(16); - -/** - * crypto random key generated from core node {crypto} module - * - * {note}: please read the value for KEY from your app's environment - */ -const _key = process.env.KEY || 'please provide a KEY in your .env file or config'; -const key: Buffer = crypto.scryptSync(_key, 'salt', 32); - -/** - * intermediate data encoder function - * @param {string.} text - * @param secret - * @returns {string} encrypted or cipher text - */ -export const encode = (text: string) => { - let cipher = crypto.createCipheriv(algorithm, Buffer.from(key), initialVector); - let encrypted = cipher.update(text); - - encrypted = Buffer.concat([encrypted, cipher.final()]); - return `${initialVector.toString('hex')}.${encrypted.toString('hex')}`; -} - -/** - * intermediate data decoder function - * @param {string.} text - * @returns {string.} decrypted data - */ -export const decode = (text: string) => { - - if (typeof text !== 'string') { - throw new TypeError('argument must be a string, or a string-like object'); - } - - const iv = text.split('.')[0]; - const encryptedData = text.split('.')[1]; - - let _iv = Buffer.from(iv, 'hex'); - let encryptedText = Buffer.from(encryptedData, 'hex'); - let decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), _iv); - let decrypted = decipher.update(encryptedText); - - decrypted = Buffer.concat([decrypted, decipher.final()]); - return decrypted.toString(); -} diff --git a/test/ncrypt.test.ts b/test/ncrypt.test.ts index 7d95242..c298fe8 100644 --- a/test/ncrypt.test.ts +++ b/test/ncrypt.test.ts @@ -1,33 +1,57 @@ -import * as chai from "chai"; +import * as chai from 'chai'; import ncrypt from '../index'; - const expect = chai.expect; +// initialize const object = { NcryptJs: "is great.", You: "should try it!" }; -const string: string = "ncrypt-js is great."; + const number: number = 19960404; +const string: string = "ncrypt-js is great."; const boolean: boolean = false; -const _nullData: any = null; +const _null = null as any; const _secret = 'shhh its a secret'; - const { encrypt, decrypt } = new ncrypt(_secret); const encryptString = encrypt(string); const encryptNumber = encrypt(number); const encryptObject = encrypt(object); const encryptBoolean = encrypt(boolean); -const encryptNullData = encrypt(_nullData); +const encryptNullData = encrypt(_null); const decryptString = decrypt(encryptString); const decryptNumber = decrypt(encryptNumber); const decryptObject = decrypt(encryptObject); const decryptBoolean = decrypt(encryptBoolean); -const decryptNullData = encrypt(_nullData); +const decryptNullData = encrypt(_null); + +describe('RandomString', () => { + it('should generate a random string', () => { + const size = 32, secret = ncrypt.randomString(size, 'hex'); + + expect(secret.length).equal((size * 2)); + expect(typeof ncrypt.randomString(size, 'hex')).equal('string'); + }); + + it('should should generate a hex string', () => { + const str = ncrypt.randomString(32, 'hex'); + expect(Buffer.from(str, 'hex').toString('hex') === str).equal(true); + }); + + it('should should generate a base64 string', () => { + const str = ncrypt.randomString(32, 'base64'); + expect(Buffer.from(str, 'base64').toString('base64') === str).equal(true); + }); + + it('should generate string using default size and encoding', () => { + const str = ncrypt.randomString(); + expect(Buffer.from(str, 'base64').toString('base64') === str).equal(true); + }); +}); describe('Encryption', () => { it('should be able to encrypt a string', () => { @@ -78,7 +102,7 @@ describe('Error handling and validations', () => { try { encrypt('nullSecret'); } catch (error) { - expect(error.message).equal('must be initialized with a secret key of type string'); + expect(error.message).matches(/must be initialized with a secret key of type string/); } }); @@ -88,16 +112,16 @@ describe('Error handling and validations', () => { //@ts-ignore decrypt(nonStringData); } catch (error) { - expect(error.message).equal('argument must be a string, or a string-like object'); + expect(error.message).matches(/argument must be a string, or a string-like object/); } }); it('should error when a non string data type is to be decrypted', () => { try { - const nonStringData: any = void(0); + const nonStringData: any = void (0); decrypt(nonStringData); } catch (error) { - expect(error.message).equal('argument must be a string, or a string-like object'); + expect(error.message).matches(/argument must be a string, or a string-like object/); } }); @@ -105,23 +129,23 @@ describe('Error handling and validations', () => { try { decrypt(decryptNullData); } catch (error) { - expect(error.message).equal('argument must be a string, or a string-like object'); + expect(error.message).match(/argument must be a string, or a string-like object/); } }); it('should throw an error when an undefined data is to be encrypted', () => { try { - encrypt(undefined); + encrypt(undefined as any); } catch (error) { - expect(error.message).equal('invalid data was entered, enter data of type object, number, string or boolean to be encrypted.'); + expect(error.message).match(/invalid data was entered, enter data of type object, number, string or boolean to be encrypted./); } }); it('should throw an error when an undefined data is to be encrypted', () => { try { - encrypt(null); + encrypt(null as any); } catch (error) { - expect(error.message).equal('no data was entered, enter data of type object, number, string or boolean to be encrypted.'); + expect(error.message).match(/no data was entered, enter data of type object, number, string or boolean to be encrypted./); } }); @@ -129,7 +153,8 @@ describe('Error handling and validations', () => { try { encrypt(encryptNullData); } catch (error) { - expect(error.message).equal('invalid data was entered, enter data of type object, number, string or boolean to be encrypted.'); + expect(error.message).match(/invalid data was entered, enter data of type object, number, string or boolean to be encrypted./); } }); }); + diff --git a/tsconfig.json b/tsconfig.json index a9307c8..ac16686 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "esModuleInterop": true, "noImplicitAny": true, "moduleResolution": "node", + "declaration": true, "sourceMap": false, "outDir": "dist", "baseUrl": ".", diff --git a/yarn.lock b/yarn.lock index b337adc..5b6b59f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -619,54 +619,7 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.22.1, es-abstract@^1.22.3: - version "1.22.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.5.tgz#1417df4e97cc55f09bf7e58d1e614bc61cb8df46" - integrity sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w== - dependencies: - array-buffer-byte-length "^1.0.1" - arraybuffer.prototype.slice "^1.0.3" - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - es-define-property "^1.0.0" - es-errors "^1.3.0" - es-set-tostringtag "^2.0.3" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.4" - get-symbol-description "^1.0.2" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - has-proto "^1.0.3" - has-symbols "^1.0.3" - hasown "^2.0.1" - internal-slot "^1.0.7" - is-array-buffer "^3.0.4" - is-callable "^1.2.7" - is-negative-zero "^2.0.3" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.3" - is-string "^1.0.7" - is-typed-array "^1.1.13" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.5" - regexp.prototype.flags "^1.5.2" - safe-array-concat "^1.1.0" - safe-regex-test "^1.0.3" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.2" - typed-array-byte-length "^1.0.1" - typed-array-byte-offset "^1.0.2" - typed-array-length "^1.0.5" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.14" - -es-abstract@^1.23.0, es-abstract@^1.23.2: +es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: version "1.23.2" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.2.tgz#693312f3940f967b8dd3eebacb590b01712622e0" integrity sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w== @@ -1970,7 +1923,7 @@ rimraf@^2.6.2, rimraf@^2.6.3: dependencies: glob "^7.1.3" -safe-array-concat@^1.1.0, safe-array-concat@^1.1.2: +safe-array-concat@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== @@ -2158,7 +2111,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string.prototype.trim@^1.2.8, string.prototype.trim@^1.2.9: +string.prototype.trim@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== @@ -2168,7 +2121,7 @@ string.prototype.trim@^1.2.8, string.prototype.trim@^1.2.9: es-abstract "^1.23.0" es-object-atoms "^1.0.0" -string.prototype.trimend@^1.0.7, string.prototype.trimend@^1.0.8: +string.prototype.trimend@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== @@ -2178,13 +2131,13 @@ string.prototype.trimend@^1.0.7, string.prototype.trimend@^1.0.8: es-object-atoms "^1.0.0" string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" strip-ansi@^4.0.0: version "4.0.0" @@ -2334,9 +2287,9 @@ typed-array-byte-offset@^1.0.2: is-typed-array "^1.1.13" typed-array-length@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.5.tgz#57d44da160296d8663fd63180a1802ebf25905d5" - integrity sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA== + version "1.0.6" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== dependencies: call-bind "^1.0.7" for-each "^0.3.3" @@ -2345,10 +2298,10 @@ typed-array-length@^1.0.5: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typescript@^3.8.3: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== +typescript@3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== uglify-js@^3.1.4: version "3.17.4"