diff --git a/.github/workflows/main_ci.yml b/.github/workflows/main_ci.yml new file mode 100644 index 0000000..ef25fd8 --- /dev/null +++ b/.github/workflows/main_ci.yml @@ -0,0 +1,80 @@ +name: Run Tests + +on: + push: + branches: + - master + pull_request: + +permissions: + contents: read + +jobs: + ################## + # Jobs with matrix + ################## + unit: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: [14, 'lts/*'] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # v3 + with: + node-version: ${{ matrix.node-version }} + registry-url: https://registry.npmjs.org/ + cache: 'npm' + - run: npm ci + - run: npm run unit + + ##################### + # Jobs without matrix + ##################### + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2 + - uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # v3 + with: + node-version: 'lts/*' + registry-url: https://registry.npmjs.org/ + cache: 'npm' + - run: npm ci + - run: npm run coverage + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2 + - uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # v3 + with: + node-version: 'lts/*' + registry-url: https://registry.npmjs.org/ + cache: 'npm' + - run: npm ci + - run: npm run format:ci + gitdiff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2 + - uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # v3 + with: + node-version: 'lts/*' + registry-url: https://registry.npmjs.org/ + cache: 'npm' + - run: npm ci + - run: npm run gitdiff:ci + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2 + - uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # v3 + with: + node-version: 'lts/*' + registry-url: https://registry.npmjs.org/ + cache: 'npm' + - run: npm ci + - run: npm run lint diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 10a45ee..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -sudo: false -language: node_js -before_install: - - npm install npm -g -node_js: - - "lts/*" - - "9" - - "10" -matrix: - include: - - node_js: "lts/*" - env: TEST_SUITE=gitdiff:ci -env: - - TEST_SUITE=test -script: npm run-script $TEST_SUITE diff --git a/package-lock.json b/package-lock.json index 010e328..a7d7c2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,14 @@ "dev": true, "requires": { "path-parse": "^1.0.6" + }, + "dependencies": { + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + } } }, "semver": { @@ -179,44 +187,22 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==" + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, - "@types/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-tvo2dQ4TRKi0GYsblpWnhpJKR7Dvyyu+JdWhu4K5J8MKKONQfD9imAI/RIZn9brZXJ7n5DHxjwMpB4XOIVvGaw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/node": { "version": "11.11.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" }, - "@types/pbkdf2": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.0.0.tgz", - "integrity": "sha512-6J6MHaAlBJC/eVMy9jOwj9oHaprfutukfW/Dyt0NEnpQ/6HN6YQrpvLwzWdWDeWZIdenjGHlbYDzyEODO5Z+2Q==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/randombytes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/randombytes/-/randombytes-2.0.0.tgz", - "integrity": "sha512-bz8PhAVlwN72vqefzxa14DKNT8jK/mV66CSjwdVQM/k3Th3EPKfUtdMniwZgMedQTFuywAsfjnZsg+pEnltaMA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", @@ -267,9 +253,9 @@ } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "brace-expansion": { @@ -317,15 +303,6 @@ "supports-color": "^5.3.0" } }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -373,7 +350,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "convert-source-map": { @@ -385,31 +362,6 @@ "safe-buffer": "~5.1.1" } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "cross-spawn": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", @@ -421,12 +373,6 @@ "which": "^2.0.1" } }, - "data-uri-to-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", - "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", - "dev": true - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -555,16 +501,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "fetch-blob": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.4.tgz", - "integrity": "sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==", - "dev": true, - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } - }, "fill-keys": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", @@ -615,15 +551,6 @@ "signal-exit": "^3.0.2" } }, - "formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, - "requires": { - "fetch-blob": "^3.1.2" - } - }, "fromentries": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz", @@ -701,15 +628,6 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "hasha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz", @@ -759,7 +677,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "is-arguments": { "version": "1.0.4", @@ -952,13 +871,10 @@ "dev": true }, "json5": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", - "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true }, "locate-path": { "version": "5.0.0", @@ -970,9 +886,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.flattendeep": { @@ -990,16 +906,6 @@ "semver": "^6.0.0" } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1007,9 +913,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -1042,21 +948,13 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "dev": true - }, "node-fetch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.1.1.tgz", - "integrity": "sha512-SMk+vKgU77PYotRdWzqZGTZeuFKlsJ0hu4KPviQKkfY+N3vn2MIzr0rvpnYpR8MtB3IEuhlEcuOLbGvLRlA+yg==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dev": true, "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.3", - "formdata-polyfill": "^4.0.10" + "whatwg-url": "^5.0.0" } }, "node-preload": { @@ -1206,24 +1104,6 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -1259,14 +1139,6 @@ "resolve": "~1.1.7" } }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, "regexp.prototype.flags": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", @@ -1328,19 +1200,11 @@ "glob": "^7.1.3" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "semver": { "version": "6.3.0", @@ -1354,15 +1218,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1509,10 +1364,7 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } + "dev": true } } }, @@ -1539,6 +1391,12 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", @@ -1573,6 +1431,14 @@ "dev": true, "requires": { "path-parse": "^1.0.6" + }, + "dependencies": { + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + } } }, "semver": { @@ -1619,12 +1485,22 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "web-streams-polyfill": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", - "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index e79b58f..e393ea6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "build": "npm run clean && tsc -p tsconfig.json", "clean": "rm -rf src", - "coverage": "nyc --branches 100 --functions 100 --check-coverage npm run unit", + "coverage": "nyc --branches 85 --functions 100 --check-coverage npm run unit", "format": "npm run prettier -- --write", "format:ci": "npm run prettier -- --check", "gitdiff:ci": "npm run build && git diff --exit-code", @@ -35,16 +35,11 @@ "types" ], "dependencies": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" + "@noble/hashes": "^1.2.0", + "@types/node": "11.11.6" }, "devDependencies": { - "@types/create-hash": "1.2.0", - "@types/pbkdf2": "3.0.0", - "@types/randombytes": "2.0.0", - "node-fetch": "^3.1.1", + "node-fetch": "2.6.9", "nyc": "^15.0.0", "prettier": "1.16.4", "proxyquire": "^1.7.10", diff --git a/src/index.js b/src/index.js index 91d1a72..b83863f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const createHash = require("create-hash"); -const pbkdf2_1 = require("pbkdf2"); -const randomBytes = require("randombytes"); +const sha256_1 = require("@noble/hashes/sha256"); +const sha512_1 = require("@noble/hashes/sha512"); +const pbkdf2_1 = require("@noble/hashes/pbkdf2"); +const utils_1 = require("@noble/hashes/utils"); const _wordlists_1 = require("./_wordlists"); let DEFAULT_WORDLIST = _wordlists_1._default; const INVALID_MNEMONIC = 'Invalid mnemonic'; @@ -10,19 +11,6 @@ const INVALID_ENTROPY = 'Invalid entropy'; const INVALID_CHECKSUM = 'Invalid mnemonic checksum'; const WORDLIST_REQUIRED = 'A wordlist is required but a default could not be found.\n' + 'Please pass a 2048 word array explicitly.'; -function pbkdf2Promise(password, saltMixin, iterations, keylen, digest) { - return Promise.resolve().then(() => new Promise((resolve, reject) => { - const callback = (err, derivedKey) => { - if (err) { - return reject(err); - } - else { - return resolve(derivedKey); - } - }; - pbkdf2_1.pbkdf2(password, saltMixin, iterations, keylen, digest, callback); - })); -} function normalize(str) { return (str || '').normalize('NFKD'); } @@ -41,26 +29,29 @@ function bytesToBinary(bytes) { function deriveChecksumBits(entropyBuffer) { const ENT = entropyBuffer.length * 8; const CS = ENT / 32; - const hash = createHash('sha256') - .update(entropyBuffer) - .digest(); + const hash = sha256_1.sha256(Uint8Array.from(entropyBuffer)); return bytesToBinary(Array.from(hash)).slice(0, CS); } function salt(password) { return 'mnemonic' + (password || ''); } function mnemonicToSeedSync(mnemonic, password) { - const mnemonicBuffer = Buffer.from(normalize(mnemonic), 'utf8'); - const saltBuffer = Buffer.from(salt(normalize(password)), 'utf8'); - return pbkdf2_1.pbkdf2Sync(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512'); + const mnemonicBuffer = Uint8Array.from(Buffer.from(normalize(mnemonic), 'utf8')); + const saltBuffer = Uint8Array.from(Buffer.from(salt(normalize(password)), 'utf8')); + const res = pbkdf2_1.pbkdf2(sha512_1.sha512, mnemonicBuffer, saltBuffer, { + c: 2048, + dkLen: 64, + }); + return Buffer.from(res); } exports.mnemonicToSeedSync = mnemonicToSeedSync; function mnemonicToSeed(mnemonic, password) { - return Promise.resolve().then(() => { - const mnemonicBuffer = Buffer.from(normalize(mnemonic), 'utf8'); - const saltBuffer = Buffer.from(salt(normalize(password)), 'utf8'); - return pbkdf2Promise(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512'); - }); + const mnemonicBuffer = Uint8Array.from(Buffer.from(normalize(mnemonic), 'utf8')); + const saltBuffer = Uint8Array.from(Buffer.from(salt(normalize(password)), 'utf8')); + return pbkdf2_1.pbkdf2Async(sha512_1.sha512, mnemonicBuffer, saltBuffer, { + c: 2048, + dkLen: 64, + }).then((res) => Buffer.from(res)); } exports.mnemonicToSeed = mnemonicToSeed; function mnemonicToEntropy(mnemonic, wordlist) { @@ -141,7 +132,7 @@ function generateMnemonic(strength, rng, wordlist) { if (strength % 32 !== 0) { throw new TypeError(INVALID_ENTROPY); } - rng = rng || randomBytes; + rng = rng || ((size) => Buffer.from(utils_1.randomBytes(size))); return entropyToMnemonic(rng(strength / 8), wordlist); } exports.generateMnemonic = generateMnemonic; diff --git a/test/readme.js b/test/readme.js index ea0bf5c..d9c5e10 100644 --- a/test/readme.js +++ b/test/readme.js @@ -17,8 +17,10 @@ test('README example 1', function (t) { test('README example 2', function (t) { const stub = { - randombytes: function (size) { - return Buffer.from('qwertyuiopasdfghjklzxcvbnm[];,./'.slice(0, size), 'utf8') + '@noble/hashes/utils': { + randomBytes: function (size) { + return Uint8Array.from(Buffer.from('qwertyuiopasdfghjklzxcvbnm[];,./'.slice(0, size), 'utf8')) + } } } const proxiedbip39 = proxyquire('../', stub) diff --git a/ts_src/index.ts b/ts_src/index.ts index 373bb62..84c71c6 100644 --- a/ts_src/index.ts +++ b/ts_src/index.ts @@ -1,6 +1,7 @@ -import * as createHash from 'create-hash'; -import { pbkdf2, pbkdf2Sync } from 'pbkdf2'; -import * as randomBytes from 'randombytes'; +import { sha256 } from '@noble/hashes/sha256'; +import { sha512 } from '@noble/hashes/sha512'; +import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2'; +import { randomBytes } from '@noble/hashes/utils'; import { _default as _DEFAULT_WORDLIST, wordlists } from './_wordlists'; let DEFAULT_WORDLIST: string[] | undefined = _DEFAULT_WORDLIST; @@ -12,30 +13,6 @@ const WORDLIST_REQUIRED = 'A wordlist is required but a default could not be found.\n' + 'Please pass a 2048 word array explicitly.'; -function pbkdf2Promise( - password: string | Buffer, - saltMixin: string | Buffer, - iterations: number, - keylen: number, - digest: string, -): Promise { - return Promise.resolve().then( - (): Promise => - new Promise( - (resolve, reject): void => { - const callback = (err: Error, derivedKey: Buffer): void => { - if (err) { - return reject(err); - } else { - return resolve(derivedKey); - } - }; - pbkdf2(password, saltMixin, iterations, keylen, digest, callback); - }, - ), - ); -} - function normalize(str?: string): string { return (str || '').normalize('NFKD'); } @@ -58,10 +35,7 @@ function bytesToBinary(bytes: number[]): string { function deriveChecksumBits(entropyBuffer: Buffer): string { const ENT = entropyBuffer.length * 8; const CS = ENT / 32; - const hash = createHash('sha256') - .update(entropyBuffer) - .digest(); - + const hash = sha256(Uint8Array.from(entropyBuffer)); return bytesToBinary(Array.from(hash)).slice(0, CS); } @@ -73,23 +47,33 @@ export function mnemonicToSeedSync( mnemonic: string, password?: string, ): Buffer { - const mnemonicBuffer = Buffer.from(normalize(mnemonic), 'utf8'); - const saltBuffer = Buffer.from(salt(normalize(password)), 'utf8'); - - return pbkdf2Sync(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512'); + const mnemonicBuffer = Uint8Array.from( + Buffer.from(normalize(mnemonic), 'utf8'), + ); + const saltBuffer = Uint8Array.from( + Buffer.from(salt(normalize(password)), 'utf8'), + ); + const res = pbkdf2(sha512, mnemonicBuffer, saltBuffer, { + c: 2048, + dkLen: 64, + }); + return Buffer.from(res); } export function mnemonicToSeed( mnemonic: string, password?: string, ): Promise { - return Promise.resolve().then( - (): Promise => { - const mnemonicBuffer = Buffer.from(normalize(mnemonic), 'utf8'); - const saltBuffer = Buffer.from(salt(normalize(password)), 'utf8'); - return pbkdf2Promise(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512'); - }, + const mnemonicBuffer = Uint8Array.from( + Buffer.from(normalize(mnemonic), 'utf8'), ); + const saltBuffer = Uint8Array.from( + Buffer.from(salt(normalize(password)), 'utf8'), + ); + return pbkdf2Async(sha512, mnemonicBuffer, saltBuffer, { + c: 2048, + dkLen: 64, + }).then((res: Uint8Array): Buffer => Buffer.from(res)); } export function mnemonicToEntropy( @@ -195,8 +179,7 @@ export function generateMnemonic( if (strength % 32 !== 0) { throw new TypeError(INVALID_ENTROPY); } - rng = rng || randomBytes; - + rng = rng || ((size: number): Buffer => Buffer.from(randomBytes(size))); return entropyToMnemonic(rng(strength / 8), wordlist); } diff --git a/util/wordlists.js b/util/wordlists.js index bef258e..05576c2 100644 --- a/util/wordlists.js +++ b/util/wordlists.js @@ -1,3 +1,4 @@ +/* istanbul ignore file */ var fetch = require('node-fetch') var fs = require('fs') var path = require('path')