From 1ca154132e187f45988e342e8019ff7932b6f523 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 18:34:46 +0200 Subject: [PATCH 01/22] ran npm audit fix --- package-lock.json | 718 ++++++++++++++++------------------------------ 1 file changed, 248 insertions(+), 470 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7fc371d..1bbeaf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,9 +55,9 @@ }, "dependencies": { "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true } } @@ -231,6 +231,15 @@ "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", "dev": true }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -261,35 +270,17 @@ } }, "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -302,12 +293,6 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", @@ -505,9 +490,9 @@ "dev": true }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, "babel-code-frame": { @@ -720,6 +705,16 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", @@ -872,12 +867,6 @@ "resolve": "1.1.7" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, "browserify": { "version": "14.5.0", "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", @@ -1291,9 +1280,9 @@ } }, "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -1384,12 +1373,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, "combine-source-map": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", @@ -1626,19 +1609,6 @@ "inherits": "^2.0.1" } }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, "crypto-browserify": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", @@ -1657,12 +1627,6 @@ "randombytes": "^2.0.0" } }, - "dargs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz", - "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=", - "dev": true - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1832,12 +1796,6 @@ "defined": "^1.0.0" } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, "diffie-hellman": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", @@ -2008,21 +1966,6 @@ "create-hash": "^1.1.1" } }, - "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -2223,30 +2166,25 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -2452,14 +2390,15 @@ "dev": true }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "node-pre-gyp": "*" }, "dependencies": { "abbrev": { @@ -2492,10 +2431,22 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, "chownr": { - "version": "1.1.1", + "version": "1.1.4", "bundled": true, "dev": true, "optional": true @@ -2508,7 +2459,9 @@ }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -2523,7 +2476,7 @@ "optional": true }, "debug": { - "version": "4.1.1", + "version": "3.2.6", "bundled": true, "dev": true, "optional": true, @@ -2550,12 +2503,12 @@ "optional": true }, "fs-minipass": { - "version": "1.2.5", + "version": "1.2.7", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "^2.6.0" } }, "fs.realpath": { @@ -2581,7 +2534,7 @@ } }, "glob": { - "version": "7.1.3", + "version": "7.1.6", "bundled": true, "dev": true, "optional": true, @@ -2610,7 +2563,7 @@ } }, "ignore-walk": { - "version": "3.0.1", + "version": "3.0.3", "bundled": true, "dev": true, "optional": true, @@ -2629,7 +2582,7 @@ } }, "inherits": { - "version": "2.0.3", + "version": "2.0.4", "bundled": true, "dev": true, "optional": true @@ -2665,13 +2618,13 @@ } }, "minimist": { - "version": "0.0.8", + "version": "1.2.5", "bundled": true, "dev": true, "optional": true }, "minipass": { - "version": "2.3.5", + "version": "2.9.0", "bundled": true, "dev": true, "optional": true, @@ -2681,42 +2634,42 @@ } }, "minizlib": { - "version": "1.2.1", + "version": "1.3.3", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "^2.9.0" } }, "mkdirp": { - "version": "0.5.1", + "version": "0.5.3", "bundled": true, "dev": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { - "version": "2.1.1", + "version": "2.1.2", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.3.0", + "version": "2.3.3", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^4.1.0", + "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.12.0", + "version": "0.14.0", "bundled": true, "dev": true, "optional": true, @@ -2730,11 +2683,11 @@ "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", - "tar": "^4" + "tar": "^4.4.2" } }, "nopt": { - "version": "4.0.1", + "version": "4.0.3", "bundled": true, "dev": true, "optional": true, @@ -2744,19 +2697,29 @@ } }, "npm-bundled": { - "version": "1.0.6", + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.4.1", + "version": "1.4.8", "bundled": true, "dev": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, "npmlog": { @@ -2821,7 +2784,7 @@ "optional": true }, "process-nextick-args": { - "version": "2.0.0", + "version": "2.0.1", "bundled": true, "dev": true, "optional": true @@ -2836,18 +2799,10 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } } }, "readable-stream": { - "version": "2.3.6", + "version": "2.3.7", "bundled": true, "dev": true, "optional": true, @@ -2862,7 +2817,7 @@ } }, "rimraf": { - "version": "2.6.3", + "version": "2.7.1", "bundled": true, "dev": true, "optional": true, @@ -2889,7 +2844,7 @@ "optional": true }, "semver": { - "version": "5.7.0", + "version": "5.7.1", "bundled": true, "dev": true, "optional": true @@ -2942,18 +2897,18 @@ "optional": true }, "tar": { - "version": "4.4.8", + "version": "4.4.13", "bundled": true, "dev": true, "optional": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "yallist": "^3.0.3" } }, "util-deprecate": { @@ -2978,7 +2933,7 @@ "optional": true }, "yallist": { - "version": "3.0.3", + "version": "3.1.1", "bundled": true, "dev": true, "optional": true @@ -3145,78 +3100,6 @@ "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "gulp-mocha": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gulp-mocha/-/gulp-mocha-6.0.0.tgz", - "integrity": "sha512-FfBldW5ttnDpKf4Sg6/BLOOKCCbr5mbixDGK1t02/8oSrTCwNhgN/mdszG3cuQuYNzuouUdw4EH/mlYtgUscPg==", - "dev": true, - "requires": { - "dargs": "^5.1.0", - "execa": "^0.10.0", - "mocha": "^5.2.0", - "npm-run-path": "^2.0.2", - "plugin-error": "^1.0.1", - "supports-color": "^5.4.0", - "through2": "^2.0.3" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, "handlebars": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.14.tgz", @@ -3349,12 +3232,6 @@ "walk": "2.3.9" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, "highlight.js": { "version": "9.12.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", @@ -3706,12 +3583,6 @@ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", "dev": true }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, "is-symbol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", @@ -3736,12 +3607,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", @@ -3895,9 +3760,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "labeled-stream-splicer": { @@ -4116,9 +3981,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mixin-deep": { @@ -4143,101 +4008,26 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } + "minimist": "^1.2.5" } }, + "mkdirp-classic": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz", + "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g==", + "dev": true + }, "mktemp": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", "integrity": "sha1-bQUVYRyKjITkhKogABKbmOmB/ws=", "dev": true }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "module-deps": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.1.tgz", @@ -4365,12 +4155,6 @@ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -4391,15 +4175,6 @@ "sort-keys": "^2.0.0" } }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -4613,12 +4388,6 @@ "string.prototype.trim": "^1.1.2" } }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -4649,12 +4418,6 @@ "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=", "dev": true }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -4694,18 +4457,6 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -4741,9 +4492,9 @@ } }, "psl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", - "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "public-encrypt": { @@ -5152,21 +4903,6 @@ "sha.js": "~2.4.4" } }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, "shell-quote": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", @@ -5179,12 +4915,6 @@ "jsonify": "~0.0.0" } }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -5585,12 +5315,6 @@ "ansi-regex": "^2.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -5770,12 +5494,6 @@ } } }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -6015,9 +5733,9 @@ } }, "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, "uri-js": { @@ -6179,9 +5897,9 @@ }, "dependencies": { "browserify": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", - "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.1.tgz", + "integrity": "sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A==", "dev": true, "requires": { "JSONStream": "^1.0.3", @@ -6189,7 +5907,7 @@ "browser-pack": "^6.0.1", "browser-resolve": "^1.11.0", "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", + "buffer": "~5.2.1", "cached-path-relative": "^1.0.0", "concat-stream": "^1.6.0", "console-browserify": "^1.1.0", @@ -6207,7 +5925,7 @@ "inherits": "~2.0.1", "insert-module-globals": "^7.0.0", "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", + "mkdirp-classic": "^0.5.2", "module-deps": "^6.0.0", "os-browserify": "~0.3.0", "parents": "^1.0.1", @@ -6221,7 +5939,7 @@ "shasum": "^1.0.0", "shell-quote": "^1.6.1", "stream-browserify": "^2.0.0", - "stream-http": "^2.0.0", + "stream-http": "^3.0.0", "string_decoder": "^1.1.1", "subarg": "^1.0.0", "syntax-error": "^1.1.1", @@ -6232,8 +5950,41 @@ "util": "~0.10.1", "vm-browserify": "^1.0.0", "xtend": "^4.0.0" + }, + "dependencies": { + "stream-http": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.1.0.tgz", + "integrity": "sha512-cuB6RgO7BqC4FBYzmnvhob5Do3wIdIsXAgGycHJnW+981gHqoYcYz9lqjJrk8WXRddbwPuqPYRl+bag6mYv4lw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^3.0.6", + "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + } } }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", @@ -6247,9 +5998,9 @@ }, "dependencies": { "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -6291,12 +6042,20 @@ "dev": true }, "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } } }, "tty-browserify": { @@ -6306,23 +6065,21 @@ "dev": true }, "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true } } }, "wd": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/wd/-/wd-1.11.3.tgz", - "integrity": "sha512-doB7E6DDhis6sSCfWps9Uz0UBBPAySv1x96KH6klfHp8y89HvhqEq3c0O8LPZhG37egJULN0m7+M9t16xUTG0g==", + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/wd/-/wd-1.11.4.tgz", + "integrity": "sha512-FHL+ofdCoU2FGvDFser8rXI4GFwwcyAaUuvddtdctig2X0zVVT6p7FAXf7nS0z7wTwXtEuZXX7MrnVTvFPqJTQ==", "dev": true, "requires": { "archiver": "^3.0.0", "async": "^2.0.0", - "fancy-log": "^1.3.3", - "gulp-mocha": "^6.0.0", "lodash": "^4.0.0", "mkdirp": "^0.5.1", "q": "^1.5.1", @@ -6331,9 +6088,9 @@ }, "dependencies": { "archiver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.0.3.tgz", - "integrity": "sha512-d0W7NUyXoLklozHHfvWnHoHS3dvQk8eB22pv5tBwcu1jEO5eZY8W+gHytkAaJ0R8fU2TnNThrWYxjvFlKvRxpw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", "dev": true, "requires": { "archiver-utils": "^2.1.0", @@ -6342,7 +6099,7 @@ "glob": "^7.1.4", "readable-stream": "^3.4.0", "tar-stream": "^2.1.0", - "zip-stream": "^2.1.0" + "zip-stream": "^2.1.2" }, "dependencies": { "async": { @@ -6375,9 +6132,9 @@ }, "dependencies": { "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -6392,30 +6149,50 @@ } }, "bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "buffer": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.5.0.tgz", + "integrity": "sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==", "dev": true, "requires": { - "readable-stream": "^3.0.1" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "compress-commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.0.0.tgz", - "integrity": "sha512-gnETNngrfsAoLBENM8M0DoiCDJkHwz3OfIg4mBtqKDcRgE4oXNwHxHxgHvwKKlrcD7eZ7BVTy4l8t9xVF7q3FQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", "dev": true, "requires": { "buffer-crc32": "^0.2.13", - "crc32-stream": "^2.0.0", + "crc32-stream": "^3.0.1", "normalize-path": "^3.0.0", "readable-stream": "^2.3.6" }, "dependencies": { "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -6429,6 +6206,16 @@ } } }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6442,9 +6229,9 @@ "dev": true }, "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -6462,12 +6249,12 @@ } }, "tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", "dev": true, "requires": { - "bl": "^3.0.0", + "bl": "^4.0.1", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", @@ -6475,27 +6262,18 @@ } }, "zip-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.0.tgz", - "integrity": "sha512-F/xoLqlQShgvn1BzHQCNiYIoo2R93GQIMH+tA6JC3ckMDkme4bnhEEXSferZcG5ea/6bZNx3GqSUHqT8TUO6uQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", + "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", "dev": true, "requires": { "archiver-utils": "^2.1.0", - "compress-commons": "^2.0.0", + "compress-commons": "^2.1.1", "readable-stream": "^3.4.0" } } } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", From bb9016f6336d454bf83848b00a52cea865fc7baf Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 21:07:39 +0200 Subject: [PATCH 02/22] added new feature: additional invalid characters - added new functionality in index.js - added new tests and confirmed current tests are still working - added new TypeScript declarations --- index.d.ts | 1 + index.js | 13 +++++++++--- test.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/index.d.ts b/index.d.ts index fedab92..0df6661 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,6 +2,7 @@ declare function sanitize( input: string, options?: { replacement?: string | ((substring: string) => string); + invalid?: string[]; } ): string; diff --git a/index.js b/index.js index db3f020..0ba35bd 100644 --- a/index.js +++ b/index.js @@ -36,7 +36,7 @@ var reservedRe = /^\.+$/; var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; var windowsTrailingRe = /[\. ]+$/; -function sanitize(input, replacement) { +function sanitize(input, replacement, invalids) { if (typeof input !== 'string') { throw new Error('Input must be string'); } @@ -46,14 +46,21 @@ function sanitize(input, replacement) { .replace(reservedRe, replacement) .replace(windowsReservedRe, replacement) .replace(windowsTrailingRe, replacement); + for (const invalid of invalids) { + sanitized = sanitized.replace(new RegExp(invalid, 'g'), replacement); + } return truncate(sanitized, 255); } module.exports = function (input, options) { var replacement = (options && options.replacement) || ''; - var output = sanitize(input, replacement); + var invalids = (options && options.invalid) || []; + var output = sanitize(input, replacement, invalids); if (replacement === '') { return output; } - return sanitize(output, ''); + if (invalids.indexOf(replacement) !== -1) { + return sanitize(output, '', invalids); + } + return sanitize(output, '', []); }; diff --git a/test.js b/test.js index 62acc64..ff1123a 100644 --- a/test.js +++ b/test.js @@ -11,6 +11,20 @@ var REPLACEMENT_OPTS = { replacement: "_", }; +const INVALID_OPTS = { + invalid: [`'`, ` `], +} + +const INVALID_AND_REPLACEMENT_OPTS = { + replacement: "_", + invalid: [`'`, ` `], +} + +const INVALID_AS_REPLACEMENT_OPTS = { + replacement: "_", + invalid: [`'`, ` `, `_`], +} + test("valid names", function(t) { ["the quick brown fox jumped over the lazy dog.mp3", "résumé"].forEach(function(name) { @@ -26,6 +40,13 @@ test("valid names", function(t) { t.end(); }); +test("valid names", function(t) { + ["valid-name.mp3", "résumé"].forEach(function(name) { + t.equal(sanitize(name, INVALID_OPTS), name); + }); + t.end(); +}); + test("null character", function(t) { t.equal(sanitize("hello\u0000world"), "helloworld"); t.end(); @@ -36,6 +57,11 @@ test("null character", function(t) { t.end(); }); +test("null character", function(t) { + t.equal(sanitize("hello\u0000world", INVALID_OPTS), "helloworld"); + t.end(); +}); + test("control characters", function(t) { t.equal(sanitize("hello\nworld"), "helloworld"); t.end(); @@ -46,6 +72,11 @@ test("control characters", function(t) { t.end(); }); +test("control characters", function(t) { + t.equal(sanitize("hello\nworld", INVALID_OPTS), "helloworld"); + t.end(); +}); + test("restricted codes", function(t) { ["h?w", "h/w", "h*w"].forEach(function(name) { t.equal(sanitize(name), "hw"); @@ -60,6 +91,34 @@ test("restricted codes", function(t) { t.end(); }); +test("restricted codes", function(t) { + ["h?w", "h/w", "h*w"].forEach(function(name) { + t.equal(sanitize(name, INVALID_OPTS), "hw"); + }); + t.end(); +}); + +test("additional invalids", function(t) { + ["h'w", "h w"].forEach(function(name) { + t.equal(sanitize(name, INVALID_OPTS), "hw"); + }); + t.end(); +}); + +test("additional invalids with replacement", function(t) { + ["h'w", "h w"].forEach(function(name) { + t.equal(sanitize(name, INVALID_AND_REPLACEMENT_OPTS), "h_w"); + }); + t.end(); +}); + +test("replacement part of additional invalids", function(t) { + ["h'w", "h w", "h_w"].forEach(function(name) { + t.equal(sanitize(name, INVALID_AS_REPLACEMENT_OPTS), "hw"); + }); + t.end(); +}); + // https://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx test("restricted suffixes", function(t) { ["mr.", "mr..", "mr ", "mr "].forEach(function(name) { From 6f49e84cfbc207f6691a752991539b950147b469 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 21:11:36 +0200 Subject: [PATCH 03/22] updated jsdoc --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 0ba35bd..c77547a 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ * Replaces characters in strings that are illegal/unsafe for filenames. * Unsafe characters are either removed or replaced by a substitute set * in the optional `options` object. + * Additionally, more invalid characters can be passed using `invalid` attribute of the optional `options` object. * * Illegal Characters on Various Operating Systems * / ? < > \ : * | " @@ -24,7 +25,7 @@ * http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs * * @param {String} input Original filename - * @param {Object} options {replacement: String | Function } + * @param {Object} options {replacement: String | Function, invalid: String[] } * @return {String} Sanitized filename */ From 6abc74c55a0332ae9b72dc4f805c6194d3189bc5 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 21:54:53 +0200 Subject: [PATCH 04/22] remove additional invalids first - this helps to cope with certain cenarios --- index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index c77547a..20b0302 100644 --- a/index.js +++ b/index.js @@ -41,15 +41,16 @@ function sanitize(input, replacement, invalids) { if (typeof input !== 'string') { throw new Error('Input must be string'); } - var sanitized = input + var sanitized = input; + for (const invalid of invalids) { + sanitized = sanitized.replace(new RegExp(invalid, 'g'), replacement); + } + sanitized = sanitized .replace(illegalRe, replacement) .replace(controlRe, replacement) .replace(reservedRe, replacement) .replace(windowsReservedRe, replacement) .replace(windowsTrailingRe, replacement); - for (const invalid of invalids) { - sanitized = sanitized.replace(new RegExp(invalid, 'g'), replacement); - } return truncate(sanitized, 255); } From 41dc7588b19a713d41a9f38b942c604f8b6e093e Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 21:54:57 +0200 Subject: [PATCH 05/22] added further testing - more complex tests - used some additional invalids when testing with FS, some from blns --- test.js | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/test.js b/test.js index ff1123a..95edc55 100644 --- a/test.js +++ b/test.js @@ -25,6 +25,22 @@ const INVALID_AS_REPLACEMENT_OPTS = { invalid: [`'`, ` `, `_`], } +const INVALID_EMPTY_STRING = { + invalid: [``], +} + +const INVALID_WHOLE_WORDS = { + invalid: [`test`, `hello`, `, ,`], +} + +const INVALID_ALREADY_INVALID = { + invalid: [`<`, `|`, ` `], +} + +const INVALID_MIX_INVALID_NON_INVALID = { + invalid: [``, `te st`], +} + test("valid names", function(t) { ["the quick brown fox jumped over the lazy dog.mp3", "résumé"].forEach(function(name) { @@ -105,6 +121,13 @@ test("additional invalids", function(t) { t.end(); }); +test("additional invalid multiple times", function(t) { + [" h w ", "'h'w'", "'h w'"].forEach(function(name) { + t.equal(sanitize(name, INVALID_OPTS), "hw"); + }); + t.end(); +}); + test("additional invalids with replacement", function(t) { ["h'w", "h w"].forEach(function(name) { t.equal(sanitize(name, INVALID_AND_REPLACEMENT_OPTS), "h_w"); @@ -119,6 +142,40 @@ test("replacement part of additional invalids", function(t) { t.end(); }); +test("empty string as additional invalid", function(t) { + ["hw", "h w", "h_w"].forEach(function(name) { + t.equal(sanitize(name, INVALID_EMPTY_STRING), name); + }); + t.end(); +}); + +test("already invalid as additional invalid", function(t) { + ["hw", "hte stw"].forEach(function(name) { + t.equal(sanitize(name, INVALID_MIX_INVALID_NON_INVALID), "hw"); + }); + t.end(); +}); + +test("words as additional invalids", function(t) { + ["xtestx", "x, ,x"].forEach(function(name) { + t.equal(sanitize(name, INVALID_WHOLE_WORDS), "xx"); + }); + t.end(); +}); + +test("words as additional invalids two-in-one", function(t) { + t.equal(sanitize("xtestestx", INVALID_WHOLE_WORDS), "xestx"); + t.equal(sanitize("x, , ,x", INVALID_WHOLE_WORDS), "x ,x"); + t.end(); +}); + // https://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx test("restricted suffixes", function(t) { ["mr.", "mr..", "mr ", "mr "].forEach(function(name) { @@ -259,6 +316,31 @@ function testStringUsingFS(str, t) { }); } +function testStringUsingFSAdditionalInvalids(str, t) { + var sanitized = sanitize(str, {invalid: [` `, `'`, `,`, `test`, `😍`]}) || "default"; + var filepath = path.join(tempdir, sanitized); + + // Should not contain any directories or relative paths + t.equal(path.dirname(path.resolve("/abs/path", sanitized)), path.resolve("/abs/path")); + + // Should be max 255 bytes + t.assert(Buffer.byteLength(sanitized) <= 255, "max 255 bytes"); + + // Should write and read file to disk + t.equal(path.dirname(path.normalize(filepath)), tempdir); + fs.writeFile(filepath, "foobar", function(err) { + t.ifError(err, "no error writing file"); + fs.readFile(filepath, function(err, data) { + t.ifError(err, "no error reading file"); + t.equal(data.toString(), "foobar", "file contents equals"); + fs.unlink(filepath, function(err) { + t.ifError(err, "no error unlinking file"); + t.end(); + }); + }); + }); +} + // Don't run these tests in browser environments if ( ! process.browser) { // ## Browserify Build @@ -353,6 +435,9 @@ if ( ! process.browser) { test(JSON.stringify(str), function(t) { testStringUsingFS(str, t); }); + test(JSON.stringify(str), function(t) { + testStringUsingFSAdditionalInvalids(str, t); + }); }); test("remove temp directory", function(t) { @@ -361,4 +446,4 @@ if ( ! process.browser) { t.end(); }); }); -} +} \ No newline at end of file From 5251bfbf4dcb1351af33459f197a002004346ca2 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 22:04:33 +0200 Subject: [PATCH 06/22] handle replacement functions - only check if replacement is part of invalids if it's a string and not a function --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 20b0302..1d59b4f 100644 --- a/index.js +++ b/index.js @@ -61,7 +61,7 @@ module.exports = function (input, options) { if (replacement === '') { return output; } - if (invalids.indexOf(replacement) !== -1) { + if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { return sanitize(output, '', invalids); } return sanitize(output, '', []); From 91a1fb518cf9a63269b722c2f24033517ea55ec3 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 22:05:45 +0200 Subject: [PATCH 07/22] updated readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1287d30..00d4a17 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,11 @@ Sanitize `inputString` by removing or replacing invalid characters. Options: - * `options.replacement`: *optional, string/function, default: `""`*. If passed +* `options.replacement`: *optional, string/function, default: `""`*. If passed as a string, it's used as the replacement for invalid characters. If passed as a function, the function will be called with the invalid characters and it's return value will be used as the replacement. See [`String.prototype.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) for more info. +* `options.invalid`: *optional, array of strings, default:* `[]` + Any additional strings or characters that should be considered invalid and be replaced. This will not override the default invalid characters, only specify additional ones. + If a string containing a mix of valid and invalid characters is supplied, all occurences of the whole string will be replaced. From 038971a9bba7140ccb47c122fc467b12edc87c60 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 23:17:12 +0200 Subject: [PATCH 08/22] edge cases - implemented replacement of recursive patterns (this causes some restrictions with options.invalid) - added error handling for unsupported cases --- index.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 1d59b4f..48ad7ab 100644 --- a/index.js +++ b/index.js @@ -41,9 +41,20 @@ function sanitize(input, replacement, invalids) { if (typeof input !== 'string') { throw new Error('Input must be string'); } + if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { + throw new Error(`The replacement string can't be part of options.invalid or contain substrings which are part of options.invalid!`); + } var sanitized = input; - for (const invalid of invalids) { - sanitized = sanitized.replace(new RegExp(invalid, 'g'), replacement); + while (invalids.some(invalid => sanitized.includes(invalid))) { + let counter = 0; + for (const invalid of invalids) { + sanitized = sanitized.split(invalid).join(replacement); + } + if (counter > 1000) { + throw new Error(`Invalid replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.invalid!`); + } else { + counter++; + } } sanitized = sanitized .replace(illegalRe, replacement) @@ -61,8 +72,5 @@ module.exports = function (input, options) { if (replacement === '') { return output; } - if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { - return sanitize(output, '', invalids); - } return sanitize(output, '', []); }; From 6f5718787ef41369a3f879625cd61889950a04f5 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 23:17:36 +0200 Subject: [PATCH 09/22] modified tests to account for new edge cases --- test.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/test.js b/test.js index 95edc55..65069b7 100644 --- a/test.js +++ b/test.js @@ -137,14 +137,18 @@ test("additional invalids with replacement", function(t) { test("replacement part of additional invalids", function(t) { ["h'w", "h w", "h_w"].forEach(function(name) { - t.equal(sanitize(name, INVALID_AS_REPLACEMENT_OPTS), "hw"); + t.throws(function() { + sanitize(name, INVALID_AS_REPLACEMENT_OPTS); + }, null, 'replacement part of options.invalid'); }); t.end(); }); test("empty string as additional invalid", function(t) { ["hw", "h w", "h_w"].forEach(function(name) { - t.equal(sanitize(name, INVALID_EMPTY_STRING), name); + t.throws(function() { + sanitize(name, INVALID_AS_REPLACEMENT_OPTS); + }, null, 'empty string is default replacement and part of options.invalid'); }); t.end(); }); @@ -170,6 +174,20 @@ test("words as additional invalids", function(t) { t.end(); }); +test("words as additional invalids multiple times", function(t) { + ["xtestxtest", ", ,, ,x, ,x"].forEach(function(name) { + t.equal(sanitize(name, INVALID_WHOLE_WORDS), "xx"); + }); + t.end(); +}); + +test("words as additional invalids nested", function(t) { + ["xteteststx", "x,, , , ,,x"].forEach(function(name) { + t.equal(sanitize(name, INVALID_WHOLE_WORDS), "xx"); + }); + t.end(); +}); + test("words as additional invalids two-in-one", function(t) { t.equal(sanitize("xtestestx", INVALID_WHOLE_WORDS), "xestx"); t.equal(sanitize("x, , ,x", INVALID_WHOLE_WORDS), "x ,x"); From 07704fd6675984b797087811aeed658af600e716 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 23:34:06 +0200 Subject: [PATCH 10/22] rename option from 'invalid' to 'additionalInvalids' for clarity --- README.md | 2 +- index.d.ts | 2 +- index.js | 4 ++-- test.js | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 00d4a17..ab50d89 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,6 @@ Options: a function, the function will be called with the invalid characters and it's return value will be used as the replacement. See [`String.prototype.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) for more info. -* `options.invalid`: *optional, array of strings, default:* `[]` +* `options.additionalInvalids`: *optional, array of strings, default:* `[]` Any additional strings or characters that should be considered invalid and be replaced. This will not override the default invalid characters, only specify additional ones. If a string containing a mix of valid and invalid characters is supplied, all occurences of the whole string will be replaced. diff --git a/index.d.ts b/index.d.ts index 0df6661..d72411e 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ declare function sanitize( input: string, options?: { replacement?: string | ((substring: string) => string); - invalid?: string[]; + additionalInvalids?: string[]; } ): string; diff --git a/index.js b/index.js index 48ad7ab..c99ff74 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ * Replaces characters in strings that are illegal/unsafe for filenames. * Unsafe characters are either removed or replaced by a substitute set * in the optional `options` object. - * Additionally, more invalid characters can be passed using `invalid` attribute of the optional `options` object. + * Additionally, more invalid characters can be passed using `additionalInvalids` attribute of the optional `options` object. * * Illegal Characters on Various Operating Systems * / ? < > \ : * | " @@ -67,7 +67,7 @@ function sanitize(input, replacement, invalids) { module.exports = function (input, options) { var replacement = (options && options.replacement) || ''; - var invalids = (options && options.invalid) || []; + var invalids = (options && options.additionalInvalids) || []; var output = sanitize(input, replacement, invalids); if (replacement === '') { return output; diff --git a/test.js b/test.js index 65069b7..d3015e6 100644 --- a/test.js +++ b/test.js @@ -12,33 +12,33 @@ var REPLACEMENT_OPTS = { }; const INVALID_OPTS = { - invalid: [`'`, ` `], + additionalInvalids: [`'`, ` `], } const INVALID_AND_REPLACEMENT_OPTS = { replacement: "_", - invalid: [`'`, ` `], + additionalInvalids: [`'`, ` `], } const INVALID_AS_REPLACEMENT_OPTS = { replacement: "_", - invalid: [`'`, ` `, `_`], + additionalInvalids: [`'`, ` `, `_`], } const INVALID_EMPTY_STRING = { - invalid: [``], + additionalInvalids: [``], } const INVALID_WHOLE_WORDS = { - invalid: [`test`, `hello`, `, ,`], + additionalInvalids: [`test`, `hello`, `, ,`], } const INVALID_ALREADY_INVALID = { - invalid: [`<`, `|`, ` `], + additionalInvalids: [`<`, `|`, ` `], } const INVALID_MIX_INVALID_NON_INVALID = { - invalid: [``, `te st`], + additionalInvalids: [``, `te st`], } test("valid names", function(t) { @@ -335,7 +335,7 @@ function testStringUsingFS(str, t) { } function testStringUsingFSAdditionalInvalids(str, t) { - var sanitized = sanitize(str, {invalid: [` `, `'`, `,`, `test`, `😍`]}) || "default"; + var sanitized = sanitize(str, {additionalInvalids: [` `, `'`, `,`, `test`, `😍`]}) || "default"; var filepath = path.join(tempdir, sanitized); // Should not contain any directories or relative paths From da938545eeb07ea80ce5312d278d39651923c2c2 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 8 Apr 2020 23:37:44 +0200 Subject: [PATCH 11/22] more renaming and fixed typos --- index.js | 8 ++++---- test.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index c99ff74..a75f2a4 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ * Replaces characters in strings that are illegal/unsafe for filenames. * Unsafe characters are either removed or replaced by a substitute set * in the optional `options` object. - * Additionally, more invalid characters can be passed using `additionalInvalids` attribute of the optional `options` object. + * Additionally, more invalid characters can be passed using the `additionalInvalids` attribute of the optional `options` object. * * Illegal Characters on Various Operating Systems * / ? < > \ : * | " @@ -25,7 +25,7 @@ * http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs * * @param {String} input Original filename - * @param {Object} options {replacement: String | Function, invalid: String[] } + * @param {Object} options {replacement: String | Function, additionalInvalids: String[] } * @return {String} Sanitized filename */ @@ -42,7 +42,7 @@ function sanitize(input, replacement, invalids) { throw new Error('Input must be string'); } if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { - throw new Error(`The replacement string can't be part of options.invalid or contain substrings which are part of options.invalid!`); + throw new Error(`The replacement string can't be part of options.additionalInvalids or contain substrings which are part of options.additionalInvalids!`); } var sanitized = input; while (invalids.some(invalid => sanitized.includes(invalid))) { @@ -51,7 +51,7 @@ function sanitize(input, replacement, invalids) { sanitized = sanitized.split(invalid).join(replacement); } if (counter > 1000) { - throw new Error(`Invalid replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.invalid!`); + throw new Error(`Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalids!`); } else { counter++; } diff --git a/test.js b/test.js index d3015e6..c0d24ee 100644 --- a/test.js +++ b/test.js @@ -121,7 +121,7 @@ test("additional invalids", function(t) { t.end(); }); -test("additional invalid multiple times", function(t) { +test("additional invalids multiple times", function(t) { [" h w ", "'h'w'", "'h w'"].forEach(function(name) { t.equal(sanitize(name, INVALID_OPTS), "hw"); }); @@ -139,7 +139,7 @@ test("replacement part of additional invalids", function(t) { ["h'w", "h w", "h_w"].forEach(function(name) { t.throws(function() { sanitize(name, INVALID_AS_REPLACEMENT_OPTS); - }, null, 'replacement part of options.invalid'); + }, null, 'replacement part of options.additionalInvalids'); }); t.end(); }); @@ -148,7 +148,7 @@ test("empty string as additional invalid", function(t) { ["hw", "h w", "h_w"].forEach(function(name) { t.throws(function() { sanitize(name, INVALID_AS_REPLACEMENT_OPTS); - }, null, 'empty string is default replacement and part of options.invalid'); + }, null, 'empty string is default replacement and part of options.additionalInvalids'); }); t.end(); }); From e4b609bac9ffa948a7855f9d4df6f539d305ef80 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 14:31:32 +0200 Subject: [PATCH 12/22] convert to ES5 --- index.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index a75f2a4..1505bc8 100644 --- a/index.js +++ b/index.js @@ -37,6 +37,16 @@ var reservedRe = /^\.+$/; var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; var windowsTrailingRe = /[\. ]+$/; +function containsInvalids(input, invalids) { + for (var invalid of invalids) { + if (input.includes(invalid)) { + return true; + } + } + return false; + // invalids.some(invalid => sanitized.includes(invalid)) +} + function sanitize(input, replacement, invalids) { if (typeof input !== 'string') { throw new Error('Input must be string'); @@ -45,9 +55,9 @@ function sanitize(input, replacement, invalids) { throw new Error(`The replacement string can't be part of options.additionalInvalids or contain substrings which are part of options.additionalInvalids!`); } var sanitized = input; - while (invalids.some(invalid => sanitized.includes(invalid))) { - let counter = 0; - for (const invalid of invalids) { + while (containsInvalids(sanitized, invalids)) { + var counter = 0; + for (var invalid of invalids) { sanitized = sanitized.split(invalid).join(replacement); } if (counter > 1000) { From ea2bd1eb36aae24034258da1db85068d2f304fb0 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 14:35:24 +0200 Subject: [PATCH 13/22] rename option to 'additionalInvalidStrings' --- README.md | 2 +- index.d.ts | 2 +- index.js | 10 +++++----- test.js | 24 ++++++++++++------------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index ab50d89..32a0ec1 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,6 @@ Options: a function, the function will be called with the invalid characters and it's return value will be used as the replacement. See [`String.prototype.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) for more info. -* `options.additionalInvalids`: *optional, array of strings, default:* `[]` +* `options.additionalInvalidStrings`: *optional, array of strings, default:* `[]` Any additional strings or characters that should be considered invalid and be replaced. This will not override the default invalid characters, only specify additional ones. If a string containing a mix of valid and invalid characters is supplied, all occurences of the whole string will be replaced. diff --git a/index.d.ts b/index.d.ts index d72411e..e01ab10 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ declare function sanitize( input: string, options?: { replacement?: string | ((substring: string) => string); - additionalInvalids?: string[]; + additionalInvalidStrings?: string[]; } ): string; diff --git a/index.js b/index.js index 1505bc8..d03f443 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ * Replaces characters in strings that are illegal/unsafe for filenames. * Unsafe characters are either removed or replaced by a substitute set * in the optional `options` object. - * Additionally, more invalid characters can be passed using the `additionalInvalids` attribute of the optional `options` object. + * Additionally, more invalid characters can be passed using the `additionalInvalidStrings` attribute of the optional `options` object. * * Illegal Characters on Various Operating Systems * / ? < > \ : * | " @@ -25,7 +25,7 @@ * http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs * * @param {String} input Original filename - * @param {Object} options {replacement: String | Function, additionalInvalids: String[] } + * @param {Object} options {replacement: String | Function, additionalInvalidStrings: String[] } * @return {String} Sanitized filename */ @@ -52,7 +52,7 @@ function sanitize(input, replacement, invalids) { throw new Error('Input must be string'); } if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { - throw new Error(`The replacement string can't be part of options.additionalInvalids or contain substrings which are part of options.additionalInvalids!`); + throw new Error(`The replacement string can't be part of options.additionalInvalidStrings or contain substrings which are part of options.additionalInvalidStrings!`); } var sanitized = input; while (containsInvalids(sanitized, invalids)) { @@ -61,7 +61,7 @@ function sanitize(input, replacement, invalids) { sanitized = sanitized.split(invalid).join(replacement); } if (counter > 1000) { - throw new Error(`Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalids!`); + throw new Error(`Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalidStrings!`); } else { counter++; } @@ -77,7 +77,7 @@ function sanitize(input, replacement, invalids) { module.exports = function (input, options) { var replacement = (options && options.replacement) || ''; - var invalids = (options && options.additionalInvalids) || []; + var invalids = (options && options.additionalInvalidStrings) || []; var output = sanitize(input, replacement, invalids); if (replacement === '') { return output; diff --git a/test.js b/test.js index c0d24ee..8d87cdb 100644 --- a/test.js +++ b/test.js @@ -12,33 +12,33 @@ var REPLACEMENT_OPTS = { }; const INVALID_OPTS = { - additionalInvalids: [`'`, ` `], + additionalInvalidStrings: [`'`, ` `], } const INVALID_AND_REPLACEMENT_OPTS = { replacement: "_", - additionalInvalids: [`'`, ` `], + additionalInvalidStrings: [`'`, ` `], } const INVALID_AS_REPLACEMENT_OPTS = { replacement: "_", - additionalInvalids: [`'`, ` `, `_`], + additionalInvalidStrings: [`'`, ` `, `_`], } const INVALID_EMPTY_STRING = { - additionalInvalids: [``], + additionalInvalidStrings: [``], } const INVALID_WHOLE_WORDS = { - additionalInvalids: [`test`, `hello`, `, ,`], + additionalInvalidStrings: [`test`, `hello`, `, ,`], } const INVALID_ALREADY_INVALID = { - additionalInvalids: [`<`, `|`, ` `], + additionalInvalidStrings: [`<`, `|`, ` `], } const INVALID_MIX_INVALID_NON_INVALID = { - additionalInvalids: [``, `te st`], + additionalInvalidStrings: [``, `te st`], } test("valid names", function(t) { @@ -139,7 +139,7 @@ test("replacement part of additional invalids", function(t) { ["h'w", "h w", "h_w"].forEach(function(name) { t.throws(function() { sanitize(name, INVALID_AS_REPLACEMENT_OPTS); - }, null, 'replacement part of options.additionalInvalids'); + }, null, 'replacement part of options.additionalInvalidStrings'); }); t.end(); }); @@ -148,7 +148,7 @@ test("empty string as additional invalid", function(t) { ["hw", "h w", "h_w"].forEach(function(name) { t.throws(function() { sanitize(name, INVALID_AS_REPLACEMENT_OPTS); - }, null, 'empty string is default replacement and part of options.additionalInvalids'); + }, null, 'empty string is default replacement and part of options.additionalInvalidStrings'); }); t.end(); }); @@ -334,8 +334,8 @@ function testStringUsingFS(str, t) { }); } -function testStringUsingFSAdditionalInvalids(str, t) { - var sanitized = sanitize(str, {additionalInvalids: [` `, `'`, `,`, `test`, `😍`]}) || "default"; +function testStringUsingFSadditionalInvalidStrings(str, t) { + var sanitized = sanitize(str, {additionalInvalidStrings: [` `, `'`, `,`, `test`, `😍`]}) || "default"; var filepath = path.join(tempdir, sanitized); // Should not contain any directories or relative paths @@ -454,7 +454,7 @@ if ( ! process.browser) { testStringUsingFS(str, t); }); test(JSON.stringify(str), function(t) { - testStringUsingFSAdditionalInvalids(str, t); + testStringUsingFSadditionalInvalidStrings(str, t); }); }); From 057e3e90285e204dd173dc85d09efbb629a18bd8 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 14:39:13 +0200 Subject: [PATCH 14/22] replace keyword 'const' with 'var' - also removed unneeded object --- test.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test.js b/test.js index 8d87cdb..25856da 100644 --- a/test.js +++ b/test.js @@ -11,33 +11,29 @@ var REPLACEMENT_OPTS = { replacement: "_", }; -const INVALID_OPTS = { +var INVALID_OPTS = { additionalInvalidStrings: [`'`, ` `], } -const INVALID_AND_REPLACEMENT_OPTS = { +var INVALID_AND_REPLACEMENT_OPTS = { replacement: "_", additionalInvalidStrings: [`'`, ` `], } -const INVALID_AS_REPLACEMENT_OPTS = { +var INVALID_AS_REPLACEMENT_OPTS = { replacement: "_", additionalInvalidStrings: [`'`, ` `, `_`], } -const INVALID_EMPTY_STRING = { - additionalInvalidStrings: [``], -} - -const INVALID_WHOLE_WORDS = { +var INVALID_WHOLE_WORDS = { additionalInvalidStrings: [`test`, `hello`, `, ,`], } -const INVALID_ALREADY_INVALID = { +var INVALID_ALREADY_INVALID = { additionalInvalidStrings: [`<`, `|`, ` `], } -const INVALID_MIX_INVALID_NON_INVALID = { +var INVALID_MIX_INVALID_NON_INVALID = { additionalInvalidStrings: [``, `te st`], } From 7365cdb53fe1418f9c9c14d2b1e00725b25b31b0 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 14:44:13 +0200 Subject: [PATCH 15/22] replaced backticks with " --- index.js | 4 ++-- test.js | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index d03f443..589eeea 100644 --- a/index.js +++ b/index.js @@ -52,7 +52,7 @@ function sanitize(input, replacement, invalids) { throw new Error('Input must be string'); } if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { - throw new Error(`The replacement string can't be part of options.additionalInvalidStrings or contain substrings which are part of options.additionalInvalidStrings!`); + throw new Error("The replacement string can't be part of options.additionalInvalidStrings or contain substrings which are part of options.additionalInvalidStrings!"); } var sanitized = input; while (containsInvalids(sanitized, invalids)) { @@ -61,7 +61,7 @@ function sanitize(input, replacement, invalids) { sanitized = sanitized.split(invalid).join(replacement); } if (counter > 1000) { - throw new Error(`Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalidStrings!`); + throw new Error("Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalidStrings!"); } else { counter++; } diff --git a/test.js b/test.js index 25856da..7fda30c 100644 --- a/test.js +++ b/test.js @@ -12,29 +12,29 @@ var REPLACEMENT_OPTS = { }; var INVALID_OPTS = { - additionalInvalidStrings: [`'`, ` `], + additionalInvalidStrings: ["'", " "], } var INVALID_AND_REPLACEMENT_OPTS = { replacement: "_", - additionalInvalidStrings: [`'`, ` `], + additionalInvalidStrings: ["'", " "], } var INVALID_AS_REPLACEMENT_OPTS = { replacement: "_", - additionalInvalidStrings: [`'`, ` `, `_`], + additionalInvalidStrings: ["'", " ", "_"], } var INVALID_WHOLE_WORDS = { - additionalInvalidStrings: [`test`, `hello`, `, ,`], + additionalInvalidStrings: ["test", "hello", ", ,"], } var INVALID_ALREADY_INVALID = { - additionalInvalidStrings: [`<`, `|`, ` `], + additionalInvalidStrings: ["<", "|", " "], } var INVALID_MIX_INVALID_NON_INVALID = { - additionalInvalidStrings: [``, `te st`], + additionalInvalidStrings: ["", "te st"], } test("valid names", function(t) { @@ -331,7 +331,7 @@ function testStringUsingFS(str, t) { } function testStringUsingFSadditionalInvalidStrings(str, t) { - var sanitized = sanitize(str, {additionalInvalidStrings: [` `, `'`, `,`, `test`, `😍`]}) || "default"; + var sanitized = sanitize(str, {additionalInvalidStrings: [" ", "'", ",", "test", "😍"]}) || "default"; var filepath = path.join(tempdir, sanitized); // Should not contain any directories or relative paths From 020a4ee318849acc4edb2fdc1bc9e3d4f81c4161 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 15:05:58 +0200 Subject: [PATCH 16/22] remove shorthand from for loop --- index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 589eeea..3b9df0f 100644 --- a/index.js +++ b/index.js @@ -38,8 +38,8 @@ var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; var windowsTrailingRe = /[\. ]+$/; function containsInvalids(input, invalids) { - for (var invalid of invalids) { - if (input.includes(invalid)) { + for (var i = 0; i < invalids.length; i++) { + if (input.includes(invalids[i])) { return true; } } @@ -57,8 +57,8 @@ function sanitize(input, replacement, invalids) { var sanitized = input; while (containsInvalids(sanitized, invalids)) { var counter = 0; - for (var invalid of invalids) { - sanitized = sanitized.split(invalid).join(replacement); + for (var i = 0; i < invalids.length; i++) { + sanitized = sanitized.split(invalids[i]).join(replacement); } if (counter > 1000) { throw new Error("Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalidStrings!"); From 99cde1111b44367a0318d8576e88bc6d4124ad5f Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 15:07:46 +0200 Subject: [PATCH 17/22] move counter declaration to prevent re-initialization --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 3b9df0f..91e2304 100644 --- a/index.js +++ b/index.js @@ -55,8 +55,8 @@ function sanitize(input, replacement, invalids) { throw new Error("The replacement string can't be part of options.additionalInvalidStrings or contain substrings which are part of options.additionalInvalidStrings!"); } var sanitized = input; + var counter = 0; while (containsInvalids(sanitized, invalids)) { - var counter = 0; for (var i = 0; i < invalids.length; i++) { sanitized = sanitized.split(invalids[i]).join(replacement); } From 0dd8b47047396bef84dc9c934ad5656f400654c1 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 15:36:51 +0200 Subject: [PATCH 18/22] replace String.includes() with String.indexOf --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 91e2304..0068209 100644 --- a/index.js +++ b/index.js @@ -39,12 +39,11 @@ var windowsTrailingRe = /[\. ]+$/; function containsInvalids(input, invalids) { for (var i = 0; i < invalids.length; i++) { - if (input.includes(invalids[i])) { + if (input.indexOf(invalids[i]) !== -1) { return true; } } return false; - // invalids.some(invalid => sanitized.includes(invalid)) } function sanitize(input, replacement, invalids) { From 6ec33837956a31a91bee6e907abe08991651d15a Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 15:48:15 +0200 Subject: [PATCH 19/22] properly handle replacement function --- index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 0068209..1b0068f 100644 --- a/index.js +++ b/index.js @@ -57,7 +57,12 @@ function sanitize(input, replacement, invalids) { var counter = 0; while (containsInvalids(sanitized, invalids)) { for (var i = 0; i < invalids.length; i++) { - sanitized = sanitized.split(invalids[i]).join(replacement); + if (typeof replacement !== 'string') { + var tempReplacement = replacement(invalids[i]); + sanitized = sanitized.split(invalids[i]).join(tempReplacement); + } else { + sanitized = sanitized.split(invalids[i]).join(replacement); + } } if (counter > 1000) { throw new Error("Illeagal replacement function. Make sure that replacements generated by your function do not contain any of the strings specified in options.additionalInvalidStrings!"); From 8843c2051eaaebf47ae450e78ed870fc908b6333 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Thu, 9 Apr 2020 15:48:31 +0200 Subject: [PATCH 20/22] add test for illegal replacement function --- test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test.js b/test.js index 7fda30c..7eb45f0 100644 --- a/test.js +++ b/test.js @@ -37,6 +37,13 @@ var INVALID_MIX_INVALID_NON_INVALID = { additionalInvalidStrings: ["", "te st"], } +var IILEGAL_REPLACEMENT_FUNCTION = { + replacement: function(x) { + return x; + }, + additionalInvalidStrings: [",", "'"], +} + test("valid names", function(t) { ["the quick brown fox jumped over the lazy dog.mp3", "résumé"].forEach(function(name) { @@ -149,6 +156,15 @@ test("empty string as additional invalid", function(t) { t.end(); }); +test("illegal replacement function", function(t) { + ["h,w", "h'w"].forEach(function(name) { + t.throws(function() { + sanitize(name, IILEGAL_REPLACEMENT_FUNCTION); + }, null, 'the replacement function returns an invalid character'); + }); + t.end(); +}); + test("already invalid as additional invalid", function(t) { ["h Date: Fri, 10 Apr 2020 22:52:45 +0200 Subject: [PATCH 21/22] check type of replacement --- index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 1b0068f..a13dff2 100644 --- a/index.js +++ b/index.js @@ -50,6 +50,9 @@ function sanitize(input, replacement, invalids) { if (typeof input !== 'string') { throw new Error('Input must be string'); } + if (!(typeof replacement === 'string' || typeof replacement === 'function')) { + throw new Error("Replacement must be a string or a function returning a string!"); + } if (typeof replacement === 'string' && invalids.indexOf(replacement) !== -1) { throw new Error("The replacement string can't be part of options.additionalInvalidStrings or contain substrings which are part of options.additionalInvalidStrings!"); } @@ -57,7 +60,7 @@ function sanitize(input, replacement, invalids) { var counter = 0; while (containsInvalids(sanitized, invalids)) { for (var i = 0; i < invalids.length; i++) { - if (typeof replacement !== 'string') { + if (typeof replacement === 'function') { var tempReplacement = replacement(invalids[i]); sanitized = sanitized.split(invalids[i]).join(tempReplacement); } else { From 4ba9696a4197e10e01fc7f3f602fa9e884cec897 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Fri, 10 Apr 2020 23:20:59 +0200 Subject: [PATCH 22/22] added more tests - added test for wrong type of replacement function - added tests for making sure replacement function works with additional invalids --- test.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/test.js b/test.js index 7eb45f0..a4ea9a6 100644 --- a/test.js +++ b/test.js @@ -11,6 +11,19 @@ var REPLACEMENT_OPTS = { replacement: "_", }; +var REPLACEMENT_FUNCTION = { + replacement: function(invalid) { + return invalid.length; + }, +}; + +var REPLACEMENT_FUNCTION_WITH_INVALIDS = { + replacement: function(invalid) { + return invalid.length; + }, + additionalInvalidStrings: ["'", " "], +}; + var INVALID_OPTS = { additionalInvalidStrings: ["'", " "], } @@ -52,20 +65,34 @@ test("valid names", function(t) { t.end(); }); -test("valid names", function(t) { +test("valid names with replacement", function(t) { ["valid name.mp3", "résumé"].forEach(function(name) { t.equal(sanitize(name, REPLACEMENT_OPTS), name); }); t.end(); }); -test("valid names", function(t) { +test("valid names with additional invalid", function(t) { ["valid-name.mp3", "résumé"].forEach(function(name) { t.equal(sanitize(name, INVALID_OPTS), name); }); t.end(); }); +test("invalid names with replacement function", function(t) { + ["te|st", "te/st"].forEach(function(name) { + t.equal(sanitize(name, REPLACEMENT_FUNCTION), "te1st"); + }); + t.end(); +}); + +test("invalid names with replacement function and additional invalids", function(t) { + ["te|st", "te/st", "te'st", "te st"].forEach(function(name) { + t.equal(sanitize(name, REPLACEMENT_FUNCTION_WITH_INVALIDS), "te1st"); + }); + t.end(); +}); + test("null character", function(t) { t.equal(sanitize("hello\u0000world"), "helloworld"); t.end(); @@ -321,6 +348,33 @@ test("invalid input", function(t) { t.end(); }); +test("invalid replacement", function(t) { + [ + // the commented ones are legal, because they will all be replaced with the default replacement + // undefined, + // null, + // false, + true, + {}, + { + replace: function() { + return "foo"; + }, + toString: function() { + return "bar"; + }, + }, + [], + new Buffer('asdf'), + ].forEach(function(replacement) { + t.throws(function() { + sanitize('test', {replacement: replacement}); + }, null, 'Illegal replacement:'+JSON.stringify(replacement)); + }); + + t.end(); +}); + function testStringUsingFS(str, t) { var sanitized = sanitize(str) || "default"; var filepath = path.join(tempdir, sanitized);