diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..58fc5aac --- /dev/null +++ b/.babelrc @@ -0,0 +1,20 @@ +{ + "presets": [[ + "@babel/env", + { + "targets": { + "node": "12.8.1" + } + } + ]], + "plugins": [[ + "module-resolver", + { + "alias": { + "builtins": "./src/builtins/builtins.js", + "data": "./src/data/data.js", + "modules": "./src/modules/modules.js" + } + } + ]] +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 40e032d0..8c96285c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,7 +14,7 @@ "jquery": true }, "parserOptions": { - "ecmaVersion": 8, + "ecmaVersion": 2017, "sourceType": "module", "ecmaFeatures": { "jsx": true diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..7ca138de --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: node_js + +node_js: +- "node" + +branches: + only: + - development + +install: + - npm install + +script: + - npm run build-all + - npm run test + +deploy: + provider: pages + skip_cleanup: true + github_token: $TRAVIS_ACCESS + keep_history: true + local_dir: ./dist + name: BetterDiscord Deployment + target_branch: gh-pages \ No newline at end of file diff --git a/README.md b/README.md index deea9340..2b3f3b63 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# BandagedBD [![Patreon][patreon-badge]][patreon-link] [![Paypal][paypal-badge]][paypal-link] +# BandagedBD [![Build Status][travis-badge]][travis-link] [![Language Grade][lgtm-badge]][lgtm-link] [![Patreon][patreon-badge]][patreon-link] [![Paypal][paypal-badge]][paypal-link] [patreon-badge]: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.herokuapp.com%2FZerebos&style=flat-square [patreon-link]: https://patreon.com/Zerebos @@ -6,6 +6,12 @@ [paypal-badge]: https://img.shields.io/badge/Paypal-Donate!-%2300457C.svg?logo=paypal&style=flat-square [paypal-link]: https://paypal.me/ZackRauen +[lgtm-badge]: https://img.shields.io/lgtm/grade/javascript/g/rauenzi/BetterDiscordApp.svg?style=flat-square +[lgtm-link]: https://lgtm.com/projects/g/rauenzi/BetterDiscordApp/context:javascript + +[travis-badge]: https://img.shields.io/travis/rauenzi/BetterDiscordApp.svg?&style=flat-square&branch=development +[travis-link]: https://travis-ci.org/rauenzi/BetterDiscordApp + This branch is for the ongoing rewrite of BandagedBD. You can view what I believe to be left in the TODO.md file. # Testing diff --git a/TODO.md b/TODO.md index af24e00f..d12bed2f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # To-Do List -This list only reflects the items that have needed to be done since July 2020, there was a lot of progress/change before this point. +This list only reflects the items that have needed to be done since July 23 2020, there was a lot of progress/change before this point. Note: The items listed here are not in any sort of priority order. @@ -8,10 +8,8 @@ Note: The items listed here are not in any sort of priority order. - Transition code ### To Do (Injector) -- Update to new windowprefs location -- Remove dependency management -- Remove string script injection/communication with remote -- expand ipc/config commands +- Expand ipc/config commands +- Move more to preload ### To Do (Meta) - Update README (info, patrons) @@ -19,7 +17,6 @@ Note: The items listed here are not in any sort of priority order. - Add gh funding ### Someday -- Switch from /css and /js to /release - Move old utilities to BdApi - Component patcher (also does additional classes, etc) - Plugin Class diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000..c34821e8 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2017", + "allowSyntheticDefaultImports": false, + "baseUrl": "./", + "paths": { + "modules": ["./src/modules/modules.js"], + "builtins": ["./src/builtins/builtins.js"], + "data": ["./src/data/data.js"] + } + }, + "exclude": ["node_modules", "dist"] + } \ No newline at end of file diff --git a/lgtm.yml b/lgtm.yml new file mode 100644 index 00000000..460604a6 --- /dev/null +++ b/lgtm.yml @@ -0,0 +1,5 @@ +path_classifiers: + generated: + - "dist/*" + test: + - "tests/*.js" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bbc793eb..d3ca03f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1641,6 +1641,18 @@ "function-bind": "^1.1.1" } }, + "array.prototype.map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", + "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.4" + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -1775,6 +1787,19 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-module-resolver": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz", + "integrity": "sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q==", + "dev": true, + "requires": { + "find-babel-config": "^1.2.0", + "glob": "^7.1.6", + "pkg-up": "^3.1.0", + "reselect": "^4.0.0", + "resolve": "^1.13.1" + } + }, "bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -1944,6 +1969,12 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, + "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-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -2856,6 +2887,12 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -3111,6 +3148,35 @@ "string.prototype.trimstart": "^1.0.1" } }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "es-get-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", + "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", + "dev": true, + "requires": { + "es-abstract": "^1.17.4", + "has-symbols": "^1.0.1", + "is-arguments": "^1.0.4", + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -3839,6 +3905,24 @@ } } }, + "find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "dev": true, + "requires": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + } + } + }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", @@ -3890,6 +3974,23 @@ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + } + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -4178,6 +4279,12 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "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": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", @@ -4443,6 +4550,12 @@ "minimalistic-assert": "^1.0.1" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -4708,6 +4821,12 @@ "is-decimal": "^1.0.0" } }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4825,6 +4944,12 @@ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "dev": true }, + "is-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", + "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", + "dev": true + }, "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -4890,6 +5015,12 @@ "is-unc-path": "^1.0.0" } }, + "is-set": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", + "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", + "dev": true + }, "is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", @@ -4974,6 +5105,22 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "iterate-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", + "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", + "dev": true + }, + "iterate-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", + "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", + "dev": true, + "requires": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5712,6 +5859,256 @@ "minimist": "^1.2.5" } }, + "mocha": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", + "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==", + "dev": true, + "requires": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.3.1", + "debug": "3.2.6", + "diff": "4.0.2", + "escape-string-regexp": "1.0.5", + "find-up": "4.1.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "object.assign": "4.1.0", + "promise.allsettled": "1.0.2", + "serialize-javascript": "3.0.0", + "strip-json-comments": "3.0.1", + "supports-color": "7.1.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.0", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.7" + } + }, + "serialize-javascript": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", + "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -6330,6 +6727,15 @@ "find-up": "^3.0.0" } }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, "plugin-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", @@ -6678,6 +7084,19 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "promise.allsettled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", + "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", + "dev": true, + "requires": { + "array.prototype.map": "^1.0.1", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "iterate-value": "^1.0.0" + } + }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -7109,6 +7528,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "reselect": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==", + "dev": true + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -9062,6 +9487,42 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -9077,6 +9538,12 @@ "errno": "~0.1.7" } }, + "workerpool": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", + "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", + "dev": true + }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -9187,6 +9654,17 @@ "camelcase": "^5.0.0", "decamelize": "^1.2.0" } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } } } } diff --git a/package.json b/package.json index 01424fd1..7e85e34a 100644 --- a/package.json +++ b/package.json @@ -8,16 +8,14 @@ "watch": "webpack --progress --colors --watch", "build-prod": "webpack --progress --colors --mode production -o dist/index.min.js --devtool none", "lint-js": "eslint --ext .jsx,.js src/", - "build-css": "gulp build-css", "watch-css": "gulp watch-css", "minify-css": "gulp minify-css", "lint-css": "stylelint src/styles/*.css && stylelint src/styles/**/*.css && stylelint dist/style.css", - "minify": "npm run build-prod && npm run minify-css", "build-all": "npm run build-prod && npm run build-css && npm run minify-css", "lint": "npm run lint-js && npm run lint-css", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "mocha --require @babel/register --recursive \"./tests/*.js\"" }, "repository": { "type": "git", @@ -35,12 +33,14 @@ "@babel/preset-react": "^7.10.4", "@babel/register": "^7.10.5", "babel-loader": "^8.1.0", + "babel-plugin-module-resolver": "^4.0.0", "circular-dependency-plugin": "^5.2.0", "eslint": "^7.5.0", "eslint-plugin-react": "^7.20.3", "gulp": "^4.0.2", "gulp-postcss": "^8.0.0", "gulp-rename": "^2.0.0", + "mocha": "^8.0.1", "postcss-csso": "^4.0.0", "postcss-easy-import": "^3.0.0", "stylelint": "^13.6.1", diff --git a/tests/.eslintrc b/tests/.eslintrc new file mode 100644 index 00000000..bde54260 --- /dev/null +++ b/tests/.eslintrc @@ -0,0 +1,8 @@ +{ + "extends": "../.eslintrc", + "globals": { + "describe": false, + "it": false, + "Reflect": false + } +} \ No newline at end of file diff --git a/tests/utilities.js b/tests/utilities.js new file mode 100644 index 00000000..3247b3b0 --- /dev/null +++ b/tests/utilities.js @@ -0,0 +1,158 @@ +import assert from "assert"; +import Utilities from "../src/modules/utilities"; + +describe("Utilities", function() { + + describe("suppressErrors", function() { + it("Prevent error propagation", function() { + const thrower = () => {throw "Error";}; + const wrapped = Utilities.suppressErrors(thrower); + assert.doesNotThrow(wrapped); + }); + it("Allows arguments through", function() { + const thrower = (foo) => { + assert.equal(foo, "bar"); + }; + const wrapped = Utilities.suppressErrors(thrower); + wrapped("bar"); + }); + it("Retains the return value", function() { + const thrower = () => {return "bar";}; + const wrapped = Utilities.suppressErrors(thrower); + const foo = wrapped(); + assert.equal(foo, "bar"); + }); + }); + + describe("formatString", function() { + it("Should handle direct replacement", function() { + const template = `This is a {{success}}`; + const filledOut = Utilities.formatString(template, {success: "success"}); + assert.equal("This is a success", filledOut); + }); + it("Should not error with excess data", function() { + const template = `This is a {{success}}`; + const filledOut = Utilities.formatString(template, {success: "success", otherthing: "foo"}); + assert.equal("This is a success", filledOut); + }); + it("Should toString objects", function() { + const template = `This is a {{success}}`; + const filledOut = Utilities.formatString(template, {success: {misnomer: "good"}}); + assert.equal(`This is a [object Object]`, filledOut); + const filledOut2 = Utilities.formatString(template, {success: {toString: () => {return "good test";}}}); + assert.equal(`This is a good test`, filledOut2); + }); + it("Should stringify arrays", function() { + const template = `This is a {{success}}`; + const filledOut = Utilities.formatString(template, {success: ["success", "or", "failure"]}); + assert.equal(`This is a ["success","or","failure"]`, filledOut); + }); + it("Use the return value of functions", function() { + const template = `This is a {{success}}`; + const filledOut = Utilities.formatString(template, {success: () => "test"}); + assert.equal(`This is a test`, filledOut); + }); + }); + + describe("getNestedProp", function() { + const testObj = {test: {deep: {go: "far"}, other: [0, 1, {test2: "foo"}]}}; + it("Gets a shallow property", function() { + const result = Utilities.getNestedProp(testObj, "test"); + assert.deepEqual(result, testObj.test); + }); + it("Gets a deep property", function() { + const result = Utilities.getNestedProp(testObj, "test.deep.go"); + assert.deepEqual(result, testObj.test.deep.go); + }); + it("Gets a property through index", function() { + const result = Utilities.getNestedProp(testObj, "test.other.2.test2"); + assert.deepEqual(result, testObj.test.other[2].test2); + }); + it("Returns null when the a prop is not found", function() { + const result = Utilities.getNestedProp(testObj, "test.foo"); + assert.equal(result, null); + }); + it("Returns null when several layers are not found", function() { + const result = Utilities.getNestedProp(testObj, "test.deep.far.doit.cmon"); + assert.equal(result, null); + }); + }); + + describe("findInTree", function() { + const testObj = {test: {deep: {go: "far"}, other: [0, 1, {test2: "foo"}]}}; + it("Gets a shallow property using a string", function() { + const result = Utilities.findInTree(testObj, "test"); + assert.deepEqual(result, testObj.test); + }); + it("Gets a shallow property using a function", function() { + const result = Utilities.findInTree(testObj, o => Object.keys(o).includes("deep")); + assert.deepEqual(result, testObj.test); + }); + it("Gets a deep property using a string", function() { + const result = Utilities.findInTree(testObj, "go"); + assert.deepEqual(result, testObj.test.deep.go); + }); + it("Gets a deep property using a function", function() { + const result = Utilities.findInTree(testObj, o => o == "far"); + assert.deepEqual(result, testObj.test.deep.go); + }); + it("Returns undefined when not found using string", function() { + const result = Utilities.findInTree(testObj, "foobar"); + assert.equal(result, undefined); + }); + it("Returns undefined when not found using function", function() { + const result = Utilities.findInTree(testObj, o => o && o.foobar); + assert.equal(result, undefined); + }); + + const walkingObj = {foo: {bar: "final1", deeper: "final2", test: "final3"}, test: "final4", otherTest: {bar: "final5", deeper: "final6"}}; + it("Gets a property using a string limited to walkable keys", function() { + const result = Utilities.findInTree(walkingObj, "bar", {walkable: ["foo", "bar"]}); + assert.equal(result, walkingObj.foo.bar); + }); + it("Gets a property using a function limited to walkable keys", function() { + const result = Utilities.findInTree(walkingObj, o => o.deeper, {walkable: ["foo", "bar"]}); + assert.deepEqual(result, walkingObj.foo); + }); + it("Gets a property using a string ignoring specific keys", function() { + const result = Utilities.findInTree(walkingObj, "bar", {ignore: ["foo", "bar"]}); + assert.equal(result, walkingObj.otherTest.bar); + }); + it("Gets a property using a function ignoring specific keys", function() { + const result = Utilities.findInTree(walkingObj, o => o.deeper, {ignore: ["foo", "bar"]}); + assert.deepEqual(result, walkingObj.otherTest); + }); + }); + + describe("findInReactTree", function() { + const originalFindInTree = Utilities.findInTree; + + it("Passes the original object", function() { + const myObj = {props: "foo"}; + Utilities.findInTree = function(obj) { assert.deepEqual(obj, myObj); return Reflect.apply(originalFindInTree, Utilities, arguments); }; + const result = Utilities.findInReactTree(myObj, "props"); + assert.equal(result, "foo"); + }); + it("Passes the original filter", function() { + const myObj = {props: "foo"}; + const myFilter = "props"; + Utilities.findInTree = function(obj, filter) { assert.deepEqual(filter, myFilter); return Reflect.apply(originalFindInTree, Utilities, arguments); }; + const result = Utilities.findInReactTree(myObj, myFilter); + assert.equal(result, "foo"); + + const myFilter2 = o => o == "foo"; + Utilities.findInTree = function(obj, filter) { assert.deepEqual(filter, myFilter2); return Reflect.apply(originalFindInTree, Utilities, arguments); }; + const result2 = Utilities.findInReactTree(myObj, myFilter2); + assert.equal(result2, "foo"); + }); + it("Includes the react walkables", function() { + Utilities.findInTree = function(obj, filter, {walkable}) { + const shouldWalk = ["props", "children", "return", "stateNode"]; + assert.ok(shouldWalk.every(k => walkable.includes(k))); + }; + Utilities.findInReactTree({}, "foobar"); + }); + + Utilities.findInTree = originalFindInTree; + }); +}); \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 0de68013..5ed78be3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -22,11 +22,11 @@ module.exports = { }, resolve: { extensions: [".js", ".jsx"], - modules: [ - path.resolve("src", "builtins"), - path.resolve("src", "data"), - path.resolve("src", "modules") - ] + alias: { + modules$: path.resolve("src", "modules"), + data$: path.resolve("src", "modules"), + builtins$: path.resolve("src", "modules") + } }, module: { rules: [ @@ -36,22 +36,18 @@ module.exports = { exclude: /node_modules/, query: { presets: [["@babel/env", { - targets: { - node: "10.11.0", - chrome: "69" - } - }], "@babel/react"] + targets: { + node: "10.11.0", + chrome: "69" + } + }], "@babel/react"] } } ] }, plugins: [ new CircularDependencyPlugin({ - // exclude detection of files based on a RegExp exclude: /node_modules/, - // add errors to webpack instead of warnings - // failOnError: true, - // set the current working directory for displaying module paths cwd: process.cwd(), }) ]