From 886d16c87177d4a2954616ae6dcd1799be1db876 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Tue, 25 May 2021 19:45:53 +0200 Subject: [PATCH 01/22] feat: add context to confirm dailog --- frappe/public/js/frappe/ui/messages.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/ui/messages.js b/frappe/public/js/frappe/ui/messages.js index 2e8ba7d206..f465250af9 100644 --- a/frappe/public/js/frappe/ui/messages.js +++ b/frappe/public/js/frappe/ui/messages.js @@ -26,13 +26,13 @@ frappe.throw = function(msg) { frappe.confirm = function(message, confirm_action, reject_action) { var d = new frappe.ui.Dialog({ - title: __("Confirm"), - primary_action_label: __("Yes"), + title: __("Confirm", null, "Title of confirmation dialog"), + primary_action_label: __("Yes", null, "Approve confirmation dialog"), primary_action: () => { confirm_action && confirm_action(); d.hide(); }, - secondary_action_label: __("No"), + secondary_action_label: __("No", null, "Dismiss confirmation dialog"), secondary_action: () => d.hide(), }); From d3121d753ead5511ecc6a0e57e6e6825901c68ad Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Tue, 25 May 2021 19:47:15 +0200 Subject: [PATCH 02/22] feat: add context to prompt dialog --- frappe/public/js/frappe/ui/messages.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/ui/messages.js b/frappe/public/js/frappe/ui/messages.js index f465250af9..067fed233c 100644 --- a/frappe/public/js/frappe/ui/messages.js +++ b/frappe/public/js/frappe/ui/messages.js @@ -88,9 +88,9 @@ frappe.prompt = function(fields, callback, title, primary_label) { if(!$.isArray(fields)) fields = [fields]; var d = new frappe.ui.Dialog({ fields: fields, - title: title || __("Enter Value"), + title: title || __("Enter Value", null, "Title of prompt dialog"), }); - d.set_primary_action(primary_label || __("Submit"), function() { + d.set_primary_action(primary_label || __("Submit", null, "Primary action of prompt dialog"), function() { var values = d.get_values(); if(!values) { return; From d7d0ddf6adee391714e5b4f31ab559fe61c322c5 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Wed, 26 May 2021 02:54:04 +0000 Subject: [PATCH 03/22] fix: package.json & yarn.lock to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-NORMALIZEURL-1296539 --- package.json | 2 +- yarn.lock | 1022 ++++++++++++++++++++------------------------------ 2 files changed, 418 insertions(+), 606 deletions(-) diff --git a/package.json b/package.json index e666a2e1ce..25bf0b0695 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "bootstrap": "4.5.0", "cliui": "^7.0.4", "cookie": "^0.4.0", - "cssnano": "^4.1.10", + "cssnano": "^5.0.0", "driver.js": "^0.9.8", "express": "^4.17.1", "fast-deep-equal": "^2.0.1", diff --git a/yarn.lock b/yarn.lock index 86719d81f4..96a6059ecc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,27 @@ resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.10.1.tgz#70e45678f06c72fa2e350e8553ec4a4d72b92e06" integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== +"@babel/code-frame@^7.0.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@deepcode/dcignore@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@deepcode/dcignore/-/dcignore-1.0.2.tgz#39e4a3df7dde8811925330506e4bb3fbf3c288d8" @@ -361,6 +382,11 @@ dependencies: defer-to-connect "^2.0.0" +"@trysound/sax@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" + integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== + "@types/babel-types@*", "@types/babel-types@^7.0.0": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.9.tgz#01d7b86949f455402a94c788883fe4ba574cad41" @@ -463,10 +489,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.4.tgz#76c3cb3a12909510f52e5dc04a6298cdf9504ffd" integrity sha512-oVeL12C6gQS/GAExndigSaLxTrKpQPxewx9bOcwfvJiJge4rr7wNaph4J+ns5hrmIV2as5qxqN8YKthn9qh0jw== -"@types/q@^1.5.1": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18" - integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA== +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" @@ -595,7 +621,7 @@ align-text@^0.1.1, align-text@^0.1.3: longest "^1.0.1" repeat-string "^1.5.2" -alphanum-sort@^1.0.0: +alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= @@ -958,7 +984,7 @@ body-parser@1.19.0: raw-body "2.4.0" type-is "~1.6.17" -boolbase@^1.0.0, boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -1009,7 +1035,7 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.16.3: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.16.0, browserslist@^4.16.3: version "4.16.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== @@ -1077,24 +1103,10 @@ call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase-keys@^2.0.0: version "2.1.0" @@ -1166,7 +1178,7 @@ chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1313,21 +1325,12 @@ clone@^2.1.1, clone@^2.1.2: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1346,26 +1349,15 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.0.tgz#d8e9fb096732875774c84bf922815df0308d0ffc" - integrity sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" +colord@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.0.0.tgz#f8c19f2526b7dc5b22d6e57ef102f03a2a43a3d8" + integrity sha512-WMDFJfoY3wqPZNpKUFdse3HhD5BHCbE9JCdxRzoVH+ywRITGOeWAHNkGEmyxLlErEpN9OLMWgdM9dWQtDk5dog== colorette@^1.2.1, colorette@^1.2.2: version "1.2.2" @@ -1379,6 +1371,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" @@ -1492,16 +1489,16 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.1.0.tgz#6c5c35e97f37f985061cdf653f114784231185cf" - integrity sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q== +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.9.0" - lodash.get "^4.4.2" - parse-json "^4.0.0" + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" cross-spawn@^3.0.0: version "3.0.1" @@ -1532,17 +1529,21 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-color-names@0.0.4, css-color-names@^0.0.4: +css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= -css-declaration-sorter@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" - integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== +css-color-names@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" + integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== + +css-declaration-sorter@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9" + integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw== dependencies: - postcss "^7.0.1" timsort "^0.3.0" css-parse@~2.0.0: @@ -1552,20 +1553,16 @@ css-parse@~2.0.0: dependencies: css "^2.0.0" -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== - -css-select@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" - integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== +css-select@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" + integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== dependencies: boolbase "^1.0.0" - css-what "^2.1.2" - domutils "^1.7.0" - nth-check "^1.0.2" + css-what "^4.0.0" + domhandler "^4.0.0" + domutils "^2.4.3" + nth-check "^2.0.0" css-selector-tokenizer@^0.7.0: version "0.7.1" @@ -1576,36 +1573,18 @@ css-selector-tokenizer@^0.7.0: fastparse "^1.1.1" regexpu-core "^1.0.0" -css-tree@1.0.0-alpha.28: - version "1.0.0-alpha.28" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.28.tgz#8e8968190d886c9477bc8d61e96f61af3f7ffa7f" - integrity sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w== +css-tree@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== dependencies: - mdn-data "~1.1.0" - source-map "^0.5.3" + mdn-data "2.0.14" + source-map "^0.6.1" -css-tree@1.0.0-alpha.29: - version "1.0.0-alpha.29" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" - integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== - dependencies: - mdn-data "~1.1.0" - source-map "^0.5.3" - -css-unit-converter@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" - integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= - -css-url-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" - integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= - -css-what@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== +css-what@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" + integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== css@^2.0.0: version "2.2.4" @@ -1622,90 +1601,66 @@ cssesc@^0.1.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== +cssnano-preset-default@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.1.tgz#5cd783caed942cc94159aeb10583af4691445b8c" + integrity sha512-kAhR71Tascmnjlhl4UegGA3KGGbMLXHkkqVpA9idsRT1JmIhIsz1C3tDpBeQMUw5EX5Rfb1HGc/PRqD2AFk3Vg== dependencies: - css-declaration-sorter "^4.0.1" - cssnano-util-raw-cache "^4.0.1" - postcss "^7.0.0" - postcss-calc "^7.0.1" - postcss-colormin "^4.0.3" - postcss-convert-values "^4.0.1" - postcss-discard-comments "^4.0.2" - postcss-discard-duplicates "^4.0.2" - postcss-discard-empty "^4.0.1" - postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.11" - postcss-merge-rules "^4.0.3" - postcss-minify-font-values "^4.0.2" - postcss-minify-gradients "^4.0.2" - postcss-minify-params "^4.0.2" - postcss-minify-selectors "^4.0.2" - postcss-normalize-charset "^4.0.1" - postcss-normalize-display-values "^4.0.2" - postcss-normalize-positions "^4.0.2" - postcss-normalize-repeat-style "^4.0.2" - postcss-normalize-string "^4.0.2" - postcss-normalize-timing-functions "^4.0.2" - postcss-normalize-unicode "^4.0.1" - postcss-normalize-url "^4.0.1" - postcss-normalize-whitespace "^4.0.2" - postcss-ordered-values "^4.1.2" - postcss-reduce-initial "^4.0.3" - postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" - postcss-unique-selectors "^4.0.1" + css-declaration-sorter "^6.0.3" + cssnano-utils "^2.0.1" + postcss-calc "^8.0.0" + postcss-colormin "^5.1.1" + postcss-convert-values "^5.0.1" + postcss-discard-comments "^5.0.1" + postcss-discard-duplicates "^5.0.1" + postcss-discard-empty "^5.0.1" + postcss-discard-overridden "^5.0.1" + postcss-merge-longhand "^5.0.2" + postcss-merge-rules "^5.0.1" + postcss-minify-font-values "^5.0.1" + postcss-minify-gradients "^5.0.1" + postcss-minify-params "^5.0.1" + postcss-minify-selectors "^5.1.0" + postcss-normalize-charset "^5.0.1" + postcss-normalize-display-values "^5.0.1" + postcss-normalize-positions "^5.0.1" + postcss-normalize-repeat-style "^5.0.1" + postcss-normalize-string "^5.0.1" + postcss-normalize-timing-functions "^5.0.1" + postcss-normalize-unicode "^5.0.1" + postcss-normalize-url "^5.0.1" + postcss-normalize-whitespace "^5.0.1" + postcss-ordered-values "^5.0.1" + postcss-reduce-initial "^5.0.1" + postcss-reduce-transforms "^5.0.1" + postcss-svgo "^5.0.1" + postcss-unique-selectors "^5.0.1" -cssnano-util-get-arguments@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= +cssnano-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" + integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== -cssnano-util-get-match@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= - -cssnano-util-raw-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" - integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== +cssnano@^5.0.0: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.4.tgz#5ca90729c94c71c4bc3d45abb543be10740bf381" + integrity sha512-I+fDW74CJ4yb31765ov9xXe70XLZvFTXjwhmA//VgAAuSAU34Oblbe94Q9zffiCX1VhcSfQWARQnwhz+Nqgb4Q== dependencies: - postcss "^7.0.0" + cosmiconfig "^7.0.0" + cssnano-preset-default "^5.1.1" + is-resolvable "^1.1.0" -cssnano-util-same-parent@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" - integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== - -cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: - cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" - is-resolvable "^1.0.0" - postcss "^7.0.0" - -csso@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b" - integrity sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg== - dependencies: - css-tree "1.0.0-alpha.29" + css-tree "^1.1.2" currently-unhandled@^0.4.1: version "0.4.1" @@ -1928,33 +1883,35 @@ doctypes@^1.1.0: resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= -dom-serializer@0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" -domelementtype@1, domelementtype@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== -domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" + integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== dependencies: - dom-serializer "0" - domelementtype "1" + domelementtype "^2.2.0" -dot-prop@^4.1.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" - integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ== +domutils@^2.4.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" + integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== dependencies: - is-obj "^1.0.0" + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" dot-prop@^5.2.0: version "5.2.0" @@ -2102,10 +2059,10 @@ engine.io@~3.5.0: engine.io-parser "~2.2.0" ws "~7.4.2" -entities@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== errno@^0.1.1: version "0.1.7" @@ -2121,18 +2078,6 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.12.0, es-abstract@^1.5.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" - es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: version "1.17.5" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" @@ -2163,15 +2108,6 @@ es-get-iterator@^1.1.0: is-string "^1.0.5" isarray "^2.0.5" -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -2914,7 +2850,7 @@ has-yarn@^2.1.0: resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== -has@^1.0.0, has@^1.0.1, has@^1.0.3: +has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -2993,11 +2929,6 @@ hsla-regex@^1.0.0: resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" @@ -3084,13 +3015,13 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" + parent-module "^1.0.0" + resolve-from "^4.0.0" import-lazy@^2.1.0: version "2.1.0" @@ -3162,10 +3093,10 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== is-arguments@^1.0.4: version "1.0.4" @@ -3177,11 +3108,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - is-bigint@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4" @@ -3221,7 +3147,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-color-stop@^1.0.0: +is-color-stop@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= @@ -3255,11 +3181,6 @@ is-deflate@^1.0.0: resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14" integrity sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ= -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - is-docker@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" @@ -3350,11 +3271,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -3378,13 +3294,6 @@ is-regex@^1.0.3: call-bind "^1.0.2" has-symbols "^1.0.1" -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= - dependencies: - has "^1.0.1" - is-regex@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" @@ -3392,7 +3301,7 @@ is-regex@^1.0.5: dependencies: has-symbols "^1.0.1" -is-resolvable@^1.0.0: +is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== @@ -3412,13 +3321,6 @@ is-string@^1.0.4, is-string@^1.0.5: resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== - dependencies: - html-comment-regex "^1.1.0" - is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -3543,7 +3445,12 @@ js-stringify@^1.0.1: resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= -js-yaml@^3.12.0, js-yaml@^3.13.1, js-yaml@^3.9.0: +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: version "3.14.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== @@ -3576,10 +3483,10 @@ json-buffer@3.0.1: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" @@ -3740,6 +3647,11 @@ lie@~3.3.0: dependencies: immediate "~3.0.5" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -4129,10 +4041,10 @@ md5@^2.3.0: crypt "0.0.2" is-buffer "~1.1.6" -mdn-data@~1.1.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" - integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== media-typer@0.3.0: version "0.3.0" @@ -4248,11 +4160,6 @@ minimatch@^3.0.4, minimatch@~3.0.2: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - minimist@^1.1.3, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -4290,13 +4197,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - moment-timezone@^0.5.28: version "0.5.28" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338" @@ -4505,16 +4405,16 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== - normalize-url@^4.1.0: version "4.5.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== +normalize-url@^4.5.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4532,12 +4432,12 @@ npm-run-path@^2.0.0: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== dependencies: - boolbase "~1.0.0" + boolbase "^1.0.0" num2fraction@^1.2.2: version "1.2.2" @@ -4597,24 +4497,6 @@ object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - -object.values@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" - integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.12.0" - function-bind "^1.1.1" - has "^1.0.3" - omggif@^1.0.5: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -4765,6 +4647,13 @@ parchment@^1.1.4: resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5" integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg== +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-data-uri@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/parse-data-uri/-/parse-data-uri-0.2.0.tgz#bf04d851dd5c87b0ab238e5d01ace494b604b4c9" @@ -4779,13 +4668,15 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: + "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" parse-link-header@^1.0.1: version "1.0.1" @@ -4860,6 +4751,11 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + peek-stream@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67" @@ -4938,124 +4834,104 @@ popper.js@^1.16.0: resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== -postcss-calc@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" - integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ== +postcss-calc@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" + integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== dependencies: - css-unit-converter "^1.1.1" - postcss "^7.0.5" - postcss-selector-parser "^5.0.0-rc.4" - postcss-value-parser "^3.3.1" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" -postcss-colormin@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" - integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== +postcss-colormin@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.1.1.tgz#834d262f6021f832d9085e355f08ade288a92a1d" + integrity sha512-SyTmqKKN6PyYNeeKEC0hqIP5CDuprO1hHurdW1aezDyfofDUOn7y7MaxcolbsW3oazPwFiGiY30XRiW1V4iZpA== dependencies: - browserslist "^4.0.0" - color "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + browserslist "^4.16.0" + colord "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-convert-values@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" - integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== +postcss-convert-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz#4ec19d6016534e30e3102fdf414e753398645232" + integrity sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-discard-comments@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" - integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== - dependencies: - postcss "^7.0.0" +postcss-discard-comments@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" + integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== -postcss-discard-duplicates@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" - integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== - dependencies: - postcss "^7.0.0" +postcss-discard-duplicates@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" + integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== -postcss-discard-empty@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" - integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== - dependencies: - postcss "^7.0.0" +postcss-discard-empty@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" + integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== -postcss-discard-overridden@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" - integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== - dependencies: - postcss "^7.0.0" +postcss-discard-overridden@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" + integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== -postcss-merge-longhand@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" - integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== +postcss-merge-longhand@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz#277ada51d9a7958e8ef8cf263103c9384b322a41" + integrity sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw== dependencies: - css-color-names "0.0.4" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - stylehacks "^4.0.0" + css-color-names "^1.0.1" + postcss-value-parser "^4.1.0" + stylehacks "^5.0.1" -postcss-merge-rules@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" - integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== +postcss-merge-rules@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.1.tgz#4ff61c5089d86845184a0f149e88d687028bef7e" + integrity sha512-UR6R5Ph0c96QB9TMBH3ml8/kvPCThPHepdhRqAbvMRDRHQACPC8iM5NpfIC03+VRMZTGXy4L/BvFzcDFCgb+fA== dependencies: - browserslist "^4.0.0" + browserslist "^4.16.0" caniuse-api "^3.0.0" - cssnano-util-same-parent "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - vendors "^1.0.0" + cssnano-utils "^2.0.1" + postcss-selector-parser "^6.0.5" + vendors "^1.0.3" -postcss-minify-font-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" - integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== +postcss-minify-font-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" + integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-minify-gradients@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" - integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== +postcss-minify-gradients@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz#2dc79fd1a1afcb72a9e727bc549ce860f93565d2" + integrity sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g== dependencies: - cssnano-util-get-arguments "^4.0.0" - is-color-stop "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.1" + is-color-stop "^1.1.0" + postcss-value-parser "^4.1.0" -postcss-minify-params@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" - integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== +postcss-minify-params@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" + integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== dependencies: - alphanum-sort "^1.0.0" - browserslist "^4.0.0" - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + alphanum-sort "^1.0.2" + browserslist "^4.16.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" uniqs "^2.0.0" -postcss-minify-selectors@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" - integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== +postcss-minify-selectors@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" + integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== dependencies: - alphanum-sort "^1.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" postcss-modules-extract-imports@^3.0.0: version "3.0.0" @@ -5127,133 +5003,96 @@ postcss-modules@^4.0.0: postcss-modules-values "^4.0.0" string-hash "^1.1.1" -postcss-normalize-charset@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" - integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== - dependencies: - postcss "^7.0.0" +postcss-normalize-charset@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" + integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== -postcss-normalize-display-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" - integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== +postcss-normalize-display-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" + integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" -postcss-normalize-positions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" - integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== +postcss-normalize-positions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" + integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== dependencies: - cssnano-util-get-arguments "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-repeat-style@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" - integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== +postcss-normalize-repeat-style@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" + integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== dependencies: - cssnano-util-get-arguments "^4.0.0" - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" -postcss-normalize-string@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" - integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== +postcss-normalize-string@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" + integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== dependencies: - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-timing-functions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" - integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== +postcss-normalize-timing-functions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" + integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" -postcss-normalize-unicode@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" - integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== +postcss-normalize-unicode@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" + integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + browserslist "^4.16.0" + postcss-value-parser "^4.1.0" -postcss-normalize-url@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" - integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== +postcss-normalize-url@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.1.tgz#ffa9fe545935d8b57becbbb7934dd5e245513183" + integrity sha512-hkbG0j58Z1M830/CJ73VsP7gvlG1yF+4y7Fd1w4tD2c7CaA2Psll+pQ6eQhth9y9EaqZSLzamff/D0MZBMbYSg== dependencies: - is-absolute-url "^2.0.0" - normalize-url "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + is-absolute-url "^3.0.3" + normalize-url "^4.5.0" + postcss-value-parser "^4.1.0" -postcss-normalize-whitespace@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" - integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== +postcss-normalize-whitespace@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" + integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-ordered-values@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" - integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== +postcss-ordered-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.1.tgz#79ef6e2bd267ccad3fc0c4f4a586dfd01c131f64" + integrity sha512-6mkCF5BQ25HvEcDfrMHCLLFHlraBSlOXFnQMHYhSpDO/5jSR1k8LdEXOkv+7+uzW6o6tBYea1Km0wQSRkPJkwA== dependencies: - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" -postcss-reduce-initial@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" - integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== +postcss-reduce-initial@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" + integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== dependencies: - browserslist "^4.0.0" + browserslist "^4.16.0" caniuse-api "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" -postcss-reduce-transforms@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" - integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== +postcss-reduce-transforms@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" + integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== dependencies: - cssnano-util-get-match "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-selector-parser@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" - integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU= - dependencies: - dot-prop "^4.1.1" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^5.0.0-rc.4: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== - dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.4" @@ -5265,31 +5104,32 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: uniq "^1.0.1" util-deprecate "^1.0.2" -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== +postcss-selector-parser@^6.0.5: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== dependencies: - is-svg "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - svgo "^1.0.0" + cssesc "^3.0.0" + util-deprecate "^1.0.2" -postcss-unique-selectors@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" - integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== +postcss-svgo@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.1.tgz#6ed5e01e164e59204978994d844c653a331a8100" + integrity sha512-cD7DFo6tF9i5eWvwtI4irKOHCpmASFS0xvZ5EQIgEdA1AWfM/XiHHY/iss0gcKHhkqwgYmuo2M0KhJLd5Us6mg== dependencies: - alphanum-sort "^1.0.0" - postcss "^7.0.0" + postcss-value-parser "^4.1.0" + svgo "^2.3.0" + +postcss-unique-selectors@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" + integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" uniqs "^2.0.0" -postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - -postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== @@ -5322,7 +5162,7 @@ postcss@^6.0.1: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.5: +postcss@^7.0.14: version "7.0.14" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" integrity sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg== @@ -5554,11 +5394,6 @@ pupa@^2.0.1: dependencies: escape-goat "^2.0.0" -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - qs@6.7.0, qs@^6.5.1: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -5924,10 +5759,10 @@ resolve-file@^0.3.0: lazy-cache "^2.0.2" resolve "^1.2.0" -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-url@^0.2.1: version "0.2.1" @@ -6217,13 +6052,6 @@ signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - snyk-config@4.0.0, snyk-config@^4.0.0-rc.2: version "4.0.0" resolved "https://registry.yarnpkg.com/snyk-config/-/snyk-config-4.0.0.tgz#21d459f19087991246cc07a7ffb4501dce6f4159" @@ -6677,7 +6505,7 @@ source-map@^0.4.2: dependencies: amdefine ">=0.0.4" -source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: +source-map@^0.5.6, source-map@~0.5.1: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -6935,14 +6763,13 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -stylehacks@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" - integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== +stylehacks@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" + integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" + browserslist "^4.16.0" + postcss-selector-parser "^6.0.4" stylus@^0.54.5, stylus@^0.x: version "0.54.8" @@ -7007,25 +6834,18 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -svgo@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.0.tgz#305a8fc0f4f9710828c65039bb93d5793225ffc3" - integrity sha512-xBfxJxfk4UeVN8asec9jNxHiv3UAMv/ujwBWGYvQhhMb2u3YTGKkiybPcLFDLq7GLLWE9wa73e0/m8L5nTzQbw== +svgo@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.0.tgz#6b3af81d0cbd1e19c83f5f63cec2cb98c70b5373" + integrity sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q== dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.28" - css-url-regex "^1.1.0" - csso "^3.5.1" - js-yaml "^3.12.0" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" + "@trysound/sax" "0.1.1" + chalk "^4.1.0" + commander "^7.1.0" + css-select "^3.1.2" + css-tree "^1.1.2" + csso "^4.2.0" stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" tar-stream@^2.1.0: version "2.1.0" @@ -7332,11 +7152,6 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - update-notifier@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.1.tgz#895fc8562bbe666179500f9f2cebac4f26323746" @@ -7390,14 +7205,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -7436,10 +7243,10 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -vendors@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801" - integrity sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ== +vendors@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== verror@1.10.0: version "1.10.0" @@ -7672,6 +7479,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + yaml@^1.9.2: version "1.10.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" From 55a49ce445aac635c09bfba14fbdadc621d59811 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 1 Jun 2021 17:39:25 +0530 Subject: [PATCH 04/22] fix: cannot set shortcut for actions menu item --- frappe/public/js/frappe/ui/page.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js index e740718ef9..a302c26892 100644 --- a/frappe/public/js/frappe/ui/page.js +++ b/frappe/public/js/frappe/ui/page.js @@ -377,11 +377,12 @@ frappe.ui.Page = class Page { }); } - add_actions_menu_item(label, click, standard) { + add_actions_menu_item(label, click, standard, shortcut) { return this.add_dropdown_item({ label, click, standard, + shortcut, parent: this.actions, show_parent: false }); From 02765c98c9b6814e30cc32929706f6f2c12a141c Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Sun, 6 Jun 2021 13:47:17 +0530 Subject: [PATCH 05/22] fix: ensure `Page.add_dropdown_item` returns link even if it already exists (#13420) --- frappe/public/js/frappe/ui/page.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js index e740718ef9..c5ef0d0184 100644 --- a/frappe/public/js/frappe/ui/page.js +++ b/frappe/public/js/frappe/ui/page.js @@ -409,6 +409,9 @@ frappe.ui.Page = class Page { parent.parent().removeClass("hide"); } + let $link = this.is_in_group_button_dropdown(parent, 'li > a.grey-link', label); + if ($link) return $link; + let $li; let $icon = ``; @@ -440,9 +443,8 @@ frappe.ui.Page = class Page { `); } - var $link = $li.find("a").on("click", click); - if (this.is_in_group_button_dropdown(parent, 'li > a.grey-link', label)) return; + $link = $li.find("a").on("click", click); if (standard) { $li.appendTo(parent); @@ -508,7 +510,7 @@ frappe.ui.Page = class Page { let item = $(this).html(); return $(item).attr('data-label') === label; }); - return result.length > 0; + return result.length > 0 && result; } clear_btn_group(parent) { From 674c8cf77b963f3d20e6439f6871b1640e9cd7b4 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Jun 2021 11:36:38 +0530 Subject: [PATCH 06/22] chore: Use get_absolute_url to doc.get_url Avoid re-implementation to reduce interfaces for possible bugs/fixes --- frappe/model/document.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/model/document.py b/frappe/model/document.py index 8f57aae475..61160e1f01 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -14,8 +14,8 @@ from frappe.model.workflow import set_workflow_state_on_action from frappe.utils.global_search import update_global_search from frappe.integrations.doctype.webhook import run_webhooks from frappe.desk.form.document_follow import follow_document -from frappe.desk.utils import slug from frappe.core.doctype.server_script.server_script_utils import run_server_script_for_doc_event +from frappe.utils.data import get_absolute_url # once_only validation # methods @@ -1200,8 +1200,8 @@ class Document(BaseDocument): doc.set(fieldname, flt(doc.get(fieldname), self.precision(fieldname, doc.parentfield))) def get_url(self): - """Returns Desk URL for this document. `/app/{doctype}/{name}`""" - return f"/app/{slug(self.doctype)}/{self.name}" + """Returns Desk URL for this document.""" + return get_absolute_url(self.doctype, self.name) def add_comment(self, comment_type='Comment', text=None, comment_email=None, link_doctype=None, link_name=None, comment_by=None): """Add a comment to this document. From 8e8490976cefb150b67b30e56badeb838081c8d5 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Jun 2021 14:10:49 +0530 Subject: [PATCH 07/22] fix: Remove frappe from boilerplate requirements.txt Remove frappe from new app boilerplates to avoid possible supply chain attacks. Don't make pip fetch frappe from PyPI --- frappe/utils/boilerplate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/boilerplate.py b/frappe/utils/boilerplate.py index 92150b79cf..e80410393d 100755 --- a/frappe/utils/boilerplate.py +++ b/frappe/utils/boilerplate.py @@ -70,7 +70,7 @@ def make_boilerplate(dest, app_name): f.write(frappe.as_unicode(setup_template.format(**hooks))) with open(os.path.join(dest, hooks.app_name, "requirements.txt"), "w") as f: - f.write("frappe") + f.write("# frappe -- https://github.com/frappe/frappe is installed via 'bench init'") with open(os.path.join(dest, hooks.app_name, "README.md"), "w") as f: f.write(frappe.as_unicode("## {0}\n\n{1}\n\n#### License\n\n{2}".format(hooks.app_title, From d8113698d1322304dd70c6797485fe347507a4c0 Mon Sep 17 00:00:00 2001 From: Brian Pond Date: Mon, 7 Jun 2021 16:15:59 -0700 Subject: [PATCH 08/22] bug: db_query.py The object 'meta' does not always have the attribute 'is_submittable.' This extra syntax checks for existence first. --- frappe/model/db_query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 7f22282acf..1acccdc142 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -730,7 +730,7 @@ class DatabaseQuery(object): args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype, sort_field or "modified", sort_order or "desc") # draft docs always on top - if meta.is_submittable: + if hasattr(meta, 'is_submittable') and meta.is_submittable: args.order_by = "`tab{0}`.docstatus asc, {1}".format(self.doctype, args.order_by) def validate_order_by_and_group_by(self, parameters): From efb3489a238c7e3480536e77169df632f4902d00 Mon Sep 17 00:00:00 2001 From: leela Date: Fri, 4 Jun 2021 05:42:34 +0530 Subject: [PATCH 09/22] refactor: sendmail of communication doctype Added a CommunicationEmailMixin that has all mail related functionality --- .../doctype/communication/communication.py | 77 ++-- frappe/core/doctype/communication/email.py | 340 +----------------- frappe/core/doctype/communication/mixins.py | 297 +++++++++++++++ .../doctype/email_account/email_account.py | 7 +- 4 files changed, 356 insertions(+), 365 deletions(-) create mode 100644 frappe/core/doctype/communication/mixins.py diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 0caa565e2c..17b1290776 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -6,10 +6,11 @@ import frappe from frappe import _ from frappe.model.document import Document from frappe.utils import validate_email_address, strip_html, cstr, time_diff_in_seconds -from frappe.core.doctype.communication.email import validate_email, notify, _notify +from frappe.core.doctype.communication.email import validate_email +from frappe.core.doctype.communication.mixins import CommunicationEmailMixin from frappe.core.utils import get_parent_doc from frappe.utils.bot import BotReply -from frappe.utils import parse_addr +from frappe.utils import parse_addr, split_emails from frappe.core.doctype.comment.comment import update_comment_in_doc from email.utils import parseaddr from urllib.parse import unquote @@ -19,7 +20,7 @@ from frappe.automation.doctype.assignment_rule.assignment_rule import apply as a exclude_from_linked_with = True -class Communication(Document): +class Communication(Document, CommunicationEmailMixin): """Communication represents an external communication like Email. """ no_feed_on_delete = True @@ -125,6 +126,45 @@ class Communication(Document): if self.communication_type == "Communication": self.notify_change('delete') + @property + def sender_mailid(self): + return parse_addr(self.sender)[1] if self.sender else "" + + @staticmethod + def _get_emails_list(emails=None, exclude_displayname = False): + """Returns list of emails from given email string. + + * Removes duplicate mailids + * Removes display name from email address if exclude_displayname is True + """ + emails = split_emails(emails) if isinstance(emails, str) else (emails or []) + if exclude_displayname: + return [email.lower() for email in set([parse_addr(email)[1] for email in emails]) if email] + return [email.lower() for email in set(emails) if email] + + def to_list(self, exclude_displayname = True): + """Returns to list. + """ + return self._get_emails_list(self.recipients, exclude_displayname=exclude_displayname) + + def cc_list(self, exclude_displayname = True): + """Returns cc list. + """ + return self._get_emails_list(self.cc, exclude_displayname=exclude_displayname) + + def bcc_list(self, exclude_displayname = True): + """Returns bcc list. + """ + return self._get_emails_list(self.bcc, exclude_displayname=exclude_displayname) + + def get_attachments(self): + attachments = frappe.get_all( + "File", + fields=["name", "file_name", "file_url", "is_private"], + filters = {"attached_to_name": self.name, "attached_to_doctype": self.DOCTYPE} + ) + return attachments + def notify_change(self, action): frappe.publish_realtime('update_docinfo_for_{}_{}'.format(self.reference_doctype, self.reference_name), { 'doc': self.as_dict(), @@ -198,36 +238,6 @@ class Communication(Document): if not self.sender_full_name: self.sender_full_name = sender_email - def send(self, print_html=None, print_format=None, attachments=None, - send_me_a_copy=False, recipients=None): - """Send communication via Email. - - :param print_html: Send given value as HTML attachment. - :param print_format: Attach print format of parent document.""" - - self.send_me_a_copy = send_me_a_copy - self.notify(print_html, print_format, attachments, recipients) - - def notify(self, print_html=None, print_format=None, attachments=None, - recipients=None, cc=None, bcc=None,fetched_from_email_account=False): - """Calls a delayed task 'sendmail' that enqueus email in Email Queue queue - - :param print_html: Send given value as HTML attachment - :param print_format: Attach print format of parent document - :param attachments: A list of filenames that should be attached when sending this email - :param recipients: Email recipients - :param cc: Send email as CC to - :param fetched_from_email_account: True when pulling email, the notification shouldn't go to the main recipient - - """ - notify(self, print_html, print_format, attachments, recipients, cc, bcc, - fetched_from_email_account) - - def _notify(self, print_html=None, print_format=None, attachments=None, - recipients=None, cc=None, bcc=None): - - _notify(self, print_html, print_format, attachments, recipients, cc, bcc) - def bot_reply(self): if self.comment_type == 'Bot' and self.communication_type == 'Chat': reply = BotReply().get_reply(self.content) @@ -504,3 +514,4 @@ def set_avg_response_time(parent, communication): if response_times: avg_response_time = sum(response_times) / len(response_times) parent.db_set("avg_response_time", avg_response_time) + diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index c28956b41f..d35c118550 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -13,6 +13,11 @@ import time from frappe import _ from frappe.utils.background_jobs import enqueue +OUTGOING_EMAIL_ACCOUNT_MISSING = _(""" + Unable to send mail because of a missing email account. + Please setup default Email Account from Setup > Email > Email Account +""") + @frappe.whitelist() def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", sender=None, sender_full_name=None, recipients=None, communication_medium="Email", send_email=False, @@ -36,7 +41,6 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = :param send_me_a_copy: Send a copy to the sender (default **False**). :param email_template: Template which is used to compose mail . """ - is_error_report = (doctype=="User" and name==frappe.session.user and subject=="Error Report") send_me_a_copy = cint(send_me_a_copy) @@ -84,12 +88,16 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = frappe.db.commit() if cint(send_email): - frappe.flags.print_letterhead = cint(print_letterhead) - comm.send(print_html, print_format, attachments, send_me_a_copy=send_me_a_copy) + if not comm.get_outgoing_email_account(): + frappe.throw(msg=OUTGOING_EMAIL_ACCOUNT_MISSING, exc=frappe.OutgoingEmailError) + comm.send_email(print_html=print_html, print_format=print_format, + send_me_a_copy=send_me_a_copy, print_letterhead=print_letterhead) + + emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy) return { "name": comm.name, - "emails_not_sent_to": ", ".join(comm.emails_not_sent_to) if hasattr(comm, "emails_not_sent_to") else None + "emails_not_sent_to": ", ".join(emails_not_sent_to or []) } def validate_email(doc): @@ -110,164 +118,6 @@ def validate_email(doc): # validate sender -def notify(doc, print_html=None, print_format=None, attachments=None, - recipients=None, cc=None, bcc=None, fetched_from_email_account=False): - """Calls a delayed task 'sendmail' that enqueus email in Email Queue queue - - :param print_html: Send given value as HTML attachment - :param print_format: Attach print format of parent document - :param attachments: A list of filenames that should be attached when sending this email - :param recipients: Email recipients - :param cc: Send email as CC to - :param bcc: Send email as BCC to - :param fetched_from_email_account: True when pulling email, the notification shouldn't go to the main recipient - - """ - recipients, cc, bcc = get_recipients_cc_and_bcc(doc, recipients, cc, bcc, - fetched_from_email_account=fetched_from_email_account) - - if not recipients and not cc: - return - - doc.emails_not_sent_to = set(doc.all_email_addresses) - set(doc.sent_email_addresses) - - if frappe.flags.in_test: - # for test cases, run synchronously - doc._notify(print_html=print_html, print_format=print_format, attachments=attachments, - recipients=recipients, cc=cc, bcc=None) - else: - enqueue(sendmail, queue="default", timeout=300, event="sendmail", - communication_name=doc.name, - print_html=print_html, print_format=print_format, attachments=attachments, - recipients=recipients, cc=cc, bcc=bcc, lang=frappe.local.lang, - session=frappe.local.session, print_letterhead=frappe.flags.print_letterhead) - -def _notify(doc, print_html=None, print_format=None, attachments=None, - recipients=None, cc=None, bcc=None): - - prepare_to_notify(doc, print_html, print_format, attachments) - - if doc.outgoing_email_account.send_unsubscribe_message: - unsubscribe_message = _("Leave this conversation") - else: - unsubscribe_message = "" - - frappe.sendmail( - recipients=(recipients or []), - cc=(cc or []), - bcc=(bcc or []), - expose_recipients="header", - sender=doc.sender, - reply_to=doc.incoming_email_account, - subject=doc.subject, - content=doc.content, - reference_doctype=doc.reference_doctype, - reference_name=doc.reference_name, - attachments=doc.attachments, - message_id=doc.message_id, - unsubscribe_message=unsubscribe_message, - delayed=True, - communication=doc.name, - read_receipt=doc.read_receipt, - is_notification=True if doc.sent_or_received =="Received" else False, - print_letterhead=frappe.flags.print_letterhead - ) - -def get_recipients_cc_and_bcc(doc, recipients, cc, bcc, fetched_from_email_account=False): - doc.all_email_addresses = [] - doc.sent_email_addresses = [] - doc.previous_email_sender = None - - if not recipients: - recipients = get_recipients(doc, fetched_from_email_account=fetched_from_email_account) - - if not cc: - cc = get_cc(doc, recipients, fetched_from_email_account=fetched_from_email_account) - - if not bcc: - bcc = get_bcc(doc, recipients, fetched_from_email_account=fetched_from_email_account) - - if fetched_from_email_account: - # email was already sent to the original recipient by the sender's email service - original_recipients, recipients = recipients, [] - - # send email to the sender of the previous email in the thread which this email is a reply to - #provides erratic results and can send external - #if doc.previous_email_sender: - # recipients.append(doc.previous_email_sender) - - # cc that was received in the email - original_cc = split_emails(doc.cc) - - # don't cc to people who already received the mail from sender's email service - cc = list(set(cc) - set(original_cc) - set(original_recipients)) - remove_administrator_from_email_list(cc) - - original_bcc = split_emails(doc.bcc) - bcc = list(set(bcc) - set(original_bcc) - set(original_recipients)) - remove_administrator_from_email_list(bcc) - - remove_administrator_from_email_list(recipients) - - return recipients, cc, bcc - -def remove_administrator_from_email_list(email_list): - administrator_email = list(filter(lambda emails: "Administrator" in emails, email_list)) - if administrator_email: - email_list.remove(administrator_email[0]) - -def prepare_to_notify(doc, print_html=None, print_format=None, attachments=None): - """Prepare to make multipart MIME Email - - :param print_html: Send given value as HTML attachment. - :param print_format: Attach print format of parent document.""" - - view_link = frappe.utils.cint(frappe.db.get_value("System Settings", "System Settings", "attach_view_link")) - - if print_format and view_link: - doc.content += get_attach_link(doc, print_format) - - set_incoming_outgoing_accounts(doc) - - if not doc.sender: - doc.sender = doc.outgoing_email_account.email_id - - if not doc.sender_full_name: - doc.sender_full_name = doc.outgoing_email_account.name or _("Notification") - - if doc.sender: - # combine for sending to get the format 'Jane ' - doc.sender = get_formatted_email(doc.sender_full_name, mail=doc.sender) - - doc.attachments = [] - - if print_html or print_format: - doc.attachments.append({"print_format_attachment":1, "doctype":doc.reference_doctype, - "name":doc.reference_name, "print_format":print_format, "html":print_html}) - - if attachments: - if isinstance(attachments, str): - attachments = json.loads(attachments) - - for a in attachments: - if isinstance(a, str): - # is it a filename? - try: - # check for both filename and file id - file_id = frappe.db.get_list('File', or_filters={'file_name': a, 'name': a}, limit=1) - if not file_id: - frappe.throw(_("Unable to find attachment {0}").format(a)) - file_id = file_id[0]['name'] - _file = frappe.get_doc("File", file_id) - _file.get_content() - # these attachments will be attached on-demand - # and won't be stored in the message - doc.attachments.append({"fid": file_id}) - except IOError: - frappe.throw(_("Unable to find attachment {0}").format(a)) - else: - doc.attachments.append(a) - def set_incoming_outgoing_accounts(doc): from frappe.email.doctype.email_account.email_account import EmailAccount incoming_email_account = EmailAccount.find_incoming( @@ -280,74 +130,6 @@ def set_incoming_outgoing_accounts(doc): if doc.sent_or_received == "Sent": doc.db_set("email_account", doc.outgoing_email_account.name) -def get_recipients(doc, fetched_from_email_account=False): - """Build a list of email addresses for To""" - # [EDGE CASE] doc.recipients can be None when an email is sent as BCC - recipients = split_emails(doc.recipients) - - #if fetched_from_email_account and doc.in_reply_to: - # add sender of previous reply - #doc.previous_email_sender = frappe.db.get_value("Communication", doc.in_reply_to, "sender") - #recipients.append(doc.previous_email_sender) - - if recipients: - recipients = filter_email_list(doc, recipients, []) - - return recipients - -def get_cc(doc, recipients=None, fetched_from_email_account=False): - """Build a list of email addresses for CC""" - # get a copy of CC list - cc = split_emails(doc.cc) - - if doc.reference_doctype and doc.reference_name: - if fetched_from_email_account: - # if it is a fetched email, add follows to CC - cc.append(get_owner_email(doc)) - cc += get_assignees(doc) - - if getattr(doc, "send_me_a_copy", False) and doc.sender not in cc: - cc.append(doc.sender) - - if cc: - # exclude unfollows, recipients and unsubscribes - exclude = [] #added to remove account check - exclude += [d[0] for d in frappe.db.get_all("User", ["email"], {"thread_notify": 0}, as_list=True)] - exclude += [(parse_addr(email)[1] or "").lower() for email in recipients] - - if fetched_from_email_account: - # exclude sender when pulling email - exclude += [parse_addr(doc.sender)[1]] - - if doc.reference_doctype and doc.reference_name: - exclude += [d[0] for d in frappe.db.get_all("Email Unsubscribe", ["email"], - {"reference_doctype": doc.reference_doctype, "reference_name": doc.reference_name}, as_list=True)] - - cc = filter_email_list(doc, cc, exclude, is_cc=True) - - return cc - -def get_bcc(doc, recipients=None, fetched_from_email_account=False): - """Build a list of email addresses for BCC""" - bcc = split_emails(doc.bcc) - - if bcc: - exclude = [] - exclude += [d[0] for d in frappe.db.get_all("User", ["email"], {"thread_notify": 0}, as_list=True)] - exclude += [(parse_addr(email)[1] or "").lower() for email in recipients] - - if fetched_from_email_account: - # exclude sender when pulling email - exclude += [parse_addr(doc.sender)[1]] - - if doc.reference_doctype and doc.reference_name: - exclude += [d[0] for d in frappe.db.get_all("Email Unsubscribe", ["email"], - {"reference_doctype": doc.reference_doctype, "reference_name": doc.reference_name}, as_list=True)] - - bcc = filter_email_list(doc, bcc, exclude, is_bcc=True) - - return bcc - def add_attachments(name, attachments): '''Add attachments to the given Communication''' # loop through attachments @@ -355,7 +137,6 @@ def add_attachments(name, attachments): if isinstance(a, str): attach = frappe.db.get_value("File", {"name":a}, ["file_name", "file_url", "is_private"], as_dict=1) - # save attachments to new doc _file = frappe.get_doc({ "doctype": "File", @@ -367,103 +148,6 @@ def add_attachments(name, attachments): }) _file.save(ignore_permissions=True) -def filter_email_list(doc, email_list, exclude, is_cc=False, is_bcc=False): - # temp variables - filtered = [] - email_address_list = [] - - for email in list(set(email_list)): - email_address = (parse_addr(email)[1] or "").lower() - if not email_address: - continue - - # this will be used to eventually find email addresses that aren't sent to - doc.all_email_addresses.append(email_address) - - if (email in exclude) or (email_address in exclude): - continue - - if is_cc: - is_user_enabled = frappe.db.get_value("User", email_address, "enabled") - if is_user_enabled==0: - # don't send to disabled users - continue - - if is_bcc: - is_user_enabled = frappe.db.get_value("User", email_address, "enabled") - if is_user_enabled==0: - continue - - # make sure of case-insensitive uniqueness of email address - if email_address not in email_address_list: - # append the full email i.e. "Human " - filtered.append(email) - email_address_list.append(email_address) - - doc.sent_email_addresses.extend(email_address_list) - - return filtered - -def get_owner_email(doc): - owner = get_parent_doc(doc).owner - return get_formatted_email(owner) or owner - -def get_assignees(doc): - return [( get_formatted_email(d.owner) or d.owner ) for d in - frappe.db.get_all("ToDo", filters={ - "reference_type": doc.reference_doctype, - "reference_name": doc.reference_name, - "status": "Open" - }, fields=["owner"]) - ] - -def get_attach_link(doc, print_format): - """Returns public link for the attachment via `templates/emails/print_link.html`.""" - return frappe.get_template("templates/emails/print_link.html").render({ - "url": get_url(), - "doctype": doc.reference_doctype, - "name": doc.reference_name, - "print_format": print_format, - "key": get_parent_doc(doc).get_signature() - }) - -def sendmail(communication_name, print_html=None, print_format=None, attachments=None, - recipients=None, cc=None, bcc=None, lang=None, session=None, print_letterhead=None): - try: - - if lang: - frappe.local.lang = lang - - if session: - # hack to enable access to private files in PDF - session['data'] = frappe._dict(session['data']) - frappe.local.session.update(session) - - if print_letterhead: - frappe.flags.print_letterhead = print_letterhead - - # upto 3 retries - for i in range(3): - try: - communication = frappe.get_doc("Communication", communication_name) - communication._notify(print_html=print_html, print_format=print_format, attachments=attachments, - recipients=recipients, cc=cc, bcc=bcc) - - except frappe.db.InternalError as e: - # deadlock, try again - if frappe.db.is_deadlocked(e): - frappe.db.rollback() - time.sleep(1) - continue - else: - raise - else: - break - - except: - traceback = frappe.log_error("frappe.core.doctype.communication.email.sendmail") - raise - @frappe.whitelist(allow_guest=True) def mark_email_as_seen(name=None): try: diff --git a/frappe/core/doctype/communication/mixins.py b/frappe/core/doctype/communication/mixins.py new file mode 100644 index 0000000000..82a47d24d9 --- /dev/null +++ b/frappe/core/doctype/communication/mixins.py @@ -0,0 +1,297 @@ +import frappe +from frappe import _ +from frappe.core.utils import get_parent_doc +from frappe.utils import parse_addr, get_formatted_email, get_url +from frappe.email.doctype.email_account.email_account import EmailAccount + +class CommunicationEmailMixin: + """Mixin class to handle communication mails. + """ + def is_email_communication(self): + return self.communication_type=="Communication" and self.communication_medium == "Email" + + def get_owner(self): + """Get owner of the communication docs parent. + """ + parent_doc = get_parent_doc(self) + return parent_doc.owner if parent_doc else None + + def get_all_email_addresses(self, exclude_displayname=False): + """Get all Email addresses mentioned in the doc along with display name. + """ + return self.to_list(exclude_displayname=exclude_displayname) + \ + self.cc_list(exclude_displayname=exclude_displayname) + \ + self.bcc_list(exclude_displayname=exclude_displayname) + + def get_email_with_displayname(self, email_address): + """Returns email address after adding displayname. + """ + display_name, email = parse_addr(email_address) + if display_name and display_name != email: + return email_address + + # emailid to emailid with display name map. + email_map = {parse_addr(email)[1]: email for email in self.get_all_email_addresses()} + return email_map.get(email, email) + + def mail_recipients(self, is_inbound_mail_communcation=False): + """Build to(recipient) list to send an email. + """ + # Incase of inbound mail, recipients already received the mail, no need to send again. + if is_inbound_mail_communcation: + return [] + + if hasattr(self, '_final_recipients'): + return self._final_recipients + + to = self.to_list() + self._final_recipients = list(filter(lambda id: id != 'Administrator', to)) + return self._final_recipients + + def get_mail_recipients_with_displayname(self, is_inbound_mail_communcation=False): + """Build to(recipient) list to send an email including displayname in email. + """ + to_list = self.mail_recipients(is_inbound_mail_communcation=is_inbound_mail_communcation) + return [self.get_email_with_displayname(email) for email in to_list] + + def mail_cc(self, is_inbound_mail_communcation=False, include_sender = False): + """Build cc list to send an email. + + * if email copy is requested by sender, then add sender to CC. + * If this doc is created through inbound mail, then add doc owner to cc list + * remove all the thread_notify disabled users. + * Make sure that all users enabled in the system + * Remove admin from email list + + * FixMe: Removed adding TODO owners to cc list. Check if that is needed. + """ + if hasattr(self, '_final_cc'): + return self._final_cc + + cc = self.cc_list() + + # Need to inform parent document owner incase communication is created through inbound mail + if include_sender: + cc.append(self.sender_mailid) + if is_inbound_mail_communcation: + cc.append(self.get_owner()) + cc = set(cc) - {self.sender_mailid} + + cc = set(cc) - set(self.filter_thread_notification_disbled_users(cc)) + cc = cc - set(self.mail_recipients(is_inbound_mail_communcation=is_inbound_mail_communcation)) + cc = cc - set(self.filter_disabled_users(cc)) + + # # Incase of inbound mail, to and cc already received the mail, no need to send again. + if is_inbound_mail_communcation: + cc = cc - set(self.cc_list() + self.to_list()) + + self._final_cc = list(filter(lambda id: id != 'Administrator', cc)) + return self._final_cc + + def get_mail_cc_with_displayname(self, is_inbound_mail_communcation=False, include_sender = False): + cc_list = self.mail_cc(is_inbound_mail_communcation=False, include_sender = False) + return [self.get_email_with_displayname(email) for email in cc_list] + + def mail_bcc(self, is_inbound_mail_communcation=False): + """ + * Thread_notify check + * Email unsubscribe list + * User must be enabled in the system + * remove_administrator_from_email_list + """ + if hasattr(self, '_final_bcc'): + return self._final_bcc + + bcc = set(self.bcc_list()) + if is_inbound_mail_communcation: + bcc = bcc - {self.sender_mailid} + bcc = bcc - set(self.filter_thread_notification_disbled_users(bcc)) + bcc = bcc - set(self.mail_recipients(is_inbound_mail_communcation=is_inbound_mail_communcation)) + bcc = bcc - set(self.filter_disabled_users(bcc)) + + # Incase of inbound mail, to and cc & bcc already received the mail, no need to send again. + if is_inbound_mail_communcation: + bcc = bcc - set(self.bcc_list() + self.to_list()) + + self._final_bcc = list(filter(lambda id: id != 'Administrator', bcc)) + return self._final_bcc + + def get_mail_bcc_with_displayname(self, is_inbound_mail_communcation=False): + bcc_list = self.mail_bcc(is_inbound_mail_communcation=is_inbound_mail_communcation) + return [self.get_email_with_displayname(email) for email in bcc_list] + + def mail_sender(self): + email_account = self.get_outgoing_email_account() + if not self.sender_mailid and email_account: + return email_account.email_id + return self.sender_mailid + + def mail_sender_fullname(self): + email_account = self.get_outgoing_email_account() + if not self.sender_full_name: + return (email_account and email_account.name) or _("Notification") + return self.sender_full_name + + def get_mail_sender_with_displayname(self): + return get_formatted_email(self.mail_sender_fullname(), mail=self.mail_sender()) + + def get_content(self, print_format=None): + if print_format: + return self.content + self.get_attach_link(print_format) + return self.content + + def get_attach_link(self, print_format): + """Returns public link for the attachment via `templates/emails/print_link.html`.""" + return frappe.get_template("templates/emails/print_link.html").render({ + "url": get_url(), + "doctype": self.reference_doctype, + "name": self.reference_name, + "print_format": print_format, + "key": get_parent_doc(self).get_signature() + }) + + def get_outgoing_email_account(self): + if not hasattr(self, '_outgoing_email_account'): + if self.email_account: + self._outgoing_email_account = EmailAccount.find(self.email_account) + else: + self._outgoing_email_account = EmailAccount.find_outgoing( + match_by_email=self.sender_mailid, + match_by_doctype=self.reference_doctype + ) + + if self.sent_or_received == "Sent" and self._outgoing_email_account: + self.db_set("email_account", self._outgoing_email_account.name) + + return self._outgoing_email_account + + def get_incoming_email_account(self): + if not hasattr(self, '_incoming_email_account'): + self._incoming_email_account = EmailAccount.find_incoming( + match_by_email=self.sender_mailid, + match_by_doctype=self.reference_doctype + ) + return self._incoming_email_account + + def mail_attachments(self, print_format=None, print_html=None): + final_attachments = [] + + if print_format and print_html: + d = {'print_format': print_format, 'print_html': print_html, 'print_format_attachment': 1, + 'doctype': self.reference_doctype, 'name': self.reference_name} + final_attachments.append(d) + + for a in self.get_attachments() or []: + final_attachments.append({"fid": a['name']}) + + return final_attachments + + def get_unsubscribe_message(self): + email_account = self.get_outgoing_email_account() + if email_account and email_account.send_unsubscribe_message: + return _("Leave this conversation") + return '' + + def exclude_emails_list(self, is_inbound_mail_communcation=False, include_sender=False): + """List of mail id's excluded while sending mail. + """ + all_ids = self.get_all_email_addresses(exclude_displayname=True) + final_ids = self.mail_recipients(is_inbound_mail_communcation = is_inbound_mail_communcation) + \ + self.mail_bcc(is_inbound_mail_communcation = is_inbound_mail_communcation) + \ + self.mail_cc(is_inbound_mail_communcation = is_inbound_mail_communcation, include_sender=include_sender) + return set(all_ids) - set(final_ids) + + @staticmethod + def filter_thread_notification_disbled_users(emails): + """Filter users based on notifications for email threads setting is disabled. + """ + if not emails: + return [] + + disabled_users = frappe.db.sql_list(""" + SELECT + email + FROM + `tabUser` + where + email in %(emails)s + and + thread_notify=0 + """, {'emails': tuple(emails)}) + return disabled_users + + @staticmethod + def filter_disabled_users(emails): + """ + """ + if not emails: + return [] + + disabled_users = frappe.db.sql_list(""" + SELECT + email + FROM + `tabUser` + where + email in %(emails)s + and + enabled=0 + """, {'emails': tuple(emails)}) + return disabled_users + + def sendmail_input_dict(self, print_html=None, print_format=None, + send_me_a_copy=None, print_letterhead=None, is_inbound_mail_communcation=None): + + outgoing_email_account = self.get_outgoing_email_account() + if not outgoing_email_account: + return {} + + recipients = self.get_mail_recipients_with_displayname( + is_inbound_mail_communcation=is_inbound_mail_communcation + ) + cc = self.get_mail_cc_with_displayname( + is_inbound_mail_communcation=is_inbound_mail_communcation, + include_sender = send_me_a_copy + ) + bcc = self.get_mail_bcc_with_displayname( + is_inbound_mail_communcation=is_inbound_mail_communcation + ) + + if not (recipients or cc): + return {} + + final_attachments = self.mail_attachments(print_format=print_format, print_html=print_html) + incoming_email_account = self.get_incoming_email_account() + return { + "recipients": recipients, + "cc": cc, + "bcc": bcc, + "expose_recipients": "header", + "sender": self.get_mail_sender_with_displayname(), + "reply_to": incoming_email_account and incoming_email_account.email_id, + "subject": self.subject, + "content": self.get_content(print_format=print_format), + "reference_doctype": self.reference_doctype, + "reference_name": self.reference_name, + "attachments": final_attachments, + "message_id": self.message_id, + "unsubscribe_message": self.get_unsubscribe_message(), + "delayed": True, + "communication": self.name, + "read_receipt": self.read_receipt, + "is_notification": (self.sent_or_received =="Received" and True) or False, + "print_letterhead": print_letterhead + } + + def send_email(self, print_html=None, print_format=None, + send_me_a_copy=None, print_letterhead=None, is_inbound_mail_communcation=None): + input_dict = self.sendmail_input_dict( + print_html=print_html, + print_format=print_format, + send_me_a_copy=send_me_a_copy, + print_letterhead=print_letterhead, + is_inbound_mail_communcation=is_inbound_mail_communcation + ) + + if input_dict: + frappe.sendmail(**input_dict) diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index 7aba559d1f..7ca4e6f99c 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -441,10 +441,7 @@ class EmailAccount(Document): if self.enable_auto_reply: self.send_auto_reply(communication, mail) - attachments = [] - if hasattr(communication, '_attachments'): - attachments = [d.file_name for d in communication._attachments] - communication.notify(attachments=attachments, fetched_from_email_account=True) + communication.send_email(is_inbound_mail_communcation=True) except SentEmailInInboxError: frappe.db.rollback() except Exception: @@ -453,6 +450,8 @@ class EmailAccount(Document): if self.use_imap: self.handle_bad_emails(mail.uid, mail.raw_message, frappe.get_traceback()) exceptions.append(frappe.get_traceback()) + else: + frappe.db.commit() #notify if user is linked to account if len(inbound_mails)>0 and not frappe.local.flags.in_test: From 63f4e9ed7bacc83211c0e0f382e4ba05a1d31d6b Mon Sep 17 00:00:00 2001 From: leela Date: Wed, 9 Jun 2021 11:21:06 +0530 Subject: [PATCH 10/22] test: testcases for communication email mixin --- .../communication/test_communication.py | 72 ++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/communication/test_communication.py b/frappe/core/doctype/communication/test_communication.py index 5b400398a5..d50a4db88a 100644 --- a/frappe/core/doctype/communication/test_communication.py +++ b/frappe/core/doctype/communication/test_communication.py @@ -1,10 +1,12 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -import frappe import unittest from urllib.parse import quote -test_records = frappe.get_test_records('Communication') +import frappe +from frappe.email.doctype.email_queue.email_queue import EmailQueue + +test_records = frappe.get_test_records('Communication') class TestCommunication(unittest.TestCase): @@ -199,6 +201,70 @@ class TestCommunication(unittest.TestCase): self.assertIn(("Note", note.name), doc_links) +class TestCommunicationEmailMixin(unittest.TestCase): + def new_communication(self, recipients=None, cc=None, bcc=None): + recipients = ', '.join(recipients or []) + cc = ', '.join(cc or []) + bcc = ', '.join(bcc or []) + + comm = frappe.get_doc({ + "doctype": "Communication", + "communication_type": "Communication", + "communication_medium": "Email", + "content": "Test content", + "recipients": recipients, + "cc": cc, + "bcc": bcc + }).insert(ignore_permissions=True) + return comm + + def new_user(self, email, **user_data): + user_data.setdefault('first_name', 'first_name') + user = frappe.new_doc('User') + user.email = email + user.update(user_data) + user.insert(ignore_permissions=True, ignore_if_duplicate=True) + return user + + def test_recipients(self): + to_list = ['to@test.com', 'receiver ', 'to@test.com'] + comm = self.new_communication(recipients = to_list) + res = comm.get_mail_recipients_with_displayname() + self.assertCountEqual(res, ['to@test.com', 'receiver ']) + comm.delete() + + def test_cc(self): + to_list = ['to@test.com'] + cc_list = ['cc+1@test.com', 'cc ', 'to@test.com'] + user = self.new_user(email='cc+1@test.com', thread_notify=0) + comm = self.new_communication(recipients=to_list, cc=cc_list) + res = comm.get_mail_cc_with_displayname() + self.assertCountEqual(res, ['cc ']) + user.delete() + comm.delete() + + def test_bcc(self): + bcc_list = ['bcc+1@test.com', 'cc ', ] + user = self.new_user(email='bcc+2@test.com', enabled=0) + comm = self.new_communication(bcc=bcc_list) + res = comm.get_mail_bcc_with_displayname() + self.assertCountEqual(res, ['bcc+1@test.com']) + user.delete() + comm.delete() + + def test_sendmail(self): + to_list = ['to '] + cc_list = ['cc ', 'cc '] + + comm = self.new_communication(recipients=to_list, cc=cc_list) + comm.send_email() + doc = EmailQueue.find_one_by_filters(communication=comm.name) + mail_receivers = [each.recipient for each in doc.recipients] + self.assertIsNotNone(doc) + self.assertCountEqual(to_list+cc_list, mail_receivers) + doc.delete() + comm.delete() + def create_email_account(): frappe.delete_doc_if_exists("Email Account", "_Test Comm Account 1") @@ -229,4 +295,4 @@ def create_email_account(): "enable_automatic_linking": 1 }).insert(ignore_permissions=True) - return email_account \ No newline at end of file + return email_account From 14a1b7f4acd0b20a273fc29d1966db555d1f3e57 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 10 Jun 2021 11:13:37 +0000 Subject: [PATCH 11/22] chore(deps): [security] bump jquery from 2.2.4 to 3.5.0 Bumps [jquery](https://github.com/jquery/jquery) from 2.2.4 to 3.5.0. **This update includes security fixes.** - [Release notes](https://github.com/jquery/jquery/releases) - [Commits](https://github.com/jquery/jquery/compare/2.2.4...3.5.0) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- yarn.lock | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index e666a2e1ce..086e6a72b4 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "frappe-gantt": "^0.5.0", "fuse.js": "^3.4.6", "highlight.js": "^10.4.1", - "jquery": "2.2.4", + "jquery": "3.5.0", "js-sha256": "^0.9.0", "jsbarcode": "^3.9.0", "localforage": "^1.9.0", diff --git a/yarn.lock b/yarn.lock index 298c424b72..028cabaaee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3513,15 +3513,10 @@ jpeg-js@^0.3.2: resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.6.tgz#c40382aac9506e7d1f2d856eb02f6c7b2a98b37c" integrity sha512-MUj2XlMB8kpe+8DJUGH/3UJm4XpI8XEgZQ+CiHDeyrGoKPdW/8FJv6ku+3UiYm5Fz3CWaL+iXmD8Q4Ap6aC1Jw== -jquery@2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-2.2.4.tgz#2c89d6889b5eac522a7eea32c14521559c6cbf02" - integrity sha1-LInWiJterFIqfuoywUUhVZxsvwI= - -"jquery@>=2.0.0 <4.0.0": - version "3.4.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" - integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== +jquery@3.5.0, "jquery@>=2.0.0 <4.0.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9" + integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ== js-base64@^2.1.8: version "2.6.4" From f3550f84610e9791ff4b886f9b5a19498133061a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Jun 2021 11:34:24 +0000 Subject: [PATCH 12/22] chore(deps): bump normalize-url from 4.5.0 to 4.5.1 Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/sindresorhus/normalize-url/releases) - [Commits](https://github.com/sindresorhus/normalize-url/commits) --- updated-dependencies: - dependency-name: normalize-url dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index d2fb9772c1..bb85cf704b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4405,12 +4405,7 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - -normalize-url@^4.5.0: +normalize-url@^4.1.0, normalize-url@^4.5.0: version "4.5.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== From e534dc0a026b49e7f22cba3d2f3d003aa600063a Mon Sep 17 00:00:00 2001 From: leela Date: Thu, 10 Jun 2021 21:30:53 +0530 Subject: [PATCH 13/22] feat: Make url's clickable in text editor when typed/copied Using a Quill module named quill-magic-url to automatically convert typed/copied urls into links. --- .../public/js/frappe/form/controls/text_editor.js | 6 +++++- package.json | 1 + yarn.lock | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/text_editor.js b/frappe/public/js/frappe/form/controls/text_editor.js index 059b0f76f8..1c7077eb64 100644 --- a/frappe/public/js/frappe/form/controls/text_editor.js +++ b/frappe/public/js/frappe/form/controls/text_editor.js @@ -1,7 +1,10 @@ import Quill from 'quill'; import ImageResize from 'quill-image-resize'; +import MagicUrl from 'quill-magic-url'; + Quill.register('modules/imageResize', ImageResize); +Quill.register('modules/magicUrl', MagicUrl) const CodeBlockContainer = Quill.import('formats/code-block-container'); CodeBlockContainer.tagName = 'PRE'; Quill.register(CodeBlockContainer, true); @@ -148,7 +151,8 @@ frappe.ui.form.ControlTextEditor = class ControlTextEditor extends frappe.ui.for modules: { toolbar: this.get_toolbar_options(), table: true, - imageResize: {} + imageResize: {}, + magicUrl: true }, theme: 'snow' }; diff --git a/package.json b/package.json index e666a2e1ce..078af44cd7 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "quagga": "^0.12.1", "quill": "2.0.0-dev.4", "quill-image-resize": "^3.0.9", + "quill-magic-url": "^3.0.0", "qz-tray": "^2.0.8", "redis": "^3.1.1", "showdown": "^1.9.1", diff --git a/yarn.lock b/yarn.lock index 298c424b72..4da6fe14e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4515,6 +4515,11 @@ normalize-url@^4.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== +normalize-url@^4.5.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -5626,6 +5631,14 @@ quill-image-resize@^3.0.9: quill "^1.2.2" raw-loader "^0.5.1" +quill-magic-url@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/quill-magic-url/-/quill-magic-url-3.0.2.tgz#84654c749650e006250cbaf905295cb87796f3a7" + integrity sha512-kLPDwjNExGJZyCLGxbaiTFD/OYHagNLRvsdKRV+2d946I8cxaXaB7IT9wbrB49jC8z1X5cwI+pzZzHZeV0orFw== + dependencies: + normalize-url "^4.5.0" + quill-delta "^3.6.2" + quill@2.0.0-dev.4: version "2.0.0-dev.4" resolved "https://registry.yarnpkg.com/quill/-/quill-2.0.0-dev.4.tgz#130e38efe7a16b3766d767d750c8aacc038945e7" From 97ac79a2954c52153714a75a78148560e2064212 Mon Sep 17 00:00:00 2001 From: leela Date: Fri, 11 Jun 2021 13:50:14 +0530 Subject: [PATCH 14/22] fix: consider email account while checking email limits Added email_account argument for out going email count utility functions as these are used to validate email limits. --- .../email/doctype/email_queue/email_queue.py | 9 ++- frappe/email/queue.py | 62 ++++++++++++++++--- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py index dad473b8aa..e1e332f978 100644 --- a/frappe/email/doctype/email_queue/email_queue.py +++ b/frappe/email/doctype/email_queue/email_queue.py @@ -179,7 +179,14 @@ class SendMailContext: else: email_status = self.is_mail_sent_to_all() and 'Sent' email_status = email_status or (self.sent_to and 'Partially Sent') or 'Not Sent' - self.queue_doc.update_status(status = email_status, commit = True) + + update_fields = {'status': email_status} + if self.email_account_doc.is_exists_in_db(): + update_fields['email_account'] = self.email_account_doc.name + else: + update_fields['email_account'] = None + + self.queue_doc.update_status(**update_fields, commit = True) def log_exception(self, exc_type, exc_val, exc_tb): if exc_type: diff --git a/frappe/email/queue.py b/frappe/email/queue.py index ca96981aa8..885a306cfb 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -6,15 +6,61 @@ from frappe import msgprint, _ from frappe.utils.verified_command import get_signed_params, verify_request from frappe.utils import get_url, now_datetime, cint -def get_emails_sent_this_month(): - return frappe.db.sql(""" - SELECT COUNT(*) FROM `tabEmail Queue` - WHERE `status`='Sent' AND EXTRACT(YEAR_MONTH FROM `creation`) = EXTRACT(YEAR_MONTH FROM NOW()) - """)[0][0] +def get_emails_sent_this_month(email_account=None): + """Get count of emails sent from a specific email account. -def get_emails_sent_today(): - return frappe.db.sql("""SELECT COUNT(`name`) FROM `tabEmail Queue` WHERE - `status` in ('Sent', 'Not Sent', 'Sending') AND `creation` > (NOW() - INTERVAL '24' HOUR)""")[0][0] + :param email_account: name of the email account used to send mail + + if email_account=None, email account filter is not applied while counting + """ + q = """ + SELECT + COUNT(*) + FROM + `tabEmail Queue` + WHERE + `status`='Sent' + AND + EXTRACT(YEAR_MONTH FROM `creation`) = EXTRACT(YEAR_MONTH FROM NOW()) + """ + + q_args = {} + if email_account is not None: + if email_account: + q += " AND email_account = %(email_account)s" + q_args['email_account'] = email_account + else: + q += " AND (email_account is null OR email_account='')" + + return frappe.db.sql(q, q_args)[0][0] + +def get_emails_sent_today(email_account=None): + """Get count of emails sent from a specific email account. + + :param email_account: name of the email account used to send mail + + if email_account=None, email account filter is not applied while counting + """ + q = """ + SELECT + COUNT(`name`) + FROM + `tabEmail Queue` + WHERE + `status` in ('Sent', 'Not Sent', 'Sending') + AND + `creation` > (NOW() - INTERVAL '24' HOUR) + """ + + q_args = {} + if email_account is not None: + if email_account: + q += " AND email_account = %(email_account)s" + q_args['email_account'] = email_account + else: + q += " AND (email_account is null OR email_account='')" + + return frappe.db.sql(q, q_args)[0][0] def get_unsubscribe_message(unsubscribe_message, expose_recipients): if unsubscribe_message: From 1e7cffe8bc413fbfc9fbbe9eeeee32114df545ec Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 11 Jun 2021 16:22:00 +0530 Subject: [PATCH 15/22] chore(ci): Add wait time before checking list view Cypress form.js tests run just fine locally but not on GHA :thonk: --- cypress/integration/form.js | 1 + 1 file changed, 1 insertion(+) diff --git a/cypress/integration/form.js b/cypress/integration/form.js index 20ed7a61cd..909955c1df 100644 --- a/cypress/integration/form.js +++ b/cypress/integration/form.js @@ -18,6 +18,7 @@ context('Form', () => { cy.get('.primary-action').click(); cy.wait('@form_save').its('response.statusCode').should('eq', 200); cy.visit('/app/todo'); + cy.wait(300); cy.get('.title-text').should('be.visible').and('contain', 'To Do'); cy.get('.list-row').should('contain', 'this is a test todo'); }); From 0e99ea6c4cbfd310d7fe26b241aec6e74c700d0f Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 5 Jun 2021 15:00:57 +0530 Subject: [PATCH 16/22] fix: property to hide grid delete button (cherry picked from commit d44a4ad730464137cac7a52b372163862687516b) --- frappe/public/js/frappe/form/grid.js | 4 ++++ frappe/public/js/frappe/form/grid_row.js | 3 +++ 2 files changed, 7 insertions(+) diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index a77791d0a2..5614add585 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -236,6 +236,10 @@ export default class Grid { } refresh_remove_rows_button() { + if (this.df.cannot_delete_rows) { + return; + } + this.remove_rows_button.toggleClass('hidden', this.wrapper.find('.grid-body .grid-row-check:checked:first').length ? false : true); this.remove_all_rows_button.toggleClass('hidden', diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index 33db00dede..8c51314066 100644 --- a/frappe/public/js/frappe/form/grid_row.js +++ b/frappe/public/js/frappe/form/grid_row.js @@ -569,6 +569,9 @@ export default class GridRow { .find('.grid-insert-row-below, .grid-insert-row, .grid-duplicate-row, .grid-append-row') .toggle(!cannot_add_rows); + this.wrapper.find('.grid-delete-row') + .toggle(!(this.grid.df && this.grid.df.cannot_delete_rows)); + frappe.dom.freeze("", "dark"); if (cur_frm) cur_frm.cur_grid = this; this.wrapper.addClass("grid-row-open"); From ff75a72a6ed39c6c9f640ba9969188a4eda00acc Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 14 Jun 2021 09:13:26 +0530 Subject: [PATCH 17/22] fix: Grid delete all should trigger form change --- frappe/public/js/frappe/form/grid.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index a77791d0a2..af89c7bd8a 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -210,9 +210,9 @@ export default class Grid { delete_all_rows() { frappe.confirm(__("Are you sure you want to delete all rows?"), () => { - this.frm.doc[this.df.fieldname] = []; - $(this.parent).find('.rows').empty(); - this.grid_rows = []; + this.grid_rows.forEach(row => { + row.remove(); + }); this.frm.script_manager.trigger(this.df.fieldname + "_delete", this.doctype); this.wrapper.find('.grid-heading-row .grid-row-check:checked:first').prop('checked', 0); From c523e760fdb4a49547212d5f11399940022a438a Mon Sep 17 00:00:00 2001 From: leela Date: Mon, 24 May 2021 13:56:21 +0530 Subject: [PATCH 18/22] fix: encode error to add outgoing mail to sent folder Failed to add outgoing mail to sent folder because of encoding issue. fixed it by using safe_encode method. (cherry picked from commit 5165e2afa3884310fd653280c834d984a5feda8d) --- frappe/email/doctype/email_account/email_account.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index 36b662bb39..86d1892e92 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -12,7 +12,7 @@ import functools import email.utils -from frappe import _, are_emails_muted +from frappe import _, are_emails_muted, safe_encode from frappe.model.document import Document from frappe.utils import (validate_email_address, cint, cstr, get_datetime, DATE_FORMAT, strip, comma_or, sanitize_html, add_days, parse_addr) @@ -882,7 +882,6 @@ class EmailAccount(Document): def append_email_to_sent_folder(self, message): - email_server = None try: email_server = self.get_incoming_server(in_receive=True) @@ -896,7 +895,8 @@ class EmailAccount(Document): if email_server.imap: try: - email_server.imap.append("Sent", "\\Seen", imaplib.Time2Internaldate(time.time()), message.encode()) + message = safe_encode(message) + email_server.imap.append("Sent", "\\Seen", imaplib.Time2Internaldate(time.time()), message) except Exception: frappe.log_error() From eae6ab3cf965963b39a4a830a7aed3eda66a361b Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:05:14 +0530 Subject: [PATCH 19/22] style: Add missing semicolon --- frappe/public/js/frappe/form/controls/text_editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/text_editor.js b/frappe/public/js/frappe/form/controls/text_editor.js index 1c7077eb64..99e87c5f21 100644 --- a/frappe/public/js/frappe/form/controls/text_editor.js +++ b/frappe/public/js/frappe/form/controls/text_editor.js @@ -4,7 +4,7 @@ import MagicUrl from 'quill-magic-url'; Quill.register('modules/imageResize', ImageResize); -Quill.register('modules/magicUrl', MagicUrl) +Quill.register('modules/magicUrl', MagicUrl); const CodeBlockContainer = Quill.import('formats/code-block-container'); CodeBlockContainer.tagName = 'PRE'; Quill.register(CodeBlockContainer, true); From a571cb9f91094fa5971f282c88c735dda859e131 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 14 Jun 2021 11:02:17 +0530 Subject: [PATCH 20/22] fix: Allow to remove filters from shortcut completely --- frappe/public/js/frappe/widgets/widget_dialog.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/widgets/widget_dialog.js b/frappe/public/js/frappe/widgets/widget_dialog.js index eefb78c29a..3f5a4acd73 100644 --- a/frappe/public/js/frappe/widgets/widget_dialog.js +++ b/frappe/public/js/frappe/widgets/widget_dialog.js @@ -271,18 +271,19 @@ class ShortcutDialog extends WidgetDialog { } process_data(data) { - let stats_filter = {}; if (this.dialog.get_value("type") == "DocType" && this.filter_group) { let filters = this.filter_group.get_filters(); + let stats_filter = null; if (filters.length) { + stats_filter = {}; filters.forEach((arr) => { stats_filter[arr[1]] = [arr[2], arr[3]]; }); - - data.stats_filter = JSON.stringify(stats_filter); + stats_filter = JSON.stringify(stats_filter); } + data.stats_filter = stats_filter; } data.label = data.label From 425b73ab6a33260fe9807e68f023f68f785ba698 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 14 Jun 2021 11:03:13 +0530 Subject: [PATCH 21/22] fix: Remove "No filter" message while adding filters --- frappe/public/js/frappe/ui/filters/filter_list.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/js/frappe/ui/filters/filter_list.js b/frappe/public/js/frappe/ui/filters/filter_list.js index 611ab024bf..69a9457c35 100644 --- a/frappe/public/js/frappe/ui/filters/filter_list.js +++ b/frappe/public/js/frappe/ui/filters/filter_list.js @@ -323,6 +323,7 @@ frappe.ui.FilterGroup = class { } add_filters_to_filter_group(filters) { + this.toggle_empty_filters(false); filters.forEach((filter) => { this.add_filter(filter[0], filter[1], filter[2], filter[3]); }); From e7d1eecef98db1481e7cd7cdba1b3badb4cfdad7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 14 Jun 2021 11:53:20 +0530 Subject: [PATCH 22/22] fix: Remove "No filter" message only if filter exists --- frappe/public/js/frappe/ui/filters/filter_list.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/ui/filters/filter_list.js b/frappe/public/js/frappe/ui/filters/filter_list.js index 69a9457c35..72312d7f13 100644 --- a/frappe/public/js/frappe/ui/filters/filter_list.js +++ b/frappe/public/js/frappe/ui/filters/filter_list.js @@ -323,10 +323,12 @@ frappe.ui.FilterGroup = class { } add_filters_to_filter_group(filters) { - this.toggle_empty_filters(false); - filters.forEach((filter) => { - this.add_filter(filter[0], filter[1], filter[2], filter[3]); - }); + if (filters.length) { + this.toggle_empty_filters(false); + filters.forEach((filter) => { + this.add_filter(filter[0], filter[1], filter[2], filter[3]); + }); + } } add(filters, refresh = true) {