From 436261e703e7b939afe4503ad3f3af2dfe2a6da8 Mon Sep 17 00:00:00 2001 From: Erik Ritter Date: Tue, 3 Sep 2019 14:13:58 -0700 Subject: [PATCH 01/19] [Codemod] Rename react unsafe lifecycles (#8143) * [Codemod] Rename react unsafe lifecycles * Fix lint errors * [Codemod] Rename react unsafe lifecycles * Fix lint errors --- superset/assets/.eslintrc | 56 +- superset/assets/package-lock.json | 746 +++++++++--------- superset/assets/package.json | 4 +- .../components/AlteredSliceTag_spec.jsx | 4 +- .../dashboard/components/Dashboard_spec.jsx | 4 +- .../dashboard/components/SliceAdder_spec.jsx | 4 +- .../javascripts/sqllab/ResultSet_spec.jsx | 2 +- superset/assets/src/CRUD/CollectionTable.jsx | 2 +- .../SqlLab/components/AceEditorWrapper.jsx | 2 +- .../SqlLab/components/QueryAutoRefresh.jsx | 2 +- .../src/SqlLab/components/ResultSet.jsx | 2 +- .../src/SqlLab/components/SouthPane.jsx | 2 +- .../src/SqlLab/components/SqlEditor.jsx | 2 +- .../SqlLab/components/TabbedSqlEditors.jsx | 2 +- superset/assets/src/chart/chartAction.js | 7 +- .../assets/src/components/AlteredSliceTag.jsx | 2 +- superset/assets/src/components/AnchorLink.jsx | 2 +- .../assets/src/components/EditableTitle.jsx | 2 +- .../assets/src/components/TableLoader.jsx | 2 +- superset/assets/src/components/Timer.jsx | 2 +- .../src/dashboard/components/Dashboard.jsx | 2 +- .../dashboard/components/DashboardBuilder.jsx | 2 +- .../src/dashboard/components/Header.jsx | 2 +- .../components/HeaderActionsDropdown.jsx | 2 +- .../src/dashboard/components/SliceAdder.jsx | 2 +- .../components/gridComponents/Markdown.jsx | 2 +- .../components/gridComponents/Tabs.jsx | 2 +- .../components/menu/WithPopoverMenu.jsx | 2 +- ...AdhocFilterEditPopoverSimpleTabContent.jsx | 2 +- .../components/ExploreViewContainer.jsx | 2 +- .../controls/AdhocFilterControl.jsx | 2 +- .../controls/AnnotationLayerControl.jsx | 2 +- .../components/controls/MetricsControl.jsx | 2 +- .../components/controls/SelectControl.jsx | 2 +- .../deckgl/CategoricalDeckGLContainer.jsx | 2 +- .../src/visualizations/deckgl/Multi/Multi.jsx | 2 +- .../src/visualizations/deckgl/factory.jsx | 2 +- 37 files changed, 431 insertions(+), 454 deletions(-) diff --git a/superset/assets/.eslintrc b/superset/assets/.eslintrc index 276e21c5ed314..c41b7a5d71e76 100644 --- a/superset/assets/.eslintrc +++ b/superset/assets/.eslintrc @@ -28,37 +28,47 @@ "browser": true }, "rules": { - "prefer-template": 0, - "new-cap": 0, - "no-restricted-syntax": 0, - "guard-for-in": 0, - "prefer-arrow-callback": 0, + "camelcase": ["error", { + "allow": ["^UNSAFE_"], + "properties": "never" + }], + "class-methods-use-this": 0, "func-names": 0, - "react/jsx-no-bind": 0, - "no-confusing-arrow": 0, - "jsx-a11y/no-static-element-interactions": 0, + "guard-for-in": 0, + "import/extensions": ["error", { + ".js": "always", + ".jsx": "always", + ".ts": "always", + ".tsx": "always", + ".json": "always" + }], + "import/no-named-as-default": 0, + "import/prefer-default-export": 0, + "indent": 0, "jsx-a11y/anchor-has-content": 0, - "react/require-default-props": 0, - "no-plusplus": 0, - "no-mixed-operators": 0, - "no-continue": 0, + "jsx-a11y/href-no-hash": 0, + "jsx-a11y/no-static-element-interactions": 0, + "new-cap": 0, "no-bitwise": 0, + "no-confusing-arrow": 0, + "no-continue": 0, + "no-mixed-operators": 0, "no-multi-assign": 0, - "react/no-array-index-key": 0, - "no-restricted-properties": 0, + "no-multi-spaces": 0, + "no-plusplus": 0, "no-prototype-builtins": 0, - "jsx-a11y/href-no-hash": 0, + "no-restricted-properties": 0, + "no-restricted-syntax": 0, + "padded-blocks": 0, + "prefer-arrow-callback": 0, + "prefer-template": 0, "react/forbid-prop-types": 0, - "class-methods-use-this": 0, - "import/no-named-as-default": 0, - "import/prefer-default-export": 0, + "react/jsx-no-bind": 0, + "react/no-array-index-key": 0, + "react/no-string-refs": 0, "react/no-unescaped-entities": 0, "react/no-unused-prop-types": 0, - "react/no-string-refs": 0, - "indent": 0, - "no-multi-spaces": 0, - "padded-blocks": 0, - "import/extensions": [".js", ".jsx", ".ts", ".tsx", ".json"] + "react/require-default-props": 0 }, "settings": { "import/resolver": "webpack" diff --git a/superset/assets/package-lock.json b/superset/assets/package-lock.json index 1df1124e2444b..8fc440a8ec31a 100644 --- a/superset/assets/package-lock.json +++ b/superset/assets/package-lock.json @@ -5006,21 +5006,10 @@ } }, "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "dev": true }, "acorn-walk": { "version": "6.1.1", @@ -5846,76 +5835,26 @@ "dev": true }, "babel-eslint": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz", - "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.0.0", "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "path-parse": "^1.0.6" } } } @@ -6699,19 +6638,10 @@ } } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { @@ -6795,9 +6725,9 @@ "integrity": "sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ==" }, "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "charenc": { @@ -7544,12 +7474,6 @@ "safe-buffer": "^5.0.1" } }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -7587,6 +7511,15 @@ "rimraf": "^2.6.1" } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -9617,67 +9550,66 @@ } }, "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.2.tgz", + "integrity": "sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw==", "dev": true, "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", + "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { @@ -9690,9 +9622,9 @@ } }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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", @@ -9700,57 +9632,59 @@ "supports-color": "^5.3.0" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "ms": "^2.1.1" } }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { - "ms": "^2.1.1" + "esutils": "^2.0.2" } }, - "fast-deep-equal": { + "eslint-visitor-keys": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, - "globals": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz", - "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", - "dev": true + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "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 }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } }, "supports-color": { @@ -9761,6 +9695,12 @@ "requires": { "has-flag": "^3.0.0" } + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true } } }, @@ -10022,15 +9962,24 @@ "dev": true }, "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -10043,13 +9992,28 @@ "integrity": "sha512-wOuWtQCkkwD1WKQN/k3RsyGSSN+AmiUzdKftn8vaC+uV9JesYmQlODJxgXaaRz0LaaFIlUxZaUu5NPiUAjKAAA==" }, "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + } } }, "esprima": { @@ -10295,25 +10259,14 @@ } }, "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", "tmp": "^0.0.33" - }, - "dependencies": { - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - } } }, "extglob": { @@ -10506,14 +10459,22 @@ "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", "dev": true }, - "file-entry-cache": { + "figures": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^2.0.1" } }, "file-loader": { @@ -10591,15 +10552,25 @@ } }, "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flat-colors": { @@ -10607,6 +10578,12 @@ "resolved": "https://registry.npmjs.org/flat-colors/-/flat-colors-3.0.0.tgz", "integrity": "sha1-JTqxojmJwyHxOwrNS/c//0By7Lc=" }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -11871,6 +11848,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", @@ -12689,9 +12675,9 @@ "dev": true }, "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "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 }, "ignore-styles": { @@ -12855,33 +12841,26 @@ } }, "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "external-editor": "^2.0.4", + "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.3.0", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", + "rxjs": "^6.4.0", "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { - "ansi-escapes": { - "version": "3.1.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -12898,9 +12877,9 @@ } }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "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", @@ -12908,49 +12887,12 @@ "supports-color": "^5.3.0" } }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -12959,15 +12901,34 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } }, "supports-color": { @@ -13321,6 +13282,12 @@ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "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": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -13341,6 +13308,15 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "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-hexadecimal": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz", @@ -16943,6 +16919,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, "opener": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", @@ -17145,6 +17130,15 @@ "readable-stream": "^2.1.5" } }, + "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-asn1": { "version": "5.1.1", "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", @@ -17381,12 +17375,6 @@ "find-up": "^2.1.0" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -21050,9 +21038,9 @@ "dev": true }, "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, "regexpu-core": { @@ -21196,16 +21184,6 @@ "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz", "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk=" }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -21248,9 +21226,9 @@ } }, "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "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 }, "resolve-protobuf-schema": { @@ -21267,6 +21245,16 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -21351,19 +21339,13 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", "dev": true, "requires": { - "rx-lite": "*" + "tslib": "^1.9.0" } }, "safe-buffer": { @@ -21743,6 +21725,34 @@ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.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" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -22438,9 +22448,9 @@ "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, "style-loader": { @@ -22659,67 +22669,39 @@ "dev": true }, "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" }, "dependencies": { "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "is-fullwidth-code-point": { @@ -22728,47 +22710,24 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ansi-regex": "^4.1.0" } } } @@ -23019,6 +22978,15 @@ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -26911,9 +26879,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { "mkdirp": "^0.5.1" diff --git a/superset/assets/package.json b/superset/assets/package.json index 001f51bdbc2a5..a110ad24c6654 100644 --- a/superset/assets/package.json +++ b/superset/assets/package.json @@ -162,7 +162,7 @@ "@types/react": "^16.4.18", "@types/react-dom": "^16.0.9", "babel-core": "^7.0.0-bridge.0", - "babel-eslint": "^10.0.1", + "babel-eslint": "^10.0.3", "babel-jest": "^24.8.0", "babel-loader": "^8.0.4", "babel-plugin-css-modules-transform": "^1.1.0", @@ -175,7 +175,7 @@ "css-loader": "^1.0.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", - "eslint": "^4.19.1", + "eslint": "^6.2.2", "eslint-config-airbnb": "^15.0.1", "eslint-config-prettier": "^2.9.0", "eslint-import-resolver-webpack": "^0.10.1", diff --git a/superset/assets/spec/javascripts/components/AlteredSliceTag_spec.jsx b/superset/assets/spec/javascripts/components/AlteredSliceTag_spec.jsx index b90acf48d15c0..51f0002497d9a 100644 --- a/superset/assets/spec/javascripts/components/AlteredSliceTag_spec.jsx +++ b/superset/assets/spec/javascripts/components/AlteredSliceTag_spec.jsx @@ -145,7 +145,7 @@ describe('AlteredSliceTag', () => { }; newProps.currentFormData.beta = 10; wrapper = shallow(); - wrapper.instance().componentWillReceiveProps(newProps); + wrapper.instance().UNSAFE_componentWillReceiveProps(newProps); const newDiffs = wrapper.instance().state.diffs; const expectedBeta = { before: undefined, after: 10 }; expect(newDiffs.beta).toEqual(expectedBeta); @@ -153,7 +153,7 @@ describe('AlteredSliceTag', () => { it('does not set new state when props are the same', () => { const currentDiff = wrapper.instance().state.diffs; - wrapper.instance().componentWillReceiveProps(props); + wrapper.instance().UNSAFE_componentWillReceiveProps(props); // Check equal references expect(wrapper.instance().state.diffs).toBe(currentDiff); }); diff --git a/superset/assets/spec/javascripts/dashboard/components/Dashboard_spec.jsx b/superset/assets/spec/javascripts/dashboard/components/Dashboard_spec.jsx index 22ed6d6169a7e..02e71e44c9e50 100644 --- a/superset/assets/spec/javascripts/dashboard/components/Dashboard_spec.jsx +++ b/superset/assets/spec/javascripts/dashboard/components/Dashboard_spec.jsx @@ -160,7 +160,7 @@ describe('Dashboard', () => { it('should call addSliceToDashboard if a new slice is added to the layout', () => { const wrapper = setup(); const spy = sinon.spy(props.actions, 'addSliceToDashboard'); - wrapper.instance().componentWillReceiveProps({ + wrapper.instance().UNSAFE_componentWillReceiveProps({ ...props, layout: layoutWithExtraChart, }); @@ -174,7 +174,7 @@ describe('Dashboard', () => { const nextLayout = { ...layoutWithExtraChart }; delete nextLayout[1001]; - wrapper.instance().componentWillReceiveProps({ + wrapper.instance().UNSAFE_componentWillReceiveProps({ ...props, layout: nextLayout, }); diff --git a/superset/assets/spec/javascripts/dashboard/components/SliceAdder_spec.jsx b/superset/assets/spec/javascripts/dashboard/components/SliceAdder_spec.jsx index 986df264ce7c2..945abc4ee5bf2 100644 --- a/superset/assets/spec/javascripts/dashboard/components/SliceAdder_spec.jsx +++ b/superset/assets/spec/javascripts/dashboard/components/SliceAdder_spec.jsx @@ -109,7 +109,7 @@ describe('SliceAdder', () => { }); it('fetch slices should update state', () => { - wrapper.instance().componentWillReceiveProps({ + wrapper.instance().UNSAFE_componentWillReceiveProps({ ...props, lastUpdated: new Date().getTime(), }); @@ -122,7 +122,7 @@ describe('SliceAdder', () => { }); it('select slices should update state', () => { - wrapper.instance().componentWillReceiveProps({ + wrapper.instance().UNSAFE_componentWillReceiveProps({ ...props, selectedSliceIds: [127], }); diff --git a/superset/assets/spec/javascripts/sqllab/ResultSet_spec.jsx b/superset/assets/spec/javascripts/sqllab/ResultSet_spec.jsx index e02d797abbb7d..8aa00a9a989bf 100644 --- a/superset/assets/spec/javascripts/sqllab/ResultSet_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/ResultSet_spec.jsx @@ -70,7 +70,7 @@ describe('ResultSet', () => { beforeEach(() => { clearQuerySpy.reset(); fetchQuerySpy.reset(); - spy = sinon.spy(ResultSet.prototype, 'componentWillReceiveProps'); + spy = sinon.spy(ResultSet.prototype, 'UNSAFE_componentWillReceiveProps'); }); afterEach(() => { spy.restore(); diff --git a/superset/assets/src/CRUD/CollectionTable.jsx b/superset/assets/src/CRUD/CollectionTable.jsx index 2feaed639dff7..ffe0733ef87d9 100644 --- a/superset/assets/src/CRUD/CollectionTable.jsx +++ b/superset/assets/src/CRUD/CollectionTable.jsx @@ -82,7 +82,7 @@ export default class CRUDCollection extends React.PureComponent { this.renderTableBody = this.renderTableBody.bind(this); this.changeCollection = this.changeCollection.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.collection !== this.props.collection) { this.setState({ collection: createKeyedCollection(nextProps.collection), diff --git a/superset/assets/src/SqlLab/components/AceEditorWrapper.jsx b/superset/assets/src/SqlLab/components/AceEditorWrapper.jsx index 661b7d06638c0..0ae43624fca5b 100644 --- a/superset/assets/src/SqlLab/components/AceEditorWrapper.jsx +++ b/superset/assets/src/SqlLab/components/AceEditorWrapper.jsx @@ -83,7 +83,7 @@ class AceEditorWrapper extends React.PureComponent { this.props.actions.queryEditorSetSelectedText(this.props.queryEditor, null); this.setAutoCompleter(this.props); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (!areArraysShallowEqual(this.props.tables, nextProps.tables) || !areArraysShallowEqual(this.props.schemas, nextProps.schemas) || !areArraysShallowEqual(this.props.extendedTables, nextProps.extendedTables)) { diff --git a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx index 3fcab31a64de0..ee508d90541d8 100644 --- a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx +++ b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx @@ -36,7 +36,7 @@ class QueryAutoRefresh extends React.PureComponent { offline: props.offline, }; } - componentWillMount() { + UNSAFE_componentWillMount() { this.startTimer(); } componentDidUpdate(prevProps) { diff --git a/superset/assets/src/SqlLab/components/ResultSet.jsx b/superset/assets/src/SqlLab/components/ResultSet.jsx index e0dd5700accbf..1ebe812c13a3d 100644 --- a/superset/assets/src/SqlLab/components/ResultSet.jsx +++ b/superset/assets/src/SqlLab/components/ResultSet.jsx @@ -69,7 +69,7 @@ export default class ResultSet extends React.PureComponent { // only do this the first time the component is rendered/mounted this.reRunQueryIfSessionTimeoutErrorOnMount(); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { // when new results comes in, save them locally and clear in store if (this.props.cache && (!nextProps.query.cached) && nextProps.query.results diff --git a/superset/assets/src/SqlLab/components/SouthPane.jsx b/superset/assets/src/SqlLab/components/SouthPane.jsx index ab9e658d41875..debc8ded59ef9 100644 --- a/superset/assets/src/SqlLab/components/SouthPane.jsx +++ b/superset/assets/src/SqlLab/components/SouthPane.jsx @@ -61,7 +61,7 @@ export class SouthPane extends React.PureComponent { this.getSouthPaneHeight = this.getSouthPaneHeight.bind(this); this.switchTab = this.switchTab.bind(this); } - componentWillReceiveProps() { + UNSAFE_componentWillReceiveProps() { // south pane expands the entire height of the tab content on mount this.setState({ height: this.getSouthPaneHeight() }); } diff --git a/superset/assets/src/SqlLab/components/SqlEditor.jsx b/superset/assets/src/SqlLab/components/SqlEditor.jsx index 8524daaea6483..cb0c6179fa255 100644 --- a/superset/assets/src/SqlLab/components/SqlEditor.jsx +++ b/superset/assets/src/SqlLab/components/SqlEditor.jsx @@ -114,7 +114,7 @@ class SqlEditor extends React.PureComponent { WINDOW_RESIZE_THROTTLE_MS, ); } - componentWillMount() { + UNSAFE_componentWillMount() { if (this.state.autorun) { this.setState({ autorun: false }); this.props.actions.queryEditorSetAutorun(this.props.queryEditor, false); diff --git a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx index 7c32021107e2d..c50b8b11d9ea4 100644 --- a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx @@ -104,7 +104,7 @@ class TabbedSqlEditors extends React.PureComponent { this.popNewTab(); } } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const nextActiveQeId = nextProps.tabHistory[nextProps.tabHistory.length - 1]; const queriesArray = []; for (const id in nextProps.queries) { diff --git a/superset/assets/src/chart/chartAction.js b/superset/assets/src/chart/chartAction.js index c8c9c5d2b03cd..69a074d9c9b3c 100644 --- a/superset/assets/src/chart/chartAction.js +++ b/superset/assets/src/chart/chartAction.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ -/* global window, AbortController */ /* eslint no-undef: 'error' */ /* eslint no-param-reassign: ["error", { "props": false }] */ import { t } from '@superset-ui/translation'; @@ -114,8 +113,8 @@ export function runAnnotationQuery(annotation, timeout = 60, formData = null, ke ); if (fd !== null) { - const hasExtraFilters = fd.extra_filters && fd.extra_filters.length > 0; - sliceFormData.extra_filters = hasExtraFilters ? fd.extra_filters : undefined; + const hasExtraFilters = fd.extra_filters && fd.extra_filters.length > 0; + sliceFormData.extra_filters = hasExtraFilters ? fd.extra_filters : undefined; } const isNative = annotation.sourceType === ANNOTATION_SOURCE_TYPES.NATIVE; @@ -140,7 +139,7 @@ export function runAnnotationQuery(annotation, timeout = 60, formData = null, ke dispatch(annotationQueryFailed(annotation, err, sliceKey)); } }), - ); + ); }; } diff --git a/superset/assets/src/components/AlteredSliceTag.jsx b/superset/assets/src/components/AlteredSliceTag.jsx index 985b16f427356..a2746aaacb614 100644 --- a/superset/assets/src/components/AlteredSliceTag.jsx +++ b/superset/assets/src/components/AlteredSliceTag.jsx @@ -57,7 +57,7 @@ export default class AlteredSliceTag extends React.Component { this.state = { diffs, hasDiffs: !isEmpty(diffs) }; } - componentWillReceiveProps(newProps) { + UNSAFE_componentWillReceiveProps(newProps) { // Update differences if need be if (isEqual(this.props, newProps)) { return; diff --git a/superset/assets/src/components/AnchorLink.jsx b/superset/assets/src/components/AnchorLink.jsx index e703013f4cf9a..f99403a423a83 100644 --- a/superset/assets/src/components/AnchorLink.jsx +++ b/superset/assets/src/components/AnchorLink.jsx @@ -50,7 +50,7 @@ class AnchorLink extends React.PureComponent { } } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const { inFocus = false } = nextProps; if (inFocus) { this.scrollToView(); diff --git a/superset/assets/src/components/EditableTitle.jsx b/superset/assets/src/components/EditableTitle.jsx index 80e91fdf71744..fc6d47615f803 100644 --- a/superset/assets/src/components/EditableTitle.jsx +++ b/superset/assets/src/components/EditableTitle.jsx @@ -61,7 +61,7 @@ export default class EditableTitle extends React.PureComponent { this.contentRef = React.createRef(); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.title !== this.state.title) { this.setState({ lastTitle: this.state.title, diff --git a/superset/assets/src/components/TableLoader.jsx b/superset/assets/src/components/TableLoader.jsx index 65cafaf19147a..0545fef55aa90 100644 --- a/superset/assets/src/components/TableLoader.jsx +++ b/superset/assets/src/components/TableLoader.jsx @@ -45,7 +45,7 @@ class TableLoader extends React.PureComponent { }; } - componentWillMount() { + UNSAFE_componentWillMount() { const { dataEndpoint, mutator } = this.props; SupersetClient.get({ endpoint: dataEndpoint }) diff --git a/superset/assets/src/components/Timer.jsx b/superset/assets/src/components/Timer.jsx index 4370f3382c751..8f77797f62383 100644 --- a/superset/assets/src/components/Timer.jsx +++ b/superset/assets/src/components/Timer.jsx @@ -43,7 +43,7 @@ export default class Timer extends React.PureComponent { }; this.stopwatch = this.stopwatch.bind(this); } - componentWillMount() { + UNSAFE_componentWillMount() { this.startTimer(); } componentWillUnmount() { diff --git a/superset/assets/src/dashboard/components/Dashboard.jsx b/superset/assets/src/dashboard/components/Dashboard.jsx index 72d3d949fe7c9..334704e4c697a 100644 --- a/superset/assets/src/dashboard/components/Dashboard.jsx +++ b/superset/assets/src/dashboard/components/Dashboard.jsx @@ -89,7 +89,7 @@ class Dashboard extends React.PureComponent { this.props.actions.logEvent(LOG_ACTIONS_MOUNT_DASHBOARD); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const currentChartIds = getChartIdsFromLayout(this.props.layout); const nextChartIds = getChartIdsFromLayout(nextProps.layout); diff --git a/superset/assets/src/dashboard/components/DashboardBuilder.jsx b/superset/assets/src/dashboard/components/DashboardBuilder.jsx index a5e3d2997529c..de9a94eddd23a 100644 --- a/superset/assets/src/dashboard/components/DashboardBuilder.jsx +++ b/superset/assets/src/dashboard/components/DashboardBuilder.jsx @@ -122,7 +122,7 @@ class DashboardBuilder extends React.Component { }; } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const nextFocusComponent = getLeafComponentIdFromPath( nextProps.directPathToChild, ); diff --git a/superset/assets/src/dashboard/components/Header.jsx b/superset/assets/src/dashboard/components/Header.jsx index d8bacf8253b68..b80727370d995 100644 --- a/superset/assets/src/dashboard/components/Header.jsx +++ b/superset/assets/src/dashboard/components/Header.jsx @@ -123,7 +123,7 @@ class Header extends React.PureComponent { this.props.startPeriodicRender(refreshFrequency * 1000); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if ( UNDO_LIMIT - nextProps.undoLength <= 0 && !this.state.didNotifyMaxUndoHistoryToast diff --git a/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx b/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx index af82267f1d221..6fc0182551e56 100644 --- a/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx +++ b/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx @@ -76,7 +76,7 @@ class HeaderActionsDropdown extends React.PureComponent { this.changeRefreshInterval = this.changeRefreshInterval.bind(this); } - componentWillMount() { + UNSAFE_componentWillMount() { injectCustomCss(this.state.css); SupersetClient.get({ endpoint: '/csstemplateasyncmodelview/api/read' }) diff --git a/superset/assets/src/dashboard/components/SliceAdder.jsx b/superset/assets/src/dashboard/components/SliceAdder.jsx index dd6ad56756847..f9c256f87f104 100644 --- a/superset/assets/src/dashboard/components/SliceAdder.jsx +++ b/superset/assets/src/dashboard/components/SliceAdder.jsx @@ -102,7 +102,7 @@ class SliceAdder extends React.Component { this.slicesRequest = this.props.fetchAllSlices(this.props.userId); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const nextState = {}; if (nextProps.lastUpdated !== this.props.lastUpdated) { nextState.filteredSlices = Object.values(nextProps.slices) diff --git a/superset/assets/src/dashboard/components/gridComponents/Markdown.jsx b/superset/assets/src/dashboard/components/gridComponents/Markdown.jsx index a5614f1592c24..6329824aa4615 100644 --- a/superset/assets/src/dashboard/components/gridComponents/Markdown.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/Markdown.jsx @@ -100,7 +100,7 @@ class Markdown extends React.PureComponent { }); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const nextSource = nextProps.component.meta.code; if (this.state.markdownSource !== nextSource) { this.setState({ markdownSource: nextSource }); diff --git a/superset/assets/src/dashboard/components/gridComponents/Tabs.jsx b/superset/assets/src/dashboard/components/gridComponents/Tabs.jsx index c8ffa41249211..ce565fec3ec8d 100644 --- a/superset/assets/src/dashboard/components/gridComponents/Tabs.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/Tabs.jsx @@ -97,7 +97,7 @@ class Tabs extends React.PureComponent { this.handleDropOnTab = this.handleDropOnTab.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const maxIndex = Math.max(0, nextProps.component.children.length - 1); if (this.state.tabIndex > maxIndex) { this.setState(() => ({ tabIndex: maxIndex })); diff --git a/superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx b/superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx index 6131bdf272e23..42158dccfe69b 100644 --- a/superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx +++ b/superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx @@ -53,7 +53,7 @@ class WithPopoverMenu extends React.PureComponent { this.handleClick = this.handleClick.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.editMode && nextProps.isFocused && !this.state.isFocused) { document.addEventListener('click', this.handleClick); document.addEventListener('drag', this.handleClick); diff --git a/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx b/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx index 8faffbda2d605..c84d6bf3bd4f7 100644 --- a/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx +++ b/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx @@ -96,7 +96,7 @@ export default class AdhocFilterEditPopoverSimpleTabContent extends React.Compon }; } - componentWillMount() { + UNSAFE_componentWillMount() { this.refreshComparatorSuggestions(); } diff --git a/superset/assets/src/explore/components/ExploreViewContainer.jsx b/superset/assets/src/explore/components/ExploreViewContainer.jsx index 7990c9be1f971..88da0f97119fe 100644 --- a/superset/assets/src/explore/components/ExploreViewContainer.jsx +++ b/superset/assets/src/explore/components/ExploreViewContainer.jsx @@ -103,7 +103,7 @@ class ExploreViewContainer extends React.Component { } } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.controls.viz_type.value !== this.props.controls.viz_type.value) { this.props.actions.resetControls(); } diff --git a/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx b/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx index cbec5c87ef365..312f6bb54d8b2 100644 --- a/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx +++ b/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx @@ -89,7 +89,7 @@ export default class AdhocFilterControl extends React.Component { }; } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if ( this.props.columns !== nextProps.columns || this.props.formData !== nextProps.formData diff --git a/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx b/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx index 6f71c22e7ba83..6180ba1064332 100644 --- a/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx +++ b/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx @@ -56,7 +56,7 @@ class AnnotationLayerControl extends React.PureComponent { this.removeAnnotationLayer = this.removeAnnotationLayer.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const { name, annotationError, validationErrors, value } = nextProps; if (Object.keys(annotationError).length && !validationErrors.length) { this.props.actions.setControlValue(name, value, Object.keys(annotationError)); diff --git a/superset/assets/src/explore/components/controls/MetricsControl.jsx b/superset/assets/src/explore/components/controls/MetricsControl.jsx index a998283f0ccfd..f72dce3f1dec4 100644 --- a/superset/assets/src/explore/components/controls/MetricsControl.jsx +++ b/superset/assets/src/explore/components/controls/MetricsControl.jsx @@ -151,7 +151,7 @@ export default class MetricsControl extends React.PureComponent { }; } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const { value } = this.props; if ( !isEqual(this.props.columns, nextProps.columns) || diff --git a/superset/assets/src/explore/components/controls/SelectControl.jsx b/superset/assets/src/explore/components/controls/SelectControl.jsx index 906d867eab5e4..852425a60a4bc 100644 --- a/superset/assets/src/explore/components/controls/SelectControl.jsx +++ b/superset/assets/src/explore/components/controls/SelectControl.jsx @@ -82,7 +82,7 @@ export default class SelectControl extends React.PureComponent { this.createMetaSelectAllOption = this.createMetaSelectAllOption.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.choices !== this.props.choices || nextProps.options !== this.props.options) { const options = this.getOptions(nextProps); diff --git a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx index 7352b3d49512c..2a3e7b3c717a8 100644 --- a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx +++ b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx @@ -78,7 +78,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { this.toggleCategory = this.toggleCategory.bind(this); this.showSingleCategory = this.showSingleCategory.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.payload.form_data !== this.state.formData) { this.setState({ ...this.getStateFromProps(nextProps) }); } diff --git a/superset/assets/src/visualizations/deckgl/Multi/Multi.jsx b/superset/assets/src/visualizations/deckgl/Multi/Multi.jsx index 095ea8b4a6f33..335ba3a7e02be 100644 --- a/superset/assets/src/visualizations/deckgl/Multi/Multi.jsx +++ b/superset/assets/src/visualizations/deckgl/Multi/Multi.jsx @@ -52,7 +52,7 @@ class DeckMulti extends React.PureComponent { this.loadLayers(formData, payload); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const { formData, payload } = nextProps; const hasChanges = !_.isEqual(this.props.formData.deck_slices, nextProps.formData.deck_slices); if (hasChanges) { diff --git a/superset/assets/src/visualizations/deckgl/factory.jsx b/superset/assets/src/visualizations/deckgl/factory.jsx index 1ad8bd373d4c5..abbdcca0db433 100644 --- a/superset/assets/src/visualizations/deckgl/factory.jsx +++ b/superset/assets/src/visualizations/deckgl/factory.jsx @@ -52,7 +52,7 @@ export function createDeckGLComponent(getLayer, getPoints) { }; this.onViewportChange = this.onViewportChange.bind(this); } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { // Only recompute the layer if anything BUT the viewport has changed const nextFdNoVP = { ...nextProps.formData, viewport: null }; const currFdNoVP = { ...this.props.formData, viewport: null }; From 00257b94337988ad5840fac1e245ce28a85b09dd Mon Sep 17 00:00:00 2001 From: serenajiang Date: Tue, 3 Sep 2019 16:37:42 -0700 Subject: [PATCH 02/19] [sqllab] add retries for stop_query (#8139) * [sqllab] add retries for stop_query * use backoff for retries * address PR comments * import statement order --- requirements.txt | 1 + setup.py | 1 + superset/sql_lab.py | 42 +++++++++++++++++++++++++----------------- superset/views/core.py | 30 ++++++++++++++++++++++++------ 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/requirements.txt b/requirements.txt index 32afb6c8e35ad..7b85ebe4c72d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ apispec[yaml]==1.3.3 # via flask-appbuilder asn1crypto==0.24.0 # via cryptography attrs==19.1.0 # via jsonschema babel==2.7.0 # via flask-babel +backoff==1.8.0 billiard==3.6.0.0 # via celery bleach==3.1.0 celery==4.3.0 diff --git a/setup.py b/setup.py index d4620d054b91d..7bcc48640153c 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ def get_git_sha(): zip_safe=False, scripts=["superset/bin/superset"], install_requires=[ + "backoff>=1.8.0", "bleach>=3.0.2, <4.0.0", "celery>=4.3.0, <5.0.0", "click>=6.0, <7.0.0", # `click`>=7 forces "-" instead of "_" diff --git a/superset/sql_lab.py b/superset/sql_lab.py index bc649e839afdc..1094c0ecc6eeb 100644 --- a/superset/sql_lab.py +++ b/superset/sql_lab.py @@ -19,10 +19,10 @@ from datetime import datetime import logging from sys import getsizeof -from time import sleep from typing import Optional, Tuple, Union import uuid +import backoff from celery.exceptions import SoftTimeLimitExceeded from contextlib2 import contextmanager from flask_babel import lazy_gettext as _ @@ -82,23 +82,31 @@ def handle_query_error(msg, query, session, payload=None): return payload -def get_query(query_id, session, retry_count=5): - """attemps to get the query and retry if it cannot""" - query = None - attempt = 0 - while not query and attempt < retry_count: - try: - query = session.query(Query).filter_by(id=query_id).one() - except Exception: - attempt += 1 - logging.error(f"Query with id `{query_id}` could not be retrieved") - stats_logger.incr("error_attempting_orm_query_" + str(attempt)) - logging.error(f"Query {query_id}: Sleeping for a sec before retrying...") - sleep(1) - if not query: - stats_logger.incr("error_failed_at_getting_orm_query") +def get_query_backoff_handler(details): + query_id = details["kwargs"]["query_id"] + logging.error(f"Query with id `{query_id}` could not be retrieved") + stats_logger.incr("error_attempting_orm_query_{}".format(details["tries"] - 1)) + logging.error(f"Query {query_id}: Sleeping for a sec before retrying...") + + +def get_query_giveup_handler(details): + stats_logger.incr("error_failed_at_getting_orm_query") + + +@backoff.on_exception( + backoff.constant, + SqlLabException, + interval=1, + on_backoff=get_query_backoff_handler, + on_giveup=get_query_giveup_handler, + max_tries=5, +) +def get_query(query_id, session): + """attempts to get the query and retry if it cannot""" + try: + return session.query(Query).filter_by(id=query_id).one() + except Exception: raise SqlLabException("Failed at getting query") - return query @contextmanager diff --git a/superset/views/core.py b/superset/views/core.py index fab1800c811be..d413288425499 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -22,6 +22,7 @@ from typing import Dict, List, Optional, Union # noqa: F401 from urllib import parse +import backoff from flask import ( abort, flash, @@ -45,6 +46,7 @@ import pyarrow as pa import simplejson as json from sqlalchemy import and_, or_, select +from sqlalchemy.exc import DatabaseError from werkzeug.routing import BaseConverter from superset import ( @@ -2466,14 +2468,30 @@ def results(self, key): @has_access_api @expose("/stop_query/", methods=["POST"]) @event_logger.log_this + @backoff.on_exception( + backoff.constant, + DatabaseError, + interval=1, + on_backoff=lambda details: db.session.rollback(), + on_giveup=lambda details: db.session.rollback(), + max_tries=5, + ) def stop_query(self): client_id = request.form.get("client_id") - try: - query = db.session.query(Query).filter_by(client_id=client_id).one() - query.status = QueryStatus.STOPPED - db.session.commit() - except Exception: - pass + + query = db.session.query(Query).filter_by(client_id=client_id).one() + if query.status in [ + QueryStatus.FAILED, + QueryStatus.SUCCESS, + QueryStatus.TIMED_OUT, + ]: + logging.error( + f"Query with client_id {client_id} could not be stopped: query already complete" + ) + return self.json_response("OK") + query.status = QueryStatus.STOPPED + db.session.commit() + return self.json_response("OK") @has_access_api From 650de93752059a510f15aa8203c486954a76b8e3 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Tue, 3 Sep 2019 23:56:50 -0700 Subject: [PATCH 03/19] Bump cypress from 3.1.5 to 3.4.1 (#8158) --- superset/assets/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset/assets/package.json b/superset/assets/package.json index a110ad24c6654..3c936f36b8d69 100644 --- a/superset/assets/package.json +++ b/superset/assets/package.json @@ -19,7 +19,7 @@ "lint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx . && tslint -c tslint.json --fix ./{src,spec}/**/*.ts{,x}", "cypress": "cypress", "cypress-debug": "cypress open --config watchForFileChanges=true", - "install-cypress": "npm install cypress@3.1.5" + "install-cypress": "npm install cypress@3.4.1" }, "repository": { "type": "git", From ae0dc30c0a428e53d77bd00484aac5663a2856b5 Mon Sep 17 00:00:00 2001 From: ericandrewmeadows Date: Wed, 4 Sep 2019 10:21:13 -0700 Subject: [PATCH 04/19] Fix to Werkzeug ProxyFix; expose ProxyFix configuration items (#8117) * Fix to werkzeug proxy; expose additional configuration items * Forced to all x-forwarded configurations ON; black done * added comments related to x_port after testing * Updated UPDATING.md * Removed accidental notebook; added *.ipynb to gitignore * Delete Untitled-checkpoint.ipynb --- .gitignore | 1 + UPDATING.md | 5 +++++ setup.py | 2 +- superset/__init__.py | 5 +++-- superset/config.py | 4 +++- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index ad106b34fa1ad..ab5126af5d5e3 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +*.ipynb *.bak *.db *.pyc diff --git a/UPDATING.md b/UPDATING.md index 9fc0c356d4505..654eb914b3b02 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -23,6 +23,11 @@ assists people when migrating to a new version. ## Next Version +* [8117](https://github.com/apache/incubator-superset/pull/8117): If you are +using `ENABLE_PROXY_FIX = True`, review the newly-introducted variable, +`PROXY_FIX_CONFIG`, which changes the proxy behavior in accordance with +[Werkzeug](https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/) + * [8069](https://github.com/apache/incubator-superset/pull/8069): introduces [MessagePack](https://github.com/msgpack/msgpack-python) and [PyArrow](https://arrow.apache.org/docs/python/) for async query results diff --git a/setup.py b/setup.py index 7bcc48640153c..5a17843d6ac93 100644 --- a/setup.py +++ b/setup.py @@ -73,7 +73,7 @@ def get_git_sha(): "contextlib2", "croniter>=0.3.28", "cryptography>=2.4.2", - "flask>=1.0.0, <2.0.0", + "flask>=1.1.0, <2.0.0", "flask-appbuilder>=2.1.9, <2.3.0", "flask-caching", "flask-compress", diff --git a/superset/__init__.py b/superset/__init__.py index d841bcf378b75..8481d2a684a16 100644 --- a/superset/__init__.py +++ b/superset/__init__.py @@ -28,7 +28,6 @@ from flask_migrate import Migrate from flask_talisman import Talisman from flask_wtf.csrf import CSRFProtect -from werkzeug.contrib.fixers import ProxyFix import wtforms_json from superset import config @@ -139,7 +138,9 @@ def get_manifest(): CORS(app, **app.config.get("CORS_OPTIONS")) if app.config.get("ENABLE_PROXY_FIX"): - app.wsgi_app = ProxyFix(app.wsgi_app) + from werkzeug.middleware.proxy_fix import ProxyFix + + app.wsgi_app = ProxyFix(app.wsgi_app, **app.config.get("PROXY_FIX_CONFIG")) if app.config.get("ENABLE_CHUNK_ENCODING"): diff --git a/superset/config.py b/superset/config.py index e0fb649f19c80..782cdcbf0512d 100644 --- a/superset/config.py +++ b/superset/config.py @@ -123,8 +123,10 @@ # and it's more secure to turn it off in production settings. SHOW_STACKTRACE = True -# Extract and use X-Forwarded-For/X-Forwarded-Proto headers? +# Use all X-Forwarded headers when ENABLE_PROXY_FIX is True. +# When proxying to a different port, set "x_port" to 0 to avoid downstream issues. ENABLE_PROXY_FIX = False +PROXY_FIX_CONFIG = {"x_for": 1, "x_proto": 1, "x_host": 1, "x_port": 1, "x_prefix": 1} # ------------------------------ # GLOBALS FOR APP Builder From 8f071e8f7e9a7e4d56f45dd116a9362d15bc6b13 Mon Sep 17 00:00:00 2001 From: klxiang <39042920+klxiang@users.noreply.github.com> Date: Fri, 6 Sep 2019 02:25:24 +0800 Subject: [PATCH 05/19] Update messages.json (#8179) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Pop"这里应该翻译成"弹出",而不是"流行"。 --- superset/translations/zh/LC_MESSAGES/messages.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/superset/translations/zh/LC_MESSAGES/messages.json b/superset/translations/zh/LC_MESSAGES/messages.json index e5ed80a00ab71..a902a1e62e231 100644 --- a/superset/translations/zh/LC_MESSAGES/messages.json +++ b/superset/translations/zh/LC_MESSAGES/messages.json @@ -3323,7 +3323,7 @@ "编辑保存的查询" ], "Pop Tab Link": [ - "流行标签链接" + "弹出标签链接" ], "Changed on": [ "改变为" @@ -3333,4 +3333,4 @@ ] } } -} \ No newline at end of file +} From 4e1e54b538c935e2d666758341a6dfa00f58e4f3 Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Thu, 5 Sep 2019 22:44:34 +0300 Subject: [PATCH 06/19] [bugfix] Correctly quote table and schema in select_star (#8181) * Fix select_star table quoting bug * Add unit test for fully qualified names in select_star * Rename main_db to db * Rename test function --- superset/connectors/sqla/models.py | 2 +- tests/model_tests.py | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 24d1243b0a708..3407b76f47506 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -478,7 +478,7 @@ def select_star(self): # show_cols and latest_partition set to false to avoid # the expensive cost of inspecting the DB return self.database.select_star( - self.name, show_cols=False, latest_partition=False + self.table_name, schema=self.schema, show_cols=False, latest_partition=False ) def get_col(self, col_name): diff --git a/tests/model_tests.py b/tests/model_tests.py index 55926cfc0d454..f65db84c7661f 100644 --- a/tests/model_tests.py +++ b/tests/model_tests.py @@ -104,9 +104,9 @@ def test_database_impersonate_user(self): self.assertNotEquals(example_user, user_name) def test_select_star(self): - main_db = get_example_database() + db = get_example_database() table_name = "energy_usage" - sql = main_db.select_star(table_name, show_cols=False, latest_partition=False) + sql = db.select_star(table_name, show_cols=False, latest_partition=False) expected = textwrap.dedent( f"""\ SELECT * @@ -115,7 +115,7 @@ def test_select_star(self): ) assert sql.startswith(expected) - sql = main_db.select_star(table_name, show_cols=True, latest_partition=False) + sql = db.select_star(table_name, show_cols=True, latest_partition=False) expected = textwrap.dedent( f"""\ SELECT source, @@ -126,6 +126,28 @@ def test_select_star(self): ) assert sql.startswith(expected) + def test_select_star_fully_qualified_names(self): + db = get_example_database() + schema = "schema.name" + table_name = "table/name" + sql = db.select_star( + table_name, schema=schema, show_cols=False, latest_partition=False + ) + fully_qualified_names = { + "sqlite": '"schema.name"."table/name"', + "mysql": "`schema.name`.`table/name`", + "postgres": '"schema.name"."table/name"', + } + fully_qualified_name = fully_qualified_names.get(db.db_engine_spec.engine) + if fully_qualified_name: + expected = textwrap.dedent( + f"""\ + SELECT * + FROM {fully_qualified_name} + LIMIT 100""" + ) + assert sql.startswith(expected) + def test_single_statement(self): main_db = get_main_database() From 15e623898d4780a08808b9f42f0ecb243397d261 Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Fri, 6 Sep 2019 13:05:17 +0300 Subject: [PATCH 07/19] Make orderby native sqla construct (#8180) --- superset/connectors/sqla/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 3407b76f47506..fbb909b5a51ca 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -794,6 +794,8 @@ def get_sqla_query( # sqla direction = asc if ascending else desc if utils.is_adhoc_metric(col): col = self.adhoc_metric_to_sqla(col, cols) + elif col in cols: + col = cols[col].get_sqla_col() qry = qry.order_by(direction(col)) if row_limit: From be33934b838f9fae097882d401c9473bfc2d124c Mon Sep 17 00:00:00 2001 From: serenajiang Date: Fri, 6 Sep 2019 10:16:08 -0700 Subject: [PATCH 08/19] [fix] retry stop_query on all exceptions (#8184) --- superset/views/core.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/superset/views/core.py b/superset/views/core.py index d413288425499..ecf0770ca9665 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -46,7 +46,6 @@ import pyarrow as pa import simplejson as json from sqlalchemy import and_, or_, select -from sqlalchemy.exc import DatabaseError from werkzeug.routing import BaseConverter from superset import ( @@ -2470,7 +2469,7 @@ def results(self, key): @event_logger.log_this @backoff.on_exception( backoff.constant, - DatabaseError, + Exception, interval=1, on_backoff=lambda details: db.session.rollback(), on_giveup=lambda details: db.session.rollback(), From 9dfa0a3f8e871eb3f4d574bdaed4c492725e2894 Mon Sep 17 00:00:00 2001 From: John Bodley <4567245+john-bodley@users.noreply.github.com> Date: Sat, 7 Sep 2019 23:32:17 -0700 Subject: [PATCH 09/19] Update core.py (#8191) --- superset/views/core.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/superset/views/core.py b/superset/views/core.py index ecf0770ca9665..af4fe7e1e32da 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -2447,10 +2447,7 @@ def results(self, key): ) if rejected_tables: return json_error_response( - security_manager.get_table_access_error_msg( - "{}".format(rejected_tables) - ), - status=403, + security_manager.get_table_access_error_msg(rejected_tables), status=403 ) payload = utils.zlib_decompress(blob, decode=not results_backend_use_msgpack) From 3250c5ac948cae8edd7deb2bf94ef4154608b705 Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Sun, 8 Sep 2019 08:34:40 +0200 Subject: [PATCH 10/19] [bugfix] fix timegrain addon regression (#8165) * Fix regression in time grain addons * Revert privatization of time_grain_functions * Fix test * Rename variable * Fix test * Fix typing error * Refactor and add tests * Add TODO --- superset/db_engine_specs/athena.py | 2 +- superset/db_engine_specs/base.py | 62 ++++++++++++-------------- superset/db_engine_specs/bigquery.py | 2 +- superset/db_engine_specs/clickhouse.py | 2 +- superset/db_engine_specs/db2.py | 2 +- superset/db_engine_specs/drill.py | 2 +- superset/db_engine_specs/druid.py | 2 +- superset/db_engine_specs/impala.py | 2 +- superset/db_engine_specs/kylin.py | 2 +- superset/db_engine_specs/mssql.py | 2 +- superset/db_engine_specs/mysql.py | 2 +- superset/db_engine_specs/oracle.py | 2 +- superset/db_engine_specs/pinot.py | 4 +- superset/db_engine_specs/postgres.py | 2 +- superset/db_engine_specs/presto.py | 2 +- superset/db_engine_specs/snowflake.py | 2 +- superset/db_engine_specs/sqlite.py | 2 +- superset/db_engine_specs/teradata.py | 2 +- tests/db_engine_specs_test.py | 35 ++++++++------- 19 files changed, 67 insertions(+), 66 deletions(-) diff --git a/superset/db_engine_specs/athena.py b/superset/db_engine_specs/athena.py index 861516d43c14b..e516664b76a4c 100644 --- a/superset/db_engine_specs/athena.py +++ b/superset/db_engine_specs/athena.py @@ -23,7 +23,7 @@ class AthenaEngineSpec(BaseEngineSpec): engine = "awsathena" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "date_trunc('second', CAST({col} AS TIMESTAMP))", "PT1M": "date_trunc('minute', CAST({col} AS TIMESTAMP))", diff --git a/superset/db_engine_specs/base.py b/superset/db_engine_specs/base.py index 1a5bb8c656def..7df093fdbb5d8 100644 --- a/superset/db_engine_specs/base.py +++ b/superset/db_engine_specs/base.py @@ -109,34 +109,11 @@ class LimitMethod(object): FORCE_LIMIT = "force_limit" -def _create_time_grains_tuple( - time_grains: Dict[Optional[str], str], - time_grain_functions: Dict[Optional[str], str], - blacklist: List[str], -) -> Tuple[TimeGrain, ...]: - """ - function for creating a tuple of time grains based on time grains provided by - the engine and any potential additional or blacklisted grains in the config file. - - :param time_grains: all time grains supported by the engine + config files - :param time_grain_functions: mapping between time grain id and sql expression - :param blacklist: list of time grain ids to be excluded - :return: final collection of time grains - """ - ret_list = [] - blacklist = blacklist if blacklist else [] - for duration, func in time_grain_functions.items(): - if duration in time_grains and duration not in blacklist: - name = time_grains[duration] - ret_list.append(TimeGrain(name, _(name), func, duration)) - return tuple(ret_list) - - class BaseEngineSpec: """Abstract class for database engine specific configurations""" engine = "base" # str as defined in sqlalchemy.engine.engine - time_grain_functions: Dict[Optional[str], str] = {} + _time_grain_functions: Dict[Optional[str], str] = {} time_groupby_inline = False limit_method = LimitMethod.FORCE_LIMIT time_secondary_columns = False @@ -161,7 +138,7 @@ def get_timestamp_expr( :return: TimestampExpression object """ if time_grain: - time_expr = cls.time_grain_functions.get(time_grain) + time_expr = cls.get_time_grain_functions().get(time_grain) if not time_expr: raise NotImplementedError( f"No grain spec for {time_grain} for database {cls.engine}" @@ -180,18 +157,37 @@ def get_timestamp_expr( @classmethod def get_time_grains(cls) -> Tuple[TimeGrain, ...]: """ - Generate a tuple of time grains based on time grains provided by the engine - and any potential additional or blacklisted grains in the config file. + Generate a tuple of supported time grains. :return: All time grains supported by the engine """ - blacklist: List[str] = config.get("TIME_GRAIN_BLACKLIST", []) - supported_grains = builtin_time_grains.copy() - supported_grains.update(config.get("TIME_GRAIN_ADDONS", {})) - grain_functions = cls.time_grain_functions.copy() + + ret_list = [] + time_grain_functions = cls.get_time_grain_functions() + time_grains = builtin_time_grains.copy() + time_grains.update(config.get("TIME_GRAIN_ADDONS", {})) + for duration, func in time_grain_functions.items(): + if duration in time_grains: + name = time_grains[duration] + ret_list.append(TimeGrain(name, _(name), func, duration)) + return tuple(ret_list) + + @classmethod + def get_time_grain_functions(cls) -> Dict[Optional[str], str]: + """ + Return a dict of all supported time grains including any potential added grains + but excluding any potentially blacklisted grains in the config file. + + :return: All time grain functions supported by the engine + """ + # TODO: use @memoize decorator or similar to avoid recomputation on every call + time_grain_functions = cls._time_grain_functions.copy() grain_addon_functions = config.get("TIME_GRAIN_ADDON_FUNCTIONS", {}) - grain_functions.update(grain_addon_functions.get(cls.engine, {})) - return _create_time_grains_tuple(supported_grains, grain_functions, blacklist) + time_grain_functions.update(grain_addon_functions.get(cls.engine, {})) + blacklist: List[str] = config.get("TIME_GRAIN_BLACKLIST", []) + for key in blacklist: + time_grain_functions.pop(key) + return time_grain_functions @classmethod def make_select_compatible( diff --git a/superset/db_engine_specs/bigquery.py b/superset/db_engine_specs/bigquery.py index addf4fd11f2f3..2e0476c95e322 100644 --- a/superset/db_engine_specs/bigquery.py +++ b/superset/db_engine_specs/bigquery.py @@ -45,7 +45,7 @@ class BigQueryEngineSpec(BaseEngineSpec): """ arraysize = 5000 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "TIMESTAMP_TRUNC({col}, SECOND)", "PT1M": "TIMESTAMP_TRUNC({col}, MINUTE)", diff --git a/superset/db_engine_specs/clickhouse.py b/superset/db_engine_specs/clickhouse.py index 1095e1fc1b0e8..e72f8752ea7b0 100644 --- a/superset/db_engine_specs/clickhouse.py +++ b/superset/db_engine_specs/clickhouse.py @@ -28,7 +28,7 @@ class ClickHouseEngineSpec(BaseEngineSpec): time_secondary_columns = True time_groupby_inline = True - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1M": "toStartOfMinute(toDateTime({col}))", "PT5M": "toDateTime(intDiv(toUInt32(toDateTime({col})), 300)*300)", diff --git a/superset/db_engine_specs/db2.py b/superset/db_engine_specs/db2.py index 30822e3d74563..93cb76f71bb20 100644 --- a/superset/db_engine_specs/db2.py +++ b/superset/db_engine_specs/db2.py @@ -26,7 +26,7 @@ class Db2EngineSpec(BaseEngineSpec): force_column_alias_quotes = True max_column_name_length = 30 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "CAST({col} as TIMESTAMP)" " - MICROSECOND({col}) MICROSECONDS", "PT1M": "CAST({col} as TIMESTAMP)" diff --git a/superset/db_engine_specs/drill.py b/superset/db_engine_specs/drill.py index d82a25ff63dcf..9ebe877030f67 100644 --- a/superset/db_engine_specs/drill.py +++ b/superset/db_engine_specs/drill.py @@ -26,7 +26,7 @@ class DrillEngineSpec(BaseEngineSpec): engine = "drill" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "NEARESTDATE({col}, 'SECOND')", "PT1M": "NEARESTDATE({col}, 'MINUTE')", diff --git a/superset/db_engine_specs/druid.py b/superset/db_engine_specs/druid.py index 8cd0c4cb91c94..78a2a64610fc2 100644 --- a/superset/db_engine_specs/druid.py +++ b/superset/db_engine_specs/druid.py @@ -25,7 +25,7 @@ class DruidEngineSpec(BaseEngineSpec): allows_joins = False allows_subqueries = True - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "FLOOR({col} TO SECOND)", "PT1M": "FLOOR({col} TO MINUTE)", diff --git a/superset/db_engine_specs/impala.py b/superset/db_engine_specs/impala.py index f2fa57a395fd6..4feb3fc0dc51c 100644 --- a/superset/db_engine_specs/impala.py +++ b/superset/db_engine_specs/impala.py @@ -28,7 +28,7 @@ class ImpalaEngineSpec(BaseEngineSpec): engine = "impala" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1M": "TRUNC({col}, 'MI')", "PT1H": "TRUNC({col}, 'HH')", diff --git a/superset/db_engine_specs/kylin.py b/superset/db_engine_specs/kylin.py index b3ebe81b0b11d..edde71dedc68f 100644 --- a/superset/db_engine_specs/kylin.py +++ b/superset/db_engine_specs/kylin.py @@ -25,7 +25,7 @@ class KylinEngineSpec(BaseEngineSpec): engine = "kylin" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "CAST(FLOOR(CAST({col} AS TIMESTAMP) TO SECOND) AS TIMESTAMP)", "PT1M": "CAST(FLOOR(CAST({col} AS TIMESTAMP) TO MINUTE) AS TIMESTAMP)", diff --git a/superset/db_engine_specs/mssql.py b/superset/db_engine_specs/mssql.py index 0c4685118fd9b..4e5a4fe8987d7 100644 --- a/superset/db_engine_specs/mssql.py +++ b/superset/db_engine_specs/mssql.py @@ -31,7 +31,7 @@ class MssqlEngineSpec(BaseEngineSpec): limit_method = LimitMethod.WRAP_SQL max_column_name_length = 128 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "DATEADD(second, DATEDIFF(second, '2000-01-01', {col}), '2000-01-01')", "PT1M": "DATEADD(minute, DATEDIFF(minute, 0, {col}), 0)", diff --git a/superset/db_engine_specs/mysql.py b/superset/db_engine_specs/mysql.py index 3a48032e764cc..a8964a4111bdc 100644 --- a/superset/db_engine_specs/mysql.py +++ b/superset/db_engine_specs/mysql.py @@ -29,7 +29,7 @@ class MySQLEngineSpec(BaseEngineSpec): engine = "mysql" max_column_name_length = 64 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "DATE_ADD(DATE({col}), " "INTERVAL (HOUR({col})*60*60 + MINUTE({col})*60" diff --git a/superset/db_engine_specs/oracle.py b/superset/db_engine_specs/oracle.py index eaa815c5b2079..3b42f9d4364e6 100644 --- a/superset/db_engine_specs/oracle.py +++ b/superset/db_engine_specs/oracle.py @@ -27,7 +27,7 @@ class OracleEngineSpec(PostgresBaseEngineSpec): force_column_alias_quotes = True max_column_name_length = 30 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "CAST({col} as DATE)", "PT1M": "TRUNC(CAST({col} as DATE), 'MI')", diff --git a/superset/db_engine_specs/pinot.py b/superset/db_engine_specs/pinot.py index f4bb843338399..af3fc2b255c35 100644 --- a/superset/db_engine_specs/pinot.py +++ b/superset/db_engine_specs/pinot.py @@ -29,7 +29,7 @@ class PinotEngineSpec(BaseEngineSpec): allows_column_aliases = False # Pinot does its own conversion below - time_grain_functions: Dict[Optional[str], str] = { + _time_grain_functions: Dict[Optional[str], str] = { "PT1S": "1:SECONDS", "PT1M": "1:MINUTES", "PT1H": "1:HOURS", @@ -52,7 +52,7 @@ def get_timestamp_expr( # We are not really converting any time units, just bucketing them. seconds_or_ms = "MILLISECONDS" if pdf == "epoch_ms" else "SECONDS" tf = f"1:{seconds_or_ms}:EPOCH" - granularity = cls.time_grain_functions.get(time_grain) + granularity = cls.get_time_grain_functions().get(time_grain) if not granularity: raise NotImplementedError("No pinot grain spec for " + str(time_grain)) # In pinot the output is a string since there is no timestamp column like pg diff --git a/superset/db_engine_specs/postgres.py b/superset/db_engine_specs/postgres.py index 6bfe12da7cb46..4716b07586ac8 100644 --- a/superset/db_engine_specs/postgres.py +++ b/superset/db_engine_specs/postgres.py @@ -28,7 +28,7 @@ class PostgresBaseEngineSpec(BaseEngineSpec): engine = "" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "DATE_TRUNC('second', {col})", "PT1M": "DATE_TRUNC('minute', {col})", diff --git a/superset/db_engine_specs/presto.py b/superset/db_engine_specs/presto.py index 87aac9b9cbd36..e648f65a0126e 100644 --- a/superset/db_engine_specs/presto.py +++ b/superset/db_engine_specs/presto.py @@ -43,7 +43,7 @@ class PrestoEngineSpec(BaseEngineSpec): engine = "presto" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "date_trunc('second', CAST({col} AS TIMESTAMP))", "PT1M": "date_trunc('minute', CAST({col} AS TIMESTAMP))", diff --git a/superset/db_engine_specs/snowflake.py b/superset/db_engine_specs/snowflake.py index 07d266d4972b6..8a1edc7744e05 100644 --- a/superset/db_engine_specs/snowflake.py +++ b/superset/db_engine_specs/snowflake.py @@ -25,7 +25,7 @@ class SnowflakeEngineSpec(PostgresBaseEngineSpec): force_column_alias_quotes = True max_column_name_length = 256 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "DATE_TRUNC('SECOND', {col})", "PT1M": "DATE_TRUNC('MINUTE', {col})", diff --git a/superset/db_engine_specs/sqlite.py b/superset/db_engine_specs/sqlite.py index 58a2c67122219..28c8843057cfc 100644 --- a/superset/db_engine_specs/sqlite.py +++ b/superset/db_engine_specs/sqlite.py @@ -27,7 +27,7 @@ class SqliteEngineSpec(BaseEngineSpec): engine = "sqlite" - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1S": "DATETIME(STRFTIME('%Y-%m-%dT%H:%M:%S', {col}))", "PT1M": "DATETIME(STRFTIME('%Y-%m-%dT%H:%M:00', {col}))", diff --git a/superset/db_engine_specs/teradata.py b/superset/db_engine_specs/teradata.py index ceba88c68d2f4..fc6304908af40 100644 --- a/superset/db_engine_specs/teradata.py +++ b/superset/db_engine_specs/teradata.py @@ -25,7 +25,7 @@ class TeradataEngineSpec(BaseEngineSpec): limit_method = LimitMethod.WRAP_SQL max_column_name_length = 30 # since 14.10 this is 128 - time_grain_functions = { + _time_grain_functions = { None: "{col}", "PT1M": "TRUNC(CAST({col} as DATE), 'MI')", "PT1H": "TRUNC(CAST({col} as DATE), 'HH')", diff --git a/tests/db_engine_specs_test.py b/tests/db_engine_specs_test.py index 3419d25e10f0b..2824205ded695 100644 --- a/tests/db_engine_specs_test.py +++ b/tests/db_engine_specs_test.py @@ -24,12 +24,9 @@ from sqlalchemy.sql import select from sqlalchemy.types import String, UnicodeText +from superset import app from superset.db_engine_specs import engines -from superset.db_engine_specs.base import ( - _create_time_grains_tuple, - BaseEngineSpec, - builtin_time_grains, -) +from superset.db_engine_specs.base import BaseEngineSpec, builtin_time_grains from superset.db_engine_specs.bigquery import BigQueryEngineSpec from superset.db_engine_specs.hive import HiveEngineSpec from superset.db_engine_specs.mssql import MssqlEngineSpec @@ -38,6 +35,7 @@ from superset.db_engine_specs.pinot import PinotEngineSpec from superset.db_engine_specs.postgres import PostgresEngineSpec from superset.db_engine_specs.presto import PrestoEngineSpec +from superset.db_engine_specs.sqlite import SqliteEngineSpec from superset.models.core import Database from superset.utils.core import get_example_database from .base_tests import SupersetTestCase @@ -315,14 +313,21 @@ def test_limit_with_non_token_limit(self): ) def test_time_grain_blacklist(self): - blacklist = ["PT1M"] - time_grains = {"PT1S": "second", "PT1M": "minute"} - time_grain_functions = {"PT1S": "{col}", "PT1M": "{col}"} - time_grains = _create_time_grains_tuple( - time_grains, time_grain_functions, blacklist - ) - self.assertEqual(1, len(time_grains)) - self.assertEqual("PT1S", time_grains[0].duration) + with app.app_context(): + app.config["TIME_GRAIN_BLACKLIST"] = ["PT1M"] + time_grain_functions = SqliteEngineSpec.get_time_grain_functions() + self.assertNotIn("PT1M", time_grain_functions) + + def test_time_grain_addons(self): + with app.app_context(): + app.config["TIME_GRAIN_ADDONS"] = {"PTXM": "x seconds"} + app.config["TIME_GRAIN_ADDON_FUNCTIONS"] = { + "sqlite": {"PTXM": "ABC({col})"} + } + time_grains = SqliteEngineSpec.get_time_grains() + time_grain_addon = time_grains[-1] + self.assertEqual("PTXM", time_grain_addon.duration) + self.assertEqual("x seconds", time_grain_addon.label) def test_engine_time_grain_validity(self): time_grains = set(builtin_time_grains.keys()) @@ -330,8 +335,8 @@ def test_engine_time_grain_validity(self): for engine in engines.values(): if engine is not BaseEngineSpec: # make sure time grain functions have been defined - self.assertGreater(len(engine.time_grain_functions), 0) - # make sure that all defined time grains are supported + self.assertGreater(len(engine.get_time_grain_functions()), 0) + # make sure all defined time grains are supported defined_grains = {grain.duration for grain in engine.get_time_grains()} intersection = time_grains.intersection(defined_grains) self.assertSetEqual(defined_grains, intersection, engine) From 22302e341f2824785687e3542a5e5935280cbd4f Mon Sep 17 00:00:00 2001 From: Paul Vickers Date: Sun, 8 Sep 2019 17:58:59 +0100 Subject: [PATCH 11/19] Bump flask-appbuilder to 2.1.13 (#8174) * Bump flask-appbuilder to 2.1.12 To pick up this fix https://github.com/dpgaspar/Flask-AppBuilder/pull/1095 which addresses https://github.com/apache/incubator-superset/issues/7739 * Bump FAB again to 2.1.13 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7b85ebe4c72d2..c9d0d4c529cce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ croniter==0.3.30 cryptography==2.7 decorator==4.4.0 # via retry defusedxml==0.6.0 # via python3-openid -flask-appbuilder==2.1.9 +flask-appbuilder==2.1.13 flask-babel==0.12.2 # via flask-appbuilder flask-caching==1.7.2 flask-compress==1.4.0 From 9d350aadf0aa5ab5ba8fd381a5d397077af1eefa Mon Sep 17 00:00:00 2001 From: Garrett Bates Date: Sun, 8 Sep 2019 13:16:07 -0400 Subject: [PATCH 12/19] ignore formatting for clearable (#7215) (@mistercrunch) +- [#7215](https://github.com/apache/incubator-superset/pull/7215) Fix `