From 8f1da35befc3bec4f7e8883bd4dd0e33cb798de5 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:39:10 +0100 Subject: [PATCH 01/11] [misc] setup eslint and prettier and fix any errors --- server-ce/.eslintrc | 17 + server-ce/.prettierrc | 8 + server-ce/package-lock.json | 1764 ++++++++++++++++++++++++++++++++++- server-ce/package.json | 17 + server-ce/services.js | 104 ++- 5 files changed, 1851 insertions(+), 59 deletions(-) create mode 100644 server-ce/.eslintrc create mode 100644 server-ce/.prettierrc diff --git a/server-ce/.eslintrc b/server-ce/.eslintrc new file mode 100644 index 0000000000..1efb79d093 --- /dev/null +++ b/server-ce/.eslintrc @@ -0,0 +1,17 @@ +{ + "extends": [ + "eslint:recommended", + "standard", + "prettier" + ], + "parserOptions": { + "ecmaVersion": 2018 + }, + "env": { + "node": true + }, + "rules": { + // Do not allow importing of implicit dependencies. + "import/no-extraneous-dependencies": "error" + } +} diff --git a/server-ce/.prettierrc b/server-ce/.prettierrc new file mode 100644 index 0000000000..e692368d0e --- /dev/null +++ b/server-ce/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "avoid", + "semi": false, + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "useTabs": false +} diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json index 62038e3213..69bb8563cf 100644 --- a/server-ce/package-lock.json +++ b/server-ce/package-lock.json @@ -4,12 +4,201 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.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" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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" + } + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "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": "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 + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", @@ -40,6 +229,36 @@ } } }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", @@ -49,15 +268,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -78,6 +295,22 @@ "mv": "~2" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "chalk": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", @@ -94,6 +327,21 @@ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "colors": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", @@ -104,8 +352,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -113,6 +360,28 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "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" + } + } + } + }, "dateformat": { "version": "1.0.2-1.2.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", @@ -125,6 +394,30 @@ "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", "dev": true }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", @@ -180,12 +473,543 @@ "resolved": "https://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz", "integrity": "sha1-WKtCdGaRy+ITtBweiG8EttyCq8A=" }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "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 + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.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" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true + }, + "eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-chai-expect": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz", + "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", + "dev": true + }, + "eslint-plugin-chai-friendly": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.6.0.tgz", + "integrity": "sha512-Uvvv1gkbRGp/qfN15B0kQyQWg+oFA8buDSqrwmW3egNSk/FpqH2MjQqKOuKwmEL6w4QIQrIjDp+gg6kGGmD3oQ==", + "dev": true + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.23.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", + "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", + "dev": true, + "requires": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.1", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.4.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.3", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-mocha": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.2.0.tgz", + "integrity": "sha512-8oOR47Ejt+YJPNQzedbiklDqS1zurEaNrxXpRs+Uk4DMDPVmKNagShFeUaYsfvWP55AhI+P1non5QZAHV6K78A==", + "dev": true, + "requires": { + "eslint-utils": "^2.1.0", + "ramda": "^0.27.1" + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "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" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", + "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, "esprima": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", "dev": true }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", @@ -198,6 +1022,42 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "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 + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "findup-sync": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", @@ -236,6 +1096,85 @@ } } }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "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" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "getobject": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", @@ -261,6 +1200,24 @@ } } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, "graceful-fs": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", @@ -586,30 +1543,84 @@ } } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-color": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", "dev": true }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, "iconv-lite": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", "dev": true }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, - "optional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -621,12 +1632,124 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "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 + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", @@ -637,6 +1760,33 @@ "esprima": "~ 1.0.2" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "knox": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/knox/-/knox-0.8.10.tgz", @@ -649,6 +1799,16 @@ "xml2js": "0.2.x" } }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "load-grunt-config": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/load-grunt-config/-/load-grunt-config-0.19.2.tgz", @@ -1009,11 +2169,59 @@ } } }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lpad": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lpad/-/lpad-0.1.0.tgz", @@ -1046,8 +2254,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true + "dev": true }, "mkdirp": { "version": "0.5.5", @@ -1280,6 +2487,12 @@ } } }, + "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 + }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -1328,6 +2541,12 @@ } } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -1344,22 +2563,226 @@ "abbrev": "1" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, - "optional": true + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } }, "readable-stream": { "version": "1.0.34", @@ -1400,6 +2823,34 @@ } } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "rimraf": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", @@ -1431,12 +2882,102 @@ } } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "stream-counter": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.1.0.tgz", @@ -1446,6 +2987,48 @@ "readable-stream": "~1.0.2" } }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -1458,6 +3041,114 @@ "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", "dev": true }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "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" + } + }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "requires": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -1469,18 +3160,61 @@ "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", "dev": true }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "which": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", "dev": true }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "xml2js": { "version": "0.2.8", @@ -1490,6 +3224,12 @@ "requires": { "sax": "0.5.x" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } } diff --git a/server-ce/package.json b/server-ce/package.json index 4b32165fcd..b9f180e084 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -2,6 +2,12 @@ "name": "sharelatex", "version": "0.0.1", "description": "An online collaborative LaTeX editor", + "scripts": { + "lint": "eslint --max-warnings 0 --format unix .", + "lint:fix": "eslint --fix .", + "format": "prettier --list-different $PWD/'**/*.js'", + "format:fix": "prettier --write $PWD/'**/*.js'" + }, "dependencies": { "async": "^0.9.0", "bson": "^1.0.4", @@ -21,11 +27,22 @@ "devDependencies": { "grunt": "~0.4.2", "bunyan": "~0.22.1", + "eslint": "^7.21.0", + "eslint-config-prettier": "^8.1.0", + "eslint-config-standard": "^16.0.2", + "eslint-plugin-chai-expect": "^2.2.0", + "eslint-plugin-chai-friendly": "^0.6.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-mocha": "^8.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^5.0.0", "grunt-bunyan": "~0.5.0", "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", "grunt-concurrent": "~0.4.3", "grunt-contrib-coffee": "~0.10.1", + "prettier": "^2.2.1", "semver": "~2.2.1", "knox": "~0.8.9" } diff --git a/server-ce/services.js b/server-ce/services.js index 84fd7622f5..4fc6365f6b 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -1,47 +1,57 @@ -module.exports = - -[{ - name: "web", - repo: "https://github.com/sharelatex/web-sharelatex.git", - version: "master" -}, { - name: "real-time", - repo: "https://github.com/sharelatex/real-time-sharelatex.git", - version: "master" -}, { - name: "document-updater", - repo: "https://github.com/sharelatex/document-updater-sharelatex.git", - version: "master" -}, { - name: "clsi", - repo: "https://github.com/sharelatex/clsi-sharelatex.git", - version: "master" -}, { - name: "filestore", - repo: "https://github.com/sharelatex/filestore-sharelatex.git", - version: "master" -}, { - name: "track-changes", - repo: "https://github.com/sharelatex/track-changes-sharelatex.git", - version: "master" -}, { - name: "docstore", - repo: "https://github.com/sharelatex/docstore-sharelatex.git", - version: "master" -}, { - name: "chat", - repo: "https://github.com/sharelatex/chat-sharelatex.git", - version: "master" -}, { - name: "spelling", - repo: "https://github.com/sharelatex/spelling-sharelatex.git", - version: "master" -}, { - name: "contacts", - repo: "https://github.com/sharelatex/contacts-sharelatex.git", - version: "master" -}, { - name: "notifications", - repo: "https://github.com/sharelatex/notifications-sharelatex.git", - version: "master" -}] +module.exports = [ + { + name: 'web', + repo: 'https://github.com/sharelatex/web-sharelatex.git', + version: 'master', + }, + { + name: 'real-time', + repo: 'https://github.com/sharelatex/real-time-sharelatex.git', + version: 'master', + }, + { + name: 'document-updater', + repo: 'https://github.com/sharelatex/document-updater-sharelatex.git', + version: 'master', + }, + { + name: 'clsi', + repo: 'https://github.com/sharelatex/clsi-sharelatex.git', + version: 'master', + }, + { + name: 'filestore', + repo: 'https://github.com/sharelatex/filestore-sharelatex.git', + version: 'master', + }, + { + name: 'track-changes', + repo: 'https://github.com/sharelatex/track-changes-sharelatex.git', + version: 'master', + }, + { + name: 'docstore', + repo: 'https://github.com/sharelatex/docstore-sharelatex.git', + version: 'master', + }, + { + name: 'chat', + repo: 'https://github.com/sharelatex/chat-sharelatex.git', + version: 'master', + }, + { + name: 'spelling', + repo: 'https://github.com/sharelatex/spelling-sharelatex.git', + version: 'master', + }, + { + name: 'contacts', + repo: 'https://github.com/sharelatex/contacts-sharelatex.git', + version: 'master', + }, + { + name: 'notifications', + repo: 'https://github.com/sharelatex/notifications-sharelatex.git', + version: 'master', + }, +] From d152a798102f110314ee3dea4896fb89a77b0495 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 7 Jul 2021 11:39:38 +0000 Subject: [PATCH 02/11] decaffeinate: Rename coffee files from .coffee to .js --- server-ce/{Gruntfile.coffee => Gruntfile.js} | 0 server-ce/{settings.coffee => settings.js} | 0 .../{CreateAndDestroyUsers.coffee => CreateAndDestroyUsers.js} | 0 server-ce/tasks/{ProjectSize.coffee => ProjectSize.js} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename server-ce/{Gruntfile.coffee => Gruntfile.js} (100%) rename server-ce/{settings.coffee => settings.js} (100%) rename server-ce/tasks/{CreateAndDestroyUsers.coffee => CreateAndDestroyUsers.js} (100%) rename server-ce/tasks/{ProjectSize.coffee => ProjectSize.js} (100%) diff --git a/server-ce/Gruntfile.coffee b/server-ce/Gruntfile.js similarity index 100% rename from server-ce/Gruntfile.coffee rename to server-ce/Gruntfile.js diff --git a/server-ce/settings.coffee b/server-ce/settings.js similarity index 100% rename from server-ce/settings.coffee rename to server-ce/settings.js diff --git a/server-ce/tasks/CreateAndDestroyUsers.coffee b/server-ce/tasks/CreateAndDestroyUsers.js similarity index 100% rename from server-ce/tasks/CreateAndDestroyUsers.coffee rename to server-ce/tasks/CreateAndDestroyUsers.js diff --git a/server-ce/tasks/ProjectSize.coffee b/server-ce/tasks/ProjectSize.js similarity index 100% rename from server-ce/tasks/ProjectSize.coffee rename to server-ce/tasks/ProjectSize.js From efd16d99d6136c1d06164b5897d73e07006103f8 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 7 Jul 2021 11:39:42 +0000 Subject: [PATCH 03/11] decaffeinate: Convert coffee files to JS --- server-ce/Gruntfile.js | 417 ++++++---- server-ce/settings.js | 992 +++++++++++++---------- server-ce/tasks/CreateAndDestroyUsers.js | 125 +-- server-ce/tasks/ProjectSize.js | 42 +- 4 files changed, 899 insertions(+), 677 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index 9375096d62..a1173ed864 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -1,216 +1,311 @@ -coffee = require("coffee-script") -fs = require "fs" -spawn = require("child_process").spawn -exec = require("child_process").exec -rimraf = require "rimraf" -Path = require "path" -semver = require "semver" -knox = require "knox" -crypto = require "crypto" -async = require "async" -settings = require("settings-sharelatex") -_ = require("underscore") +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const coffee = require("coffee-script"); +const fs = require("fs"); +const { + spawn +} = require("child_process"); +const { + exec +} = require("child_process"); +const rimraf = require("rimraf"); +const Path = require("path"); +const semver = require("semver"); +const knox = require("knox"); +const crypto = require("crypto"); +const async = require("async"); +const settings = require("settings-sharelatex"); +const _ = require("underscore"); -SERVICES = require("./config/services") +const SERVICES = require("./config/services"); -module.exports = (grunt) -> - grunt.loadNpmTasks 'grunt-bunyan' - grunt.loadNpmTasks 'grunt-execute' - grunt.loadNpmTasks 'grunt-available-tasks' - grunt.loadNpmTasks 'grunt-concurrent' - grunt.loadNpmTasks "grunt-contrib-coffee" - grunt.loadNpmTasks "grunt-shell" +module.exports = function(grunt) { + let Helpers; + let service; + grunt.loadNpmTasks('grunt-bunyan'); + grunt.loadNpmTasks('grunt-execute'); + grunt.loadNpmTasks('grunt-available-tasks'); + grunt.loadNpmTasks('grunt-concurrent'); + grunt.loadNpmTasks("grunt-contrib-coffee"); + grunt.loadNpmTasks("grunt-shell"); - grunt.task.loadTasks "./tasks" + grunt.task.loadTasks("./tasks"); - execute = {} - for service in SERVICES + const execute = {}; + for (service of Array.from(SERVICES)) { execute[service.name] = - src: "#{service.name}/app.js" + {src: `${service.name}/app.js`}; + } - grunt.initConfig - execute: execute + grunt.initConfig({ + execute, - concurrent: - all: - tasks: ("run:#{service.name}" for service in SERVICES) - options: - limit: SERVICES.length + concurrent: { + all: { + tasks: (((() => { + const result = []; + for (service of Array.from(SERVICES)) { result.push(`run:${service.name}`); + } + return result; + })())), + options: { + limit: SERVICES.length, logConcurrentOutput: true - availabletasks: - tasks: - options: + availabletasks: { + tasks: { + options: { filter: 'exclude', tasks: [ - 'concurrent' - 'execute' - 'bunyan' + 'concurrent', + 'execute', + 'bunyan', 'availabletasks' - ] - groups: + ], + groups: { "Run tasks": [ - "run" - "run:all" + "run", + "run:all", "default" - ].concat ("run:#{service.name}" for service in SERVICES) + ].concat(((() => { + const result1 = []; + for (service of Array.from(SERVICES)) { result1.push(`run:${service.name}`); + } + return result1; + })())), "Misc": [ "help" - ] - "Install tasks": ("install:#{service.name}" for service in SERVICES).concat(["install:all", "install"]) - "Update tasks": ("update:#{service.name}" for service in SERVICES).concat(["update:all", "update"]) + ], + "Install tasks": ((() => { + const result2 = []; + for (service of Array.from(SERVICES)) { result2.push(`install:${service.name}`); + } + return result2; + })()).concat(["install:all", "install"]), + "Update tasks": ((() => { + const result3 = []; + for (service of Array.from(SERVICES)) { result3.push(`update:${service.name}`); + } + return result3; + })()).concat(["update:all", "update"]), "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make", "check:mongo"] + } + } + } + }}); - for service in SERVICES - do (service) -> - grunt.registerTask "install:#{service.name}", "Download and set up the #{service.name} service", () -> - done = @async() - Helpers.installService(service, done) + for (service of Array.from(SERVICES)) { + ((service => grunt.registerTask(`install:${service.name}`, `Download and set up the ${service.name} service`, function() { + const done = this.async(); + return Helpers.installService(service, done); + })))(service); + } - grunt.registerTask 'install:all', "Download and set up all ShareLaTeX services", + grunt.registerTask('install:all', "Download and set up all ShareLaTeX services", [].concat( - ("install:#{service.name}" for service in SERVICES) + ((() => { + const result4 = []; + for (service of Array.from(SERVICES)) { result4.push(`install:${service.name}`); + } + return result4; + })()) ).concat(['postinstall']) + ); - grunt.registerTask 'install', 'install:all' - grunt.registerTask 'postinstall', 'Explain postinstall steps', () -> - Helpers.postinstallMessage @async() + grunt.registerTask('install', 'install:all'); + grunt.registerTask('postinstall', 'Explain postinstall steps', function() { + return Helpers.postinstallMessage(this.async()); + }); - grunt.registerTask 'update:all', "Checkout and update all ShareLaTeX services", + grunt.registerTask('update:all', "Checkout and update all ShareLaTeX services", ["check:make"].concat( - ("update:#{service.name}" for service in SERVICES) + ((() => { + const result5 = []; + for (service of Array.from(SERVICES)) { result5.push(`update:${service.name}`); + } + return result5; + })()) ) - grunt.registerTask 'update', 'update:all' - grunt.registerTask 'run', "Run all of the sharelatex processes", ['concurrent:all'] - grunt.registerTask 'run:all', 'run' + ); + grunt.registerTask('update', 'update:all'); + grunt.registerTask('run', "Run all of the sharelatex processes", ['concurrent:all']); + grunt.registerTask('run:all', 'run'); - grunt.registerTask 'help', 'Display this help list', 'availabletasks' - grunt.registerTask 'default', 'run' + grunt.registerTask('help', 'Display this help list', 'availabletasks'); + grunt.registerTask('default', 'run'); - grunt.registerTask "check:redis", "Check that redis is installed and running", () -> - Helpers.checkRedisConnect @async() + grunt.registerTask("check:redis", "Check that redis is installed and running", function() { + return Helpers.checkRedisConnect(this.async()); + }); - grunt.registerTask "check:mongo", "Check that mongo is installed", () -> - Helpers.checkMongoConnect @async() + grunt.registerTask("check:mongo", "Check that mongo is installed", function() { + return Helpers.checkMongoConnect(this.async()); + }); - grunt.registerTask "check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"] + grunt.registerTask("check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"]); - grunt.registerTask "check:make", "Check that make is installed", () -> - Helpers.checkMake @async() + grunt.registerTask("check:make", "Check that make is installed", function() { + return Helpers.checkMake(this.async()); + }); - Helpers = - installService: (service, callback = (error) ->) -> - console.log "Installing #{service.name}" - Helpers.cloneGitRepo service, (error) -> - if error? - callback(error) - else - callback() + return Helpers = { + installService(service, callback) { + if (callback == null) { callback = function(error) {}; } + console.log(`Installing ${service.name}`); + return Helpers.cloneGitRepo(service, function(error) { + if (error != null) { + return callback(error); + } else { + return callback(); + } + }); + }, - cloneGitRepo: (service, callback = (error) ->) -> - repo_src = service.repo - dir = service.name - if !fs.existsSync(dir) - proc = spawn "git", [ + cloneGitRepo(service, callback) { + if (callback == null) { callback = function(error) {}; } + const repo_src = service.repo; + const dir = service.name; + if (!fs.existsSync(dir)) { + const proc = spawn("git", [ "clone", repo_src, dir - ], stdio: "inherit" - proc.on "close", () -> - Helpers.checkoutVersion service, callback - else - console.log "#{dir} already installed, skipping." - callback() + ], {stdio: "inherit"}); + return proc.on("close", () => Helpers.checkoutVersion(service, callback)); + } else { + console.log(`${dir} already installed, skipping.`); + return callback(); + } + }, - checkoutVersion: (service, callback = (error) ->) -> - dir = service.name - grunt.log.write "checking out #{service.name} #{service.version}" - proc = spawn "git", ["checkout", service.version], stdio: "inherit", cwd: dir - proc.on "close", () -> - callback() + checkoutVersion(service, callback) { + if (callback == null) { callback = function(error) {}; } + const dir = service.name; + grunt.log.write(`checking out ${service.name} ${service.version}`); + const proc = spawn("git", ["checkout", service.version], {stdio: "inherit", cwd: dir}); + return proc.on("close", () => callback()); + }, - postinstallMessage: (callback = (error) ->) -> - grunt.log.write """ - Services cloned: - #{service.name for service in SERVICES} - To install services run: - $ source bin/install-services - This will install the required node versions and run `npm install` for each service. - See https://github.com/sharelatex/sharelatex/pull/549 for more info. - """ - callback() + postinstallMessage(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write(`\ +Services cloned: + ${(() => { + const result6 = []; + for (service of Array.from(SERVICES)) { result6.push(service.name); + } + return result6; + })()} +To install services run: + $ source bin/install-services +This will install the required node versions and run \`npm install\` for each service. +See https://github.com/sharelatex/sharelatex/pull/549 for more info.\ +` + ); + return callback(); + }, - checkMake: (callback = (error) ->) -> - grunt.log.write "Checking make is installed... " - exec "make --version", (error, stdout, stderr) -> - if error? and error.message.match("not found") - grunt.log.error "FAIL." - grunt.log.errorlns """ - Either make is not installed or is not in your path. + checkMake(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write("Checking make is installed... "); + return exec("make --version", function(error, stdout, stderr) { + if ((error != null) && error.message.match("not found")) { + grunt.log.error("FAIL."); + grunt.log.errorlns(`\ +Either make is not installed or is not in your path. - On Ubuntu you can install make with: +On Ubuntu you can install make with: - sudo apt-get install build-essential + sudo apt-get install build-essential +\ +` + ); + return callback(error); + } else if (error != null) { + return callback(error); + } else { + grunt.log.write("OK."); + return callback(); + } + }); + }, + checkMongoConnect(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write("Checking can connect to mongo"); + const mongojs = require("mongojs"); + const db = mongojs(settings.mongo.url, ["tags"]); + db.runCommand({ ping: 1 }, function(err, res) { + if (!err && res.ok) { + grunt.log.write("OK."); + } + return callback(); + }); + return db.on('error', function(err){ + err = "Can not connect to mongodb"; + grunt.log.error("FAIL."); + grunt.log.errorlns(`\ +!!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! - """ - return callback(error) - else if error? - return callback(error) - else - grunt.log.write "OK." - return callback() - checkMongoConnect: (callback = (error) ->) -> - grunt.log.write "Checking can connect to mongo" - mongojs = require("mongojs") - db = mongojs(settings.mongo.url, ["tags"]) - db.runCommand { ping: 1 }, (err, res) -> - if !err and res.ok - grunt.log.write "OK." - return callback() - db.on 'error', (err)-> - err = "Can not connect to mongodb" - grunt.log.error "FAIL." - grunt.log.errorlns """ - !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! +ShareLaTeX can not talk to the mongodb instance - ShareLaTeX can not talk to the mongodb instance +Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL - Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL - - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - """ - throw new Error("Can not connect to Mongodb") - return callback(err) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ +` + ); + throw new Error("Can not connect to Mongodb"); + return callback(err); + }); + }, - checkRedisConnect: (callback = (error) ->) -> - grunt.log.write "Checking can connect to redis\n" - rclient = require("redis").createClient(settings.redis.web) + checkRedisConnect(callback) { + if (callback == null) { callback = function(error) {}; } + grunt.log.write("Checking can connect to redis\n"); + const rclient = require("redis").createClient(settings.redis.web); - rclient.ping (err, res) -> - if !err? - grunt.log.write "OK." - else - throw new Error("Can not connect to redis") - return callback() - errorHandler = _.once (err)-> - err = "Can not connect to redis" - grunt.log.error "FAIL." - grunt.log.errorlns """ - !!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! + rclient.ping(function(err, res) { + if ((err == null)) { + grunt.log.write("OK."); + } else { + throw new Error("Can not connect to redis"); + } + return callback(); + }); + const errorHandler = _.once(function(err){ + err = "Can not connect to redis"; + grunt.log.error("FAIL."); + grunt.log.errorlns(`\ +!!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! - ShareLaTeX can not talk to the redis instance +ShareLaTeX can not talk to the redis instance - Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST +Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - """ - throw new Error("Can not connect to redis") - return callback(err) - rclient.on 'error', errorHandler +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ +` + ); + throw new Error("Can not connect to redis"); + return callback(err); + }); + return rclient.on('error', errorHandler); + } + }; +}; + +function __guard__(value, transform) { + return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; +} diff --git a/server-ce/settings.js b/server-ce/settings.js index 684bf18d53..1d2fc7a018 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -1,576 +1,684 @@ -Path = require('path') +/* + * decaffeinate suggestions: + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl; +let e; +const Path = require('path'); -# These credentials are used for authenticating api requests -# between services that may need to go over public channels -httpAuthUser = "sharelatex" -httpAuthPass = process.env["WEB_API_PASSWORD"] -httpAuthUsers = {} -httpAuthUsers[httpAuthUser] = httpAuthPass +// These credentials are used for authenticating api requests +// between services that may need to go over public channels +const httpAuthUser = "sharelatex"; +const httpAuthPass = process.env["WEB_API_PASSWORD"]; +const httpAuthUsers = {}; +httpAuthUsers[httpAuthUser] = httpAuthPass; -parse = (option)-> - if option? - try - opt = JSON.parse(option) - return opt - catch err - throw new Error("problem parsing #{option}, invalid JSON") +const parse = function(option){ + if (option != null) { + try { + const opt = JSON.parse(option); + return opt; + } catch (err) { + throw new Error(`problem parsing ${option}, invalid JSON`); + } + } +}; -parseIntOrFail = (value)-> - parsedValue = parseInt(value, 10) - if isNaN(parsedValue) - throw new Error("'#{value}' is an invalid integer") - return parsedValue +const parseIntOrFail = function(value){ + const parsedValue = parseInt(value, 10); + if (isNaN(parsedValue)) { + throw new Error(`'${value}' is an invalid integer`); + } + return parsedValue; +}; -DATA_DIR = '/var/lib/sharelatex/data' -TMP_DIR = '/var/lib/sharelatex/tmp' +const DATA_DIR = '/var/lib/sharelatex/data'; +const TMP_DIR = '/var/lib/sharelatex/tmp'; -settings = +const settings = { - clsi: - optimiseInDocker: process.env['OPTIMISE_PDF'] == 'true' + clsi: { + optimiseInDocker: process.env['OPTIMISE_PDF'] === 'true' + }, - brandPrefix: "" + brandPrefix: "", allowAnonymousReadAndWriteSharing: - process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] == 'true' + process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] === 'true', - # Databases - # --------- + // Databases + // --------- - # ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) - # Documentation about the URL connection string format can be found at: - # - # http://docs.mongodb.org/manual/reference/connection-string/ - # - # The following works out of the box with Mongo's default settings: - mongo: - url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://dockerhost/sharelatex' + // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) + // Documentation about the URL connection string format can be found at: + // + // http://docs.mongodb.org/manual/reference/connection-string/ + // + // The following works out of the box with Mongo's default settings: + mongo: { + url : process.env["SHARELATEX_MONGO_URL"] || 'mongodb://dockerhost/sharelatex' + }, - # Redis is used in ShareLaTeX for high volume queries, like real-time - # editing, and session management. - # - # The following config will work with Redis's default settings: - redis: - web: redisConfig = - host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost" - port: process.env["SHARELATEX_REDIS_PORT"] or "6379" - password: process.env["SHARELATEX_REDIS_PASS"] or undefined - key_schema: - # document-updater - blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" - docLines: ({doc_id}) -> "doclines:#{doc_id}" - docOps: ({doc_id}) -> "DocOps:#{doc_id}" - docVersion: ({doc_id}) -> "DocVersion:#{doc_id}" - docHash: ({doc_id}) -> "DocHash:#{doc_id}" - projectKey: ({doc_id}) -> "ProjectId:#{doc_id}" - docsInProject: ({project_id}) -> "DocsIn:#{project_id}" - ranges: ({doc_id}) -> "Ranges:#{doc_id}" - # document-updater:realtime - pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}" - # document-updater:history - uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" - docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" - # document-updater:lock - blockingKey: ({doc_id}) -> "Blocking:#{doc_id}" - # track-changes:lock - historyLock: ({doc_id}) -> "HistoryLock:#{doc_id}" - historyIndexLock: ({project_id}) -> "HistoryIndexLock:#{project_id}" - # track-changes:history - uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}" - docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}" - # realtime - clientsInProject: ({project_id}) -> "clients_in_project:#{project_id}" - connectedUser: ({project_id, client_id})-> "connected_user:#{project_id}:#{client_id}" - fairy: redisConfig - # track-changes and document-updater - realtime: redisConfig - documentupdater: redisConfig - lock: redisConfig - history: redisConfig - websessions: redisConfig - api: redisConfig - pubsub: redisConfig + // Redis is used in ShareLaTeX for high volume queries, like real-time + // editing, and session management. + // + // The following config will work with Redis's default settings: + redis: { + web: (redisConfig = { + host: process.env["SHARELATEX_REDIS_HOST"] || "dockerhost", + port: process.env["SHARELATEX_REDIS_PORT"] || "6379", + password: process.env["SHARELATEX_REDIS_PASS"] || undefined, + key_schema: { + // document-updater + blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, + docLines({doc_id}) { return `doclines:${doc_id}`; }, + docOps({doc_id}) { return `DocOps:${doc_id}`; }, + docVersion({doc_id}) { return `DocVersion:${doc_id}`; }, + docHash({doc_id}) { return `DocHash:${doc_id}`; }, + projectKey({doc_id}) { return `ProjectId:${doc_id}`; }, + docsInProject({project_id}) { return `DocsIn:${project_id}`; }, + ranges({doc_id}) { return `Ranges:${doc_id}`; }, + // document-updater:realtime + pendingUpdates({doc_id}) { return `PendingUpdates:${doc_id}`; }, + // document-updater:history + uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, + docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, + // document-updater:lock + blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, + // track-changes:lock + historyLock({doc_id}) { return `HistoryLock:${doc_id}`; }, + historyIndexLock({project_id}) { return `HistoryIndexLock:${project_id}`; }, + // track-changes:history + uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, + docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, + // realtime + clientsInProject({project_id}) { return `clients_in_project:${project_id}`; }, + connectedUser({project_id, client_id}){ return `connected_user:${project_id}:${client_id}`; } + } + }), + fairy: redisConfig, + // track-changes and document-updater + realtime: redisConfig, + documentupdater: redisConfig, + lock: redisConfig, + history: redisConfig, + websessions: redisConfig, + api: redisConfig, + pubsub: redisConfig, project_history: redisConfig + }, - # The compile server (the clsi) uses a SQL database to cache files and - # meta-data. sqlite is the default, and the load is low enough that this will - # be fine in production (we use sqlite at sharelatex.com). - # - # If you want to configure a different database, see the Sequelize documentation - # for available options: - # - # https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage - # - mysql: - clsi: - database: "clsi" - username: "clsi" - password: "" - dialect: "sqlite" + // The compile server (the clsi) uses a SQL database to cache files and + // meta-data. sqlite is the default, and the load is low enough that this will + // be fine in production (we use sqlite at sharelatex.com). + // + // If you want to configure a different database, see the Sequelize documentation + // for available options: + // + // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + // + mysql: { + clsi: { + database: "clsi", + username: "clsi", + password: "", + dialect: "sqlite", storage: Path.join(DATA_DIR, "db.sqlite") + } + }, - # File storage - # ------------ + // File storage + // ------------ - # ShareLaTeX can store binary files like images either locally or in Amazon - # S3. The default is locally: - filestore: - backend: "fs" - stores: - user_files: Path.join(DATA_DIR, "user_files") + // ShareLaTeX can store binary files like images either locally or in Amazon + // S3. The default is locally: + filestore: { + backend: "fs", + stores: { + user_files: Path.join(DATA_DIR, "user_files"), template_files: Path.join(DATA_DIR, "template_files") + } + }, - # To use Amazon S3 as a storage backend, comment out the above config, and - # uncomment the following, filling in your key, secret, and bucket name: - # - # filestore: - # backend: "s3" - # stores: - # user_files: "BUCKET_NAME" - # s3: - # key: "AWS_KEY" - # secret: "AWS_SECRET" - # + // To use Amazon S3 as a storage backend, comment out the above config, and + // uncomment the following, filling in your key, secret, and bucket name: + // + // filestore: + // backend: "s3" + // stores: + // user_files: "BUCKET_NAME" + // s3: + // key: "AWS_KEY" + // secret: "AWS_SECRET" + // - trackchanges: + trackchanges: { continueOnError: true + }, - # Local disk caching - # ------------------ - path: - # If we ever need to write something to disk (e.g. incoming requests - # that need processing but may be too big for memory), then write - # them to disk here: - dumpFolder: Path.join(TMP_DIR, "dumpFolder") - # Where to write uploads before they are processed - uploadFolder: Path.join(TMP_DIR, "uploads") - # Where to write the project to disk before running LaTeX on it - compilesDir: Path.join(DATA_DIR, "compiles") - # Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.join(DATA_DIR, "cache") - # Where to write the output files to disk after running LaTeX + // Local disk caching + // ------------------ + path: { + // If we ever need to write something to disk (e.g. incoming requests + // that need processing but may be too big for memory), then write + // them to disk here: + dumpFolder: Path.join(TMP_DIR, "dumpFolder"), + // Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, "uploads"), + // Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, "compiles"), + // Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, "cache"), + // Where to write the output files to disk after running LaTeX outputDir: Path.join(DATA_DIR, "output") + }, - # Server Config - # ------------- + // Server Config + // ------------- - # Where your instance of ShareLaTeX can be found publicly. This is used - # when emails are sent out and in generated links: - siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost' + // Where your instance of ShareLaTeX can be found publicly. This is used + // when emails are sent out and in generated links: + siteUrl: (siteUrl = process.env["SHARELATEX_SITE_URL"] || 'http://localhost'), - # The name this is used to describe your ShareLaTeX Installation - appName: process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX (Community Edition)" + // The name this is used to describe your ShareLaTeX Installation + appName: process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX (Community Edition)", - restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] == 'true' + restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] === 'true', - nav: - title: process.env["SHARELATEX_NAV_TITLE"] or process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Community Edition" + nav: { + title: process.env["SHARELATEX_NAV_TITLE"] || process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX Community Edition" + }, - # The email address which users will be directed to as the main point of - # contact for this installation of ShareLaTeX. - adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] or "placeholder@example.com" + // The email address which users will be directed to as the main point of + // contact for this installation of ShareLaTeX. + adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] || "placeholder@example.com", - # If provided, a sessionSecret is used to sign cookies so that they cannot be - # spoofed. This is recommended. - security: - sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or process.env["CRYPTO_RANDOM"] + // If provided, a sessionSecret is used to sign cookies so that they cannot be + // spoofed. This is recommended. + security: { + sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] || process.env["CRYPTO_RANDOM"] + }, - # These credentials are used for authenticating api requests - # between services that may need to go over public channels - httpAuthUsers: httpAuthUsers + // These credentials are used for authenticating api requests + // between services that may need to go over public channels + httpAuthUsers, - # Should javascript assets be served minified or not. - useMinifiedJs: true + // Should javascript assets be served minified or not. + useMinifiedJs: true, - # Should static assets be sent with a header to tell the browser to cache - # them. This should be false in development where changes are being made, - # but should be set to true in production. - cacheStaticAssets: true + // Should static assets be sent with a header to tell the browser to cache + // them. This should be false in development where changes are being made, + // but should be set to true in production. + cacheStaticAssets: true, - # If you are running ShareLaTeX over https, set this to true to send the - # cookie with a secure flag (recommended). - secureCookie: process.env["SHARELATEX_SECURE_COOKIE"]? + // If you are running ShareLaTeX over https, set this to true to send the + // cookie with a secure flag (recommended). + secureCookie: (process.env["SHARELATEX_SECURE_COOKIE"] != null), - # If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) - # then set this to true to allow it to correctly detect the forwarded IP - # address and http/https protocol information. + // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + // then set this to true to allow it to correctly detect the forwarded IP + // address and http/https protocol information. - behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false + behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] || false, - i18n: - subdomainLang: - www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] or "en", url: siteUrl} - defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] or "en" + i18n: { + subdomainLang: { + www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] || "en", url: siteUrl} + }, + defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] || "en" + }, - currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"] + currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"], - apis: - web: - url: "http://localhost:3000" - user: httpAuthUser + apis: { + web: { + url: "http://localhost:3000", + user: httpAuthUser, pass: httpAuthPass - project_history: + }, + project_history: { enabled: false - references:{} - notifications:undefined + } + }, + references:{}, + notifications:undefined, - defaultFeatures: - collaborators: -1 - dropbox: true - versioning: true - compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] or 180) - compileGroup: "standard" - trackChanges: true - templates: true + defaultFeatures: { + collaborators: -1, + dropbox: true, + versioning: true, + compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] || 180), + compileGroup: "standard", + trackChanges: true, + templates: true, references: true + } +}; -## OPTIONAL CONFIGURABLE SETTINGS +//# OPTIONAL CONFIGURABLE SETTINGS -if process.env["SHARELATEX_LEFT_FOOTER"]? - try - settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]) - catch e - console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON") +if (process.env["SHARELATEX_LEFT_FOOTER"] != null) { + try { + settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]); + } catch (error) { + e = error; + console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON"); + } +} -if process.env["SHARELATEX_RIGHT_FOOTER"]? - settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"] - try - settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]) - catch e - console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON") +if (process.env["SHARELATEX_RIGHT_FOOTER"] != null) { + settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"]; + try { + settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]); + } catch (error1) { + e = error1; + console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON"); + } +} -if process.env["SHARELATEX_HEADER_IMAGE_URL"]? - settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"] +if (process.env["SHARELATEX_HEADER_IMAGE_URL"] != null) { + settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"]; +} -if process.env["SHARELATEX_HEADER_NAV_LINKS"]? - console.error """ +if (process.env["SHARELATEX_HEADER_NAV_LINKS"] != null) { + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: SHARELATEX_HEADER_NAV_LINKS is no longer supported # See https://github.com/sharelatex/sharelatex/wiki/Configuring-Headers,-Footers-&-Logo # -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -""" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ +` + ); +} -if process.env["SHARELATEX_HEADER_EXTRAS"]? - try - settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]) - catch e - console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON") +if (process.env["SHARELATEX_HEADER_EXTRAS"] != null) { + try { + settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]); + } catch (error2) { + e = error2; + console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON"); + } +} -# Sending Email -# ------------- -# -# You must configure a mail server to be able to send invite emails from -# ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer -# documentation for available options: -# -# http://www.nodemailer.com/docs/transports +// Sending Email +// ------------- +// +// You must configure a mail server to be able to send invite emails from +// ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer +// documentation for available options: +// +// http://www.nodemailer.com/docs/transports -if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]? +if (process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] != null) { - settings.email = - fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] - replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or "" - driver: process.env["SHARELATEX_EMAIL_DRIVER"] - parameters: - #AWS Creds - AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"] - AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"] + settings.email = { + fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"], + replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] || "", + driver: process.env["SHARELATEX_EMAIL_DRIVER"], + parameters: { + //AWS Creds + AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"], + AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"], - #SMTP Creds - host: process.env["SHARELATEX_EMAIL_SMTP_HOST"] + //SMTP Creds + host: process.env["SHARELATEX_EMAIL_SMTP_HOST"], port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], - secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]) - ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]) - name: process.env["SHARELATEX_EMAIL_SMTP_NAME"] - logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] == 'true' + secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]), + ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]), + name: process.env["SHARELATEX_EMAIL_SMTP_NAME"], + logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] === 'true' + }, - textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"] - template: + textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"], + template: { customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] + } + }; - if process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]? - settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] + if (process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] != null) { + settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]; + } - if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]? - settings.email.parameters.auth = - user: process.env["SHARELATEX_EMAIL_SMTP_USER"] + if ((process.env["SHARELATEX_EMAIL_SMTP_USER"] != null) || (process.env["SHARELATEX_EMAIL_SMTP_PASS"] != null)) { + settings.email.parameters.auth = { + user: process.env["SHARELATEX_EMAIL_SMTP_USER"], pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + }; + } - if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]? + if (process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] != null) { settings.email.parameters.tls = - rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]) + {rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"])}; + } +} -# i18n -if process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]? +// i18n +if (process.env["SHARELATEX_LANG_DOMAIN_MAPPING"] != null) { - settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]) + settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]); +} -# Password Settings -# ----------- -# These restrict the passwords users can use when registering -# opts are from http://antelle.github.io/passfield -if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] +// Password Settings +// ----------- +// These restrict the passwords users can use when registering +// opts are from http://antelle.github.io/passfield +if (process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"]) { - settings.passwordStrengthOptions = - pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or "aA$3" - length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 150} + settings.passwordStrengthOptions = { + pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || "aA$3", + length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] || 150} + }; +} -####################### -# ShareLaTeX Server Pro -####################### +//###################### +// ShareLaTeX Server Pro +//###################### -if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true - settings.bypassPercentageRollouts = true +if (parse(process.env["SHARELATEX_IS_SERVER_PRO"]) === true) { + settings.bypassPercentageRollouts = true; settings.apis.references = - url: "http://localhost:3040" + {url: "http://localhost:3040"}; +} -# LDAP - SERVER PRO ONLY -# ---------- +// LDAP - SERVER PRO ONLY +// ---------- -if process.env["SHARELATEX_LDAP_HOST"] - console.error """ +if (process.env["SHARELATEX_LDAP_HOST"]) { + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: The LDAP configuration format has changed in version 0.5.1 # See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config # -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -""" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ +` + ); +} -if process.env["SHARELATEX_LDAP_URL"] - settings.externalAuth = true - settings.ldap = - emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] - nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"] - lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"] - updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' - placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] - server: - url: process.env["SHARELATEX_LDAP_URL"] - bindDn: process.env["SHARELATEX_LDAP_BIND_DN"] - bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"] - bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"] - searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"] - searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"] - searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"] +if (process.env["SHARELATEX_LDAP_URL"]) { + let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout; + settings.externalAuth = true; + settings.ldap = { + emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"], + nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"], + lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"], + updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', + placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"], + server: { + url: process.env["SHARELATEX_LDAP_URL"], + bindDn: process.env["SHARELATEX_LDAP_BIND_DN"], + bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"], + bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"], + searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"], + searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"], + searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"], searchAttributes: ( - if _ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"] - try - JSON.parse(_ldap_search_attribs) - catch e - console.error "could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES" - else + (_ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"]) ? + (() => { try { + return JSON.parse(_ldap_search_attribs); + } catch (error3) { + e = error3; + return console.error("could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES"); + } })() + : undefined - ) - groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"] - groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"] - groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"] - groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"] + ), + groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"], + groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"], + groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"], + groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"], groupSearchAttributes: ( - if _ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"] - try - JSON.parse(_ldap_group_search_attribs) - catch e - console.error "could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES" - else + (_ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"]) ? + (() => { try { + return JSON.parse(_ldap_group_search_attribs); + } catch (error4) { + e = error4; + return console.error("could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"); + } })() + : undefined - ) - cache: process.env["SHARELATEX_LDAP_CACHE"] == 'true' + ), + cache: process.env["SHARELATEX_LDAP_CACHE"] === 'true', timeout: ( - if _ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"] - try - parseIntOrFail(_ldap_timeout) - catch e - console.error "Cannot parse SHARELATEX_LDAP_TIMEOUT" - else + (_ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"]) ? + (() => { try { + return parseIntOrFail(_ldap_timeout); + } catch (error5) { + e = error5; + return console.error("Cannot parse SHARELATEX_LDAP_TIMEOUT"); + } })() + : undefined - ) + ), connectTimeout: ( - if _ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"] - try - parseIntOrFail(_ldap_connect_timeout) - catch e - console.error "Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT" - else + (_ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"]) ? + (() => { try { + return parseIntOrFail(_ldap_connect_timeout); + } catch (error6) { + e = error6; + return console.error("Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT"); + } })() + : undefined ) + } + }; - if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"] - try - ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) - catch e - console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON" + if (process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) { + let ca, ca_paths; + try { + ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]); + } catch (error7) { + e = error7; + console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"); + } - if typeof(ca) == 'string' - ca_paths = [ca] - else if typeof(ca) == 'object' && ca?.length? - ca_paths = ca - else - console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH" + if (typeof(ca) === 'string') { + ca_paths = [ca]; + } else if ((typeof(ca) === 'object') && ((ca != null ? ca.length : undefined) != null)) { + ca_paths = ca; + } else { + console.error("problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH"); + } - settings.ldap.server.tlsOptions = - rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true" - ca:ca_paths # e.g.'/etc/ldap/ca_certs.pem' + settings.ldap.server.tlsOptions = { + rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] === "true", + ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem' + }; + } +} -if process.env["SHARELATEX_SAML_ENTRYPOINT"] - # NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options - settings.externalAuth = true - settings.saml = - updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true' - identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"] - emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"] - firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"] - lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"] - server: - # strings - entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"] - callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"] - issuer: process.env["SHARELATEX_SAML_ISSUER"] - decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"] - decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"] - signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"] - identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"] - attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"] - authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"] - authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"] - validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"] - cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"] - logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"] - logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"] - disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] == 'true' - forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] == 'true' - skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] == 'true' +if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { + // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options + let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew; + settings.externalAuth = true; + settings.saml = { + updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', + identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"], + emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"], + firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"], + lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"], + server: { + // strings + entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"], + callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"], + issuer: process.env["SHARELATEX_SAML_ISSUER"], + decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"], + decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"], + signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"], + identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"], + attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"], + authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"], + authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"], + validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"], + cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"], + logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"], + logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"], + disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] === 'true', + forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] === 'true', + skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] === 'true', acceptedClockSkewMs: ( - if _saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"] - try - parseIntOrFail(_saml_skew) - catch e - console.error "Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS" - else + (_saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"]) ? + (() => { try { + return parseIntOrFail(_saml_skew); + } catch (error8) { + e = error8; + return console.error("Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"); + } })() + : undefined - ) + ), requestIdExpirationPeriodMs: ( - if _saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"] - try - parseIntOrFail(_saml_expiration) - catch e - console.error "Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS" - else + (_saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"]) ? + (() => { try { + return parseIntOrFail(_saml_expiration); + } catch (error9) { + e = error9; + return console.error("Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"); + } })() + : undefined - ) + ), additionalParams: ( - if _saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"] - try - JSON.parse(_saml_additionalParams) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS" - else + (_saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"]) ? + (() => { try { + return JSON.parse(_saml_additionalParams); + } catch (error10) { + e = error10; + return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS"); + } })() + : undefined - ) + ), additionalAuthorizeParams: ( - if _saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"] - try - JSON.parse(_saml_additionalAuthorizeParams ) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS" - else + (_saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"]) ? + (() => { try { + return JSON.parse(_saml_additionalAuthorizeParams ); + } catch (error11) { + e = error11; + return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"); + } })() + : undefined - ) + ), additionalLogoutParams: ( - if _saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"] - try - JSON.parse(_saml_additionalLogoutParams ) - catch e - console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS" - else + (_saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"]) ? + (() => { try { + return JSON.parse(_saml_additionalLogoutParams ); + } catch (error12) { + e = error12; + return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"); + } })() + : undefined ) + } + }; - # SHARELATEX_SAML_CERT cannot be empty - # https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 - if process.env["SHARELATEX_SAML_CERT"] - settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"] - settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"] + // SHARELATEX_SAML_CERT cannot be empty + // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + if (process.env["SHARELATEX_SAML_CERT"]) { + settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"]; + settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"]; + } +} -# Compiler -# -------- -if process.env["SANDBOXED_COMPILES"] == "true" - settings.clsi = - dockerRunner: true - docker: - image: process.env["TEX_LIVE_DOCKER_IMAGE"] - env: - HOME: "/tmp" - PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +// Compiler +// -------- +if (process.env["SANDBOXED_COMPILES"] === "true") { + settings.clsi = { + dockerRunner: true, + docker: { + image: process.env["TEX_LIVE_DOCKER_IMAGE"], + env: { + HOME: "/tmp", + PATH: process.env["COMPILER_PATH"] || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + }, user: "www-data" + } + }; - if !settings.path? - settings.path = {} - settings.path.synctexBaseDir = () -> "/compile" - if process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] == 'true' - console.log("Using sibling containers for sandboxed compiles") - if process.env['SANDBOXED_COMPILES_HOST_DIR'] - settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR'] - else - console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set') + if ((settings.path == null)) { + settings.path = {}; + } + settings.path.synctexBaseDir = () => "/compile"; + if (process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] === 'true') { + console.log("Using sibling containers for sandboxed compiles"); + if (process.env['SANDBOXED_COMPILES_HOST_DIR']) { + settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR']; + } else { + console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set'); + } + } +} -# Templates -# --------- -if process.env["SHARELATEX_TEMPLATES_USER_ID"] - settings.templates = - mountPointUrl: "/templates" +// Templates +// --------- +if (process.env["SHARELATEX_TEMPLATES_USER_ID"]) { + settings.templates = { + mountPointUrl: "/templates", user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + }; - settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]) + settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]); +} -# /Learn -# ------- -if process.env["SHARELATEX_PROXY_LEARN"]? - settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]) +// /Learn +// ------- +if (process.env["SHARELATEX_PROXY_LEARN"] != null) { + settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]); +} -# /References -# ----------- -if process.env["SHARELATEX_ELASTICSEARCH_URL"]? +// /References +// ----------- +if (process.env["SHARELATEX_ELASTICSEARCH_URL"] != null) { settings.references.elasticsearch = - host: process.env["SHARELATEX_ELASTICSEARCH_URL"] + {host: process.env["SHARELATEX_ELASTICSEARCH_URL"]}; +} -# TeX Live Images -# ----------- -if process.env["ALL_TEX_LIVE_DOCKER_IMAGES"]? - allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(',') -if process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"]? - allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(',') -if allTexLiveDockerImages? - settings.allowedImageNames = [] - for fullImageName, index in allTexLiveDockerImages - imageName = Path.basename(fullImageName) - imageDesc = if allTexLiveDockerImageNames? then allTexLiveDockerImageNames[index] else imageName - settings.allowedImageNames.push({ imageName, imageDesc }) +// TeX Live Images +// ----------- +if (process.env["ALL_TEX_LIVE_DOCKER_IMAGES"] != null) { + allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(','); +} +if (process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"] != null) { + allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(','); +} +if (allTexLiveDockerImages != null) { + settings.allowedImageNames = []; + for (let index = 0; index < allTexLiveDockerImages.length; index++) { + const fullImageName = allTexLiveDockerImages[index]; + const imageName = Path.basename(fullImageName); + const imageDesc = (allTexLiveDockerImageNames != null) ? allTexLiveDockerImageNames[index] : imageName; + settings.allowedImageNames.push({ imageName, imageDesc }); + } +} -# With lots of incoming and outgoing HTTP connections to different services, -# sometimes long running, it is a good idea to increase the default number -# of sockets that Node will hold open. -http = require('http') -http.globalAgent.maxSockets = 300 -https = require('https') -https.globalAgent.maxSockets = 300 +// With lots of incoming and outgoing HTTP connections to different services, +// sometimes long running, it is a good idea to increase the default number +// of sockets that Node will hold open. +const http = require('http'); +http.globalAgent.maxSockets = 300; +const https = require('https'); +https.globalAgent.maxSockets = 300; -module.exports = settings +module.exports = settings; diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index 79da259c67..cff38d35be 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -1,60 +1,79 @@ +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ -module.exports = (grunt) -> +module.exports = function(grunt) { - grunt.registerTask 'user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", () -> - done = @async() - email = grunt.option("email") - if !email? - console.error "Usage: grunt user:create-admin --email=joe@example.com" - process.exit(1) + grunt.registerTask('user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", function() { + const done = this.async(); + const email = grunt.option("email"); + if ((email == null)) { + console.error("Usage: grunt user:create-admin --email=joe@example.com"); + process.exit(1); + } - settings = require "settings-sharelatex" - mongodb = require "../web/app/src/infrastructure/mongodb" - UserRegistrationHandler = require "../web/app/src/Features/User/UserRegistrationHandler" - OneTimeTokenHandler = require "../web/app/src/Features/Security/OneTimeTokenHandler" - mongodb.waitForDb().then () -> - UserRegistrationHandler.registerNewUser { - email: email - password: require("crypto").randomBytes(32).toString("hex") - }, (error, user) -> - if error? and error?.message != "EmailAlreadyRegistered" - throw error - user.isAdmin = true - user.save (error) -> - throw error if error? - ONE_WEEK = 7 * 24 * 60 * 60 # seconds - OneTimeTokenHandler.getNewToken "password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, (err, token)-> - return next(err) if err? + const settings = require("settings-sharelatex"); + const mongodb = require("../web/app/src/infrastructure/mongodb"); + const UserRegistrationHandler = require("../web/app/src/Features/User/UserRegistrationHandler"); + const OneTimeTokenHandler = require("../web/app/src/Features/Security/OneTimeTokenHandler"); + return mongodb.waitForDb().then(() => UserRegistrationHandler.registerNewUser({ + email, + password: require("crypto").randomBytes(32).toString("hex") + }, function(error, user) { + if ((error != null) && ((error != null ? error.message : undefined) !== "EmailAlreadyRegistered")) { + throw error; + } + user.isAdmin = true; + return user.save(function(error) { + if (error != null) { throw error; } + const ONE_WEEK = 7 * 24 * 60 * 60; // seconds + return OneTimeTokenHandler.getNewToken("password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, function(err, token){ + if (err != null) { return next(err); } - console.log "" - console.log """ - Successfully created #{email} as an admin user. + console.log(""); + console.log(`\ +Successfully created ${email} as an admin user. - Please visit the following URL to set a password for #{email} and log in: +Please visit the following URL to set a password for ${email} and log in: - #{settings.siteUrl}/user/password/set?passwordResetToken=#{token} +${settings.siteUrl}/user/password/set?passwordResetToken=${token} +\ +` + ); + return done(); + }); + }); + })); + }); - """ - done() - - grunt.registerTask 'user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", () -> - done = @async() - email = grunt.option("email") - if !email? - console.error "Usage: grunt user:delete --email=joe@example.com" - process.exit(1) - settings = require "settings-sharelatex" - mongodb = require "../web/app/src/infrastructure/mongodb" - UserGetter = require "../web/app/src/Features/User/UserGetter" - UserDeleter = require "../web/app/src/Features/User/UserDeleter" - mongodb.waitForDb().then () -> - UserGetter.getUser email:email, (error, user) -> - if error? - throw error - if !user? - console.log("user #{email} not in database, potentially already deleted") - return done() - UserDeleter.deleteUser user._id, (err)-> - if err? - throw err - done() + return grunt.registerTask('user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", function() { + const done = this.async(); + const email = grunt.option("email"); + if ((email == null)) { + console.error("Usage: grunt user:delete --email=joe@example.com"); + process.exit(1); + } + const settings = require("settings-sharelatex"); + const mongodb = require("../web/app/src/infrastructure/mongodb"); + const UserGetter = require("../web/app/src/Features/User/UserGetter"); + const UserDeleter = require("../web/app/src/Features/User/UserDeleter"); + return mongodb.waitForDb().then(() => UserGetter.getUser({email}, function(error, user) { + if (error != null) { + throw error; + } + if ((user == null)) { + console.log(`user ${email} not in database, potentially already deleted`); + return done(); + } + return UserDeleter.deleteUser(user._id, function(err){ + if (err != null) { + throw err; + } + return done(); + }); + })); + }); +}; diff --git a/server-ce/tasks/ProjectSize.js b/server-ce/tasks/ProjectSize.js index 1d02d33d26..77565724cd 100644 --- a/server-ce/tasks/ProjectSize.js +++ b/server-ce/tasks/ProjectSize.js @@ -1,24 +1,24 @@ -# require("coffee-script") +// require("coffee-script") -# fs = require("fs") -# _ = require("underscore") +// fs = require("fs") +// _ = require("underscore") -# if not process.argv[2] -# console.log "Usage: coffee project_size.coffee user_files_path" -# else -# dirPath = process.argv[2] -# if not fs.lstatSync(dirPath).isDirectory() -# console.log dirPath + " directory not exist" -# else -# fs.readdir dirPath, (err, files)-> -# projects = [] -# files.forEach (file)-> -# project_id = file.split("_")[0] -# if !projects[project_id] -# projects[project_id] = 0 -# projects[project_id] += fs.lstatSync(dirPath+"/"+file).size +// if not process.argv[2] +// console.log "Usage: coffee project_size.coffee user_files_path" +// else +// dirPath = process.argv[2] +// if not fs.lstatSync(dirPath).isDirectory() +// console.log dirPath + " directory not exist" +// else +// fs.readdir dirPath, (err, files)-> +// projects = [] +// files.forEach (file)-> +// project_id = file.split("_")[0] +// if !projects[project_id] +// projects[project_id] = 0 +// projects[project_id] += fs.lstatSync(dirPath+"/"+file).size -# ids = _.keys projects -# console.log "project \t size" -# ids.forEach (id)-> -# console.log id + "\t" + projects[id] +// ids = _.keys projects +// console.log "project \t size" +// ids.forEach (id)-> +// console.log id + "\t" + projects[id] From d812c86c517ccfcd3494486b0cb769451528d2c2 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 7 Jul 2021 11:39:45 +0000 Subject: [PATCH 04/11] decaffeinate: Run post-processing cleanups on coffee files --- server-ce/Gruntfile.js | 9 + server-ce/settings.js | 278 ++++++++++++----------- server-ce/tasks/CreateAndDestroyUsers.js | 6 + server-ce/tasks/ProjectSize.js | 2 + 4 files changed, 160 insertions(+), 135 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index a1173ed864..bee096789c 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -1,3 +1,12 @@ +/* eslint-disable + camelcase, + no-return-assign, + no-unreachable, + no-unused-vars, + node/handle-callback-err, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from diff --git a/server-ce/settings.js b/server-ce/settings.js index 1d2fc7a018..09d21d0015 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -1,3 +1,11 @@ +/* eslint-disable + camelcase, + no-cond-assign, + no-dupe-keys, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS205: Consider reworking code to avoid use of IIFEs @@ -11,7 +19,7 @@ const Path = require('path'); // These credentials are used for authenticating api requests // between services that may need to go over public channels const httpAuthUser = "sharelatex"; -const httpAuthPass = process.env["WEB_API_PASSWORD"]; +const httpAuthPass = process.env.WEB_API_PASSWORD; const httpAuthUsers = {}; httpAuthUsers[httpAuthUser] = httpAuthPass; @@ -40,13 +48,13 @@ const TMP_DIR = '/var/lib/sharelatex/tmp'; const settings = { clsi: { - optimiseInDocker: process.env['OPTIMISE_PDF'] === 'true' + optimiseInDocker: process.env.OPTIMISE_PDF === 'true' }, brandPrefix: "", allowAnonymousReadAndWriteSharing: - process.env['SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING'] === 'true', + process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true', // Databases // --------- @@ -58,7 +66,7 @@ const settings = { // // The following works out of the box with Mongo's default settings: mongo: { - url : process.env["SHARELATEX_MONGO_URL"] || 'mongodb://dockerhost/sharelatex' + url : process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex' }, // Redis is used in ShareLaTeX for high volume queries, like real-time @@ -67,9 +75,9 @@ const settings = { // The following config will work with Redis's default settings: redis: { web: (redisConfig = { - host: process.env["SHARELATEX_REDIS_HOST"] || "dockerhost", - port: process.env["SHARELATEX_REDIS_PORT"] || "6379", - password: process.env["SHARELATEX_REDIS_PASS"] || undefined, + host: process.env.SHARELATEX_REDIS_HOST || "dockerhost", + port: process.env.SHARELATEX_REDIS_PORT || "6379", + password: process.env.SHARELATEX_REDIS_PASS || undefined, key_schema: { // document-updater blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, @@ -180,26 +188,26 @@ const settings = { // Where your instance of ShareLaTeX can be found publicly. This is used // when emails are sent out and in generated links: - siteUrl: (siteUrl = process.env["SHARELATEX_SITE_URL"] || 'http://localhost'), + siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'), // The name this is used to describe your ShareLaTeX Installation - appName: process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX (Community Edition)", + appName: process.env.SHARELATEX_APP_NAME || "ShareLaTeX (Community Edition)", - restrictInvitesToExistingAccounts: process.env["SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS"] === 'true', + restrictInvitesToExistingAccounts: process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true', nav: { - title: process.env["SHARELATEX_NAV_TITLE"] || process.env["SHARELATEX_APP_NAME"] || "ShareLaTeX Community Edition" + title: process.env.SHARELATEX_NAV_TITLE || process.env.SHARELATEX_APP_NAME || "ShareLaTeX Community Edition" }, // The email address which users will be directed to as the main point of // contact for this installation of ShareLaTeX. - adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] || "placeholder@example.com", + adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || "placeholder@example.com", // If provided, a sessionSecret is used to sign cookies so that they cannot be // spoofed. This is recommended. security: { - sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] || process.env["CRYPTO_RANDOM"] + sessionSecret: process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM }, // These credentials are used for authenticating api requests @@ -216,22 +224,22 @@ const settings = { // If you are running ShareLaTeX over https, set this to true to send the // cookie with a secure flag (recommended). - secureCookie: (process.env["SHARELATEX_SECURE_COOKIE"] != null), + secureCookie: (process.env.SHARELATEX_SECURE_COOKIE != null), // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) // then set this to true to allow it to correctly detect the forwarded IP // address and http/https protocol information. - behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] || false, + behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false, i18n: { subdomainLang: { - www: {lngCode:process.env["SHARELATEX_SITE_LANGUAGE"] || "en", url: siteUrl} + www: {lngCode:process.env.SHARELATEX_SITE_LANGUAGE || "en", url: siteUrl} }, - defaultLng: process.env["SHARELATEX_SITE_LANGUAGE"] || "en" + defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || "en" }, - currentImageName: process.env["TEX_LIVE_DOCKER_IMAGE"], + currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE, apis: { web: { @@ -250,7 +258,7 @@ const settings = { collaborators: -1, dropbox: true, versioning: true, - compileTimeout: parseIntOrFail(process.env["COMPILE_TIMEOUT"] || 180), + compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180), compileGroup: "standard", trackChanges: true, templates: true, @@ -258,32 +266,32 @@ const settings = { } }; -//# OPTIONAL CONFIGURABLE SETTINGS +// # OPTIONAL CONFIGURABLE SETTINGS -if (process.env["SHARELATEX_LEFT_FOOTER"] != null) { +if (process.env.SHARELATEX_LEFT_FOOTER != null) { try { - settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"]); + settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER); } catch (error) { e = error; console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON"); } } -if (process.env["SHARELATEX_RIGHT_FOOTER"] != null) { - settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"]; +if (process.env.SHARELATEX_RIGHT_FOOTER != null) { + settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER; try { - settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"]); + settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER); } catch (error1) { e = error1; console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON"); } } -if (process.env["SHARELATEX_HEADER_IMAGE_URL"] != null) { - settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"]; +if (process.env.SHARELATEX_HEADER_IMAGE_URL != null) { + settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL; } -if (process.env["SHARELATEX_HEADER_NAV_LINKS"] != null) { +if (process.env.SHARELATEX_HEADER_NAV_LINKS != null) { console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @@ -295,9 +303,9 @@ if (process.env["SHARELATEX_HEADER_NAV_LINKS"] != null) { ); } -if (process.env["SHARELATEX_HEADER_EXTRAS"] != null) { +if (process.env.SHARELATEX_HEADER_EXTRAS != null) { try { - settings.nav.header_extras = JSON.parse(process.env["SHARELATEX_HEADER_EXTRAS"]); + settings.nav.header_extras = JSON.parse(process.env.SHARELATEX_HEADER_EXTRAS); } catch (error2) { e = error2; console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON"); @@ -316,76 +324,76 @@ if (process.env["SHARELATEX_HEADER_EXTRAS"] != null) { // http://www.nodemailer.com/docs/transports -if (process.env["SHARELATEX_EMAIL_FROM_ADDRESS"] != null) { +if (process.env.SHARELATEX_EMAIL_FROM_ADDRESS != null) { settings.email = { - fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"], - replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] || "", - driver: process.env["SHARELATEX_EMAIL_DRIVER"], + fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS, + replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || "", + driver: process.env.SHARELATEX_EMAIL_DRIVER, parameters: { - //AWS Creds - AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"], - AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"], + // AWS Creds + AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID, + AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY, - //SMTP Creds - host: process.env["SHARELATEX_EMAIL_SMTP_HOST"], - port: process.env["SHARELATEX_EMAIL_SMTP_PORT"], - secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"]), - ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"]), - name: process.env["SHARELATEX_EMAIL_SMTP_NAME"], - logger: process.env["SHARELATEX_EMAIL_SMTP_LOGGER"] === 'true' + // SMTP Creds + host: process.env.SHARELATEX_EMAIL_SMTP_HOST, + port: process.env.SHARELATEX_EMAIL_SMTP_PORT, + secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE), + ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS), + name: process.env.SHARELATEX_EMAIL_SMTP_NAME, + logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true' }, - textEncoding: process.env["SHARELATEX_EMAIL_TEXT_ENCODING"], + textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING, template: { - customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"] + customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER } }; - if (process.env["SHARELATEX_EMAIL_AWS_SES_REGION"] != null) { - settings.email.parameters.region = process.env["SHARELATEX_EMAIL_AWS_SES_REGION"]; + if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) { + settings.email.parameters.region = process.env.SHARELATEX_EMAIL_AWS_SES_REGION; } - if ((process.env["SHARELATEX_EMAIL_SMTP_USER"] != null) || (process.env["SHARELATEX_EMAIL_SMTP_PASS"] != null)) { + if ((process.env.SHARELATEX_EMAIL_SMTP_USER != null) || (process.env.SHARELATEX_EMAIL_SMTP_PASS != null)) { settings.email.parameters.auth = { - user: process.env["SHARELATEX_EMAIL_SMTP_USER"], - pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"] + user: process.env.SHARELATEX_EMAIL_SMTP_USER, + pass: process.env.SHARELATEX_EMAIL_SMTP_PASS }; } - if (process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"] != null) { + if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) { settings.email.parameters.tls = - {rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"])}; + {rejectUnauthorized: parse(process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH)}; } } // i18n -if (process.env["SHARELATEX_LANG_DOMAIN_MAPPING"] != null) { +if (process.env.SHARELATEX_LANG_DOMAIN_MAPPING != null) { - settings.i18n.subdomainLang = parse(process.env["SHARELATEX_LANG_DOMAIN_MAPPING"]); + settings.i18n.subdomainLang = parse(process.env.SHARELATEX_LANG_DOMAIN_MAPPING); } // Password Settings // ----------- // These restrict the passwords users can use when registering // opts are from http://antelle.github.io/passfield -if (process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"]) { +if (process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH) { settings.passwordStrengthOptions = { - pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] || "aA$3", - length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] || 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] || 150} + pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || "aA$3", + length: {min:process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150} }; } -//###################### +// ###################### // ShareLaTeX Server Pro -//###################### +// ###################### -if (parse(process.env["SHARELATEX_IS_SERVER_PRO"]) === true) { +if (parse(process.env.SHARELATEX_IS_SERVER_PRO) === true) { settings.bypassPercentageRollouts = true; settings.apis.references = {url: "http://localhost:3040"}; @@ -395,7 +403,7 @@ if (parse(process.env["SHARELATEX_IS_SERVER_PRO"]) === true) { // LDAP - SERVER PRO ONLY // ---------- -if (process.env["SHARELATEX_LDAP_HOST"]) { +if (process.env.SHARELATEX_LDAP_HOST) { console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @@ -407,25 +415,25 @@ if (process.env["SHARELATEX_LDAP_HOST"]) { ); } -if (process.env["SHARELATEX_LDAP_URL"]) { +if (process.env.SHARELATEX_LDAP_URL) { let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout; settings.externalAuth = true; settings.ldap = { - emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"], - nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"], - lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"], - updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', - placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"], + emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT, + nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT, + lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT, + updateUserDetailsOnLogin: process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER, server: { - url: process.env["SHARELATEX_LDAP_URL"], - bindDn: process.env["SHARELATEX_LDAP_BIND_DN"], - bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"], - bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"], - searchBase: process.env["SHARELATEX_LDAP_SEARCH_BASE"], - searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"], - searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"], + url: process.env.SHARELATEX_LDAP_URL, + bindDn: process.env.SHARELATEX_LDAP_BIND_DN, + bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS, + bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY, + searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE, + searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE, + searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER, searchAttributes: ( - (_ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"]) ? + (_ldap_search_attribs = process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) ? (() => { try { return JSON.parse(_ldap_search_attribs); } catch (error3) { @@ -435,12 +443,12 @@ if (process.env["SHARELATEX_LDAP_URL"]) { : undefined ), - groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"], - groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"], - groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"], - groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"], + groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY, + groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE, + groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE, + groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER, groupSearchAttributes: ( - (_ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"]) ? + (_ldap_group_search_attribs = process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) ? (() => { try { return JSON.parse(_ldap_group_search_attribs); } catch (error4) { @@ -450,9 +458,9 @@ if (process.env["SHARELATEX_LDAP_URL"]) { : undefined ), - cache: process.env["SHARELATEX_LDAP_CACHE"] === 'true', + cache: process.env.SHARELATEX_LDAP_CACHE === 'true', timeout: ( - (_ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"]) ? + (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) ? (() => { try { return parseIntOrFail(_ldap_timeout); } catch (error5) { @@ -463,7 +471,7 @@ if (process.env["SHARELATEX_LDAP_URL"]) { undefined ), connectTimeout: ( - (_ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"]) ? + (_ldap_connect_timeout = process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) ? (() => { try { return parseIntOrFail(_ldap_connect_timeout); } catch (error6) { @@ -476,10 +484,10 @@ if (process.env["SHARELATEX_LDAP_URL"]) { } }; - if (process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]) { + if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) { let ca, ca_paths; try { - ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]); + ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH); } catch (error7) { e = error7; console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"); @@ -494,7 +502,7 @@ if (process.env["SHARELATEX_LDAP_URL"]) { } settings.ldap.server.tlsOptions = { - rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] === "true", + rejectUnauthorized: process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === "true", ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem' }; } @@ -504,37 +512,37 @@ if (process.env["SHARELATEX_LDAP_URL"]) { -if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { +if (process.env.SHARELATEX_SAML_ENTRYPOINT) { // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew; settings.externalAuth = true; settings.saml = { - updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] === 'true', - identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"], - emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"], - firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"], - lastNameField: process.env["SHARELATEX_SAML_LAST_NAME_FIELD"], + updateUserDetailsOnLogin: process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME, + emailField: process.env.SHARELATEX_SAML_EMAIL_FIELD || process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME, + firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD, + lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD, server: { // strings - entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"], - callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"], - issuer: process.env["SHARELATEX_SAML_ISSUER"], - decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"], - decryptionCert: process.env["SHARELATEX_SAML_DECRYPTION_CERT"], - signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"], - identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"], - attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"], - authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"], - authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"], - validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"], - cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"], - logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"], - logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"], - disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] === 'true', - forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] === 'true', - skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] === 'true', + entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT, + callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL, + issuer: process.env.SHARELATEX_SAML_ISSUER, + decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK, + decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT, + signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM, + identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT, + attributeConsumingServiceIndex: process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX, + authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT, + authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING, + validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO, + cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER, + logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL, + logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL, + disableRequestedAuthnContext: process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true', + forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true', + skipRequestCompression: process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true', acceptedClockSkewMs: ( - (_saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"]) ? + (_saml_skew = process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) ? (() => { try { return parseIntOrFail(_saml_skew); } catch (error8) { @@ -545,7 +553,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), requestIdExpirationPeriodMs: ( - (_saml_expiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"]) ? + (_saml_expiration = process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) ? (() => { try { return parseIntOrFail(_saml_expiration); } catch (error9) { @@ -556,7 +564,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), additionalParams: ( - (_saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"]) ? + (_saml_additionalParams = process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) ? (() => { try { return JSON.parse(_saml_additionalParams); } catch (error10) { @@ -567,7 +575,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), additionalAuthorizeParams: ( - (_saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"]) ? + (_saml_additionalAuthorizeParams = process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) ? (() => { try { return JSON.parse(_saml_additionalAuthorizeParams ); } catch (error11) { @@ -578,7 +586,7 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { undefined ), additionalLogoutParams: ( - (_saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"]) ? + (_saml_additionalLogoutParams = process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) ? (() => { try { return JSON.parse(_saml_additionalLogoutParams ); } catch (error12) { @@ -593,22 +601,22 @@ if (process.env["SHARELATEX_SAML_ENTRYPOINT"]) { // SHARELATEX_SAML_CERT cannot be empty // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 - if (process.env["SHARELATEX_SAML_CERT"]) { - settings.saml.server.cert = process.env["SHARELATEX_SAML_CERT"]; - settings.saml.server.privateCert = process.env["SHARELATEX_SAML_PRIVATE_CERT"]; + if (process.env.SHARELATEX_SAML_CERT) { + settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT; + settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT; } } // Compiler // -------- -if (process.env["SANDBOXED_COMPILES"] === "true") { +if (process.env.SANDBOXED_COMPILES === "true") { settings.clsi = { dockerRunner: true, docker: { - image: process.env["TEX_LIVE_DOCKER_IMAGE"], + image: process.env.TEX_LIVE_DOCKER_IMAGE, env: { HOME: "/tmp", - PATH: process.env["COMPILER_PATH"] || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + PATH: process.env.COMPILER_PATH || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }, user: "www-data" } @@ -618,10 +626,10 @@ if (process.env["SANDBOXED_COMPILES"] === "true") { settings.path = {}; } settings.path.synctexBaseDir = () => "/compile"; - if (process.env['SANDBOXED_COMPILES_SIBLING_CONTAINERS'] === 'true') { + if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') { console.log("Using sibling containers for sandboxed compiles"); - if (process.env['SANDBOXED_COMPILES_HOST_DIR']) { - settings.path.sandboxedCompilesHostDir = process.env['SANDBOXED_COMPILES_HOST_DIR']; + if (process.env.SANDBOXED_COMPILES_HOST_DIR) { + settings.path.sandboxedCompilesHostDir = process.env.SANDBOXED_COMPILES_HOST_DIR; } else { console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set'); } @@ -631,37 +639,37 @@ if (process.env["SANDBOXED_COMPILES"] === "true") { // Templates // --------- -if (process.env["SHARELATEX_TEMPLATES_USER_ID"]) { +if (process.env.SHARELATEX_TEMPLATES_USER_ID) { settings.templates = { mountPointUrl: "/templates", - user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"] + user_id: process.env.SHARELATEX_TEMPLATES_USER_ID }; - settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"]); + settings.templateLinks = parse(process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS); } // /Learn // ------- -if (process.env["SHARELATEX_PROXY_LEARN"] != null) { - settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"]); +if (process.env.SHARELATEX_PROXY_LEARN != null) { + settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN); } // /References // ----------- -if (process.env["SHARELATEX_ELASTICSEARCH_URL"] != null) { +if (process.env.SHARELATEX_ELASTICSEARCH_URL != null) { settings.references.elasticsearch = - {host: process.env["SHARELATEX_ELASTICSEARCH_URL"]}; + {host: process.env.SHARELATEX_ELASTICSEARCH_URL}; } // TeX Live Images // ----------- -if (process.env["ALL_TEX_LIVE_DOCKER_IMAGES"] != null) { - allTexLiveDockerImages = process.env["ALL_TEX_LIVE_DOCKER_IMAGES"].split(','); +if (process.env.ALL_TEX_LIVE_DOCKER_IMAGES != null) { + allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(','); } -if (process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"] != null) { - allTexLiveDockerImageNames = process.env["ALL_TEX_LIVE_DOCKER_IMAGE_NAMES"].split(','); +if (process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES != null) { + allTexLiveDockerImageNames = process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(','); } if (allTexLiveDockerImages != null) { settings.allowedImageNames = []; diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index cff38d35be..9417396b73 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -1,3 +1,9 @@ +/* eslint-disable + no-undef, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns diff --git a/server-ce/tasks/ProjectSize.js b/server-ce/tasks/ProjectSize.js index 77565724cd..5e663f5b2c 100644 --- a/server-ce/tasks/ProjectSize.js +++ b/server-ce/tasks/ProjectSize.js @@ -1,3 +1,5 @@ +// TODO: This file was created by bulk-decaffeinate. +// Sanity-check the conversion and remove this comment. // require("coffee-script") // fs = require("fs") From d7c641eaf7f9e67df9c8aa024e664a8bf53ece95 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:43:33 +0100 Subject: [PATCH 05/11] [misc] run format:fix --- server-ce/Gruntfile.js | 537 +++++----- server-ce/settings.js | 1142 ++++++++++++---------- server-ce/tasks/CreateAndDestroyUsers.js | 153 +-- 3 files changed, 993 insertions(+), 839 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index bee096789c..9cee93ccb6 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -16,254 +16,292 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const coffee = require("coffee-script"); -const fs = require("fs"); -const { - spawn -} = require("child_process"); -const { - exec -} = require("child_process"); -const rimraf = require("rimraf"); -const Path = require("path"); -const semver = require("semver"); -const knox = require("knox"); -const crypto = require("crypto"); -const async = require("async"); -const settings = require("settings-sharelatex"); -const _ = require("underscore"); +const coffee = require('coffee-script') +const fs = require('fs') +const { spawn } = require('child_process') +const { exec } = require('child_process') +const rimraf = require('rimraf') +const Path = require('path') +const semver = require('semver') +const knox = require('knox') +const crypto = require('crypto') +const async = require('async') +const settings = require('settings-sharelatex') +const _ = require('underscore') +const SERVICES = require('./config/services') -const SERVICES = require("./config/services"); +module.exports = function (grunt) { + let Helpers + let service + grunt.loadNpmTasks('grunt-bunyan') + grunt.loadNpmTasks('grunt-execute') + grunt.loadNpmTasks('grunt-available-tasks') + grunt.loadNpmTasks('grunt-concurrent') + grunt.loadNpmTasks('grunt-contrib-coffee') + grunt.loadNpmTasks('grunt-shell') -module.exports = function(grunt) { - let Helpers; - let service; - grunt.loadNpmTasks('grunt-bunyan'); - grunt.loadNpmTasks('grunt-execute'); - grunt.loadNpmTasks('grunt-available-tasks'); - grunt.loadNpmTasks('grunt-concurrent'); - grunt.loadNpmTasks("grunt-contrib-coffee"); - grunt.loadNpmTasks("grunt-shell"); + grunt.task.loadTasks('./tasks') - grunt.task.loadTasks("./tasks"); + const execute = {} + for (service of Array.from(SERVICES)) { + execute[service.name] = { src: `${service.name}/app.js` } + } - const execute = {}; - for (service of Array.from(SERVICES)) { - execute[service.name] = - {src: `${service.name}/app.js`}; - } + grunt.initConfig({ + execute, - grunt.initConfig({ - execute, + concurrent: { + all: { + tasks: (() => { + const result = [] + for (service of Array.from(SERVICES)) { + result.push(`run:${service.name}`) + } + return result + })(), + options: { + limit: SERVICES.length, + logConcurrentOutput: true, + }, + }, + }, - concurrent: { - all: { - tasks: (((() => { - const result = []; - for (service of Array.from(SERVICES)) { result.push(`run:${service.name}`); - } - return result; - })())), - options: { - limit: SERVICES.length, - logConcurrentOutput: true + availabletasks: { + tasks: { + options: { + filter: 'exclude', + tasks: ['concurrent', 'execute', 'bunyan', 'availabletasks'], + groups: { + 'Run tasks': ['run', 'run:all', 'default'].concat( + (() => { + const result1 = [] + for (service of Array.from(SERVICES)) { + result1.push(`run:${service.name}`) + } + return result1 + })() + ), + Misc: ['help'], + 'Install tasks': (() => { + const result2 = [] + for (service of Array.from(SERVICES)) { + result2.push(`install:${service.name}`) + } + return result2 + })().concat(['install:all', 'install']), + 'Update tasks': (() => { + const result3 = [] + for (service of Array.from(SERVICES)) { + result3.push(`update:${service.name}`) + } + return result3 + })().concat(['update:all', 'update']), + Checks: [ + 'check', + 'check:redis', + 'check:latexmk', + 'check:s3', + 'check:make', + 'check:mongo', + ], + }, + }, + }, + }, + }) - availabletasks: { - tasks: { - options: { - filter: 'exclude', - tasks: [ - 'concurrent', - 'execute', - 'bunyan', - 'availabletasks' - ], - groups: { - "Run tasks": [ - "run", - "run:all", - "default" - ].concat(((() => { - const result1 = []; - for (service of Array.from(SERVICES)) { result1.push(`run:${service.name}`); - } - return result1; - })())), - "Misc": [ - "help" - ], - "Install tasks": ((() => { - const result2 = []; - for (service of Array.from(SERVICES)) { result2.push(`install:${service.name}`); - } - return result2; - })()).concat(["install:all", "install"]), - "Update tasks": ((() => { - const result3 = []; - for (service of Array.from(SERVICES)) { result3.push(`update:${service.name}`); - } - return result3; - })()).concat(["update:all", "update"]), - "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make", "check:mongo"] - } - } - } - }}); + for (service of Array.from(SERVICES)) { + ;(service => + grunt.registerTask( + `install:${service.name}`, + `Download and set up the ${service.name} service`, + function () { + const done = this.async() + return Helpers.installService(service, done) + } + ))(service) + } - for (service of Array.from(SERVICES)) { - ((service => grunt.registerTask(`install:${service.name}`, `Download and set up the ${service.name} service`, function() { - const done = this.async(); - return Helpers.installService(service, done); - })))(service); - } + grunt.registerTask( + 'install:all', + 'Download and set up all ShareLaTeX services', + [] + .concat( + (() => { + const result4 = [] + for (service of Array.from(SERVICES)) { + result4.push(`install:${service.name}`) + } + return result4 + })() + ) + .concat(['postinstall']) + ) + grunt.registerTask('install', 'install:all') + grunt.registerTask('postinstall', 'Explain postinstall steps', function () { + return Helpers.postinstallMessage(this.async()) + }) + grunt.registerTask( + 'update:all', + 'Checkout and update all ShareLaTeX services', + ['check:make'].concat( + (() => { + const result5 = [] + for (service of Array.from(SERVICES)) { + result5.push(`update:${service.name}`) + } + return result5 + })() + ) + ) + grunt.registerTask('update', 'update:all') + grunt.registerTask('run', 'Run all of the sharelatex processes', [ + 'concurrent:all', + ]) + grunt.registerTask('run:all', 'run') - grunt.registerTask('install:all', "Download and set up all ShareLaTeX services", - [].concat( - ((() => { - const result4 = []; - for (service of Array.from(SERVICES)) { result4.push(`install:${service.name}`); - } - return result4; - })()) - ).concat(['postinstall']) - ); + grunt.registerTask('help', 'Display this help list', 'availabletasks') + grunt.registerTask('default', 'run') - grunt.registerTask('install', 'install:all'); - grunt.registerTask('postinstall', 'Explain postinstall steps', function() { - return Helpers.postinstallMessage(this.async()); - }); + grunt.registerTask( + 'check:redis', + 'Check that redis is installed and running', + function () { + return Helpers.checkRedisConnect(this.async()) + } + ) - grunt.registerTask('update:all', "Checkout and update all ShareLaTeX services", - ["check:make"].concat( - ((() => { - const result5 = []; - for (service of Array.from(SERVICES)) { result5.push(`update:${service.name}`); - } - return result5; - })()) - ) - ); - grunt.registerTask('update', 'update:all'); - grunt.registerTask('run', "Run all of the sharelatex processes", ['concurrent:all']); - grunt.registerTask('run:all', 'run'); + grunt.registerTask( + 'check:mongo', + 'Check that mongo is installed', + function () { + return Helpers.checkMongoConnect(this.async()) + } + ) - grunt.registerTask('help', 'Display this help list', 'availabletasks'); - grunt.registerTask('default', 'run'); + grunt.registerTask( + 'check', + 'Check that you have the required dependencies installed', + ['check:redis', 'check:mongo', 'check:make'] + ) - grunt.registerTask("check:redis", "Check that redis is installed and running", function() { - return Helpers.checkRedisConnect(this.async()); - }); + grunt.registerTask('check:make', 'Check that make is installed', function () { + return Helpers.checkMake(this.async()) + }) - grunt.registerTask("check:mongo", "Check that mongo is installed", function() { - return Helpers.checkMongoConnect(this.async()); - }); + return (Helpers = { + installService(service, callback) { + if (callback == null) { + callback = function (error) {} + } + console.log(`Installing ${service.name}`) + return Helpers.cloneGitRepo(service, function (error) { + if (error != null) { + return callback(error) + } else { + return callback() + } + }) + }, - grunt.registerTask("check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"]); + cloneGitRepo(service, callback) { + if (callback == null) { + callback = function (error) {} + } + const repo_src = service.repo + const dir = service.name + if (!fs.existsSync(dir)) { + const proc = spawn('git', ['clone', repo_src, dir], { + stdio: 'inherit', + }) + return proc.on('close', () => + Helpers.checkoutVersion(service, callback) + ) + } else { + console.log(`${dir} already installed, skipping.`) + return callback() + } + }, - grunt.registerTask("check:make", "Check that make is installed", function() { - return Helpers.checkMake(this.async()); - }); + checkoutVersion(service, callback) { + if (callback == null) { + callback = function (error) {} + } + const dir = service.name + grunt.log.write(`checking out ${service.name} ${service.version}`) + const proc = spawn('git', ['checkout', service.version], { + stdio: 'inherit', + cwd: dir, + }) + return proc.on('close', () => callback()) + }, - - return Helpers = { - installService(service, callback) { - if (callback == null) { callback = function(error) {}; } - console.log(`Installing ${service.name}`); - return Helpers.cloneGitRepo(service, function(error) { - if (error != null) { - return callback(error); - } else { - return callback(); - } - }); - }, - - cloneGitRepo(service, callback) { - if (callback == null) { callback = function(error) {}; } - const repo_src = service.repo; - const dir = service.name; - if (!fs.existsSync(dir)) { - const proc = spawn("git", [ - "clone", - repo_src, - dir - ], {stdio: "inherit"}); - return proc.on("close", () => Helpers.checkoutVersion(service, callback)); - } else { - console.log(`${dir} already installed, skipping.`); - return callback(); - } - }, - - checkoutVersion(service, callback) { - if (callback == null) { callback = function(error) {}; } - const dir = service.name; - grunt.log.write(`checking out ${service.name} ${service.version}`); - const proc = spawn("git", ["checkout", service.version], {stdio: "inherit", cwd: dir}); - return proc.on("close", () => callback()); - }, - - postinstallMessage(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write(`\ + postinstallMessage(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write(`\ Services cloned: ${(() => { - const result6 = []; - for (service of Array.from(SERVICES)) { result6.push(service.name); - } - return result6; - })()} + const result6 = [] + for (service of Array.from(SERVICES)) { + result6.push(service.name) + } + return result6 + })()} To install services run: $ source bin/install-services This will install the required node versions and run \`npm install\` for each service. See https://github.com/sharelatex/sharelatex/pull/549 for more info.\ -` - ); - return callback(); - }, +`) + return callback() + }, - checkMake(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write("Checking make is installed... "); - return exec("make --version", function(error, stdout, stderr) { - if ((error != null) && error.message.match("not found")) { - grunt.log.error("FAIL."); - grunt.log.errorlns(`\ + checkMake(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write('Checking make is installed... ') + return exec('make --version', function (error, stdout, stderr) { + if (error != null && error.message.match('not found')) { + grunt.log.error('FAIL.') + grunt.log.errorlns(`\ Either make is not installed or is not in your path. On Ubuntu you can install make with: sudo apt-get install build-essential \ -` - ); - return callback(error); - } else if (error != null) { - return callback(error); - } else { - grunt.log.write("OK."); - return callback(); - } - }); - }, - checkMongoConnect(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write("Checking can connect to mongo"); - const mongojs = require("mongojs"); - const db = mongojs(settings.mongo.url, ["tags"]); - db.runCommand({ ping: 1 }, function(err, res) { - if (!err && res.ok) { - grunt.log.write("OK."); - } - return callback(); - }); - return db.on('error', function(err){ - err = "Can not connect to mongodb"; - grunt.log.error("FAIL."); - grunt.log.errorlns(`\ +`) + return callback(error) + } else if (error != null) { + return callback(error) + } else { + grunt.log.write('OK.') + return callback() + } + }) + }, + checkMongoConnect(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write('Checking can connect to mongo') + const mongojs = require('mongojs') + const db = mongojs(settings.mongo.url, ['tags']) + db.runCommand({ ping: 1 }, function (err, res) { + if (!err && res.ok) { + grunt.log.write('OK.') + } + return callback() + }) + return db.on('error', function (err) { + err = 'Can not connect to mongodb' + grunt.log.error('FAIL.') + grunt.log.errorlns(`\ !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!! ShareLaTeX can not talk to the mongodb instance @@ -271,30 +309,31 @@ ShareLaTeX can not talk to the mongodb instance Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ -` - ); - throw new Error("Can not connect to Mongodb"); - return callback(err); - }); - }, +`) + throw new Error('Can not connect to Mongodb') + return callback(err) + }) + }, - checkRedisConnect(callback) { - if (callback == null) { callback = function(error) {}; } - grunt.log.write("Checking can connect to redis\n"); - const rclient = require("redis").createClient(settings.redis.web); + checkRedisConnect(callback) { + if (callback == null) { + callback = function (error) {} + } + grunt.log.write('Checking can connect to redis\n') + const rclient = require('redis').createClient(settings.redis.web) - rclient.ping(function(err, res) { - if ((err == null)) { - grunt.log.write("OK."); - } else { - throw new Error("Can not connect to redis"); - } - return callback(); - }); - const errorHandler = _.once(function(err){ - err = "Can not connect to redis"; - grunt.log.error("FAIL."); - grunt.log.errorlns(`\ + rclient.ping(function (err, res) { + if (err == null) { + grunt.log.write('OK.') + } else { + throw new Error('Can not connect to redis') + } + return callback() + }) + const errorHandler = _.once(function (err) { + err = 'Can not connect to redis' + grunt.log.error('FAIL.') + grunt.log.errorlns(`\ !!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!! ShareLaTeX can not talk to the redis instance @@ -302,19 +341,17 @@ ShareLaTeX can not talk to the redis instance Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\ -` - ); - throw new Error("Can not connect to redis"); - return callback(err); - }); - return rclient.on('error', errorHandler); - } - }; -}; - - - +`) + throw new Error('Can not connect to redis') + return callback(err) + }) + return rclient.on('error', errorHandler) + }, + }) +} function __guard__(value, transform) { - return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; + return typeof value !== 'undefined' && value !== null + ? transform(value) + : undefined } diff --git a/server-ce/settings.js b/server-ce/settings.js index 09d21d0015..25de871789 100644 --- a/server-ce/settings.js +++ b/server-ce/settings.js @@ -12,308 +12,349 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl; -let e; -const Path = require('path'); +let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl +let e +const Path = require('path') // These credentials are used for authenticating api requests // between services that may need to go over public channels -const httpAuthUser = "sharelatex"; -const httpAuthPass = process.env.WEB_API_PASSWORD; -const httpAuthUsers = {}; -httpAuthUsers[httpAuthUser] = httpAuthPass; +const httpAuthUser = 'sharelatex' +const httpAuthPass = process.env.WEB_API_PASSWORD +const httpAuthUsers = {} +httpAuthUsers[httpAuthUser] = httpAuthPass -const parse = function(option){ - if (option != null) { - try { - const opt = JSON.parse(option); - return opt; - } catch (err) { - throw new Error(`problem parsing ${option}, invalid JSON`); - } - } -}; +const parse = function (option) { + if (option != null) { + try { + const opt = JSON.parse(option) + return opt + } catch (err) { + throw new Error(`problem parsing ${option}, invalid JSON`) + } + } +} -const parseIntOrFail = function(value){ - const parsedValue = parseInt(value, 10); - if (isNaN(parsedValue)) { - throw new Error(`'${value}' is an invalid integer`); - } - return parsedValue; -}; +const parseIntOrFail = function (value) { + const parsedValue = parseInt(value, 10) + if (isNaN(parsedValue)) { + throw new Error(`'${value}' is an invalid integer`) + } + return parsedValue +} -const DATA_DIR = '/var/lib/sharelatex/data'; -const TMP_DIR = '/var/lib/sharelatex/tmp'; +const DATA_DIR = '/var/lib/sharelatex/data' +const TMP_DIR = '/var/lib/sharelatex/tmp' const settings = { + clsi: { + optimiseInDocker: process.env.OPTIMISE_PDF === 'true', + }, - clsi: { - optimiseInDocker: process.env.OPTIMISE_PDF === 'true' - }, + brandPrefix: '', - brandPrefix: "", + allowAnonymousReadAndWriteSharing: + process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true', - allowAnonymousReadAndWriteSharing: - process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true', + // Databases + // --------- - // Databases - // --------- + // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) + // Documentation about the URL connection string format can be found at: + // + // http://docs.mongodb.org/manual/reference/connection-string/ + // + // The following works out of the box with Mongo's default settings: + mongo: { + url: process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex', + }, - // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/) - // Documentation about the URL connection string format can be found at: - // - // http://docs.mongodb.org/manual/reference/connection-string/ - // - // The following works out of the box with Mongo's default settings: - mongo: { - url : process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex' - }, + // Redis is used in ShareLaTeX for high volume queries, like real-time + // editing, and session management. + // + // The following config will work with Redis's default settings: + redis: { + web: (redisConfig = { + host: process.env.SHARELATEX_REDIS_HOST || 'dockerhost', + port: process.env.SHARELATEX_REDIS_PORT || '6379', + password: process.env.SHARELATEX_REDIS_PASS || undefined, + key_schema: { + // document-updater + blockingKey({ doc_id }) { + return `Blocking:${doc_id}` + }, + docLines({ doc_id }) { + return `doclines:${doc_id}` + }, + docOps({ doc_id }) { + return `DocOps:${doc_id}` + }, + docVersion({ doc_id }) { + return `DocVersion:${doc_id}` + }, + docHash({ doc_id }) { + return `DocHash:${doc_id}` + }, + projectKey({ doc_id }) { + return `ProjectId:${doc_id}` + }, + docsInProject({ project_id }) { + return `DocsIn:${project_id}` + }, + ranges({ doc_id }) { + return `Ranges:${doc_id}` + }, + // document-updater:realtime + pendingUpdates({ doc_id }) { + return `PendingUpdates:${doc_id}` + }, + // document-updater:history + uncompressedHistoryOps({ doc_id }) { + return `UncompressedHistoryOps:${doc_id}` + }, + docsWithHistoryOps({ project_id }) { + return `DocsWithHistoryOps:${project_id}` + }, + // document-updater:lock + blockingKey({ doc_id }) { + return `Blocking:${doc_id}` + }, + // track-changes:lock + historyLock({ doc_id }) { + return `HistoryLock:${doc_id}` + }, + historyIndexLock({ project_id }) { + return `HistoryIndexLock:${project_id}` + }, + // track-changes:history + uncompressedHistoryOps({ doc_id }) { + return `UncompressedHistoryOps:${doc_id}` + }, + docsWithHistoryOps({ project_id }) { + return `DocsWithHistoryOps:${project_id}` + }, + // realtime + clientsInProject({ project_id }) { + return `clients_in_project:${project_id}` + }, + connectedUser({ project_id, client_id }) { + return `connected_user:${project_id}:${client_id}` + }, + }, + }), + fairy: redisConfig, + // track-changes and document-updater + realtime: redisConfig, + documentupdater: redisConfig, + lock: redisConfig, + history: redisConfig, + websessions: redisConfig, + api: redisConfig, + pubsub: redisConfig, + project_history: redisConfig, + }, - // Redis is used in ShareLaTeX for high volume queries, like real-time - // editing, and session management. - // - // The following config will work with Redis's default settings: - redis: { - web: (redisConfig = { - host: process.env.SHARELATEX_REDIS_HOST || "dockerhost", - port: process.env.SHARELATEX_REDIS_PORT || "6379", - password: process.env.SHARELATEX_REDIS_PASS || undefined, - key_schema: { - // document-updater - blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, - docLines({doc_id}) { return `doclines:${doc_id}`; }, - docOps({doc_id}) { return `DocOps:${doc_id}`; }, - docVersion({doc_id}) { return `DocVersion:${doc_id}`; }, - docHash({doc_id}) { return `DocHash:${doc_id}`; }, - projectKey({doc_id}) { return `ProjectId:${doc_id}`; }, - docsInProject({project_id}) { return `DocsIn:${project_id}`; }, - ranges({doc_id}) { return `Ranges:${doc_id}`; }, - // document-updater:realtime - pendingUpdates({doc_id}) { return `PendingUpdates:${doc_id}`; }, - // document-updater:history - uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, - docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, - // document-updater:lock - blockingKey({doc_id}) { return `Blocking:${doc_id}`; }, - // track-changes:lock - historyLock({doc_id}) { return `HistoryLock:${doc_id}`; }, - historyIndexLock({project_id}) { return `HistoryIndexLock:${project_id}`; }, - // track-changes:history - uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; }, - docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; }, - // realtime - clientsInProject({project_id}) { return `clients_in_project:${project_id}`; }, - connectedUser({project_id, client_id}){ return `connected_user:${project_id}:${client_id}`; } - } - }), - fairy: redisConfig, - // track-changes and document-updater - realtime: redisConfig, - documentupdater: redisConfig, - lock: redisConfig, - history: redisConfig, - websessions: redisConfig, - api: redisConfig, - pubsub: redisConfig, - project_history: redisConfig - }, + // The compile server (the clsi) uses a SQL database to cache files and + // meta-data. sqlite is the default, and the load is low enough that this will + // be fine in production (we use sqlite at sharelatex.com). + // + // If you want to configure a different database, see the Sequelize documentation + // for available options: + // + // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage + // + mysql: { + clsi: { + database: 'clsi', + username: 'clsi', + password: '', + dialect: 'sqlite', + storage: Path.join(DATA_DIR, 'db.sqlite'), + }, + }, - // The compile server (the clsi) uses a SQL database to cache files and - // meta-data. sqlite is the default, and the load is low enough that this will - // be fine in production (we use sqlite at sharelatex.com). - // - // If you want to configure a different database, see the Sequelize documentation - // for available options: - // - // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage - // - mysql: { - clsi: { - database: "clsi", - username: "clsi", - password: "", - dialect: "sqlite", - storage: Path.join(DATA_DIR, "db.sqlite") - } - }, + // File storage + // ------------ - // File storage - // ------------ + // ShareLaTeX can store binary files like images either locally or in Amazon + // S3. The default is locally: + filestore: { + backend: 'fs', + stores: { + user_files: Path.join(DATA_DIR, 'user_files'), + template_files: Path.join(DATA_DIR, 'template_files'), + }, + }, - // ShareLaTeX can store binary files like images either locally or in Amazon - // S3. The default is locally: - filestore: { - backend: "fs", - stores: { - user_files: Path.join(DATA_DIR, "user_files"), - template_files: Path.join(DATA_DIR, "template_files") - } - }, + // To use Amazon S3 as a storage backend, comment out the above config, and + // uncomment the following, filling in your key, secret, and bucket name: + // + // filestore: + // backend: "s3" + // stores: + // user_files: "BUCKET_NAME" + // s3: + // key: "AWS_KEY" + // secret: "AWS_SECRET" + // - // To use Amazon S3 as a storage backend, comment out the above config, and - // uncomment the following, filling in your key, secret, and bucket name: - // - // filestore: - // backend: "s3" - // stores: - // user_files: "BUCKET_NAME" - // s3: - // key: "AWS_KEY" - // secret: "AWS_SECRET" - // + trackchanges: { + continueOnError: true, + }, - trackchanges: { - continueOnError: true - }, + // Local disk caching + // ------------------ + path: { + // If we ever need to write something to disk (e.g. incoming requests + // that need processing but may be too big for memory), then write + // them to disk here: + dumpFolder: Path.join(TMP_DIR, 'dumpFolder'), + // Where to write uploads before they are processed + uploadFolder: Path.join(TMP_DIR, 'uploads'), + // Where to write the project to disk before running LaTeX on it + compilesDir: Path.join(DATA_DIR, 'compiles'), + // Where to cache downloaded URLs for the CLSI + clsiCacheDir: Path.join(DATA_DIR, 'cache'), + // Where to write the output files to disk after running LaTeX + outputDir: Path.join(DATA_DIR, 'output'), + }, - // Local disk caching - // ------------------ - path: { - // If we ever need to write something to disk (e.g. incoming requests - // that need processing but may be too big for memory), then write - // them to disk here: - dumpFolder: Path.join(TMP_DIR, "dumpFolder"), - // Where to write uploads before they are processed - uploadFolder: Path.join(TMP_DIR, "uploads"), - // Where to write the project to disk before running LaTeX on it - compilesDir: Path.join(DATA_DIR, "compiles"), - // Where to cache downloaded URLs for the CLSI - clsiCacheDir: Path.join(DATA_DIR, "cache"), - // Where to write the output files to disk after running LaTeX - outputDir: Path.join(DATA_DIR, "output") - }, + // Server Config + // ------------- - // Server Config - // ------------- + // Where your instance of ShareLaTeX can be found publicly. This is used + // when emails are sent out and in generated links: + siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'), - // Where your instance of ShareLaTeX can be found publicly. This is used - // when emails are sent out and in generated links: - siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'), + // The name this is used to describe your ShareLaTeX Installation + appName: process.env.SHARELATEX_APP_NAME || 'ShareLaTeX (Community Edition)', - // The name this is used to describe your ShareLaTeX Installation - appName: process.env.SHARELATEX_APP_NAME || "ShareLaTeX (Community Edition)", + restrictInvitesToExistingAccounts: + process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true', - restrictInvitesToExistingAccounts: process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true', + nav: { + title: + process.env.SHARELATEX_NAV_TITLE || + process.env.SHARELATEX_APP_NAME || + 'ShareLaTeX Community Edition', + }, - nav: { - title: process.env.SHARELATEX_NAV_TITLE || process.env.SHARELATEX_APP_NAME || "ShareLaTeX Community Edition" - }, + // The email address which users will be directed to as the main point of + // contact for this installation of ShareLaTeX. + adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || 'placeholder@example.com', + // If provided, a sessionSecret is used to sign cookies so that they cannot be + // spoofed. This is recommended. + security: { + sessionSecret: + process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM, + }, - // The email address which users will be directed to as the main point of - // contact for this installation of ShareLaTeX. - adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || "placeholder@example.com", + // These credentials are used for authenticating api requests + // between services that may need to go over public channels + httpAuthUsers, - // If provided, a sessionSecret is used to sign cookies so that they cannot be - // spoofed. This is recommended. - security: { - sessionSecret: process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM - }, + // Should javascript assets be served minified or not. + useMinifiedJs: true, - // These credentials are used for authenticating api requests - // between services that may need to go over public channels - httpAuthUsers, + // Should static assets be sent with a header to tell the browser to cache + // them. This should be false in development where changes are being made, + // but should be set to true in production. + cacheStaticAssets: true, - // Should javascript assets be served minified or not. - useMinifiedJs: true, + // If you are running ShareLaTeX over https, set this to true to send the + // cookie with a secure flag (recommended). + secureCookie: process.env.SHARELATEX_SECURE_COOKIE != null, - // Should static assets be sent with a header to tell the browser to cache - // them. This should be false in development where changes are being made, - // but should be set to true in production. - cacheStaticAssets: true, + // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) + // then set this to true to allow it to correctly detect the forwarded IP + // address and http/https protocol information. - // If you are running ShareLaTeX over https, set this to true to send the - // cookie with a secure flag (recommended). - secureCookie: (process.env.SHARELATEX_SECURE_COOKIE != null), + behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false, - // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc) - // then set this to true to allow it to correctly detect the forwarded IP - // address and http/https protocol information. + i18n: { + subdomainLang: { + www: { + lngCode: process.env.SHARELATEX_SITE_LANGUAGE || 'en', + url: siteUrl, + }, + }, + defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || 'en', + }, - behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false, + currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE, - i18n: { - subdomainLang: { - www: {lngCode:process.env.SHARELATEX_SITE_LANGUAGE || "en", url: siteUrl} - }, - defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || "en" - }, + apis: { + web: { + url: 'http://localhost:3000', + user: httpAuthUser, + pass: httpAuthPass, + }, + project_history: { + enabled: false, + }, + }, + references: {}, + notifications: undefined, - currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE, - - apis: { - web: { - url: "http://localhost:3000", - user: httpAuthUser, - pass: httpAuthPass - }, - project_history: { - enabled: false - } - }, - references:{}, - notifications:undefined, - - defaultFeatures: { - collaborators: -1, - dropbox: true, - versioning: true, - compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180), - compileGroup: "standard", - trackChanges: true, - templates: true, - references: true - } -}; + defaultFeatures: { + collaborators: -1, + dropbox: true, + versioning: true, + compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180), + compileGroup: 'standard', + trackChanges: true, + templates: true, + references: true, + }, +} // # OPTIONAL CONFIGURABLE SETTINGS if (process.env.SHARELATEX_LEFT_FOOTER != null) { - try { - settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER); - } catch (error) { - e = error; - console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON"); - } + try { + settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER) + } catch (error) { + e = error + console.error('could not parse SHARELATEX_LEFT_FOOTER, not valid JSON') + } } if (process.env.SHARELATEX_RIGHT_FOOTER != null) { - settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER; - try { - settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER); - } catch (error1) { - e = error1; - console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON"); - } + settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER + try { + settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER) + } catch (error1) { + e = error1 + console.error('could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON') + } } if (process.env.SHARELATEX_HEADER_IMAGE_URL != null) { - settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL; + settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL } if (process.env.SHARELATEX_HEADER_NAV_LINKS != null) { - console.error(`\ + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: SHARELATEX_HEADER_NAV_LINKS is no longer supported # See https://github.com/sharelatex/sharelatex/wiki/Configuring-Headers,-Footers-&-Logo # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ -` - ); +`) } if (process.env.SHARELATEX_HEADER_EXTRAS != null) { - try { - settings.nav.header_extras = JSON.parse(process.env.SHARELATEX_HEADER_EXTRAS); - } catch (error2) { - e = error2; - console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON"); - } + try { + settings.nav.header_extras = JSON.parse( + process.env.SHARELATEX_HEADER_EXTRAS + ) + } catch (error2) { + e = error2 + console.error('could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON') + } } - - // Sending Email // ------------- // @@ -323,370 +364,415 @@ if (process.env.SHARELATEX_HEADER_EXTRAS != null) { // // http://www.nodemailer.com/docs/transports - if (process.env.SHARELATEX_EMAIL_FROM_ADDRESS != null) { + settings.email = { + fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS, + replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || '', + driver: process.env.SHARELATEX_EMAIL_DRIVER, + parameters: { + // AWS Creds + AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID, + AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY, - settings.email = { - fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS, - replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || "", - driver: process.env.SHARELATEX_EMAIL_DRIVER, - parameters: { - // AWS Creds - AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID, - AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY, + // SMTP Creds + host: process.env.SHARELATEX_EMAIL_SMTP_HOST, + port: process.env.SHARELATEX_EMAIL_SMTP_PORT, + secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE), + ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS), + name: process.env.SHARELATEX_EMAIL_SMTP_NAME, + logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true', + }, - // SMTP Creds - host: process.env.SHARELATEX_EMAIL_SMTP_HOST, - port: process.env.SHARELATEX_EMAIL_SMTP_PORT, - secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE), - ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS), - name: process.env.SHARELATEX_EMAIL_SMTP_NAME, - logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true' - }, + textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING, + template: { + customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER, + }, + } - textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING, - template: { - customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER - } - }; + if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) { + settings.email.parameters.region = + process.env.SHARELATEX_EMAIL_AWS_SES_REGION + } - if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) { - settings.email.parameters.region = process.env.SHARELATEX_EMAIL_AWS_SES_REGION; - } + if ( + process.env.SHARELATEX_EMAIL_SMTP_USER != null || + process.env.SHARELATEX_EMAIL_SMTP_PASS != null + ) { + settings.email.parameters.auth = { + user: process.env.SHARELATEX_EMAIL_SMTP_USER, + pass: process.env.SHARELATEX_EMAIL_SMTP_PASS, + } + } - if ((process.env.SHARELATEX_EMAIL_SMTP_USER != null) || (process.env.SHARELATEX_EMAIL_SMTP_PASS != null)) { - settings.email.parameters.auth = { - user: process.env.SHARELATEX_EMAIL_SMTP_USER, - pass: process.env.SHARELATEX_EMAIL_SMTP_PASS - }; - } - - if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) { - settings.email.parameters.tls = - {rejectUnauthorized: parse(process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH)}; - } + if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) { + settings.email.parameters.tls = { + rejectUnauthorized: parse( + process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH + ), + } + } } - // i18n if (process.env.SHARELATEX_LANG_DOMAIN_MAPPING != null) { - - settings.i18n.subdomainLang = parse(process.env.SHARELATEX_LANG_DOMAIN_MAPPING); + settings.i18n.subdomainLang = parse( + process.env.SHARELATEX_LANG_DOMAIN_MAPPING + ) } // Password Settings // ----------- // These restrict the passwords users can use when registering // opts are from http://antelle.github.io/passfield -if (process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH) { - - settings.passwordStrengthOptions = { - pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || "aA$3", - length: {min:process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150} - }; +if ( + process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || + process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || + process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH +) { + settings.passwordStrengthOptions = { + pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || 'aA$3', + length: { + min: process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, + max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150, + }, + } } - - - // ###################### // ShareLaTeX Server Pro // ###################### if (parse(process.env.SHARELATEX_IS_SERVER_PRO) === true) { - settings.bypassPercentageRollouts = true; - settings.apis.references = - {url: "http://localhost:3040"}; + settings.bypassPercentageRollouts = true + settings.apis.references = { url: 'http://localhost:3040' } } - // LDAP - SERVER PRO ONLY // ---------- if (process.env.SHARELATEX_LDAP_HOST) { - console.error(`\ + console.error(`\ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WARNING: The LDAP configuration format has changed in version 0.5.1 # See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\ -` - ); +`) } if (process.env.SHARELATEX_LDAP_URL) { - let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout; - settings.externalAuth = true; - settings.ldap = { - emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT, - nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT, - lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT, - updateUserDetailsOnLogin: process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true', - placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER, - server: { - url: process.env.SHARELATEX_LDAP_URL, - bindDn: process.env.SHARELATEX_LDAP_BIND_DN, - bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS, - bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY, - searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE, - searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE, - searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER, - searchAttributes: ( - (_ldap_search_attribs = process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) ? - (() => { try { - return JSON.parse(_ldap_search_attribs); - } catch (error3) { - e = error3; - return console.error("could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES"); - } })() - : - undefined - ), - groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY, - groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE, - groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE, - groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER, - groupSearchAttributes: ( - (_ldap_group_search_attribs = process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) ? - (() => { try { - return JSON.parse(_ldap_group_search_attribs); - } catch (error4) { - e = error4; - return console.error("could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"); - } })() - : - undefined - ), - cache: process.env.SHARELATEX_LDAP_CACHE === 'true', - timeout: ( - (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) ? - (() => { try { - return parseIntOrFail(_ldap_timeout); - } catch (error5) { - e = error5; - return console.error("Cannot parse SHARELATEX_LDAP_TIMEOUT"); - } })() - : - undefined - ), - connectTimeout: ( - (_ldap_connect_timeout = process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) ? - (() => { try { - return parseIntOrFail(_ldap_connect_timeout); - } catch (error6) { - e = error6; - return console.error("Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT"); - } })() - : - undefined - ) - } - }; + let _ldap_connect_timeout, + _ldap_group_search_attribs, + _ldap_search_attribs, + _ldap_timeout + settings.externalAuth = true + settings.ldap = { + emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT, + nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT, + lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT, + updateUserDetailsOnLogin: + process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER, + server: { + url: process.env.SHARELATEX_LDAP_URL, + bindDn: process.env.SHARELATEX_LDAP_BIND_DN, + bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS, + bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY, + searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE, + searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE, + searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER, + searchAttributes: (_ldap_search_attribs = + process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) + ? (() => { + try { + return JSON.parse(_ldap_search_attribs) + } catch (error3) { + e = error3 + return console.error( + 'could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES' + ) + } + })() + : undefined, + groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY, + groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE, + groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE, + groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER, + groupSearchAttributes: (_ldap_group_search_attribs = + process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) + ? (() => { + try { + return JSON.parse(_ldap_group_search_attribs) + } catch (error4) { + e = error4 + return console.error( + 'could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES' + ) + } + })() + : undefined, + cache: process.env.SHARELATEX_LDAP_CACHE === 'true', + timeout: (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) + ? (() => { + try { + return parseIntOrFail(_ldap_timeout) + } catch (error5) { + e = error5 + return console.error('Cannot parse SHARELATEX_LDAP_TIMEOUT') + } + })() + : undefined, + connectTimeout: (_ldap_connect_timeout = + process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) + ? (() => { + try { + return parseIntOrFail(_ldap_connect_timeout) + } catch (error6) { + e = error6 + return console.error( + 'Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT' + ) + } + })() + : undefined, + }, + } - if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) { - let ca, ca_paths; - try { - ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH); - } catch (error7) { - e = error7; - console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"); - } + if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) { + let ca, ca_paths + try { + ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) + } catch (error7) { + e = error7 + console.error( + 'could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON' + ) + } - if (typeof(ca) === 'string') { - ca_paths = [ca]; - } else if ((typeof(ca) === 'object') && ((ca != null ? ca.length : undefined) != null)) { - ca_paths = ca; - } else { - console.error("problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH"); - } + if (typeof ca === 'string') { + ca_paths = [ca] + } else if ( + typeof ca === 'object' && + (ca != null ? ca.length : undefined) != null + ) { + ca_paths = ca + } else { + console.error('problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH') + } - settings.ldap.server.tlsOptions = { - rejectUnauthorized: process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === "true", - ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem' - }; - } + settings.ldap.server.tlsOptions = { + rejectUnauthorized: + process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === 'true', + ca: ca_paths, // e.g.'/etc/ldap/ca_certs.pem' + } + } } - - - - if (process.env.SHARELATEX_SAML_ENTRYPOINT) { - // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options - let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew; - settings.externalAuth = true; - settings.saml = { - updateUserDetailsOnLogin: process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true', - identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME, - emailField: process.env.SHARELATEX_SAML_EMAIL_FIELD || process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME, - firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD, - lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD, - server: { - // strings - entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT, - callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL, - issuer: process.env.SHARELATEX_SAML_ISSUER, - decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK, - decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT, - signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM, - identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT, - attributeConsumingServiceIndex: process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX, - authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT, - authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING, - validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO, - cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER, - logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL, - logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL, - disableRequestedAuthnContext: process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true', - forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true', - skipRequestCompression: process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true', - acceptedClockSkewMs: ( - (_saml_skew = process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) ? - (() => { try { - return parseIntOrFail(_saml_skew); - } catch (error8) { - e = error8; - return console.error("Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"); - } })() - : - undefined - ), - requestIdExpirationPeriodMs: ( - (_saml_expiration = process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) ? - (() => { try { - return parseIntOrFail(_saml_expiration); - } catch (error9) { - e = error9; - return console.error("Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"); - } })() - : - undefined - ), - additionalParams: ( - (_saml_additionalParams = process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) ? - (() => { try { - return JSON.parse(_saml_additionalParams); - } catch (error10) { - e = error10; - return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS"); - } })() - : - undefined - ), - additionalAuthorizeParams: ( - (_saml_additionalAuthorizeParams = process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) ? - (() => { try { - return JSON.parse(_saml_additionalAuthorizeParams ); - } catch (error11) { - e = error11; - return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"); - } })() - : - undefined - ), - additionalLogoutParams: ( - (_saml_additionalLogoutParams = process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) ? - (() => { try { - return JSON.parse(_saml_additionalLogoutParams ); - } catch (error12) { - e = error12; - return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"); - } })() - : - undefined - ) - } - }; + // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options + let _saml_additionalAuthorizeParams, + _saml_additionalLogoutParams, + _saml_additionalParams, + _saml_expiration, + _saml_skew + settings.externalAuth = true + settings.saml = { + updateUserDetailsOnLogin: + process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true', + identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME, + emailField: + process.env.SHARELATEX_SAML_EMAIL_FIELD || + process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME, + firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD, + lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD, + server: { + // strings + entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT, + callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL, + issuer: process.env.SHARELATEX_SAML_ISSUER, + decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK, + decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT, + signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM, + identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT, + attributeConsumingServiceIndex: + process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX, + authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT, + authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING, + validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO, + cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER, + logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL, + logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL, + disableRequestedAuthnContext: + process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true', + forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true', + skipRequestCompression: + process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true', + acceptedClockSkewMs: (_saml_skew = + process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) + ? (() => { + try { + return parseIntOrFail(_saml_skew) + } catch (error8) { + e = error8 + return console.error( + 'Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS' + ) + } + })() + : undefined, + requestIdExpirationPeriodMs: (_saml_expiration = + process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) + ? (() => { + try { + return parseIntOrFail(_saml_expiration) + } catch (error9) { + e = error9 + return console.error( + 'Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS' + ) + } + })() + : undefined, + additionalParams: (_saml_additionalParams = + process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) + ? (() => { + try { + return JSON.parse(_saml_additionalParams) + } catch (error10) { + e = error10 + return console.error( + 'Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS' + ) + } + })() + : undefined, + additionalAuthorizeParams: (_saml_additionalAuthorizeParams = + process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) + ? (() => { + try { + return JSON.parse(_saml_additionalAuthorizeParams) + } catch (error11) { + e = error11 + return console.error( + 'Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS' + ) + } + })() + : undefined, + additionalLogoutParams: (_saml_additionalLogoutParams = + process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) + ? (() => { + try { + return JSON.parse(_saml_additionalLogoutParams) + } catch (error12) { + e = error12 + return console.error( + 'Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS' + ) + } + })() + : undefined, + }, + } - // SHARELATEX_SAML_CERT cannot be empty - // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 - if (process.env.SHARELATEX_SAML_CERT) { - settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT; - settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT; - } + // SHARELATEX_SAML_CERT cannot be empty + // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102 + if (process.env.SHARELATEX_SAML_CERT) { + settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT + settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT + } } // Compiler // -------- -if (process.env.SANDBOXED_COMPILES === "true") { - settings.clsi = { - dockerRunner: true, - docker: { - image: process.env.TEX_LIVE_DOCKER_IMAGE, - env: { - HOME: "/tmp", - PATH: process.env.COMPILER_PATH || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - }, - user: "www-data" - } - }; +if (process.env.SANDBOXED_COMPILES === 'true') { + settings.clsi = { + dockerRunner: true, + docker: { + image: process.env.TEX_LIVE_DOCKER_IMAGE, + env: { + HOME: '/tmp', + PATH: + process.env.COMPILER_PATH || + '/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + }, + user: 'www-data', + }, + } - if ((settings.path == null)) { - settings.path = {}; - } - settings.path.synctexBaseDir = () => "/compile"; - if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') { - console.log("Using sibling containers for sandboxed compiles"); - if (process.env.SANDBOXED_COMPILES_HOST_DIR) { - settings.path.sandboxedCompilesHostDir = process.env.SANDBOXED_COMPILES_HOST_DIR; - } else { - console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set'); - } - } + if (settings.path == null) { + settings.path = {} + } + settings.path.synctexBaseDir = () => '/compile' + if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') { + console.log('Using sibling containers for sandboxed compiles') + if (process.env.SANDBOXED_COMPILES_HOST_DIR) { + settings.path.sandboxedCompilesHostDir = + process.env.SANDBOXED_COMPILES_HOST_DIR + } else { + console.error( + 'Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set' + ) + } + } } - // Templates // --------- if (process.env.SHARELATEX_TEMPLATES_USER_ID) { - settings.templates = { - mountPointUrl: "/templates", - user_id: process.env.SHARELATEX_TEMPLATES_USER_ID - }; + settings.templates = { + mountPointUrl: '/templates', + user_id: process.env.SHARELATEX_TEMPLATES_USER_ID, + } - settings.templateLinks = parse(process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS); + settings.templateLinks = parse( + process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS + ) } - // /Learn // ------- if (process.env.SHARELATEX_PROXY_LEARN != null) { - settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN); + settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN) } - // /References // ----------- if (process.env.SHARELATEX_ELASTICSEARCH_URL != null) { - settings.references.elasticsearch = - {host: process.env.SHARELATEX_ELASTICSEARCH_URL}; + settings.references.elasticsearch = { + host: process.env.SHARELATEX_ELASTICSEARCH_URL, + } } // TeX Live Images // ----------- if (process.env.ALL_TEX_LIVE_DOCKER_IMAGES != null) { - allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(','); + allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(',') } if (process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES != null) { - allTexLiveDockerImageNames = process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(','); + allTexLiveDockerImageNames = + process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(',') } if (allTexLiveDockerImages != null) { - settings.allowedImageNames = []; - for (let index = 0; index < allTexLiveDockerImages.length; index++) { - const fullImageName = allTexLiveDockerImages[index]; - const imageName = Path.basename(fullImageName); - const imageDesc = (allTexLiveDockerImageNames != null) ? allTexLiveDockerImageNames[index] : imageName; - settings.allowedImageNames.push({ imageName, imageDesc }); - } + settings.allowedImageNames = [] + for (let index = 0; index < allTexLiveDockerImages.length; index++) { + const fullImageName = allTexLiveDockerImages[index] + const imageName = Path.basename(fullImageName) + const imageDesc = + allTexLiveDockerImageNames != null + ? allTexLiveDockerImageNames[index] + : imageName + settings.allowedImageNames.push({ imageName, imageDesc }) + } } // With lots of incoming and outgoing HTTP connections to different services, // sometimes long running, it is a good idea to increase the default number // of sockets that Node will hold open. -const http = require('http'); -http.globalAgent.maxSockets = 300; -const https = require('https'); -https.globalAgent.maxSockets = 300; +const http = require('http') +http.globalAgent.maxSockets = 300 +const https = require('https') +https.globalAgent.maxSockets = 300 -module.exports = settings; +module.exports = settings diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index 9417396b73..22be44ae88 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -11,75 +11,106 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -module.exports = function(grunt) { +module.exports = function (grunt) { + grunt.registerTask( + 'user:create-admin', + 'Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com', + function () { + const done = this.async() + const email = grunt.option('email') + if (email == null) { + console.error('Usage: grunt user:create-admin --email=joe@example.com') + process.exit(1) + } - grunt.registerTask('user:create-admin', "Create a user with the given email address and make them an admin. Update in place if the user already exists. Usage: grunt user:create-admin --email joe@example.com", function() { - const done = this.async(); - const email = grunt.option("email"); - if ((email == null)) { - console.error("Usage: grunt user:create-admin --email=joe@example.com"); - process.exit(1); - } - - const settings = require("settings-sharelatex"); - const mongodb = require("../web/app/src/infrastructure/mongodb"); - const UserRegistrationHandler = require("../web/app/src/Features/User/UserRegistrationHandler"); - const OneTimeTokenHandler = require("../web/app/src/Features/Security/OneTimeTokenHandler"); - return mongodb.waitForDb().then(() => UserRegistrationHandler.registerNewUser({ + const settings = require('settings-sharelatex') + const mongodb = require('../web/app/src/infrastructure/mongodb') + const UserRegistrationHandler = require('../web/app/src/Features/User/UserRegistrationHandler') + const OneTimeTokenHandler = require('../web/app/src/Features/Security/OneTimeTokenHandler') + return mongodb.waitForDb().then(() => + UserRegistrationHandler.registerNewUser( + { email, - password: require("crypto").randomBytes(32).toString("hex") - }, function(error, user) { - if ((error != null) && ((error != null ? error.message : undefined) !== "EmailAlreadyRegistered")) { - throw error; + password: require('crypto').randomBytes(32).toString('hex'), + }, + function (error, user) { + if ( + error != null && + (error != null ? error.message : undefined) !== + 'EmailAlreadyRegistered' + ) { + throw error } - user.isAdmin = true; - return user.save(function(error) { - if (error != null) { throw error; } - const ONE_WEEK = 7 * 24 * 60 * 60; // seconds - return OneTimeTokenHandler.getNewToken("password", { expiresIn: ONE_WEEK, email:user.email, user_id: user._id.toString() }, function(err, token){ - if (err != null) { return next(err); } + user.isAdmin = true + return user.save(function (error) { + if (error != null) { + throw error + } + const ONE_WEEK = 7 * 24 * 60 * 60 // seconds + return OneTimeTokenHandler.getNewToken( + 'password', + { + expiresIn: ONE_WEEK, + email: user.email, + user_id: user._id.toString(), + }, + function (err, token) { + if (err != null) { + return next(err) + } - console.log(""); - console.log(`\ + console.log('') + console.log(`\ Successfully created ${email} as an admin user. Please visit the following URL to set a password for ${email} and log in: ${settings.siteUrl}/user/password/set?passwordResetToken=${token} \ -` - ); - return done(); - }); - }); - })); - }); - - return grunt.registerTask('user:delete', "deletes a user and all their data, Usage: grunt user:delete --email joe@example.com", function() { - const done = this.async(); - const email = grunt.option("email"); - if ((email == null)) { - console.error("Usage: grunt user:delete --email=joe@example.com"); - process.exit(1); - } - const settings = require("settings-sharelatex"); - const mongodb = require("../web/app/src/infrastructure/mongodb"); - const UserGetter = require("../web/app/src/Features/User/UserGetter"); - const UserDeleter = require("../web/app/src/Features/User/UserDeleter"); - return mongodb.waitForDb().then(() => UserGetter.getUser({email}, function(error, user) { - if (error != null) { - throw error; - } - if ((user == null)) { - console.log(`user ${email} not in database, potentially already deleted`); - return done(); - } - return UserDeleter.deleteUser(user._id, function(err){ - if (err != null) { - throw err; +`) + return done() } - return done(); - }); - })); - }); -}; + ) + }) + } + ) + ) + } + ) + + return grunt.registerTask( + 'user:delete', + 'deletes a user and all their data, Usage: grunt user:delete --email joe@example.com', + function () { + const done = this.async() + const email = grunt.option('email') + if (email == null) { + console.error('Usage: grunt user:delete --email=joe@example.com') + process.exit(1) + } + const settings = require('settings-sharelatex') + const mongodb = require('../web/app/src/infrastructure/mongodb') + const UserGetter = require('../web/app/src/Features/User/UserGetter') + const UserDeleter = require('../web/app/src/Features/User/UserDeleter') + return mongodb.waitForDb().then(() => + UserGetter.getUser({ email }, function (error, user) { + if (error != null) { + throw error + } + if (user == null) { + console.log( + `user ${email} not in database, potentially already deleted` + ) + return done() + } + return UserDeleter.deleteUser(user._id, function (err) { + if (err != null) { + throw err + } + return done() + }) + }) + ) + } + ) +} From 763e25fbdfb6ff1fc87efa7e674205d9daaf4063 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 11:58:33 +0100 Subject: [PATCH 06/11] [misc] delete commented ProjectSize task --- server-ce/tasks/ProjectSize.js | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 server-ce/tasks/ProjectSize.js diff --git a/server-ce/tasks/ProjectSize.js b/server-ce/tasks/ProjectSize.js deleted file mode 100644 index 5e663f5b2c..0000000000 --- a/server-ce/tasks/ProjectSize.js +++ /dev/null @@ -1,26 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Sanity-check the conversion and remove this comment. -// require("coffee-script") - -// fs = require("fs") -// _ = require("underscore") - -// if not process.argv[2] -// console.log "Usage: coffee project_size.coffee user_files_path" -// else -// dirPath = process.argv[2] -// if not fs.lstatSync(dirPath).isDirectory() -// console.log dirPath + " directory not exist" -// else -// fs.readdir dirPath, (err, files)-> -// projects = [] -// files.forEach (file)-> -// project_id = file.split("_")[0] -// if !projects[project_id] -// projects[project_id] = 0 -// projects[project_id] += fs.lstatSync(dirPath+"/"+file).size - -// ids = _.keys projects -// console.log "project \t size" -// ids.forEach (id)-> -// console.log id + "\t" + projects[id] From 6c6335ce9831b756fcb26885e46e6db4dfd8ea0f Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:00:50 +0100 Subject: [PATCH 07/11] [misc] do not set SHARELATEX_CONFIG in run scripts --- server-ce/runit/chat-sharelatex/run | 1 - server-ce/runit/clsi-sharelatex/run | 1 - server-ce/runit/contacts-sharelatex/run | 1 - server-ce/runit/docstore-sharelatex/run | 1 - server-ce/runit/document-updater-sharelatex/run | 1 - server-ce/runit/filestore-sharelatex/run | 1 - server-ce/runit/notifications-sharelatex/run | 1 - server-ce/runit/real-time-sharelatex/run | 1 - server-ce/runit/spelling-sharelatex/run | 1 - server-ce/runit/track-changes-sharelatex/run | 1 - server-ce/runit/web-sharelatex/run | 1 - 11 files changed, 11 deletions(-) diff --git a/server-ce/runit/chat-sharelatex/run b/server-ce/runit/chat-sharelatex/run index cc5f75057f..c000f7d80d 100755 --- a/server-ce/runit/chat-sharelatex/run +++ b/server-ce/runit/chat-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/clsi-sharelatex/run b/server-ce/runit/clsi-sharelatex/run index c1469b6cfe..e8e7bbaf4c 100755 --- a/server-ce/runit/clsi-sharelatex/run +++ b/server-ce/runit/clsi-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/contacts-sharelatex/run b/server-ce/runit/contacts-sharelatex/run index 4c01aa0985..8de491ac6a 100755 --- a/server-ce/runit/contacts-sharelatex/run +++ b/server-ce/runit/contacts-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/docstore-sharelatex/run b/server-ce/runit/docstore-sharelatex/run index 2a171f0968..f6b3285358 100755 --- a/server-ce/runit/docstore-sharelatex/run +++ b/server-ce/runit/docstore-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/document-updater-sharelatex/run b/server-ce/runit/document-updater-sharelatex/run index 51472b3d48..7d688a17de 100755 --- a/server-ce/runit/document-updater-sharelatex/run +++ b/server-ce/runit/document-updater-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/filestore-sharelatex/run b/server-ce/runit/filestore-sharelatex/run index 4237a38793..8baccbfe0b 100755 --- a/server-ce/runit/filestore-sharelatex/run +++ b/server-ce/runit/filestore-sharelatex/run @@ -1,3 +1,2 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/filestore/app.js >> /var/log/sharelatex/filestore.log 2>&1 diff --git a/server-ce/runit/notifications-sharelatex/run b/server-ce/runit/notifications-sharelatex/run index 89f8ad54f9..721b1cf1e9 100755 --- a/server-ce/runit/notifications-sharelatex/run +++ b/server-ce/runit/notifications-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/real-time-sharelatex/run b/server-ce/runit/real-time-sharelatex/run index ad005b624c..392c4525ef 100755 --- a/server-ce/runit/real-time-sharelatex/run +++ b/server-ce/runit/real-time-sharelatex/run @@ -1,3 +1,2 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee exec /sbin/setuser www-data /usr/bin/node /var/www/sharelatex/real-time/app.js >> /var/log/sharelatex/real-time.log 2>&1 diff --git a/server-ce/runit/spelling-sharelatex/run b/server-ce/runit/spelling-sharelatex/run index a9a73f8ae0..af7941a4b4 100755 --- a/server-ce/runit/spelling-sharelatex/run +++ b/server-ce/runit/spelling-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/track-changes-sharelatex/run b/server-ce/runit/track-changes-sharelatex/run index 45b3b77ebc..a137098588 100755 --- a/server-ce/runit/track-changes-sharelatex/run +++ b/server-ce/runit/track-changes-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then diff --git a/server-ce/runit/web-sharelatex/run b/server-ce/runit/web-sharelatex/run index c1371de0f4..15fba8f806 100755 --- a/server-ce/runit/web-sharelatex/run +++ b/server-ce/runit/web-sharelatex/run @@ -1,5 +1,4 @@ #!/bin/bash -export SHARELATEX_CONFIG=/etc/sharelatex/settings.coffee NODE_PARAMS="" if [ "$DEBUG_NODE" == "true" ]; then From 42b680c7c7d08414670eb2fc4561f5f7382184b9 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:09:09 +0100 Subject: [PATCH 08/11] [misc] update references to decaffeinated coffee-script files --- server-ce/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index ace431967f..33f2e0baab 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -5,7 +5,7 @@ ARG SHARELATEX_BASE_TAG=sharelatex/sharelatex-base:latest FROM $SHARELATEX_BASE_TAG -ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee +ENV SHARELATEX_CONFIG /etc/sharelatex/settings.js # Add required source files @@ -13,7 +13,7 @@ ENV SHARELATEX_CONFIG /etc/sharelatex/settings.coffee ADD ${baseDir}/bin /var/www/sharelatex/bin ADD ${baseDir}/doc /var/www/sharelatex/doc ADD ${baseDir}/tasks /var/www/sharelatex/tasks -ADD ${baseDir}/Gruntfile.coffee /var/www/sharelatex/Gruntfile.coffee +ADD ${baseDir}/Gruntfile.js /var/www/sharelatex/Gruntfile.js ADD ${baseDir}/package.json /var/www/sharelatex/package.json ADD ${baseDir}/package-lock.json /var/www/sharelatex/package-lock.json ADD ${baseDir}/services.js /var/www/sharelatex/config/services.js @@ -85,7 +85,7 @@ COPY ${baseDir}/init_scripts/ /etc/my_init.d/ # Copy app settings files # ----------------------- -COPY ${baseDir}/settings.coffee /etc/sharelatex/settings.coffee +COPY ${baseDir}/settings.js /etc/sharelatex/settings.js # Set Environment Variables # -------------------------------- From faca804fc176c1fe80c18277892cb1b7938ce15b Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:48:36 +0100 Subject: [PATCH 09/11] [misc] upgrade settings module to v2 --- server-ce/Gruntfile.js | 2 +- server-ce/package-lock.json | 19 +++++-------------- server-ce/package.json | 2 +- server-ce/tasks/CreateAndDestroyUsers.js | 4 ++-- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index 9cee93ccb6..c38511386f 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -26,7 +26,7 @@ const semver = require('semver') const knox = require('knox') const crypto = require('crypto') const async = require('async') -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') const _ = require('underscore') const SERVICES = require('./config/services') diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json index 69bb8563cf..2f074b3a51 100644 --- a/server-ce/package-lock.json +++ b/server-ce/package-lock.json @@ -157,6 +157,11 @@ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", "dev": true }, + "@overleaf/settings": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@overleaf/settings/-/settings-2.1.1.tgz", + "integrity": "sha512-vcJwqCGFKmQxTP/syUqCeMaSRjHmBcQgKOACR9He2uJcErg2GZPa1go+nGvszMbkElM4HfRKm/MfxvqHhoN4TQ==" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -2868,20 +2873,6 @@ "integrity": "sha1-eUEYKz/8xYC/8cF5QqzfeVHA0hM=", "dev": true }, - "settings-sharelatex": { - "version": "git+https://github.com/sharelatex/settings-sharelatex.git#b4fb8404c5de571d029bf4c29e96a60b21206f94", - "from": "git+https://github.com/sharelatex/settings-sharelatex.git", - "requires": { - "coffee-script": "1.6.0" - }, - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" - } - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/server-ce/package.json b/server-ce/package.json index b9f180e084..c46ac96be4 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -9,6 +9,7 @@ "format:fix": "prettier --write $PWD/'**/*.js'" }, "dependencies": { + "@overleaf/settings": "^2.1.1", "async": "^0.9.0", "bson": "^1.0.4", "coffee-script": "^1.11.1", @@ -21,7 +22,6 @@ "mongojs": "2.4.0", "redis": "^2.6.2", "rimraf": "~2.2.6", - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git", "underscore": "^1.7.0" }, "devDependencies": { diff --git a/server-ce/tasks/CreateAndDestroyUsers.js b/server-ce/tasks/CreateAndDestroyUsers.js index 22be44ae88..b7d519cc6c 100644 --- a/server-ce/tasks/CreateAndDestroyUsers.js +++ b/server-ce/tasks/CreateAndDestroyUsers.js @@ -23,7 +23,7 @@ module.exports = function (grunt) { process.exit(1) } - const settings = require('settings-sharelatex') + const settings = require('@overleaf/settings') const mongodb = require('../web/app/src/infrastructure/mongodb') const UserRegistrationHandler = require('../web/app/src/Features/User/UserRegistrationHandler') const OneTimeTokenHandler = require('../web/app/src/Features/Security/OneTimeTokenHandler') @@ -88,7 +88,7 @@ ${settings.siteUrl}/user/password/set?passwordResetToken=${token} console.error('Usage: grunt user:delete --email=joe@example.com') process.exit(1) } - const settings = require('settings-sharelatex') + const settings = require('@overleaf/settings') const mongodb = require('../web/app/src/infrastructure/mongodb') const UserGetter = require('../web/app/src/Features/User/UserGetter') const UserDeleter = require('../web/app/src/Features/User/UserDeleter') From 859252696b6b9d4b202b21c0cf0d697cdc7c7c35 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 12:48:45 +0100 Subject: [PATCH 10/11] [misc] drop coffee-script imports --- server-ce/Gruntfile.js | 2 - server-ce/package-lock.json | 780 +++++++++++++++--------------------- server-ce/package.json | 2 - 3 files changed, 327 insertions(+), 457 deletions(-) diff --git a/server-ce/Gruntfile.js b/server-ce/Gruntfile.js index c38511386f..170ee5b353 100644 --- a/server-ce/Gruntfile.js +++ b/server-ce/Gruntfile.js @@ -16,7 +16,6 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const coffee = require('coffee-script') const fs = require('fs') const { spawn } = require('child_process') const { exec } = require('child_process') @@ -38,7 +37,6 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-execute') grunt.loadNpmTasks('grunt-available-tasks') grunt.loadNpmTasks('grunt-concurrent') - grunt.loadNpmTasks('grunt-contrib-coffee') grunt.loadNpmTasks('grunt-shell') grunt.task.loadTasks('./tasks') diff --git a/server-ce/package-lock.json b/server-ce/package-lock.json index 2f074b3a51..3331f87502 100644 --- a/server-ce/package-lock.json +++ b/server-ce/package-lock.json @@ -30,31 +30,10 @@ "js-tokens": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" } } }, @@ -205,10 +184,13 @@ "dev": true }, "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } }, "argparse": { "version": "0.1.16", @@ -234,6 +216,11 @@ } } }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, "array-includes": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", @@ -247,6 +234,19 @@ "is-string": "^1.0.5" } }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, "array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", @@ -258,6 +258,11 @@ "es-abstract": "^1.18.0-next.1" } }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -317,14 +322,13 @@ "dev": true }, "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" + "ansi-styles": "^3.2.1", + "supports-color": "^5.3.0" } }, "coffee-script": { @@ -353,6 +357,14 @@ "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", "dev": true }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -387,6 +399,26 @@ } } }, + "cson": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/cson/-/cson-3.0.2.tgz", + "integrity": "sha1-g+6Qids8JUvsHpjkmNmqzxGtzFQ=", + "requires": { + "coffee-script": "^1.9.0", + "cson-parser": "^1.0.6", + "extract-opts": "^3.0.1", + "requirefresh": "^2.0.0", + "safefs": "^4.0.0" + } + }, + "cson-parser": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", + "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", + "requires": { + "coffee-script": "^1.10.0" + } + }, "dateformat": { "version": "1.0.2-1.2.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", @@ -423,6 +455,11 @@ "esutils": "^2.0.2" } }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", @@ -430,6 +467,20 @@ "dev": true, "optional": true }, + "each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + }, + "eachr": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz", + "integrity": "sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ=", + "requires": { + "editions": "^1.1.1", + "typechecker": "^4.3.0" + } + }, "east": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/east/-/east-0.5.7.tgz", @@ -441,35 +492,10 @@ "twostep": "0.4.2" }, "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "requires": { - "graceful-readlink": ">= 1.0.0" - }, - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - } - } - }, - "expressionify": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz", - "integrity": "sha1-/iJnx+hpRXfxP02oML/DyNgXf5I=" - }, "progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" - }, - "twostep": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", - "integrity": "sha1-hLxQh6hxV00ev3vjB54D4SLUFbY=" } } }, @@ -478,6 +504,11 @@ "resolved": "https://registry.npmjs.org/east-mongo/-/east-mongo-0.3.3.tgz", "integrity": "sha1-WKtCdGaRy+ITtBweiG8EttyCq8A=" }, + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -537,6 +568,11 @@ "is-symbol": "^1.0.2" } }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -692,15 +728,6 @@ "lru-cache": "^6.0.0" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1027,6 +1054,21 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, + "expressionify": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/expressionify/-/expressionify-0.9.3.tgz", + "integrity": "sha1-/iJnx+hpRXfxP02oML/DyNgXf5I=" + }, + "extract-opts": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", + "integrity": "sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E=", + "requires": { + "eachr": "^3.2.0", + "editions": "^1.1.1", + "typechecker": "^4.3.0" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1229,6 +1271,11 @@ "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", "dev": true }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, "grunt": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", @@ -1336,40 +1383,6 @@ } } }, - "grunt-contrib-coffee": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.10.1.tgz", - "integrity": "sha1-7SLGgp9FiqjqR/hnaEM+mBMUAYY=", - "dev": true, - "requires": { - "chalk": "~0.4.0", - "coffee-script": "~1.7.0", - "lodash": "~2.4.1" - }, - "dependencies": { - "coffee-script": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", - "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", - "dev": true, - "requires": { - "mkdirp": "~0.3.5" - } - }, - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, "grunt-execute": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.1.5.tgz", @@ -1525,26 +1538,6 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "requires": { - "path-key": "^1.0.0" - }, - "dependencies": { - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" } } }, @@ -1563,12 +1556,6 @@ "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -1749,6 +1736,11 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "jit-grunt": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz", + "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1827,98 +1819,6 @@ "lodash": "~3.10.1" }, "dependencies": { - "cson": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/cson/-/cson-3.0.2.tgz", - "integrity": "sha1-g+6Qids8JUvsHpjkmNmqzxGtzFQ=", - "requires": { - "coffee-script": "^1.9.0", - "cson-parser": "^1.0.6", - "extract-opts": "^3.0.1", - "requirefresh": "^2.0.0", - "safefs": "^4.0.0" - }, - "dependencies": { - "cson-parser": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", - "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", - "requires": { - "coffee-script": "^1.10.0" - } - }, - "extract-opts": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-3.3.1.tgz", - "integrity": "sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E=", - "requires": { - "eachr": "^3.2.0", - "editions": "^1.1.1", - "typechecker": "^4.3.0" - }, - "dependencies": { - "eachr": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eachr/-/eachr-3.2.0.tgz", - "integrity": "sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ=", - "requires": { - "editions": "^1.1.1", - "typechecker": "^4.3.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - }, - "typechecker": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz", - "integrity": "sha1-+XuV9RsDhBchLWd9RaNz7nvO1+Y=", - "requires": { - "editions": "^1.3.3" - } - } - } - }, - "requirefresh": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", - "integrity": "sha1-dC3Mwg86lpGNZsbxWX3I/+vE9vU=", - "requires": { - "editions": "^1.1.1" - }, - "dependencies": { - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - } - } - }, - "safefs": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", - "integrity": "sha1-+CrrS9165R9lPrIPZyizBYyNZEU=", - "requires": { - "editions": "^1.1.1", - "graceful-fs": "^4.1.4" - }, - "dependencies": { - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==" - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - } - } - } - } - }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -2005,11 +1905,6 @@ } } }, - "jit-grunt": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz", - "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=" - }, "js-yaml": { "version": "3.4.6", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", @@ -2046,125 +1941,56 @@ "integrity": "sha1-8WFLBshUToEo5CKchjR9tzrZeI0=" } } - }, - "load-grunt-tasks": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", - "integrity": "sha1-vliSkJRY2T3fdp60vGhRAggMYyE=", + } + } + }, + "load-grunt-tasks": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.3.0.tgz", + "integrity": "sha1-vliSkJRY2T3fdp60vGhRAggMYyE=", + "requires": { + "arrify": "^1.0.0", + "multimatch": "^2.0.0", + "pkg-up": "^1.0.0" + }, + "dependencies": { + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", "requires": { - "arrify": "^1.0.0", - "multimatch": "^2.0.0", - "pkg-up": "^1.0.0" + "find-up": "^1.0.0" }, "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" }, "dependencies": { - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "requires": { - "array-uniq": "^1.0.1" - }, - "dependencies": { - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - } - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - } - } - } - } - } - } - }, - "pkg-up": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", - "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" }, "dependencies": { - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - } - } + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" } } } @@ -2281,43 +2107,6 @@ "readable-stream": "2.2.7" }, "dependencies": { - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" - }, - "mongodb-core": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", - "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", - "requires": { - "bson": "~1.0.4", - "require_optional": "~1.0.0" - }, - "dependencies": { - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" - }, - "dependencies": { - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - } - } - } - } - }, "readable-stream": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", @@ -2381,6 +2170,15 @@ } } }, + "mongodb-core": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", + "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, "mongojs": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", @@ -2396,31 +2194,6 @@ "xtend": "^4.0.0" }, "dependencies": { - "each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } - }, - "parse-mongo-url": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" - }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -2474,21 +2247,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" } } - }, - "thunky": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" - }, - "to-mongodb-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" } } }, @@ -2498,6 +2256,50 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + } + } + }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -2580,6 +2382,26 @@ "validate-npm-package-license": "^3.0.1" } }, + "npm-run-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "requires": { + "path-key": "^1.0.0" + }, + "dependencies": { + "path-key": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=" + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", @@ -2619,7 +2441,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -2681,6 +2502,11 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-mongo-url": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -2809,25 +2635,18 @@ "double-ended-queue": "^2.1.0-0", "redis-commands": "^1.2.0", "redis-parser": "^2.6.0" - }, - "dependencies": { - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, - "redis-commands": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", - "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" - } } }, + "redis-commands": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", + "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -2840,6 +2659,35 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + } + } + }, + "requirefresh": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-2.1.0.tgz", + "integrity": "sha1-dC3Mwg86lpGNZsbxWX3I/+vE9vU=", + "requires": { + "editions": "^1.1.1" + } + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -2861,6 +2709,22 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" }, + "safefs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/safefs/-/safefs-4.1.0.tgz", + "integrity": "sha1-+CrrS9165R9lPrIPZyizBYyNZEU=", + "requires": { + "editions": "^1.1.1", + "graceful-fs": "^4.1.4" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + } + } + }, "sax": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", @@ -2987,17 +2851,6 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "string.prototype.trimend": { @@ -3027,10 +2880,13 @@ "dev": true }, "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } }, "strip-bom": { "version": "3.0.0", @@ -3084,15 +2940,6 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } } }, @@ -3102,6 +2949,16 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + }, + "to-mongodb-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + }, "tsconfig-paths": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", @@ -3113,6 +2970,11 @@ "strip-bom": "^3.0.0" } }, + "twostep": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", + "integrity": "sha1-hLxQh6hxV00ev3vjB54D4SLUFbY=" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3128,6 +2990,14 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typechecker": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.4.1.tgz", + "integrity": "sha1-+XuV9RsDhBchLWd9RaNz7nvO1+Y=", + "requires": { + "editions": "^1.3.3" + } + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -3204,8 +3074,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "xml2js": { "version": "0.2.8", @@ -3216,6 +3085,11 @@ "sax": "0.5.x" } }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/server-ce/package.json b/server-ce/package.json index c46ac96be4..f7ef5fd095 100644 --- a/server-ce/package.json +++ b/server-ce/package.json @@ -12,7 +12,6 @@ "@overleaf/settings": "^2.1.1", "async": "^0.9.0", "bson": "^1.0.4", - "coffee-script": "^1.11.1", "east": "0.5.7", "east-mongo": "0.3.3", "grunt-shell": "^1.1.1", @@ -41,7 +40,6 @@ "grunt-execute": "~0.1.5", "grunt-available-tasks": "~0.4.1", "grunt-concurrent": "~0.4.3", - "grunt-contrib-coffee": "~0.10.1", "prettier": "^2.2.1", "semver": "~2.2.1", "knox": "~0.8.9" From a8ca0a896fc9d9f377e0ba5c73f167f62b915987 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 7 Jul 2021 13:04:19 +0100 Subject: [PATCH 11/11] [misc] fix listing of services for bin/ scripts --- server-ce/bin/compile-services | 7 +++---- server-ce/bin/install-services | 3 +-- server-ce/services.js | 6 ++++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/server-ce/bin/compile-services b/server-ce/bin/compile-services index 4045a49a4c..2ebde44826 100755 --- a/server-ce/bin/compile-services +++ b/server-ce/bin/compile-services @@ -2,19 +2,18 @@ set -e -grep 'name:' config/services.js | \ - sed 's/.*name: "\(.*\)",/\1/' | \ +node ./config/services.js | \ while read service do pushd $service echo "Compiling Service $service" - case $service in + case $service in web) npm run webpack:production ;; *) echo "$service doesn't require a compilation" ;; - esac + esac popd done diff --git a/server-ce/bin/install-services b/server-ce/bin/install-services index becf174cc1..591fb3354b 100755 --- a/server-ce/bin/install-services +++ b/server-ce/bin/install-services @@ -2,8 +2,7 @@ set -e -grep 'name:' config/services.js | \ - sed 's/.*name: "\(.*\)",/\1/' | \ +node ./config/services.js | \ while read service do pushd $service diff --git a/server-ce/services.js b/server-ce/services.js index 4fc6365f6b..c47186a159 100644 --- a/server-ce/services.js +++ b/server-ce/services.js @@ -55,3 +55,9 @@ module.exports = [ version: 'master', }, ] + +if (require.main === module) { + for (const service of module.exports) { + console.log(service.name) + } +}