From 8f29059b211d7574dd702a4a42107ecf3a8a4ac3 Mon Sep 17 00:00:00 2001 From: ResuBaka Date: Wed, 1 May 2019 10:23:26 +0200 Subject: [PATCH 01/18] Added prettier with prettierrc The prettierrc has rules that are like the current style. Only one thing changes with that, that the semicolons rule is true which is the default and that is needed in typescript --- .prettierrc | 5 +++++ package.json | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..721f806ea7 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "bracketSpacing": true, + "endOfLine": "lf" +} diff --git a/package.json b/package.json index b1fe1509b2..ad2b452db1 100755 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "test:e2e": "cypress open", "test:e2e:ci": "cypress run", "lint": "eslint --ext .js,.vue core src", - "lerna": "lerna" + "lerna": "lerna", + "format": "prettier --write 'core/modules/catalog/**/*.{js,vue,ts,json}'" }, "dependencies": { "@types/webpack": "^4.4.23", @@ -131,6 +132,7 @@ "phantomjs-prebuilt": "^2.1.10", "postcss-flexbugs-fixes": "^3.3.1", "postcss-loader": "^2.1.5", + "prettier": "^1.17.0", "print-message": "^2.1.0", "rimraf": "^2.6.0", "sass-loader": "^7.1.0", From f47f2f90835b3cc6d21fc6649545f3b29b26aad8 Mon Sep 17 00:00:00 2001 From: ResuBaka Date: Wed, 1 May 2019 10:26:31 +0200 Subject: [PATCH 02/18] Added eslint typescript support and updated .eslintrc.js With this we get rules that get triggert when prettier was not used. Then it adds all typescript rules for prettier and typescript it self. --- .eslintrc.js | 34 +- core/build/webpack.base.config.ts | 2 +- package.json | 8 +- yarn.lock | 4335 ++++++++++++++--------------- 4 files changed, 2179 insertions(+), 2200 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9af1b53955..85fdeececc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,20 +3,42 @@ module.exports = { env: { 'browser': true, 'jest': true }, parser: 'vue-eslint-parser', parserOptions: { - parser: "babel-eslint", + parser: '@typescript-eslint/parser', ecmaVersion: 8, sourceType: "module" }, // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style extends: [ - 'plugin:vue/recommended', 'standard' - ], - plugins: [ - 'vue', - 'vue-storefront' + 'plugin:vue/recommended', + 'standard', + 'plugin:@typescript-eslint/recommended', + 'prettier', + 'prettier/@typescript-eslint', + 'prettier/vue' ], + plugins: ['vue', 'vue-storefront', '@typescript-eslint'], // add your custom rules here rules: { + // Prettier rules these rulles should never be hit, as prettier formattes the code so + // so these will never get hit + 'no-tabs': 'error', + quotes: [ + 'error', + 'single', + { avoidEscape: true, allowTemplateLiterals: true } + ], + 'space-before-function-paren': [ + 'error', + { + anonymous: 'never', + named: 'never', + asyncArrow: 'always' + } + ], + 'array-bracket-spacing': ['error', 'never'], + semi: ['error', 'always'], + // disabled the rules because of line breaks that comes from prettier + 'standard/computed-property-even-spacing': 0, /* max attributes-per-line and order-in-components ** we should use this later, when eslint-plugin-vue will support auto fixing this */ diff --git a/core/build/webpack.base.config.ts b/core/build/webpack.base.config.ts index e0d04acd8e..dc84186eb2 100644 --- a/core/build/webpack.base.config.ts +++ b/core/build/webpack.base.config.ts @@ -123,7 +123,7 @@ export default { rules: [ { enforce: 'pre', - test: /\.(js|vue)$/, + test: /\.(js|vue,ts)$/, loader: 'eslint-loader', exclude: [/node_modules/, /test/] }, diff --git a/package.json b/package.json index ad2b452db1..7ec8b78c93 100755 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "test:unit": "jest -c test/unit/jest.conf.js", "test:e2e": "cypress open", "test:e2e:ci": "cypress run", - "lint": "eslint --ext .js,.vue core src", + "lint": "eslint --ext .js,.vue,.ts core src", "lerna": "lerna", "format": "prettier --write 'core/modules/catalog/**/*.{js,vue,ts,json}'" }, @@ -92,6 +92,8 @@ "@babel/preset-env": "^7.3.4", "@types/jest": "^24.0.11", "@types/node": "^10.12.18", + "@typescript-eslint/eslint-plugin": "^1.7.0", + "@typescript-eslint/parser": "^1.7.0", "@vue/test-utils": "^1.0.0-beta.29", "app-root-path": "^2.0.1", "autoprefixer": "^8.6.2", @@ -108,12 +110,14 @@ "d3-dsv": "^1.0.8", "detect-installed": "^2.0.4", "empty-dir": "^1.0.0", - "eslint": "^4.16.0", + "eslint": "^5.0.0", + "eslint-config-prettier": "^4.2.0", "eslint-config-standard": "^11.0.0", "eslint-friendly-formatter": "^4.0.1", "eslint-loader": "^2.0.0", "eslint-plugin-import": "^2.13.0", "eslint-plugin-node": "^6.0.1", + "eslint-plugin-prettier": "^3.0.1", "eslint-plugin-promise": "^3.7.0", "eslint-plugin-standard": "^3.1.0", "eslint-plugin-vue": "^4.5.0", diff --git a/yarn.lock b/yarn.lock index 88da29c458..e62735129f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,17 +38,17 @@ source-map "^0.5.0" "@babel/core@^7.1.0", "@babel/core@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" - integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.4.tgz#84055750b05fcd50f9915a826b44fa347a825250" + integrity sha512-lQgGX3FPRgbz2SKmhMtYgJvVzGZrmjaF4apZ2bLwofAKiSjxU0drPh4S/VasyYXwaTs+A1gvQ45BN8SQJzHsQQ== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.3.4" - "@babel/helpers" "^7.2.0" - "@babel/parser" "^7.3.4" - "@babel/template" "^7.2.2" - "@babel/traverse" "^7.3.4" - "@babel/types" "^7.3.4" + "@babel/generator" "^7.4.4" + "@babel/helpers" "^7.4.4" + "@babel/parser" "^7.4.4" + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -68,12 +68,12 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.0.0", "@babel/generator@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.4.tgz#9aa48c1989257877a9d971296e5b73bfe72e446e" - integrity sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041" + integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ== dependencies: - "@babel/types" "^7.3.4" + "@babel/types" "^7.4.4" jsesc "^2.5.1" lodash "^4.17.11" source-map "^0.5.0" @@ -118,14 +118,14 @@ "@babel/traverse" "7.0.0-beta.47" "@babel/types" "7.0.0-beta.47" -"@babel/helper-call-delegate@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" - integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ== +"@babel/helper-call-delegate@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" + integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== dependencies: - "@babel/helper-hoist-variables" "^7.0.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-hoist-variables" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" "@babel/helper-define-map@7.0.0-beta.47": version "7.0.0-beta.47" @@ -136,14 +136,14 @@ "@babel/types" "7.0.0-beta.47" lodash "^4.17.5" -"@babel/helper-define-map@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" - integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg== +"@babel/helper-define-map@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a" + integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg== dependencies: "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.0.0" - lodash "^4.17.10" + "@babel/types" "^7.4.4" + lodash "^4.17.11" "@babel/helper-explode-assignable-expression@7.0.0-beta.47": version "7.0.0-beta.47" @@ -200,12 +200,12 @@ dependencies: "@babel/types" "7.0.0-beta.47" -"@babel/helper-hoist-variables@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" - integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w== +"@babel/helper-hoist-variables@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" + integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.4.4" "@babel/helper-member-expression-to-functions@7.0.0-beta.47": version "7.0.0-beta.47" @@ -248,17 +248,17 @@ "@babel/types" "7.0.0-beta.47" lodash "^4.17.5" -"@babel/helper-module-transforms@^7.1.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz#ab2f8e8d231409f8370c883d20c335190284b963" - integrity sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA== +"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8" + integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/template" "^7.2.2" - "@babel/types" "^7.2.2" - lodash "^4.17.10" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/template" "^7.4.4" + "@babel/types" "^7.4.4" + lodash "^4.17.11" "@babel/helper-optimise-call-expression@7.0.0-beta.47": version "7.0.0-beta.47" @@ -291,12 +291,12 @@ dependencies: lodash "^4.17.5" -"@babel/helper-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" - integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg== +"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" + integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== dependencies: - lodash "^4.17.10" + lodash "^4.17.11" "@babel/helper-remap-async-to-generator@7.0.0-beta.47": version "7.0.0-beta.47" @@ -330,15 +330,15 @@ "@babel/traverse" "7.0.0-beta.47" "@babel/types" "7.0.0-beta.47" -"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.3.4.tgz#a795208e9b911a6eeb08e5891faacf06e7013e13" - integrity sha512-pvObL9WVf2ADs+ePg0jrqlhHoxRXlOa+SHRHzAXIz2xkYuOHfGl+fKxPMaS4Fq+uje8JQPobnertBBvyrWnQ1A== +"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27" + integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg== dependencies: "@babel/helper-member-expression-to-functions" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.3.4" - "@babel/types" "^7.3.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" "@babel/helper-simple-access@7.0.0-beta.47": version "7.0.0-beta.47" @@ -364,12 +364,12 @@ dependencies: "@babel/types" "7.0.0-beta.47" -"@babel/helper-split-export-declaration@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" - integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== +"@babel/helper-split-export-declaration@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" + integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.4.4" "@babel/helper-wrap-function@7.0.0-beta.47": version "7.0.0-beta.47" @@ -400,14 +400,14 @@ "@babel/traverse" "7.0.0-beta.47" "@babel/types" "7.0.0-beta.47" -"@babel/helpers@^7.2.0": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9" - integrity sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA== +"@babel/helpers@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.4.tgz#868b0ef59c1dd4e78744562d5ce1b59c89f2f2a5" + integrity sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A== dependencies: - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.5" - "@babel/types" "^7.3.0" + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" "@babel/highlight@7.0.0-beta.47": version "7.0.0-beta.47" @@ -427,15 +427,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" - integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== - -"@babel/parser@^7.1.0": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.3.tgz#eb3ac80f64aa101c907d4ce5406360fe75b7895b" - integrity sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6" + integrity sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w== "@babel/plugin-proposal-async-generator-functions@7.0.0-beta.47": version "7.0.0-beta.47" @@ -514,10 +509,10 @@ "@babel/helper-plugin-utils" "7.0.0-beta.47" "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.47" -"@babel/plugin-proposal-object-rest-spread@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.4.tgz#47f73cf7f2a721aad5c0261205405c642e424654" - integrity sha512-j7VQmbbkA+qrzNqbKHrBsW3ddFnOeva6wzSe/zB7T+xaxGc+RCpwo44wCmRixAIGRoIpmVgvzFzNJqQcO3/9RA== +"@babel/plugin-proposal-object-rest-spread@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz#1ef173fcf24b3e2df92a678f027673b55e7e3005" + integrity sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -555,14 +550,14 @@ "@babel/helper-regex" "7.0.0-beta.47" regexpu-core "^4.1.4" -"@babel/plugin-proposal-unicode-property-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" - integrity sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw== +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" + integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - regexpu-core "^4.2.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" "@babel/plugin-syntax-async-generators@7.0.0-beta.47": version "7.0.0-beta.47" @@ -706,10 +701,10 @@ "@babel/helper-plugin-utils" "7.0.0-beta.47" "@babel/helper-remap-async-to-generator" "7.0.0-beta.47" -"@babel/plugin-transform-async-to-generator@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.3.4.tgz#4e45408d3c3da231c0e7b823f407a53a7eb3048c" - integrity sha512-Y7nCzv2fw/jEZ9f678MuKdMo99MFDJMT/PvD9LisrR5JDFcJH6vYeH6RnjVt3p5tceyGRvTtEN0VOlU+rgHZjA== +"@babel/plugin-transform-async-to-generator@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz#a3f1d01f2f21cadab20b33a82133116f14fb5894" + integrity sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -737,10 +732,10 @@ "@babel/helper-plugin-utils" "7.0.0-beta.47" lodash "^4.17.5" -"@babel/plugin-transform-block-scoping@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.3.4.tgz#5c22c339de234076eee96c8783b2fed61202c5c4" - integrity sha512-blRr2O8IOZLAOJklXLV4WhcEzpYafYQKSGT3+R26lWG41u/FODJuBggehtOwilVAcFu393v3OFj+HmaE6tVjhA== +"@babel/plugin-transform-block-scoping@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d" + integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.11" @@ -759,18 +754,18 @@ "@babel/helper-split-export-declaration" "7.0.0-beta.47" globals "^11.1.0" -"@babel/plugin-transform-classes@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.4.tgz#dc173cb999c6c5297e0b5f2277fdaaec3739d0cc" - integrity sha512-J9fAvCFBkXEvBimgYxCjvaVDzL6thk0j0dBvCeZmIUDBwyt+nv6HfbImsSrWsYXfDNDivyANgJlFXDUWRTZBuA== +"@babel/plugin-transform-classes@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6" + integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.1.0" + "@babel/helper-define-map" "^7.4.4" "@babel/helper-function-name" "^7.1.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.3.4" - "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-split-export-declaration" "^7.4.4" globals "^11.1.0" "@babel/plugin-transform-computed-properties@7.0.0-beta.47": @@ -794,10 +789,10 @@ dependencies: "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-destructuring@^7.2.0": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.3.2.tgz#f2f5520be055ba1c38c41c0e094d8a461dd78f2d" - integrity sha512-Lrj/u53Ufqxl/sGxyjsJ2XNtNuEjDyjpqdhMNh5aZ+XFOdThL46KBj27Uem4ggoezSYBxKWAil6Hu8HtwqesYw== +"@babel/plugin-transform-destructuring@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz#9d964717829cc9e4b601fc82a26a71a4d8faf20f" + integrity sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -810,14 +805,14 @@ "@babel/helper-regex" "7.0.0-beta.47" regexpu-core "^4.1.3" -"@babel/plugin-transform-dotall-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49" - integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ== +"@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" + integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - regexpu-core "^4.1.3" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" "@babel/plugin-transform-duplicate-keys@7.0.0-beta.47": version "7.0.0-beta.47" @@ -856,10 +851,10 @@ dependencies: "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-for-of@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" - integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ== +"@babel/plugin-transform-for-of@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" + integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -871,10 +866,10 @@ "@babel/helper-function-name" "7.0.0-beta.47" "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-function-name@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" - integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== +"@babel/plugin-transform-function-name@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" + integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -893,6 +888,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-member-expression-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" + integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-modules-amd@7.0.0-beta.47": version "7.0.0-beta.47" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-beta.47.tgz#84564419b11c1be6b9fcd4c7b3a6737f2335aac4" @@ -918,12 +920,12 @@ "@babel/helper-plugin-utils" "7.0.0-beta.47" "@babel/helper-simple-access" "7.0.0-beta.47" -"@babel/plugin-transform-modules-commonjs@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" - integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ== +"@babel/plugin-transform-modules-commonjs@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e" + integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw== dependencies: - "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-module-transforms" "^7.4.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" @@ -935,12 +937,12 @@ "@babel/helper-hoist-variables" "7.0.0-beta.47" "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-modules-systemjs@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.3.4.tgz#813b34cd9acb6ba70a84939f3680be0eb2e58861" - integrity sha512-VZ4+jlGOF36S7TjKs8g4ojp4MEI+ebCQZdswWb/T9I4X84j8OtFAyjXjt/M16iIm5RIZn0UMQgg/VgIwo/87vw== +"@babel/plugin-transform-modules-systemjs@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405" + integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ== dependencies: - "@babel/helper-hoist-variables" "^7.0.0" + "@babel/helper-hoist-variables" "^7.4.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-umd@7.0.0-beta.47": @@ -959,10 +961,10 @@ "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz#140b52985b2d6ef0cb092ef3b29502b990f9cd50" - integrity sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw== +"@babel/plugin-transform-named-capturing-groups-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz#5611d96d987dfc4a3a81c4383bb173361037d68d" + integrity sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA== dependencies: regexp-tree "^0.1.0" @@ -973,10 +975,10 @@ dependencies: "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-new-target@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" - integrity sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw== +"@babel/plugin-transform-new-target@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" + integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -1005,15 +1007,22 @@ "@babel/helper-get-function-arity" "7.0.0-beta.47" "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-parameters@^7.2.0": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.3.3.tgz#3a873e07114e1a5bee17d04815662c8317f10e30" - integrity sha512-IrIP25VvXWu/VlBWTpsjGptpomtIkYrN/3aDp4UKm7xK6UxZY88kcJ1UwETbzHAlwN21MnNfwlar0u8y3KpiXw== +"@babel/plugin-transform-parameters@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" + integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== dependencies: - "@babel/helper-call-delegate" "^7.1.0" + "@babel/helper-call-delegate" "^7.4.4" "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-property-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" + integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-regenerator@7.0.0-beta.47": version "7.0.0-beta.47" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.47.tgz#86500e1c404055fb98fc82b73b09bd053cacb516" @@ -1021,13 +1030,20 @@ dependencies: regenerator-transform "^0.12.3" -"@babel/plugin-transform-regenerator@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.3.4.tgz#1601655c362f5b38eead6a52631f5106b29fa46a" - integrity sha512-hvJg8EReQvXT6G9H2MvNPXkv9zK36Vxa1+csAVTpE1J3j0zlHplw76uudEbJxgvqZzAq9Yh45FLD4pk5mKRFQA== +"@babel/plugin-transform-regenerator@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.4.tgz#5b4da4df79391895fca9e28f99e87e22cfc02072" + integrity sha512-Zz3w+pX1SI0KMIiqshFZkwnVGUhDZzpX2vtPzfJBKQQq8WsP/Xy9DNdELWivxcKOCX/Pywge4SiEaPaLtoDT4g== dependencies: regenerator-transform "^0.13.4" +"@babel/plugin-transform-reserved-words@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" + integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-runtime@7.0.0-beta.47": version "7.0.0-beta.47" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.0.0-beta.47.tgz#1700938fa8710909cbf28f7dd39f9b40688b09fd" @@ -1088,10 +1104,10 @@ "@babel/helper-annotate-as-pure" "7.0.0-beta.47" "@babel/helper-plugin-utils" "7.0.0-beta.47" -"@babel/plugin-transform-template-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" - integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== +"@babel/plugin-transform-template-literals@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" + integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -1119,22 +1135,22 @@ "@babel/helper-regex" "7.0.0-beta.47" regexpu-core "^4.1.3" -"@babel/plugin-transform-unicode-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" - integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== +"@babel/plugin-transform-unicode-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" + integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - regexpu-core "^4.1.3" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" "@babel/polyfill@^7.2.5": - version "7.2.5" - resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.2.5.tgz#6c54b964f71ad27edddc567d065e57e87ed7fa7d" - integrity sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893" + integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg== dependencies: - core-js "^2.5.7" - regenerator-runtime "^0.12.0" + core-js "^2.6.5" + regenerator-runtime "^0.13.2" "@babel/preset-env@7.0.0-beta.47": version "7.0.0-beta.47" @@ -1182,53 +1198,58 @@ semver "^5.3.0" "@babel/preset-env@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.4.tgz#887cf38b6d23c82f19b5135298bdb160062e33e1" - integrity sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.4.tgz#b6f6825bfb27b3e1394ca3de4f926482722c1d6f" + integrity sha512-FU1H+ACWqZZqfw1x2G1tgtSSYSfxJLkpaUQL37CenULFARDo+h4xJoVHzRoHbK+85ViLciuI7ME4WTIhFRBBlw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-async-generator-functions" "^7.2.0" "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.3.4" + "@babel/plugin-proposal-object-rest-spread" "^7.4.4" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" "@babel/plugin-syntax-async-generators" "^7.2.0" "@babel/plugin-syntax-json-strings" "^7.2.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.3.4" + "@babel/plugin-transform-async-to-generator" "^7.4.4" "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.3.4" - "@babel/plugin-transform-classes" "^7.3.4" + "@babel/plugin-transform-block-scoping" "^7.4.4" + "@babel/plugin-transform-classes" "^7.4.4" "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.2.0" - "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" "@babel/plugin-transform-duplicate-keys" "^7.2.0" "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.2.0" - "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.4.4" + "@babel/plugin-transform-function-name" "^7.4.4" "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-member-expression-literals" "^7.2.0" "@babel/plugin-transform-modules-amd" "^7.2.0" - "@babel/plugin-transform-modules-commonjs" "^7.2.0" - "@babel/plugin-transform-modules-systemjs" "^7.3.4" + "@babel/plugin-transform-modules-commonjs" "^7.4.4" + "@babel/plugin-transform-modules-systemjs" "^7.4.4" "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" - "@babel/plugin-transform-new-target" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.4" + "@babel/plugin-transform-new-target" "^7.4.4" "@babel/plugin-transform-object-super" "^7.2.0" - "@babel/plugin-transform-parameters" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.3.4" + "@babel/plugin-transform-parameters" "^7.4.4" + "@babel/plugin-transform-property-literals" "^7.2.0" + "@babel/plugin-transform-regenerator" "^7.4.4" + "@babel/plugin-transform-reserved-words" "^7.2.0" "@babel/plugin-transform-shorthand-properties" "^7.2.0" "@babel/plugin-transform-spread" "^7.2.0" "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.4.4" "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.2.0" - browserslist "^4.3.4" + "@babel/plugin-transform-unicode-regex" "^7.4.4" + "@babel/types" "^7.4.4" + browserslist "^4.5.2" + core-js-compat "^3.0.0" invariant "^2.2.2" js-levenshtein "^1.1.3" - semver "^5.3.0" + semver "^5.5.0" "@babel/preset-stage-2@7.0.0-beta.47": version "7.0.0-beta.47" @@ -1275,14 +1296,14 @@ babylon "7.0.0-beta.47" lodash "^4.17.5" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" - integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" + integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.2.2" - "@babel/types" "^7.2.2" + "@babel/parser" "^7.4.4" + "@babel/types" "^7.4.4" "@babel/traverse@7.0.0-beta.47": version "7.0.0-beta.47" @@ -1300,17 +1321,17 @@ invariant "^2.2.0" lodash "^4.17.5" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.3.4.tgz#1330aab72234f8dea091b08c4f8b9d05c7119e06" - integrity sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.4.tgz#0776f038f6d78361860b6823887d4f3937133fe8" + integrity sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.3.4" + "@babel/generator" "^7.4.4" "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.3.4" - "@babel/types" "^7.3.4" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.4.4" + "@babel/types" "^7.4.4" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.11" @@ -1324,10 +1345,10 @@ lodash "^4.17.5" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" - integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" + integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ== dependencies: esutils "^2.0.2" lodash "^4.17.11" @@ -1351,10 +1372,10 @@ date-fns "^1.27.2" figures "^1.7.0" -"@cypress/xvfb@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.3.tgz#6319afdcdcff7d1505daeeaa84484d0596189860" - integrity sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw== +"@cypress/xvfb@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== dependencies: debug "^3.1.0" lodash.once "^4.1.1" @@ -1503,14 +1524,14 @@ "@types/istanbul-lib-coverage" "^2.0.0" "@types/yargs" "^12.0.9" -"@lerna/add@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.13.1.tgz#2cd7838857edb3b43ed73e3c21f69a20beb9b702" - integrity sha512-cXk42YbuhzEnADCK8Qte5laC9Qo03eJLVnr0qKY85jQUM/T4URe3IIUemqpg0CpVATrB+Vz+iNdeqw9ng1iALw== +"@lerna/add@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.13.3.tgz#f4c1674839780e458f0426d4f7b6d0a77b9a2ae9" + integrity sha512-T3/Lsbo9ZFq+vL3ssaHxA8oKikZAPTJTGFe4CRuQgWCDd/M61+51jeWsngdaHpwzSSRDRjxg8fJTG10y10pnfA== dependencies: - "@lerna/bootstrap" "3.13.1" - "@lerna/command" "3.13.1" - "@lerna/filter-options" "3.13.0" + "@lerna/bootstrap" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" "@lerna/npm-conf" "3.13.0" "@lerna/validation-error" "3.13.0" dedent "^0.7.0" @@ -1528,19 +1549,19 @@ "@lerna/validation-error" "3.13.0" npmlog "^4.1.2" -"@lerna/bootstrap@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.13.1.tgz#f2edd7c8093c8b139e78b0ca5f845f23efd01f08" - integrity sha512-mKdi5Ds5f82PZwEFyB9/W60I3iELobi1i87sTeVrbJh/um7GvqpSPy7kG/JPxyOdMpB2njX6LiJgw+7b6BEPWw== +"@lerna/bootstrap@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.13.3.tgz#a0e5e466de5c100b49d558d39139204fc4db5c95" + integrity sha512-2XzijnLHRZOVQh8pwS7+5GR3cG4uh+EiLrWOishCq2TVzkqgjaS3GGBoef7KMCXfWHoLqAZRr/jEdLqfETLVqg== dependencies: "@lerna/batch-packages" "3.13.0" - "@lerna/command" "3.13.1" - "@lerna/filter-options" "3.13.0" - "@lerna/has-npm-version" "3.13.0" - "@lerna/npm-install" "3.13.0" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/has-npm-version" "3.13.3" + "@lerna/npm-install" "3.13.3" "@lerna/package-graph" "3.13.0" "@lerna/pulse-till-done" "3.13.0" - "@lerna/rimraf-dir" "3.13.0" + "@lerna/rimraf-dir" "3.13.3" "@lerna/run-lifecycle" "3.13.0" "@lerna/run-parallel-batches" "3.13.0" "@lerna/symlink-binary" "3.13.0" @@ -1558,44 +1579,44 @@ read-package-tree "^5.1.6" semver "^5.5.0" -"@lerna/changed@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.13.1.tgz#dc92476aad43c932fe741969bbd0bcf6146a4c52" - integrity sha512-BRXitEJGOkoudbxEewW7WhjkLxFD+tTk4PrYpHLyCBk63pNTWtQLRE6dc1hqwh4emwyGncoyW6RgXfLgMZgryw== +"@lerna/changed@3.13.4": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.13.4.tgz#c69d8a079999e49611dd58987f08437baee81ad4" + integrity sha512-9lfOyRVObasw6L/z7yCSfsEl1QKy0Eamb8t2Krg1deIoAt+cE3JXOdGGC1MhOSli+7f/U9LyLXjJzIOs/pc9fw== dependencies: - "@lerna/collect-updates" "3.13.0" - "@lerna/command" "3.13.1" + "@lerna/collect-updates" "3.13.3" + "@lerna/command" "3.13.3" "@lerna/listable" "3.13.0" "@lerna/output" "3.13.0" - "@lerna/version" "3.13.1" + "@lerna/version" "3.13.4" -"@lerna/check-working-tree@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.13.0.tgz#1ddcd4d9b1aceb65efaaa4cd1333a66706d67c9c" - integrity sha512-dsdO15NXX5To+Q53SYeCrBEpiqv4m5VkaPZxbGQZNwoRen1MloXuqxSymJANQn+ZLEqarv5V56gydebeROPH5A== +"@lerna/check-working-tree@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.13.3.tgz#836a3ffd4413a29aca92ccca4a115e4f97109992" + integrity sha512-LoGZvTkne+V1WpVdCTU0XNzFKsQa2AiAFKksGRT0v8NQj6VAPp0jfVYDayTqwaWt2Ne0OGKOFE79Y5LStOuhaQ== dependencies: - "@lerna/describe-ref" "3.13.0" + "@lerna/describe-ref" "3.13.3" "@lerna/validation-error" "3.13.0" -"@lerna/child-process@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.13.0.tgz#84e35adf3217a6983edd28080657b9596a052674" - integrity sha512-0iDS8y2jiEucD4fJHEzKoc8aQJgm7s+hG+0RmDNtfT0MM3n17pZnf5JOMtS1FJp+SEXOjMKQndyyaDIPFsnp6A== +"@lerna/child-process@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.13.3.tgz#6c084ee5cca9fc9e04d6bf4fc3f743ed26ff190c" + integrity sha512-3/e2uCLnbU+bydDnDwyadpOmuzazS01EcnOleAnuj9235CU2U97DH6OyoG1EW/fU59x11J+HjIqovh5vBaMQjQ== dependencies: chalk "^2.3.1" execa "^1.0.0" strong-log-transformer "^2.0.0" -"@lerna/clean@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.13.1.tgz#9a7432efceccd720a51da5c76f849fc59c5a14ce" - integrity sha512-myGIaXv7RUO2qCFZXvx8SJeI+eN6y9SUD5zZ4/LvNogbOiEIlujC5lUAqK65rAHayQ9ltSa/yK6Xv510xhZXZQ== +"@lerna/clean@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.13.3.tgz#5673a1238e0712d31711e7e4e8cb9641891daaea" + integrity sha512-xmNauF1PpmDaKdtA2yuRc23Tru4q7UMO6yB1a/TTwxYPYYsAWG/CBK65bV26J7x4RlZtEv06ztYGMa9zh34UXA== dependencies: - "@lerna/command" "3.13.1" - "@lerna/filter-options" "3.13.0" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" "@lerna/prompt" "3.13.0" "@lerna/pulse-till-done" "3.13.0" - "@lerna/rimraf-dir" "3.13.0" + "@lerna/rimraf-dir" "3.13.3" p-map "^1.2.0" p-map-series "^1.0.0" p-waterfall "^1.0.0" @@ -1610,23 +1631,23 @@ npmlog "^4.1.2" yargs "^12.0.1" -"@lerna/collect-updates@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.13.0.tgz#f0828d84ff959ff153d006765659ffc4d68cdefc" - integrity sha512-uR3u6uTzrS1p46tHQ/mlHog/nRJGBqskTHYYJbgirujxm6FqNh7Do+I1Q/7zSee407G4lzsNxZdm8IL927HemQ== +"@lerna/collect-updates@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.13.3.tgz#616648da59f0aff4a8e60257795cc46ca6921edd" + integrity sha512-sTpALOAxli/ZS+Mjq6fbmjU9YXqFJ2E4FrE1Ijl4wPC5stXEosg2u0Z1uPY+zVKdM+mOIhLxPVdx83rUgRS+Cg== dependencies: - "@lerna/child-process" "3.13.0" - "@lerna/describe-ref" "3.13.0" + "@lerna/child-process" "3.13.3" + "@lerna/describe-ref" "3.13.3" minimatch "^3.0.4" npmlog "^4.1.2" slash "^1.0.0" -"@lerna/command@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.13.1.tgz#b60dda2c0d9ffbb6030d61ddf7cceedc1e8f7e6e" - integrity sha512-SYWezxX+iheWvzRoHCrbs8v5zHPaxAx3kWvZhqi70vuGsdOVAWmaG4IvHLn11ztS+Vpd5PM+ztBWSbnykpLFKQ== +"@lerna/command@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.13.3.tgz#5b20b3f507224573551039e0460bc36c39f7e9d1" + integrity sha512-WHFIQCubJV0T8gSLRNr6exZUxTswrh+iAtJCb86SE0Sa+auMPklE8af7w2Yck5GJfewmxSjke3yrjNxQrstx7w== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" "@lerna/package-graph" "3.13.0" "@lerna/project" "3.13.1" "@lerna/validation-error" "3.13.0" @@ -1662,13 +1683,13 @@ fs-extra "^7.0.0" npmlog "^4.1.2" -"@lerna/create@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.13.1.tgz#2c1284cfdc59f0d2b88286d78bc797f4ab330f79" - integrity sha512-pLENMXgTkQuvKxAopjKeoLOv9fVUCnpTUD7aLrY5d95/1xqSZlnsOcQfUYcpMf3GpOvHc8ILmI5OXkPqjAf54g== +"@lerna/create@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.13.3.tgz#6ded142c54b7f3cea86413c3637b067027b7f55d" + integrity sha512-4M5xT1AyUMwt1gCDph4BfW3e6fZmt0KjTa3FoXkUotf/w/eqTsc2IQ+ULz2+gOFQmtuNbqIZEOK3J4P9ArJJ/A== dependencies: - "@lerna/child-process" "3.13.0" - "@lerna/command" "3.13.1" + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" "@lerna/npm-conf" "3.13.0" "@lerna/validation-error" "3.13.0" camelcase "^5.0.0" @@ -1686,42 +1707,42 @@ validate-npm-package-name "^3.0.0" whatwg-url "^7.0.0" -"@lerna/describe-ref@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.13.0.tgz#fb4c3863fd6bcccad67ce7b183887a5fc1942bb6" - integrity sha512-UJefF5mLxLae9I2Sbz5RLYGbqbikRuMqdgTam0MS5OhXnyuuKYBUpwBshCURNb1dPBXTQhSwc7+oUhORx8ojCg== +"@lerna/describe-ref@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.13.3.tgz#13318513613f6a407d37fc5dc025ec2cfb705606" + integrity sha512-5KcLTvjdS4gU5evW8ESbZ0BF44NM5HrP3dQNtWnOUSKJRgsES8Gj0lq9AlB2+YglZfjEftFT03uOYOxnKto4Uw== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" npmlog "^4.1.2" -"@lerna/diff@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.13.1.tgz#5c734321b0f6c46a3c87f55c99afef3b01d46520" - integrity sha512-cKqmpONO57mdvxtp8e+l5+tjtmF04+7E+O0QEcLcNUAjC6UR2OSM77nwRCXDukou/1h72JtWs0jjcdYLwAmApg== +"@lerna/diff@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.13.3.tgz#883cb3a83a956dbfc2c17bc9a156468a5d3fae17" + integrity sha512-/DRS2keYbnKaAC+5AkDyZRGkP/kT7v1GlUS0JGZeiRDPQ1H6PzhX09EgE5X6nj0Ytrm0sUasDeN++CDVvgaI+A== dependencies: - "@lerna/child-process" "3.13.0" - "@lerna/command" "3.13.1" + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" "@lerna/validation-error" "3.13.0" npmlog "^4.1.2" -"@lerna/exec@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.13.1.tgz#4439e90fb0877ec38a6ef933c86580d43eeaf81b" - integrity sha512-I34wEP9lrAqqM7tTXLDxv/6454WFzrnXDWpNDbiKQiZs6SIrOOjmm6I4FiQsx+rU3o9d+HkC6tcUJRN5mlJUgA== +"@lerna/exec@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.13.3.tgz#5d2eda3f6e584f2f15b115e8a4b5bc960ba5de85" + integrity sha512-c0bD4XqM96CTPV8+lvkxzE7mkxiFyv/WNM4H01YvvbFAJzk+S4Y7cBtRkIYFTfkFZW3FLo8pEgtG1ONtIdM+tg== dependencies: "@lerna/batch-packages" "3.13.0" - "@lerna/child-process" "3.13.0" - "@lerna/command" "3.13.1" - "@lerna/filter-options" "3.13.0" + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" "@lerna/run-parallel-batches" "3.13.0" "@lerna/validation-error" "3.13.0" -"@lerna/filter-options@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.13.0.tgz#976e3d8b9fcd47001ab981d276565c1e9f767868" - integrity sha512-SRp7DCo9zrf+7NkQxZMkeyO1GRN6GICoB9UcBAbXhLbWisT37Cx5/6+jh49gYB63d/0/WYHSEPMlheUrpv1Srw== +"@lerna/filter-options@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.13.3.tgz#aa42a4ab78837b8a6c4278ba871d27e92d77c54f" + integrity sha512-DbtQX4eRgrBz1wCFWRP99JBD7ODykYme9ykEK79+RrKph40znhJQRlLg4idogj6IsUEzwo1OHjihCzSfnVo6Cg== dependencies: - "@lerna/collect-updates" "3.13.0" + "@lerna/collect-updates" "3.13.3" "@lerna/filter-packages" "3.13.0" dedent "^0.7.0" @@ -1750,12 +1771,12 @@ ssri "^6.0.1" tar "^4.4.8" -"@lerna/github-client@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-3.13.1.tgz#cb9bf9f01685a0cee0fac63f287f6c3673e45aa3" - integrity sha512-iPLUp8FFoAKGURksYEYZzfuo9TRA+NepVlseRXFaWlmy36dCQN20AciINpoXiXGoHcEUHXUKHQvY3ARFdMlf3w== +"@lerna/github-client@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-3.13.3.tgz#bcf9b4ff40bdd104cb40cd257322f052b41bb9ce" + integrity sha512-fcJkjab4kX0zcLLSa/DCUNvU3v8wmy2c1lhdIbL7s7gABmDcV0QZq93LhnEee3VkC9UpnJ6GKG4EkD7eIifBnA== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" "@octokit/plugin-enterprise-rest" "^2.1.1" "@octokit/rest" "^16.16.0" git-url-parse "^11.1.2" @@ -1766,21 +1787,21 @@ resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.13.0.tgz#217662290db06ad9cf2c49d8e3100ee28eaebae1" integrity sha512-SlZvh1gVRRzYLVluz9fryY1nJpZ0FHDGB66U9tFfvnnxmueckRQxLopn3tXj3NU1kc3QANT2I5BsQkOqZ4TEFQ== -"@lerna/has-npm-version@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.13.0.tgz#6e1f7e9336cce3e029066f0175f06dd9d51ad09f" - integrity sha512-Oqu7DGLnrMENPm+bPFGOHnqxK8lCnuYr6bk3g/CoNn8/U0qgFvHcq6Iv8/Z04TsvleX+3/RgauSD2kMfRmbypg== +"@lerna/has-npm-version@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.13.3.tgz#167e3f602a2fb58f84f93cf5df39705ca6432a2d" + integrity sha512-mQzoghRw4dBg0R9FFfHrj0TH0glvXyzdEZmYZ8Isvx5BSuEEwpsryoywuZSdppcvLu8o7NAdU5Tac8cJ/mT52w== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" semver "^5.5.0" -"@lerna/import@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.13.1.tgz#69d641341a38b79bd379129da1c717d51dd728c7" - integrity sha512-A1Vk1siYx1XkRl6w+zkaA0iptV5TIynVlHPR9S7NY0XAfhykjztYVvwtxarlh6+VcNrO9We6if0+FXCrfDEoIg== +"@lerna/import@3.13.4": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.13.4.tgz#e9a1831b8fed33f3cbeab3b84c722c9371a2eaf7" + integrity sha512-dn6eNuPEljWsifBEzJ9B6NoaLwl/Zvof7PBUPA4hRyRlqG5sXRn6F9DnusMTovvSarbicmTURbOokYuotVWQQA== dependencies: - "@lerna/child-process" "3.13.0" - "@lerna/command" "3.13.1" + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" "@lerna/prompt" "3.13.0" "@lerna/pulse-till-done" "3.13.0" "@lerna/validation-error" "3.13.0" @@ -1788,35 +1809,35 @@ fs-extra "^7.0.0" p-map-series "^1.0.0" -"@lerna/init@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.13.1.tgz#0392c822abb3d63a75be4916c5e761cfa7b34dda" - integrity sha512-M59WACqim8WkH5FQEGOCEZ89NDxCKBfFTx4ZD5ig3LkGyJ8RdcJq5KEfpW/aESuRE9JrZLzVr0IjKbZSxzwEMA== +"@lerna/init@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.13.3.tgz#ebd522fee9b9d7d3b2dacb0261eaddb4826851ff" + integrity sha512-bK/mp0sF6jT0N+c+xrbMCqN4xRoiZCXQzlYsyACxPK99KH/mpHv7hViZlTYUGlYcymtew6ZC770miv5A9wF9hA== dependencies: - "@lerna/child-process" "3.13.0" - "@lerna/command" "3.13.1" + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" fs-extra "^7.0.0" p-map "^1.2.0" write-json-file "^2.3.0" -"@lerna/link@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.13.1.tgz#7d8ed4774bfa198d1780f790a14abb8722a3aad1" - integrity sha512-N3h3Fj1dcea+1RaAoAdy4g2m3fvU7m89HoUn5X/Zcw5n2kPoK8kTO+NfhNAatfRV8VtMXst8vbNrWQQtfm0FFw== +"@lerna/link@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.13.3.tgz#11124d4a0c8d0b79752fbda3babedfd62dd57847" + integrity sha512-IHhtdhA0KlIdevCsq6WHkI2rF3lHWHziJs2mlrEWAKniVrFczbELON1KJAgdJS1k3kAP/WeWVqmIYZ2hJDxMvg== dependencies: - "@lerna/command" "3.13.1" + "@lerna/command" "3.13.3" "@lerna/package-graph" "3.13.0" "@lerna/symlink-dependencies" "3.13.0" p-map "^1.2.0" slash "^1.0.0" -"@lerna/list@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.13.1.tgz#f9513ed143e52156c10ada4070f903c5847dcd10" - integrity sha512-635iRbdgd9gNvYLLIbYdQCQLr+HioM5FGJLFS0g3DPGygr6iDR8KS47hzCRGH91LU9NcM1mD1RoT/AChF+QbiA== +"@lerna/list@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.13.3.tgz#fa93864d43cadeb4cd540a4e78a52886c57dbe74" + integrity sha512-rLRDsBCkydMq2FL6WY1J/elvnXIjxxRtb72lfKHdvDEqVdquT5Qgt9ci42hwjmcocFwWcFJgF6BZozj5pbc13A== dependencies: - "@lerna/command" "3.13.1" - "@lerna/filter-options" "3.13.0" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" "@lerna/listable" "3.13.0" "@lerna/output" "3.13.0" @@ -1857,12 +1878,12 @@ npm-registry-fetch "^3.9.0" npmlog "^4.1.2" -"@lerna/npm-install@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.13.0.tgz#88f4cc39f4f737c8a8721256b915ea1bcc6a7227" - integrity sha512-qNyfts//isYQxore6fsPorNYJmPVKZ6tOThSH97tP0aV91zGMtrYRqlAoUnDwDdAjHPYEM16hNujg2wRmsqqIw== +"@lerna/npm-install@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.13.3.tgz#9b09852732e51c16d2e060ff2fd8bfbbb49cf7ba" + integrity sha512-7Jig9MLpwAfcsdQ5UeanAjndChUjiTjTp50zJ+UZz4CbIBIDhoBehvNMTCL2G6pOEC7sGEg6sAqJINAqred6Tg== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" "@lerna/get-npm-exec-opts" "3.13.0" fs-extra "^7.0.0" npm-package-arg "^6.1.0" @@ -1870,25 +1891,26 @@ signal-exit "^3.0.2" write-pkg "^3.1.0" -"@lerna/npm-publish@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.13.0.tgz#5c74808376e778865ffdc5885fe83935e15e60c3" - integrity sha512-y4WO0XTaf9gNRkI7as6P2ItVDOxmYHwYto357fjybcnfXgMqEA94c3GJ++jU41j0A9vnmYC6/XxpTd9sVmH9tA== +"@lerna/npm-publish@3.13.2": + version "3.13.2" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.13.2.tgz#ad713ca6f91a852687d7d0e1bda7f9c66df21768" + integrity sha512-HMucPyEYZfom5tRJL4GsKBRi47yvSS2ynMXYxL3kO0ie+j9J7cb0Ir8NmaAMEd3uJWJVFCPuQarehyfTDZsSxg== dependencies: "@lerna/run-lifecycle" "3.13.0" figgy-pudding "^3.5.1" fs-extra "^7.0.0" libnpmpublish "^1.1.1" + npm-package-arg "^6.1.0" npmlog "^4.1.2" pify "^3.0.0" read-package-json "^2.0.13" -"@lerna/npm-run-script@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.13.0.tgz#e5997f045402b9948bdc066033ebb36bf94fc9e4" - integrity sha512-hiL3/VeVp+NFatBjkGN8mUdX24EfZx9rQlSie0CMgtjc7iZrtd0jCguLomSCRHYjJuvqgbp+LLYo7nHVykfkaQ== +"@lerna/npm-run-script@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.13.3.tgz#9bb6389ed70cd506905d6b05b6eab336b4266caf" + integrity sha512-qR4o9BFt5hI8Od5/DqLalOJydnKpiQFEeN0h9xZi7MwzuX1Ukwh3X22vqsX4YRbipIelSFtrDzleNVUm5jj0ow== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" "@lerna/get-npm-exec-opts" "3.13.0" npmlog "^4.1.2" @@ -1957,21 +1979,21 @@ inquirer "^6.2.0" npmlog "^4.1.2" -"@lerna/publish@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.13.1.tgz#217e401dcb5824cdd6d36555a36303fb7520c514" - integrity sha512-KhCJ9UDx76HWCF03i5TD7z5lX+2yklHh5SyO8eDaLptgdLDQ0Z78lfGj3JhewHU2l46FztmqxL/ss0IkWHDL+g== +"@lerna/publish@3.13.4": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.13.4.tgz#25b678c285110897a7fc5198a35bdfa9db7f9cc1" + integrity sha512-v03pabiPlqCDwX6cVNis1PDdT6/jBgkVb5Nl4e8wcJXevIhZw3ClvtI94gSZu/wdoVFX0RMfc8QBVmaimSO0qg== dependencies: "@lerna/batch-packages" "3.13.0" - "@lerna/check-working-tree" "3.13.0" - "@lerna/child-process" "3.13.0" - "@lerna/collect-updates" "3.13.0" - "@lerna/command" "3.13.1" - "@lerna/describe-ref" "3.13.0" + "@lerna/check-working-tree" "3.13.3" + "@lerna/child-process" "3.13.3" + "@lerna/collect-updates" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/describe-ref" "3.13.3" "@lerna/log-packed" "3.13.0" "@lerna/npm-conf" "3.13.0" "@lerna/npm-dist-tag" "3.13.0" - "@lerna/npm-publish" "3.13.0" + "@lerna/npm-publish" "3.13.2" "@lerna/output" "3.13.0" "@lerna/pack-directory" "3.13.1" "@lerna/prompt" "3.13.0" @@ -1979,7 +2001,7 @@ "@lerna/run-lifecycle" "3.13.0" "@lerna/run-parallel-batches" "3.13.0" "@lerna/validation-error" "3.13.0" - "@lerna/version" "3.13.1" + "@lerna/version" "3.13.4" figgy-pudding "^3.5.1" fs-extra "^7.0.0" libnpmaccess "^3.0.1" @@ -2009,12 +2031,12 @@ npmlog "^4.1.2" read-cmd-shim "^1.0.1" -"@lerna/rimraf-dir@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.13.0.tgz#bb1006104b4aabcb6985624273254648f872b278" - integrity sha512-kte+pMemulre8cmPqljxIYjCmdLByz8DgHBHXB49kz2EiPf8JJ+hJFt0PzEubEyJZ2YE2EVAx5Tv5+NfGNUQyQ== +"@lerna/rimraf-dir@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.13.3.tgz#3a8e71317fde853893ef0262bc9bba6a180b7227" + integrity sha512-d0T1Hxwu3gpYVv73ytSL+/Oy8JitsmvOYUR5ouRSABsmqS7ZZCh5t6FgVDDGVXeuhbw82+vuny1Og6Q0k4ilqw== dependencies: - "@lerna/child-process" "3.13.0" + "@lerna/child-process" "3.13.3" npmlog "^4.1.2" path-exists "^3.0.0" rimraf "^2.6.2" @@ -2037,15 +2059,15 @@ p-map "^1.2.0" p-map-series "^1.0.0" -"@lerna/run@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.13.1.tgz#87e174c1d271894ddd29adc315c068fb7b1b0117" - integrity sha512-nv1oj7bsqppWm1M4ifN+/IIbVu9F4RixrbQD2okqDGYne4RQPAXyb5cEZuAzY/wyGTWWiVaZ1zpj5ogPWvH0bw== +"@lerna/run@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.13.3.tgz#0781c82d225ef6e85e28d3e763f7fc090a376a21" + integrity sha512-ygnLIfIYS6YY1JHWOM4CsdZiY8kTYPsDFOLAwASlRnlAXF9HiMT08GFXLmMHIblZJ8yJhsM2+QgraCB0WdxzOQ== dependencies: "@lerna/batch-packages" "3.13.0" - "@lerna/command" "3.13.1" - "@lerna/filter-options" "3.13.0" - "@lerna/npm-run-script" "3.13.0" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/npm-run-script" "3.13.3" "@lerna/output" "3.13.0" "@lerna/run-parallel-batches" "3.13.0" "@lerna/timer" "3.13.0" @@ -2087,18 +2109,18 @@ dependencies: npmlog "^4.1.2" -"@lerna/version@3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.13.1.tgz#5e919d13abb13a663dcc7922bb40931f12fb137b" - integrity sha512-WpfKc5jZBBOJ6bFS4atPJEbHSiywQ/Gcd+vrwaEGyQHWHQZnPTvhqLuq3q9fIb9sbuhH5pSY6eehhuBrKqTnjg== +"@lerna/version@3.13.4": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.13.4.tgz#ea23b264bebda425ccbfcdcd1de13ef45a390e59" + integrity sha512-pptWUEgN/lUTQZu34+gfH1g4Uhs7TDKRcdZY9A4T9k6RTOwpKC2ceLGiXdeR+ZgQJAey2C4qiE8fo5Z6Rbc6QA== dependencies: "@lerna/batch-packages" "3.13.0" - "@lerna/check-working-tree" "3.13.0" - "@lerna/child-process" "3.13.0" - "@lerna/collect-updates" "3.13.0" - "@lerna/command" "3.13.1" + "@lerna/check-working-tree" "3.13.3" + "@lerna/child-process" "3.13.3" + "@lerna/collect-updates" "3.13.3" + "@lerna/command" "3.13.3" "@lerna/conventional-commits" "3.13.0" - "@lerna/github-client" "3.13.1" + "@lerna/github-client" "3.13.3" "@lerna/output" "3.13.0" "@lerna/prompt" "3.13.0" "@lerna/run-lifecycle" "3.13.0" @@ -2136,45 +2158,48 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@octokit/endpoint@^3.1.1": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-3.1.3.tgz#f6e9c2521b83b74367600e474b24efec2b0471c4" - integrity sha512-vAWzeoj9Lzpl3V3YkWKhGzmDUoMfKpyxJhpq74/ohMvmLXDoEuAGnApy/7TRi3OmnjyX2Lr+e9UGGAD0919ohA== +"@octokit/endpoint@^4.0.0": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-4.2.2.tgz#4ff11382bad89c7e01030a1e62d5e9d13c2402b0" + integrity sha512-5IZjkUNhx5q0IRN7Juwf5A+Lu2qAso7ULST7C1P2mbGHePuCOk936Stcl/5GdJpB3ovD8M6/Lv3xra6Mn0IKNQ== dependencies: deepmerge "3.2.0" - is-plain-object "^2.0.4" + is-plain-object "^3.0.0" universal-user-agent "^2.0.1" url-template "^2.0.8" "@octokit/plugin-enterprise-rest@^2.1.1": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.1.2.tgz#259bd5ac00825a8a482ff6584ae9aed60acd0b41" - integrity sha512-EWKrEqhSgzqWXI9DuEsEI691PNJppm/a4zW62//te27I8pYI5zSNVR3wtNUk0NWPlvs7054YzGZochwbUbhI8A== + version "2.2.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.2.2.tgz#c0e22067a043e19f96ff9c7832e2a3019f9be75c" + integrity sha512-CTZr64jZYhGWNTDGlSJ2mvIlFsm9OEO3LqWn9I/gmoHI4jRBp4kpHoFYNemG4oA75zUAcmbuWblb7jjP877YZw== -"@octokit/request@2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-2.4.1.tgz#98c4d6870e4abe3ccdd2b9799034b4ae3f441c30" - integrity sha512-nN8W24ZXEpJQJoVgMsGZeK9FOzxkc39Xn9ykseUpPpPMNEDFSvqfkCeqqKrjUiXRm72ubGLWG1SOz0aJPcgGww== +"@octokit/request@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-3.0.1.tgz#21e888c6dce80566ec69477360bab79f2f14861f" + integrity sha512-aH61OVkMKMofGW/go2x4mJ44X4U/JF8xsiFFictwkZYtz0psE8OPKpsP2TZBZaJoCg2wmeTyEgqGfY+veg0hGQ== dependencies: - "@octokit/endpoint" "^3.1.1" + "@octokit/endpoint" "^4.0.0" deprecation "^1.0.1" - is-plain-object "^2.0.4" + is-plain-object "^3.0.0" node-fetch "^2.3.0" once "^1.4.0" universal-user-agent "^2.0.1" "@octokit/rest@^16.16.0": - version "16.16.5" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.16.5.tgz#2427fe2d8ef7887731ac6fcf86f90136f1007a7a" - integrity sha512-R7SD1DUUJVwNuiJWYiIYOm20Q/MFObN48o4BLnfhkzn4ArENWe4Vl5YOvVRZIC0vHGoYCgRtKhzBA6/WOjE/ig== + version "16.25.1" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.25.1.tgz#60a3171018dbc4feb23d1bf9805a06aad106d53e" + integrity sha512-a1Byzjj07OMQNUQDP5Ng/rChaI7aq6TNMY1ZFf8+zCVEEtYzCgcmrFG9BDerFbLPPKGQ5TAeRRFyLujUUN1HIg== dependencies: - "@octokit/request" "2.4.1" + "@octokit/request" "3.0.1" + atob-lite "^2.0.0" before-after-hook "^1.4.0" btoa-lite "^1.0.0" + deprecation "^1.0.1" lodash.get "^4.4.2" lodash.set "^4.3.2" lodash.uniq "^4.5.0" octokit-pagination-methods "^1.1.0" + once "^1.4.0" universal-user-agent "^2.0.0" url-template "^2.0.8" @@ -2197,14 +2222,9 @@ debug "^2.6.8" "@types/anymatch@*": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.0.tgz#d1d55958d1fccc5527d4aba29fc9c4b942f563ff" - integrity sha512-7WcbyctkE8GTzogDb0ulRAEw7v8oIS54ft9mQTU7PfM0hp5e+8kpa+HeQ7IQrFbKtJXBKcZ4bh+Em9dTw5L6AQ== - -"@types/async@2.0.50": - version "2.0.50" - resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" - integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== "@types/babel__core@^7.1.0": version "7.1.1" @@ -2239,16 +2259,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/blob-util@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/blob-util/-/blob-util-1.3.3.tgz#adba644ae34f88e1dd9a5864c66ad651caaf628a" - integrity sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w== - -"@types/bluebird@3.5.18": - version "3.5.18" - resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.18.tgz#6a60435d4663e290f3709898a4f75014f279c4d6" - integrity sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w== - "@types/body-parser@*": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -2257,24 +2267,6 @@ "@types/connect" "*" "@types/node" "*" -"@types/chai-jquery@1.1.35": - version "1.1.35" - resolved "https://registry.yarnpkg.com/@types/chai-jquery/-/chai-jquery-1.1.35.tgz#9a8f0a39ec0851b2768a8f8c764158c2a2568d04" - integrity sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ== - dependencies: - "@types/chai" "*" - "@types/jquery" "*" - -"@types/chai@*": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" - integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== - -"@types/chai@4.0.8": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.8.tgz#d27600e9ba2f371e08695d90a0fe0408d89c7be7" - integrity sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg== - "@types/connect@*": version "3.4.32" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" @@ -2282,24 +2274,18 @@ dependencies: "@types/node" "*" -"@types/events@*": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" - integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== - "@types/express-serve-static-core@*": - version "4.16.0" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" - integrity sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w== + version "4.16.4" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.4.tgz#56bb8be4559401d68af4a3624ae9dd3166103e60" + integrity sha512-x/8h6FHm14rPWnW2HP5likD/rsqJ3t/77OWx2PLxym0hXbeBWQmcPyHmwX+CtCQpjIfgrUdEoDFcLPwPZWiqzQ== dependencies: - "@types/events" "*" "@types/node" "*" "@types/range-parser" "*" "@types/express@*": - version "4.16.0" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" - integrity sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w== + version "4.16.1" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.1.tgz#d756bd1a85c34d87eaf44c888bad27ba8a4b7cf0" + integrity sha512-V0clmJow23WeyblmACoxbHBu2JKlE5TiIme6Lem14FnPW9gsttyHtk6wq7njcdIWH1njAaFgR8gW09lgY98gQg== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "*" @@ -2315,17 +2301,16 @@ "@types/node" "*" "@types/http-proxy@*": - version "1.16.2" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.16.2.tgz#16cb373b52fff2aa2f389d23d940ed4a642349e5" - integrity sha512-GgqePmC3rlsn1nv+kx5OviPuUBU2omhnlXOaJSXFgOdsTcScNFap+OaCb2ip9Bm4m5L8EOehgT5d9M4uNB90zg== + version "1.17.0" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.0.tgz#baf82ff6aa2723fd29f90e3ba1384e665006863e" + integrity sha512-l+s0IoxSHqhLFJPDHRfO235kgrCkvFD8JmdV/T9C4BKBYPIjrQopGFH4r7h2e3jQqgJRCthRCAZIxDoFnj1zwQ== dependencies: - "@types/events" "*" "@types/node" "*" "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" - integrity sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== "@types/jest-diff@*": version "20.0.1" @@ -2333,64 +2318,32 @@ integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA== "@types/jest@^24.0.11": - version "24.0.11" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.11.tgz#1f099bea332c228ea6505a88159bfa86a5858340" - integrity sha512-2kLuPC5FDnWIDvaJBzsGTBQaBbnDweznicvK7UGYzlIJP4RJR2a4A/ByLUXEyEgag6jz8eHdlWExGDtH3EYUXQ== + version "24.0.12" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.12.tgz#0553dd0a5ac744e7dc4e8700da6d3baedbde3e8f" + integrity sha512-60sjqMhat7i7XntZckcSGV8iREJyXXI6yFHZkSZvCPUeOnEJ/VP1rU/WpEWQ56mvoh8NhC+sfKAuJRTyGtCOow== dependencies: "@types/jest-diff" "*" -"@types/jquery@*": - version "3.3.22" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.22.tgz#cde55dc8f83207dffd16205b05f97ce824581735" - integrity sha512-a4JDcIhJhHYnoWCkG3xT2CZxXZeA92JeREESorg0DMQ3ZsjuKF48h7XK4l5Gl2GRa/ItGRpKMT0pyK88yRgqXQ== - dependencies: - "@types/sizzle" "*" - -"@types/jquery@3.3.6": - version "3.3.6" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.6.tgz#5932ead926307ca21e5b36808257f7c926b06565" - integrity sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg== - -"@types/lodash@4.14.87": - version "4.14.87" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.87.tgz#55f92183b048c2c64402afe472f8333f4e319a6b" - integrity sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw== - "@types/mime@*": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" - integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== - -"@types/minimatch@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/mocha@2.2.44": - version "2.2.44" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e" - integrity sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== -"@types/node@*", "@types/node@^10.12.18": - version "10.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== +"@types/node@*": + version "11.13.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.8.tgz#e5d71173c95533be9842b2c798978f095f912aab" + integrity sha512-szA3x/3miL90ZJxUCzx9haNbK5/zmPieGraZEe4WI+3srN0eGLiT22NXeMHmyhNEopn+IrxqMc7wdVwvPl8meg== -"@types/node@^10.11.7": - version "10.12.29" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.29.tgz#c2c8d2d27bb55649fbafe8ea1731658421f38acf" - integrity sha512-J/tnbnj8HcsBgCe2apZbdUpQ7hs4d7oZNTYA5bekWdP0sr2NGsOpI/HRdDroEi209tEvTcTtxhD0FfED3DhEcw== +"@types/node@^10.12.18": + version "10.14.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.6.tgz#9cbfcb62c50947217f4d88d4d274cc40c22625a9" + integrity sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg== "@types/range-parser@*": version "1.2.3" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== -"@types/semver@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" - integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== - "@types/serve-static@*": version "1.13.2" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" @@ -2399,29 +2352,6 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/sinon-chai@3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.2.tgz#5cfdbda70bae30f79a9423334af9e490e4cce793" - integrity sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-5.0.7.tgz#0d9f89dd0c9988c4f1505a92a3a324ee7bdb18a6" - integrity sha512-opwMHufhUwkn/UUDk35LDbKJpA2VBsZT8WLU8NjayvRLGPxQkN+8XmfC2Xl35MAscBE8469koLLBjaI3XLEIww== - -"@types/sinon@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.0.tgz#84e707e157ec17d3e4c2a137f41fc3f416c0551e" - integrity sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg== - -"@types/sizzle@*": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" - integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -2450,9 +2380,9 @@ source-map "^0.6.1" "@types/webpack-dev-server@^3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.1.1.tgz#12ae26194b3e1b8a317559592659921f282583c2" - integrity sha512-TnEQPT+OZjWV2kRyNs0RPMDQmBCiLrr/ZhKSgFNF6aM4O/moUAfo2Yu3MIMUjoi3aE/02RH1iVR+Y6mWmXOlVA== + version "3.1.5" + resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.1.5.tgz#cf1f2a19ae07983a7c80c7b7f57548c81949b9b3" + integrity sha512-eizwVjKPHA7pBMqNGx3bi+cxqMV625Rt/NEy27N432YG9Tm2q+iLglBgvMNTALMDPtkv9zO3nDKfp76PhWRfFA== dependencies: "@types/express" "*" "@types/http-proxy-middleware" "*" @@ -2460,9 +2390,9 @@ "@types/webpack" "*" "@types/webpack@*", "@types/webpack@^4.4.23": - version "4.4.23" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.23.tgz#059d6f4598cfd65ddee0e2db38317ef989696712" - integrity sha512-WswyG+2mRg0ul/ytPpCSWo+kOlVVPW/fKCBEVwqmPVC/2ffWEwhsCEQgnFbWDf8EWId2qGcpL623EjLfNTRk9A== + version "4.4.29" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.29.tgz#d2a1c1d8c071b06521d32cee1c6b33d704b54b2c" + integrity sha512-8KVp+cNy9OPYsa4jU6vWsBemn5ixJ0Durh95Cw/YpEKm5ks2ODhdXc4FG3Xc46KIbPrJolwY7mSZFNn1aU3hKg== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -2480,6 +2410,35 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== +"@typescript-eslint/eslint-plugin@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.7.0.tgz#570e45dc84fb97852e363f1e00f47e604a0b8bcc" + integrity sha512-NUSz1aTlIzzTjFFVFyzrbo8oFjHg3K/M9MzYByqbMCxeFdErhLAcGITVfXzSz+Yvp5OOpMu3HkIttB0NyKl54Q== + dependencies: + "@typescript-eslint/parser" "1.7.0" + "@typescript-eslint/typescript-estree" "1.7.0" + eslint-utils "^1.3.1" + regexpp "^2.0.1" + requireindex "^1.2.0" + tsutils "^3.7.0" + +"@typescript-eslint/parser@1.7.0", "@typescript-eslint/parser@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-1.7.0.tgz#c3ea0d158349ceefbb6da95b5b09924b75357851" + integrity sha512-1QFKxs2V940372srm12ovSE683afqc1jB6zF/f8iKhgLz1yoSjYeGHipasao33VXKI+0a/ob9okeogGdKGvvlg== + dependencies: + "@typescript-eslint/typescript-estree" "1.7.0" + eslint-scope "^4.0.0" + eslint-visitor-keys "^1.0.0" + +"@typescript-eslint/typescript-estree@1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.7.0.tgz#59ec02f5371964da1cc679dba7b878a417bc8c60" + integrity sha512-K5uedUxVmlYrVkFbyV3htDipvLqTE3QMOUQEHYJaKtgzxj6r7c5Ca/DG1tGgFxX+fsbi9nDIrf4arq7Ib7H/Yw== + dependencies: + lodash.unescape "4.0.1" + semver "5.5.0" + "@vue/babel-preset-app@3.0.0-beta.11": version "3.0.0-beta.11" resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.0.0-beta.11.tgz#c8b889aa73464050f9cd3f9dc621951d85c24508" @@ -2494,45 +2453,22 @@ babel-plugin-dynamic-import-node "^1.2.0" babel-plugin-transform-vue-jsx "^4.0.1" -"@vue/component-compiler-utils@^2.0.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.3.0.tgz#4f580f1b28fc7685859d87ea0e92a1c0271c93da" - integrity sha512-4RB1mow8IO2X0/86plKhflMJYSiSn3sWHiqVob8s/LCADFMHSaFRTQp5GdqvjvlGmwjhdn2dzDQik+RLjTx/5g== - dependencies: - consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" - merge-source-map "^1.1.0" - postcss "^6.0.20" - postcss-selector-parser "^3.1.1" - prettier "1.13.7" - source-map "^0.5.6" - vue-template-es2015-compiler "^1.6.0" - -"@vue/component-compiler-utils@^2.4.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.5.0.tgz#411846d582d393f701f747517ddd29275ce64ca4" - integrity sha512-mSB8jWmE/ZeYZHPDEx9hNiiRh5P2V1Q0tObxEQWtxxfXtkIAvPnj7oucGm5SO8Y/QwIlDJgAGqHfj5MCjoKoOg== +"@vue/component-compiler-utils@^2.5.1": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz#aa46d2a6f7647440b0b8932434d22f12371e543b" + integrity sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw== dependencies: consolidate "^0.15.1" hash-sum "^1.0.2" lru-cache "^4.1.2" merge-source-map "^1.1.0" - postcss "^7.0.7" + postcss "^7.0.14" postcss-selector-parser "^5.0.0" - prettier "1.13.7" - source-map "^0.7.3" - vue-template-es2015-compiler "^1.6.0" - -"@vue/test-utils@^1.0.0-beta.19": - version "1.0.0-beta.26" - resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.26.tgz#1ae7e1dc2bef4f49f9dbfdfecad342d17d6c5c88" - integrity sha512-2bvTgdh4Rh9NqeIrH+rah6AjXUHYxFqLO+NoOMqWXYqSvk1PGgvI5o5sT6Pty4HklIReOZxWxsMpgnJFK9rW+A== - dependencies: - dom-event-types "^1.0.0" - lodash "^4.17.4" + prettier "1.16.3" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" -"@vue/test-utils@^1.0.0-beta.29": +"@vue/test-utils@^1.0.0-beta.19", "@vue/test-utils@^1.0.0-beta.29": version "1.0.0-beta.29" resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.29.tgz#c942cf25e891cf081b6a03332b4ae1ef430726f0" integrity sha512-yX4sxEIHh4M9yAbLA/ikpEnGKMNBCnoX98xE1RwxfhQVcn0MaXNSj1Qmac+ZydTj6VBSEVukchBogXBTwc+9iA== @@ -2540,148 +2476,151 @@ dom-event-types "^1.0.0" lodash "^4.17.4" -"@webassemblyjs/ast@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" - integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== - dependencies: - "@webassemblyjs/helper-module-context" "1.7.11" - "@webassemblyjs/helper-wasm-bytecode" "1.7.11" - "@webassemblyjs/wast-parser" "1.7.11" - -"@webassemblyjs/floating-point-hex-parser@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" - integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== - -"@webassemblyjs/helper-api-error@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" - integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== - -"@webassemblyjs/helper-buffer@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" - integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== - -"@webassemblyjs/helper-code-frame@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" - integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== - dependencies: - "@webassemblyjs/wast-printer" "1.7.11" - -"@webassemblyjs/helper-fsm@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" - integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== - -"@webassemblyjs/helper-module-context@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" - integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== - -"@webassemblyjs/helper-wasm-bytecode@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" - integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== - -"@webassemblyjs/helper-wasm-section@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" - integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/helper-buffer" "1.7.11" - "@webassemblyjs/helper-wasm-bytecode" "1.7.11" - "@webassemblyjs/wasm-gen" "1.7.11" - -"@webassemblyjs/ieee754@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" - integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" - integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== - dependencies: - "@xtuc/long" "4.2.1" - -"@webassemblyjs/utf8@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" - integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== - -"@webassemblyjs/wasm-edit@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" - integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/helper-buffer" "1.7.11" - "@webassemblyjs/helper-wasm-bytecode" "1.7.11" - "@webassemblyjs/helper-wasm-section" "1.7.11" - "@webassemblyjs/wasm-gen" "1.7.11" - "@webassemblyjs/wasm-opt" "1.7.11" - "@webassemblyjs/wasm-parser" "1.7.11" - "@webassemblyjs/wast-printer" "1.7.11" - -"@webassemblyjs/wasm-gen@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" - integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/helper-wasm-bytecode" "1.7.11" - "@webassemblyjs/ieee754" "1.7.11" - "@webassemblyjs/leb128" "1.7.11" - "@webassemblyjs/utf8" "1.7.11" - -"@webassemblyjs/wasm-opt@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" - integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/helper-buffer" "1.7.11" - "@webassemblyjs/wasm-gen" "1.7.11" - "@webassemblyjs/wasm-parser" "1.7.11" - -"@webassemblyjs/wasm-parser@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" - integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/helper-api-error" "1.7.11" - "@webassemblyjs/helper-wasm-bytecode" "1.7.11" - "@webassemblyjs/ieee754" "1.7.11" - "@webassemblyjs/leb128" "1.7.11" - "@webassemblyjs/utf8" "1.7.11" - -"@webassemblyjs/wast-parser@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" - integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/floating-point-hex-parser" "1.7.11" - "@webassemblyjs/helper-api-error" "1.7.11" - "@webassemblyjs/helper-code-frame" "1.7.11" - "@webassemblyjs/helper-fsm" "1.7.11" - "@xtuc/long" "4.2.1" - -"@webassemblyjs/wast-printer@1.7.11": - version "1.7.11" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" - integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/wast-parser" "1.7.11" - "@xtuc/long" "4.2.1" +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" "@webpack-contrib/config-loader@^1.1.1": version "1.2.1" @@ -2715,10 +2654,10 @@ resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== -"@xtuc/long@4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" - integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== JSONStream@^1.0.4, JSONStream@^1.3.4: version "1.3.5" @@ -2739,56 +2678,59 @@ abbrev@1: integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@^1.3.5, accepts@~1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== dependencies: - mime-types "~2.1.18" - negotiator "0.6.1" + mime-types "~2.1.24" + negotiator "0.6.2" -acorn-dynamic-import@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" - integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== - dependencies: - acorn "^5.0.0" +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== acorn-globals@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" - integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw== + version "4.3.2" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006" + integrity sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ== dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" acorn-jsx@^3.0.0: version "3.0.1" - resolved "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= dependencies: acorn "^3.0.4" -acorn-walk@^6.0.1: +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn-walk@^6.0.1, acorn-walk@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== acorn@^3.0.4: version "3.3.0" - resolved "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= -acorn@^5.0.0, acorn@^5.5.0, acorn@^5.5.3, acorn@^5.6.2, acorn@^5.7.3: +acorn@^5.5.0, acorn@^5.5.3: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1: +acorn@^6.0.1, acorn@^6.0.5, acorn@^6.0.7: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== -agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: +agent-base@4, agent-base@^4.1.0, agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== @@ -2797,7 +2739,7 @@ agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: agentkeepalive@^2.2.0: version "2.2.0" - resolved "http://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" integrity sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8= agentkeepalive@^3.4.1: @@ -2808,9 +2750,9 @@ agentkeepalive@^3.4.1: humanize-ms "^1.2.1" ajv-errors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59" - integrity sha1-7PAh+hCP0X37Xms4Py3SM+Mf/Fk= + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-keywords@^2.1.0: version "2.1.1" @@ -2818,11 +2760,11 @@ ajv-keywords@^2.1.0: integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" - integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= + version "3.4.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" + integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw== -ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: +ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= @@ -2832,10 +2774,10 @@ ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.5: - version "6.6.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" - integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== +ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.5, ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -2843,12 +2785,12 @@ ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.5: uri-js "^4.2.2" algoliasearch@^3.24.5: - version "3.31.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.31.0.tgz#c4083375ff02538ef50d9ec73e6a72e5e19ed96f" - integrity sha512-RJ3m8bQEitEQvWVfJa8WCTM4B9WSt0D4PPEYoqOga7Q0GAfBOqXTWeFYyDO46o085SWBSBWBInVuKyr5BIFP3A== + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== dependencies: agentkeepalive "^2.2.0" - debug "^2.6.8" + debug "^2.6.9" envify "^4.0.0" es6-promise "^4.1.0" events "^1.1.0" @@ -2893,21 +2835,16 @@ ansi-align@^2.0.0: string-width "^2.0.0" ansi-colors@^3.0.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.2.tgz#e49349137dbeb6d381b91e607c189915e53265ba" - integrity sha512-kJmcp4PrviBBEx95fC3dYRiC/QSN3EBd0GU1XoNEk/IuUa92rsB6o90zP3w5VAyNznR38Vkc9i8vk5zK6T7TxA== + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== ansi-escapes@^1.0.0: version "1.4.0" - resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0: - version "3.1.0" - resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== - -ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== @@ -2927,10 +2864,10 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" - integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== +ansi-regex@^4.0.0, ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== ansi-styles@^2.1.0, ansi-styles@^2.2.1: version "2.2.1" @@ -2958,77 +2895,88 @@ anymatch@^2.0.0: normalize-path "^2.1.1" apollo-cache-inmemory@^1.2.5: - version "1.3.11" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.11.tgz#6cb8f24ec812715169f9acbb0b67833f9a19ec90" - integrity sha512-fSoyjBV5RV57J3i/VHDDB74ZgXc0PFiogheNFHEhC0mL6rg5e/DjTx0Vg+csIBk23gvlzTvV+eypx7Q2NJ+dYg== + version "1.5.1" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.1.tgz#265d1ee67b0bf0aca9c37629d410bfae44e62953" + integrity sha512-D3bdpPmWfaKQkWy8lfwUg+K8OBITo3sx0BHLs1B/9vIdOIZ7JNCKq3EUcAgAfInomJUdN0QG1yOfi8M8hxkN1g== dependencies: - apollo-cache "^1.1.21" - apollo-utilities "^1.0.26" - optimism "^0.6.6" + apollo-cache "^1.2.1" + apollo-utilities "^1.2.1" + optimism "^0.6.9" + ts-invariant "^0.2.1" + tslib "^1.9.3" -apollo-cache@1.1.21, apollo-cache@^1.1.21: - version "1.1.21" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.21.tgz#950025e2272741ba8e5064419906e3ac4072925d" - integrity sha512-5ErNb78KHtrJNimkDBTEigcvHkIqUmS7QJIk4lpZZ+XLVVgvk2fD+GhD1PLP+s8vHfAKVbO6vdbRxCCjGGrh5w== +apollo-cache@1.2.1, apollo-cache@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.2.1.tgz#aae71eb4a11f1f7322adc343f84b1a39b0693644" + integrity sha512-nzFmep/oKlbzUuDyz6fS6aYhRmfpcHWqNkkA9Bbxwk18RD6LXC4eZkuE0gXRX0IibVBHNjYVK+Szi0Yied4SpQ== dependencies: - apollo-utilities "^1.0.26" + apollo-utilities "^1.2.1" + tslib "^1.9.3" apollo-client@^2.3.5: - version "2.4.7" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.7.tgz#b6712fd4c9ba346e3c44cfec7e6868e532b6a957" - integrity sha512-6aAm+16AFBYZhJF8eKxrup6AbYni01InDiwTfZhMMTP2xaXQWjsQnfaHbI2oE+hd3+AZFy1drkse8RZKghR/WQ== + version "2.5.1" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.5.1.tgz#36126ed1d32edd79c3713c6684546a3bea80e6d1" + integrity sha512-MNcQKiqLHdGmNJ0rZ0NXaHrToXapJgS/5kPk0FygXt+/FmDCdzqcujI7OPxEC6e9Yw5S/8dIvOXcRNuOMElHkA== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.21" + apollo-cache "1.2.1" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.26" + apollo-utilities "1.2.1" symbol-observable "^1.0.2" + ts-invariant "^0.2.1" + tslib "^1.9.3" zen-observable "^0.8.0" - optionalDependencies: - "@types/async" "2.0.50" apollo-link-dedup@^1.0.0: - version "1.0.11" - resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" - integrity sha512-RcvkXR0CNbQcsw6LdrPksGa+9YjZ1ghk0k2PKal6rSBCyyqzokcBawXOtoMN8q+0FLR1dGs5GnAQVeucQuY28g== + version "1.0.18" + resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.18.tgz#635cb5659b082e7f270f7649c4b0f71021f7bb4b" + integrity sha512-1rr54wyMTuqUmbWvcXbwduIcaCDcuIgU6MqQ599nAMuTrbSOXthGfoAD8BDTxBGQ9roVlM7ABP0VZVEWRoHWSg== dependencies: - apollo-link "^1.2.4" + apollo-link "^1.2.11" + tslib "^1.9.3" -apollo-link-http-common@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.6.tgz#47b9012500599fe343e2e87378026384b4fc8c1f" - integrity sha512-LUOMWvrZuBP1hyWLBXyaW0KyFeKo79j+k3N+Q4HSkXKbLibnllXQ+JxxoSKGhm0bhREygiLtJAG9JnGlhxGO/Q== +apollo-link-http-common@^0.2.13: + version "0.2.13" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.13.tgz#c688f6baaffdc7b269b2db7ae89dae7c58b5b350" + integrity sha512-Uyg1ECQpTTA691Fwx5e6Rc/6CPSu4TB4pQRTGIpwZ4l5JDOQ+812Wvi/e3IInmzOZpwx5YrrOfXrtN8BrsDXoA== dependencies: - apollo-link "^1.2.4" + apollo-link "^1.2.11" + ts-invariant "^0.3.2" + tslib "^1.9.3" apollo-link-http@^1.5.4: - version "1.5.7" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.7.tgz#098615c427a910ec8c5817476bbabe68c586b339" - integrity sha512-EZ9nynHjwYCpGYP5IsRrZGTWidUVpshk7MuSG4joqGtJMwpFCgMQz+y3BHdUhowHtfAd9z60XmeOTG9FJolb8A== + version "1.5.14" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.14.tgz#ed6292248d1819ccd16523e346d35203a1b31109" + integrity sha512-XEoPXmGpxFG3wioovgAlPXIarWaW4oWzt8YzjTYZ87R4R7d1A3wKR/KcvkdMV1m5G7YSAHcNkDLe/8hF2nH6cg== dependencies: - apollo-link "^1.2.4" - apollo-link-http-common "^0.2.6" + apollo-link "^1.2.11" + apollo-link-http-common "^0.2.13" + tslib "^1.9.3" -apollo-link@^1.0.0, apollo-link@^1.2.2, apollo-link@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.4.tgz#ab4d21d2e428db848e88b5e8f4adc717b19c954b" - integrity sha512-B1z+9H2nTyWEhMXRFSnoZ1vSuAYP+V/EdUJvRx9uZ8yuIBZMm6reyVtr1n0BWlKeSFyPieKJy2RLzmITAAQAMQ== +apollo-link@^1.0.0, apollo-link@^1.2.11, apollo-link@^1.2.2: + version "1.2.11" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.11.tgz#493293b747ad3237114ccd22e9f559e5e24a194d" + integrity sha512-PQvRCg13VduLy3X/0L79M6uOpTh5iHdxnxYuo8yL7sJlWybKRJwsv4IcRBJpMFbChOOaHY7Og9wgPo6DLKDKDA== dependencies: - apollo-utilities "^1.0.0" - zen-observable-ts "^0.8.11" + apollo-utilities "^1.2.1" + ts-invariant "^0.3.2" + tslib "^1.9.3" + zen-observable-ts "^0.8.18" -apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.26: - version "1.0.26" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" - integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== +apollo-utilities@1.2.1, apollo-utilities@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.1.tgz#1c3a1ebf5607d7c8efe7636daaf58e7463b41b3c" + integrity sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg== dependencies: fast-json-stable-stringify "^2.0.0" + ts-invariant "^0.2.1" + tslib "^1.9.3" app-root-path@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a" - integrity sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo= + version "2.2.1" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" + integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== append-transform@^1.0.0: version "1.0.0" @@ -3106,7 +3054,7 @@ array-find-index@^1.0.1: array-flatten@1.1.1: version "1.1.1" - resolved "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-ify@^1.0.0: @@ -3114,6 +3062,14 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -3184,10 +3140,10 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== async-foreach@^0.1.3: version "0.1.3" @@ -3209,7 +3165,7 @@ async-listener@^0.6.0: async@1.5, async@^1.5.2: version "1.5.2" - resolved "http://registry.npmjs.org/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= async@2.4.0: @@ -3219,14 +3175,7 @@ async@2.4.0: dependencies: lodash "^4.14.0" -async@^2.5, async@^2.5.0, async@^2.6: - version "2.6.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== - dependencies: - lodash "^4.17.10" - -async@^2.6.1: +async@^2.5, async@^2.6, async@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== @@ -3235,7 +3184,7 @@ async@^2.6.1: async@~1.0.0: version "1.0.0" - resolved "http://registry.npmjs.org/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k= asynckit@^0.4.0: @@ -3243,6 +3192,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +atob-lite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696" + integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY= + atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -3284,7 +3238,7 @@ aws-sign2@~0.7.0: resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= -aws4@^1.6.0, aws4@^1.8.0: +aws4@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== @@ -3498,17 +3452,7 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-jest@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.1.0.tgz#441e23ef75ded3bd547e300ac3194cef87b55190" - integrity sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw== - dependencies: - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.1.0" - chalk "^2.4.2" - slash "^2.0.0" - -babel-jest@^24.7.1: +babel-jest@^24.1.0, babel-jest@^24.7.1: version "24.7.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.7.1.tgz#73902c9ff15a7dfbdc9994b0b17fcefd96042178" integrity sha512-GPnLqfk8Mtt0i4OemjWkChi73A3ALs4w2/QbG64uAj8b5mmwzxc7jbJVRZt8NJkxi6FopVHog9S3xX6UJKb2qg== @@ -3572,18 +3516,13 @@ babel-plugin-dynamic-import-node@^1.2.0: babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-istanbul@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz#7981590f1956d75d67630ba46f0c22493588c893" - integrity sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ== + version "5.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.3.tgz#202d20ffc96a821c68a3964412de75b9bdeb48c7" + integrity sha512-IFyehbvRRwdBlI1lDp+FaMsWNnEndEk7065IB8NhzBX+ZKLPwPodgk4I5Gobw/8SNUUzso2Dv3hbqRh88eiSCQ== dependencies: find-up "^3.0.0" - istanbul-lib-instrument "^3.0.0" - test-exclude "^5.0.0" - -babel-plugin-jest-hoist@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz#dfecc491fb15e2668abbd690a697a8fd1411a7f8" - integrity sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw== + istanbul-lib-instrument "^3.2.0" + test-exclude "^5.2.2" babel-plugin-jest-hoist@^24.6.0: version "24.6.0" @@ -3594,32 +3533,32 @@ babel-plugin-jest-hoist@^24.6.0: babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= babel-plugin-syntax-async-generators@^6.5.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= babel-plugin-syntax-object-rest-spread@^6.8.0: @@ -3936,14 +3875,6 @@ babel-preset-env@^1.6.x: invariant "^2.2.2" semver "^5.3.0" -babel-preset-jest@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz#83bc564fdcd4903641af65ec63f2f5de6b04132e" - integrity sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.1.0" - babel-preset-jest@^24.6.0: version "24.6.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" @@ -4095,10 +4026,15 @@ big.js@^3.1.3: resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + binary-extensions@^1.0.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== blessed@^0.1.81: version "0.1.81" @@ -4118,9 +4054,9 @@ bluebird@3.5.0: integrity sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw= bluebird@^3.1.1, bluebird@^3.5.1, bluebird@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" - integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + version "3.5.4" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.4.tgz#d6cc661595de30d5b3af5fcedd3c0b3ef6ec5714" + integrity sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" @@ -4185,7 +4121,7 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" -braces@^2.3.0, braces@^2.3.1: +braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== @@ -4220,7 +4156,7 @@ browser-resolve@^1.11.3: browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" - resolved "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" @@ -4251,7 +4187,7 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0: version "4.0.1" - resolved "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= dependencies: bn.js "^4.1.0" @@ -4293,14 +4229,14 @@ browserslist@^3.0.0, browserslist@^3.2.6, browserslist@^3.2.8: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.3.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.4.2.tgz#6ea8a74d6464bb0bd549105f659b41197d8f0ba2" - integrity sha512-ISS/AIAiHERJ3d45Fz0AVYKkgcy+F/eJHzKEvv1j0wwKGKD9T3BrwKr/5g45L+Y4XIK5PlTqefHciRFcfE1Jxg== +browserslist@^4.5.2, browserslist@^4.5.4: + version "4.5.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.6.tgz#ea42e8581ca2513fa7f371d4dd66da763938163d" + integrity sha512-o/hPOtbU9oX507lIqon+UvPYqpx3mHc8cV3QemSBTXwkG8gSQSK6UKvXcE/DcleU3+A59XTUHyCvZ5qGy8xVAg== dependencies: - caniuse-lite "^1.0.30000939" - electron-to-chromium "^1.3.113" - node-releases "^1.1.8" + caniuse-lite "^1.0.30000963" + electron-to-chromium "^1.3.127" + node-releases "^1.1.17" bs-logger@0.x: version "0.2.6" @@ -4338,18 +4274,13 @@ buffer-xor@^1.0.3: buffer@^4.3.0: version "4.9.1" - resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" isarray "^1.0.0" -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -4377,7 +4308,7 @@ bytes@3.0.0: cacache@^10.0.4: version "10.0.4" - resolved "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" integrity sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA== dependencies: bluebird "^3.5.1" @@ -4394,7 +4325,7 @@ cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" -cacache@^11.0.1, cacache@^11.3.2: +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.3.2: version "11.3.2" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== @@ -4414,26 +4345,6 @@ cacache@^11.0.1, cacache@^11.3.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^11.0.2: - version "11.3.1" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f" - integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA== - dependencies: - bluebird "^3.5.1" - chownr "^1.0.1" - figgy-pudding "^3.1.0" - glob "^7.1.2" - graceful-fs "^4.1.11" - lru-cache "^4.1.3" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.2" - ssri "^6.0.0" - unique-filename "^1.1.0" - y18n "^4.0.0" - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -4502,18 +4413,18 @@ caller-path@^2.0.0: callsites@^0.2.0: version "0.2.0" - resolved "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= callsites@^2.0.0: version "2.0.0" - resolved "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= callsites@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" - integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camel-case@3.0.x: version "3.0.0" @@ -4525,7 +4436,7 @@ camel-case@3.0.x: camelcase-keys@^2.0.0: version "2.1.0" - resolved "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= dependencies: camelcase "^2.0.0" @@ -4556,9 +4467,9 @@ camelcase@^4.0.0, camelcase@^4.1.0: integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= camelcase@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" - integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-api@^1.5.2: version "1.6.1" @@ -4571,19 +4482,14 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000916" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000916.tgz#44556ba3f7360a4e103950fc58cc98b74d253da1" - integrity sha512-XuMzGxlFYXDEm+e/6ti7ThqQki/hRXHw4aaFMQXtFHYoj2XNn92zZ5aH75AADfQ1tnXoZTOvS2+NbaaWWPypIw== - -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864: - version "1.0.30000916" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000916.tgz#3428d3f529f0a7b2bfaaec65e796037bdd433aab" - integrity sha512-D6J9jloPm2MPkg0PXcODLMQAJKkeixKO9xhqTUMvtd44MtTYMyyDXPQ2Lk9IgBq5FH0frwiPa/N/w8ncQf7kIQ== + version "1.0.30000963" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000963.tgz#df13099c13d3ad29d8ded5387f77e86319dd3805" + integrity sha512-5Qk1jSsqRY3dD7BAjU018y0MsznzYb+kMTKzGknue8vSWlHkw2S345vRnd0cVEerzZ6ugUfoKaUOOVbBxWLWCA== -caniuse-lite@^1.0.30000939: - version "1.0.30000942" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000942.tgz#454139b28274bce70bfe1d50c30970df7430c6e4" - integrity sha512-wLf+IhZUy2rfz48tc40OH7jHjXjnvDFEYqBHluINs/6MgzoNLPf25zhE4NOVzqxLKndf+hau81sAW0RcGHIaBQ== +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864, caniuse-lite@^1.0.30000963: + version "1.0.30000963" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000963.tgz#5be481d5292f22aff5ee0db4a6c049b65b5798b1" + integrity sha512-n4HUiullc7Lw0LyzpeLa2ffP8KxFBGdxqD/8G3bSL6oB758hZ2UE2CVK+tQN958tJIi0/tfpjAc67aAtoHgnrQ== capture-exit@^2.0.0: version "2.0.0" @@ -4598,9 +4504,9 @@ capture-stack-trace@^1.0.0: integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== case-sensitive-paths-webpack-plugin@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.2.tgz#c899b52175763689224571dad778742e133f0192" - integrity sha512-oEZgAFfEvKtjSRCu6VgYkuGxwrWXMnQzyBmlLPP7r6PWQVtHxP5Z5N6XsuJvtoVax78am/r7lr46bwo3IVEBOg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" + integrity sha512-u5ElzokS8A1pm9vM3/iDgTcI3xqHxuCao94Oz8etI3cf0Tio0p8izkDYbTIn09uP3yUUr6+veaE6IkjnTYS46g== caseless@~0.12.0: version "0.12.0" @@ -4609,7 +4515,7 @@ caseless@~0.12.0: chalk@1.1.1: version "1.1.1" - resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz#509afb67066e7499f7eb3535c77445772ae2d019" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.1.tgz#509afb67066e7499f7eb3535c77445772ae2d019" integrity sha1-UJr7ZwZudJn36zU1x3RFdyri0Bk= dependencies: ansi-styles "^2.1.0" @@ -4618,10 +4524,10 @@ chalk@1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, 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== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -4629,7 +4535,7 @@ chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3. chalk@^1.0.0, chalk@^1.1, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" - resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" @@ -4638,15 +4544,6 @@ chalk@^1.0.0, chalk@^1.1, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.3.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== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -4673,24 +4570,23 @@ check-types@^7.3.0: integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg== chokidar@^2, chokidar@^2.0.2, chokidar@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + version "2.1.5" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" + integrity sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A== dependencies: anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" + async-each "^1.0.1" + braces "^2.3.2" glob-parent "^3.1.0" - inherits "^2.0.1" + inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.2.2" + fsevents "^1.2.7" chownr@^1.0.1, chownr@^1.1.1: version "1.1.1" @@ -4704,7 +4600,7 @@ chrome-trace-event@^1.0.0: dependencies: tslib "^1.9.0" -ci-info@^1.0.0, ci-info@^1.5.0: +ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== @@ -4912,14 +4808,14 @@ color-name@^1.0.0: color-string@^0.3.0: version "0.3.0" - resolved "http://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" integrity sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE= dependencies: color-name "^1.0.0" color@^0.11.0: version "0.11.4" - resolved "http://registry.npmjs.org/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" + resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" integrity sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q= dependencies: clone "^1.0.2" @@ -4937,12 +4833,12 @@ colormin@^1.0.5: colors@1.0.x: version "1.0.3" - resolved "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= colors@~1.1.2: version "1.1.2" - resolved "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= columnify@^1.5.4: @@ -4953,7 +4849,7 @@ columnify@^1.5.4: strip-ansi "^3.0.0" wcwidth "^1.0.0" -combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== @@ -4965,34 +4861,32 @@ command-exists@^1.2.2: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== -commander@2, commander@^2.15.1, commander@^2.18.0, commander@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - -commander@2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== +commander@2, commander@^2.15.1, commander@^2.18.0, commander@^2.19.0, commander@~2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== commander@2.13.0, commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== -commander@2.17.x, commander@~2.17.1: +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@2.17.x: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -common-tags@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0" - integrity sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA= - dependencies: - babel-runtime "^6.18.0" +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== -common-tags@^1.4.0: +common-tags@1.8.0, common-tags@^1.4.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== @@ -5016,24 +4910,15 @@ compare-versions@^3.2.1: integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" - integrity sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc= - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" @@ -5044,6 +4929,16 @@ concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +concat-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.0.2" + typedarray "^0.0.6" + condense-newlines@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" @@ -5081,9 +4976,9 @@ configstore@^3.0.0: xdg-basedir "^3.0.0" connect-history-api-fallback@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a" - integrity sha1-sGhzk0vF40T+9hGhlqb6rgruAVo= + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== consola@^1.4.3: version "1.4.5" @@ -5124,11 +5019,18 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -content-disposition@0.5.2, content-disposition@~0.5.2: +content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= +content-disposition@~0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + content-type@^1.0.4, content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -5151,12 +5053,12 @@ conventional-changelog-angular@^5.0.3: q "^1.5.1" conventional-changelog-core@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.1.6.tgz#ac1731a461c50d150d29c1ad4f33143293bcd32f" - integrity sha512-5teTAZOtJ4HLR6384h50nPAaKdDr+IaU0rnD2Gg2C3MS7hKsEPH8pZxrDNqam9eOSPQg9tET6uZY79zzgSz+ig== + version "3.2.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.2.2.tgz#de41e6b4a71011a18bcee58e744f6f8f0e7c29c0" + integrity sha512-cssjAKajxaOX5LNAJLB+UOcoWjAIBvXtDMedv/58G+YEmAXMNfC16mmPl0JDOuVJVfIqM0nqQiZ8UCm8IXbE0g== dependencies: - conventional-changelog-writer "^4.0.3" - conventional-commits-parser "^3.0.1" + conventional-changelog-writer "^4.0.5" + conventional-commits-parser "^3.0.2" dateformat "^3.0.0" get-pkg-repo "^1.0.0" git-raw-commits "2.0.0" @@ -5167,20 +5069,20 @@ conventional-changelog-core@^3.1.6: q "^1.5.1" read-pkg "^3.0.0" read-pkg-up "^3.0.0" - through2 "^2.0.0" + through2 "^3.0.0" -conventional-changelog-preset-loader@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.2.tgz#81d1a07523913f3d17da3a49f0091f967ad345b0" - integrity sha512-pBY+qnUoJPXAXXqVGwQaVmcye05xi6z231QM98wHWamGAmu/ghkBprQAwmF5bdmyobdVxiLhPY3PrCfSeUNzRQ== +conventional-changelog-preset-loader@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.1.1.tgz#65bb600547c56d5627d23135154bcd9a907668c4" + integrity sha512-K4avzGMLm5Xw0Ek/6eE3vdOXkqnpf9ydb68XYmCc16cJ99XMMbc2oaNMuPwAsxVK6CC1yA4/I90EhmWNj0Q6HA== -conventional-changelog-writer@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.3.tgz#916a2b302d0bb5ef18efd236a034c13fb273cde1" - integrity sha512-bIlpSiQtQZ1+nDVHEEh798Erj2jhN/wEjyw9sfxY9es6h7pREE5BNJjfv0hXGH/FTrAsEpHUq4xzK99eePpwuA== +conventional-changelog-writer@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.5.tgz#fb9e384bb294e8e8a9f2568a3f4d1e11953d8641" + integrity sha512-g/Myp4MaJ1A+f7Ai+SnVhkcWtaHk6flw0SYN7A+vQ+MTu0+gSovQWs4Pg4NtcNUcIztYQ9YHsoxHP+GGQplI7Q== dependencies: compare-func "^1.3.1" - conventional-commits-filter "^2.0.1" + conventional-commits-filter "^2.0.2" dateformat "^3.0.0" handlebars "^4.1.0" json-stringify-safe "^5.0.1" @@ -5188,38 +5090,38 @@ conventional-changelog-writer@^4.0.3: meow "^4.0.0" semver "^5.5.0" split "^1.0.0" - through2 "^2.0.0" + through2 "^3.0.0" -conventional-commits-filter@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.1.tgz#55a135de1802f6510b6758e0a6aa9e0b28618db3" - integrity sha512-92OU8pz/977udhBjgPEbg3sbYzIxMDFTlQT97w7KdhR9igNqdJvy8smmedAAgn4tPiqseFloKkrVfbXCVd+E7A== +conventional-commits-filter@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz#f122f89fbcd5bb81e2af2fcac0254d062d1039c1" + integrity sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ== dependencies: - is-subset "^0.1.1" + lodash.ismatch "^4.4.0" modify-values "^1.0.0" -conventional-commits-parser@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.1.tgz#fe1c49753df3f98edb2285a5e485e11ffa7f2e4c" - integrity sha512-P6U5UOvDeidUJ8ebHVDIoXzI7gMlQ1OF/id6oUvp8cnZvOXMt1n8nYl74Ey9YMn0uVQtxmCtjPQawpsssBWtGg== +conventional-commits-parser@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.2.tgz#1295590dd195f64f53d6f8eb7c41114bb9a60742" + integrity sha512-y5eqgaKR0F6xsBNVSQ/5cI5qIF3MojddSUi1vKIggRkqUTbkqFKH9P5YX/AT1BVZp9DtSzBTIkvjyVLotLsVog== dependencies: JSONStream "^1.0.4" is-text-path "^1.0.0" lodash "^4.2.1" meow "^4.0.0" split2 "^2.0.0" - through2 "^2.0.0" + through2 "^3.0.0" trim-off-newlines "^1.0.0" conventional-recommended-bump@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.0.4.tgz#05540584641d3da758c8863c09788fcaeb586872" - integrity sha512-9mY5Yoblq+ZMqJpBzgS+RpSq+SUfP2miOR3H/NR9drGf08WCrY9B6HAGJZEm6+ThsVP917VHAahSOjM6k1vhPg== + version "4.1.1" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.1.1.tgz#37014fadeda267d0607e2fc81124da840a585127" + integrity sha512-JT2vKfSP9kR18RXXf55BRY1O3AHG8FPg5btP3l7LYfcWJsiXI6MCf30DepQ98E8Qhowvgv7a8iev0J1bEDkTFA== dependencies: - concat-stream "^1.6.0" - conventional-changelog-preset-loader "^2.0.2" - conventional-commits-filter "^2.0.1" - conventional-commits-parser "^3.0.1" + concat-stream "^2.0.0" + conventional-changelog-preset-loader "^2.1.1" + conventional-commits-filter "^2.0.2" + conventional-commits-parser "^3.0.2" git-raw-commits "2.0.0" git-semver-tags "^2.0.2" meow "^4.0.0" @@ -5281,12 +5183,27 @@ copy-webpack-plugin@^4.5.1: p-limit "^1.0.0" serialize-javascript "^1.4.0" -core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.0.tgz#1e30793e9ee5782b307e37ffa22da0eacddd84d4" - integrity sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw== +core-js-compat@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.0.1.tgz#bff73ba31ca8687431b9c88f78d3362646fb76f0" + integrity sha512-2pC3e+Ht/1/gD7Sim/sqzvRplMiRnFQVlPpDVaHtY9l7zZP7knamr3VRD6NyGfHd84MrDC0tAM9ulNxYMW0T3g== + dependencies: + browserslist "^4.5.4" + core-js "3.0.1" + core-js-pure "3.0.1" + semver "^6.0.0" + +core-js-pure@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.0.1.tgz#37358fb0d024e6b86d443d794f4e37e949098cbe" + integrity sha512-mSxeQ6IghKW3MoyF4cz19GJ1cMm7761ON+WObSyLfTu/Jn3x7w4NwNFnrZxgl4MTSvYYepVLNuRtlB4loMwJ5g== -core-js@^2.5.7: +core-js@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.1.tgz#1343182634298f7f38622f95e73f54e48ddf4738" + integrity sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew== + +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.6.5: version "2.6.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A== @@ -5306,25 +5223,14 @@ cosmiconfig@^4.0.0: parse-json "^4.0.0" require-from-string "^2.0.1" -cosmiconfig@^5.0.2: - version "5.0.7" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" - integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== +cosmiconfig@^5.0.2, cosmiconfig@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.0.tgz#45038e4d28a7fe787203aede9c25bca4a08b12c8" + integrity sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g== dependencies: import-fresh "^2.0.0" is-directory "^0.3.1" - js-yaml "^3.9.0" - parse-json "^4.0.0" - -cosmiconfig@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.1.0.tgz#6c5c35e97f37f985061cdf653f114784231185cf" - integrity sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.9.0" - lodash.get "^4.4.2" + js-yaml "^3.13.0" parse-json "^4.0.0" create-ecdh@^4.0.0: @@ -5344,7 +5250,7 @@ create-error-class@^3.0.0: create-hash@^1.1.0, create-hash@^1.1.2: version "1.2.0" - resolved "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" @@ -5355,7 +5261,7 @@ create-hash@^1.1.0, create-hash@^1.1.2: create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: version "1.1.7" - resolved "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" @@ -5366,9 +5272,9 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: sha.js "^2.4.8" cron@^1.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/cron/-/cron-1.5.1.tgz#84bf61574dc95e40698788261c7b23ab85446d5b" - integrity sha512-KXadzIvC7hvS7eMWw+L0AK10CBKc596K7DNGi0rOsSnp9QjiSWyiwKv4pBZCMvOZTPgAMotXNttkRwP7ymYlzQ== + version "1.7.1" + resolved "https://registry.yarnpkg.com/cron/-/cron-1.7.1.tgz#e85ee9df794d1bc6579896ee382053c3ce33778f" + integrity sha512-gmMB/pJcqUVs/NklR1sCGlNYM7TizEw+1gebz20BMc/8bTm/r7QUp3ZPSPlG8Z5XRlvb7qhjEjq/+bdIfUCL2A== dependencies: moment-timezone "^0.5.x" @@ -5437,12 +5343,12 @@ crypto-random-string@^1.0.0: css-color-names@0.0.4: version "0.0.4" - resolved "http://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= css-loader@^0.28.11: version "0.28.11" - resolved "http://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7" integrity sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg== dependencies: babel-code-frame "^6.26.0" @@ -5485,7 +5391,7 @@ css-parse@1.7.x: css-select@^1.1.0: version "1.2.0" - resolved "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= dependencies: boolbase "~1.0.0" @@ -5503,9 +5409,9 @@ css-selector-tokenizer@^0.7.0: regexpu-core "^1.0.0" css-what@2.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" - integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== + 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@^2.1.0: version "2.2.4" @@ -5529,7 +5435,7 @@ cssesc@^2.0.0: cssnano@^3.10.0: version "3.10.0" - resolved "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" integrity sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg= dependencies: autoprefixer "^6.3.1" @@ -5579,9 +5485,9 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== cssstyle@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.2.1.tgz#3aceb2759eaf514ac1a21628d723d6043a819495" - integrity sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A== + version "1.2.2" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.2.2.tgz#427ea4d585b18624f6fdbf9de7a2a1a3ba713077" + integrity sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow== dependencies: cssom "0.3.x" @@ -5603,55 +5509,45 @@ cyclist@~0.2.2: integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= cypress@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.1.5.tgz#5227b2ce9306c47236d29e703bad9055d7218042" - integrity sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.2.0.tgz#c2d5befd5077dab6fb52ad70721e0868ac057001" + integrity sha512-PN0wz6x634QyNL56/voTzJoeScDfwtecvSfFTHfv5MkHuECVSR4VQcEZTvYtKWln3CMBMUkWbBKPIwwu2+a/kw== dependencies: "@cypress/listr-verbose-renderer" "0.4.1" - "@cypress/xvfb" "1.2.3" - "@types/blob-util" "1.3.3" - "@types/bluebird" "3.5.18" - "@types/chai" "4.0.8" - "@types/chai-jquery" "1.1.35" - "@types/jquery" "3.3.6" - "@types/lodash" "4.14.87" - "@types/minimatch" "3.0.3" - "@types/mocha" "2.2.44" - "@types/sinon" "7.0.0" - "@types/sinon-chai" "3.2.2" + "@cypress/xvfb" "1.2.4" bluebird "3.5.0" cachedir "1.3.0" - chalk "2.4.1" + chalk "2.4.2" check-more-types "2.24.0" - commander "2.11.0" - common-tags "1.4.0" + commander "2.15.1" + common-tags "1.8.0" debug "3.1.0" execa "0.10.0" executable "4.1.1" - extract-zip "1.6.6" + extract-zip "1.6.7" fs-extra "4.0.1" getos "3.1.0" - glob "7.1.2" - is-ci "1.0.10" + glob "7.1.3" + is-ci "1.2.1" is-installed-globally "0.1.0" lazy-ass "1.6.0" listr "0.12.0" lodash "4.17.11" log-symbols "2.2.0" minimist "1.2.0" - moment "2.22.2" + moment "2.24.0" ramda "0.24.1" - request "2.87.0" - request-progress "0.3.1" - supports-color "5.1.0" - tmp "0.0.31" + request "2.88.0" + request-progress "0.4.0" + supports-color "5.5.0" + tmp "0.0.33" url "0.11.0" - yauzl "2.8.0" + yauzl "2.10.0" d3-dsv@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.10.tgz#4371c489a2a654a297aca16fcaf605a6f31a6f51" - integrity sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g== + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.1.1.tgz#aaa830ecb76c4b5015572c647cc6441e3c7bb701" + integrity sha512-1EH1oRGSkeDUlDRbhsFytAXU6cAmXFzc52YUe6MRlPClmWb85MP1J5x+YJRzya4ynZWnbELdSAvATFW/MbxaXw== dependencies: commander "2" iconv-lite "0.4" @@ -5659,7 +5555,7 @@ d3-dsv@^1.0.8: d@1: version "1.0.0" - resolved "http://registry.npmjs.org/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= dependencies: es5-ext "^0.10.9" @@ -5688,9 +5584,9 @@ data-urls@^1.0.0: whatwg-url "^7.0.0" date-fns@^1.27.2: - version "1.29.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" - integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== date-now@^0.1.4: version "0.1.4" @@ -5707,14 +5603,14 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= -debug@*: - version "4.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== +debug@*, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.1, debug@^2.6.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.1, debug@^2.6.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -5735,13 +5631,6 @@ debug@^3, debug@^3.0, debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -5792,7 +5681,7 @@ deep-metrics@^0.0.1: dependencies: semver "^5.3.0" -deepmerge@3.2.0: +deepmerge@3.2.0, deepmerge@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e" integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow== @@ -5802,11 +5691,6 @@ deepmerge@^1.5.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== -deepmerge@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" - integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== - default-require-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" @@ -5883,9 +5767,9 @@ delegates@^1.0.0: integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= denque@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.0.tgz#79e2f0490195502107f24d9553f374837dabc916" - integrity sha512-gh513ac7aiKrAgjiIBWZG0EASyDF9p4JMWwKA8YU5s9figrL5SRNEMT6FDynsegakuhWd1wVqTvqvqAoDxw7wQ== + version "1.4.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" + integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== depd@^1.1.2, depd@~1.1.2: version "1.1.2" @@ -5910,6 +5794,11 @@ destroy@^1.0.4, destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" @@ -5924,7 +5813,7 @@ detect-indent@^5.0.0: detect-installed@^2.0.4: version "2.0.4" - resolved "http://registry.npmjs.org/detect-installed/-/detect-installed-2.0.4.tgz#a0850465e7c3ebcff979d6b6535ad344b80dd7c5" + resolved "https://registry.yarnpkg.com/detect-installed/-/detect-installed-2.0.4.tgz#a0850465e7c3ebcff979d6b6535ad344b80dd7c5" integrity sha1-oIUEZefD68/5eda2U1rTRLgN18U= dependencies: get-installed-path "^2.0.3" @@ -5964,14 +5853,14 @@ diff@^3.1.0: diffie-hellman@^5.0.0: version "5.0.3" - resolved "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" miller-rabin "^4.0.0" randombytes "^2.0.0" -dir-glob@^2.0.0: +dir-glob@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== @@ -5979,6 +5868,13 @@ dir-glob@^2.0.0: arrify "^1.0.1" path-type "^3.0.0" +dir-glob@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + docsearch.js@^2.5.2: version "2.6.2" resolved "https://registry.yarnpkg.com/docsearch.js/-/docsearch.js-2.6.2.tgz#cb36a97aeac8a8d31eed5915cdee808a2248b41c" @@ -5994,7 +5890,7 @@ docsearch.js@^2.5.2: doctrine@1.5.0: version "1.5.0" - resolved "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= dependencies: esutils "^2.0.2" @@ -6007,7 +5903,14 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" -dom-converter@~0.2: +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-converter@^0.2: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== @@ -6020,12 +5923,12 @@ dom-event-types@^1.0.0: integrity sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ== dom-serializer@0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" - integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== dependencies: - domelementtype "~1.1.1" - entities "~1.1.1" + domelementtype "^1.3.0" + entities "^1.1.1" dom-urls@^1.1.0: version "1.1.0" @@ -6044,16 +5947,11 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1: +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== -domelementtype@~1.1.1: - version "1.1.3" - resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" - integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= - domexception@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" @@ -6061,17 +5959,10 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" -domhandler@2.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" - integrity sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ= - dependencies: - domelementtype "1" - -domutils@1.1: - version "1.1.6" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" - integrity sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU= +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== dependencies: domelementtype "1" @@ -6083,6 +5974,14 @@ domutils@1.5.1: dom-serializer "0" domelementtype "1" +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + dot-prop@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" @@ -6090,7 +5989,7 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" -dot-prop@^4.1.0, dot-prop@^4.1.1, dot-prop@^4.2.0: +dot-prop@^4.1.0, dot-prop@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== @@ -6104,13 +6003,13 @@ duplexer3@^0.1.4: duplexer@^0.1.1: version "0.1.1" - resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= duplexify@^3.4.2, duplexify@^3.6.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" - integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== dependencies: end-of-stream "^1.0.0" inherits "^2.0.1" @@ -6126,14 +6025,12 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" editorconfig@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.2.tgz#047be983abb9ab3c2eefe5199cb2b7c5689f0702" - integrity sha512-GWjSI19PVJAM9IZRGOS+YKI8LN+/sjkSjNyvxL5ucqP9/IqtYNXBaQ/6c/hkPNYQHyOHra2KoXZI/JVpuqwmcQ== + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== dependencies: - "@types/node" "^10.11.7" - "@types/semver" "^5.5.0" commander "^2.19.0" - lru-cache "^4.1.3" + lru-cache "^4.1.5" semver "^5.6.0" sigmund "^1.0.1" @@ -6147,15 +6044,10 @@ ejs@^2.6.1: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.47: - version "1.3.88" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.88.tgz#f36ab32634f49ef2b0fdc1e82e2d1cc17feb29e7" - integrity sha512-UPV4NuQMKeUh1S0OWRvwg0PI8ASHN9kBC8yDTk1ROXLC85W5GnhTRu/MZu3Teqx3JjlQYuckuHYXSUSgtb3J+A== - -electron-to-chromium@^1.3.113: - version "1.3.113" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9" - integrity sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g== +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.127, electron-to-chromium@^1.3.47: + version "1.3.127" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.127.tgz#9b34d3d63ee0f3747967205b953b25fe7feb0e10" + integrity sha512-1o25iFRf/dbgauTWalEzmD1EmRN3a2CzP/K7UVpYLEBduk96LF0FyUdCcf4Ry2mAWJ1VxyblFjC93q6qlLwA2A== elegant-spinner@^1.0.1: version "1.0.1" @@ -6182,6 +6074,11 @@ emitter-listener@^1.1.1: dependencies: shimmer "^1.2.0" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -6220,7 +6117,7 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: memory-fs "^0.4.0" tapable "^1.0.0" -entities@~1.1.1: +entities@^1.1.1, 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== @@ -6257,18 +6154,19 @@ error-inject@^1.0.0: resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= -es-abstract@^1.5.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== +es-abstract@^1.5.1, es-abstract@^1.7.0: + 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.1.1" + es-to-primitive "^1.2.0" function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" + has "^1.0.3" + is-callable "^1.1.4" is-regex "^1.0.4" + object-keys "^1.0.12" -es-to-primitive@^1.1.1: +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== @@ -6278,13 +6176,13 @@ es-to-primitive@^1.1.1: is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.46" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572" - integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw== + version "0.10.50" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" + integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw== dependencies: es6-iterator "~2.0.3" es6-symbol "~3.1.1" - next-tick "1" + next-tick "^1.0.0" es6-iterator@~2.0.3: version "2.0.3" @@ -6296,9 +6194,9 @@ es6-iterator@~2.0.3: es6-symbol "^3.1.1" es6-promise@^4.0.3, es6-promise@^4.0.5, es6-promise@^4.1.0, es6-promise@^4.2.4: - version "4.2.5" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" - integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== + version "4.2.6" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" + integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q== es6-promisify@^5.0.0: version "5.0.0" @@ -6342,9 +6240,16 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.2.0.tgz#70b946b629cd0e3e98233fd9ecde4cb9778de96c" + integrity sha512-y0uWc/FRfrHhpPZCYflWC8aE0KRJRY04rdZVfl8cL3sEZmOYyaBdhdlQPjKZBnuRMyLVK+JUZr7HaZFClQiH4w== + dependencies: + get-stdin "^6.0.0" + eslint-config-standard@^11.0.0: version "11.0.0" - resolved "http://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz#87ee0d3c9d95382dc761958cbb23da9eea31e0ba" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz#87ee0d3c9d95382dc761958cbb23da9eea31e0ba" integrity sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw== eslint-friendly-formatter@^4.0.1: @@ -6359,7 +6264,7 @@ eslint-friendly-formatter@^4.0.1: strip-ansi "^4.0.0" text-table "^0.2.0" -eslint-import-resolver-node@^0.3.1: +eslint-import-resolver-node@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== @@ -6368,9 +6273,9 @@ eslint-import-resolver-node@^0.3.1: resolve "^1.5.0" eslint-loader@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.1.tgz#2a9251523652430bfdd643efdb0afc1a2a89546a" - integrity sha512-1GrJFfSevQdYpoDzx8mEE2TDWsb/zmFuY09l6hURg1AeFIKQOvZ+vH0UPjzmd1CZIbfTV5HUkMeBmFiDBkgIsQ== + version "2.1.2" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.2.tgz#453542a1230d6ffac90e4e7cb9cadba9d851be68" + integrity sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg== dependencies: loader-fs-cache "^1.0.0" loader-utils "^1.0.2" @@ -6378,33 +6283,34 @@ eslint-loader@^2.0.0: object-hash "^1.1.4" rimraf "^2.6.1" -eslint-module-utils@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= +eslint-module-utils@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" + integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw== dependencies: debug "^2.6.8" - pkg-dir "^1.0.0" + pkg-dir "^2.0.0" eslint-plugin-import@^2.12.0, eslint-plugin-import@^2.13.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== + version "2.17.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.17.2.tgz#d227d5c6dc67eca71eb590d2bb62fb38d86e9fcb" + integrity sha512-m+cSVxM7oLsIpmwNn2WXTJoReOF9f/CtLMo7qOVmKd1KntBy0hEcuNZ3erTmWjx+DxRO0Zcrm5KwAvI9wHcV5g== dependencies: + array-includes "^3.0.3" contains-path "^0.1.0" - debug "^2.6.8" + debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" read-pkg-up "^2.0.0" - resolve "^1.6.0" + resolve "^1.10.0" eslint-plugin-node@^6.0.1: version "6.0.1" - resolved "http://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz#bf19642298064379315d7a4b2a75937376fa05e4" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz#bf19642298064379315d7a4b2a75937376fa05e4" integrity sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw== dependencies: ignore "^3.3.6" @@ -6412,6 +6318,13 @@ eslint-plugin-node@^6.0.1: resolve "^1.3.3" semver "^5.4.1" +eslint-plugin-prettier@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz#19d521e3981f69dd6d14f64aec8c6a6ac6eb0b0d" + integrity sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ== + dependencies: + prettier-linter-helpers "^1.0.0" + eslint-plugin-promise@^3.7.0: version "3.8.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621" @@ -6452,14 +6365,19 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== +eslint-scope@^4.0.0, eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" @@ -6467,7 +6385,7 @@ eslint-visitor-keys@^1.0.0: eslint@^4.16.0: version "4.19.1" - resolved "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== dependencies: ajv "^5.3.0" @@ -6493,30 +6411,81 @@ eslint@^4.16.0: js-yaml "^3.9.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.4" - minimatch "^3.0.2" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + +eslint@^5.0.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^7.0.0" progress "^2.0.0" - regexpp "^1.0.1" - require-uncached "^1.0.3" - semver "^5.3.0" + regexpp "^2.0.1" + semver "^5.5.1" strip-ansi "^4.0.0" - strip-json-comments "~2.0.1" - table "4.0.2" - text-table "~0.2.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" espree@^3.5.2, espree@^3.5.4: version "3.5.4" - resolved "http://registry.npmjs.org/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== dependencies: acorn "^5.5.0" acorn-jsx "^3.0.0" +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -6532,7 +6501,7 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.0: +esquery@^1.0.0, esquery@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== @@ -6563,19 +6532,24 @@ etag@~1.8.1: eventemitter2@1.0.5: version "1.0.5" - resolved "http://registry.npmjs.org/eventemitter2/-/eventemitter2-1.0.5.tgz#f983610517b1737c0b9dc643beca93893c04df18" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-1.0.5.tgz#f983610517b1737c0b9dc643beca93893c04df18" integrity sha1-+YNhBRexc3wLncZDvsqTiTwE3xg= eventemitter2@~0.4.14: version "0.4.14" - resolved "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas= -events@^1.0.0, events@^1.1.0: +events@^1.1.0: version "1.1.1" - resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -6589,7 +6563,7 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== -execa@0.10.0, execa@^0.10.0: +execa@0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== @@ -6680,7 +6654,7 @@ expand-brackets@^2.1.4: expand-range@^1.8.1: version "1.8.2" - resolved "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= dependencies: fill-range "^2.1.0" @@ -6755,14 +6729,14 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.1, extend@~3.0.2: +extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== external-editor@^2.0.4: version "2.2.0" - resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== dependencies: chardet "^0.4.0" @@ -6806,17 +6780,7 @@ extract-from-css@^0.4.4: dependencies: css "^2.1.0" -extract-zip@1.6.6: - version "1.6.6" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" - integrity sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw= - dependencies: - concat-stream "1.6.0" - debug "2.6.9" - mkdirp "0.5.0" - yauzl "2.4.1" - -extract-zip@^1.6.5: +extract-zip@1.6.7, extract-zip@^1.6.5: version "1.6.7" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= @@ -6843,7 +6807,7 @@ eyes@0.1.x: fast-deep-equal@^1.0.0: version "1.1.0" - resolved "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= fast-deep-equal@^2.0.1: @@ -6851,10 +6815,15 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-glob@^2.0.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" - integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== + version "2.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295" + integrity sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w== dependencies: "@mrmlnc/readdir-enhanced" "^2.2.1" "@nodelib/fs.stat" "^1.1.2" @@ -6897,7 +6866,14 @@ fd-slicer@~1.0.1: dependencies: pend "~1.2.0" -figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== @@ -6925,9 +6901,16 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + file-loader@^1.1.11: version "1.1.11" - resolved "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" integrity sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg== dependencies: loader-utils "^1.0.2" @@ -6974,7 +6957,7 @@ fill-range@^4.0.0: finalhandler@1.1.1: version "1.1.1" - resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== dependencies: debug "2.6.9" @@ -7012,12 +6995,12 @@ find-cache-dir@^1.0.0: pkg-dir "^2.0.0" find-cache-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" - integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== dependencies: commondir "^1.0.1" - make-dir "^1.0.0" + make-dir "^2.0.0" pkg-dir "^3.0.0" find-up@^1.0.0: @@ -7042,6 +7025,16 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" @@ -7052,6 +7045,20 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" @@ -7063,12 +7070,12 @@ flexbuffer@0.0.6: integrity sha1-A5/fI/iCPkQMOPMnfm/vEXQhWzA= flush-write-stream@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" - integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== dependencies: - inherits "^2.0.1" - readable-stream "^2.0.4" + inherits "^2.0.3" + readable-stream "^2.3.6" for-in@^0.1.3: version "0.1.8" @@ -7104,7 +7111,7 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@~2.3.1, form-data@~2.3.2: +form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== @@ -7154,7 +7161,7 @@ fs-extra@4.0.1: fs-extra@^1.0.0: version "1.0.0" - resolved "http://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= dependencies: graceful-fs "^4.1.2" @@ -7210,21 +7217,13 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - fsevents@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" - integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" + nan "^2.12.1" + node-pre-gyp "^0.12.0" fstream@^1.0.0, fstream@^1.0.2: version "1.0.11" @@ -7310,9 +7309,14 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + get-stream@^3.0.0: version "3.0.0" - resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= get-stream@^4.0.0, get-stream@^4.1.0: @@ -7434,19 +7438,7 @@ glob@7.0.x: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1: +glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -7465,11 +7457,6 @@ global-dirs@^0.1.0: dependencies: ini "^1.3.4" -global-modules-path@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.1.tgz#e541f4c800a1a8514a990477b267ac67525b9931" - integrity sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg== - global-modules@1.0.0, global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -7498,10 +7485,10 @@ global@^4.3.2: min-document "^2.19.0" process "~0.5.1" -globals@^11.0.1, globals@^11.1.0: - version "11.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" - integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== +globals@^11.0.1, globals@^11.1.0, globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^9.18.0: version "9.18.0" @@ -7510,7 +7497,7 @@ globals@^9.18.0: globby@^6.1.0: version "6.1.0" - resolved "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= dependencies: array-union "^1.0.1" @@ -7532,12 +7519,12 @@ globby@^7.1.1: slash "^1.0.0" globby@^8.0.1: - version "8.0.1" - resolved "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" - integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== dependencies: array-union "^1.0.1" - dir-glob "^2.0.0" + dir-glob "2.0.0" fast-glob "^2.0.2" glob "^7.1.2" ignore "^3.3.5" @@ -7562,7 +7549,7 @@ good-listener@^1.2.2: got@^6.7.1: version "6.7.1" - resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= dependencies: create-error-class "^3.0.0" @@ -7583,21 +7570,21 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== graphql-tag@^2.9.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" - integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== + version "2.10.1" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" + integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== graphql@^0.13.2: version "0.13.2" - resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== dependencies: iterall "^1.2.1" gray-matter@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.1.tgz#375263c194f0d9755578c277e41b1c1dfdf22c7d" - integrity sha512-p0MADBEBl1CohV7nRZ8sVinBexEe3CKVhh0A0QIHKpcbRoxB0VgeMpRPjW/HBHIPLAKrpIIIm5mZ6hKu3E+iQg== + version "4.0.2" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.2.tgz#9aa379e3acaf421193fce7d2a28cebd4518ac454" + integrity sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw== dependencies: js-yaml "^3.11.0" kind-of "^6.0.2" @@ -7610,19 +7597,19 @@ growly@^1.3.0: integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= gzip-size@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" - integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA== + version "5.1.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.0.tgz#2db0396c71f5c902d5cf6b52add5030b93c99bd2" + integrity sha512-wfSnvypBDRW94v5W3ckvvz/zFUNdJ81VgOP6tE4bPpRUcc0wGqU+y0eZjJEvKxwubJFix6P84sE8M51YWLT7rQ== dependencies: duplexer "^0.1.1" - pify "^3.0.0" + pify "^4.0.1" handlebars@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.0.tgz#0d6a6f34ff1f63cecec8423aa4169827bf787c3a" - integrity sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w== + version "4.1.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" + integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== dependencies: - async "^2.5.0" + neo-async "^2.6.0" optimist "^0.6.1" source-map "^0.6.1" optionalDependencies: @@ -7633,14 +7620,6 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - har-validator@~5.1.0: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" @@ -7661,11 +7640,6 @@ has-flag@^1.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -7712,7 +7686,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1: +has@^1.0.1, 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== @@ -7764,7 +7738,7 @@ hmac-drbg@^1.0.0: hoek@4.x.x: version "4.2.1" - resolved "http://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== hogan.js@^3.0.2: @@ -7784,9 +7758,9 @@ home-or-tmp@^2.0.0: os-tmpdir "^1.0.1" homedir-polyfill@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" - integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw= + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== dependencies: parse-passwd "^1.0.0" @@ -7832,7 +7806,7 @@ html-minifier@^3.2.3: html-webpack-plugin@^3.2.0: version "3.2.0" - resolved "http://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= dependencies: html-minifier "^3.2.3" @@ -7843,23 +7817,25 @@ html-webpack-plugin@^3.2.0: toposort "^1.0.0" util.promisify "1.0.0" -htmlparser2@~3.3.0: - version "3.3.0" - resolved "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe" - integrity sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4= +htmlparser2@^3.3.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== dependencies: - domelementtype "1" - domhandler "2.1" - domutils "1.1" - readable-stream "1.0" + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" http-assert@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.0.tgz#0e550b4fca6adf121bbeed83248c17e62f593a9a" - integrity sha512-tPVv62a6l3BbQoM/N5qo969l0OFxqpnQzNUPeYfTP6Spo4zkgWeDBD1D5thI7sDLg7jCCihXTLB0X8UtdyAy8A== + version "1.4.1" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" + integrity sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw== dependencies: deep-equal "~1.0.1" - http-errors "~1.7.1" + http-errors "~1.7.2" http-cache-semantics@^3.8.1: version "3.8.1" @@ -7868,7 +7844,7 @@ http-cache-semantics@^3.8.1: http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" - resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= dependencies: depd "~1.1.2" @@ -7876,14 +7852,14 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-errors@^1.6.1, http-errors@^1.6.3, http-errors@~1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.1.tgz#6a4ffe5d35188e1c39f872534690585852e1f027" - integrity sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw== +http-errors@^1.6.1, http-errors@^1.6.3, http-errors@~1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== dependencies: depd "~1.1.2" inherits "2.0.3" - setprototypeof "1.1.0" + setprototypeof "1.1.1" statuses ">= 1.5.0 < 2" toidentifier "1.0.0" @@ -7956,9 +7932,9 @@ icss-utils@^2.1.0: postcss "^6.0.1" ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== iferr@^0.1.5: version "0.1.5" @@ -7977,6 +7953,11 @@ ignore@^3.3.3, ignore@^3.3.5, ignore@^3.3.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" @@ -7988,9 +7969,9 @@ immediate@~3.0.5: integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= immutable-tuple@^0.4.9: - version "0.4.9" - resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" - integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== + version "0.4.10" + resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.10.tgz#e0b1625384f514084a7a84b749a3bb26e9179929" + integrity sha512-45jheDbc3Kr5Cw8EtDD+4woGRUV0utIrJBZT8XH0TPZRfm8tzT0/sLGGzyyCCFqFMG5Pv5Igf3WY/arn6+8V9Q== import-cwd@^2.0.0: version "2.1.0" @@ -8007,6 +7988,14 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-from@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" @@ -8124,10 +8113,10 @@ inquirer@^3.0.6, inquirer@^3.3.0: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^6.2.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" - integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== +inquirer@^6.2.0, inquirer@^6.2.2: + version "6.3.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.3.1.tgz#7a413b5e7950811013a3db491c61d1f3b776e8e7" + integrity sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA== dependencies: ansi-escapes "^3.2.0" chalk "^2.4.2" @@ -8140,13 +8129,13 @@ inquirer@^6.2.0: run-async "^2.2.0" rxjs "^6.4.0" string-width "^2.1.0" - strip-ansi "^5.0.0" + strip-ansi "^5.1.0" through "^2.3.6" interpret@^1.0.0, interpret@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== invariant@^2.2.0, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" @@ -8166,9 +8155,9 @@ invert-kv@^2.0.0: integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== ioredis@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.2.0.tgz#f0f76fa5067a51c365ef1411f6572478a825971d" - integrity sha512-PdxZGNJBfPiR2RI6DkqmiacL1+ML3gaqEiaC5QXWQt9eSTlGj+BwDCct0s8irn1ed8GyzAHTzcjvU9fmnl6D7A== + version "4.9.0" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.9.0.tgz#0c52de498363309ebd48b5f6695d9d432b0f6669" + integrity sha512-YzfCLsN++Ct43QqGK9CWxaEK6OUvJ7rnENieAPNw3DVp/oF2uBrP2NJChbhO74Ng3LWA+i5zdIEUsZYr6dKDIQ== dependencies: cluster-key-slot "^1.0.6" debug "^3.1.0" @@ -8179,17 +8168,17 @@ ioredis@^4.0.0: redis-commands "1.4.0" redis-errors "^1.2.0" redis-parser "^3.0.0" - standard-as-callback "^1.0.0" + standard-as-callback "^2.0.1" ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" - integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= +ipaddr.js@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" + integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== is-absolute-url@^2.0.0: version "2.1.0" @@ -8227,26 +8216,12 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= - dependencies: - builtin-modules "^1.0.0" - -is-callable@^1.1.3, is-callable@^1.1.4: +is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== -is-ci@1.0.10: - version "1.0.10" - resolved "http://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" - integrity sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4= - dependencies: - ci-info "^1.0.0" - -is-ci@^1.0.10, is-ci@^1.1.0: +is-ci@1.2.1, is-ci@^1.0.10, is-ci@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== @@ -8356,9 +8331,9 @@ is-fullwidth-code-point@^2.0.0: integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-generator-fn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.0.0.tgz#038c31b774709641bda678b1f06a4e3227c10b3e" - integrity sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g== + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-generator-function@^1.0.7: version "1.0.7" @@ -8380,9 +8355,9 @@ is-glob@^3.1.0: is-extglob "^2.1.0" is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" @@ -8420,7 +8395,7 @@ is-number@^4.0.0: is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" - resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-path-cwd@^1.0.0: @@ -8454,6 +8429,13 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-plain-object@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928" + integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg== + dependencies: + isobject "^4.0.0" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -8508,11 +8490,6 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-subset@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" - integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= - is-svg@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" @@ -8560,9 +8537,9 @@ is-wsl@^1.1.0: integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= is@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" - integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= + version "3.3.0" + resolved "https://registry.yarnpkg.com/is/-/is-3.3.0.tgz#61cff6dd3c4193db94a3d62582072b44e5645d79" + integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg== isarray@0.0.1: version "0.0.1" @@ -8603,6 +8580,11 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isobject@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" + integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== + isomorphic-fetch@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" @@ -8617,73 +8599,73 @@ isstream@0.1.x, isstream@~0.1.2: integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= istanbul-api@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.1.tgz#194b773f6d9cbc99a9258446848b0f988951c4d0" - integrity sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw== + version "2.1.5" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.5.tgz#697b95ec69856c278aacafc0f86ee7392338d5b5" + integrity sha512-meYk1BwDp59Pfse1TvPrkKYgVqAufbdBLEVoqvu/hLLKSaQ054ZTksbNepyc223tMnWdm6AdK2URIJJRqdP87g== dependencies: async "^2.6.1" compare-versions "^3.2.1" fileset "^2.0.3" - istanbul-lib-coverage "^2.0.3" - istanbul-lib-hook "^2.0.3" - istanbul-lib-instrument "^3.1.0" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.2" - istanbul-reports "^2.1.1" - js-yaml "^3.12.0" - make-dir "^1.3.0" + istanbul-lib-coverage "^2.0.4" + istanbul-lib-hook "^2.0.6" + istanbul-lib-instrument "^3.2.0" + istanbul-lib-report "^2.0.7" + istanbul-lib-source-maps "^3.0.5" + istanbul-reports "^2.2.3" + js-yaml "^3.13.0" + make-dir "^2.1.0" minimatch "^3.0.4" once "^1.4.0" -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" - integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw== +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#927a354005d99dd43a24607bb8b33fd4e9aca1ad" + integrity sha512-LXTBICkMARVgo579kWDm8SqfB6nvSDKNqIOBEjmJRnL04JvoMHCYGWaMddQnseJYtkEuEvO/sIcOxPLk9gERug== -istanbul-lib-hook@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz#e0e581e461c611be5d0e5ef31c5f0109759916fb" - integrity sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA== +istanbul-lib-hook@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.6.tgz#5baa6067860a38290aef038b389068b225b01b7d" + integrity sha512-829DKONApZ7UCiPXcOYWSgkFXa4+vNYoNOt3F+4uDJLKL1OotAoVwvThoEj1i8jmOj7odbYcR3rnaHu+QroaXg== dependencies: append-transform "^1.0.0" -istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" - integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA== +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.2.0.tgz#c549208da8a793f6622257a2da83e0ea96ae6a93" + integrity sha512-06IM3xShbNW4NgZv5AP4QH0oHqf1/ivFo8eFys0ZjPXHGldHJQWb3riYOKXqmOqfxXBfxu4B+g/iuhOPZH0RJg== dependencies: "@babel/generator" "^7.0.0" "@babel/parser" "^7.0.0" "@babel/template" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - istanbul-lib-coverage "^2.0.3" - semver "^5.5.0" + istanbul-lib-coverage "^2.0.4" + semver "^6.0.0" -istanbul-lib-report@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4" - integrity sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA== +istanbul-lib-report@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.7.tgz#370d80d433c4dbc7f58de63618f49599c74bd954" + integrity sha512-wLH6beJBFbRBLiTlMOBxmb85cnVM1Vyl36N48e4e/aTKSM3WbOx7zbVIH1SQ537fhhsPbX0/C5JB4qsmyRXXyA== dependencies: - istanbul-lib-coverage "^2.0.3" - make-dir "^1.3.0" + istanbul-lib-coverage "^2.0.4" + make-dir "^2.1.0" supports-color "^6.0.0" -istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz#f1e817229a9146e8424a28e5d69ba220fda34156" - integrity sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ== +istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.5.tgz#1d9ee9d94d2633f15611ee7aae28f9cac6d1aeb9" + integrity sha512-eDhZ7r6r1d1zQPVZehLc3D0K14vRba/eBYkz3rw16DLOrrTzve9RmnkcwrrkWVgO1FL3EK5knujVe5S8QHE9xw== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.3" - make-dir "^1.3.0" + istanbul-lib-coverage "^2.0.4" + make-dir "^2.1.0" rimraf "^2.6.2" source-map "^0.6.1" -istanbul-reports@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9" - integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw== +istanbul-reports@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.3.tgz#14e0d00ecbfa9387757999cf36599b88e9f2176e" + integrity sha512-T6EbPuc8Cb620LWAYyZ4D8SSn06dY9i1+IgUX2lTH8gbwflMc9Obd33zHTyNX653ybjpamAHS9toKS3E6cGhTw== dependencies: handlebars "^4.1.0" @@ -9066,14 +9048,14 @@ joi@^11.1.1: topo "2.x.x" js-base64@^2.1.8, js-base64@^2.1.9: - version "2.4.9" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" - integrity sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ== + version "2.5.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" + integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== js-beautify@^1.6.12, js-beautify@^1.6.14: - version "1.9.0" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.9.0.tgz#2562fcdee340f9f962ae2ec4a8a40e7aaa6d964f" - integrity sha512-P0skmY4IDjfLiVrx+GLDeme8w5G0R1IGXgccVU5HP2VM3lRblH7qN2LTea5vZAxrDjpZBD0Jv+ahpjwVcbz/rw== + version "1.9.1" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.9.1.tgz#6f9ef915f5d8d92b9f907606fce63795884c8040" + integrity sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ== dependencies: config-chain "^1.1.12" editorconfig "^0.15.2" @@ -9101,18 +9083,10 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.11.0, js-yaml@^3.9.0, js-yaml@^3.9.1: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.12.0: - version "3.12.2" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.2.tgz#ef1d067c5a9d9cb65bd72f285b5d8105c77f14fc" - integrity sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q== +js-yaml@^3.11.0, js-yaml@^3.13.0, js-yaml@^3.9.0, js-yaml@^3.9.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -9164,7 +9138,7 @@ jsdom@^11.5.1: jsesc@^1.3.0: version "1.3.0" - resolved "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= jsesc@^2.5.1: @@ -9174,7 +9148,7 @@ jsesc@^2.5.1: jsesc@~0.5.0: version "0.5.0" - resolved "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: @@ -9216,19 +9190,19 @@ json5@2.x, json5@^2.1.0: json5@^0.5.0, json5@^0.5.1: version "0.5.1" - resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= json5@^1.0.1: version "1.0.1" - resolved "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: minimist "^1.2.0" jsonfile@^2.1.0: version "2.4.0" - resolved "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= optionalDependencies: graceful-fs "^4.1.6" @@ -9264,7 +9238,7 @@ jsprim@^1.2.2: kew@^0.7.0: version "0.7.0" - resolved "http://registry.npmjs.org/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" + resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" integrity sha1-edk9LTM2PW/dKXCzNdkUGtWR15s= keygrip@~1.0.3: @@ -9309,9 +9283,9 @@ klaw@^1.0.0: graceful-fs "^4.1.9" kleur@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.2.tgz#83c7ec858a41098b613d5998a7b653962b504f68" - integrity sha512-3h7B2WRT5LNXOtQiAaWonilegHcPSf9nLVXlSTci8lu1dZUuui61+EsPEZqSVxY7rXYmB2DVKMQILxaO5WL61Q== + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== koa-compose@^3.0.0, koa-compose@^3.2.1: version "3.2.1" @@ -9360,7 +9334,7 @@ koa-range@^0.3.0: koa-send@^4.1.3: version "4.1.3" - resolved "http://registry.npmjs.org/koa-send/-/koa-send-4.1.3.tgz#0822207bbf5253a414c8f1765ebc29fa41353cb6" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-4.1.3.tgz#0822207bbf5253a414c8f1765ebc29fa41353cb6" integrity sha512-3UetMBdaXSiw24qM2Mx5mKmxLKw5ZTPRjACjfhK6Haca55RKm9hr/uHDrkrxhSl5/S1CKI/RivZVIopiatZuTA== dependencies: debug "^2.6.3" @@ -9388,9 +9362,9 @@ koa-webpack@^4.0.0: webpack-log "^1.1.1" koa@^2.4.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.6.2.tgz#57ba4d049b0a99cae0d594e6144e2931949a7ce1" - integrity sha512-KdnBFhTgh9ysMMoYe4J4fLvaKjT7mF3nRYV8MjxLzx6qywFNeptqi4xevyUltg1fZl2CFJ+HeLXuCGx07Yvl/A== + version "2.7.0" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.7.0.tgz#7e00843506942b9d82c6cc33749f657c6e5e7adf" + integrity sha512-7ojD05s2Q+hFudF8tDLZ1CpCdVZw8JQELWSkcfG9bdtoTDzMmkRF6BQBU7JzIzCCOY3xd3tftiy/loHBUYaY2Q== dependencies: accepts "^1.3.5" cache-content-type "^1.0.0" @@ -9457,9 +9431,9 @@ lcid@^2.0.0: invert-kv "^2.0.0" lean-he@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lean-he/-/lean-he-2.1.0.tgz#d46582c5ac2d0ca52db1df4f0150f45f38197461" - integrity sha512-sKR8hsOpYHpO4iG+RS4C+dCbvoSnlkMFE9Xk0XsTxjYxrgDuqflZPsRZ3+jC7Vy95UEAczKQVA6Qt5O78ss8iQ== + version "2.1.2" + resolved "https://registry.yarnpkg.com/lean-he/-/lean-he-2.1.2.tgz#50c2422f0ca42f6737c9c1988b555cf00ebc712f" + integrity sha512-g/cq01j/rnv7JWoxFmeLgJdd/CucksyDtS+pyepO89EdT0O4KfHJokOVz/xQ4mvjKJzcrj87Q3/s2ESou90WCQ== left-pad@^1.3.0: version "1.3.0" @@ -9467,25 +9441,25 @@ left-pad@^1.3.0: integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== lerna@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.13.1.tgz#feaff562176f304bd82329ca29ce46ab6c033463" - integrity sha512-7kSz8LLozVsoUNTJzJzy+b8TnV9YdviR2Ee2PwGZSlVw3T1Rn7kOAPZjEi+3IWnOPC96zMPHVmjCmzQ4uubalw== - dependencies: - "@lerna/add" "3.13.1" - "@lerna/bootstrap" "3.13.1" - "@lerna/changed" "3.13.1" - "@lerna/clean" "3.13.1" + version "3.13.4" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.13.4.tgz#03026c11c5643f341fda42e4fb1882e2df35e6cb" + integrity sha512-qTp22nlpcgVrJGZuD7oHnFbTk72j2USFimc2Pj4kC0/rXmcU2xPtCiyuxLl8y6/6Lj5g9kwEuvKDZtSXujjX/A== + dependencies: + "@lerna/add" "3.13.3" + "@lerna/bootstrap" "3.13.3" + "@lerna/changed" "3.13.4" + "@lerna/clean" "3.13.3" "@lerna/cli" "3.13.0" - "@lerna/create" "3.13.1" - "@lerna/diff" "3.13.1" - "@lerna/exec" "3.13.1" - "@lerna/import" "3.13.1" - "@lerna/init" "3.13.1" - "@lerna/link" "3.13.1" - "@lerna/list" "3.13.1" - "@lerna/publish" "3.13.1" - "@lerna/run" "3.13.1" - "@lerna/version" "3.13.1" + "@lerna/create" "3.13.3" + "@lerna/diff" "3.13.3" + "@lerna/exec" "3.13.3" + "@lerna/import" "3.13.4" + "@lerna/init" "3.13.3" + "@lerna/link" "3.13.3" + "@lerna/list" "3.13.3" + "@lerna/publish" "3.13.4" + "@lerna/run" "3.13.3" + "@lerna/version" "3.13.4" import-local "^1.0.0" npmlog "^4.1.2" @@ -9594,7 +9568,7 @@ listr@0.12.0: load-json-file@^1.0.0: version "1.1.0" - resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= dependencies: graceful-fs "^4.1.2" @@ -9605,7 +9579,7 @@ load-json-file@^1.0.0: load-json-file@^2.0.0: version "2.0.0" - resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= dependencies: graceful-fs "^4.1.2" @@ -9629,17 +9603,17 @@ load-script@^1.0.0: integrity sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ= loader-fs-cache@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc" - integrity sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw= + version "1.0.2" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" + integrity sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw== dependencies: find-cache-dir "^0.1.1" mkdirp "0.5.1" loader-runner@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" - integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== loader-utils@^0.2.16: version "0.2.17" @@ -9652,13 +9626,13 @@ loader-utils@^0.2.16: object-assign "^4.0.1" loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== dependencies: - big.js "^3.1.3" + big.js "^5.2.2" emojis-list "^2.0.0" - json5 "^0.5.0" + json5 "^1.0.1" localforage@^1.7.2: version "1.7.3" @@ -9693,26 +9667,16 @@ lodash._reinterpolate@~3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= -lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= -lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.5.0: +lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -9738,6 +9702,11 @@ lodash.isequal@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= +lodash.ismatch@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" + integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -9753,11 +9722,6 @@ lodash.merge@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ== -lodash.mergewith@^4.6.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== - lodash.once@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" @@ -9798,11 +9762,21 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= +lodash.unescape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" + integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= +lodash.uniqueid@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.uniqueid/-/lodash.uniqueid-4.0.1.tgz#3268f26a7c88e4f4b1758d679271814e31fa5b26" + integrity sha1-MmjyanyI5PSxdY1nknGBTjH6WyY= + lodash@4.17.11, lodash@4.x, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.9.0, lodash@~4.17.10: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -9872,7 +9846,7 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== -lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3: +lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3, lru-cache@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== @@ -9887,27 +9861,35 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -macos-release@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.0.0.tgz#7dddf4caf79001a851eb4fba7fb6034f251276ab" - integrity sha512-iCM3ZGeqIzlrH7KxYK+fphlJpCCczyHXc+HhRVbEu9uNTCrzYJjvvtefzeKTCVHd5AP/aD/fzC80JZ4ZP+dQ/A== +macos-release@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.2.0.tgz#ab58d55dd4714f0a05ad4b0e90f4370fef5cdea8" + integrity sha512-iV2IDxZaX8dIcM7fG6cI46uNmHUxHE4yN+Z8tKHAW1TBPMZDIKHf/3L+YnOuj/FK9il14UaVdHmiQ1tsi90ltA== "magento2-rest-client@github:DivanteLtd/magento2-rest-client": - version "0.0.7" - resolved "https://codeload.github.com/DivanteLtd/magento2-rest-client/tar.gz/77b217ba140a1bc484697e1d141676b8b5c83933" + version "0.0.8" + resolved "https://codeload.github.com/DivanteLtd/magento2-rest-client/tar.gz/30a67752e65a8d02eac3c7caa1ace51ea2c5f815" dependencies: humps "^1.1.0" oauth-1.0a "^1.0.1" request "^2.72.0" winston "^2.2.0" -make-dir@^1.0.0, make-dir@^1.3.0: +make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" +make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + make-error@1.x, make-error@^1.1.1: version "1.3.5" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" @@ -9937,6 +9919,11 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -9982,9 +9969,9 @@ markdown-it-emoji@^1.4.0: integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw= markdown-it-table-of-contents@^0.4.0: - version "0.4.3" - resolved "https://registry.yarnpkg.com/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.3.tgz#6453925a76e49b9b3d9569a0d89f1c2168b46982" - integrity sha512-x/OdaRzLYxAjmB+jIVlXuE3nX7tZTLDQxm58RkgjTLyQ+I290jYQvPS9cJjVN6SM3U6K6CHKYNgUtPNZmLblYQ== + version "0.4.4" + resolved "https://registry.yarnpkg.com/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz#3dc7ce8b8fc17e5981c77cc398d1782319f37fbc" + integrity sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw== markdown-it@^8.4.1: version "8.4.2" @@ -10003,9 +9990,9 @@ math-expression-evaluator@^1.2.14: integrity sha1-3oGf282E3M2PrlnGrreWFbnSZqw= math-random@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== md5.js@^1.3.4: version "1.3.5" @@ -10023,17 +10010,17 @@ mdurl@^1.0.1: media-typer@0.3.0: version "0.3.0" - resolved "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= mem@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" - integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== dependencies: map-age-cleaner "^0.1.1" - mimic-fn "^1.0.0" - p-is-promise "^1.1.0" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" @@ -10045,7 +10032,7 @@ memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: meow@^3.3.0, meow@^3.7.0: version "3.7.0" - resolved "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= dependencies: camelcase-keys "^2.0.0" @@ -10144,7 +10131,7 @@ micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -10171,17 +10158,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@~1.37.0: - version "1.37.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" - integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19: - version "2.1.21" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" - integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== dependencies: - mime-db "~1.37.0" + mime-db "1.40.0" mime@1.4.1: version "1.4.1" @@ -10189,15 +10176,20 @@ mime@1.4.1: integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== mime@^2.0.3, mime@^2.3.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" - integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== + version "2.4.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.2.tgz#ce5229a5e99ffc313abac806b482c10e7ba6ac78" + integrity sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -10241,17 +10233,17 @@ minimist-options@^3.0.1: minimist@0.0.8: version "0.0.8" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@1.2.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= minimist@~0.0.1: version "0.0.10" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: @@ -10263,9 +10255,9 @@ minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: yallist "^3.0.0" minizlib@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.0.tgz#59517387478fd98d8017ed0299c6cb16cbd12da3" - integrity sha512-vQhkoouK/oKRVuFJynustmW3wrqZEXOrfbVVirvOVeglH4TNvIkcqiyojlIbbZYYDJZSbEKEXmDudg+tyRkm6g== + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== dependencies: minipass "^2.2.1" @@ -10319,19 +10311,12 @@ mixin-object@^2.0.1: mkdirp@0.3.0: version "0.3.0" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= -mkdirp@0.5.0: - version "0.5.0" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" - integrity sha1-HXMHam35hs2TROFecfzAWkyavxI= - dependencies: - minimist "0.0.8" - mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" @@ -10342,18 +10327,13 @@ modify-values@^1.0.0: integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== moment-timezone@^0.5.x: - version "0.5.23" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.23.tgz#7cbb00db2c14c71b19303cb47b0fb0a6d8651463" - integrity sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w== + version "0.5.25" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.25.tgz#a11bfa2f74e088327f2cd4c08b3e7bdf55957810" + integrity sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw== dependencies: moment ">= 2.9.0" -moment@2.22.2, "moment@>= 2.9.0", moment@^2.19: - version "2.22.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" - integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= - -moment@^2.24.0: +moment@2.24.0, "moment@>= 2.9.0", moment@^2.19, moment@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== @@ -10390,11 +10370,16 @@ multimatch@^2.1.0: arrify "^1.0.0" minimatch "^3.0.0" -mute-stream@0.0.7, mute-stream@~0.0.4: +mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + mz@^2.6.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" @@ -10404,10 +10389,10 @@ mz@^2.6.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.10.0, nan@^2.9.2: - version "2.11.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== +nan@^2.12.1, nan@^2.13.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== nanoassert@^1.1.0: version "1.1.0" @@ -10415,9 +10400,9 @@ nanoassert@^1.1.0: integrity sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40= nanobus@^4.3.1: - version "4.3.5" - resolved "https://registry.yarnpkg.com/nanobus/-/nanobus-4.3.5.tgz#9d106c35a1f136bc34e0c4b5d28230a6cdb9e6ae" - integrity sha512-6UlqagLV9/ADqcTU60mipAPEd16WDbO+a9WeeGVn9RucHKNDTcPt9MOf8ZmAvbA3V2CV+EJS28eupNalg4YF8Q== + version "4.4.0" + resolved "https://registry.yarnpkg.com/nanobus/-/nanobus-4.4.0.tgz#e5c20846fa17cff01ef5aac301410d1e541f81ed" + integrity sha512-Hv9USGyH8EsPy0o8pPWE7x3YRIfuZDgMBirzjU6XLebhiSK2g53JlfqgolD0c39ne6wXAfaBNcIAvYe22Bav+Q== dependencies: nanoassert "^1.1.0" nanotiming "^7.2.0" @@ -10461,27 +10446,27 @@ natural-compare@^1.4.0: integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= needle@^2.1.0, needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.1.tgz#d272f2f4034afb9c4c9ab1379aabc17fc85c9388" + integrity sha512-CaLXV3W8Vnbps8ZANqDGz7j4x7Yj1LW4TWF/TQuDfj7Cfx4nAPTvw98qgTevtto1oHDrh3pQkaODbqupXlsWTg== dependencies: - debug "^2.1.2" + debug "^4.1.0" iconv-lite "^0.4.4" sax "^1.2.4" -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.5.0: +neo-async@^2.5.0, neo-async@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== -next-tick@1: +next-tick@^1.0.0: version "1.0.0" - resolved "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= nice-try@^1.0.4: @@ -10504,6 +10489,11 @@ node-cache@^4.1.1: clone "2.x" lodash "4.x" +node-eta@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/node-eta/-/node-eta-0.1.1.tgz#4066109b39371c761c72b7ebda9a9ea0a5de121f" + integrity sha1-QGYQmzk3HHYccrfr2pqeoKXeEh8= + node-fetch-npm@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" @@ -10522,9 +10512,9 @@ node-fetch@^1.0.1: is-stream "^1.0.1" node-fetch@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" - integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + version "2.5.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.5.0.tgz#8028c49fc1191bba56a07adc6e2a954644a48501" + integrity sha512-YuZKluhWGJwCcUu4RlZstdAxr8bFfOVHakc1mplwHkk8J+tqM1Y5yraYvIUpeX8aY7+crCwiELJq7Vl0o0LWXw== node-gyp@^3.8.0: version "3.8.0" @@ -10550,9 +10540,9 @@ node-int64@^0.4.0: integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= node-libs-browser@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" - integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" + integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA== dependencies: assert "^1.1.1" browserify-zlib "^0.2.0" @@ -10561,7 +10551,7 @@ node-libs-browser@^2.0.0: constants-browserify "^1.0.0" crypto-browserify "^3.11.0" domain-browser "^1.1.1" - events "^1.0.0" + events "^3.0.0" https-browserify "^1.0.0" os-browserify "^0.3.0" path-browserify "0.0.0" @@ -10575,7 +10565,7 @@ node-libs-browser@^2.0.0: timers-browserify "^2.0.4" tty-browserify "0.0.0" url "^0.11.0" - util "^0.10.3" + util "^0.11.0" vm-browserify "0.0.4" node-modules-regexp@^1.0.0: @@ -10594,10 +10584,10 @@ node-notifier@^5.2.1: shellwords "^0.1.1" which "^1.3.0" -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -10610,17 +10600,17 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.8: - version "1.1.9" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.9.tgz#70d0985ec4bf7de9f08fc481f5dae111889ca482" - integrity sha512-oic3GT4OtbWWKfRolz5Syw0Xus0KRFxeorLNj0s93ofX6PWyuzKjsiGxsCtWktBwwmTF6DdRRf2KreGqeOk5KA== +node-releases@^1.1.17: + version "1.1.17" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.17.tgz#71ea4631f0a97d5cd4f65f7d04ecf9072eac711a" + integrity sha512-/SCjetyta1m7YXLgtACZGDYJdCSIBAWorDWkGCGZlydP2Ll7J48l7j/JxNYZ+xsgSPbWfdulVS/aY+GdjUsQ7Q== dependencies: semver "^5.3.0" node-sass@^4.9.3: - version "4.10.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.10.0.tgz#dcc2b364c0913630945ccbf7a2bbf1f926effca4" - integrity sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q== + version "4.12.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" + integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -10629,12 +10619,10 @@ node-sass@^4.9.3: get-stdin "^4.0.1" glob "^7.0.3" in-publish "^2.0.0" - lodash.assign "^4.2.0" - lodash.clonedeep "^4.3.2" - lodash.mergewith "^4.6.0" + lodash "^4.17.11" meow "^3.7.0" mkdirp "^0.5.1" - nan "^2.10.0" + nan "^2.13.2" node-gyp "^3.8.0" npmlog "^4.0.0" request "^2.88.0" @@ -10664,7 +10652,7 @@ nopt@^4.0.1, nopt@~4.0.1: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.0.0, normalize-package-data@^2.4.0: +normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -10674,16 +10662,6 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.4.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -10691,6 +10669,11 @@ normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" @@ -10712,9 +10695,9 @@ normalize-url@^3.3.0: integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== npm-bundled@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== npm-lifecycle@^2.1.0: version "2.1.0" @@ -10740,7 +10723,7 @@ npm-lifecycle@^2.1.0: semver "^5.5.0" validate-npm-package-name "^3.0.0" -npm-packlist@^1.1.12, npm-packlist@^1.4.1: +npm-packlist@^1.1.12, npm-packlist@^1.1.6, npm-packlist@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== @@ -10748,14 +10731,6 @@ npm-packlist@^1.1.12, npm-packlist@^1.4.1: ignore-walk "^3.0.1" npm-bundled "^1.0.1" -npm-packlist@^1.1.6: - version "1.1.12" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-pick-manifest@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40" @@ -10796,7 +10771,7 @@ npm-run-path@^2.0.0: nprogress@^0.2.0: version "0.2.0" - resolved "http://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E= nssocket@0.6.0: @@ -10825,22 +10800,17 @@ number-is-nan@^1.0.0: integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= nwsapi@^2.0.7: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.1.tgz#08d6d75e69fd791bdea31507ffafe8c843b67e9c" - integrity sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg== + version "2.1.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" + integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== oauth-1.0a@^1.0.1: version "1.0.1" - resolved "http://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-1.0.1.tgz#29a9b580d7cf5de29573e2269fb05eb3efb1d819" + resolved "https://registry.yarnpkg.com/oauth-1.0a/-/oauth-1.0a-1.0.1.tgz#29a9b580d7cf5de29573e2269fb05eb3efb1d819" integrity sha1-Kam1gNfPXeKVc+Imn7Bes++x2Bk= dependencies: crypto-js "~3.1.2-2" -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -10865,10 +10835,10 @@ object-hash@^1.1.4: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@~1.0.0: - version "1.0.12" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" - integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object-visit@^1.0.0: version "1.0.1" @@ -10931,7 +10901,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: onetime@^1.0.0: version "1.1.0" - resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= onetime@^2.0.0: @@ -10952,16 +10922,16 @@ opener@^1.5.1: integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== opn@^5.1.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" - integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== dependencies: is-wsl "^1.1.0" -optimism@^0.6.6: - version "0.6.8" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" - integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== +optimism@^0.6.9: + version "0.6.9" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.9.tgz#19258ff8b3be0cea29ac35f06bff818e026e30bb" + integrity sha512-xoQm2lvXbCA9Kd7SCx6y713Y7sZ6fUc5R6VYpoL5M6svKJbTuvtNopexK8sO8K4s0EOUYHuPN2+yAEsNyRggkQ== dependencies: immutable-tuple "^0.4.9" @@ -10995,7 +10965,7 @@ optionator@^0.8.1, optionator@^0.8.2: ora@^0.2.3: version "0.2.3" - resolved "http://registry.npmjs.org/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" integrity sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q= dependencies: chalk "^1.1.1" @@ -11010,36 +10980,36 @@ os-browserify@^0.3.0: os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" - resolved "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-locale@^1.4.0: version "1.4.0" - resolved "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= dependencies: lcid "^1.0.0" os-locale@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" - integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== dependencies: - execa "^0.10.0" + execa "^1.0.0" lcid "^2.0.0" mem "^4.0.0" os-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.0.0.tgz#e1434dbfddb8e74b44c98b56797d951b7648a5d9" - integrity sha512-7c74tib2FsdFbQ3W+qj8Tyd1R3Z6tuVRNNxXjJcZ4NgjIEQU9N/prVMqcW29XZPXGACqaXN3jq58/6hoaoXH6g== + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" + integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== dependencies: - macos-release "^2.0.0" + macos-release "^2.2.0" windows-release "^3.1.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" - resolved "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@0, osenv@^0.1.4, osenv@^0.1.5: @@ -11067,10 +11037,10 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-is-promise@^1.1.0: - version "1.1.0" - resolved "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" - integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== p-limit@^1.0.0, p-limit@^1.1.0: version "1.3.0" @@ -11080,9 +11050,9 @@ p-limit@^1.0.0, p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== dependencies: p-try "^2.0.0" @@ -11128,9 +11098,9 @@ p-try@^1.0.0: integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" - integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== p-waterfall@^1.0.0: version "1.0.0" @@ -11183,9 +11153,9 @@ pacote@^9.5.0: which "^1.3.1" pako@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.7.tgz#2473439021b57f1516c82f58be7275ad8ef1bb27" - integrity sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ== + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== parallel-transform@^1.1.0: version "1.1.0" @@ -11203,16 +11173,24 @@ param-case@2.1.x: dependencies: no-case "^2.2.0" +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-asn1@^5.0.0: - version "5.1.1" - resolved "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" - integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + version "5.1.4" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" + integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" parse-github-repo-url@^1.3.0: version "1.4.1" @@ -11273,9 +11251,9 @@ parse5@4.0.0: integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== parseurl@^1.3.2, parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" @@ -11306,7 +11284,7 @@ path-exists@^3.0.0: path-is-absolute@1.0.1, path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" - resolved "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1, path-is-inside@^1.0.2: @@ -11319,7 +11297,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5, path-parse@^1.0.6: +path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== @@ -11402,7 +11380,7 @@ pidusage@^1.2.0: pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: version "2.3.0" - resolved "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: @@ -11410,6 +11388,11 @@ pify@^3.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -11555,7 +11538,7 @@ posix-character-classes@^0.1.0: postcss-calc@^5.2.0: version "5.3.1" - resolved "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" integrity sha1-d7rnypKK2FcW4v2kLyYb98HWW14= dependencies: postcss "^5.0.2" @@ -11581,7 +11564,7 @@ postcss-convert-values@^2.3.4: postcss-discard-comments@^2.0.4: version "2.0.4" - resolved "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" integrity sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0= dependencies: postcss "^5.0.14" @@ -11595,21 +11578,21 @@ postcss-discard-duplicates@^2.0.1: postcss-discard-empty@^2.0.1: version "2.1.0" - resolved "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" integrity sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU= dependencies: postcss "^5.0.14" postcss-discard-overridden@^0.1.1: version "0.1.1" - resolved "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" integrity sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg= dependencies: postcss "^5.0.16" postcss-discard-unused@^2.2.1: version "2.2.3" - resolved "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" integrity sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM= dependencies: postcss "^5.0.14" @@ -11649,7 +11632,7 @@ postcss-loader@^2.1.5: postcss-merge-idents@^2.1.5: version "2.1.7" - resolved "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" integrity sha1-TFUwMTwI4dWzu/PSu8dH4njuonA= dependencies: has "^1.0.1" @@ -11681,7 +11664,7 @@ postcss-message-helpers@^2.0.0: postcss-minify-font-values@^1.0.2: version "1.0.5" - resolved "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" integrity sha1-S1jttWZB66fIR0qzUmyv17vey2k= dependencies: object-assign "^4.0.1" @@ -11690,7 +11673,7 @@ postcss-minify-font-values@^1.0.2: postcss-minify-gradients@^1.0.1: version "1.0.5" - resolved "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" integrity sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE= dependencies: postcss "^5.0.12" @@ -11698,7 +11681,7 @@ postcss-minify-gradients@^1.0.1: postcss-minify-params@^1.0.4: version "1.2.2" - resolved "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" integrity sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM= dependencies: alphanum-sort "^1.0.1" @@ -11708,7 +11691,7 @@ postcss-minify-params@^1.0.4: postcss-minify-selectors@^2.0.4: version "2.1.1" - resolved "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" integrity sha1-ssapjAByz5G5MtGkllCBFDEXNb8= dependencies: alphanum-sort "^1.0.2" @@ -11749,14 +11732,14 @@ postcss-modules-values@^1.3.0: postcss-normalize-charset@^1.1.0: version "1.1.1" - resolved "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" integrity sha1-757nEhLX/nWceO0WL2HtYrXLk/E= dependencies: postcss "^5.0.5" postcss-normalize-url@^3.0.7: version "3.0.8" - resolved "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" integrity sha1-EI90s/L82viRov+j6kWSJ5/HgiI= dependencies: is-absolute-url "^2.0.0" @@ -11774,7 +11757,7 @@ postcss-ordered-values@^2.1.0: postcss-reduce-idents@^2.2.2: version "2.4.0" - resolved "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" integrity sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM= dependencies: postcss "^5.0.4" @@ -11782,14 +11765,14 @@ postcss-reduce-idents@^2.2.2: postcss-reduce-initial@^1.0.0: version "1.0.1" - resolved "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" integrity sha1-aPgGlfBF0IJjqHmtJA343WT2ROo= dependencies: postcss "^5.0.4" postcss-reduce-transforms@^1.0.3: version "1.0.4" - resolved "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" integrity sha1-/3b02CEkN7McKYpC0uFEQCV3GuE= dependencies: has "^1.0.1" @@ -11805,15 +11788,6 @@ postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^3.1.1: - 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: version "5.0.0" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" @@ -11825,7 +11799,7 @@ postcss-selector-parser@^5.0.0: postcss-svgo@^2.1.1: version "2.1.6" - resolved "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" integrity sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0= dependencies: is-svg "^2.0.0" @@ -11835,7 +11809,7 @@ postcss-svgo@^2.1.1: postcss-unique-selectors@^2.0.2: version "2.0.2" - resolved "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" integrity sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0= dependencies: alphanum-sort "^1.0.1" @@ -11849,7 +11823,7 @@ postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^ postcss-zindex@^2.0.1: version "2.2.0" - resolved "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" integrity sha1-0hCd3AVbka9n/EyzsCWUZjnSryI= dependencies: has "^1.0.1" @@ -11866,7 +11840,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.20, postcss@^6.0.23: +postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.23: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== @@ -11875,14 +11849,14 @@ postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.20, postcss@^6.0.23: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.7: - version "7.0.7" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.7.tgz#2754d073f77acb4ef08f1235c36c5721a7201614" - integrity sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg== +postcss@^7.0.14: + version "7.0.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" + integrity sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg== dependencies: - chalk "^2.4.1" + chalk "^2.4.2" source-map "^0.6.1" - supports-color "^5.5.0" + supports-color "^6.1.0" prelude-ls@~1.1.2: version "1.1.2" @@ -11899,14 +11873,26 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= -prettier@1.13.7: - version "1.13.7" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281" - integrity sha512-KIU72UmYPGk4MujZGYMFwinB7lOf2LsDNGSOC8ufevsrPLISrZbNJlWstRi3m0AMuszbH+EFSQ/r6w56RSPK6w== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@1.16.3: + version "1.16.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.3.tgz#8c62168453badef702f34b45b6ee899574a6a65d" + integrity sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw== + +prettier@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" + integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== pretty-bytes@^4.0.2: version "4.0.2" - resolved "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" integrity sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk= pretty-error@^2.0.2: @@ -11949,9 +11935,9 @@ print-message@^2.1.0: chalk "1.1.1" prismjs@^1.13.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.15.0.tgz#8801d332e472091ba8def94976c8877ad60398d9" - integrity sha512-Lf2JrFYx8FanHrjoV5oL8YHCclLQgbJcVZR+gikGGMqz6ub5QVWDTM6YIwm3BuPxM/LOV+rKns3LssXNLIf+DA== + version "1.16.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.16.0.tgz#406eb2c8aacb0f5f0f1167930cb83835d10a4308" + integrity sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA== optionalDependencies: clipboard "^2.0.0" @@ -11977,7 +11963,7 @@ process@~0.5.1: progress@^1.1.8: version "1.1.8" - resolved "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= progress@^2.0.0: @@ -12006,9 +11992,9 @@ promptly@2.2.0: read "^1.0.4" prompts@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.3.tgz#c5ccb324010b2e8f74752aadceeb57134c1d2522" - integrity sha512-H8oWEoRZpybm6NV4to9/1limhttEo13xK62pNvn2JzY0MA03p7s0OjtmhXyon3uJmxiJJVSuUwEJFFssI3eBiQ== + version "2.0.4" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.4.tgz#179f9d4db3128b9933aa35f93a800d8fce76a682" + integrity sha512-HTzM3UWp/99A0gk51gAegwo1QRYA7xjcZufMNe33rCclFszUYAuHe1fIN/3ZmiHeGPkUsNaRyQm1hHOfM0PKxA== dependencies: kleur "^3.0.2" sisteransi "^1.0.0" @@ -12038,12 +12024,12 @@ protoduck@^5.0.1: genfun "^5.0.0" proxy-addr@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" - integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + version "2.0.5" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" + integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== dependencies: forwarded "~0.1.2" - ipaddr.js "1.8.0" + ipaddr.js "1.9.0" prr@~1.0.1: version "1.0.1" @@ -12055,12 +12041,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.24: - version "1.1.29" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" - integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== - -psl@^1.1.28: +psl@^1.1.24, psl@^1.1.28: version "1.1.31" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== @@ -12122,7 +12103,7 @@ q@^1.1.2, q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.5.2, qs@~6.5.1, qs@~6.5.2: +qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== @@ -12136,11 +12117,12 @@ query-string@^4.1.0: strict-uri-encode "^1.0.0" query-string@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.2.0.tgz#468edeb542b7e0538f9f9b1aeb26f034f19c86e1" - integrity sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA== + version "6.5.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.5.0.tgz#2e1a70125af01f6f04573692d02c09302a1d8bfc" + integrity sha512-TYC4hDjZSvVxLMEucDMySkuAS9UIzSbAiYGyA9GWCjLKB8fQpviFbjd20fD7uejCDxZS+ftSdBKE6DS+xucJFg== dependencies: decode-uri-component "^0.2.0" + split-on-first "^1.0.0" strict-uri-encode "^2.0.0" querystring-es3@^0.2.0, querystring-es3@^0.2.1: @@ -12153,10 +12135,10 @@ querystring@0.2.0, querystring@^0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -querystringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" - integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== quick-lru@^1.0.0: version "1.1.0" @@ -12178,9 +12160,9 @@ randomatic@^3.0.0: math-random "^1.0.1" randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" - integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" @@ -12318,9 +12300,9 @@ read@1, read@^1.0.4, read@~1.0.1: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" @@ -12331,15 +12313,14 @@ read@1, read@^1.0.4, read@~1.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@1.0: - version "1.0.34" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= +"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9" + integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw== dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" readdir-scoped-modules@^1.0.0: version "1.0.2" @@ -12351,7 +12332,7 @@ readdir-scoped-modules@^1.0.0: graceful-fs "^4.1.2" once "^1.3.0" -readdirp@^2.0.0: +readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== @@ -12416,7 +12397,7 @@ redis-tag-cache@^1.2.1: reduce-css-calc@^1.2.6: version "1.3.0" - resolved "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= dependencies: balanced-match "^0.4.2" @@ -12431,28 +12412,21 @@ reduce-function-call@^1.0.1: balanced-match "^0.4.2" reduce@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/reduce/-/reduce-1.0.1.tgz#14fa2e5ff1fc560703a020cbb5fbaab691565804" - integrity sha1-FPouX/H8VgcDoCDLtfuqtpFWWAQ= + version "1.0.2" + resolved "https://registry.yarnpkg.com/reduce/-/reduce-1.0.2.tgz#0cd680ad3ffe0b060e57a5c68bdfce37168d361b" + integrity sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ== dependencies: - object-keys "~1.0.0" + object-keys "^1.1.0" reflect-metadata@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" - integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== - -regenerate-unicode-properties@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" - integrity sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw== - dependencies: - regenerate "^1.4.0" + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== -regenerate-unicode-properties@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.1.tgz#58a4a74e736380a7ab3c5f7e03f303a941b31289" - integrity sha512-HTjMafphaH5d5QDHuwW8Me6Hbc/GhXg8luNqTkPVwZ/oCZhnoifjWhGYsu2BzepMELTlbnoVcXvV0f+2uDDvoQ== +regenerate-unicode-properties@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz#7b38faa296252376d363558cfbda90c9ce709662" + integrity sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ== dependencies: regenerate "^1.4.0" @@ -12466,10 +12440,10 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== regenerator-transform@^0.10.0: version "0.10.1" @@ -12510,18 +12484,23 @@ regex-not@^1.0.0, regex-not@^1.0.2: safe-regex "^1.1.0" regexp-tree@^0.1.0: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.5.tgz#7cd71fca17198d04b4176efd79713f2998009397" - integrity sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ== + version "0.1.6" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.6.tgz#84900fa12fdf428a2ac25f04300382a7c0148479" + integrity sha512-LFrA98Dw/heXqDojz7qKFdygZmFoiVlvE1Zp7Cq2cvF+ZA+03Gmhy0k0PQlsC1jvHPiTUSs+pDHEuSWv6+6D7w== regexpp@^1.0.1: version "1.1.0" - resolved "http://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + regexpu-core@^1.0.0: version "1.0.0" - resolved "http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs= dependencies: regenerate "^1.2.1" @@ -12530,46 +12509,34 @@ regexpu-core@^1.0.0: regexpu-core@^2.0.0: version "2.0.0" - resolved "http://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= dependencies: regenerate "^1.2.1" regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu-core@^4.1.3, regexpu-core@^4.1.4: - version "4.4.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.4.0.tgz#8d43e0d1266883969720345e70c275ee0aec0d32" - integrity sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^7.0.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.0.2" - -regexpu-core@^4.2.0: - version "4.5.3" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.3.tgz#72f572e03bb8b9f4f4d895a0ccc57e707f4af2e4" - integrity sha512-LON8666bTAlViVEPXMv65ZqiaR3rMNLz36PIaQ7D+er5snu93k0peR7FSvO0QteYbZ3GOkvfHKbGr/B1xDu9FA== +regexpu-core@^4.1.3, regexpu-core@^4.1.4, regexpu-core@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" + integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.1" + regenerate-unicode-properties "^8.0.2" regjsgen "^0.5.0" regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.1.0" register-service-worker@^1.5.1, register-service-worker@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/register-service-worker/-/register-service-worker-1.5.2.tgz#a4631896c38d6ec5597358f44988cc46a911912d" - integrity sha512-XNqSZHJsFGnvEGkg/2IrCp6G8Ya3qLj4mq0bSHil/dfdO82LOxGnMnJjAD9MYCvf/8cDCO8pL+1i65yzmP7rPQ== + version "1.6.2" + resolved "https://registry.yarnpkg.com/register-service-worker/-/register-service-worker-1.6.2.tgz#9297e54c205c371c6e49bfa88f6997e8dd315f4c" + integrity sha512-I8L87fX2TK29LDx+wgyOUh2BJ3rDIRC1FtRZEHeP3rivzDv6p1DDZLGGtPucqjEkm45+2crtFIFssEWv56+9Wg== registry-auth-token@^3.0.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== dependencies: rc "^1.1.6" safe-buffer "^5.0.1" @@ -12583,7 +12550,7 @@ registry-url@^3.0.3: regjsgen@^0.2.0: version "0.2.0" - resolved "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= regjsgen@^0.5.0: @@ -12593,7 +12560,7 @@ regjsgen@^0.5.0: regjsparser@^0.1.4: version "0.1.5" - resolved "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= dependencies: jsesc "~0.5.0" @@ -12616,9 +12583,9 @@ remove-accents@^0.4.2: integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= remove-array-items@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-array-items/-/remove-array-items-1.1.0.tgz#e3d4aaba795a412479ea89408dee345387da7d3b" - integrity sha512-+YAHWd5patqAM/F4uBsto9h8RXDVxPRrKW46AkbI6eH12OFrN9wlGpkNWYxCjCfwtkidTjaaCXqU634V4mysvw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/remove-array-items/-/remove-array-items-1.1.1.tgz#fd745ff73d0822e561ea910bf1b401fc7843e693" + integrity sha512-MXW/jtHyl5F1PZI7NbpS8SOtympdLuF20aoWJT5lELR1p/HJDd5nqW8Eu9uLh/hCRY3FgvrIT5AwDCgBODklcA== remove-trailing-separator@^1.0.1: version "1.1.0" @@ -12626,13 +12593,13 @@ remove-trailing-separator@^1.0.1: integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= renderkid@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.2.tgz#12d310f255360c07ad8fde253f6c9e9de372d2aa" - integrity sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== dependencies: css-select "^1.1.0" - dom-converter "~0.2" - htmlparser2 "~3.3.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" strip-ansi "^3.0.0" utila "^0.4.0" @@ -12653,12 +12620,13 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request-progress@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.3.1.tgz#0721c105d8a96ac6b2ce8b2c89ae2d5ecfcf6b3a" - integrity sha1-ByHBBdipasayzossia4tXs/Pazo= +request-progress@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.4.0.tgz#c1954e39086aa85269c5660bcee0142a6a70d7e7" + integrity sha1-wZVOOQhqqFJpxWYLzuAUKmpw1+c= dependencies: - throttleit "~0.0.2" + node-eta "^0.1.1" + throttleit "^0.0.2" request-progress@^2.0.1: version "2.0.1" @@ -12683,33 +12651,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@2.87.0: - version "2.87.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" - integrity sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -request@^2.72.0, request@^2.81.0, request@^2.87.0, request@^2.88.0: +request@2.88.0, request@^2.72.0, request@^2.81.0, request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -12750,15 +12692,20 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + require-uncached@^1.0.3: version "1.0.3" - resolved "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" -requireindex@~1.2.0: +requireindex@^1.2.0, requireindex@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== @@ -12775,7 +12722,7 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" -resolve-dir@^1.0.0: +resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= @@ -12816,20 +12763,13 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" - integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== +resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0, resolve@^1.6.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.1.tgz#664842ac960795bbe758221cdccda61fb64b5f18" + integrity sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA== dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0, resolve@^1.6.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== - dependencies: - path-parse "^1.0.5" - restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" @@ -12856,12 +12796,12 @@ retry@^0.10.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== +rimraf@2, rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: - glob "^7.0.5" + glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" @@ -12915,9 +12855,9 @@ rxjs@^5.0.0-beta.11: symbol-observable "1.0.1" rxjs@^6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" - integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== + version "6.5.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.1.tgz#f7a005a9386361921b8524f38f54cbf80e5d08f4" + integrity sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg== dependencies: tslib "^1.9.0" @@ -12928,7 +12868,7 @@ safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s safe-regex@^1.1.0: version "1.1.0" - resolved "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" @@ -12977,7 +12917,7 @@ sass-loader@^7.0.3, sass-loader@^7.1.0: sax@0.5.x: version "0.5.8" - resolved "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" + resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE= sax@^1.2.4, sax@~1.2.1: @@ -12985,7 +12925,7 @@ sax@^1.2.4, sax@~1.2.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.4, schema-utils@^0.4.5: +schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== @@ -13031,13 +12971,23 @@ semver-diff@^2.0.0: semver "^5.0.3" "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.*, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +semver@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== + +semver@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.0.0.tgz#05e359ee571e5ad7ed641a6eec1e547ba52dea65" + integrity sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ== semver@~5.3.0: version "5.3.0" - resolved "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= send@0.16.2: @@ -13060,9 +13010,9 @@ send@0.16.2: statuses "~1.4.0" serialize-javascript@^1.3.0, serialize-javascript@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" - integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== + version "1.7.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" + integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== serve-static@1.13.2: version "1.13.2" @@ -13114,9 +13064,14 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" - resolved "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -13167,9 +13122,9 @@ shellwords@^0.1.1: integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== shimmer@^1.0.0, shimmer@^1.1.0, shimmer@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.0.tgz#f966f7555789763e74d8841193685a5e78736665" - integrity sha512-xTCx2vohXC2EWWDqY/zb4+5Mu28D+HYNSOuFzsyRDRvI/e1ICb69afwaUwfjr+25ZXldbOLyp+iDUZHq8UnTag== + version "1.2.1" + resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" + integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== sigmund@^1.0.1: version "1.0.1" @@ -13198,7 +13153,7 @@ slash@^2.0.0: slice-ansi@0.0.4: version "0.0.4" - resolved "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= slice-ansi@1.0.0: @@ -13208,6 +13163,15 @@ slice-ansi@1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + slide@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -13249,17 +13213,17 @@ snapdragon@^0.8.1: use "^3.1.0" socks-proxy-agent@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" - integrity sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== dependencies: - agent-base "~4.2.0" - socks "~2.2.0" + agent-base "~4.2.1" + socks "~2.3.2" -socks@~2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.3.tgz#7399ce11e19b2a997153c983a9ccb6306721f2dc" - integrity sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA== +socks@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e" + integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ== dependencies: ip "^1.1.5" smart-buffer "4.0.2" @@ -13301,18 +13265,10 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" -source-map-support@^0.5, source-map-support@~0.5.6: - version "0.5.9" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.5.6: - version "0.5.10" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.10.tgz#2214080bc9d51832511ee2bab96e3c2f9353120c" - integrity sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ== +source-map-support@^0.5, source-map-support@^0.5.6, source-map-support@~0.5.10: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -13324,19 +13280,19 @@ source-map-url@^0.4.0: source-map@0.1.x: version "0.1.43" - resolved "http://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= dependencies: amdefine ">=0.0.4" source-map@0.5.6: version "0.5.6" - resolved "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= source-map@^0.4.2: version "0.4.4" - resolved "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" integrity sha1-66T12pwNyZneaAMti092FzZSA2s= dependencies: amdefine ">=0.0.4" @@ -13351,11 +13307,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -13378,9 +13329,14 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" - integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + version "3.0.4" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" + integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== + +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -13414,9 +13370,9 @@ sprintf-js@~1.0.2: integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" - integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -13452,10 +13408,10 @@ stack-utils@^1.0.1: resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== -standard-as-callback@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-1.0.1.tgz#2e9e1e9d278d7d77580253faaec42269015e3c1d" - integrity sha512-izxEITSyc7S+5oOiF/URiYaNkemPUxIndCNv66jJ548Y1TVxhBvioNMSPrZIQdaZDlhnguOdUzHA/7hJ3xFhuQ== +standard-as-callback@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.0.1.tgz#ed8bb25648e15831759b6023bdb87e6b60b38126" + integrity sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg== static-extend@^0.1.1: version "0.1.2" @@ -13495,9 +13451,9 @@ stealthy-require@^1.1.1: integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= stream-browserify@^2.0.1: - version "2.0.1" - resolved "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" - integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" readable-stream "^2.0.2" @@ -13571,21 +13527,25 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^1.0.0: +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== dependencies: safe-buffer "~5.1.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - string_decoder@~1.1.1: version "1.1.1" - resolved "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" @@ -13601,7 +13561,7 @@ stringify-object@^3.2.2: strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" @@ -13613,12 +13573,12 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" - integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== +strip-ansi@^5.0.0, strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: - ansi-regex "^4.0.0" + ansi-regex "^4.1.0" strip-bom-string@^1.0.0: version "1.0.0" @@ -13647,7 +13607,7 @@ strip-comments@^1.0.2: strip-eof@^1.0.0: version "1.0.0" - resolved "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-indent@^1.0.1: @@ -13662,7 +13622,7 @@ strip-indent@^2.0.0: resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= -strip-json-comments@^2.0.0, strip-json-comments@~2.0.1: +strip-json-comments@^2.0.0, strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -13697,12 +13657,12 @@ stylus@^0.54.5: sax "0.5.x" source-map "0.1.x" -supports-color@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5" - integrity sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ== +supports-color@5.5.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: - has-flag "^2.0.0" + has-flag "^3.0.0" supports-color@^2.0.0: version "2.0.0" @@ -13716,13 +13676,6 @@ supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^6.0.0, supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" @@ -13745,7 +13698,7 @@ svgo@^0.7.0: sw-precache-webpack-plugin@^0.11.5: version "0.11.5" - resolved "http://registry.npmjs.org/sw-precache-webpack-plugin/-/sw-precache-webpack-plugin-0.11.5.tgz#9b53f65a4966e3adc298e256b3cef7a55c73fdfd" + resolved "https://registry.yarnpkg.com/sw-precache-webpack-plugin/-/sw-precache-webpack-plugin-0.11.5.tgz#9b53f65a4966e3adc298e256b3cef7a55c73fdfd" integrity sha512-K6E52DbYyzGNXGyv2LhI2Duomr3t/2FFMmnGdHZ1Ruk3ulFHDMASJtg3WpA3CXlWODZx189tTaOIO5mWkSKyVg== dependencies: del "^3.0.0" @@ -13805,7 +13758,7 @@ table@4.0.2: table@^4.0.3: version "4.0.3" - resolved "http://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" integrity sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg== dependencies: ajv "^6.0.1" @@ -13815,14 +13768,24 @@ table@^4.0.3: slice-ansi "1.0.0" string-width "^2.1.1" +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== + dependencies: + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" + tapable@^1.0.0, tapable@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e" - integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^2.0.0: version "2.2.1" - resolved "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= dependencies: block-stream "*" @@ -13867,37 +13830,37 @@ term-size@^1.2.0: execa "^0.7.0" terser-webpack-plugin@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.1.0.tgz#cf7c25a1eee25bf121f4a587bb9e004e3f80e528" - integrity sha512-61lV0DSxMAZ8AyZG7/A4a3UPlrbOBo8NIQ4tJzLPAdGOQ+yoNC7l5ijEow27lBAL2humer01KLS6bGIMYQxKoA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz#3f98bc902fac3e5d0de730869f50668561262ec8" + integrity sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA== dependencies: cacache "^11.0.2" find-cache-dir "^2.0.0" schema-utils "^1.0.0" serialize-javascript "^1.4.0" source-map "^0.6.1" - terser "^3.8.1" + terser "^3.16.1" webpack-sources "^1.1.0" worker-farm "^1.5.2" -terser@^3.8.1: - version "3.11.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-3.11.0.tgz#60782893e1f4d6788acc696351f40636d0e37af0" - integrity sha512-5iLMdhEPIq3zFWskpmbzmKwMQixKmTYwY3Ox9pjtSklBLnHiuQ0GKJLhL1HSYtyffHM3/lDIFBnb82m9D7ewwQ== +terser@^3.16.1: + version "3.17.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" + integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ== dependencies: - commander "~2.17.1" + commander "^2.19.0" source-map "~0.6.1" - source-map-support "~0.5.6" + source-map-support "~0.5.10" -test-exclude@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" - integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA== +test-exclude@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.2.tgz#7322f8ab037b0b93ad2aab35fe9068baf997a4c4" + integrity sha512-N2pvaLpT8guUpb5Fe1GJlmvmzH3x+DAKmmyEQmFP792QcLYoGE1syxztSvPD1V8yPe6VrcCt6YGQVjSRjCASsA== dependencies: - arrify "^1.0.1" + glob "^7.1.3" minimatch "^3.0.4" read-pkg-up "^4.0.0" - require-main-filename "^1.0.1" + require-main-filename "^2.0.0" text-extensions@^1.0.0: version "1.9.0" @@ -13929,20 +13892,20 @@ throat@^4.0.0: integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= throttle-debounce@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.0.1.tgz#7307ddd6cd9acadb349132fbf6c18d78c88a5e62" - integrity sha512-Sr6jZBlWShsAaSXKyNXyNicOrJW/KtkDqIEwHt4wYwWA2wa/q67Luhqoujg48V8hTk60wB56tYrJJn6jc2R7VA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.1.0.tgz#257e648f0a56bd9e54fe0f132c4ab8611df4e1d5" + integrity sha512-AOvyNahXQuU7NN+VVvOOX+uW6FPaWdAOdRP5HfwYxAfCzXTFKRMoIMk+n+po318+ktcChx+F1Dd91G3YHeMKyg== + +throttleit@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" + integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8= throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw= -throttleit@~0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" - integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8= - through2@^2.0.0, through2@^2.0.2: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -13951,9 +13914,16 @@ through2@^2.0.0, through2@^2.0.2: readable-stream "~2.3.6" xtend "~4.0.1" +through2@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@~2.3.4: version "2.3.8" - resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= time-fix-plugin@^2.0.0: @@ -13974,18 +13944,11 @@ timers-browserify@^2.0.4: setimmediate "^1.0.4" tiny-emitter@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c" - integrity sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow== - -tmp@0.0.31: - version "0.0.31" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" - integrity sha1-jzirlDjhcxXl29izZX6L+yd65Kc= - dependencies: - os-tmpdir "~1.0.1" + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== -tmp@^0.0.33: +tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== @@ -14048,13 +14011,13 @@ toidentifier@1.0.0: integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== toml@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.3.tgz#8d683d729577cb286231dfc7a8affe58d31728fb" - integrity sha512-O7L5hhSQHxuufWUdcTRPfuTh3phKfAZ/dqfxZFoxPCj2RYmpaSGLEIs016FCXItQwNr08yefUB5TSjzRYnajTA== + version "2.3.6" + resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.6.tgz#25b0866483a9722474895559088b436fd11f861b" + integrity sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ== topo@2.x.x: version "2.0.2" - resolved "http://registry.npmjs.org/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" + resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" integrity sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI= dependencies: hoek "4.x.x" @@ -14072,13 +14035,6 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@~2.3.3: - version "2.3.4" - resolved "http://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== - dependencies: - punycode "^1.4.1" - tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -14126,10 +14082,24 @@ tryer@^1.0.0: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +ts-invariant@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.2.1.tgz#3d587f9d6e3bded97bf9ec17951dd9814d5a9d3f" + integrity sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg== + dependencies: + tslib "^1.9.3" + +ts-invariant@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.3.3.tgz#b5742b1885ecf9e29c31a750307480f045ec0b16" + integrity sha512-UReOKsrJFGC9tUblgSRWo+BsVNbEd77Cl6WiV/XpMlkifXwNIJbknViCucHvVZkXSC/mcWeRnIGdY7uprcwvdQ== + dependencies: + tslib "^1.9.3" + ts-jest@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.0.0.tgz#3f26bf2ec1fa584863a5a9c29bd8717d549efbf6" - integrity sha512-o8BO3TkMREpAATaFTrXkovMsCpBl2z4NDBoLJuWZcJJj1ijI49UnvDMfVpj+iogn/Jl8Pbhuei5nc/Ti+frEHw== + version "24.0.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.0.2.tgz#8dde6cece97c31c03e80e474c749753ffd27194d" + integrity sha512-h6ZCZiA1EQgjczxq+uGLXQlNgeg02WWJBbeT8j6nyIBRQdglqbvzDoHahTEIiS6Eor6x8mK6PfZ7brQ9Q6tzHw== dependencies: bs-logger "0.x" buffer-from "1.x" @@ -14142,9 +14112,9 @@ ts-jest@^24.0.0: yargs-parser "10.x" ts-loader@^5.3.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.3.1.tgz#70614c8ec4354a9c8b89c9f97b2becb7a98a3980" - integrity sha512-fDDgpBH3SR8xlt2MasLdz3Yy611PQ/UY/KGyo7TgXhTRU/6sS8uGG0nJYnU1OdFBNKcoYbId1UTNaAOUn+i41g== + version "5.4.5" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.4.5.tgz#a0c1f034b017a9344cef0961bfd97cc192492b8b" + integrity sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw== dependencies: chalk "^2.3.0" enhanced-resolve "^4.0.0" @@ -14176,11 +14146,18 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.9.0: +tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tsutils@^3.7.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.10.0.tgz#6f1c95c94606e098592b0dff06590cf9659227d6" + integrity sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q== + dependencies: + tslib "^1.8.1" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -14211,12 +14188,12 @@ type-check@~0.3.2: prelude-ls "~1.1.2" type-is@^1.6.16, type-is@~1.6.16: - version "1.6.16" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" - integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" - mime-types "~2.1.18" + mime-types "~2.1.24" typedarray@^0.0.6: version "0.0.6" @@ -14224,14 +14201,14 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^3.1.6: - version "3.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" - integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== + version "3.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99" + integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw== uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.5.tgz#0c65f15f815aa08b560a61ce8b4db7ffc3f45376" - integrity sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg== + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== uglify-es@^3.3.9: version "3.3.9" @@ -14241,12 +14218,20 @@ uglify-es@^3.3.9: commander "~2.13.0" source-map "~0.6.1" -uglify-js@3.4.x, uglify-js@^3.1.4: - version "3.4.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" - integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uglify-js@^3.1.4: + version "3.5.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.9.tgz#372fbf95939555b1f460b1777d33a67d4a994ac9" + integrity sha512-WpT0RqsDtAWPNJK955DEnb6xjymR8Fn0OlK4TT4pS0ASYsVPqr5ELhgwOwLCP5J5vHeJ4xmMmz3DEgdqC10JeQ== dependencies: - commander "~2.17.1" + commander "~2.20.0" source-map "~0.6.1" uid-number@0.0.6: @@ -14272,20 +14257,15 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" -unicode-match-property-value-ecmascript@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4" - integrity sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ== - unicode-match-property-value-ecmascript@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" - integrity sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg== + version "1.0.5" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" + integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== union-value@^1.0.0: version "1.0.0" @@ -14358,10 +14338,10 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= -upath@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== update-notifier@^2.3.0: version "2.5.0" @@ -14423,11 +14403,11 @@ url-parse-lax@^1.0.0: prepend-http "^1.0.1" url-parse@^1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" - integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== dependencies: - querystringify "^2.0.0" + querystringify "^2.1.1" requires-port "^1.0.0" url-template@^2.0.8: @@ -14448,7 +14428,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -14463,15 +14443,15 @@ util.promisify@1.0.0, util.promisify@^1.0.0: util@0.10.3: version "0.10.3" - resolved "http://registry.npmjs.org/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" -util@^0.10.3: - version "0.10.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" - integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== dependencies: inherits "2.0.3" @@ -14549,14 +14529,14 @@ vm-browserify@0.0.4: indexof "0.0.1" vue-analytics@^5.16.1: - version "5.16.1" - resolved "https://registry.yarnpkg.com/vue-analytics/-/vue-analytics-5.16.1.tgz#2fa909a245e1cee9993a69f0b72caf1dd6126c10" - integrity sha512-3gnS0c9lxS7+eOtzEPZKZHgWur+qSFLsM+ZIXgPOGPBLfG4mIttT18RJROEozQ+qrCRmqnSCj/dgyg6FxVMM0A== + version "5.16.4" + resolved "https://registry.yarnpkg.com/vue-analytics/-/vue-analytics-5.16.4.tgz#7f9e197cbc64afac96884a05214b17efaf8e9d09" + integrity sha512-M67cUqpPeyk2rftrvlx2uU+BQ/C4E8SkF2Ct9LizOYUoTccZtCCJwhMJfQ3XL8xep6p3K8KYz58FzRWvx5zlPw== vue-apollo@^3.0.0-beta.19: - version "3.0.0-beta.26" - resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.0-beta.26.tgz#d78874d737d61656743adf59e65e6b98cf35ef5d" - integrity sha512-nWaPoKBGq1NR8g6kBnLy5yCCcoHkaxWQwPrY7vCcoBgYU8ZmA0czYN1na7hurtWLZdEiMC6B9LbaJWc+FRcUEA== + version "3.0.0-beta.28" + resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.0-beta.28.tgz#be6a3a1504be2096cbfb23996537e2fc95c8c239" + integrity sha512-ceCc1xTyxpNtiSeJMQgSkfgJue6pnv+TIvp75CwZlwMxRtNZjITj4MGvBWFwnoIEhVrUAw45ff/5udgJ8z9sdQ== dependencies: chalk "^2.4.1" throttle-debounce "^2.0.0" @@ -14568,7 +14548,7 @@ vue-carousel@^0.6.9: vue-eslint-parser@^2.0.3: version "2.0.3" - resolved "http://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1" integrity sha512-ZezcU71Owm84xVF6gfurBQUGg8WQ+WZGxgDEQu1IHFBZNx7BFZg3L1yHxrCBNNwbwFtE1GuvfJKMtb6Xuwc/Bw== dependencies: debug "^3.1.0" @@ -14584,14 +14564,14 @@ vue-gtm@^2.0.0: integrity sha512-9h2FI8Z4kZQ5SP55uFFQVHDwdr5UsJav8HpaRmsWB9D4lbP/HAzcsNxLPbgr/pLOMP+0ZXIYte90Cj0Uqyj2bg== vue-hot-reload-api@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2" - integrity sha512-AA86yKZ5uOKz87/q1UpngEXhbRkaYg1b7HMMVRobNV1IVKqZe8oLIzo6iMocVwZXnYitlGwf2k4ZRLOZlS8oPQ== + version "2.3.3" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf" + integrity sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g== vue-i18n@^8.0.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.4.0.tgz#bc3437ff8f5f389c57235ced602e9d7bfd87995c" - integrity sha512-MiBI1v2pY22aAEbNrcy7GX9qigoUQE9PbmrAydrBuYNRwn0RbD1RZpMemtmGW3Ju6LBA1yn7TZOPa3lxWrT0Eg== + version "8.11.2" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.11.2.tgz#92827fc42449f4602d2a0ddb437dfc4e3370d9d7" + integrity sha512-STcpmxqBrG77SyWi7e0Yn/B3DjKR6mSDwYS4F/V7zoi+e/+CPbVb2TaBqFwnrkoDcPmRfjM7nTwsiRQQOGdifw== vue-jest@^3.0.2: version "3.0.4" @@ -14614,35 +14594,25 @@ vue-lazyload@^1.2.6: resolved "https://registry.yarnpkg.com/vue-lazyload/-/vue-lazyload-1.2.6.tgz#baa04c172d52a812608eb12c7a6bfb14f5c91079" integrity sha512-6a61+pzwcfowhLRQiPdmRuJ40n/4fL/sEynu8KQZoCf5RVA0NH0X68vplLY0+lUM8mKNScYomaepV+hdjgnZhg== -vue-loader@^15.2.4, vue-loader@^15.4.2: - version "15.4.2" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.4.2.tgz#812bb26e447dd3b84c485eb634190d914ce125e2" - integrity sha512-nVV27GNIA9MeoD8yQ3dkUzwlAaAsWeYSWZHsu/K04KCD339lW0Jv2sJWsjj3721SP7sl2lYdPmjcHgkWQSp5bg== +vue-loader@^15.2.4, vue-loader@^15.4.2, vue-loader@^15.5.1: + version "15.7.0" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.7.0.tgz#27275aa5a3ef4958c5379c006dd1436ad04b25b3" + integrity sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA== dependencies: - "@vue/component-compiler-utils" "^2.0.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -vue-loader@^15.5.1: - version "15.5.1" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.5.1.tgz#e005d5fc2481a55a19910f0dcf434206d68acc2a" - integrity sha512-gsTA9xRzu9jGBzkcrAB8my14RkHMzdr5rY/mCFmxgY2tOVsd2Z1MaYCDXHu5nX6PyHAsVK2/hXmarPln/2MiIw== - dependencies: - "@vue/component-compiler-utils" "^2.4.0" + "@vue/component-compiler-utils" "^2.5.1" hash-sum "^1.0.2" loader-utils "^1.1.0" vue-hot-reload-api "^2.3.0" vue-style-loader "^4.1.0" vue-meta@^1.5.3: - version "1.5.6" - resolved "https://registry.yarnpkg.com/vue-meta/-/vue-meta-1.5.6.tgz#8c6e56e560217c63637bb9ed66434df15c162057" - integrity sha512-0MK3VGtAeZvGBkWmvCIsTE3LzoXvfbbduF1vbNOa491tYw7E1IlLMsmdr0DNypIdrFGS4NmOajVMJcDXCSp2VA== + version "1.6.0" + resolved "https://registry.yarnpkg.com/vue-meta/-/vue-meta-1.6.0.tgz#89b664f6011a207e098e8ba3b9d32e29c819b65d" + integrity sha512-LLHejsOYbJiSEDSgZvjHB3fFY7lUxsDFLkuSqf5eBohEvhhddBTOHa3heoFTcI5sxsZSZt26uUzoLVe4CT6Y4A== dependencies: - deepmerge "^2.2.1" + deepmerge "^3.2.0" lodash.isplainobject "^4.0.6" + lodash.uniqueid "^4.0.1" object-assign "^4.1.1" vue-no-ssr@^0.2.2: @@ -14666,28 +14636,14 @@ vue-progressbar@^0.7.5: integrity sha512-VeNG/inMsFbvdCTS7lJ1gjDAKSUZdqkhW9gS1tb0we1rqFKxR+BCEiVUgw5C84vODKb14M2GWHTw0WVdpoVg6g== vue-router@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be" - integrity sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg== - -vue-server-renderer@^2.5.16: - version "2.5.17" - resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.5.17.tgz#c1f24815a4b12a2797c154549b29b44b6be004b5" - integrity sha512-n62Fg4xv9ouxNloW2U3Bru2Jj+DkbnnrlzwuTkaU1o7CIDifG+r0+ILLMW0eVjgCjhKefHTYjwJ49RJ3bCjv1Q== - dependencies: - chalk "^1.1.3" - hash-sum "^1.0.2" - he "^1.1.0" - lodash.template "^4.4.0" - lodash.uniq "^4.5.0" - resolve "^1.2.0" - serialize-javascript "^1.3.0" - source-map "0.5.6" + version "3.0.6" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.6.tgz#2e4f0f9cbb0b96d0205ab2690cfe588935136ac3" + integrity sha512-Ox0ciFLswtSGRTHYhGvx2L44sVbTPNS+uD2kRISuo8B39Y79rOo0Kw0hzupTmiVtftQYCZl87mwldhh2L9Aquw== -vue-server-renderer@^2.6.6: - version "2.6.6" - resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.6.tgz#a2b1174cf1914817147b34789cc1a6baa0672aa1" - integrity sha512-dJ4IrIilS3nhxpOrR12+IKGu9Meg8L0t/W/e/UNSXKyh9EkwDqFPK0nZTfGPudXzr9FMQfg2hK6p2RMydPRU2Q== +vue-server-renderer@^2.5.16, vue-server-renderer@^2.6.6: + version "2.6.10" + resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz#cb2558842ead360ae2ec1f3719b75564a805b375" + integrity sha512-UYoCEutBpKzL2fKCwx8zlRtRtwxbPZXKTqbl2iIF4yRZUNO/ovrHyDAJDljft0kd+K0tZhN53XRHkgvCZoIhug== dependencies: chalk "^1.1.3" hash-sum "^1.0.2" @@ -14714,36 +14670,23 @@ vue-style-loader@^4.1.0: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@^2.5.16: - version "2.5.17" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.17.tgz#52a4a078c327deb937482a509ae85c06f346c3cb" - integrity sha512-63uI4syCwtGR5IJvZM0LN5tVsahrelomHtCxvRkZPJ/Tf3ADm1U1wG6KWycK3qCfqR+ygM5vewUvmJ0REAYksg== - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - -vue-template-compiler@^2.6.6: - version "2.6.6" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.6.tgz#a807acbf3d51971d3721d75ecb1b927b517c1a02" - integrity sha512-OakxDGyrmMQViCjkakQFbDZlG0NibiOzpLauOfyCUVRQc9yPmTqpiz9nF0VeA+dFkXegetw0E5x65BFhhLXO0A== +vue-template-compiler@^2.5.16, vue-template-compiler@^2.6.6: + version "2.6.10" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz#323b4f3495f04faa3503337a82f5d6507799c9cc" + integrity sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg== dependencies: de-indent "^1.0.2" he "^1.1.0" -vue-template-es2015-compiler@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18" - integrity sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg== - -vue@^2.5.16: - version "2.5.17" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada" - integrity sha512-mFbcWoDIJi0w0Za4emyLiW72Jae0yjANHbCVquMKijcavBGypqlF7zHRgMa5k4sesdv7hv2rB4JPdZfR+TPfhQ== +vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" + integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== -vue@^2.6.6: - version "2.6.6" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.6.tgz#dde41e483c11c46a7bf523909f4f2f816ab60d25" - integrity sha512-Y2DdOZD8sxApS+iUlwv1v8U1qN41kq6Kw45lM6nVZKhygeWA49q7VCCXkjXqeDBXgurrKWkYQ9cJeEJwAq0b9Q== +vue@^2.5.16, vue@^2.6.6: + version "2.6.10" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637" + integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ== vuelidate@^0.6.2: version "0.6.2" @@ -14764,9 +14707,9 @@ vuepress-html-webpack-plugin@^3.2.0: util.promisify "1.0.0" vuepress@^0.14.2: - version "0.14.10" - resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-0.14.10.tgz#070281ad0c9d48e7c848eb9511c96ceb106414ab" - integrity sha512-upD0br3AUmZQ+kNJMg135jW36JjYAdShl6XYwDmVMw4XbtcLDSMGWTLqLCQN3PTIs/7TgiJ3cLWNL1ps63gyUQ== + version "0.14.11" + resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-0.14.11.tgz#fc6ba0e609e3433a8070e95301b4d987712b2a08" + integrity sha512-5iB7iWeEG7GtEiNwmS2LOcifp2V93aZ4+oO9pq8OcUgOWay9/NqmNqzg7KQ7AJ0puZGg0tYwUKKjifIWIPE8jQ== dependencies: "@babel/core" "7.0.0-beta.47" "@vue/babel-preset-app" "3.0.0-beta.11" @@ -14831,9 +14774,9 @@ vuex-router-sync@^5.0.0: integrity sha512-Mry2sO4kiAG64714X1CFpTA/shUH1DmkZ26DFDtwoM/yyx6OtMrc+MxrU+7vvbNLO9LSpgwkiJ8W+rlmRtsM+w== vuex@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2" - integrity sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w== + version "3.1.0" + resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.0.tgz#634b81515cf0cfe976bd1ffe9601755e51f843b9" + integrity sha512-mdHeHT/7u4BncpUZMlxNaIdcN/HIt1GsGG5LKByArvYG/v6DvHcOxvDCts+7SRdCoIRGllK8IMZvQtQXLppDYg== vxx@^1.2.0: version "1.2.2" @@ -14888,11 +14831,12 @@ webidl-conversions@^4.0.2: integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== webpack-bundle-analyzer@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz#dbc7fff8f52058b6714a20fddf309d0790e3e0a0" - integrity sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw== + version "3.3.2" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz#3da733a900f515914e729fcebcd4c40dde71fc6f" + integrity sha512-7qvJLPKB4rRWZGjVp5U1KEjwutbDHSKboAl0IfafnrdXMrgC0tOtZbQD6Rw0u4cmpgRN4O02Fc0t8eAT+FgGzA== dependencies: - acorn "^5.7.3" + acorn "^6.0.7" + acorn-walk "^6.1.1" bfj "^6.1.1" chalk "^2.4.1" commander "^2.18.0" @@ -14914,27 +14858,28 @@ webpack-chain@^4.6.0: javascript-stringify "^1.6.0" webpack-cli@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" - integrity sha512-Cnqo7CeqeSvC6PTdts+dywNi5CRlIPbLx1AoUPK2T6vC1YAugMG3IOoO9DmEscd+Dghw7uRlnzV1KwOe5IrtgQ== + version "3.3.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.1.tgz#98b0499c7138ba9ece8898bd99c4f007db59909d" + integrity sha512-c2inFU7SM0IttEgF7fK6AaUsbBnORRzminvbyRKS+NlbQHVZdCtzKBlavRL5359bFsywXGRAItA5di/IruC8mg== dependencies: chalk "^2.4.1" cross-spawn "^6.0.5" enhanced-resolve "^4.1.0" - global-modules-path "^2.3.0" + findup-sync "^2.0.0" + global-modules "^1.0.0" import-local "^2.0.0" interpret "^1.1.0" loader-utils "^1.1.0" supports-color "^5.5.0" v8-compile-cache "^2.0.2" - yargs "^12.0.2" + yargs "^12.0.5" webpack-dev-middleware@^3.0.0, webpack-dev-middleware@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890" - integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.6.2.tgz#f37a27ad7c09cd7dc67cd97655413abaa1f55942" + integrity sha512-A47I5SX60IkHrMmZUlB0ZKSWi29TZTcPz7cha1Z75yYOsgWh/1AcPmQEbC8ZIbU3A1ytSv1PMU0PyPz2Lmz2jg== dependencies: - memory-fs "~0.4.1" + memory-fs "^0.4.1" mime "^2.3.1" range-parser "^1.0.3" webpack-log "^2.0.0" @@ -14952,9 +14897,9 @@ webpack-hot-client@^3.0.0: ws "^4.0.0" webpack-hot-middleware@^2.24.3: - version "2.24.3" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.24.3.tgz#5bb76259a8fc0d97463ab517640ba91d3382d4a6" - integrity sha512-pPlmcdoR2Fn6UhYjAhp1g/IJy1Yc9hD+T6O9mjRcWV2pFbBjIFoJXhP0CoD0xPOhWJuWXuZXGBga9ybbOdzXpg== + version "2.24.4" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.24.4.tgz#0ae1eeca000c6ffdcb22eb574d0e6d7717672b0f" + integrity sha512-YFA4j2tg9WPkcQKcyHMZn6787QngWf/ahXvAJRZ1ripySa+4ihjzDcYBsfC4ihOucTd02IJ12v+VTGMsEGxq0w== dependencies: ansi-html "0.0.7" html-entities "^1.2.0" @@ -14980,9 +14925,9 @@ webpack-log@^2.0.0: uuid "^3.3.2" webpack-merge@^4.1.2, webpack-merge@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.4.tgz#0fde38eabf2d5fd85251c24a5a8c48f8a3f4eb7b" - integrity sha512-TmSe1HZKeOPey3oy1Ov2iS3guIZjWvMT2BBJDzzT5jScHTjVC3mpjJofgueEzaEd6ibhxRDD6MIblDr8tzh8iQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4" + integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw== dependencies: lodash "^4.17.5" @@ -15025,16 +14970,16 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0: source-map "~0.6.1" webpack@^4.25.1, webpack@^4.8.1: - version "4.27.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.27.1.tgz#5f2e2db446d2266376fa15d7d2277a1a9c2e12bb" - integrity sha512-WArHiLvHrlfyRM8i7f+2SFbr/XbQ0bXqTkPF8JpHOzub5482Y3wx7rEO8stuLGOKOgZJcqcisLhD7LrM/+fVMw== - dependencies: - "@webassemblyjs/ast" "1.7.11" - "@webassemblyjs/helper-module-context" "1.7.11" - "@webassemblyjs/wasm-edit" "1.7.11" - "@webassemblyjs/wasm-parser" "1.7.11" - acorn "^5.6.2" - acorn-dynamic-import "^3.0.0" + version "4.30.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.30.0.tgz#aca76ef75630a22c49fcc235b39b4c57591d33a9" + integrity sha512-4hgvO2YbAFUhyTdlR4FNyt2+YaYBYHavyzjCMbZzgglo02rlKi/pcsEzwCuCpsn1ryzIl1cq/u8ArIKu8JBYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.0.5" + acorn-dynamic-import "^4.0.0" ajv "^6.1.0" ajv-keywords "^3.1.0" chrome-trace-event "^1.0.0" @@ -15048,16 +14993,16 @@ webpack@^4.25.1, webpack@^4.8.1: mkdirp "~0.5.0" neo-async "^2.5.0" node-libs-browser "^2.0.0" - schema-utils "^0.4.4" + schema-utils "^1.0.0" tapable "^1.1.0" terser-webpack-plugin "^1.1.0" watchpack "^1.5.0" webpack-sources "^1.3.0" webpackbar@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-2.6.3.tgz#4f2d0078375acfe95c0e55227771a2ed98ecc5c9" - integrity sha512-UlTm7Yz4meJV0THhZMrgRTE9v/vZ0xfUoJ/eOig98TvzsqNiW+FLSv5WaZeML3uJUPrMQ6K5jo1FJJFXNCc8+g== + version "2.6.4" + resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-2.6.4.tgz#9118dde6b8f513a2d50ce630952157bca9218c6f" + integrity sha512-uQzJwuX172E+Vnk2NRFSM1hZBMCXd2CIpRUl1hr5tbAndTGVnDmYXQKHsbgbCKQXFJKKAl8EHYsdeauJZu2Qvg== dependencies: chalk "^2.4.1" consola "^1.4.3" @@ -15147,11 +15092,11 @@ widest-line@^2.0.0: string-width "^2.1.1" windows-release@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.1.0.tgz#8d4a7e266cbf5a233f6c717dac19ce00af36e12e" - integrity sha512-hBb7m7acFgQPQc222uEQTmdcGLeBmQLNLFIh0rDk3CwFOBrfjefLzEfEfmpMq8Af/n/GnFf3eYf203FY1PmudA== + version "3.2.0" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" + integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== dependencies: - execa "^0.10.0" + execa "^1.0.0" winston@^2.2.0: version "2.4.4" @@ -15302,7 +15247,7 @@ worker-farm@^1.5.2: wrap-ansi@^2.0.0: version "2.1.0" - resolved "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= dependencies: string-width "^1.0.1" @@ -15331,9 +15276,9 @@ write-file-atomic@2.4.1: signal-exit "^3.0.2" write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== + version "2.4.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -15359,6 +15304,13 @@ write-pkg@^3.1.0: sort-keys "^2.0.0" write-json-file "^2.2.0" +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -15368,7 +15320,7 @@ write@^0.2.1: ws@^4.0.0: version "4.1.0" - resolved "http://registry.npmjs.org/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" integrity sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA== dependencies: async-limiter "~1.0.0" @@ -15382,9 +15334,9 @@ ws@^5.2.0: async-limiter "~1.0.0" ws@^6.0.0: - version "6.1.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" - integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== dependencies: async-limiter "~1.0.0" @@ -15453,7 +15405,7 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" -yargs@^12.0.1, yargs@^12.0.2: +yargs@^12.0.1, yargs@^12.0.2, yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== @@ -15490,6 +15442,14 @@ yargs@^7.0.0: y18n "^3.2.1" yargs-parser "^5.0.0" +yauzl@2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yauzl@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" @@ -15497,14 +15457,6 @@ yauzl@2.4.1: dependencies: fd-slicer "~1.0.1" -yauzl@2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.8.0.tgz#79450aff22b2a9c5a41ef54e02db907ccfbf9ee2" - integrity sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI= - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.0.1" - ylru@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" @@ -15515,17 +15467,18 @@ yn@^2.0.0: resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= -zen-observable-ts@^0.8.11: - version "0.8.11" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" - integrity sha512-8bs7rgGV4kz5iTb9isudkuQjtWwPnQ8lXq6/T76vrepYZVMsDEv6BXaEA+DHdJSK3KVLduagi9jSpSAJ5NgKHw== +zen-observable-ts@^0.8.18: + version "0.8.18" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.18.tgz#ade44b1060cc4a800627856ec10b9c67f5f639c8" + integrity sha512-q7d05s75Rn1j39U5Oapg3HI2wzriVwERVo4N7uFGpIYuHB9ff02P/E92P9B8T7QVC93jCMHpbXH7X0eVR5LA7A== dependencies: + tslib "^1.9.3" zen-observable "^0.8.0" zen-observable@^0.8.0: - version "0.8.11" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" - integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ== + version "0.8.14" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.14.tgz#d33058359d335bc0db1f0af66158b32872af3bf7" + integrity sha512-kQz39uonEjEESwh+qCi83kcC3rZJGh4mrZW7xjkSQYXkq//JZHTtKo+6yuVloTgMtzsIWOJrjIrKvk/dqm0L5g== zepto@^1.2.0: version "1.2.0" From c4d9991d57692dbb9a45925292b104822a0901b6 Mon Sep 17 00:00:00 2001 From: ResuBaka Date: Wed, 1 May 2019 11:11:18 +0200 Subject: [PATCH 03/18] Changed prettier parameter path to the right folders --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ec8b78c93..7c2e51af4a 100755 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "test:e2e:ci": "cypress run", "lint": "eslint --ext .js,.vue,.ts core src", "lerna": "lerna", - "format": "prettier --write 'core/modules/catalog/**/*.{js,vue,ts,json}'" + "format": "prettier --write '{core,src}/**/*.{js,vue,ts,json}'" }, "dependencies": { "@types/webpack": "^4.4.23", From b395e090683dedb5010eaf2d63f6657446f27e3e Mon Sep 17 00:00:00 2001 From: ResuBaka Date: Wed, 1 May 2019 20:23:08 +0200 Subject: [PATCH 04/18] Fixed eslint issue with semicolons --- .eslintrc.js | 16 +++++++++------- package.json | 6 +++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 85fdeececc..40e933c236 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,11 +1,11 @@ module.exports = { root: true, - env: { 'browser': true, 'jest': true }, + env: { browser: true, jest: true }, parser: 'vue-eslint-parser', parserOptions: { parser: '@typescript-eslint/parser', ecmaVersion: 8, - sourceType: "module" + sourceType: 'module' }, // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style extends: [ @@ -19,6 +19,9 @@ module.exports = { plugins: ['vue', 'vue-storefront', '@typescript-eslint'], // add your custom rules here rules: { + '@typescript-eslint/camelcase': 0, + semi: 'off', + '@typescript-eslint/semi': ['error'], // Prettier rules these rulles should never be hit, as prettier formattes the code so // so these will never get hit 'no-tabs': 'error', @@ -36,12 +39,11 @@ module.exports = { } ], 'array-bracket-spacing': ['error', 'never'], - semi: ['error', 'always'], // disabled the rules because of line breaks that comes from prettier 'standard/computed-property-even-spacing': 0, /* max attributes-per-line and order-in-components - ** we should use this later, when eslint-plugin-vue will support auto fixing this - */ + ** we should use this later, when eslint-plugin-vue will support auto fixing this + */ 'vue/max-attributes-per-line': 0, 'vue/order-in-components': 0, 'vue/attributes-order': 0, @@ -54,10 +56,10 @@ module.exports = { 'generator-star-spacing': 0, // allow debugger during development 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, - 'no-restricted-imports': [2, { 'paths': ['lodash-es'] }], + 'no-restricted-imports': [2, { paths: ['lodash-es'] }], 'vue-storefront/no-corecomponent-import': 'error', 'vue-storefront/no-corecomponent': 'error', 'vue-storefront/no-corepage-import': 'error', 'vue-storefront/no-corepage': 'error' } -} +}; diff --git a/package.json b/package.json index 7c2e51af4a..64995409f6 100755 --- a/package.json +++ b/package.json @@ -92,8 +92,8 @@ "@babel/preset-env": "^7.3.4", "@types/jest": "^24.0.11", "@types/node": "^10.12.18", - "@typescript-eslint/eslint-plugin": "^1.7.0", - "@typescript-eslint/parser": "^1.7.0", + "@typescript-eslint/eslint-plugin": "^1.7.1-alpha.17", + "@typescript-eslint/parser": "^1.7.1-alpha.17", "@vue/test-utils": "^1.0.0-beta.29", "app-root-path": "^2.0.1", "autoprefixer": "^8.6.2", @@ -120,7 +120,7 @@ "eslint-plugin-prettier": "^3.0.1", "eslint-plugin-promise": "^3.7.0", "eslint-plugin-standard": "^3.1.0", - "eslint-plugin-vue": "^4.5.0", + "eslint-plugin-vue": "^5.2.2", "eslint-plugin-vue-storefront": "^0.0.1", "file-loader": "^1.1.11", "fs-exists-sync": "^0.1.0", From b1e758894929ddb595686ce4413bd399ca1d106c Mon Sep 17 00:00:00 2001 From: ResuBaka Date: Wed, 1 May 2019 20:24:29 +0200 Subject: [PATCH 05/18] Formatted source code with prettier --- core/app.ts | 148 +- core/build/dev-server.js | 84 +- core/build/theme-path.js | 21 +- core/build/webpack.base.config.ts | 115 +- core/build/webpack.client.config.ts | 24 +- core/build/webpack.prod.client.config.ts | 11 +- core/build/webpack.prod.server.config.ts | 6 +- core/build/webpack.prod.sw.config.ts | 139 +- core/build/webpack.server.config.ts | 12 +- core/client-entry.ts | 489 ++++--- core/compatibility/components/AddToCart.js | 6 +- core/compatibility/components/Breadcrumbs.js | 2 +- .../components/GenericSelector.js | 4 +- core/compatibility/components/Notification.js | 42 +- core/compatibility/components/Overlay.js | 10 +- .../compatibility/components/PriceSelector.js | 39 +- core/compatibility/components/SortBy.js | 12 +- .../components/ValidationError.js | 2 +- .../components/blocks/Auth/Login.js | 4 +- .../components/blocks/Auth/Register.js | 4 +- .../components/blocks/Category/Sidebar.js | 62 +- .../components/blocks/Header/AccountIcon.js | 12 +- .../components/blocks/Header/CompareIcon.js | 8 +- .../components/blocks/Header/HamburgerIcon.js | 8 +- .../components/blocks/Header/MicrocartIcon.js | 16 +- .../components/blocks/Header/ReturnIcon.js | 8 +- .../components/blocks/Header/SearchIcon.js | 8 +- .../components/blocks/Header/WishlistIcon.js | 24 +- .../components/blocks/Microcart/Microcart.js | 16 +- .../components/blocks/Microcart/Product.js | 55 +- .../blocks/MyAccount/MyNewsletter.js | 54 +- .../components/blocks/MyAccount/MyOrder.js | 4 +- .../components/blocks/MyAccount/MyOrders.js | 4 +- .../components/blocks/MyAccount/MyProfile.js | 4 +- .../blocks/MyAccount/MyShippingDetails.js | 4 +- .../blocks/SearchPanel/SearchPanel.js | 18 +- .../blocks/SidebarMenu/SidebarMenu.js | 40 +- .../components/blocks/Wishlist/Product.js | 8 +- .../components/blocks/Wishlist/Wishlist.js | 14 +- core/compatibility/lib/extensions.ts | 23 +- core/compatibility/plugins/config/index.js | 16 +- core/compatibility/plugins/event-bus/index.js | 42 +- core/compatibility/plugins/index.js | 9 +- core/filters/capitalize.js | 8 +- core/filters/date.js | 8 +- core/filters/html-decode.js | 6 +- core/filters/index.js | 14 +- core/filters/price.js | 30 +- core/filters/product-messages/index.js | 8 +- core/filters/product-messages/typed.ts | 8 +- core/filters/strip-html.js | 6 +- core/helpers/exceptions.js | 12 +- core/helpers/index.ts | 194 ++- core/helpers/initCacheStorage.ts | 49 +- core/helpers/log.js | 34 +- core/i18n/index.ts | 70 +- core/i18n/scripts/translation.preprocessor.js | 83 +- core/lib/async-data-loader.ts | 76 +- core/lib/logger.ts | 174 ++- core/lib/module/helpers.ts | 57 +- core/lib/module/index.ts | 213 +-- core/lib/module/types.ts | 46 +- core/lib/multistore.ts | 238 ++-- core/lib/passive-listeners.js | 87 +- core/lib/router-manager.ts | 29 +- core/lib/search.ts | 201 ++- .../search/adapter/api/elasticsearch/boost.js | 18 +- .../adapter/api/elasticsearch/mapping.js | 18 +- .../adapter/api/elasticsearch/multimatch.js | 50 +- .../search/adapter/api/elasticsearch/score.js | 41 +- .../search/adapter/api/elasticsearchQuery.js | 170 ++- core/lib/search/adapter/api/searchAdapter.ts | 217 +-- core/lib/search/adapter/graphql/gqlQuery.js | 106 +- .../adapter/graphql/processor/processType.ts | 58 +- .../search/adapter/graphql/searchAdapter.ts | 268 ++-- .../search/adapter/searchAdapterFactory.js | 28 +- core/lib/search/searchQuery.js | 84 +- core/lib/sync/index.ts | 144 +- core/lib/sync/task.ts | 406 ++++-- core/lib/sync/types/Task.ts | 22 +- core/lib/test/unit/logger.spec.ts | 400 +++--- core/lib/themes.ts | 15 +- core/mixins/composite.js | 39 +- core/mixins/index.js | 9 +- core/mixins/multistore.js | 20 +- core/mixins/onEscapePress.js | 16 +- core/mixins/thumbnail.js | 8 +- core/modules-entry.ts | 15 +- .../breadcrumbs/components/Breadcrumbs.ts | 10 +- core/modules/breadcrumbs/helpers/index.ts | 14 +- core/modules/breadcrumbs/index.ts | 12 +- core/modules/breadcrumbs/store/index.ts | 14 +- core/modules/cart/components/AddToCart.ts | 8 +- core/modules/cart/components/Microcart.ts | 36 +- .../cart/components/MicrocartButton.ts | 17 +- core/modules/cart/components/Product.ts | 23 +- core/modules/cart/helpers/cartCacheHandler.ts | 24 +- core/modules/cart/hooks/afterRegistration.ts | 8 +- core/modules/cart/hooks/beforeRegistration.ts | 24 +- core/modules/cart/index.ts | 12 +- core/modules/cart/store/actions.ts | 1210 +++++++++++------ core/modules/cart/store/getters.ts | 97 +- core/modules/cart/store/index.ts | 15 +- core/modules/cart/store/mutation-types.ts | 26 +- core/modules/cart/store/mutations.ts | 150 +- .../test/unit/components/AddToCart.spec.ts | 20 +- .../test/unit/components/Microcart.spec.ts | 39 +- .../unit/components/MicrocartButton.spec.ts | 12 +- .../cart/test/unit/components/Product.spec.ts | 46 +- .../unit/helpers/cartCacheHandler.spec.ts | 101 +- .../test/unit/hooks/afterRegistration.spec.ts | 26 +- .../unit/hooks/beforeRegistration.spec.ts | 27 +- core/modules/cart/test/unit/index.spec.ts | 10 +- .../cart/test/unit/store/actions.spec.ts | 437 +++--- .../cart/test/unit/store/getters.spec.ts | 134 +- .../cart/test/unit/store/index.spec.ts | 6 +- .../cart/test/unit/store/mutations.spec.ts | 618 +++++---- core/modules/cart/types/AppliedCoupon.ts | 6 +- core/modules/cart/types/CartItem.ts | 16 +- core/modules/cart/types/CartItemOption.ts | 4 +- core/modules/cart/types/CartItemTotals.ts | 43 +- core/modules/cart/types/CartState.ts | 36 +- core/modules/cart/types/CartTotalSegments.ts | 5 +- .../cart/types/CartTotalSegmentsItem.ts | 10 +- .../catalog/components/CategoryFilters.ts | 44 +- .../catalog/components/CategorySort.ts | 14 +- .../catalog/components/ProductAttribute.ts | 42 +- .../catalog/components/ProductBundleOption.ts | 48 +- .../components/ProductBundleOptions.ts | 133 +- .../catalog/components/ProductCustomOption.ts | 36 +- .../components/ProductCustomOptions.ts | 135 +- .../catalog/components/ProductGallery.ts | 7 +- .../modules/catalog/components/ProductTile.ts | 36 +- .../catalog/components/ProductVideo.ts | 28 +- core/modules/catalog/components/Search.ts | 114 +- core/modules/catalog/helpers/index.ts | 916 ++++++++----- core/modules/catalog/helpers/optionLabel.ts | 32 +- core/modules/catalog/helpers/tax.ts | 234 ++-- .../catalog/hooks/beforeRegistration.ts | 62 +- core/modules/catalog/index.ts | 34 +- core/modules/catalog/queries/common.js | 40 +- core/modules/catalog/queries/related.js | 24 +- core/modules/catalog/queries/searchPanel.js | 22 +- .../catalog/store/attribute/actions.ts | 114 +- .../catalog/store/attribute/getters.ts | 14 +- core/modules/catalog/store/attribute/index.ts | 14 +- .../catalog/store/attribute/mutation-types.ts | 4 +- .../catalog/store/attribute/mutations.ts | 60 +- .../modules/catalog/store/category/actions.ts | 776 +++++++---- .../modules/catalog/store/category/getters.ts | 10 +- core/modules/catalog/store/category/index.ts | 14 +- .../catalog/store/category/mutation-types.ts | 21 +- .../catalog/store/category/mutations.ts | 109 +- core/modules/catalog/store/product/actions.ts | 1172 ++++++++++------ core/modules/catalog/store/product/getters.ts | 24 +- core/modules/catalog/store/product/index.ts | 14 +- .../catalog/store/product/mutation-types.ts | 28 +- .../catalog/store/product/mutations.ts | 93 +- core/modules/catalog/store/stock/actions.ts | 147 +- core/modules/catalog/store/stock/index.ts | 11 +- core/modules/catalog/store/tax/actions.ts | 44 +- core/modules/catalog/store/tax/index.ts | 12 +- .../catalog/store/tax/mutation-types.ts | 4 +- core/modules/catalog/store/tax/mutations.ts | 33 +- core/modules/catalog/types/AttributeState.ts | 8 +- core/modules/catalog/types/CategoryState.ts | 18 +- core/modules/catalog/types/Product.ts | 120 +- core/modules/catalog/types/ProductState.ts | 40 +- core/modules/catalog/types/StockState.ts | 2 +- core/modules/catalog/types/TaxState.ts | 2 +- .../checkout/components/CartSummary.ts | 6 +- .../checkout/components/OrderReview.ts | 83 +- core/modules/checkout/components/Payment.ts | 174 ++- .../checkout/components/PersonalDetails.ts | 58 +- core/modules/checkout/components/Product.ts | 18 +- core/modules/checkout/components/Shipping.ts | 157 ++- .../checkout/hooks/afterRegistration.ts | 44 +- .../checkout/hooks/beforeRegistration.ts | 25 +- core/modules/checkout/index.ts | 28 +- .../checkout/store/checkout/actions.ts | 116 +- .../checkout/store/checkout/getters.ts | 10 +- core/modules/checkout/store/checkout/index.ts | 14 +- .../checkout/store/checkout/mutation-types.ts | 28 +- .../checkout/store/checkout/mutations.ts | 54 +- core/modules/checkout/store/payment/index.ts | 44 +- core/modules/checkout/store/shipping/index.ts | 30 +- .../test/unit/components/CartSummary.spec.ts | 15 +- core/modules/checkout/types/CheckoutState.ts | 70 +- core/modules/checkout/types/PaymentState.ts | 2 +- core/modules/checkout/types/ShippingState.ts | 2 +- core/modules/cms/hooks/beforeRegistration.ts | 22 +- core/modules/cms/index.ts | 31 +- core/modules/cms/store/block/actions.ts | 123 +- core/modules/cms/store/block/getters.ts | 22 +- core/modules/cms/store/block/index.ts | 18 +- .../modules/cms/store/block/mutation-types.ts | 6 +- core/modules/cms/store/block/mutations.ts | 20 +- core/modules/cms/store/hierarchy/actions.ts | 39 +- core/modules/cms/store/hierarchy/index.ts | 13 +- .../cms/store/hierarchy/mutation-types.ts | 5 +- core/modules/cms/store/page/actions.ts | 152 ++- core/modules/cms/store/page/getters.ts | 12 +- core/modules/cms/store/page/index.ts | 16 +- core/modules/cms/store/page/mutation-types.ts | 8 +- core/modules/cms/store/page/mutations.ts | 24 +- core/modules/cms/store/plugin.ts | 38 +- core/modules/cms/types/CmsBlockState.ts | 2 +- core/modules/cms/types/CmsHierarchyState.ts | 2 +- core/modules/cms/types/CmsPageState.ts | 4 +- .../compare/components/AddToCompare.ts | 10 +- core/modules/compare/components/Compare.ts | 37 +- .../compare/components/CompareButton.ts | 8 +- core/modules/compare/components/Product.ts | 14 +- .../compare/hooks/afterRegistration.ts | 3 +- .../compare/hooks/beforeRegistration.ts | 24 +- core/modules/compare/index.ts | 16 +- .../compare/mixins/compareMountedMixin.js | 6 +- core/modules/compare/store/actions.ts | 62 +- core/modules/compare/store/getters.ts | 14 +- core/modules/compare/store/index.ts | 14 +- core/modules/compare/store/mutation-types.ts | 10 +- core/modules/compare/store/mutations.ts | 28 +- core/modules/compare/store/plugin.ts | 24 +- core/modules/compare/types/CompareState.ts | 4 +- core/modules/mailer/components/EmailForm.ts | 48 +- core/modules/mailer/index.ts | 10 +- core/modules/mailer/store/index.ts | 56 +- core/modules/mailer/types/MailItem.ts | 10 +- .../notification/components/Notification.ts | 8 +- core/modules/notification/index.ts | 10 +- core/modules/notification/store/index.ts | 41 +- .../notification/types/NotificationItem.ts | 16 +- .../notification/types/NotificationState.ts | 4 +- .../offline-order/components/CancelOrders.ts | 46 +- .../offline-order/components/ConfirmOrders.ts | 12 +- .../offline-order/extends/service-worker.js | 28 +- .../helpers/onNetworkStatusChange.ts | 62 +- core/modules/order/components/UserOrders.ts | 39 +- .../order/components/UserSingleOrder.ts | 55 +- .../modules/order/hooks/beforeRegistration.ts | 18 +- core/modules/order/index.ts | 10 +- core/modules/order/store/actions.ts | 98 +- core/modules/order/store/getters.ts | 10 +- core/modules/order/store/index.ts | 15 +- core/modules/order/store/mutation-types.ts | 15 +- core/modules/order/store/mutations.ts | 66 +- core/modules/order/store/order.schema.json | 197 +-- core/modules/order/types/Order.ts | 2 +- core/modules/order/types/OrderState.ts | 4 +- .../components/RecentlyViewed.js | 8 +- .../hooks/afterRegistration.ts | 6 +- core/modules/recently-viewed/index.ts | 16 +- core/modules/recently-viewed/store/actions.ts | 22 +- core/modules/recently-viewed/store/index.ts | 13 +- .../recently-viewed/store/mutation-types.ts | 6 +- .../recently-viewed/store/mutations.ts | 26 +- core/modules/recently-viewed/store/plugin.ts | 21 +- .../types/RecentlyViewedState.ts | 2 +- core/modules/review/components/AddReview.ts | 8 +- core/modules/review/components/Reviews.ts | 8 +- core/modules/review/index.ts | 10 +- core/modules/review/store/actions.ts | 100 +- core/modules/review/store/index.ts | 14 +- core/modules/review/store/mutation-types.ts | 4 +- core/modules/review/store/mutations.ts | 14 +- core/modules/review/types/ReviewRequest.ts | 2 +- core/modules/review/types/ReviewState.ts | 2 +- .../social-share/components/WebShare.vue | 30 +- core/modules/url/helpers/index.ts | 131 +- core/modules/url/index.ts | 20 +- core/modules/url/router/beforeEach.ts | 105 +- core/modules/url/store/actions.ts | 117 +- core/modules/url/store/index.ts | 12 +- core/modules/url/store/mutation-types.ts | 2 +- core/modules/url/store/mutations.ts | 10 +- core/modules/url/store/state.ts | 4 +- core/modules/url/types/UrlState.ts | 4 +- core/modules/user/components/AccountButton.ts | 25 +- core/modules/user/components/Login.ts | 57 +- core/modules/user/components/Register.ts | 73 +- core/modules/user/components/UserAccount.ts | 194 +-- .../user/components/UserShippingDetails.ts | 234 ++-- core/modules/user/hooks/afterRegistration.ts | 68 +- core/modules/user/hooks/beforeRegistration.ts | 36 +- core/modules/user/index.ts | 14 +- core/modules/user/router/beforeEach.ts | 30 +- core/modules/user/store/actions.ts | 403 +++--- core/modules/user/store/getters.ts | 18 +- core/modules/user/store/index.ts | 14 +- core/modules/user/store/mutation-types.ts | 20 +- core/modules/user/store/mutations.ts | 48 +- core/modules/user/types/UserProfile.ts | 22 +- core/modules/user/types/UserState.ts | 18 +- .../wishlist/components/AddToWishlist.ts | 18 +- .../wishlist/components/IsOnWishlist.ts | 20 +- core/modules/wishlist/components/Product.ts | 16 +- .../wishlist/components/RemoveFromWishlist.ts | 14 +- core/modules/wishlist/components/Wishlist.ts | 22 +- .../wishlist/components/WishlistButton.ts | 6 +- core/modules/wishlist/index.ts | 17 +- .../wishlist/mixins/wishlistMountedMixin.js | 6 +- core/modules/wishlist/store/actions.ts | 66 +- core/modules/wishlist/store/index.ts | 15 +- core/modules/wishlist/store/mutation-types.ts | 10 +- core/modules/wishlist/store/mutations.ts | 34 +- core/modules/wishlist/store/plugin.ts | 24 +- core/modules/wishlist/types/WishlistState.ts | 4 +- core/pages/Category.js | 475 ++++--- core/pages/Checkout.js | 436 +++--- core/pages/CmsPage.js | 74 +- core/pages/Compare.js | 8 +- core/pages/Compilation.js | 2 +- core/pages/Error.js | 25 +- core/pages/Home.js | 44 +- core/pages/MyAccount.js | 62 +- core/pages/PageNotFound.js | 31 +- core/pages/Product.js | 393 ++++-- core/scripts/all.js | 103 +- core/scripts/cache.js | 68 +- core/scripts/installer.js | 818 ++++++----- core/scripts/resolvers/resolveGraphQL.js | 72 +- core/scripts/server.js | 412 +++--- core/scripts/utils/api-status.js | 10 +- core/scripts/utils/cache-instance.js | 24 +- core/server-entry.ts | 225 +-- core/service-worker/index.js | 4 +- core/service-worker/registration.js | 30 +- core/store/index.ts | 18 +- core/store/lib/entities.ts | 44 +- core/store/lib/filters.ts | 6 +- core/store/lib/storage.ts | 517 ++++--- core/types/RootState.ts | 60 +- core/types/isomorphic-fetch.d.ts | 2 +- core/types/search/HttpQuery.ts | 14 +- core/types/search/SearchRequest.ts | 24 +- core/types/search/SearchResponse.ts | 20 +- src/extensions/index.ts | 4 +- src/modules/amp-renderer/index.ts | 10 +- src/modules/amp-renderer/router.ts | 4 +- .../claims/hooks/beforeRegistration.ts | 24 +- src/modules/claims/index.ts | 12 +- src/modules/claims/store/actions.ts | 56 +- src/modules/claims/store/index.ts | 11 +- src/modules/claims/types/ClaimsState.ts | 3 +- .../components/DroppointMap.vue | 209 +-- src/modules/droppoint-shipping/index.ts | 12 +- .../droppoint-shipping/store/actions.ts | 16 +- src/modules/droppoint-shipping/store/index.ts | 8 +- .../hooks/afterRegistration.ts | 14 +- .../hooks/beforeRegistration.ts | 14 +- src/modules/google-analytics/index.ts | 12 +- .../hooks/afterRegistration.ts | 89 +- .../hooks/beforeRegistration.ts | 25 +- src/modules/google-tag-manager/index.ts | 17 +- src/modules/homepage/index.ts | 8 +- src/modules/hotjar/hooks/afterRegistration.ts | 27 +- src/modules/hotjar/index.ts | 4 +- src/modules/index.ts | 42 +- .../components/InstantCheckout.vue | 329 +++-- src/modules/instant-checkout/index.ts | 11 +- .../magento-2-cms/components/CmsData.vue | 57 +- .../magento-2-cms/hooks/afterRegistration.ts | 17 +- src/modules/magento-2-cms/index.ts | 10 +- src/modules/magento-2-cms/store/index.js | 52 +- src/modules/mailchimp/components/Subscribe.ts | 37 +- .../mailchimp/components/Unsubscribe.ts | 21 +- src/modules/mailchimp/index.ts | 19 +- src/modules/mailchimp/store/index.ts | 64 +- src/modules/mailchimp/store/mutation-types.ts | 6 +- src/modules/mailchimp/types/mailchimpState.ts | 6 +- .../components/ExtensionComponent.ts | 29 +- .../hooks/afterRegistration.ts | 9 +- .../hooks/beforeRegistration.ts | 24 +- src/modules/module-template/index.ts | 23 +- .../module-template/pages/ExtensionPage.vue | 10 +- .../module-template/queries/exampleQuery.ts | 10 +- .../module-template/router/afterEach.ts | 6 +- .../module-template/router/beforeEach.ts | 8 +- src/modules/module-template/store/actions.ts | 37 +- src/modules/module-template/store/getters.ts | 4 +- src/modules/module-template/store/index.ts | 14 +- .../module-template/store/mutation-types.ts | 4 +- .../module-template/store/mutations.ts | 16 +- src/modules/module-template/store/plugin.ts | 14 +- src/modules/module-template/store/state.ts | 4 +- .../module-template/types/ExampleState.ts | 4 +- .../hooks/afterRegistration.ts | 44 +- src/modules/payment-backend-methods/index.ts | 16 +- .../store/mutation-types.ts | 2 +- .../components/Info.vue | 8 +- .../hooks/afterRegistration.ts | 62 +- src/modules/payment-cash-on-delivery/index.ts | 8 +- src/modules/promoted-offers/index.ts | 8 +- src/modules/promoted-offers/store/actions.ts | 42 +- src/modules/promoted-offers/store/getters.ts | 12 +- src/modules/promoted-offers/store/index.ts | 14 +- .../promoted-offers/store/mutations.ts | 16 +- .../types/PromotedOffersState.ts | 10 +- src/modules/raw-output-example/index.ts | 8 +- .../raw-output-example/pages/NoJSExample.vue | 40 +- .../pages/NoLayoutAppendPrependExample.vue | 39 +- .../pages/RawOutputExample.vue | 25 +- .../raw-output-example/router/routes.ts | 20 +- .../hooks/afterRegistration.ts | 58 +- .../sample-custom-entity-graphql/index.ts | 10 +- src/modules/ui-store/index.ts | 66 +- src/server/index.js | 6 +- src/server/robots.js | 9 +- .../default-amp/components/core/Header.vue | 85 +- .../components/core/ProductListing.vue | 27 +- .../components/core/ProductTile.vue | 72 +- src/themes/default-amp/index.js | 14 +- src/themes/default-amp/pages/Category.vue | 201 +-- src/themes/default-amp/pages/Product.vue | 160 ++- src/themes/default-amp/router/index.ts | 124 +- src/themes/default-amp/webpack.config.js | 6 +- src/themes/default/App.vue | 21 +- src/themes/default/assets/manifest.json | 88 +- .../default/components/core/AddToCart.vue | 32 +- .../default/components/core/Breadcrumbs.vue | 7 +- .../default/components/core/ColorSelector.vue | 58 +- .../components/core/CookieNotification.vue | 54 +- .../components/core/GenericSelector.vue | 58 +- .../components/core/LanguageSwitcher.vue | 27 +- src/themes/default/components/core/Loader.vue | 38 +- .../default/components/core/LoaderScoped.vue | 10 +- src/themes/default/components/core/Logo.vue | 10 +- src/themes/default/components/core/Modal.vue | 92 +- .../components/core/NewsletterPopup.vue | 40 +- .../default/components/core/Notification.vue | 18 +- .../default/components/core/OfflineBadge.vue | 6 +- .../default/components/core/Overlay.vue | 24 +- .../default/components/core/PriceSelector.vue | 50 +- .../components/core/ProductAttribute.vue | 8 +- .../components/core/ProductBundleOption.vue | 218 +-- .../components/core/ProductBundleOptions.vue | 20 +- .../components/core/ProductCustomOptions.vue | 231 ++-- .../components/core/ProductGallery.vue | 55 +- .../core/ProductGalleryCarousel.vue | 169 ++- .../components/core/ProductGalleryOverlay.vue | 26 +- .../core/ProductGalleryZoomCarousel.vue | 75 +- .../default/components/core/ProductLinks.vue | 38 +- .../components/core/ProductListing.vue | 25 +- .../default/components/core/ProductTile.vue | 75 +- .../default/components/core/ProductVideo.vue | 17 +- .../components/core/ProductsSlider.vue | 41 +- .../default/components/core/SizeSelector.vue | 56 +- src/themes/default/components/core/SortBy.vue | 81 +- .../components/core/ValidationError.vue | 4 +- .../core/blocks/Auth/ForgotPass.vue | 93 +- .../components/core/blocks/Auth/Login.vue | 82 +- .../components/core/blocks/Auth/Register.vue | 60 +- .../components/core/blocks/Auth/SignUp.vue | 18 +- .../core/blocks/Category/CategoryPanel.vue | 28 +- .../core/blocks/Category/Sidebar.vue | 23 +- .../core/blocks/Checkout/CartSummary.vue | 57 +- .../blocks/Checkout/OrderConfirmation.vue | 75 +- .../core/blocks/Checkout/OrderReview.vue | 101 +- .../core/blocks/Checkout/Payment.vue | 173 ++- .../core/blocks/Checkout/PersonalDetails.vue | 113 +- .../core/blocks/Checkout/Product.vue | 55 +- .../core/blocks/Checkout/Shipping.vue | 157 ++- .../core/blocks/Checkout/ThankYouPage.vue | 190 ++- .../components/core/blocks/Cms/Block.vue | 28 +- .../core/blocks/Compare/ProductAttribute.vue | 6 +- .../components/core/blocks/Footer/Footer.vue | 152 ++- .../core/blocks/Footer/MinimalFooter.vue | 173 ++- .../core/blocks/Footer/Newsletter.vue | 51 +- .../core/blocks/Form/BaseCheckbox.vue | 121 +- .../components/core/blocks/Form/BaseInput.vue | 121 +- .../core/blocks/Form/BaseInputNumber.vue | 62 +- .../core/blocks/Form/BaseRadiobutton.vue | 113 +- .../core/blocks/Form/BaseSelect.vue | 31 +- .../core/blocks/Form/BaseTextarea.vue | 88 +- .../core/blocks/Form/ValidationMessages.vue | 2 +- .../core/blocks/Header/AccountIcon.vue | 71 +- .../core/blocks/Header/CompareIcon.vue | 10 +- .../core/blocks/Header/HamburgerIcon.vue | 4 +- .../components/core/blocks/Header/Header.vue | 93 +- .../core/blocks/Header/MicrocartIcon.vue | 18 +- .../core/blocks/Header/MinimalHeader.vue | 19 +- .../core/blocks/Header/ReturnIcon.vue | 11 +- .../core/blocks/Header/SearchIcon.vue | 4 +- .../core/blocks/Header/WishlistIcon.vue | 4 +- .../core/blocks/MainSlider/HeadImage.vue | 21 +- .../core/blocks/MainSlider/MainSlider.vue | 44 +- .../core/blocks/Microcart/ClearCartButton.vue | 14 +- .../core/blocks/Microcart/Microcart.vue | 300 ++-- .../core/blocks/Microcart/Product.vue | 194 +-- .../core/blocks/Microcart/RemoveButton.vue | 4 +- .../core/blocks/MyAccount/MyNewsletter.vue | 17 +- .../core/blocks/MyAccount/MyOrder.vue | 93 +- .../core/blocks/MyAccount/MyOrders.vue | 63 +- .../core/blocks/MyAccount/MyProfile.vue | 147 +- .../blocks/MyAccount/MyRecentlyViewed.vue | 8 +- .../blocks/MyAccount/MyShippingDetails.vue | 101 +- .../core/blocks/Product/Related.vue | 88 +- .../core/blocks/Reviews/Reviews.vue | 120 +- .../blocks/SearchPanel/SearchPanel.gql.vue | 30 +- .../core/blocks/SearchPanel/SearchPanel.vue | 93 +- .../core/blocks/SidebarMenu/SidebarMenu.vue | 74 +- .../core/blocks/SidebarMenu/SubBtn.vue | 15 +- .../core/blocks/SidebarMenu/SubCategory.vue | 103 +- .../core/blocks/Switcher/Language.vue | 121 +- .../core/blocks/Wishlist/AddToWishlist.vue | 21 +- .../core/blocks/Wishlist/Product.vue | 59 +- .../core/blocks/Wishlist/Wishlist.vue | 30 +- .../default/components/theme/ButtonFull.vue | 22 +- .../components/theme/ButtonOutline.vue | 64 +- .../blocks/AsyncSidebar/AsyncSidebar.vue | 130 +- .../blocks/AsyncSidebar/LoadingError.vue | 22 +- .../blocks/AsyncSidebar/LoadingSpinner.vue | 21 +- .../theme/blocks/Collection/Collection.vue | 29 +- .../components/theme/blocks/Home/Onboard.vue | 44 +- .../blocks/Inspirations/InspirationTile.vue | 28 +- .../blocks/Inspirations/Inspirations.vue | 41 +- .../blocks/PromotedOffers/PromotedOffers.vue | 123 +- .../theme/blocks/Reviews/ReviewsList.vue | 124 +- .../theme/blocks/Static/Example.vue | 29 +- .../components/theme/blocks/Static/Short.vue | 19 +- .../theme/blocks/TileLinks/TileLinks.vue | 18 +- .../components/theme/directives/focusClean.js | 41 +- src/themes/default/head.js | 73 +- src/themes/default/index.js | 33 +- src/themes/default/layouts/Default.vue | 130 +- src/themes/default/layouts/Empty.vue | 2 +- src/themes/default/layouts/Minimal.vue | 33 +- .../default/mixins/currentPage/index.js | 32 +- src/themes/default/pages/Category.vue | 201 +-- src/themes/default/pages/Checkout.vue | 215 +-- .../default/pages/CmsBlockDemoPageSsr.vue | 10 +- src/themes/default/pages/CmsPage.vue | 12 +- src/themes/default/pages/Compare.vue | 61 +- src/themes/default/pages/CustomCmsPage.vue | 12 +- src/themes/default/pages/Error.vue | 23 +- src/themes/default/pages/Home.vue | 124 +- src/themes/default/pages/MyAccount.vue | 57 +- src/themes/default/pages/PageNotFound.vue | 52 +- src/themes/default/pages/Product.vue | 192 ++- src/themes/default/pages/Static.vue | 93 +- .../resource/banners/de_main-image.json | 8 +- .../resource/banners/de_promoted_offers.json | 24 +- .../resource/banners/it_main-image.json | 8 +- .../resource/banners/it_promoted_offers.json | 24 +- src/themes/default/resource/main-image.json | 8 +- .../default/resource/promoted_offers.json | 26 +- src/themes/default/resource/slider.json | 2 +- src/themes/default/router/index.js | 287 +++- src/themes/default/webpack.config.js | 6 +- 549 files changed, 19888 insertions(+), 13844 deletions(-) diff --git a/core/app.ts b/core/app.ts index bf46c08564..a209520b39 100755 --- a/core/app.ts +++ b/core/app.ts @@ -1,42 +1,42 @@ -import { Store } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import Vue from 'vue' -import buildTimeConfig from 'config' -import { isServer } from '@vue-storefront/core/helpers' -import { Logger } from '@vue-storefront/core/lib/logger' +import { Store } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import Vue from 'vue'; +import buildTimeConfig from 'config'; +import { isServer } from '@vue-storefront/core/helpers'; +import { Logger } from '@vue-storefront/core/lib/logger'; // Plugins -import i18n from '@vue-storefront/i18n' -import VueRouter from 'vue-router' -import VueLazyload from 'vue-lazyload' -import Vuelidate from 'vuelidate' -import Meta from 'vue-meta' -import { sync } from 'vuex-router-sync' -import VueObserveVisibility from 'vue-observe-visibility' +import i18n from '@vue-storefront/i18n'; +import VueRouter from 'vue-router'; +import VueLazyload from 'vue-lazyload'; +import Vuelidate from 'vuelidate'; +import Meta from 'vue-meta'; +import { sync } from 'vuex-router-sync'; +import VueObserveVisibility from 'vue-observe-visibility'; // Apollo GraphQL client -import { getApolloProvider } from './scripts/resolvers/resolveGraphQL' +import { getApolloProvider } from './scripts/resolvers/resolveGraphQL'; // TODO simplify by removing global mixins, plugins and filters - it can be done in normal 'vue' way -import { registerTheme } from '@vue-storefront/core/lib/themes' -import { themeEntry } from 'theme/index.js' -import { registerModules } from '@vue-storefront/core/lib/module' -import { prepareStoreView } from '@vue-storefront/core/lib/multistore' +import { registerTheme } from '@vue-storefront/core/lib/themes'; +import { themeEntry } from 'theme/index.js'; +import { registerModules } from '@vue-storefront/core/lib/module'; +import { prepareStoreView } from '@vue-storefront/core/lib/multistore'; -import * as coreMixins from '@vue-storefront/core/mixins' -import * as coreFilters from '@vue-storefront/core/filters' -import * as corePlugins from '@vue-storefront/core/compatibility/plugins' +import * as coreMixins from '@vue-storefront/core/mixins'; +import * as coreFilters from '@vue-storefront/core/filters'; +import * as corePlugins from '@vue-storefront/core/compatibility/plugins'; -import { once } from '@vue-storefront/core/helpers' -import store from '@vue-storefront/core/store' +import { once } from '@vue-storefront/core/helpers'; +import store from '@vue-storefront/core/store'; -import { enabledModules } from './modules-entry' +import { enabledModules } from './modules-entry'; // Will be deprecated in 1.8 -import { registerExtensions } from '@vue-storefront/core/compatibility/lib/extensions' -import { registerExtensions as extensions } from 'src/extensions' +import { registerExtensions } from '@vue-storefront/core/compatibility/lib/extensions'; +import { registerExtensions as extensions } from 'src/extensions'; -function createRouter (): VueRouter { +function createRouter(): VueRouter { return new VueRouter({ mode: 'history', base: __dirname, @@ -44,82 +44,92 @@ function createRouter (): VueRouter { if (to.hash) { return { selector: to.hash - } + }; } if (savedPosition) { - return savedPosition + return savedPosition; } else { - return {x: 0, y: 0} + return { x: 0, y: 0 }; } } - }) + }); } -let router: VueRouter = null +let router: VueRouter = null; once('__VUE_EXTEND_RR__', () => { - Vue.use(VueRouter) -}) - -const createApp = async (ssrContext, config, storeCode = null): Promise<{app: Vue, router: VueRouter, store: Store}> => { - router = createRouter() + Vue.use(VueRouter); +}); + +const createApp = async ( + ssrContext, + config, + storeCode = null +): Promise<{ app: Vue; router: VueRouter; store: Store }> => { + router = createRouter(); // sync router with vuex 'router' store - sync(store, router) + sync(store, router); // TODO: Don't mutate the state directly, use mutation instead - store.state.version = process.env.APPVERSION - store.state.config = config - store.state.__DEMO_MODE__ = (config.demomode === true) ? true : false - if(ssrContext) Vue.prototype.$ssrRequestContext = ssrContext - if (!store.state.config) store.state.config = buildTimeConfig // if provided from SSR, don't replace it - const storeView = prepareStoreView(storeCode) // prepare the default storeView - store.state.storeView = storeView + store.state.version = process.env.APPVERSION; + store.state.config = config; + store.state.__DEMO_MODE__ = config.demomode === true ? true : false; + if (ssrContext) Vue.prototype.$ssrRequestContext = ssrContext; + if (!store.state.config) store.state.config = buildTimeConfig; // if provided from SSR, don't replace it + const storeView = prepareStoreView(storeCode); // prepare the default storeView + store.state.storeView = storeView; // store.state.shipping.methods = shippingMethods - // to depreciate in near future once('__VUE_EXTEND__', () => { - Vue.use(Vuelidate) - Vue.use(VueLazyload, {attempt: 2, preLoad: 1.5}) - Vue.use(Meta) - Vue.use(VueObserveVisibility) + Vue.use(Vuelidate); + Vue.use(VueLazyload, { attempt: 2, preLoad: 1.5 }); + Vue.use(Meta); + Vue.use(VueObserveVisibility); Object.keys(corePlugins).forEach(key => { - Vue.use(corePlugins[key]) - }) + Vue.use(corePlugins[key]); + }); Object.keys(coreMixins).forEach(key => { - Vue.mixin(coreMixins[key]) - }) - }) + Vue.mixin(coreMixins[key]); + }); + }); Object.keys(coreFilters).forEach(key => { - Vue.filter(key, coreFilters[key]) - }) + Vue.filter(key, coreFilters[key]); + }); let vueOptions = { router, store, i18n, render: h => h(themeEntry) - } + }; - const apolloProvider = await getApolloProvider() - if (apolloProvider) Object.assign(vueOptions, {provider: apolloProvider}) + const apolloProvider = await getApolloProvider(); + if (apolloProvider) Object.assign(vueOptions, { provider: apolloProvider }); - const app = new Vue(vueOptions) + const app = new Vue(vueOptions); const appContext = { isServer, ssrContext - } + }; - registerModules(enabledModules, appContext) - registerExtensions(extensions, app, router, store, config, ssrContext) - registerTheme(buildTimeConfig.theme, app, router, store, store.state.config, ssrContext) + registerModules(enabledModules, appContext); + registerExtensions(extensions, app, router, store, config, ssrContext); + registerTheme( + buildTimeConfig.theme, + app, + router, + store, + store.state.config, + ssrContext + ); - app.$emit('application-after-init', app) + app.$emit('application-after-init', app); - return { app, router, store } -} + return { app, router, store }; +}; -export { router, createApp } +export { router, createApp }; diff --git a/core/build/dev-server.js b/core/build/dev-server.js index 958c1b6dbf..2aaf61de77 100644 --- a/core/build/dev-server.js +++ b/core/build/dev-server.js @@ -1,67 +1,79 @@ -const path = require('path') -const webpack = require('webpack') -const MFS = require('memory-fs') +const path = require('path'); +const webpack = require('webpack'); +const MFS = require('memory-fs'); -let baseClientConfig = require('./webpack.client.config') -let baseServerConfig = require('./webpack.server.config') +let baseClientConfig = require('./webpack.client.config'); +let baseServerConfig = require('./webpack.server.config'); -const themeRoot = require('./theme-path') -const extendedConfig = require(path.join(themeRoot, '/webpack.config.js')) +const themeRoot = require('./theme-path'); +const extendedConfig = require(path.join(themeRoot, '/webpack.config.js')); -let clientConfig = extendedConfig(baseClientConfig, { isClient: true, isDev: true }).default; -let serverConfig = extendedConfig(baseServerConfig, { isClient: false, isDev: true }).default; +let clientConfig = extendedConfig(baseClientConfig, { + isClient: true, + isDev: true +}).default; +let serverConfig = extendedConfig(baseServerConfig, { + isClient: false, + isDev: true +}).default; -module.exports = function setupDevServer (app, cb) { - let bundle - let template +module.exports = function setupDevServer(app, cb) { + let bundle; + let template; // Modify client config to work with hot middleware - clientConfig.entry.app = ['webpack-hot-middleware/client', ...clientConfig.entry.app] - clientConfig.output.filename = '[name].js' + clientConfig.entry.app = [ + 'webpack-hot-middleware/client', + ...clientConfig.entry.app + ]; + clientConfig.output.filename = '[name].js'; clientConfig.plugins.push( new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin() - ) + ); // Dev middleware - const clientCompiler = webpack(clientConfig) + const clientCompiler = webpack(clientConfig); const devMiddleware = require('webpack-dev-middleware')(clientCompiler, { publicPath: clientConfig.output.publicPath, stats: { colors: true, chunks: false } - }) - app.use(devMiddleware) + }); + app.use(devMiddleware); clientCompiler.plugin('done', () => { - const fs = devMiddleware.fileSystem - const filePath = path.join(clientConfig.output.path, 'index.html') + const fs = devMiddleware.fileSystem; + const filePath = path.join(clientConfig.output.path, 'index.html'); if (fs.existsSync(filePath)) { - template = fs.readFileSync(filePath, 'utf-8') + template = fs.readFileSync(filePath, 'utf-8'); if (bundle) { - cb(bundle, template) + cb(bundle, template); } } - }) + }); // Hot middleware - app.use(require('webpack-hot-middleware')(clientCompiler)) + app.use(require('webpack-hot-middleware')(clientCompiler)); // watch and update server renderer - const serverCompiler = webpack(serverConfig) - const mfs = new MFS() - serverCompiler.outputFileSystem = mfs + const serverCompiler = webpack(serverConfig); + const mfs = new MFS(); + serverCompiler.outputFileSystem = mfs; serverCompiler.watch({}, (err, stats) => { - if (err) throw err - stats = stats.toJson() - stats.errors.forEach(err => console.error(err)) - stats.warnings.forEach(err => console.warn(err)) + if (err) throw err; + stats = stats.toJson(); + stats.errors.forEach(err => console.error(err)); + stats.warnings.forEach(err => console.warn(err)); // Read bundle generated by vue-ssr-webpack-plugin - const bundlePath = path.join(serverConfig.output.path, 'vue-ssr-bundle.json') - bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8')) + const bundlePath = path.join( + serverConfig.output.path, + 'vue-ssr-bundle.json' + ); + bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8')); if (template) { - cb(bundle, template) + cb(bundle, template); } - }) -} + }); +}; diff --git a/core/build/theme-path.js b/core/build/theme-path.js index b48397b656..b2b9925d80 100644 --- a/core/build/theme-path.js +++ b/core/build/theme-path.js @@ -1,16 +1,15 @@ -const path = require('path') -const detectInstalled = require('detect-installed') -const config = require('./config.json') +const path = require('path'); +const detectInstalled = require('detect-installed'); +const config = require('./config.json'); -let themePath = '' -let themeName = config.theme +let themePath = ''; +let themeName = config.theme; if (detectInstalled.sync(config.theme, { local: true })) { - themePath = path.resolve(__dirname, '../../node_modules/' + themeName) -} -else { - themeName = themeName.replace('@vue-storefront/theme-', '') - themePath = path.resolve(__dirname, '../../src/themes/' + themeName) + themePath = path.resolve(__dirname, '../../node_modules/' + themeName); +} else { + themeName = themeName.replace('@vue-storefront/theme-', ''); + themePath = path.resolve(__dirname, '../../src/themes/' + themeName); } -module.exports = themePath +module.exports = themePath; diff --git a/core/build/webpack.base.config.ts b/core/build/webpack.base.config.ts index dc84186eb2..2c2b161f05 100644 --- a/core/build/webpack.base.config.ts +++ b/core/build/webpack.base.config.ts @@ -12,38 +12,53 @@ import moment from 'moment'; fs.writeFileSync( path.resolve(__dirname, './config.json'), JSON.stringify(config) -) +); -const themesRoot = '../../src/themes' +const themesRoot = '../../src/themes'; import themeRoot from './theme-path'; -const themeResources = themeRoot + '/resource' -const themeCSS = themeRoot + '/css' -const themeApp = themeRoot + '/App.vue' -const themedIndex = path.join(themeRoot, '/templates/index.template.html') -const themedIndexMinimal = path.join(themeRoot, '/templates/index.minimal.template.html') -const themedIndexBasic = path.join(themeRoot, '/templates/index.basic.template.html') -const themedIndexAmp = path.join(themeRoot, '/templates/index.amp.template.html') +const themeResources = themeRoot + '/resource'; +const themeCSS = themeRoot + '/css'; +const themeApp = themeRoot + '/App.vue'; +const themedIndex = path.join(themeRoot, '/templates/index.template.html'); +const themedIndexMinimal = path.join( + themeRoot, + '/templates/index.minimal.template.html' +); +const themedIndexBasic = path.join( + themeRoot, + '/templates/index.basic.template.html' +); +const themedIndexAmp = path.join( + themeRoot, + '/templates/index.amp.template.html' +); -const translationPreprocessor = require('@vue-storefront/i18n/scripts/translation.preprocessor.js') -translationPreprocessor([ - path.resolve(__dirname, '../../node_modules/@vue-storefront/i18n/resource/i18n/'), - path.resolve(__dirname, themeResources + '/i18n/') -], config) +const translationPreprocessor = require('@vue-storefront/i18n/scripts/translation.preprocessor.js'); +translationPreprocessor( + [ + path.resolve( + __dirname, + '../../node_modules/@vue-storefront/i18n/resource/i18n/' + ), + path.resolve(__dirname, themeResources + '/i18n/') + ], + config +); -const postcssConfig = { +const postcssConfig = { loader: 'postcss-loader', options: { ident: 'postcss', - plugins: (loader) => [ + plugins: loader => [ require('postcss-flexbugs-fixes'), require('autoprefixer')({ - flexbox: 'no-2009', - }), + flexbox: 'no-2009' + }) ] } }; -const isProd = process.env.NODE_ENV === 'production' +const isProd = process.env.NODE_ENV === 'production'; // todo: usemultipage-webpack-plugin for multistore export default { plugins: [ @@ -55,32 +70,44 @@ export default { new VueLoaderPlugin(), // generate output HTML new HTMLPlugin({ - template: fs.existsSync(themedIndex) ? themedIndex : 'src/index.template.html', + template: fs.existsSync(themedIndex) + ? themedIndex + : 'src/index.template.html', filename: 'index.html', chunksSortMode: 'none', inject: isProd == false // in dev mode we're not using clientManifest therefore renderScripts() is returning empty string and we need to inject scripts using HTMLPlugin }), new HTMLPlugin({ - template: fs.existsSync(themedIndexMinimal) ? themedIndexMinimal : 'src/index.minimal.template.html', + template: fs.existsSync(themedIndexMinimal) + ? themedIndexMinimal + : 'src/index.minimal.template.html', filename: 'index.minimal.html', chunksSortMode: 'none', inject: isProd == false }), new HTMLPlugin({ - template: fs.existsSync(themedIndexBasic) ? themedIndexBasic: 'src/index.basic.template.html', + template: fs.existsSync(themedIndexBasic) + ? themedIndexBasic + : 'src/index.basic.template.html', filename: 'index.basic.html', chunksSortMode: 'none', inject: isProd == false }), new HTMLPlugin({ - template: fs.existsSync(themedIndexAmp) ? themedIndexAmp: 'src/index.amp.template.html', + template: fs.existsSync(themedIndexAmp) + ? themedIndexAmp + : 'src/index.amp.template.html', filename: 'index.amp.html', chunksSortMode: 'none', inject: isProd == false }), new webpack.DefinePlugin({ - 'process.env.__APPVERSION__': JSON.stringify(require('../../package.json').version), - 'process.env.__BUILDTIME__': JSON.stringify(moment().format('YYYY-MM-DD HH:mm:ss')) + 'process.env.__APPVERSION__': JSON.stringify( + require('../../package.json').version + ), + 'process.env.__BUILDTIME__': JSON.stringify( + moment().format('YYYY-MM-DD HH:mm:ss') + ) }) ], devtool: 'source-map', @@ -93,30 +120,27 @@ export default { filename: '[name].[hash].js' }, resolveLoader: { - modules: [ - 'node_modules', - path.resolve(__dirname, themesRoot) - ], + modules: ['node_modules', path.resolve(__dirname, themesRoot)] }, resolve: { - modules: [ - 'node_modules', - path.resolve(__dirname, themesRoot) - ], + modules: ['node_modules', path.resolve(__dirname, themesRoot)], extensions: ['.js', '.vue', '.gql', '.graphqls', '.ts'], alias: { // Main aliases - 'config': path.resolve(__dirname, './config.json'), - 'src': path.resolve(__dirname, '../../src'), + config: path.resolve(__dirname, './config.json'), + src: path.resolve(__dirname, '../../src'), // Theme aliases - 'theme': themeRoot, + theme: themeRoot, 'theme/app': themeApp, 'theme/css': themeCSS, 'theme/resource': themeResources, // Backward compatible - '@vue-storefront/core/store/lib/multistore' : path.resolve(__dirname, '../lib/multistore.ts'), + '@vue-storefront/core/store/lib/multistore': path.resolve( + __dirname, + '../lib/multistore.ts' + ) } }, module: { @@ -132,7 +156,7 @@ export default { loader: 'vue-loader', options: { preserveWhitespace: false, - postcss: [autoprefixer()], + postcss: [autoprefixer()] } }, { @@ -161,20 +185,11 @@ export default { }, { test: /\.css$/, - use: [ - 'vue-style-loader', - 'css-loader', - postcssConfig - ] + use: ['vue-style-loader', 'css-loader', postcssConfig] }, { test: /\.scss$/, - use: [ - 'vue-style-loader', - 'css-loader', - postcssConfig, - 'sass-loader' - ] + use: ['vue-style-loader', 'css-loader', postcssConfig, 'sass-loader'] }, { test: /\.sass$/, @@ -201,4 +216,4 @@ export default { } ] } -} +}; diff --git a/core/build/webpack.client.config.ts b/core/build/webpack.client.config.ts index 89e7f9ab23..387e50cb2d 100644 --- a/core/build/webpack.client.config.ts +++ b/core/build/webpack.client.config.ts @@ -1,22 +1,22 @@ -import webpack from 'webpack' -import merge from 'webpack-merge' -import base from './webpack.base.config' -import VueSSRClientPlugin from 'vue-server-renderer/client-plugin' +import webpack from 'webpack'; +import merge from 'webpack-merge'; +import base from './webpack.base.config'; +import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'; // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const config = merge(base, { optimization: { - splitChunks: { + splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/](vue|vuex|vue-router|vue-meta|vue-i18n|vuex-router-sync|localforage)[\\/]/, name: 'vendor', - chunks: 'all', - }, - }, + chunks: 'all' + } + } }, - runtimeChunk: { - name: "manifest", + runtimeChunk: { + name: 'manifest' } }, mode: 'development', @@ -32,7 +32,7 @@ const config = merge(base, { 'process.env.VUE_ENV': '"client"' }), new VueSSRClientPlugin() - ], -}) + ] +}); export default config; diff --git a/core/build/webpack.prod.client.config.ts b/core/build/webpack.prod.client.config.ts index 8256f9f03b..5ca3af697b 100644 --- a/core/build/webpack.prod.client.config.ts +++ b/core/build/webpack.prod.client.config.ts @@ -1,18 +1,17 @@ import path from 'path'; import merge from 'webpack-merge'; import baseClientConfig from './webpack.client.config'; -const themeRoot = require ('./theme-path'); +const themeRoot = require('./theme-path'); -const extendedConfig = require(path.join(themeRoot, '/webpack.config.js')) +const extendedConfig = require(path.join(themeRoot, '/webpack.config.js')); const prodClientConfig = merge(baseClientConfig, { mode: 'production', devtool: 'nosources-source-map', - plugins: [ - ] -}) + plugins: [] +}); module.exports = extendedConfig(prodClientConfig, { isClient: true, isDev: false -}) +}); diff --git a/core/build/webpack.prod.server.config.ts b/core/build/webpack.prod.server.config.ts index 350e3d9a9d..240109a71e 100644 --- a/core/build/webpack.prod.server.config.ts +++ b/core/build/webpack.prod.server.config.ts @@ -4,11 +4,11 @@ import baseServerConfig from './webpack.server.config'; import themeRoot from './theme-path'; -const extendedConfig = require(path.join(themeRoot, '/webpack.config.js')) +const extendedConfig = require(path.join(themeRoot, '/webpack.config.js')); export default extendedConfig(baseServerConfig, { mode: 'production', - devtool: 'nosources-source-map', + devtool: 'nosources-source-map', isClient: false, isDev: false -}) +}); diff --git a/core/build/webpack.prod.sw.config.ts b/core/build/webpack.prod.sw.config.ts index d4e37d13b5..1851bb322e 100644 --- a/core/build/webpack.prod.sw.config.ts +++ b/core/build/webpack.prod.sw.config.ts @@ -28,69 +28,80 @@ module.exports = merge(base, { ], runtimeCaching: [ { - urlPattern: "^https://fonts\.googleapis\.com/", /** cache the html stub */ - handler: "cacheFirst" - }, - { - urlPattern: "^https://fonts\.gstatic\.com/", /** cache the html stub */ - handler: "cacheFirst" - }, - { - urlPattern: "^https://unpkg\.com/", /** cache the html stub */ - handler: "cacheFirst" - }, - { - urlPattern: "/pwa.html", /** cache the html stub */ - handler: "networkFirst" - },{ - urlPattern: "/", /** cache the html stub for homepage */ - handler: "networkFirst" - }, - { - urlPattern: "/p/*", /** cache the html stub */ - handler: "networkFirst" - }, - { - urlPattern: "/c/*", /** cache the html stub */ - handler: "networkFirst" - }, - { - urlPattern: "/img/(.*)", - handler: "fastest" - },{ - urlPattern: "/api/catalog/*", - handler: "networkFirst" - },{ - urlPattern: "/api/*", - handler: "networkFirst" - },{ - urlPattern: "/assets/logo.svg", - handler: "networkFirst" - },{ - urlPattern: "/index.html", - handler: "networkFirst" - },{ - urlPattern: "/assets/*", - handler: "fastest" - },{ - urlPattern: "/assets/ig/(.*)", - handler: "fastest" - },{ - urlPattern: "/dist/(.*)", - handler: "fastest" - },{ - urlPattern: "/*/*", /** this is new product URL format */ - handler: "networkFirst" - }, - { - urlPattern: "/*/*/*", /** this is new product URL format */ - handler: "networkFirst" - }, - { - urlPattern: "/*", /** this is new category URL format */ - handler: "networkFirst" - }], - "importScripts": ['/dist/core-service-worker.js'] /* custom logic */ + urlPattern: + '^https://fonts.googleapis.com/' /** cache the html stub */, + handler: 'cacheFirst' + }, + { + urlPattern: '^https://fonts.gstatic.com/' /** cache the html stub */, + handler: 'cacheFirst' + }, + { + urlPattern: '^https://unpkg.com/' /** cache the html stub */, + handler: 'cacheFirst' + }, + { + urlPattern: '/pwa.html' /** cache the html stub */, + handler: 'networkFirst' + }, + { + urlPattern: '/' /** cache the html stub for homepage */, + handler: 'networkFirst' + }, + { + urlPattern: '/p/*' /** cache the html stub */, + handler: 'networkFirst' + }, + { + urlPattern: '/c/*' /** cache the html stub */, + handler: 'networkFirst' + }, + { + urlPattern: '/img/(.*)', + handler: 'fastest' + }, + { + urlPattern: '/api/catalog/*', + handler: 'networkFirst' + }, + { + urlPattern: '/api/*', + handler: 'networkFirst' + }, + { + urlPattern: '/assets/logo.svg', + handler: 'networkFirst' + }, + { + urlPattern: '/index.html', + handler: 'networkFirst' + }, + { + urlPattern: '/assets/*', + handler: 'fastest' + }, + { + urlPattern: '/assets/ig/(.*)', + handler: 'fastest' + }, + { + urlPattern: '/dist/(.*)', + handler: 'fastest' + }, + { + urlPattern: '/*/*' /** this is new product URL format */, + handler: 'networkFirst' + }, + { + urlPattern: '/*/*/*' /** this is new product URL format */, + handler: 'networkFirst' + }, + { + urlPattern: '/*' /** this is new category URL format */, + handler: 'networkFirst' + } + ], + importScripts: ['/dist/core-service-worker.js'] /* custom logic */ }) ] -}) +}); diff --git a/core/build/webpack.server.config.ts b/core/build/webpack.server.config.ts index 729ff89a57..46a2cbc8b0 100644 --- a/core/build/webpack.server.config.ts +++ b/core/build/webpack.server.config.ts @@ -4,16 +4,16 @@ import base from './webpack.base.config'; import VueSSRPlugin from 'vue-ssr-webpack-plugin'; // when output cache is enabled generate cache version key -import config from 'config' -import fs from 'fs' -import path from 'path' -import uuid from 'uuid/v4' +import config from 'config'; +import fs from 'fs'; +import path from 'path'; +import uuid from 'uuid/v4'; if (config.server.useOutputCache) { fs.writeFileSync( path.join(__dirname, 'cache-version.json'), JSON.stringify(uuid()) - ) + ); } export default merge(base, { @@ -36,4 +36,4 @@ export default merge(base, { }), new VueSSRPlugin() ] -}) +}); diff --git a/core/client-entry.ts b/core/client-entry.ts index f57408b5c9..4c4b018344 100755 --- a/core/client-entry.ts +++ b/core/client-entry.ts @@ -1,281 +1,352 @@ -import Vue from 'vue' -import * as localForage from 'localforage' -import union from 'lodash-es/union' +import Vue from 'vue'; +import * as localForage from 'localforage'; +import union from 'lodash-es/union'; -import { createApp } from '@vue-storefront/core/app' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index' -import rootStore from '@vue-storefront/core/store' +import { createApp } from '@vue-storefront/core/app'; +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index'; +import rootStore from '@vue-storefront/core/store'; -import buildTimeConfig from 'config' -import { execute } from '@vue-storefront/core/lib/sync/task' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import i18n from '@vue-storefront/i18n' -import { prepareStoreView, storeCodeFromRoute, currentStoreView, localizedRoute } from '@vue-storefront/core/lib/multistore' -import { onNetworkStatusChange } from '@vue-storefront/core/modules/offline-order/helpers/onNetworkStatusChange' -import '@vue-storefront/core/service-worker/registration' // register the service worker -import { AsyncDataLoader } from './lib/async-data-loader' -import { Logger } from '@vue-storefront/core/lib/logger' -declare var window: any +import buildTimeConfig from 'config'; +import { execute } from '@vue-storefront/core/lib/sync/task'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import i18n from '@vue-storefront/i18n'; +import { + prepareStoreView, + storeCodeFromRoute, + currentStoreView, + localizedRoute +} from '@vue-storefront/core/lib/multistore'; +import { onNetworkStatusChange } from '@vue-storefront/core/modules/offline-order/helpers/onNetworkStatusChange'; +import '@vue-storefront/core/service-worker/registration'; // register the service worker +import { AsyncDataLoader } from './lib/async-data-loader'; +import { Logger } from '@vue-storefront/core/lib/logger'; +declare var window: any; const invokeClientEntry = async () => { - const config = Object.assign(buildTimeConfig, window.__INITIAL_STATE__.config ? window.__INITIAL_STATE__.config : buildTimeConfig) + const config = Object.assign( + buildTimeConfig, + window.__INITIAL_STATE__.config + ? window.__INITIAL_STATE__.config + : buildTimeConfig + ); // Get storeCode from server (received either from cache header or env variable) - let storeCode = window.__INITIAL_STATE__.user.current_storecode - const { app, router, store } = await createApp(null, config, storeCode) + let storeCode = window.__INITIAL_STATE__.user.current_storecode; + const { app, router, store } = await createApp(null, config, storeCode); if (window.__INITIAL_STATE__) { - store.replaceState(Object.assign({}, store.state, window.__INITIAL_STATE__, { config: buildTimeConfig })) + store.replaceState( + Object.assign({}, store.state, window.__INITIAL_STATE__, { + config: buildTimeConfig + }) + ); } - store.dispatch('url/registerDynamicRoutes') - function _commonErrorHandler (err, reject) { + store.dispatch('url/registerDynamicRoutes'); + function _commonErrorHandler(err, reject) { if (err.message.indexOf('query returned empty result') > 0) { rootStore.dispatch('notification/spawnNotification', { type: 'error', - message: i18n.t('The product, category or CMS page is not available in Offline mode. Redirecting to Home.'), + message: i18n.t( + 'The product, category or CMS page is not available in Offline mode. Redirecting to Home.' + ), action1: { label: i18n.t('OK') } - }) - router.push(localizedRoute('/', currentStoreView().storeCode)) + }); + router.push(localizedRoute('/', currentStoreView().storeCode)); } else { rootStore.dispatch('notification/spawnNotification', { type: 'error', message: i18n.t(err.message), action1: { label: i18n.t('OK') } - }) - reject() + }); + reject(); } } - function _ssrHydrateSubcomponents (components, next, to) { - Promise.all(components.map(SubComponent => { - if (SubComponent.asyncData) { - return SubComponent.asyncData({ - store, - route: to - }) - } else { - return Promise.resolve(null) - } - })).then(() => { - AsyncDataLoader.flush({ store, route: to, context: null }).then(next).catch(err => { - _commonErrorHandler(err, next) + function _ssrHydrateSubcomponents(components, next, to) { + Promise.all( + components.map(SubComponent => { + if (SubComponent.asyncData) { + return SubComponent.asyncData({ + store, + route: to + }); + } else { + return Promise.resolve(null); + } + }) + ) + .then(() => { + AsyncDataLoader.flush({ store, route: to, context: null }) + .then(next) + .catch(err => { + _commonErrorHandler(err, next); + }); }) - }).catch(err => { - _commonErrorHandler(err, next) - }) + .catch(err => { + _commonErrorHandler(err, next); + }); } router.onReady(() => { router.beforeResolve((to, from, next) => { - if (!from.name) return next() // do not resolve asyncData on server render - already been done - if (Vue.prototype.$ssrRequestContext) Vue.prototype.$ssrRequestContext.output.cacheTags = new Set() - const matched = router.getMatchedComponents(to) - const prevMatched = router.getMatchedComponents(from) - if (to) { // this is from url + if (!from.name) return next(); // do not resolve asyncData on server render - already been done + if (Vue.prototype.$ssrRequestContext) + Vue.prototype.$ssrRequestContext.output.cacheTags = new Set(); + const matched = router.getMatchedComponents(to); + const prevMatched = router.getMatchedComponents(from); + if (to) { + // this is from url if (config.storeViews.multistore === true) { - const storeCode = storeCodeFromRoute(to) - const currentStore = currentStoreView() + const storeCode = storeCodeFromRoute(to); + const currentStore = currentStoreView(); if (storeCode !== '' && storeCode !== null) { if (storeCode !== currentStore.storeCode) { - (document as any).location = to.path // full reload + (document as any).location = to.path; // full reload } else { - prepareStoreView(storeCode) + prepareStoreView(storeCode); } } } } if (!matched.length) { - return next() + return next(); } - Promise.all(matched.map((c: any) => { // TODO: update me for mixins support - const components = c.mixins && config.ssr.executeMixedinAsyncData ? Array.from(c.mixins) : [] - union(components, [c]).map(SubComponent => { - if (SubComponent.preAsyncData) { - SubComponent.preAsyncData({ store, route: to }) + Promise.all( + matched.map((c: any) => { + // TODO: update me for mixins support + const components = + c.mixins && config.ssr.executeMixedinAsyncData + ? Array.from(c.mixins) + : []; + union(components, [c]).map(SubComponent => { + if (SubComponent.preAsyncData) { + SubComponent.preAsyncData({ store, route: to }); + } + }); + if (c.asyncData) { + c.asyncData({ store, route: to }) + .then(result => { + // always execute the asyncData() from the top most component first + Logger.debug('Top-most asyncData executed')(); + _ssrHydrateSubcomponents(components, next, to); + }) + .catch(next); + } else { + _ssrHydrateSubcomponents(components, next, to); } }) - if (c.asyncData) { - c.asyncData({ store, route: to }).then(result => { // always execute the asyncData() from the top most component first - Logger.debug('Top-most asyncData executed')() - _ssrHydrateSubcomponents(components, next, to) - }).catch(next) - } else { - _ssrHydrateSubcomponents(components, next, to) - } - })) - }) - app.$mount('#app') - }) + ); + }); + app.$mount('#app'); + }); /* - * serial executes Promises sequentially. - * @param {funcs} An array of funcs that return promises. - * @example - * const urls = ['/url1', '/url2', '/url3'] - * serial(urls.map(url => () => $.ajax(url))) - * .then(Logger.log.bind(Logger))() - */ + * serial executes Promises sequentially. + * @param {funcs} An array of funcs that return promises. + * @example + * const urls = ['/url1', '/url2', '/url3'] + * serial(urls.map(url => () => $.ajax(url))) + * .then(Logger.log.bind(Logger))() + */ const serial = funcs => - funcs.reduce((promise, func) => - promise.then(result => func().then(Array.prototype.concat.bind(result))), Promise.resolve([])) + funcs.reduce( + (promise, func) => + promise.then(result => + func().then(Array.prototype.concat.bind(result)) + ), + Promise.resolve([]) + ); - const orderMutex = {} + const orderMutex = {}; // TODO: move to external file EventBus.$on('order/PROCESS_QUEUE', event => { if (typeof navigator !== 'undefined' && navigator.onLine) { - Logger.log('Sending out orders queue to server ...')() + Logger.log('Sending out orders queue to server ...')(); - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - const ordersCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'orders', - driver: localForage[config.localForage.defaultDrivers['orders']] - })) + const ordersCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'orders', + driver: localForage[config.localForage.defaultDrivers['orders']] + }) + ); - const fetchQueue = [] - ordersCollection.iterate((order, id, iterationNumber) => { - // Resulting key/value pair -- this callback - // will be executed for every item in the - // database. + const fetchQueue = []; + ordersCollection + .iterate( + (order, id, iterationNumber) => { + // Resulting key/value pair -- this callback + // will be executed for every item in the + // database. - if (!order.transmited && !orderMutex[id]) { // not sent to the server yet - orderMutex[id] = true - fetchQueue.push(() => { - const config = event.config - const orderData = order - const orderId = id + if (!order.transmited && !orderMutex[id]) { + // not sent to the server yet + orderMutex[id] = true; + fetchQueue.push(() => { + const config = event.config; + const orderData = order; + const orderId = id; - Logger.log('Pushing out order ' + orderId)() - return fetch(config.orders.endpoint, - { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(orderData) - }).then(response => { - const contentType = response.headers.get('content-type') - if (contentType && contentType.includes('application/json')) { - return response.json() - } else { - orderMutex[id] = false - Logger.error('Error with response - bad content-type!')() - } - }) - .then(jsonResponse => { - if (jsonResponse && jsonResponse.code === 200) { - Logger.info('Response for: ' + orderId + ' = ' + JSON.stringify(jsonResponse.result))() - orderData.transmited = true - orderData.transmited_at = new Date() - ordersCollection.setItem(orderId.toString(), orderData) - } else { - Logger.error(jsonResponse)() - } - orderMutex[id] = false - }).catch(err => { - if (config.orders.offline_orders.notification.enabled) { - navigator.serviceWorker.ready.then(registration => { - registration.sync.register('orderSync') - .then(() => { - Logger.log('Order sync registered')() - }) - .catch(error => { - Logger.log('Unable to sync', error)() - }) + Logger.log('Pushing out order ' + orderId)(); + return fetch(config.orders.endpoint, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(orderData) + }) + .then(response => { + const contentType = response.headers.get('content-type'); + if ( + contentType && + contentType.includes('application/json') + ) { + return response.json(); + } else { + orderMutex[id] = false; + Logger.error('Error with response - bad content-type!')(); + } }) - } - Logger.error('Error sending order: ' + orderId, err)() - orderMutex[id] = false - }) - }) - } - }, (err, result) => { - if (err) Logger.error(err)() - Logger.log('Iteration has completed')() + .then(jsonResponse => { + if (jsonResponse && jsonResponse.code === 200) { + Logger.info( + 'Response for: ' + + orderId + + ' = ' + + JSON.stringify(jsonResponse.result) + )(); + orderData.transmited = true; + orderData.transmited_at = new Date(); + ordersCollection.setItem(orderId.toString(), orderData); + } else { + Logger.error(jsonResponse)(); + } + orderMutex[id] = false; + }) + .catch(err => { + if (config.orders.offline_orders.notification.enabled) { + navigator.serviceWorker.ready.then(registration => { + registration.sync + .register('orderSync') + .then(() => { + Logger.log('Order sync registered')(); + }) + .catch(error => { + Logger.log('Unable to sync', error)(); + }); + }); + } + Logger.error('Error sending order: ' + orderId, err)(); + orderMutex[id] = false; + }); + }); + } + }, + (err, result) => { + if (err) Logger.error(err)(); + Logger.log('Iteration has completed')(); - // execute them serially - serial(fetchQueue) - .then(res => { - Logger.info('Processing orders queue has finished')() - // store.dispatch('cart/serverPull', { forceClientState: false }) - }) - }).catch(err => { - // This code runs if there were any errors - Logger.log(err)() - }) + // execute them serially + serial(fetchQueue).then(res => { + Logger.info('Processing orders queue has finished')(); + // store.dispatch('cart/serverPull', { forceClientState: false }) + }); + } + ) + .catch(err => { + // This code runs if there were any errors + Logger.log(err)(); + }); } - }) + }); // Process the background tasks // todo rewrite and split across modules and move to task lib - const mutex = {} + const mutex = {}; EventBus.$on('sync/PROCESS_QUEUE', data => { if (typeof navigator !== 'undefined' && navigator.onLine) { // event.data.config - configuration, endpoints etc - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - const syncTaskCollection = Vue.prototype.$db.syncTaskCollection + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; + const syncTaskCollection = Vue.prototype.$db.syncTaskCollection; - const usersCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'user', - driver: localForage[config.localForage.defaultDrivers['user']] - })) - const cartsCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'carts', - driver: localForage[config.localForage.defaultDrivers['carts']] - })) + const usersCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'user', + driver: localForage[config.localForage.defaultDrivers['user']] + }) + ); + const cartsCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'carts', + driver: localForage[config.localForage.defaultDrivers['carts']] + }) + ); - usersCollection.getItem('current-token', (err, currentToken) => { // TODO: if current token is null we should postpone the queue and force re-login - only if the task requires LOGIN! + usersCollection.getItem('current-token', (err, currentToken) => { + // TODO: if current token is null we should postpone the queue and force re-login - only if the task requires LOGIN! if (err) { - Logger.error(err)() + Logger.error(err)(); } cartsCollection.getItem('current-cart-token', (err, currentCartId) => { if (err) { - Logger.error(err)() + Logger.error(err)(); } - if (!currentCartId && store.state.cart.cartServerToken) { // this is workaround; sometimes after page is loaded indexedb returns null despite the cart token is properly set - currentCartId = store.state.cart.cartServerToken + if (!currentCartId && store.state.cart.cartServerToken) { + // this is workaround; sometimes after page is loaded indexedb returns null despite the cart token is properly set + currentCartId = store.state.cart.cartServerToken; } - if (!currentToken && store.state.user.token) { // this is workaround; sometimes after page is loaded indexedb returns null despite the cart token is properly set - currentToken = store.state.user.token + if (!currentToken && store.state.user.token) { + // this is workaround; sometimes after page is loaded indexedb returns null despite the cart token is properly set + currentToken = store.state.user.token; } - const fetchQueue = [] - Logger.debug('Current User token = ' + currentToken)() - Logger.debug('Current Cart token = ' + currentCartId)() - syncTaskCollection.iterate((task, id, iterationNumber) => { - if (task && !task.transmited && !mutex[id]) { // not sent to the server yet - mutex[id] = true // mark this task as being processed - fetchQueue.push(() => { - return execute(task, currentToken, currentCartId).then(executedTask => { - syncTaskCollection.removeItem(id) // remove successfully executed task from the queue - mutex[id] = false - }).catch(err => { - mutex[id] = false - Logger.error(err)() - }) - }) - } - }, (err, result) => { - if (err) Logger.error(err)() - Logger.debug('Iteration has completed')() - // execute them serially - serial(fetchQueue) - .then(res => { - Logger.debug('Processing sync tasks queue has finished')() - }) - }).catch(err => { - // This code runs if there were any errors - Logger.log(err)() - }) - }) - }) + const fetchQueue = []; + Logger.debug('Current User token = ' + currentToken)(); + Logger.debug('Current Cart token = ' + currentCartId)(); + syncTaskCollection + .iterate( + (task, id, iterationNumber) => { + if (task && !task.transmited && !mutex[id]) { + // not sent to the server yet + mutex[id] = true; // mark this task as being processed + fetchQueue.push(() => { + return execute(task, currentToken, currentCartId) + .then(executedTask => { + syncTaskCollection.removeItem(id); // remove successfully executed task from the queue + mutex[id] = false; + }) + .catch(err => { + mutex[id] = false; + Logger.error(err)(); + }); + }); + } + }, + (err, result) => { + if (err) Logger.error(err)(); + Logger.debug('Iteration has completed')(); + // execute them serially + serial(fetchQueue).then(res => { + Logger.debug('Processing sync tasks queue has finished')(); + }); + } + ) + .catch(err => { + // This code runs if there were any errors + Logger.log(err)(); + }); + }); + }); } - }) + }); - window.addEventListener('online', () => { onNetworkStatusChange(store) }) -} + window.addEventListener('online', () => { + onNetworkStatusChange(store); + }); +}; -invokeClientEntry() +invokeClientEntry(); diff --git a/core/compatibility/components/AddToCart.js b/core/compatibility/components/AddToCart.js index be5981cf12..6227caf155 100644 --- a/core/compatibility/components/AddToCart.js +++ b/core/compatibility/components/AddToCart.js @@ -1,6 +1,6 @@ -import { AddToCart } from '@vue-storefront/core/modules/cart/components/AddToCart.ts' +import { AddToCart } from '@vue-storefront/core/modules/cart/components/AddToCart.ts'; export default { name: 'AddToCart', - mixins: [ AddToCart ] -} + mixins: [AddToCart] +}; diff --git a/core/compatibility/components/Breadcrumbs.js b/core/compatibility/components/Breadcrumbs.js index b7f1c0b0c7..89ffbe2799 100644 --- a/core/compatibility/components/Breadcrumbs.js +++ b/core/compatibility/components/Breadcrumbs.js @@ -11,4 +11,4 @@ export default { default: '' } } -} +}; diff --git a/core/compatibility/components/GenericSelector.js b/core/compatibility/components/GenericSelector.js index 880a39dc33..7163422ca1 100644 --- a/core/compatibility/components/GenericSelector.js +++ b/core/compatibility/components/GenericSelector.js @@ -1,6 +1,6 @@ -import { ProductCustomOption } from '@vue-storefront/core/modules/catalog/components/ProductCustomOption' +import { ProductCustomOption } from '@vue-storefront/core/modules/catalog/components/ProductCustomOption'; // renamed to ProductCustomOption and placed in catalog module export default { name: 'GenericSelector', mixins: [ProductCustomOption] -} +}; diff --git a/core/compatibility/components/Notification.js b/core/compatibility/components/Notification.js index ee260ca989..e24a763651 100644 --- a/core/compatibility/components/Notification.js +++ b/core/compatibility/components/Notification.js @@ -1,40 +1,44 @@ // deprecated moved to store export default { name: 'Notification', - data () { + data() { return { notifications: [] - } + }; }, - beforeMount () { - this.$bus.$on('notification', this.onNotification) + beforeMount() { + this.$bus.$on('notification', this.onNotification); }, - beforeDestroy () { - this.$bus.$off('notification', this.onNotification) + beforeDestroy() { + this.$bus.$off('notification', this.onNotification); }, methods: { - onNotification (data) { - if (this.notifications.length > 0 && this.notifications[this.notifications.length - 1].message === data.message) { - return + onNotification(data) { + if ( + this.notifications.length > 0 && + this.notifications[this.notifications.length - 1].message === + data.message + ) { + return; } - this.notifications.push(data) + this.notifications.push(data); if (!data.hasNoTimeout) { setTimeout(() => { - this.action('close', this.notifications.length - 1) - }, data.timeToLive || 5000) + this.action('close', this.notifications.length - 1); + }, data.timeToLive || 5000); } }, - action (action, id, notification) { - this.$bus.$emit('notification-after-' + action, notification) + action(action, id, notification) { + this.$bus.$emit('notification-after-' + action, notification); switch (action) { case 'goToCheckout': - this.$router.push(this.localizedRoute('/checkout')) - this.notifications.splice(id, 1) - break + this.$router.push(this.localizedRoute('/checkout')); + this.notifications.splice(id, 1); + break; default: - this.notifications.splice(id, 1) + this.notifications.splice(id, 1); } } } -} +}; diff --git a/core/compatibility/components/Overlay.js b/core/compatibility/components/Overlay.js index 7822e68f12..46909a1c90 100644 --- a/core/compatibility/components/Overlay.js +++ b/core/compatibility/components/Overlay.js @@ -2,13 +2,13 @@ export default { name: 'Overlay', computed: { - isVisible () { - return this.$store.state.ui.overlay + isVisible() { + return this.$store.state.ui.overlay; } }, methods: { - close () { - this.$store.commit('ui/setOverlay', false) + close() { + this.$store.commit('ui/setOverlay', false); } } -} +}; diff --git a/core/compatibility/components/PriceSelector.js b/core/compatibility/components/PriceSelector.js index 93de829a8b..bd911bff0d 100644 --- a/core/compatibility/components/PriceSelector.js +++ b/core/compatibility/components/PriceSelector.js @@ -27,39 +27,44 @@ export default { default: '' } }, - data () { + data() { return { active: false - } + }; }, - beforeMount () { - this.$bus.$on('filter-reset', this.filterReset) - this.$bus.$on('filter-changed-' + this.context, this.filterChanged) + beforeMount() { + this.$bus.$on('filter-reset', this.filterReset); + this.$bus.$on('filter-changed-' + this.context, this.filterChanged); }, - beforeDestroy () { - this.$bus.$off('filter-reset', this.filterReset) - this.$bus.$off('filter-changed-' + this.context, this.filterChanged) + beforeDestroy() { + this.$bus.$off('filter-reset', this.filterReset); + this.$bus.$off('filter-changed-' + this.context, this.filterChanged); }, methods: { - filterChanged (filterOption) { + filterChanged(filterOption) { if (filterOption.attribute_code === this.code) { if (filterOption.id === this.id) { if (this.active) { - this.active = false + this.active = false; } else { - this.active = true + this.active = true; } } else { - this.active = false + this.active = false; } // filterOption.id === this.id ? this.active = true : this.active = false } }, - filterReset (filterOption) { - this.active = false + filterReset(filterOption) { + this.active = false; }, - switchFilter (id, from, to) { - this.$bus.$emit('filter-changed-' + this.context, { attribute_code: this.code, id: id, from: from, to: to }) + switchFilter(id, from, to) { + this.$bus.$emit('filter-changed-' + this.context, { + attribute_code: this.code, + id: id, + from: from, + to: to + }); } } -} +}; diff --git a/core/compatibility/components/SortBy.js b/core/compatibility/components/SortBy.js index 74963cee9c..73197c693c 100644 --- a/core/compatibility/components/SortBy.js +++ b/core/compatibility/components/SortBy.js @@ -1,18 +1,18 @@ -import { CategorySort } from '@vue-storefront/core/modules/catalog/components/CategorySort' +import { CategorySort } from '@vue-storefront/core/modules/catalog/components/CategorySort'; export default { name: 'SortBy', methods: { - changeOrder () { + changeOrder() { // renamed to sort - this.sort() + this.sort(); } }, computed: { - sortByAttribute () { + sortByAttribute() { // renamed to sortingOptions - return this.$store.state.config.products.sortByAttributes + return this.$store.state.config.products.sortByAttributes; } }, mixins: [CategorySort] -} +}; diff --git a/core/compatibility/components/ValidationError.js b/core/compatibility/components/ValidationError.js index 2b2036d3a9..729f4aae28 100644 --- a/core/compatibility/components/ValidationError.js +++ b/core/compatibility/components/ValidationError.js @@ -7,4 +7,4 @@ export default { default: '' } } -} +}; diff --git a/core/compatibility/components/blocks/Auth/Login.js b/core/compatibility/components/blocks/Auth/Login.js index bf1ebe4d0e..330f189636 100644 --- a/core/compatibility/components/blocks/Auth/Login.js +++ b/core/compatibility/components/blocks/Auth/Login.js @@ -1,4 +1,4 @@ -import { Login } from '@vue-storefront/core/modules/user/components/Login' +import { Login } from '@vue-storefront/core/modules/user/components/Login'; export default { mixins: [Login] -} +}; diff --git a/core/compatibility/components/blocks/Auth/Register.js b/core/compatibility/components/blocks/Auth/Register.js index 52de38a824..46884c3efb 100644 --- a/core/compatibility/components/blocks/Auth/Register.js +++ b/core/compatibility/components/blocks/Auth/Register.js @@ -1,4 +1,4 @@ -import { Register } from '@vue-storefront/core/modules/user/components/Register' +import { Register } from '@vue-storefront/core/modules/user/components/Register'; export default { mixins: [Register] -} +}; diff --git a/core/compatibility/components/blocks/Category/Sidebar.js b/core/compatibility/components/blocks/Category/Sidebar.js index 71cc2699ee..fc3166b4da 100644 --- a/core/compatibility/components/blocks/Category/Sidebar.js +++ b/core/compatibility/components/blocks/Category/Sidebar.js @@ -1,6 +1,6 @@ -import { buildFilterProductsQuery } from '@vue-storefront/core/helpers' -import { mapGetters } from 'vuex' -import pickBy from 'lodash-es/pickBy' +import { buildFilterProductsQuery } from '@vue-storefront/core/helpers'; +import { mapGetters } from 'vuex'; +import pickBy from 'lodash-es/pickBy'; export default { name: 'CategorySidebar', @@ -11,37 +11,51 @@ export default { } }, computed: { - ...mapGetters('category', ['getCurrentCategory', 'getActiveCategoryFilters', 'getCurrentCategoryProductQuery']), - category () { - return this.getCurrentCategory + ...mapGetters('category', [ + 'getCurrentCategory', + 'getActiveCategoryFilters', + 'getCurrentCategoryProductQuery' + ]), + category() { + return this.getCurrentCategory; }, - activeFilters () { - return this.getActiveCategoryFilters + activeFilters() { + return this.getActiveCategoryFilters; }, - availableFilters () { - return pickBy(this.filters, (filter) => { return (filter.length) }) + availableFilters() { + return pickBy(this.filters, filter => { + return filter.length; + }); }, - hasActiveFilters () { - return Object.keys(this.activeFilters).length !== 0 + hasActiveFilters() { + return Object.keys(this.activeFilters).length !== 0; } }, - mounted () { - this.resetAllFilters() + mounted() { + this.resetAllFilters(); }, methods: { - sortById (filters) { - return [...filters].sort((a, b) => { return a.id - b.id }) + sortById(filters) { + return [...filters].sort((a, b) => { + return a.id - b.id; + }); }, - resetAllFilters () { + resetAllFilters() { if (this.hasActiveFilters) { - this.$bus.$emit('filter-reset') - this.$store.dispatch('category/resetFilters') - this.$store.dispatch('category/searchProductQuery', {}) + this.$bus.$emit('filter-reset'); + this.$store.dispatch('category/resetFilters'); + this.$store.dispatch('category/searchProductQuery', {}); this.$store.dispatch('category/mergeSearchOptions', { - searchProductQuery: buildFilterProductsQuery(this.category, this.activeFilters) - }) - this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery) + searchProductQuery: buildFilterProductsQuery( + this.category, + this.activeFilters + ) + }); + this.$store.dispatch( + 'category/products', + this.getCurrentCategoryProductQuery + ); } } } -} +}; diff --git a/core/compatibility/components/blocks/Header/AccountIcon.js b/core/compatibility/components/blocks/Header/AccountIcon.js index 8dae2e3c03..cccec57c4d 100644 --- a/core/compatibility/components/blocks/Header/AccountIcon.js +++ b/core/compatibility/components/blocks/Header/AccountIcon.js @@ -1,18 +1,18 @@ -import { AccountButton } from '@vue-storefront/core/modules/user/components/AccountButton' +import { AccountButton } from '@vue-storefront/core/modules/user/components/AccountButton'; export default { name: 'AccountIcon', - data () { + data() { // theme-specific, deprecated return { navigation: [] - } + }; }, computed: { - currentUser () { + currentUser() { // renamed to 'user' - return this.user + return this.user; } }, mixins: [AccountButton] -} +}; diff --git a/core/compatibility/components/blocks/Header/CompareIcon.js b/core/compatibility/components/blocks/Header/CompareIcon.js index 5b12a1638c..afe862d914 100644 --- a/core/compatibility/components/blocks/Header/CompareIcon.js +++ b/core/compatibility/components/blocks/Header/CompareIcon.js @@ -1,12 +1,12 @@ -import { CompareButton } from '@vue-storefront/core/modules/compare/components/CompareButton.ts' +import { CompareButton } from '@vue-storefront/core/modules/compare/components/CompareButton.ts'; export default { name: 'CompareIcon', mixins: [CompareButton], computed: { - isActive () { + isActive() { // Computed Property renamed to 'isEmpty' - return !this.isEmpty + return !this.isEmpty; } } -} +}; diff --git a/core/compatibility/components/blocks/Header/HamburgerIcon.js b/core/compatibility/components/blocks/Header/HamburgerIcon.js index f830f3a4f2..f87d80c214 100644 --- a/core/compatibility/components/blocks/Header/HamburgerIcon.js +++ b/core/compatibility/components/blocks/Header/HamburgerIcon.js @@ -1,4 +1,4 @@ -import { mapState } from 'vuex' +import { mapState } from 'vuex'; // deprecated as theme specific export default { @@ -7,8 +7,8 @@ export default { isOpen: state => state.ui.sidebar }), methods: { - openSidebarMenu () { - this.$store.commit('ui/setSidebar', !this.isOpen) + openSidebarMenu() { + this.$store.commit('ui/setSidebar', !this.isOpen); } } -} +}; diff --git a/core/compatibility/components/blocks/Header/MicrocartIcon.js b/core/compatibility/components/blocks/Header/MicrocartIcon.js index 00ebeff97d..5bd40ebe49 100644 --- a/core/compatibility/components/blocks/Header/MicrocartIcon.js +++ b/core/compatibility/components/blocks/Header/MicrocartIcon.js @@ -1,19 +1,17 @@ -import { MicrocartButton } from '@vue-storefront/core/modules/cart/components/MicrocartButton.ts' +import { MicrocartButton } from '@vue-storefront/core/modules/cart/components/MicrocartButton.ts'; export default { methods: { - openMicrocart () { + openMicrocart() { // Method renamed to 'toggleMicrocart' and is using cart store now - this.$store.dispatch('ui/toggleMicrocart') + this.$store.dispatch('ui/toggleMicrocart'); } }, computed: { - totalQuantity () { + totalQuantity() { // Data field renamed to 'quantity' - return this.quantity + return this.quantity; } }, - mixins: [ - MicrocartButton - ] -} + mixins: [MicrocartButton] +}; diff --git a/core/compatibility/components/blocks/Header/ReturnIcon.js b/core/compatibility/components/blocks/Header/ReturnIcon.js index 5d3956049d..bb690da5ea 100644 --- a/core/compatibility/components/blocks/Header/ReturnIcon.js +++ b/core/compatibility/components/blocks/Header/ReturnIcon.js @@ -8,12 +8,12 @@ export default { } }, methods: { - goBack () { + goBack() { if (this.to) { - this.$router.push(this.to) + this.$router.push(this.to); } else { - this.$router.back() + this.$router.back(); } } } -} +}; diff --git a/core/compatibility/components/blocks/Header/SearchIcon.js b/core/compatibility/components/blocks/Header/SearchIcon.js index c904d46c79..5638359504 100644 --- a/core/compatibility/components/blocks/Header/SearchIcon.js +++ b/core/compatibility/components/blocks/Header/SearchIcon.js @@ -1,4 +1,4 @@ -import { mapState } from 'vuex' +import { mapState } from 'vuex'; export default { name: 'SearchIcon', @@ -8,8 +8,8 @@ export default { }) }, methods: { - toggleSearchpanel () { - this.$store.commit('ui/setSearchpanel', !this.isOpen) + toggleSearchpanel() { + this.$store.commit('ui/setSearchpanel', !this.isOpen); } } -} +}; diff --git a/core/compatibility/components/blocks/Header/WishlistIcon.js b/core/compatibility/components/blocks/Header/WishlistIcon.js index 8cc9d63afe..6988f76b05 100644 --- a/core/compatibility/components/blocks/Header/WishlistIcon.js +++ b/core/compatibility/components/blocks/Header/WishlistIcon.js @@ -1,32 +1,32 @@ -import { WishlistButton } from '@vue-storefront/core/modules/wishlist/components/WishlistButton' +import { WishlistButton } from '@vue-storefront/core/modules/wishlist/components/WishlistButton'; export default { name: 'WishlistIcon', - mixins: [ WishlistButton ], + mixins: [WishlistButton], props: { product: { type: Object, required: false, - default: () => { } + default: () => {} } }, computed: { // deprecated in this component - isWishlistOpen () { - return this.$store.state.ui.wishlist + isWishlistOpen() { + return this.$store.state.ui.wishlist; } }, methods: { // deprecated - closeWishlist () { - this.$store.commit('ui/setWishlist', false) + closeWishlist() { + this.$store.commit('ui/setWishlist', false); }, // deprecated - openWishlist () { - this.$store.commit('ui/setWishlist', true) + openWishlist() { + this.$store.commit('ui/setWishlist', true); }, // method renamed to toggleWishlist - toggleWishlistPanel () { - this.toggleWishlist() + toggleWishlistPanel() { + this.toggleWishlist(); } } -} +}; diff --git a/core/compatibility/components/blocks/Microcart/Microcart.js b/core/compatibility/components/blocks/Microcart/Microcart.js index ac43fbd7a8..3daa609cc6 100644 --- a/core/compatibility/components/blocks/Microcart/Microcart.js +++ b/core/compatibility/components/blocks/Microcart/Microcart.js @@ -1,19 +1,17 @@ // Core dependecies -import { Microcart } from '@vue-storefront/core/modules/cart/components/Microcart.ts' +import { Microcart } from '@vue-storefront/core/modules/cart/components/Microcart.ts'; export default { methods: { - closeMicrocart () { + closeMicrocart() { // Method renamed to 'toggleMicrocart' - this.toggleMicrocart() + this.toggleMicrocart(); } }, computed: { - isMicrocartOpen () { - return this.$store.state.ui.microcart + isMicrocartOpen() { + return this.$store.state.ui.microcart; } }, - mixins: [ - Microcart - ] -} + mixins: [Microcart] +}; diff --git a/core/compatibility/components/blocks/Microcart/Product.js b/core/compatibility/components/blocks/Microcart/Product.js index 9aafe48091..1d45afaa63 100644 --- a/core/compatibility/components/blocks/Microcart/Product.js +++ b/core/compatibility/components/blocks/Microcart/Product.js @@ -1,56 +1,55 @@ -import rootStore from '@vue-storefront/core/store' -import { MicrocartProduct } from '@vue-storefront/core/modules/cart/components/Product.ts' -import i18n from '@vue-storefront/i18n' +import rootStore from '@vue-storefront/core/store'; +import { MicrocartProduct } from '@vue-storefront/core/modules/cart/components/Product.ts'; +import i18n from '@vue-storefront/i18n'; export default { - data () { + data() { // deprecated - return { - } + return {}; }, - beforeMount () { + beforeMount() { // deprecated, will be moved to theme or removed in the near future #1742 - this.$bus.$on('cart-after-itemchanged', this.onProductChanged) - this.$bus.$on('notification-after-itemremoved', this.onProductRemoved) + this.$bus.$on('cart-after-itemchanged', this.onProductChanged); + this.$bus.$on('notification-after-itemremoved', this.onProductRemoved); }, - beforeDestroy () { + beforeDestroy() { // deprecated, will be moved to theme or removed in the near future #1742 - this.$bus.$off('cart-after-itemchanged', this.onProductChanged) - this.$bus.$off('notification-after-itemremoved', this.onProductRemoved) + this.$bus.$off('cart-after-itemchanged', this.onProductChanged); + this.$bus.$off('notification-after-itemremoved', this.onProductRemoved); }, methods: { - removeItem () { + removeItem() { if (rootStore.state.config.cart.askBeforeRemoveProduct) { this.$store.dispatch('notification/spawnNotification', { type: 'warning', item: this.product, - message: i18n.t('Are you sure you would like to remove this item from the shopping cart?'), + message: i18n.t( + 'Are you sure you would like to remove this item from the shopping cart?' + ), action2: { label: i18n.t('OK'), action: this.removeFromCart }, action1: { label: i18n.t('Cancel'), action: 'close' }, hasNoTimeout: true - }) + }); } else { - this.removeFromCart() + this.removeFromCart(); } }, - updateQuantity (newQuantity) { - let quantity = parseInt(newQuantity) - if (quantity < 1) quantity = 1 - MicrocartProduct.methods.updateQuantity.call(this, quantity) + updateQuantity(newQuantity) { + let quantity = parseInt(newQuantity); + if (quantity < 1) quantity = 1; + MicrocartProduct.methods.updateQuantity.call(this, quantity); }, - onProductChanged (event) { + onProductChanged(event) { // deprecated, will be moved to theme or removed in the near future #1742 if (event.item.sku === this.product.sku) { - this.$forceUpdate() + this.$forceUpdate(); } }, - onProductRemoved (event) { + onProductRemoved(event) { if (event.item.sku === this.product.sku) { - this.removeFromCart(event.item) + this.removeFromCart(event.item); } } }, - mixins: [ - MicrocartProduct - ] -} + mixins: [MicrocartProduct] +}; diff --git a/core/compatibility/components/blocks/MyAccount/MyNewsletter.js b/core/compatibility/components/blocks/MyAccount/MyNewsletter.js index 18ea02592b..0e55d875c4 100644 --- a/core/compatibility/components/blocks/MyAccount/MyNewsletter.js +++ b/core/compatibility/components/blocks/MyAccount/MyNewsletter.js @@ -1,44 +1,46 @@ // this component is deprecated and is now in Newsletter module export default { name: 'MyNewsletter', - data () { + data() { return { user: { isSubscribed: false } - } + }; }, methods: { - unsubscribe () { - this.$store.dispatch('mailchimp/unsubscribe', this.$store.state.user.current.email).then(() => { - this.user.isSubscribed = false - this.$store.dispatch('notification/spawnNotification', { - type: 'success', - message: this.$t('Unsubscribed from newsletter'), - action1: { label: this.$t('OK') } + unsubscribe() { + this.$store + .dispatch('mailchimp/unsubscribe', this.$store.state.user.current.email) + .then(() => { + this.user.isSubscribed = false; + this.$store.dispatch('notification/spawnNotification', { + type: 'success', + message: this.$t('Unsubscribed from newsletter'), + action1: { label: this.$t('OK') } + }); }) - }).catch(err => - this.$emit('unsubscription-error', err) - ) + .catch(err => this.$emit('unsubscription-error', err)); }, - subscribe () { - this.$store.dispatch('mailchimp/subscribe', this.$store.state.user.current.email).then(() => { - this.user.isSubscribed = true - this.$store.dispatch('notification/spawnNotification', { - type: 'success', - message: this.$t('Succesfully subscried to newsletter!'), - action1: { label: this.$t('OK') } + subscribe() { + this.$store + .dispatch('mailchimp/subscribe', this.$store.state.user.current.email) + .then(() => { + this.user.isSubscribed = true; + this.$store.dispatch('notification/spawnNotification', { + type: 'success', + message: this.$t('Succesfully subscried to newsletter!'), + action1: { label: this.$t('OK') } + }); }) - }).catch(err => - this.$emit('subscription-error', err) - ) + .catch(err => this.$emit('subscription-error', err)); }, - updateNewsletter () { + updateNewsletter() { if (this.user.isSubscribed) { - this.subscribe() + this.subscribe(); } else { - this.unsubscribe() + this.unsubscribe(); } } } -} +}; diff --git a/core/compatibility/components/blocks/MyAccount/MyOrder.js b/core/compatibility/components/blocks/MyAccount/MyOrder.js index b107d19ead..45af88f29d 100644 --- a/core/compatibility/components/blocks/MyAccount/MyOrder.js +++ b/core/compatibility/components/blocks/MyAccount/MyOrder.js @@ -1,7 +1,7 @@ -import { UserSingleOrder } from '@vue-storefront/core/modules/order/components/UserSingleOrder' +import { UserSingleOrder } from '@vue-storefront/core/modules/order/components/UserSingleOrder'; // Component deprecated, now in Order module export default { name: 'MyOrder', mixins: [UserSingleOrder] -} +}; diff --git a/core/compatibility/components/blocks/MyAccount/MyOrders.js b/core/compatibility/components/blocks/MyAccount/MyOrders.js index e63625750c..980a6e4ffb 100644 --- a/core/compatibility/components/blocks/MyAccount/MyOrders.js +++ b/core/compatibility/components/blocks/MyAccount/MyOrders.js @@ -1,7 +1,7 @@ -import { UserOrders } from '@vue-storefront/core/modules/order/components/UserOrders' +import { UserOrders } from '@vue-storefront/core/modules/order/components/UserOrders'; // component fully deprecated. Use user/components/Orders instead export default { name: 'MyOrders', mixins: [UserOrders] -} +}; diff --git a/core/compatibility/components/blocks/MyAccount/MyProfile.js b/core/compatibility/components/blocks/MyAccount/MyProfile.js index 89081c635d..673746369e 100644 --- a/core/compatibility/components/blocks/MyAccount/MyProfile.js +++ b/core/compatibility/components/blocks/MyAccount/MyProfile.js @@ -1,8 +1,8 @@ -import { UserAccount } from '@vue-storefront/core/modules/user/components/UserAccount' +import { UserAccount } from '@vue-storefront/core/modules/user/components/UserAccount'; // Component deprecated, now in User module export default { name: 'MyProfile', mixins: [UserAccount] -} +}; diff --git a/core/compatibility/components/blocks/MyAccount/MyShippingDetails.js b/core/compatibility/components/blocks/MyAccount/MyShippingDetails.js index 006c946401..9fa6e12f4a 100644 --- a/core/compatibility/components/blocks/MyAccount/MyShippingDetails.js +++ b/core/compatibility/components/blocks/MyAccount/MyShippingDetails.js @@ -1,4 +1,4 @@ -import { UserShippingDetails } from '@vue-storefront/core/modules/user/components/UserShippingDetails' +import { UserShippingDetails } from '@vue-storefront/core/modules/user/components/UserShippingDetails'; export default { mixins: [UserShippingDetails] -} +}; diff --git a/core/compatibility/components/blocks/SearchPanel/SearchPanel.js b/core/compatibility/components/blocks/SearchPanel/SearchPanel.js index fff85d7e2a..e2392c77cf 100644 --- a/core/compatibility/components/blocks/SearchPanel/SearchPanel.js +++ b/core/compatibility/components/blocks/SearchPanel/SearchPanel.js @@ -1,21 +1,21 @@ -import { Search } from '@vue-storefront/core/modules/catalog/components/Search' +import { Search } from '@vue-storefront/core/modules/catalog/components/Search'; // Moved to search module export default { mixins: [Search], - data () { + data() { return { componentLoaded: false - } + }; }, computed: { - showPanel () { - return this.isOpen && this.componentLoaded + showPanel() { + return this.isOpen && this.componentLoaded; } }, - mounted () { + mounted() { this.$nextTick(() => { - this.componentLoaded = true - }) + this.componentLoaded = true; + }); } -} +}; diff --git a/core/compatibility/components/blocks/SidebarMenu/SidebarMenu.js b/core/compatibility/components/blocks/SidebarMenu/SidebarMenu.js index 8351c6a91b..a7404c6dcb 100644 --- a/core/compatibility/components/blocks/SidebarMenu/SidebarMenu.js +++ b/core/compatibility/components/blocks/SidebarMenu/SidebarMenu.js @@ -1,6 +1,6 @@ -import { mapState, mapGetters } from 'vuex' -import onEscapePress from '@vue-storefront/core/mixins/onEscapePress' -import { CompareButton } from '@vue-storefront/core/modules/compare/components/CompareButton.ts' +import { mapState, mapGetters } from 'vuex'; +import onEscapePress from '@vue-storefront/core/mixins/onEscapePress'; +import { CompareButton } from '@vue-storefront/core/modules/compare/components/CompareButton.ts'; // deprecated as theme-specific export default { @@ -8,28 +8,34 @@ export default { mixins: [onEscapePress, CompareButton], computed: { ...mapGetters('category', ['getCategories']), - categories () { - return this.getCategories.filter((op) => { - return op.level === (this.$store.state.config.entities.category.categoriesDynamicPrefetchLevel ? this.$store.state.config.entities.category.categoriesDynamicPrefetchLevel : 2) // display only the root level (level =1 => Default Category), categoriesDynamicPrefetchLevel = 2 by default - }) + categories() { + return this.getCategories.filter(op => { + return ( + op.level === + (this.$store.state.config.entities.category + .categoriesDynamicPrefetchLevel + ? this.$store.state.config.entities.category + .categoriesDynamicPrefetchLevel + : 2) + ); // display only the root level (level =1 => Default Category), categoriesDynamicPrefetchLevel = 2 by default + }); }, ...mapState({ isOpen: state => state.ui.sidebar }), - compareIsActive () { + compareIsActive() { // Computed property renamed to 'isEmpty' - return !this.isEmpty + return !this.isEmpty; } }, - created () { - }, + created() {}, methods: { - onEscapePress () { - this.closeMenu() + onEscapePress() { + this.closeMenu(); }, - closeMenu () { - this.$store.commit('ui/setSidebar', false) - this.$store.commit('ui/setMicrocart', false) + closeMenu() { + this.$store.commit('ui/setSidebar', false); + this.$store.commit('ui/setMicrocart', false); } } -} +}; diff --git a/core/compatibility/components/blocks/Wishlist/Product.js b/core/compatibility/components/blocks/Wishlist/Product.js index de87541b62..142d775b05 100644 --- a/core/compatibility/components/blocks/Wishlist/Product.js +++ b/core/compatibility/components/blocks/Wishlist/Product.js @@ -1,11 +1,11 @@ -import { WishlistProduct } from '@vue-storefront/core/modules/wishlist/components/Product' +import { WishlistProduct } from '@vue-storefront/core/modules/wishlist/components/Product'; export default { name: 'Product', methods: { // deprecated - closeWishlist () { - this.$store.commit('ui/setWishlist', false) + closeWishlist() { + this.$store.commit('ui/setWishlist', false); } }, mixins: [WishlistProduct] -} +}; diff --git a/core/compatibility/components/blocks/Wishlist/Wishlist.js b/core/compatibility/components/blocks/Wishlist/Wishlist.js index dc474a6604..27e23930d2 100644 --- a/core/compatibility/components/blocks/Wishlist/Wishlist.js +++ b/core/compatibility/components/blocks/Wishlist/Wishlist.js @@ -1,5 +1,5 @@ -import onEscapePress from '@vue-storefront/core/mixins/onEscapePress' -import { Wishlist } from '@vue-storefront/core/modules/wishlist/components/Wishlist' +import onEscapePress from '@vue-storefront/core/mixins/onEscapePress'; +import { Wishlist } from '@vue-storefront/core/modules/wishlist/components/Wishlist'; export default { name: 'Wishlist', props: { @@ -7,14 +7,14 @@ export default { product: { type: Object, required: false, - default: () => { } + default: () => {} } }, methods: { // theme-specific - onEscapePress () { - this.closeWishlist() + onEscapePress() { + this.closeWishlist(); } }, - mixins: [ Wishlist, onEscapePress ] -} + mixins: [Wishlist, onEscapePress] +}; diff --git a/core/compatibility/lib/extensions.ts b/core/compatibility/lib/extensions.ts index 6a2567dfd1..dc648f8797 100644 --- a/core/compatibility/lib/extensions.ts +++ b/core/compatibility/lib/extensions.ts @@ -1,13 +1,24 @@ -import { Logger } from '@vue-storefront/core/lib/logger' +import { Logger } from '@vue-storefront/core/lib/logger'; -export function registerExtensions (extensions, app, router, store, config, ssrContext = null) { +export function registerExtensions( + extensions, + app, + router, + store, + config, + ssrContext = null +) { for (let extEntryPoint of extensions) { if (extEntryPoint !== null) { - if (extEntryPoint.default) extEntryPoint = extEntryPoint.default - let extDescriptor = extEntryPoint(app, router, store, config, ssrContext) // register module + if (extEntryPoint.default) extEntryPoint = extEntryPoint.default; + let extDescriptor = extEntryPoint(app, router, store, config, ssrContext); // register module if (extDescriptor != null) { - Logger.warn('Extension' + extDescriptor.EXTENSION_KEY + ' registered. Extensions are deprecated and will be removed from VS core. Use modules instead')() - app.$emit('application-after-registerExtensions', extDescriptor) + Logger.warn( + 'Extension' + + extDescriptor.EXTENSION_KEY + + ' registered. Extensions are deprecated and will be removed from VS core. Use modules instead' + )(); + app.$emit('application-after-registerExtensions', extDescriptor); } } } diff --git a/core/compatibility/plugins/config/index.js b/core/compatibility/plugins/config/index.js index d9b61aade7..665c71a295 100644 --- a/core/compatibility/plugins/config/index.js +++ b/core/compatibility/plugins/config/index.js @@ -1,18 +1,18 @@ -import store from '@vue-storefront/core/store' -const config = store.state.config +import store from '@vue-storefront/core/store'; +const config = store.state.config; // deprecated, use vuex store instead const ConfigPlugin = { - install (Vue) { + install(Vue) { if (!Vue.prototype.$config) { Object.defineProperties(Vue.prototype, { $config: { - get: function () { - return config + get: function() { + return config; } } - }) + }); } } -} +}; -export { config as default, ConfigPlugin } +export { config as default, ConfigPlugin }; diff --git a/core/compatibility/plugins/event-bus/index.js b/core/compatibility/plugins/event-bus/index.js index 959a24038b..0c4ad2d575 100644 --- a/core/compatibility/plugins/event-bus/index.js +++ b/core/compatibility/plugins/event-bus/index.js @@ -1,4 +1,4 @@ -import Vue from 'vue' +import Vue from 'vue'; // will be replaced with new mechanism with code-completion (via modules), don't use if you don't need to /** * Filter extension is for running async data filters as event handlers @@ -27,49 +27,49 @@ const filterExt = { writable: true }, // data filters to be registered by extension developers $filter: { - get: function () { + get: function() { return (eventName, callback) => { if (!this.$dataFilters[eventName]) { - this.$dataFilters[eventName] = [] + this.$dataFilters[eventName] = []; } - this.$dataFilters[eventName].push(callback) - } + this.$dataFilters[eventName].push(callback); + }; } }, $emitFilter: { - get: function () { + get: function() { return (eventName, ...args) => { if (args.length === 1) { - args = args[0] + args = args[0]; } - this.$emit(eventName, args) - let promises = [] + this.$emit(eventName, args); + let promises = []; if (this.$dataFilters[eventName]) { for (let cb of this.$dataFilters[eventName]) { - promises.push(cb(args)) + promises.push(cb(args)); } } - return Promise.all(promises) - } + return Promise.all(promises); + }; } } -} -const EventBus = new Vue() +}; +const EventBus = new Vue(); if (!EventBus.$dataFilters) { - Object.defineProperties(EventBus, filterExt) + Object.defineProperties(EventBus, filterExt); } const EventBusPlugin = { - install (Vue) { + install(Vue) { if (!Vue.prototype.$bus) { Object.defineProperties(Vue.prototype, { $bus: { - get: function () { - return EventBus + get: function() { + return EventBus; } } - }) + }); } } -} -export { EventBus as default, EventBusPlugin } +}; +export { EventBus as default, EventBusPlugin }; diff --git a/core/compatibility/plugins/index.js b/core/compatibility/plugins/index.js index 42a61e6953..1f7bb720c2 100644 --- a/core/compatibility/plugins/index.js +++ b/core/compatibility/plugins/index.js @@ -1,7 +1,4 @@ -import { EventBusPlugin } from '@vue-storefront/core/compatibility/plugins/event-bus' -import { ConfigPlugin } from '@vue-storefront/core/compatibility/plugins/config' +import { EventBusPlugin } from '@vue-storefront/core/compatibility/plugins/event-bus'; +import { ConfigPlugin } from '@vue-storefront/core/compatibility/plugins/config'; // used in core entrys and themes.js, deprecated bc of redundancy and for simplification of a project -export { - EventBusPlugin, - ConfigPlugin -} +export { EventBusPlugin, ConfigPlugin }; diff --git a/core/filters/capitalize.js b/core/filters/capitalize.js index 072a7ef840..d92843540e 100644 --- a/core/filters/capitalize.js +++ b/core/filters/capitalize.js @@ -2,8 +2,8 @@ * Capitalize first letter of provided text * @param {String} text */ -export function capitalize (text) { - if (!text) return '' - text = text.toString() - return text.charAt(0).toUpperCase() + text.slice(1) +export function capitalize(text) { + if (!text) return ''; + text = text.toString(); + return text.charAt(0).toUpperCase() + text.slice(1); } diff --git a/core/filters/date.js b/core/filters/date.js index dbb9658556..e44a0a3005 100644 --- a/core/filters/date.js +++ b/core/filters/date.js @@ -1,11 +1,11 @@ -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; /** * Converts date to format provided as an argument or defined in config file (if argument not provided) * @param {String} date * @param {String} format */ -export function date (date, format) { - const storeView = currentStoreView() - return new Date(date).toLocaleString(storeView.i18n.defaultLocale) +export function date(date, format) { + const storeView = currentStoreView(); + return new Date(date).toLocaleString(storeView.i18n.defaultLocale); } diff --git a/core/filters/html-decode.js b/core/filters/html-decode.js index c40b677072..2f57feb901 100644 --- a/core/filters/html-decode.js +++ b/core/filters/html-decode.js @@ -1,9 +1,9 @@ -import decode from 'lean-he/decode' +import decode from 'lean-he/decode'; /** * Decodes any named and numerical character references in text * @param {String} value */ -export function htmlDecode (value) { - return value ? decode(value) : '' +export function htmlDecode(value) { + return value ? decode(value) : ''; } diff --git a/core/filters/index.js b/core/filters/index.js index f649e07fa5..0188e3bdfd 100644 --- a/core/filters/index.js +++ b/core/filters/index.js @@ -1,9 +1,9 @@ -import { price } from './price' -import { htmlDecode } from './html-decode' -import { date } from './date' -import { capitalize } from './capitalize' -import { formatProductMessages } from './product-messages' -import { stripHTML } from './strip-html' +import { price } from './price'; +import { htmlDecode } from './html-decode'; +import { date } from './date'; +import { capitalize } from './capitalize'; +import { formatProductMessages } from './product-messages'; +import { stripHTML } from './strip-html'; export { price, @@ -12,4 +12,4 @@ export { capitalize, formatProductMessages, stripHTML -} +}; diff --git a/core/filters/price.js b/core/filters/price.js index e229b83807..15c4cc487b 100644 --- a/core/filters/price.js +++ b/core/filters/price.js @@ -1,33 +1,33 @@ -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; /** * Converts number to price string * @param {Number} value */ -export function price (value) { +export function price(value) { if (isNaN(value)) { - return value + return value; } - let formattedVal = Math.abs(parseFloat(value)).toFixed(2) - const storeView = currentStoreView() + let formattedVal = Math.abs(parseFloat(value)).toFixed(2); + const storeView = currentStoreView(); - const prependCurrency = (price) => { - return storeView.i18n.currencySign + price - } + const prependCurrency = price => { + return storeView.i18n.currencySign + price; + }; - const appendCurrency = (price) => { - return price + storeView.i18n.currencySign - } + const appendCurrency = price => { + return price + storeView.i18n.currencySign; + }; if (storeView.i18n.currencySignPlacement === 'append') { - formattedVal = appendCurrency(formattedVal) + formattedVal = appendCurrency(formattedVal); } else { - formattedVal = prependCurrency(formattedVal) + formattedVal = prependCurrency(formattedVal); } if (value >= 0) { - return formattedVal + return formattedVal; } else { - return '-' + formattedVal + return '-' + formattedVal; } } diff --git a/core/filters/product-messages/index.js b/core/filters/product-messages/index.js index dda95cb7ba..cff00e96f3 100644 --- a/core/filters/product-messages/index.js +++ b/core/filters/product-messages/index.js @@ -1,12 +1,12 @@ /** * Format message string for product validation messages object */ -export function formatProductMessages (messages) { - const msgs = [] +export function formatProductMessages(messages) { + const msgs = []; for (const infoKey in messages) { if (messages[infoKey]) { - msgs.push(messages[infoKey]) + msgs.push(messages[infoKey]); } } - return msgs.join(', ') + return msgs.join(', '); } diff --git a/core/filters/product-messages/typed.ts b/core/filters/product-messages/typed.ts index 76190b5be1..e728b3a162 100644 --- a/core/filters/product-messages/typed.ts +++ b/core/filters/product-messages/typed.ts @@ -1,12 +1,12 @@ /** * Format message string for product validation messages object */ -export function formatProductMessages (messages: Object): string { - const msgs = [] +export function formatProductMessages(messages: Object): string { + const msgs = []; for (const infoKey in messages) { if (messages[infoKey]) { - msgs.push(messages[infoKey]) + msgs.push(messages[infoKey]); } } - return msgs.join(', ') + return msgs.join(', '); } diff --git a/core/filters/strip-html.js b/core/filters/strip-html.js index 2f6c5f6d29..c5d7f2c586 100644 --- a/core/filters/strip-html.js +++ b/core/filters/strip-html.js @@ -2,7 +2,7 @@ * Strip HTML tags * @param {String} html */ -export function stripHTML (html) { - if (!html) return '' - return html.replace(/<[^>]+>/g, '').trim() +export function stripHTML(html) { + if (!html) return ''; + return html.replace(/<[^>]+>/g, '').trim(); } diff --git a/core/helpers/exceptions.js b/core/helpers/exceptions.js index 181a2aa8a5..b2843523ca 100644 --- a/core/helpers/exceptions.js +++ b/core/helpers/exceptions.js @@ -3,12 +3,12 @@ export class HttpError { * ValidationError to be used with multiple validation errors return from Ajv or other validators * @param {Object} _validationMessages dictionary of validation errors */ - constructor (message, code) { - this.message = message - this.code = code - this.name = 'ValidationError' + constructor(message, code) { + this.message = message; + this.code = code; + this.name = 'ValidationError'; } - toString () { - return 'HttpError' + this.code + ': ' + this.message + toString() { + return 'HttpError' + this.code + ': ' + this.message; } } diff --git a/core/helpers/index.ts b/core/helpers/index.ts index 314584e73a..50e57ade4a 100644 --- a/core/helpers/index.ts +++ b/core/helpers/index.ts @@ -1,17 +1,17 @@ -import rootStore from '@vue-storefront/core/store' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { remove as removeAccents } from 'remove-accents' -import { Logger } from '@vue-storefront/core/lib/logger' -import { formatCategoryLink } from '@vue-storefront/core/modules/url/helpers' -import Vue from 'vue' +import rootStore from '@vue-storefront/core/store'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { remove as removeAccents } from 'remove-accents'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { formatCategoryLink } from '@vue-storefront/core/modules/url/helpers'; +import Vue from 'vue'; /** * Create slugify -> "create-slugify" permalink of text * @param {String} text */ -export function slugify (text) { +export function slugify(text) { // remove regional characters - text = removeAccents(text) + text = removeAccents(text); return text .toString() @@ -19,7 +19,7 @@ export function slugify (text) { .replace(/\s+/g, '-') // Replace spaces with - .replace(/&/g, '-and-') // Replace & with 'and' .replace(/[^\w-]+/g, '') // Remove all non-word chars - .replace(/--+/g, '-') // Replace multiple - with single - + .replace(/--+/g, '-'); // Replace multiple - with single - } /** @@ -28,22 +28,34 @@ export function slugify (text) { * @param height * @returns {*} */ -export function getThumbnailPath (relativeUrl, width, height) { +export function getThumbnailPath(relativeUrl, width, height) { if (rootStore.state.config.images.useExactUrlsNoProxy) { - return relativeUrl // this is exact url mode + return relativeUrl; // this is exact url mode } else { - let resultUrl - if (relativeUrl && (relativeUrl.indexOf('://') > 0 || relativeUrl.indexOf('?') > 0 || relativeUrl.indexOf('&') > 0)) relativeUrl = encodeURIComponent(relativeUrl) - let baseUrl = rootStore.state.config.images.proxyUrl ? rootStore.state.config.images.proxyUrl : rootStore.state.config.images.baseUrl // proxyUrl is not a url base path but contains {{url}} parameters and so on to use the relativeUrl as a template value and then do the image proxy opertions + let resultUrl; + if ( + relativeUrl && + (relativeUrl.indexOf('://') > 0 || + relativeUrl.indexOf('?') > 0 || + relativeUrl.indexOf('&') > 0) + ) + relativeUrl = encodeURIComponent(relativeUrl); + let baseUrl = rootStore.state.config.images.proxyUrl + ? rootStore.state.config.images.proxyUrl + : rootStore.state.config.images.baseUrl; // proxyUrl is not a url base path but contains {{url}} parameters and so on to use the relativeUrl as a template value and then do the image proxy opertions if (baseUrl.indexOf('{{') >= 0) { - baseUrl = baseUrl.replace('{{url}}', relativeUrl) - baseUrl = baseUrl.replace('{{width}}', width) - baseUrl = baseUrl.replace('{{height}}', height) - resultUrl = baseUrl + baseUrl = baseUrl.replace('{{url}}', relativeUrl); + baseUrl = baseUrl.replace('{{width}}', width); + baseUrl = baseUrl.replace('{{height}}', height); + resultUrl = baseUrl; } else { - resultUrl = `${baseUrl}${parseInt(width)}/${parseInt(height)}/resize${relativeUrl}` + resultUrl = `${baseUrl}${parseInt(width)}/${parseInt( + height + )}/resize${relativeUrl}`; } - return relativeUrl && relativeUrl.indexOf('no_selection') < 0 ? resultUrl : rootStore.state.config.images.productPlaceholder || '' + return relativeUrl && relativeUrl.indexOf('no_selection') < 0 + ? resultUrl + : rootStore.state.config.images.productPlaceholder || ''; } } @@ -51,15 +63,15 @@ export function getThumbnailPath (relativeUrl, width, height) { * Re-format category path to be suitable for breadcrumb * @param {Array} categoryPath */ -export function formatBreadCrumbRoutes (categoryPath) { - const breadCrumbRoutesArray = [] +export function formatBreadCrumbRoutes(categoryPath) { + const breadCrumbRoutesArray = []; for (let category of categoryPath) { breadCrumbRoutesArray.push({ name: category.name, route_link: formatCategoryLink(category) - }) + }); } - return breadCrumbRoutesArray + return breadCrumbRoutesArray; } /** @@ -67,103 +79,141 @@ export function formatBreadCrumbRoutes (categoryPath) { * @param {object} product * @param {bool} ignoreConfig */ -export function productThumbnailPath (product, ignoreConfig = false) { - let thumbnail = product.image - if ((product.type_id && product.type_id === 'configurable') && product.hasOwnProperty('configurable_children') && - product.configurable_children.length && (ignoreConfig || !product.is_configured) && - ('image' in product.configurable_children[0]) +export function productThumbnailPath(product, ignoreConfig = false) { + let thumbnail = product.image; + if ( + product.type_id && + product.type_id === 'configurable' && + product.hasOwnProperty('configurable_children') && + product.configurable_children.length && + (ignoreConfig || !product.is_configured) && + 'image' in product.configurable_children[0] ) { - thumbnail = product.configurable_children[0].image + thumbnail = product.configurable_children[0].image; if (!thumbnail || thumbnail === 'no_selection') { - const childWithImg = product.configurable_children.find(f => f.image && f.image !== 'no_selection') + const childWithImg = product.configurable_children.find( + f => f.image && f.image !== 'no_selection' + ); if (childWithImg) { - thumbnail = childWithImg.image + thumbnail = childWithImg.image; } else { - thumbnail = product.image + thumbnail = product.image; } } } - return thumbnail + return thumbnail; } -export function buildFilterProductsQuery (currentCategory, chosenFilters, defaultFilters = null) { - let filterQr = baseFilterProductsQuery(currentCategory, defaultFilters == null ? rootStore.state.config.products.defaultFilters : defaultFilters) +export function buildFilterProductsQuery( + currentCategory, + chosenFilters, + defaultFilters = null +) { + let filterQr = baseFilterProductsQuery( + currentCategory, + defaultFilters == null + ? rootStore.state.config.products.defaultFilters + : defaultFilters + ); // add choosedn filters for (let code of Object.keys(chosenFilters)) { - const filter = chosenFilters[code] + const filter = chosenFilters[code]; if (filter.attribute_code !== 'price') { - filterQr = filterQr.applyFilter({key: filter.attribute_code, value: {'eq': filter.id}, scope: 'catalog'}) - } else { // multi should be possible filter here? - const rangeqr = {} + filterQr = filterQr.applyFilter({ + key: filter.attribute_code, + value: { eq: filter.id }, + scope: 'catalog' + }); + } else { + // multi should be possible filter here? + const rangeqr = {}; if (filter.from) { - rangeqr['gte'] = filter.from + rangeqr['gte'] = filter.from; } if (filter.to) { - rangeqr['lte'] = filter.to + rangeqr['lte'] = filter.to; } - filterQr = filterQr.applyFilter({key: filter.attribute_code, value: rangeqr, scope: 'catalog'}) + filterQr = filterQr.applyFilter({ + key: filter.attribute_code, + value: rangeqr, + scope: 'catalog' + }); } } - return filterQr + return filterQr; } -export function baseFilterProductsQuery (parentCategory, filters = []) { // TODO add aggregation of color_options and size_options fields - let searchProductQuery = new SearchQuery() +export function baseFilterProductsQuery(parentCategory, filters = []) { + // TODO add aggregation of color_options and size_options fields + let searchProductQuery = new SearchQuery(); searchProductQuery = searchProductQuery - .applyFilter({key: 'visibility', value: {'in': [2, 3, 4]}}) - .applyFilter({key: 'status', value: {'in': [0, 1]}}) /* 2 = disabled, 4 = out of stock */ + .applyFilter({ key: 'visibility', value: { in: [2, 3, 4] } }) + .applyFilter({ + key: 'status', + value: { in: [0, 1] } + }); /* 2 = disabled, 4 = out of stock */ if (rootStore.state.config.products.listOutOfStockProducts === false) { - searchProductQuery = searchProductQuery.applyFilter({key: 'stock.is_in_stock', value: {'eq': true}}) + searchProductQuery = searchProductQuery.applyFilter({ + key: 'stock.is_in_stock', + value: { eq: true } + }); } // Add available catalog filters for (let attrToFilter of filters) { - searchProductQuery = searchProductQuery.addAvailableFilter({field: attrToFilter, scope: 'catalog'}) + searchProductQuery = searchProductQuery.addAvailableFilter({ + field: attrToFilter, + scope: 'catalog' + }); } - let childCats = [parentCategory.id] + let childCats = [parentCategory.id]; if (parentCategory.children_data) { - let recurCatFinderBuilder = (category) => { + let recurCatFinderBuilder = category => { if (!category) { - return + return; } if (!category.children_data) { - return + return; } for (let sc of category.children_data) { if (sc && sc.id) { - childCats.push(sc.id) + childCats.push(sc.id); } - recurCatFinderBuilder(sc) + recurCatFinderBuilder(sc); } - } - recurCatFinderBuilder(parentCategory) + }; + recurCatFinderBuilder(parentCategory); } - searchProductQuery = searchProductQuery.applyFilter({key: 'category_ids', value: {'in': childCats}}) - return searchProductQuery + searchProductQuery = searchProductQuery.applyFilter({ + key: 'category_ids', + value: { in: childCats } + }); + return searchProductQuery; } - -export function once (key, fn) { - const { process = {} } = global - const processKey = key + '__ONCE__' +export function once(key, fn) { + const { process = {} } = global; + const processKey = key + '__ONCE__'; if (!process.hasOwnProperty(processKey)) { // Logger.debug(`Once ${key}`, 'helper')() - process[processKey] = true - fn() + process[processKey] = true; + fn(); } } -export const isServer: boolean = typeof window === 'undefined' +export const isServer: boolean = typeof window === 'undefined'; // Online/Offline helper -export const onlineHelper = Vue.observable({ - isOnline: isServer || navigator.onLine -}) -!isServer && window.addEventListener('online', () => onlineHelper.isOnline = true) -!isServer && window.addEventListener('offline', () => onlineHelper.isOnline = false) +export const onlineHelper = Vue.observable({ + isOnline: isServer || navigator.onLine +}); +!isServer && + window.addEventListener('online', () => (onlineHelper.isOnline = true)); +!isServer && + window.addEventListener('offline', () => (onlineHelper.isOnline = false)); diff --git a/core/helpers/initCacheStorage.ts b/core/helpers/initCacheStorage.ts index 85f973ffaa..029f17ab12 100644 --- a/core/helpers/initCacheStorage.ts +++ b/core/helpers/initCacheStorage.ts @@ -1,30 +1,35 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import rootStore from '@vue-storefront/core/store' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import rootStore from '@vue-storefront/core/store'; /** Inits cache storage for given module. By default via local storage */ export function initCacheStorage(key, localised = true) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - const config = rootStore.state.config - const cacheDriver = config.localForage && config.localForage.defaultDrivers[key] ? - config.localForage.defaultDrivers[key] : - 'LOCALSTORAGE' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; + const config = rootStore.state.config; + const cacheDriver = + config.localForage && config.localForage.defaultDrivers[key] + ? config.localForage.defaultDrivers[key] + : 'LOCALSTORAGE'; if (localised) { - const cacheStorage = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: key, - driver: localForage[cacheDriver] - })) - return cacheStorage + const cacheStorage = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: key, + driver: localForage[cacheDriver] + }) + ); + return cacheStorage; } else { - const cacheStorage = new UniversalStorage(localForage.createInstance({ - name: 'shop', - storeName: key, - driver: localForage[cacheDriver] - })) - return cacheStorage + const cacheStorage = new UniversalStorage( + localForage.createInstance({ + name: 'shop', + storeName: key, + driver: localForage[cacheDriver] + }) + ); + return cacheStorage; } } diff --git a/core/helpers/log.js b/core/helpers/log.js index 1a725b9fd1..ad7b7803e3 100644 --- a/core/helpers/log.js +++ b/core/helpers/log.js @@ -1,40 +1,40 @@ -import { isServer } from '@vue-storefront/core/helpers' +import { isServer } from '@vue-storefront/core/helpers'; /** * @param {string} level available options: 'no-console', 'only-errors', 'all' */ -export function takeOverConsole (level = 'no-console') { - const console = !isServer ? window.console : global.console - if (!console) return +export function takeOverConsole(level = 'no-console') { + const console = !isServer ? window.console : global.console; + if (!console) return; - function intercept (method) { - const original = console[method] - console[method] = function () { - let filterMethods = [] + function intercept(method) { + const original = console[method]; + console[method] = function() { + let filterMethods = []; if (level === 'no-console') { - filterMethods = ['warn', 'debug', 'log', 'error'] + filterMethods = ['warn', 'debug', 'log', 'error']; } if (level === 'only-errors') { - filterMethods = ['warn', 'debug', 'log'] + filterMethods = ['warn', 'debug', 'log']; } if (filterMethods.indexOf(method) >= 0) { - return + return; } // do sneaky stuff if (original.apply) { // Do this for normal browsers - original.apply(console, arguments) + original.apply(console, arguments); } else { // Do this for IE - const message = Array.prototype.slice.apply(arguments).join(' ') - original(message) + const message = Array.prototype.slice.apply(arguments).join(' '); + original(message); } - } + }; } - const methods = ['log', 'warn', 'error', 'debug'] + const methods = ['log', 'warn', 'error', 'debug']; for (let i = 0; i < methods.length; i++) { - intercept(methods[i]) + intercept(methods[i]); } } diff --git a/core/i18n/index.ts b/core/i18n/index.ts index 26683f6a3e..09455735c7 100644 --- a/core/i18n/index.ts +++ b/core/i18n/index.ts @@ -1,49 +1,57 @@ -import Vue from 'vue' -import VueI18n from 'vue-i18n' -import config from 'config' -import { Logger } from '@vue-storefront/core/lib/logger' -import { once } from '@vue-storefront/core/helpers' +import Vue from 'vue'; +import VueI18n from 'vue-i18n'; +import config from 'config'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { once } from '@vue-storefront/core/helpers'; once('__VUE_EXTEND_I18N__', () => { - Vue.use(VueI18n) -}) + Vue.use(VueI18n); +}); -const loadedLanguages = ['en-US'] +const loadedLanguages = ['en-US']; const i18n = new VueI18n({ - locale: config.i18n.bundleAllStoreviewLanguages ? config.i18n.defaultLocale : 'en-US', // set locale + locale: config.i18n.bundleAllStoreviewLanguages + ? config.i18n.defaultLocale + : 'en-US', // set locale fallbackLocale: 'en-US', - messages: config.i18n.bundleAllStoreviewLanguages ? require('./resource/i18n/multistoreLanguages.json') : { - 'en-US': require('./resource/i18n/en-US.json') - } -}) + messages: config.i18n.bundleAllStoreviewLanguages + ? require('./resource/i18n/multistoreLanguages.json') + : { + 'en-US': require('./resource/i18n/en-US.json') + } +}); -function setI18nLanguage (lang: string): string { - i18n.locale = lang - return lang +function setI18nLanguage(lang: string): string { + i18n.locale = lang; + return lang; } -export function loadLanguageAsync (lang: string): Promise { +export function loadLanguageAsync(lang: string): Promise { if (!config.i18n.bundleAllStoreviewLanguages) { if (i18n.locale !== lang) { if (!loadedLanguages.includes(lang)) { - return import(/* webpackChunkName: "lang-[request]" */ `./resource/i18n/${lang}.json`).then(msgs => { - i18n.setLocaleMessage(lang, msgs.default) - loadedLanguages.push(lang) - return setI18nLanguage(lang) - }).catch(err => { - Logger.debug('Unable to load translation')() - return '' - }) + return import( + /* webpackChunkName: "lang-[request]" */ `./resource/i18n/${lang}.json` + ) + .then(msgs => { + i18n.setLocaleMessage(lang, msgs.default); + loadedLanguages.push(lang); + return setI18nLanguage(lang); + }) + .catch(err => { + Logger.debug('Unable to load translation')(); + return ''; + }); } - return Promise.resolve(setI18nLanguage(lang)) + return Promise.resolve(setI18nLanguage(lang)); } } else { - loadedLanguages.push(lang) - return Promise.resolve(setI18nLanguage(lang)) + loadedLanguages.push(lang); + return Promise.resolve(setI18nLanguage(lang)); } - return Promise.resolve(lang) + return Promise.resolve(lang); } -loadLanguageAsync(config.i18n.defaultLocale) +loadLanguageAsync(config.i18n.defaultLocale); -export default i18n +export default i18n; diff --git a/core/i18n/scripts/translation.preprocessor.js b/core/i18n/scripts/translation.preprocessor.js index 1502478bea..7b0451beb8 100644 --- a/core/i18n/scripts/translation.preprocessor.js +++ b/core/i18n/scripts/translation.preprocessor.js @@ -1,57 +1,72 @@ -const fs = require('fs') -const path = require('path') -const dsvFormat = require('d3-dsv').dsvFormat -const dsv = dsvFormat(',') +const fs = require('fs'); +const path = require('path'); +const dsvFormat = require('d3-dsv').dsvFormat; +const dsv = dsvFormat(','); /** * Converts an Array to an Object */ -function convertToObject (array) { - const obj = [] +function convertToObject(array) { + const obj = []; array.forEach((element, index, array) => { - obj[element[0]] = element[1] - }) - return obj + obj[element[0]] = element[1]; + }); + return obj; } -module.exports = function (csvDirectories, config = null) { - let messages = {} - let languages = [] +module.exports = function(csvDirectories, config = null) { + let messages = {}; + let languages = []; csvDirectories.forEach(directory => { fs.readdirSync(directory).forEach(file => { - const fullFileName = path.join(directory, file) - const extName = path.extname(fullFileName) - const baseName = path.posix.basename(file, extName) + const fullFileName = path.join(directory, file); + const extName = path.extname(fullFileName); + const baseName = path.posix.basename(file, extName); if (extName === '.csv') { - const fileContent = fs.readFileSync(fullFileName, 'utf8') + const fileContent = fs.readFileSync(fullFileName, 'utf8'); if (languages.indexOf(baseName) === -1) { - languages.push(baseName) + languages.push(baseName); } - console.debug(`Processing translation file: ${fullFileName}`) - messages[baseName] = Object.assign(messages[baseName] ? messages[baseName] : {}, convertToObject(dsv.parseRows(fileContent))) + console.debug(`Processing translation file: ${fullFileName}`); + messages[baseName] = Object.assign( + messages[baseName] ? messages[baseName] : {}, + convertToObject(dsv.parseRows(fileContent)) + ); } - }) - }) + }); + }); - languages.forEach((language) => { - if (!config || !config.i18n.bundleAllStoreviewLanguages || (config.i18n.bundleAllStoreviewLanguages && language === 'en-US')) { - console.debug(`Writing JSON file: ${language}.json`) - fs.writeFileSync(path.join(__dirname, '../resource/i18n', `${language}.json`), JSON.stringify(messages[language])) + languages.forEach(language => { + if ( + !config || + !config.i18n.bundleAllStoreviewLanguages || + (config.i18n.bundleAllStoreviewLanguages && language === 'en-US') + ) { + console.debug(`Writing JSON file: ${language}.json`); + fs.writeFileSync( + path.join(__dirname, '../resource/i18n', `${language}.json`), + JSON.stringify(messages[language]) + ); } - }) + }); if (config && config.i18n.bundleAllStoreviewLanguages) { - const bundledLanguages = { 'en-US': messages['en-US'] } // fallback locale - bundledLanguages[config.i18n.defaultLocale] = messages[config.i18n.defaultLocale] // default locale - Object.keys(config.storeViews).forEach((storeCode) => { - const store = config.storeViews[storeCode] + const bundledLanguages = { 'en-US': messages['en-US'] }; // fallback locale + bundledLanguages[config.i18n.defaultLocale] = + messages[config.i18n.defaultLocale]; // default locale + Object.keys(config.storeViews).forEach(storeCode => { + const store = config.storeViews[storeCode]; if (store.hasOwnProperty('storeCode')) { if (!store.disabled && store.i18n) { - bundledLanguages[store.i18n.defaultLocale] = messages[store.i18n.defaultLocale] + bundledLanguages[store.i18n.defaultLocale] = + messages[store.i18n.defaultLocale]; } } - }) - fs.writeFileSync(path.join(__dirname, '../resource/i18n', `multistoreLanguages.json`), JSON.stringify(bundledLanguages)) + }); + fs.writeFileSync( + path.join(__dirname, '../resource/i18n', `multistoreLanguages.json`), + JSON.stringify(bundledLanguages) + ); } -} +}; diff --git a/core/lib/async-data-loader.ts b/core/lib/async-data-loader.ts index e431792d62..cd9b83df36 100644 --- a/core/lib/async-data-loader.ts +++ b/core/lib/async-data-loader.ts @@ -1,51 +1,61 @@ /** -* @deprecated This module has been created before Vue.js v2.6.0. From 2.6.x on please do preferably use the `serverPrefetch` hook to sync SSR Vuex data. More info: https://ssr.vuejs.org/api/#serverprefetch -* @description Please note: This module can be used not only for `asyncData` extensibility but also for simplyfying the data loaders in Vuex actions or other components - basicaly everywhere where we must `wait` for some async operations to complete. -*/ -import { isServer } from '@vue-storefront/core/helpers' -import { Logger } from '@vue-storefront/core/lib/logger' + * @deprecated This module has been created before Vue.js v2.6.0. From 2.6.x on please do preferably use the `serverPrefetch` hook to sync SSR Vuex data. More info: https://ssr.vuejs.org/api/#serverprefetch + * @description Please note: This module can be used not only for `asyncData` extensibility but also for simplyfying the data loaders in Vuex actions or other components - basicaly everywhere where we must `wait` for some async operations to complete. + */ +import { isServer } from '@vue-storefront/core/helpers'; +import { Logger } from '@vue-storefront/core/lib/logger'; -const DEFAULT_ACTION_CATEGORY = 'asyncData' +const DEFAULT_ACTION_CATEGORY = 'asyncData'; // Data loader queues all the data fetching operations and runs them at once - to be usedf for example in the `asyncData()` functions interface AsyncDataLoaderActionContext { - category?: string, - route: any, - store: any, - context: any + category?: string; + route: any; + store: any; + context: any; } // Data loader queues all the data fetching operations and runs them at once - to be usedf for example in the `asyncData()` functions interface AsyncDataLoaderAction { - execute: any, // this function must return a Promise - category?: string, - name?: string, - executedAt?: Date, - scheduledAt?: Date + execute: any; // this function must return a Promise + category?: string; + name?: string; + executedAt?: Date; + scheduledAt?: Date; } /** AsyncDataLoader helper for queueing the data fetching operations. The main purpose is to decentralize the `asyncData()` SSR method */ const AsyncDataLoader = { + queue: new Array(), - queue : new Array(), - - push : function (action: AsyncDataLoaderAction) { - if (!action.category) action.category = DEFAULT_ACTION_CATEGORY - action.scheduledAt = new Date() - this.queue.push(action) + push: function(action: AsyncDataLoaderAction) { + if (!action.category) action.category = DEFAULT_ACTION_CATEGORY; + action.scheduledAt = new Date(); + this.queue.push(action); }, - flush : function (actionContext: AsyncDataLoaderActionContext) { - if (!actionContext.category) actionContext.category = DEFAULT_ACTION_CATEGORY - const actionsToExecute = this.queue.filter(ac => (!ac.category || !actionContext.category) || ac.category === actionContext.category && (!ac.executedAt)).map(ac => { - ac.executedAt = new Date() - return ac.execute(actionContext) // function must return Promise - }) + flush: function(actionContext: AsyncDataLoaderActionContext) { + if (!actionContext.category) + actionContext.category = DEFAULT_ACTION_CATEGORY; + const actionsToExecute = this.queue + .filter( + ac => + !ac.category || + !actionContext.category || + (ac.category === actionContext.category && !ac.executedAt) + ) + .map(ac => { + ac.executedAt = new Date(); + return ac.execute(actionContext); // function must return Promise + }); if (actionsToExecute.length > 0) { - Logger.info('Executing data loader actions(' + actionsToExecute.length + ')', 'dataloader')() + Logger.info( + 'Executing data loader actions(' + actionsToExecute.length + ')', + 'dataloader' + )(); } - return Promise.all(actionsToExecute).then(results => { - return results - }) + return Promise.all(actionsToExecute).then(results => { + return results; + }); } -} +}; -export { AsyncDataLoader, AsyncDataLoaderActionContext, AsyncDataLoaderAction } +export { AsyncDataLoader, AsyncDataLoaderActionContext, AsyncDataLoaderAction }; diff --git a/core/lib/logger.ts b/core/lib/logger.ts index cf353d513a..d7d84a6900 100644 --- a/core/lib/logger.ts +++ b/core/lib/logger.ts @@ -1,6 +1,7 @@ -import { isServer } from '@vue-storefront/core/helpers' -import buildTimeConfig from 'config' -const bgColorStyle = (color) => `color: white; background: ${color}; padding: 4px; font-weight: bold; font-size: 0.8em'` +import { isServer } from '@vue-storefront/core/helpers'; +import buildTimeConfig from 'config'; +const bgColorStyle = color => + `color: white; background: ${color}; padding: 4px; font-weight: bold; font-size: 0.8em'`; /** VS message logger. By default works only on dev mode */ class Logger { @@ -25,20 +26,28 @@ class Logger { * @param verbosityLevel * @param showErrorOnProduction */ - constructor (verbosityLevel: string = 'display-everything', showErrorOnProduction: boolean = false) { - this.verbosityLevel = verbosityLevel - this.showErrorOnProduction = showErrorOnProduction - this.isProduction = process.env.NODE_ENV === 'production' + constructor( + verbosityLevel: string = 'display-everything', + showErrorOnProduction: boolean = false + ) { + this.verbosityLevel = verbosityLevel; + this.showErrorOnProduction = showErrorOnProduction; + this.isProduction = process.env.NODE_ENV === 'production'; } /** * Convert message to string - as it may be object, array either primitive * @param payload */ - convertToString (payload: any) { - if (typeof payload === 'string' || typeof payload === 'boolean' || typeof payload === 'number') return payload - if (payload && payload.message) return payload.message - return JSON.stringify(payload) + convertToString(payload: any) { + if ( + typeof payload === 'string' || + typeof payload === 'boolean' || + typeof payload === 'number' + ) + return payload; + if (payload && payload.message) return payload.message; + return JSON.stringify(payload); } /** @@ -46,16 +55,22 @@ class Logger { * * @param {string} method */ - canPrint (method: string) { - const allowedMethods = [] + canPrint(method: string) { + const allowedMethods = []; - if (this.verbosityLevel === 'display-everything' && this.isProduction === false) { - allowedMethods.push(...['info', 'warn', 'error', 'debug']) - } else if (this.verbosityLevel === 'only-errors' && (this.isProduction === false || this.showErrorOnProduction === true)) { - allowedMethods.push('error') + if ( + this.verbosityLevel === 'display-everything' && + this.isProduction === false + ) { + allowedMethods.push(...['info', 'warn', 'error', 'debug']); + } else if ( + this.verbosityLevel === 'only-errors' && + (this.isProduction === false || this.showErrorOnProduction === true) + ) { + allowedMethods.push('error'); } - return allowedMethods.indexOf(method) !== -1 + return allowedMethods.indexOf(method) !== -1; } /** @@ -66,19 +81,37 @@ class Logger { * @param tag short tag specifying area where message was spawned (eg. cart, sync, module) * @param context meaningful data related to this message */ - debug (message: any, tag: string = null, context: any = null) : () => void { + debug(message: any, tag: string = null, context: any = null): () => void { if (!this.canPrint('debug')) { - return () => {} + return () => {}; } if (isServer) { - return console.debug.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context) + return console.debug.bind( + console, + (tag ? `[${tag}] ` : '') + this.convertToString(message), + context + ); } if (tag) { - return console.debug.bind(window.console, '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), bgColorStyle('grey'), 'color: inherit', bgColorStyle('gray'), 'font-weight: normal', context) + return console.debug.bind( + window.console, + '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), + bgColorStyle('grey'), + 'color: inherit', + bgColorStyle('gray'), + 'font-weight: normal', + context + ); } else { - return console.debug.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('grey'), 'font-weight: normal', context) + return console.debug.bind( + window.console, + '%cVSF%c ' + this.convertToString(message), + bgColorStyle('grey'), + 'font-weight: normal', + context + ); } } @@ -90,8 +123,8 @@ class Logger { * @param tag short tag specifying area where message was spawned (eg. cart, sync, module) * @param context meaningful data related to this message */ - log (message: any, tag: string = null, context: any = null) : () => void { - return this.info(message, tag, context) + log(message: any, tag: string = null, context: any = null): () => void { + return this.info(message, tag, context); } /** @@ -102,19 +135,37 @@ class Logger { * @param tag short tag specifying area where message was spawned (eg. cart, sync, module) * @param context meaningful data related to this message */ - info (message: any, tag: string = null, context: any = null) : () => void { + info(message: any, tag: string = null, context: any = null): () => void { if (!this.canPrint('info')) { - return () => {} + return () => {}; } if (isServer) { - return console.log.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context) + return console.log.bind( + console, + (tag ? `[${tag}] ` : '') + this.convertToString(message), + context + ); } if (tag) { - return console.log.bind(window.console, '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), bgColorStyle('green'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context) + return console.log.bind( + window.console, + '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), + bgColorStyle('green'), + 'color: inherit', + bgColorStyle('gray'), + 'font-weight: bold', + context + ); } else { - return console.log.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('green'), 'font-weight: bold', context) + return console.log.bind( + window.console, + '%cVSF%c ' + this.convertToString(message), + bgColorStyle('green'), + 'font-weight: bold', + context + ); } } @@ -126,18 +177,36 @@ class Logger { * @param tag short tag specifying area where message was spawned (eg. cart, sync, module) * @param context meaningful data related to this message */ - warn (message: any, tag: string = null, context: any = null) : () => void { + warn(message: any, tag: string = null, context: any = null): () => void { if (!this.canPrint('warn')) { - return () => {} + return () => {}; } if (isServer) { - return console.warn.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context) + return console.warn.bind( + console, + (tag ? `[${tag}] ` : '') + this.convertToString(message), + context + ); } if (tag) { - return console.warn.bind(window.console, '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), bgColorStyle('orange'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context) + return console.warn.bind( + window.console, + '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), + bgColorStyle('orange'), + 'color: inherit', + bgColorStyle('gray'), + 'font-weight: bold', + context + ); } else { - return console.warn.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('orange'), 'font-weight: bold', context) + return console.warn.bind( + window.console, + '%cVSF%c ' + this.convertToString(message), + bgColorStyle('orange'), + 'font-weight: bold', + context + ); } } @@ -149,26 +218,45 @@ class Logger { * @param tag short tag specifying area where message was spawned (eg. cart, sync, module) * @param context meaningful data related to this message */ - error (message: any, tag: string = null, context: any = null) : () => void { - if (isServer) { // always show errors in SSR - return console.error.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context) + error(message: any, tag: string = null, context: any = null): () => void { + if (isServer) { + // always show errors in SSR + return console.error.bind( + console, + (tag ? `[${tag}] ` : '') + this.convertToString(message), + context + ); } if (this.canPrint('error')) { if (tag) { - return console.error.bind(window.console, '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), bgColorStyle('red'), 'color: inherit', bgColorStyle('gray'), 'font-weight: bold', context) + return console.error.bind( + window.console, + '%cVSF%c %c' + tag + '%c ' + this.convertToString(message), + bgColorStyle('red'), + 'color: inherit', + bgColorStyle('gray'), + 'font-weight: bold', + context + ); } else { - return console.error.bind(window.console, '%cVSF%c ' + this.convertToString(message), bgColorStyle('red'), 'font-weight: bold', context) + return console.error.bind( + window.console, + '%cVSF%c ' + this.convertToString(message), + bgColorStyle('red'), + 'font-weight: bold', + context + ); } } - return () => {} + return () => {}; } } const logger = new Logger( buildTimeConfig.console.verbosityLevel, buildTimeConfig.console.showErrorOnProduction -) +); -export {logger as Logger} +export { logger as Logger }; diff --git a/core/lib/module/helpers.ts b/core/lib/module/helpers.ts index 163d847d43..4412731afd 100644 --- a/core/lib/module/helpers.ts +++ b/core/lib/module/helpers.ts @@ -1,35 +1,46 @@ -import { VueStorefrontModuleConfig } from './types' -import { Module } from 'vuex' -import merge from 'lodash-es/merge' -import some from 'lodash-es/some' -import find from 'lodash-es/find' +import { VueStorefrontModuleConfig } from './types'; +import { Module } from 'vuex'; +import merge from 'lodash-es/merge'; +import some from 'lodash-es/some'; +import find from 'lodash-es/find'; -function doesStoreAlreadyExists (key: string, registeredModules: VueStorefrontModuleConfig[]) : boolean { +function doesStoreAlreadyExists( + key: string, + registeredModules: VueStorefrontModuleConfig[] +): boolean { registeredModules.forEach(m => { if (m.store) { - if (m.store.modules.some(m => m.key === key)) return true + if (m.store.modules.some(m => m.key === key)) return true; } - }) - return false + }); + return false; } -function mergeStores ( - originalStore: { modules?: { key: string, module: Module }[], plugin?: Function }, - extendedStore: { modules?: { key: string, module: Module }[], plugin?: Function } +function mergeStores( + originalStore: { + modules?: { key: string; module: Module }[]; + plugin?: Function; + }, + extendedStore: { + modules?: { key: string; module: Module }[]; + plugin?: Function; + } ) { - let mergedArray = [] + let mergedArray = []; originalStore.modules.map(item => { - mergedArray.push(merge(item, find(extendedStore.modules, { 'key' : item.key }))); - }) + mergedArray.push( + merge(item, find(extendedStore.modules, { key: item.key })) + ); + }); extendedStore.modules.map(extendedStoreItem => { - if(some(originalStore.modules, null, { 'key' : extendedStoreItem.key}) === false){ - mergedArray.push(extendedStoreItem) + if ( + some(originalStore.modules, null, { key: extendedStoreItem.key }) === + false + ) { + mergedArray.push(extendedStoreItem); } - }) - return mergedArray + }); + return mergedArray; } -export { - doesStoreAlreadyExists, - mergeStores -} \ No newline at end of file +export { doesStoreAlreadyExists, mergeStores }; diff --git a/core/lib/module/index.ts b/core/lib/module/index.ts index 1aac304662..096f09991c 100644 --- a/core/lib/module/index.ts +++ b/core/lib/module/index.ts @@ -1,128 +1,175 @@ -import { Module } from 'vuex' -import { RouteConfig, NavigationGuard } from 'vue-router' -import Vue from 'vue' -import merge from 'lodash-es/merge' -import rootStore from '@vue-storefront/core/store' -import { Logger } from '@vue-storefront/core/lib/logger' -import { setupMultistoreRoutes } from '..//multistore' -import { router } from '@vue-storefront/core/app' -import { isServer } from '@vue-storefront/core/helpers' -import { VSF, VueStorefrontModuleConfig } from './types' -import { doesStoreAlreadyExists, mergeStores } from './helpers' -import { RouterManager } from '@vue-storefront/core/lib/router-manager' - -const moduleExtendings: VueStorefrontModuleConfig[] = [] -const registeredModules: VueStorefrontModuleConfig[] = [] - -function registerModules (modules: VueStorefrontModule[], context): void { - modules.forEach(m => m.register()) +import { Module } from 'vuex'; +import { RouteConfig, NavigationGuard } from 'vue-router'; +import Vue from 'vue'; +import merge from 'lodash-es/merge'; +import rootStore from '@vue-storefront/core/store'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { setupMultistoreRoutes } from '..//multistore'; +import { router } from '@vue-storefront/core/app'; +import { isServer } from '@vue-storefront/core/helpers'; +import { VSF, VueStorefrontModuleConfig } from './types'; +import { doesStoreAlreadyExists, mergeStores } from './helpers'; +import { RouterManager } from '@vue-storefront/core/lib/router-manager'; + +const moduleExtendings: VueStorefrontModuleConfig[] = []; +const registeredModules: VueStorefrontModuleConfig[] = []; + +function registerModules(modules: VueStorefrontModule[], context): void { + modules.forEach(m => m.register()); Logger.info('VS Modules registration finished.', 'module', { - succesfulyRegistered: registeredModules.length + ' / ' + modules.length, - registrationOrder: registeredModules - } - )() + succesfulyRegistered: registeredModules.length + ' / ' + modules.length, + registrationOrder: registeredModules + })(); } -function isModuleRegistered (key: string): boolean { - return registeredModules.some(m => m.key === key) +function isModuleRegistered(key: string): boolean { + return registeredModules.some(m => m.key === key); } -function createModule (config: VueStorefrontModuleConfig): VueStorefrontModule { - return new VueStorefrontModule(config) +function createModule(config: VueStorefrontModuleConfig): VueStorefrontModule { + return new VueStorefrontModule(config); } function extendModule(moduleConfig: VueStorefrontModuleConfig) { - moduleExtendings.push(moduleConfig) + moduleExtendings.push(moduleConfig); } - class VueStorefrontModule { - private _isRegistered = false - constructor ( - private _c: VueStorefrontModuleConfig, - ) { } - - private static _extendStore (storeInstance: any, modules: { key: string, module: Module }[], plugin: any) : void { - if (modules) modules.forEach(store => storeInstance.registerModule(store.key, store.module)) - if (plugin) storeInstance.subscribe(plugin) + private _isRegistered = false; + constructor(private _c: VueStorefrontModuleConfig) {} + + private static _extendStore( + storeInstance: any, + modules: { key: string; module: Module }[], + plugin: any + ): void { + if (modules) + modules.forEach(store => + storeInstance.registerModule(store.key, store.module) + ); + if (plugin) storeInstance.subscribe(plugin); } - private static _extendRouter (routerInstance, routes?: RouteConfig[], beforeEach?: NavigationGuard, afterEach?: NavigationGuard): void { + private static _extendRouter( + routerInstance, + routes?: RouteConfig[], + beforeEach?: NavigationGuard, + afterEach?: NavigationGuard + ): void { if (routes) { - setupMultistoreRoutes(rootStore.state.config, routerInstance, routes) - RouterManager.addRoutes(routes, routerInstance) + setupMultistoreRoutes(rootStore.state.config, routerInstance, routes); + RouterManager.addRoutes(routes, routerInstance); } - if (beforeEach) routerInstance.beforeEach(beforeEach) - if (afterEach) routerInstance.afterEach(afterEach) + if (beforeEach) routerInstance.beforeEach(beforeEach); + if (afterEach) routerInstance.afterEach(afterEach); } - private _extendModule (extendedConfig: VueStorefrontModuleConfig): void { + private _extendModule(extendedConfig: VueStorefrontModuleConfig): void { const mergedStore = { modules: [] }; - const key = this._c.key - const originalStore = this._c.store - const extendedStore = extendedConfig.store - delete this._c.store - delete extendedConfig.store - this._c = merge(this._c, extendedConfig) - mergedStore.modules = mergeStores(originalStore, extendedStore) - this._c.store = mergedStore - Logger.info('Module "' + key + '" has been succesfully extended.', 'module')() + const key = this._c.key; + const originalStore = this._c.store; + const extendedStore = extendedConfig.store; + delete this._c.store; + delete extendedConfig.store; + this._c = merge(this._c, extendedConfig); + mergedStore.modules = mergeStores(originalStore, extendedStore); + this._c.store = mergedStore; + Logger.info( + 'Module "' + key + '" has been succesfully extended.', + 'module' + )(); } - public get config () { - return this._c + public get config() { + return this._c; } /** Use only if you want to explicitly modify module config. Otherwise it's much easier to use `extendModule` */ - public set config (config) { - this._c = config + public set config(config) { + this._c = config; } - - public register (): VueStorefrontModuleConfig | void { + + public register(): VueStorefrontModuleConfig | void { if (!this._isRegistered) { - let areStoresUnique = true + let areStoresUnique = true; const VSF: VSF = { - Vue, - config: rootStore.state.config, - store: rootStore, + Vue, + config: rootStore.state.config, + store: rootStore, isServer - } + }; moduleExtendings.forEach(extending => { - if (extending.key === this._c.key) this._extendModule(extending) - }) + if (extending.key === this._c.key) this._extendModule(extending); + }); if (this._c.store) { this._c.store.modules.forEach(store => { if (doesStoreAlreadyExists(store.key, registeredModules)) { - Logger.warn('Error during "' + this._c.key + '" module registration! Store with key "' + store.key + '" already exists!', 'module')() - areStoresUnique = false + Logger.warn( + 'Error during "' + + this._c.key + + '" module registration! Store with key "' + + store.key + + '" already exists!', + 'module' + )(); + areStoresUnique = false; } - }) + }); } if (areStoresUnique) { if (this._c.beforeRegistration) { - if (this._c.beforeRegistration.length === 1 ) { - this._c.beforeRegistration(VSF) + if (this._c.beforeRegistration.length === 1) { + this._c.beforeRegistration(VSF); } else { - Logger.warn('You are using outdated signature for beforeRegistration hook that soon will be deprecated and module will stop working properly. Please update to the new signature that can be found in our docs: https://docs.vuestorefront.io/guide/modules/introduction.html#beforeregistration', 'module', this._c.key)() - this._c.beforeRegistration(Vue, rootStore.state.config, rootStore, isServer) + Logger.warn( + 'You are using outdated signature for beforeRegistration hook that soon will be deprecated and module will stop working properly. Please update to the new signature that can be found in our docs: https://docs.vuestorefront.io/guide/modules/introduction.html#beforeregistration', + 'module', + this._c.key + )(); + this._c.beforeRegistration( + Vue, + rootStore.state.config, + rootStore, + isServer + ); } } - if (this._c.store) VueStorefrontModule._extendStore(rootStore, this._c.store.modules, this._c.store.plugin) - if (this._c.router) VueStorefrontModule._extendRouter(router, this._c.router.routes, this._c.router.beforeEach, this._c.router.afterEach) - registeredModules.push(this._c) - this._isRegistered = true + if (this._c.store) + VueStorefrontModule._extendStore( + rootStore, + this._c.store.modules, + this._c.store.plugin + ); + if (this._c.router) + VueStorefrontModule._extendRouter( + router, + this._c.router.routes, + this._c.router.beforeEach, + this._c.router.afterEach + ); + registeredModules.push(this._c); + this._isRegistered = true; if (this._c.afterRegistration) { - if (this._c.afterRegistration.length === 1 ) { - this._c.afterRegistration(VSF) - } else { - Logger.warn('You are using outdated signature for afterRegistration hook that soon will be deprecated and module will stop working properly. Please update to the new signature that can be found in our docs: https://docs.vuestorefront.io/guide/modules/introduction.html#afterregistration', 'module', this._c.key)() - this._c.afterRegistration(Vue, rootStore.state.config, rootStore, isServer) - } + if (this._c.afterRegistration.length === 1) { + this._c.afterRegistration(VSF); + } else { + Logger.warn( + 'You are using outdated signature for afterRegistration hook that soon will be deprecated and module will stop working properly. Please update to the new signature that can be found in our docs: https://docs.vuestorefront.io/guide/modules/introduction.html#afterregistration', + 'module', + this._c.key + )(); + this._c.afterRegistration( + Vue, + rootStore.state.config, + rootStore, + isServer + ); + } } - return this._c + return this._c; } } } @@ -136,4 +183,4 @@ export { registerModules, isModuleRegistered, createModule -} +}; diff --git a/core/lib/module/types.ts b/core/lib/module/types.ts index 03ac5d3c86..7686856c42 100644 --- a/core/lib/module/types.ts +++ b/core/lib/module/types.ts @@ -1,24 +1,38 @@ -import { Module, Store } from 'vuex' -import { RouteConfig, NavigationGuard } from 'vue-router' -import { VueConstructor } from 'vue' -import RootState from '@vue-storefront/core/types/RootState' +import { Module, Store } from 'vuex'; +import { RouteConfig, NavigationGuard } from 'vue-router'; +import { VueConstructor } from 'vue'; +import RootState from '@vue-storefront/core/types/RootState'; interface VSF { - Vue?: VueConstructor, - config?: Object, - store?: Store, - isServer?: boolean + Vue?: VueConstructor; + config?: Object; + store?: Store; + isServer?: boolean; } interface VueStorefrontModuleConfig { key: string; - store?: { modules?: { key: string, module: Module }[], plugin?: Function }; - router?: { routes?: RouteConfig[], beforeEach?: NavigationGuard, afterEach?: NavigationGuard }, - beforeRegistration?: (VSF: VSF | VueConstructor, config?: Object, store?: Store, isServer?: boolean) => void, - afterRegistration?: (VSF: VSF | VueConstructor, config?: Object, store?: Store, isServer?: boolean) => void, + store?: { + modules?: { key: string; module: Module }[]; + plugin?: Function; + }; + router?: { + routes?: RouteConfig[]; + beforeEach?: NavigationGuard; + afterEach?: NavigationGuard; + }; + beforeRegistration?: ( + VSF: VSF | VueConstructor, + config?: Object, + store?: Store, + isServer?: boolean + ) => void; + afterRegistration?: ( + VSF: VSF | VueConstructor, + config?: Object, + store?: Store, + isServer?: boolean + ) => void; } -export { - VSF, - VueStorefrontModuleConfig -} \ No newline at end of file +export { VSF, VueStorefrontModuleConfig }; diff --git a/core/lib/multistore.ts b/core/lib/multistore.ts index b63fedec32..f3979d68be 100644 --- a/core/lib/multistore.ts +++ b/core/lib/multistore.ts @@ -1,155 +1,213 @@ -import rootStore from '../store' -import { loadLanguageAsync } from '@vue-storefront/i18n' -import { initializeSyncTaskStorage } from './sync/task' -import Vue from 'vue' -import queryString from 'query-string' -import { RouterManager } from '@vue-storefront/core/lib/router-manager' +import rootStore from '../store'; +import { loadLanguageAsync } from '@vue-storefront/i18n'; +import { initializeSyncTaskStorage } from './sync/task'; +import Vue from 'vue'; +import queryString from 'query-string'; +import { RouterManager } from '@vue-storefront/core/lib/router-manager'; import VueRouter, { RouteConfig, RawLocation } from 'vue-router'; export interface LocalizedRoute { - path?: string, - name?: string, - hash?: string, - params?: object, - fullPath?: string, + path?: string; + name?: string; + hash?: string; + params?: object; + fullPath?: string; } export interface StoreView { - storeCode: string, - disabled?: boolean, - storeId: any, - name?: string, - url?: string, + storeCode: string; + disabled?: boolean; + storeId: any; + name?: string; + url?: string; elasticsearch: { - host: string, - index: string - }, + host: string; + index: string; + }; tax: { - sourcePriceIncludesTax: boolean, - defaultCountry: string, - defaultRegion: null | string, - calculateServerSide: boolean - }, + sourcePriceIncludesTax: boolean; + defaultCountry: string; + defaultRegion: null | string; + calculateServerSide: boolean; + }; i18n: { - fullCountryName: string, - fullLanguageName: string, - defaultLanguage: string, - defaultCountry: string, - defaultLocale: string, - currencyCode: string, - currencySign: string, - dateFormat: string - } + fullCountryName: string; + fullLanguageName: string; + defaultLanguage: string; + defaultCountry: string; + defaultLocale: string; + currencyCode: string; + currencySign: string; + dateFormat: string; + }; } -export function currentStoreView () : StoreView { +export function currentStoreView(): StoreView { // TODO: Change to getter all along our code - return rootStore.state.storeView + return rootStore.state.storeView; } -export function prepareStoreView (storeCode: string) : StoreView { - const config = rootStore.state.config - let storeView = { // current, default store +export function prepareStoreView(storeCode: string): StoreView { + const config = rootStore.state.config; + let storeView = { + // current, default store tax: config.tax, i18n: config.i18n, elasticsearch: config.elasticsearch, storeCode: '', - storeId: config.defaultStoreCode && config.defaultStoreCode !== '' ? config.storeViews[config.defaultStoreCode].storeId : 1 - } - const storeViewHasChanged = !rootStore.state.storeView || rootStore.state.storeView.storeCode !== storeCode - if (storeCode) { // current store code + storeId: + config.defaultStoreCode && config.defaultStoreCode !== '' + ? config.storeViews[config.defaultStoreCode].storeId + : 1 + }; + const storeViewHasChanged = + !rootStore.state.storeView || + rootStore.state.storeView.storeCode !== storeCode; + if (storeCode) { + // current store code if ((storeView = config.storeViews[storeCode])) { - storeView.storeCode = storeCode - rootStore.state.user.current_storecode = storeCode + storeView.storeCode = storeCode; + rootStore.state.user.current_storecode = storeCode; } } else { - storeView.storeCode = config.defaultStoreCode || '' - rootStore.state.user.current_storecode = config.defaultStoreCode || '' + storeView.storeCode = config.defaultStoreCode || ''; + rootStore.state.user.current_storecode = config.defaultStoreCode || ''; } - loadLanguageAsync(storeView.i18n.defaultLocale) + loadLanguageAsync(storeView.i18n.defaultLocale); if (storeViewHasChanged) { - rootStore.state.storeView = storeView + rootStore.state.storeView = storeView; } if (storeViewHasChanged || Vue.prototype.$db.currentStoreCode !== storeCode) { if (typeof Vue.prototype.$db === 'undefined') { - Vue.prototype.$db = {} + Vue.prototype.$db = {}; } - initializeSyncTaskStorage() - Vue.prototype.$db.currentStoreCode = storeView.storeCode + initializeSyncTaskStorage(); + Vue.prototype.$db.currentStoreCode = storeView.storeCode; } - return storeView + return storeView; } -export function storeCodeFromRoute (matchedRouteOrUrl: LocalizedRoute | RawLocation | string) : string { +export function storeCodeFromRoute( + matchedRouteOrUrl: LocalizedRoute | RawLocation | string +): string { if (matchedRouteOrUrl) { for (const storeCode of rootStore.state.config.storeViews.mapStoreUrlsFor) { - let urlPath = typeof matchedRouteOrUrl === 'object' ? matchedRouteOrUrl.path : matchedRouteOrUrl - if (urlPath.length > 0 && urlPath[0] !== '/') urlPath = '/' + urlPath - if (urlPath.startsWith('/' + storeCode + '/') || urlPath === '/' + storeCode) { - return storeCode + let urlPath = + typeof matchedRouteOrUrl === 'object' + ? matchedRouteOrUrl.path + : matchedRouteOrUrl; + if (urlPath.length > 0 && urlPath[0] !== '/') urlPath = '/' + urlPath; + if ( + urlPath.startsWith('/' + storeCode + '/') || + urlPath === '/' + storeCode + ) { + return storeCode; } } - return '' + return ''; } else { - return '' + return ''; } } -export function removeStoreCodeFromRoute (matchedRouteOrUrl: LocalizedRoute | string) : LocalizedRoute | string { - const storeCodeInRoute = storeCodeFromRoute(matchedRouteOrUrl) +export function removeStoreCodeFromRoute( + matchedRouteOrUrl: LocalizedRoute | string +): LocalizedRoute | string { + const storeCodeInRoute = storeCodeFromRoute(matchedRouteOrUrl); if (storeCodeInRoute !== '') { - let urlPath = typeof matchedRouteOrUrl === 'object' ? matchedRouteOrUrl.path : matchedRouteOrUrl - return urlPath.replace(storeCodeInRoute + '/', '') + let urlPath = + typeof matchedRouteOrUrl === 'object' + ? matchedRouteOrUrl.path + : matchedRouteOrUrl; + return urlPath.replace(storeCodeInRoute + '/', ''); } else { - return matchedRouteOrUrl + return matchedRouteOrUrl; } } -export function adjustMultistoreApiUrl (url: string) : string { - const storeView = currentStoreView() +export function adjustMultistoreApiUrl(url: string): string { + const storeView = currentStoreView(); if (storeView.storeCode) { - const urlSep = (url.indexOf('?') > 0) ? '&' : '?' - url += urlSep + 'storeCode=' + storeView.storeCode + const urlSep = url.indexOf('?') > 0 ? '&' : '?'; + url += urlSep + 'storeCode=' + storeView.storeCode; } - return url + return url; } -export function localizedRoute (routeObj: LocalizedRoute | string | RouteConfig | RawLocation, storeCode: string): any { - if (routeObj && (routeObj).fullPath && rootStore.state.config.seo.useUrlDispatcher) return localizedDispatcherRoute(Object.assign({}, routeObj, { params: null }), storeCode) - if (storeCode && routeObj && rootStore.state.config.defaultStoreCode !== storeCode) { +export function localizedRoute( + routeObj: LocalizedRoute | string | RouteConfig | RawLocation, + storeCode: string +): any { + if ( + routeObj && + (routeObj).fullPath && + rootStore.state.config.seo.useUrlDispatcher + ) + return localizedDispatcherRoute( + Object.assign({}, routeObj, { params: null }), + storeCode + ); + if ( + storeCode && + routeObj && + rootStore.state.config.defaultStoreCode !== storeCode + ) { if (typeof routeObj === 'object') { if (routeObj.name) { - routeObj.name = storeCode + '-' + routeObj.name + routeObj.name = storeCode + '-' + routeObj.name; } if (routeObj.path) { - routeObj.path = '/' + storeCode + '/' + (routeObj.path.startsWith('/') ? routeObj.path.slice(1) : routeObj.path) + routeObj.path = + '/' + + storeCode + + '/' + + (routeObj.path.startsWith('/') + ? routeObj.path.slice(1) + : routeObj.path); } } else { - return '/' + storeCode + routeObj + return '/' + storeCode + routeObj; } } - return routeObj + return routeObj; } -export function localizedDispatcherRoute (routeObj: LocalizedRoute | string, storeCode: string): LocalizedRoute | string { +export function localizedDispatcherRoute( + routeObj: LocalizedRoute | string, + storeCode: string +): LocalizedRoute | string { if (typeof routeObj === 'string') { - return '/' + storeCode + routeObj - } - if (routeObj && routeObj.fullPath) { // case of using dispatcher - const routeCodePrefix = rootStore.state.config.defaultStoreCode !== storeCode ? `/${storeCode}` : '' - const qrStr = queryString.stringify(routeObj.params) - return `${routeCodePrefix}/${routeObj.fullPath}${qrStr ? `?${qrStr}` : ''}` + return '/' + storeCode + routeObj; + } + if (routeObj && routeObj.fullPath) { + // case of using dispatcher + const routeCodePrefix = + rootStore.state.config.defaultStoreCode !== storeCode + ? `/${storeCode}` + : ''; + const qrStr = queryString.stringify(routeObj.params); + return `${routeCodePrefix}/${routeObj.fullPath}${qrStr ? `?${qrStr}` : ''}`; } - return routeObj + return routeObj; } -export function setupMultistoreRoutes (config, router: VueRouter, routes: RouteConfig[]): void { - if (config.storeViews.mapStoreUrlsFor.length > 0 && config.storeViews.multistore === true) { +export function setupMultistoreRoutes( + config, + router: VueRouter, + routes: RouteConfig[] +): void { + if ( + config.storeViews.mapStoreUrlsFor.length > 0 && + config.storeViews.multistore === true + ) { for (let storeCode of config.storeViews.mapStoreUrlsFor) { if (storeCode) { - let storeRoutes = [] + let storeRoutes = []; for (let route of routes) { - const localRoute = localizedRoute(Object.assign({}, route), storeCode) - storeRoutes.push(localRoute) + const localRoute = localizedRoute( + Object.assign({}, route), + storeCode + ); + storeRoutes.push(localRoute); } - RouterManager.addRoutes(storeRoutes, router) + RouterManager.addRoutes(storeRoutes, router); } } } diff --git a/core/lib/passive-listeners.js b/core/lib/passive-listeners.js index 890eff2c31..9d113b4bc5 100644 --- a/core/lib/passive-listeners.js +++ b/core/lib/passive-listeners.js @@ -1,59 +1,78 @@ const eventListenerOptionsSupported = () => { - let supported = false + let supported = false; try { const opts = Object.defineProperty({}, 'passive', { - get () { - supported = true + get() { + supported = true; } - }) + }); - window.addEventListener('test', null, opts) - window.removeEventListener('test', null, opts) + window.addEventListener('test', null, opts); + window.removeEventListener('test', null, opts); } catch (e) {} - return supported -} + return supported; +}; const defaultOptions = { passive: true, capture: false -} +}; const supportedPassiveTypes = [ - 'scroll', 'wheel', - 'touchstart', 'touchmove', 'touchenter', 'touchend', 'touchleave', - 'mouseout', 'mouseleave', 'mouseup', 'mousedown', 'mousemove', 'mouseenter', 'mousewheel', 'mouseover' -] + 'scroll', + 'wheel', + 'touchstart', + 'touchmove', + 'touchenter', + 'touchend', + 'touchleave', + 'mouseout', + 'mouseleave', + 'mouseup', + 'mousedown', + 'mousemove', + 'mouseenter', + 'mousewheel', + 'mouseover' +]; const getDefaultPassiveOption = (passive, eventName) => { - if (passive !== undefined) return passive + if (passive !== undefined) return passive; - return supportedPassiveTypes.indexOf(eventName) === -1 ? false : defaultOptions.passive -} + return supportedPassiveTypes.indexOf(eventName) === -1 + ? false + : defaultOptions.passive; +}; -const getWritableOptions = (options) => { - const passiveDescriptor = Object.getOwnPropertyDescriptor(options, 'passive') +const getWritableOptions = options => { + const passiveDescriptor = Object.getOwnPropertyDescriptor(options, 'passive'); - return passiveDescriptor && passiveDescriptor.writable !== true && passiveDescriptor.set === undefined ? Object.assign({}, options) : options -} + return passiveDescriptor && + passiveDescriptor.writable !== true && + passiveDescriptor.set === undefined + ? Object.assign({}, options) + : options; +}; -const overwriteAddEvent = (superMethod) => { - EventTarget.prototype.addEventListener = function (type, listener, options) { - const usesListenerOptions = typeof options === 'object' && options !== null - const useCapture = usesListenerOptions ? options.capture : options +const overwriteAddEvent = superMethod => { + EventTarget.prototype.addEventListener = function(type, listener, options) { + const usesListenerOptions = typeof options === 'object' && options !== null; + const useCapture = usesListenerOptions ? options.capture : options; - options = usesListenerOptions ? getWritableOptions(options) : {} - options.passive = getDefaultPassiveOption(options.passive, type) - options.capture = useCapture === undefined ? defaultOptions.capture : useCapture + options = usesListenerOptions ? getWritableOptions(options) : {}; + options.passive = getDefaultPassiveOption(options.passive, type); + options.capture = + useCapture === undefined ? defaultOptions.capture : useCapture; - superMethod.call(this, type, listener, options) - } + superMethod.call(this, type, listener, options); + }; - EventTarget.prototype.addEventListener._original = superMethod -} + EventTarget.prototype.addEventListener._original = superMethod; +}; -const supportsPassive = eventListenerOptionsSupported() +const supportsPassive = eventListenerOptionsSupported(); if (supportsPassive) { - const addEvent = EventTarget.prototype.addEventListener - overwriteAddEvent(addEvent) + const addEvent = EventTarget.prototype.addEventListener; + overwriteAddEvent(addEvent); } diff --git a/core/lib/router-manager.ts b/core/lib/router-manager.ts index 68c4998094..2157f242d9 100644 --- a/core/lib/router-manager.ts +++ b/core/lib/router-manager.ts @@ -1,19 +1,22 @@ -import { Logger } from '@vue-storefront/core/lib/logger' -import { router } from '@vue-storefront/core/app' -import VueRouter, { RouteConfig } from 'vue-router' +import { Logger } from '@vue-storefront/core/lib/logger'; +import { router } from '@vue-storefront/core/app'; +import VueRouter, { RouteConfig } from 'vue-router'; const RouterManager = { _registeredRoutes: new Array(), - addRoutes : function (routes: RouteConfig[], routerInstance: VueRouter = router): void { - this._registeredRoutes.push(...routes) - router.addRoutes(routes) + addRoutes: function( + routes: RouteConfig[], + routerInstance: VueRouter = router + ): void { + this._registeredRoutes.push(...routes); + router.addRoutes(routes); }, - findByName: function (name: string): RouteConfig { - return this._registeredRoutes.find(r => r.name === name) + findByName: function(name: string): RouteConfig { + return this._registeredRoutes.find(r => r.name === name); }, - findByPath: function (fullPath: string): RouteConfig { - return this._registeredRoutes.find(r => r.fullPath === fullPath) - } -} + findByPath: function(fullPath: string): RouteConfig { + return this._registeredRoutes.find(r => r.fullPath === fullPath); + } +}; -export { RouterManager } +export { RouterManager }; diff --git a/core/lib/search.ts b/core/lib/search.ts index e6fc746a07..f1a621d222 100644 --- a/core/lib/search.ts +++ b/core/lib/search.ts @@ -1,19 +1,19 @@ -import Vue from 'vue' +import Vue from 'vue'; -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { sha3_224 } from 'js-sha3' -import rootStore from '@vue-storefront/core/store' -import { getSearchAdapter } from './search/adapter/searchAdapterFactory' -import { SearchRequest } from '@vue-storefront/core/types/search/SearchRequest' -import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse' -import { Logger } from '@vue-storefront/core/lib/logger' +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { sha3_224 } from 'js-sha3'; +import rootStore from '@vue-storefront/core/store'; +import { getSearchAdapter } from './search/adapter/searchAdapterFactory'; +import { SearchRequest } from '@vue-storefront/core/types/search/SearchRequest'; +import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse'; +import { Logger } from '@vue-storefront/core/lib/logger'; // TODO - use one from helpers instead -export function isOnline () : boolean { +export function isOnline(): boolean { if (typeof navigator !== 'undefined') { - return navigator.onLine + return navigator.onLine; } else { - return true // SSR + return true; // SSR } } @@ -25,13 +25,22 @@ export function isOnline () : boolean { * @param {Int} size page size * @return {Promise} */ -export const quickSearchByQuery = async ({ query, start = 0, size = 50, entityType = 'product', sort = '', storeCode = null, excludeFields = null, includeFields = null }): Promise => { - const searchAdapter = await getSearchAdapter() - if (size <= 0) size = 50 - if (start < 0) start = 0 +export const quickSearchByQuery = async ({ + query, + start = 0, + size = 50, + entityType = 'product', + sort = '', + storeCode = null, + excludeFields = null, + includeFields = null +}): Promise => { + const searchAdapter = await getSearchAdapter(); + if (size <= 0) size = 50; + if (start < 0) start = 0; return new Promise((resolve, reject) => { - const storeView = currentStoreView() + const storeView = currentStoreView(); const Request: SearchRequest = { store: storeCode || storeView.storeCode, // TODO: add grouped product and bundled product support type: entityType, @@ -41,77 +50,127 @@ export const quickSearchByQuery = async ({ query, start = 0, size = 50, entityT size: size, from: start, sort: sort - } + }; - if (excludeFields) Request._sourceExclude = excludeFields - if (includeFields) Request._sourceInclude = includeFields + if (excludeFields) Request._sourceExclude = excludeFields; + if (includeFields) Request._sourceInclude = includeFields; - if (rootStore.state.config.usePriceTiers && (entityType === 'product') && rootStore.state.user.groupId) { - Request.groupId = rootStore.state.user.groupId + if ( + rootStore.state.config.usePriceTiers && + entityType === 'product' && + rootStore.state.user.groupId + ) { + Request.groupId = rootStore.state.user.groupId; } - const cache = Vue.prototype.$db.elasticCacheCollection // switch to appcache? - let servedFromCache = false - const cacheKey = sha3_224(JSON.stringify(Request)) - const benchmarkTime = new Date() + const cache = Vue.prototype.$db.elasticCacheCollection; // switch to appcache? + let servedFromCache = false; + const cacheKey = sha3_224(JSON.stringify(Request)); + const benchmarkTime = new Date(); - cache.getItem(cacheKey, (err, res) => { - if (err) console.log(err) - if (res !== null) { - res.cache = true - res.noresults = false - res.offline = !isOnline() // TODO: refactor it to checking ES heartbit - resolve(res) - Logger.debug('Result from cache for ' + cacheKey + ' (' + entityType + '), ms=' + (new Date().getTime() - benchmarkTime.getTime()))() + cache + .getItem(cacheKey, (err, res) => { + if (err) console.log(err); + if (res !== null) { + res.cache = true; + res.noresults = false; + res.offline = !isOnline(); // TODO: refactor it to checking ES heartbit + resolve(res); + Logger.debug( + 'Result from cache for ' + + cacheKey + + ' (' + + entityType + + '), ms=' + + (new Date().getTime() - benchmarkTime.getTime()) + )(); - servedFromCache = true - } - }).catch((err) => { - console.error('Cannot read cache for ' + cacheKey + ', ' + err) - }) + servedFromCache = true; + } + }) + .catch(err => { + console.error('Cannot read cache for ' + cacheKey + ', ' + err); + }); /* use only for cache */ if (Request.groupId) { - delete Request.groupId + delete Request.groupId; } - if (rootStore.state.config.usePriceTiers && rootStore.state.user.groupToken) { - Request.groupToken = rootStore.state.user.groupToken + if ( + rootStore.state.config.usePriceTiers && + rootStore.state.user.groupToken + ) { + Request.groupToken = rootStore.state.user.groupToken; } if (!searchAdapter.entities[Request.type]) { - throw new Error('No entity type registered for ' + Request.type ) + throw new Error('No entity type registered for ' + Request.type); } - searchAdapter.search(Request).then((resp) => { // we're always trying to populate cache - when online - const res = searchAdapter.entities[Request.type].resultPorcessor(resp, start, size) + searchAdapter + .search(Request) + .then(resp => { + // we're always trying to populate cache - when online + const res = searchAdapter.entities[Request.type].resultPorcessor( + resp, + start, + size + ); - if (res) { // otherwise it can be just a offline mode - cache.setItem(cacheKey, res, null, rootStore.state.config.elasticsearch.disableLocalStorageQueriesCache).catch((err) => { console.error('Cannot store cache for ' + cacheKey + ', ' + err) }) - if (!servedFromCache) { // if navigator onLine == false means ES is unreachable and probably this will return false; sometimes returned false faster than indexedDb cache returns result ... - Logger.debug('Result from ES for ' + cacheKey + ' (' + entityType + '), ms=' + (new Date().getTime() - benchmarkTime.getTime()))() - res.cache = false - res.noresults = false - res.offline = false - resolve(res) + if (res) { + // otherwise it can be just a offline mode + cache + .setItem( + cacheKey, + res, + null, + rootStore.state.config.elasticsearch + .disableLocalStorageQueriesCache + ) + .catch(err => { + console.error('Cannot store cache for ' + cacheKey + ', ' + err); + }); + if (!servedFromCache) { + // if navigator onLine == false means ES is unreachable and probably this will return false; sometimes returned false faster than indexedDb cache returns result ... + Logger.debug( + 'Result from ES for ' + + cacheKey + + ' (' + + entityType + + '), ms=' + + (new Date().getTime() - benchmarkTime.getTime()) + )(); + res.cache = false; + res.noresults = false; + res.offline = false; + resolve(res); + } } - } - }).catch(err => { - if (!servedFromCache) { - Logger.debug('No results and offline ' + cacheKey + ' (' + entityType + '), ms=' + (new Date().getTime() - benchmarkTime.getTime()))() - const res = { - items: [], - total: 0, - start: 0, - perPage: 0, - aggregations: {}, - offline: true, - cache: true, - noresults: true + }) + .catch(err => { + if (!servedFromCache) { + Logger.debug( + 'No results and offline ' + + cacheKey + + ' (' + + entityType + + '), ms=' + + (new Date().getTime() - benchmarkTime.getTime()) + )(); + const res = { + items: [], + total: 0, + start: 0, + perPage: 0, + aggregations: {}, + offline: true, + cache: true, + noresults: true + }; + resolve(res); } - resolve(res) - } - reject(err) - }) - }) -} + reject(err); + }); + }); +}; diff --git a/core/lib/search/adapter/api/elasticsearch/boost.js b/core/lib/search/adapter/api/elasticsearch/boost.js index 946a97497f..33c2ca8329 100644 --- a/core/lib/search/adapter/api/elasticsearch/boost.js +++ b/core/lib/search/adapter/api/elasticsearch/boost.js @@ -1,16 +1,18 @@ -import config from 'config' +import config from 'config'; -export default function getBoosts (attribute = '') { - let searchableAttributes = [ - ] +export default function getBoosts(attribute = '') { + let searchableAttributes = []; - if (config.elasticsearch.hasOwnProperty('searchableAttributes') && config.elasticsearch.searchableAttributes[attribute]) { - searchableAttributes = config.elasticsearch.searchableAttributes[attribute] + if ( + config.elasticsearch.hasOwnProperty('searchableAttributes') && + config.elasticsearch.searchableAttributes[attribute] + ) { + searchableAttributes = config.elasticsearch.searchableAttributes[attribute]; } if (searchableAttributes.hasOwnProperty('boost')) { - return searchableAttributes['boost'] + return searchableAttributes['boost']; } - return 1 + return 1; } diff --git a/core/lib/search/adapter/api/elasticsearch/mapping.js b/core/lib/search/adapter/api/elasticsearch/mapping.js index ed833d9c2d..a77ea35399 100644 --- a/core/lib/search/adapter/api/elasticsearch/mapping.js +++ b/core/lib/search/adapter/api/elasticsearch/mapping.js @@ -1,16 +1,18 @@ -import store from '@vue-storefront/core/store' +import store from '@vue-storefront/core/store'; -export default function getMapping (attribute, entityType = 'products') { - let mapping = [ - ] +export default function getMapping(attribute, entityType = 'products') { + let mapping = []; - if (store.state.config.hasOwnProperty(entityType) && store.state.config[entityType].hasOwnProperty('filterFieldMapping')) { - mapping = store.state.config[entityType].filterFieldMapping + if ( + store.state.config.hasOwnProperty(entityType) && + store.state.config[entityType].hasOwnProperty('filterFieldMapping') + ) { + mapping = store.state.config[entityType].filterFieldMapping; } if (mapping.hasOwnProperty(attribute)) { - return mapping[attribute] + return mapping[attribute]; } - return attribute + return attribute; } diff --git a/core/lib/search/adapter/api/elasticsearch/multimatch.js b/core/lib/search/adapter/api/elasticsearch/multimatch.js index 9a5063cf23..f8a4e2bd3a 100644 --- a/core/lib/search/adapter/api/elasticsearch/multimatch.js +++ b/core/lib/search/adapter/api/elasticsearch/multimatch.js @@ -1,31 +1,43 @@ -import config from 'config' +import config from 'config'; -export default function getMultiMatchConfig (queryText) { - return getConfig(queryText) +export default function getMultiMatchConfig(queryText) { + return getConfig(queryText); } -function getConfig (queryText) { - let scoringConfig = config.elasticsearch.hasOwnProperty('searchScoring') ? config.elasticsearch.searchScoring : {} - let minimumShouldMatch = '' +function getConfig(queryText) { + let scoringConfig = config.elasticsearch.hasOwnProperty('searchScoring') + ? config.elasticsearch.searchScoring + : {}; + let minimumShouldMatch = ''; if (config.elasticsearch.queryMethod === 'GET') { // minimum_should_match param must be have a "%" suffix, which is an illegal char while sending over query string - minimumShouldMatch = scoringConfig.hasOwnProperty('minimum_should_match') ? scoringConfig.minimum_should_match + '25' : '75%25' + minimumShouldMatch = scoringConfig.hasOwnProperty('minimum_should_match') + ? scoringConfig.minimum_should_match + '25' + : '75%25'; } else { - minimumShouldMatch = scoringConfig.hasOwnProperty('minimum_should_match') ? scoringConfig.minimum_should_match : '75%' + minimumShouldMatch = scoringConfig.hasOwnProperty('minimum_should_match') + ? scoringConfig.minimum_should_match + : '75%'; } // Create config for multi match query let multiMatchConfig = { - 'query': queryText, - 'operator': scoringConfig.operator ? scoringConfig.operator : 'or', - 'fuzziness': scoringConfig.fuzziness ? scoringConfig.fuzziness : '2', - 'cutoff_frequency': scoringConfig.cutoff_frequency ? scoringConfig.cutoff_frequency : '0.01', - 'max_expansions': scoringConfig.max_expansions ? scoringConfig.max_expansions : '3', - 'prefix_length': scoringConfig.prefix_length ? scoringConfig.prefix_length : '1', - 'minimum_should_match': minimumShouldMatch, - 'tie_breaker': scoringConfig.tie_breaker ? scoringConfig.tie_breaker : '1' - } + query: queryText, + operator: scoringConfig.operator ? scoringConfig.operator : 'or', + fuzziness: scoringConfig.fuzziness ? scoringConfig.fuzziness : '2', + cutoff_frequency: scoringConfig.cutoff_frequency + ? scoringConfig.cutoff_frequency + : '0.01', + max_expansions: scoringConfig.max_expansions + ? scoringConfig.max_expansions + : '3', + prefix_length: scoringConfig.prefix_length + ? scoringConfig.prefix_length + : '1', + minimum_should_match: minimumShouldMatch, + tie_breaker: scoringConfig.tie_breaker ? scoringConfig.tie_breaker : '1' + }; if (scoringConfig.hasOwnProperty('analyzer')) { - multiMatchConfig['analyzer'] = scoringConfig.analyzer + multiMatchConfig['analyzer'] = scoringConfig.analyzer; } - return multiMatchConfig + return multiMatchConfig; } diff --git a/core/lib/search/adapter/api/elasticsearch/score.js b/core/lib/search/adapter/api/elasticsearch/score.js index 28f9575a55..25c9b94beb 100644 --- a/core/lib/search/adapter/api/elasticsearch/score.js +++ b/core/lib/search/adapter/api/elasticsearch/score.js @@ -1,35 +1,38 @@ -import config from 'config' +import config from 'config'; -export default function getFunctionScores () { +export default function getFunctionScores() { if (!config.elasticsearch.hasOwnProperty('searchScoring')) { - return false + return false; } - let filter = [] - let esScoringAttributes = config.elasticsearch.searchScoring.attributes + let filter = []; + let esScoringAttributes = config.elasticsearch.searchScoring.attributes; if (!Object.keys(esScoringAttributes).length) { - return false + return false; } for (const attribute of Object.keys(esScoringAttributes)) { - for (const scoreValue of Object.keys(esScoringAttributes[attribute].scoreValues)) { + for (const scoreValue of Object.keys( + esScoringAttributes[attribute].scoreValues + )) { let data = { - 'filter': { - 'match': { + filter: { + match: { [attribute]: scoreValue } }, - 'weight': esScoringAttributes[attribute].scoreValues[scoreValue].weight - } - filter.push(data) + weight: esScoringAttributes[attribute].scoreValues[scoreValue].weight + }; + filter.push(data); } } if (filter.length) { - return {'functions': filter, - 'score_mode': config.score_mode ? config.score_mode : 'multiply', - 'boost_mode': config.boost_mode ? config.boost_mode : 'multiply', - 'max_boost': config.max_boost ? config.max_boost : 100, - 'min_score': config.function_min_score ? config.function_min_score : 1 - } + return { + functions: filter, + score_mode: config.score_mode ? config.score_mode : 'multiply', + boost_mode: config.boost_mode ? config.boost_mode : 'multiply', + max_boost: config.max_boost ? config.max_boost : 100, + min_score: config.function_min_score ? config.function_min_score : 1 + }; } - return false + return false; } diff --git a/core/lib/search/adapter/api/elasticsearchQuery.js b/core/lib/search/adapter/api/elasticsearchQuery.js index f35c85d10e..fa116d14ac 100644 --- a/core/lib/search/adapter/api/elasticsearchQuery.js +++ b/core/lib/search/adapter/api/elasticsearchQuery.js @@ -1,89 +1,133 @@ -import getFunctionScores from './elasticsearch/score' -import getMultiMatchConfig from './elasticsearch/multimatch' -import getBoosts from './elasticsearch/boost' -import getMapping from './elasticsearch/mapping' -import cloneDeep from 'lodash-es/cloneDeep' -import config from 'config' +import getFunctionScores from './elasticsearch/score'; +import getMultiMatchConfig from './elasticsearch/multimatch'; +import getBoosts from './elasticsearch/boost'; +import getMapping from './elasticsearch/mapping'; +import cloneDeep from 'lodash-es/cloneDeep'; +import config from 'config'; -export async function prepareElasticsearchQueryBody (searchQuery) { - const bodybuilder = await import(/* webpackChunkName: "bodybuilder" */ 'bodybuilder') - const optionsPrfeix = '_options' - const queryText = searchQuery.getSearchText() - const rangeOperators = ['gt', 'lt', 'gte', 'lte', 'moreq', 'from', 'to'] - let query = bodybuilder.default() +export async function prepareElasticsearchQueryBody(searchQuery) { + const bodybuilder = await import( + /* webpackChunkName: "bodybuilder" */ 'bodybuilder' + ); + const optionsPrfeix = '_options'; + const queryText = searchQuery.getSearchText(); + const rangeOperators = ['gt', 'lt', 'gte', 'lte', 'moreq', 'from', 'to']; + let query = bodybuilder.default(); // process applied filters - const appliedFilters = cloneDeep(searchQuery.getAppliedFilters()) // copy as function below modifies the object + const appliedFilters = cloneDeep(searchQuery.getAppliedFilters()); // copy as function below modifies the object if (appliedFilters.length > 0) { - let hasCatalogFilters = false + let hasCatalogFilters = false; // apply default filters appliedFilters.forEach(filter => { if (filter.scope === 'default') { - if (rangeOperators.every(rangeOperator => filter.value.hasOwnProperty(rangeOperator))) { + if ( + rangeOperators.every(rangeOperator => + filter.value.hasOwnProperty(rangeOperator) + ) + ) { // process range filters - query = query.filter('range', filter.attribute, filter.value) + query = query.filter('range', filter.attribute, filter.value); } else { // process terms filters - filter.value = filter.value[Object.keys(filter.value)[0]] + filter.value = filter.value[Object.keys(filter.value)[0]]; if (!Array.isArray(filter.value)) { - filter.value = [filter.value] + filter.value = [filter.value]; } - query = query.filter('terms', getMapping(filter.attribute), filter.value) + query = query.filter( + 'terms', + getMapping(filter.attribute), + filter.value + ); } } else if (filter.scope === 'catalog') { - hasCatalogFilters = true + hasCatalogFilters = true; } - }) + }); // apply catalog scope filters let attrFilterBuilder = (filterQr, attrPostfix = '') => { appliedFilters.forEach(catalogfilter => { - const valueKeys = Object.keys(catalogfilter.value) + const valueKeys = Object.keys(catalogfilter.value); if (catalogfilter.scope === 'catalog' && valueKeys.length) { - const isRange = valueKeys.filter(value => rangeOperators.indexOf(value) !== -1) + const isRange = valueKeys.filter( + value => rangeOperators.indexOf(value) !== -1 + ); if (isRange.length) { - let rangeAttribute = catalogfilter.attribute + let rangeAttribute = catalogfilter.attribute; // filter by product fiunal price if (rangeAttribute === 'price') { - rangeAttribute = 'final_price' + rangeAttribute = 'final_price'; } // process range filters - filterQr = filterQr.andFilter('range', rangeAttribute, catalogfilter.value) + filterQr = filterQr.andFilter( + 'range', + rangeAttribute, + catalogfilter.value + ); } else { // process terms filters - let newValue = catalogfilter.value[Object.keys(catalogfilter.value)[0]] + let newValue = + catalogfilter.value[Object.keys(catalogfilter.value)[0]]; if (!Array.isArray(newValue)) { - newValue = [newValue] + newValue = [newValue]; } if (attrPostfix === '') { - filterQr = filterQr.andFilter('terms', getMapping(catalogfilter.attribute), newValue) + filterQr = filterQr.andFilter( + 'terms', + getMapping(catalogfilter.attribute), + newValue + ); } else { - filterQr = filterQr.andFilter('terms', catalogfilter.attribute + attrPostfix, newValue) + filterQr = filterQr.andFilter( + 'terms', + catalogfilter.attribute + attrPostfix, + newValue + ); } } } - }) - return filterQr - } + }); + return filterQr; + }; if (hasCatalogFilters) { - query = query.orFilter('bool', (b) => attrFilterBuilder(b)) - .orFilter('bool', (b) => attrFilterBuilder(b, optionsPrfeix).filter('match', 'type_id', 'configurable')) // the queries can vary based on the product type + query = query + .orFilter('bool', b => attrFilterBuilder(b)) + .orFilter('bool', b => + attrFilterBuilder(b, optionsPrfeix).filter( + 'match', + 'type_id', + 'configurable' + ) + ); // the queries can vary based on the product type } } // Add aggregations for catalog filters - const allFilters = searchQuery.getAvailableFilters() + const allFilters = searchQuery.getAvailableFilters(); if (allFilters.length > 0) { for (let attrToFilter of allFilters) { if (attrToFilter.scope === 'catalog') { if (attrToFilter.field !== 'price') { - let aggregationSize = { size: config.products.filterAggregationSize[attrToFilter.field] || config.products.filterAggregationSize.default } - query = query.aggregation('terms', getMapping(attrToFilter.field), aggregationSize) - query = query.aggregation('terms', attrToFilter.field + optionsPrfeix, aggregationSize) + let aggregationSize = { + size: + config.products.filterAggregationSize[attrToFilter.field] || + config.products.filterAggregationSize.default + }; + query = query.aggregation( + 'terms', + getMapping(attrToFilter.field), + aggregationSize + ); + query = query.aggregation( + 'terms', + attrToFilter.field + optionsPrfeix, + aggregationSize + ); } else { - query = query.aggregation('terms', attrToFilter.field) + query = query.aggregation('terms', attrToFilter.field); query.aggregation('range', 'price', { ranges: [ { from: 0, to: 50 }, @@ -91,35 +135,49 @@ export async function prepareElasticsearchQueryBody (searchQuery) { { from: 100, to: 150 }, { from: 150 } ] - }) + }); } } } } // Get searchable fields based on user-defined config. - let getQueryBody = function (b) { - let searchableAttributes = config.elasticsearch.hasOwnProperty('searchableAttributes') ? config.elasticsearch.searchableAttributes : {'name': {'boost': 1}} - let searchableFields = [ - ] + let getQueryBody = function(b) { + let searchableAttributes = config.elasticsearch.hasOwnProperty( + 'searchableAttributes' + ) + ? config.elasticsearch.searchableAttributes + : { name: { boost: 1 } }; + let searchableFields = []; for (const attribute of Object.keys(searchableAttributes)) { - searchableFields.push(attribute + '^' + getBoosts(attribute)) + searchableFields.push(attribute + '^' + getBoosts(attribute)); } - return b.orQuery('multi_match', 'fields', searchableFields, getMultiMatchConfig(queryText)) - .orQuery('bool', b => b.orQuery('terms', 'configurable_children.sku', queryText.split('-')) - .orQuery('match_phrase', 'sku', { query: queryText, boost: 1 }) - .orQuery('match_phrase', 'configurable_children.sku', { query: queryText, boost: 1 }) + return b + .orQuery( + 'multi_match', + 'fields', + searchableFields, + getMultiMatchConfig(queryText) ) - } + .orQuery('bool', b => + b + .orQuery('terms', 'configurable_children.sku', queryText.split('-')) + .orQuery('match_phrase', 'sku', { query: queryText, boost: 1 }) + .orQuery('match_phrase', 'configurable_children.sku', { + query: queryText, + boost: 1 + }) + ); + }; if (queryText !== '') { - let functionScore = getFunctionScores() + let functionScore = getFunctionScores(); // Build bool or function_scrre accordingly if (functionScore) { - query = query.query('function_score', functionScore, getQueryBody) + query = query.query('function_score', functionScore, getQueryBody); } else { - query = query.query('bool', getQueryBody) + query = query.query('bool', getQueryBody); } } - const queryBody = query.build() + const queryBody = query.build(); - return queryBody + return queryBody; } diff --git a/core/lib/search/adapter/api/searchAdapter.ts b/core/lib/search/adapter/api/searchAdapter.ts index accc845059..3347a3e41c 100644 --- a/core/lib/search/adapter/api/searchAdapter.ts +++ b/core/lib/search/adapter/api/searchAdapter.ts @@ -1,200 +1,237 @@ -import map from 'lodash-es/map' -import rootStore from '@vue-storefront/core/store' -import { prepareElasticsearchQueryBody } from './elasticsearchQuery' -import fetch from 'isomorphic-fetch' -import { slugify } from '@vue-storefront/core/helpers' -import queryString from 'query-string' -import { currentStoreView, prepareStoreView } from '../../../multistore' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import HttpQuery from '@vue-storefront/core/types/search/HttpQuery' -import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse' +import map from 'lodash-es/map'; +import rootStore from '@vue-storefront/core/store'; +import { prepareElasticsearchQueryBody } from './elasticsearchQuery'; +import fetch from 'isomorphic-fetch'; +import { slugify } from '@vue-storefront/core/helpers'; +import queryString from 'query-string'; +import { currentStoreView, prepareStoreView } from '../../../multistore'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import HttpQuery from '@vue-storefront/core/types/search/HttpQuery'; +import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse'; export class SearchAdapter { - public entities: any + public entities: any; - constructor () { - this.entities = [] - this.initBaseTypes() + constructor() { + this.entities = []; + this.initBaseTypes(); } - async search (Request) { + async search(Request) { if (!this.entities[Request.type]) { - throw new Error('No entity type registered for ' + Request.type ) + throw new Error('No entity type registered for ' + Request.type); } - let ElasticsearchQueryBody = {} + let ElasticsearchQueryBody = {}; if (Request.searchQuery instanceof SearchQuery) { - ElasticsearchQueryBody = await prepareElasticsearchQueryBody(Request.searchQuery) + ElasticsearchQueryBody = await prepareElasticsearchQueryBody( + Request.searchQuery + ); if (Request.searchQuery.getSearchText() !== '') { - ElasticsearchQueryBody['min_score'] = rootStore.state.config.elasticsearch.min_score + ElasticsearchQueryBody['min_score'] = + rootStore.state.config.elasticsearch.min_score; } } else { // backward compatibility for old themes uses bodybuilder - ElasticsearchQueryBody = Request.searchQuery + ElasticsearchQueryBody = Request.searchQuery; } if (Request.hasOwnProperty('groupId') && Request.groupId !== null) { - ElasticsearchQueryBody['groupId'] = Request.groupId + ElasticsearchQueryBody['groupId'] = Request.groupId; } if (Request.hasOwnProperty('groupToken') && Request.groupToken !== null) { - ElasticsearchQueryBody['groupToken'] = Request.groupToken + ElasticsearchQueryBody['groupToken'] = Request.groupToken; } - const storeView = (Request.store === null) ? currentStoreView() : prepareStoreView(Request.store) + const storeView = + Request.store === null + ? currentStoreView() + : prepareStoreView(Request.store); - Request.index = storeView.elasticsearch.index + Request.index = storeView.elasticsearch.index; - let url = storeView.elasticsearch.host + let url = storeView.elasticsearch.host; if (!url.startsWith('http')) { - url = 'http://' + url + url = 'http://' + url; } if (this.entities[Request.type].url) { - url = this.entities[Request.type].url + url = this.entities[Request.type].url; } const httpQuery: HttpQuery = { size: Request.size, from: Request.from, sort: Request.sort - } + }; if (Request._sourceExclude) { - httpQuery._source_exclude = Request._sourceExclude.join(',') + httpQuery._source_exclude = Request._sourceExclude.join(','); } if (Request._sourceInclude) { - httpQuery._source_include = Request._sourceInclude.join(',') + httpQuery._source_include = Request._sourceInclude.join(','); } if (Request.q) { - httpQuery.q = Request.q + httpQuery.q = Request.q; } if (!Request.index || !Request.type) { - throw new Error('Query.index and Query.type are required arguments for executing ElasticSearch query') + throw new Error( + 'Query.index and Query.type are required arguments for executing ElasticSearch query' + ); } if (rootStore.state.config.elasticsearch.queryMethod === 'GET') { - httpQuery.request = JSON.stringify(ElasticsearchQueryBody) - } - url = url + '/' + encodeURIComponent(Request.index) + '/' + encodeURIComponent(Request.type) + '/_search' - url = url + '?' + queryString.stringify(httpQuery) - return fetch(url, { method: rootStore.state.config.elasticsearch.queryMethod, + httpQuery.request = JSON.stringify(ElasticsearchQueryBody); + } + url = + url + + '/' + + encodeURIComponent(Request.index) + + '/' + + encodeURIComponent(Request.type) + + '/_search'; + url = url + '?' + queryString.stringify(httpQuery); + return fetch(url, { + method: rootStore.state.config.elasticsearch.queryMethod, mode: 'cors', headers: { - 'Accept': 'application/json', + Accept: 'application/json', 'Content-Type': 'application/json' }, - body: rootStore.state.config.elasticsearch.queryMethod === 'POST' ? JSON.stringify(ElasticsearchQueryBody) : null - }).then(resp => { return resp.json() }) + body: + rootStore.state.config.elasticsearch.queryMethod === 'POST' + ? JSON.stringify(ElasticsearchQueryBody) + : null + }).then(resp => { + return resp.json(); + }); } - handleResult (resp, type, start = 0, size = 50): SearchResponse { + handleResult(resp, type, start = 0, size = 50): SearchResponse { if (resp === null) { - throw new Error('Invalid ES result - null not exepcted') + throw new Error('Invalid ES result - null not exepcted'); } if (resp.hasOwnProperty('hits')) { return { items: map(resp.hits.hits, hit => { - return Object.assign(hit._source, { _score: hit._score, slug: hit._source.slug ? hit._source.slug : ((hit._source.hasOwnProperty('url_key') && rootStore.state.config.products.useMagentoUrlKeys) ? hit._source.url_key : (hit._source.hasOwnProperty('name') ? slugify(hit._source.name) + '-' + hit._source.id : '')) }) // TODO: assign slugs server side + return Object.assign(hit._source, { + _score: hit._score, + slug: hit._source.slug + ? hit._source.slug + : hit._source.hasOwnProperty('url_key') && + rootStore.state.config.products.useMagentoUrlKeys + ? hit._source.url_key + : hit._source.hasOwnProperty('name') + ? slugify(hit._source.name) + '-' + hit._source.id + : '' + }); // TODO: assign slugs server side }), // TODO: add scoring information total: resp.hits.total, start: start, perPage: size, aggregations: resp.aggregations - } + }; } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with elasticsearch result in resultPorcessor for entity type \''+type+'\'') + throw new Error( + "Unknown error with elasticsearch result in resultPorcessor for entity type '" + + type + + "'" + ); } } } - registerEntityType (entityType, { url = '', queryProcessor, resultPorcessor }) { + registerEntityType( + entityType, + { url = '', queryProcessor, resultPorcessor } + ) { this.entities[entityType] = { queryProcessor: queryProcessor, resultPorcessor: resultPorcessor - } + }; if (url !== '') { - this.entities[entityType]['url'] = url + this.entities[entityType]['url'] = url; } - return this + return this; } initBaseTypes() { this.registerEntityType('product', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'product', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'product', start, size); } - }) + }); this.registerEntityType('attribute', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'attribute', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'attribute', start, size); } - }) + }); this.registerEntityType('category', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'category', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'category', start, size); } - }) + }); this.registerEntityType('taxrule', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'taxrule', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'taxrule', start, size); } - }) + }); this.registerEntityType('review', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'review', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'review', start, size); } - }) + }); this.registerEntityType('cms_page', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'cms_page', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'cms_page', start, size); } - }) + }); this.registerEntityType('cms_block', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'cms_block', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'cms_block', start, size); } - }) + }); this.registerEntityType('cms_hierarchy', { - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { - return this.handleResult(resp, 'cms_hierarchy', start, size) + resultPorcessor: (resp, start, size) => { + return this.handleResult(resp, 'cms_hierarchy', start, size); } - }) + }); } } diff --git a/core/lib/search/adapter/graphql/gqlQuery.js b/core/lib/search/adapter/graphql/gqlQuery.js index a44219fcd9..d79c1bfd20 100644 --- a/core/lib/search/adapter/graphql/gqlQuery.js +++ b/core/lib/search/adapter/graphql/gqlQuery.js @@ -1,96 +1,102 @@ -export function prepareGraphQlBody (Request) { +export function prepareGraphQlBody(Request) { // @TODO Create graphQl query builder uses gqlQuery.body params // below is a simple demo test products search query - let query = `` - let queryVariables = prepareQueryVars(Request) + let query = ``; + let queryVariables = prepareQueryVars(Request); switch (Request.type) { case 'product': - query = require('./queries/products.gql') - break + query = require('./queries/products.gql'); + break; case 'attribute': - query = require('./queries/customAttributeMetadata.gql') - break + query = require('./queries/customAttributeMetadata.gql'); + break; case 'category': - query = require('./queries/categories.gql') - break + query = require('./queries/categories.gql'); + break; case 'taxrule': - query = require('./queries/taxrule.gql') - break + query = require('./queries/taxrule.gql'); + break; case 'cms_page': - query = require('./queries/cmsPage.gql') - break + query = require('./queries/cmsPage.gql'); + break; case 'cms_block': - query = require('./queries/cmsBlock.gql') - break + query = require('./queries/cmsBlock.gql'); + break; case 'cms_hierarhy': - query = require('./queries/cmsHierarchy.gql') - break + query = require('./queries/cmsHierarchy.gql'); + break; } const body = JSON.stringify({ query, variables: queryVariables - }) + }); - return body + return body; } -export function prepareQueryVars (Request) { - let queryVariables = {} - const filters = typeof Request.searchQuery.getAppliedFilters !== 'undefined' ? Request.searchQuery.getAppliedFilters() : {} +export function prepareQueryVars(Request) { + let queryVariables = {}; + const filters = + typeof Request.searchQuery.getAppliedFilters !== 'undefined' + ? Request.searchQuery.getAppliedFilters() + : {}; - queryVariables.search = Request.searchQuery.getSearchText() - queryVariables.sort = {} - queryVariables.filter = {} - queryVariables._sourceInclude = {} - queryVariables._sourceExclude = {} + queryVariables.search = Request.searchQuery.getSearchText(); + queryVariables.sort = {}; + queryVariables.filter = {}; + queryVariables._sourceInclude = {}; + queryVariables._sourceExclude = {}; // Add aggregations for filters - const allFilters = Request.searchQuery.getAvailableFilters() + const allFilters = Request.searchQuery.getAvailableFilters(); if (allFilters.length > 0) { for (let attrToFilter of allFilters) { - queryVariables.filter[attrToFilter.field] = {} + queryVariables.filter[attrToFilter.field] = {}; if (typeof attrToFilter.scope !== 'undefined') { - queryVariables.filter[attrToFilter.field]['scope'] = attrToFilter.scope + queryVariables.filter[attrToFilter.field]['scope'] = attrToFilter.scope; } } } for (let _filter of filters) { if (_filter.scope) { - _filter.value['scope'] = _filter.scope - delete (_filter.scope) + _filter.value['scope'] = _filter.scope; + delete _filter.scope; } - let processedFilter = processNestedFieldFilter(_filter) - queryVariables.filter = Object.assign(queryVariables.filter, processedFilter) + let processedFilter = processNestedFieldFilter(_filter); + queryVariables.filter = Object.assign( + queryVariables.filter, + processedFilter + ); } if (Request.sort !== '') { - const sortParse = Request.sort.split(':') - queryVariables.sort[sortParse[0]] = sortParse[1].toUpperCase() + const sortParse = Request.sort.split(':'); + queryVariables.sort[sortParse[0]] = sortParse[1].toUpperCase(); } - queryVariables.pageSize = Request.size - queryVariables.currentPage = Request.from / Request.size + 1 - queryVariables.attributes = queryVariables.filter - queryVariables._sourceInclude = Request._sourceInclude - queryVariables._sourceExclude = Request._sourceExclude + queryVariables.pageSize = Request.size; + queryVariables.currentPage = Request.from / Request.size + 1; + queryVariables.attributes = queryVariables.filter; + queryVariables._sourceInclude = Request._sourceInclude; + queryVariables._sourceExclude = Request._sourceExclude; - return queryVariables + return queryVariables; } -function processNestedFieldFilter (filter) { - let processedFilter = {} - let filterAttributes = filter.attribute.split('.') +function processNestedFieldFilter(filter) { + let processedFilter = {}; + let filterAttributes = filter.attribute.split('.'); if (filterAttributes.length > 1) { - let nestedFilter = filter.value + let nestedFilter = filter.value; for (let i = filterAttributes.length - 1; i >= 0; i--) { - nestedFilter = { [filterAttributes[i]]: nestedFilter } + nestedFilter = { [filterAttributes[i]]: nestedFilter }; } - processedFilter = nestedFilter + processedFilter = nestedFilter; } else { - processedFilter[filter.attribute] = filter.value + processedFilter[filter.attribute] = filter.value; } - return processedFilter + return processedFilter; } diff --git a/core/lib/search/adapter/graphql/processor/processType.ts b/core/lib/search/adapter/graphql/processor/processType.ts index ee3680b39e..64aae6ea4a 100644 --- a/core/lib/search/adapter/graphql/processor/processType.ts +++ b/core/lib/search/adapter/graphql/processor/processType.ts @@ -1,59 +1,67 @@ -import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse' -import map from 'lodash-es/map' -import { slugify } from '@vue-storefront/core/helpers' -import rootStore from '@vue-storefront/core/store' +import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse'; +import map from 'lodash-es/map'; +import { slugify } from '@vue-storefront/core/helpers'; +import rootStore from '@vue-storefront/core/store'; -export function processESResponseType (resp, start, size): SearchResponse { +export function processESResponseType(resp, start, size): SearchResponse { const response = { items: map(resp.hits.hits, hit => { return Object.assign(hit._source, { _score: hit._score, - slug: hit._source.slug ? hit._source.slug : ((hit._source.hasOwnProperty('url_key') && rootStore.state.config.products.useMagentoUrlKeys) + slug: hit._source.slug + ? hit._source.slug + : hit._source.hasOwnProperty('url_key') && + rootStore.state.config.products.useMagentoUrlKeys ? hit._source.url_key - : (hit._source.hasOwnProperty('name') ? slugify(hit._source.name) + '-' + hit._source.id : '')) - }) // TODO: assign slugs server side + : hit._source.hasOwnProperty('name') + ? slugify(hit._source.name) + '-' + hit._source.id + : '' + }); // TODO: assign slugs server side }), // TODO: add scoring information total: resp.hits.total, start: start, perPage: size, aggregations: resp.aggregations - } + }; - return response + return response; } -export function processProductsType (resp, start, size): SearchResponse { +export function processProductsType(resp, start, size): SearchResponse { const response = { items: map(resp.items, item => { - let options = {} + let options = {}; if (item._score) { - options['_score'] = item._score - delete item._score + options['_score'] = item._score; + delete item._score; } - options['slug'] = item.slug ? item.slug : ((item.url_key && - rootStore.state.config.products.useMagentoUrlKeys) - ? item.url_key : (item.name - ? slugify(item.name) + '-' + item.id : '')) + options['slug'] = item.slug + ? item.slug + : item.url_key && rootStore.state.config.products.useMagentoUrlKeys + ? item.url_key + : item.name + ? slugify(item.name) + '-' + item.id + : ''; - return Object.assign(item, options) // TODO: assign slugs server side + return Object.assign(item, options); // TODO: assign slugs server side }), // TODO: add scoring information total: resp.total_count, start: start, perPage: size, aggregations: resp.aggregations - } + }; - return response + return response; } -export function processCmsType (resp, start, size): SearchResponse { +export function processCmsType(resp, start, size): SearchResponse { const response = { items: resp.items, total: resp.total_count, start: start, perPage: size, aggregations: resp.aggregations - } + }; - return response -} \ No newline at end of file + return response; +} diff --git a/core/lib/search/adapter/graphql/searchAdapter.ts b/core/lib/search/adapter/graphql/searchAdapter.ts index cf8ccf1b09..a3d02ff8ac 100644 --- a/core/lib/search/adapter/graphql/searchAdapter.ts +++ b/core/lib/search/adapter/graphql/searchAdapter.ts @@ -1,66 +1,88 @@ -import rootStore from '@vue-storefront/core/store' -import { prepareQueryVars } from './gqlQuery' -import { currentStoreView, prepareStoreView } from '../../../multistore' -import fetch from 'isomorphic-fetch' -import {processESResponseType, processProductsType, processCmsType} from './processor/processType' -import SearchQuery from '../../searchQuery' +import rootStore from '@vue-storefront/core/store'; +import { prepareQueryVars } from './gqlQuery'; +import { currentStoreView, prepareStoreView } from '../../../multistore'; +import fetch from 'isomorphic-fetch'; +import { + processESResponseType, + processProductsType, + processCmsType +} from './processor/processType'; +import SearchQuery from '../../searchQuery'; export class SearchAdapter { + public entities: any; - public entities: any - - constructor () { - this.entities = [] - this.initBaseTypes() + constructor() { + this.entities = []; + this.initBaseTypes(); } /** * register entit type using registerEntityTypeByQuery * @param {Request} Request request object * @return {Promise} - */ - search (Request) { + */ + search(Request) { if (!(Request.searchQuery instanceof SearchQuery)) { - throw new Error('SearchQuery instance has wrong class required to process with graphQl request.') + throw new Error( + 'SearchQuery instance has wrong class required to process with graphQl request.' + ); } if (!this.entities[Request.type]) { - throw new Error('No entity type registered for ' + Request.type ) + throw new Error('No entity type registered for ' + Request.type); } - const storeView = (Request.store === null) ? currentStoreView() : prepareStoreView(Request.store) - if (storeView.storeCode === undefined || storeView.storeCode == null || !Request.type) { - throw new Error('Store and SearchRequest.type are required arguments for executing Graphql query') + const storeView = + Request.store === null + ? currentStoreView() + : prepareStoreView(Request.store); + if ( + storeView.storeCode === undefined || + storeView.storeCode == null || + !Request.type + ) { + throw new Error( + 'Store and SearchRequest.type are required arguments for executing Graphql query' + ); } - const gqlQueryVars = prepareQueryVars(Request) - const query = this.entities[Request.type].query + const gqlQueryVars = prepareQueryVars(Request); + const query = this.entities[Request.type].query; const gqlQueryBody = JSON.stringify({ query, variables: gqlQueryVars - }) + }); // define GraphQL url from searchAdapter entity or use default graphQl host with storeCode param - let urlGql = '' + let urlGql = ''; if (this.entities[Request.type].url) { - urlGql = this.entities[Request.type].url + urlGql = this.entities[Request.type].url; } else { - urlGql = rootStore.state.config.server.protocol + '://' + rootStore.state.config.graphql.host + ':' + rootStore.state.config.graphql.port + '/graphql' - const urlStoreCode = (storeView.storeCode !== '') ? encodeURIComponent(storeView.storeCode) + '/' : '' - urlGql = urlGql + '/' + urlStoreCode + urlGql = + rootStore.state.config.server.protocol + + '://' + + rootStore.state.config.graphql.host + + ':' + + rootStore.state.config.graphql.port + + '/graphql'; + const urlStoreCode = + storeView.storeCode !== '' + ? encodeURIComponent(storeView.storeCode) + '/' + : ''; + urlGql = urlGql + '/' + urlStoreCode; } return fetch(urlGql, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, - body: gqlQueryBody - }) - .then(resp => { - return resp.json() - }) + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json' + }, + body: gqlQueryBody + }).then(resp => { + return resp.json(); + }); } /** @@ -70,17 +92,20 @@ export class SearchAdapter { * @param {function} queryProcessor some function which can update query if needed * @param {function} resultPorcessor process results of response * @return {Object} - */ - registerEntityType (entityType, { url = '', gql, queryProcessor, resultPorcessor }) { + */ + registerEntityType( + entityType, + { url = '', gql, queryProcessor, resultPorcessor } + ) { this.entities[entityType] = { query: require(`${gql}`), queryProcessor: queryProcessor, resultPorcessor: resultPorcessor - } + }; if (url !== '') { - this.entities[entityType]['url'] = url + this.entities[entityType]['url'] = url; } - return this + return this; } /** @@ -90,193 +115,216 @@ export class SearchAdapter { * @param {function} queryProcessor some function which can update query if needed * @param {function} resultPorcessor process results of response * @return {Object} - */ - registerEntityTypeByQuery (entityType, { url = '', query, queryProcessor, resultPorcessor }) { + */ + registerEntityTypeByQuery( + entityType, + { url = '', query, queryProcessor, resultPorcessor } + ) { this.entities[entityType] = { query: query, queryProcessor: queryProcessor, resultPorcessor: resultPorcessor - } + }; if (url !== '') { - this.entities[entityType]['url'] = url + this.entities[entityType]['url'] = url; } - return this + return this; } // initialise default entitypes initBaseTypes() { this.registerEntityType('product', { gql: './queries/products.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processProductsType(resp.data.products, start, size) + return processProductsType(resp.data.products, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'product\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'product'" + ); } } } - }) + }); this.registerEntityType('attribute', { gql: './queries/customAttributeMetadata.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.customAttributeMetadata, start, size) + return processESResponseType( + resp.data.customAttributeMetadata, + start, + size + ); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'attribute\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'attribute'" + ); } } } - }) + }); this.registerEntityType('review', { gql: './queries/reviews.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.reviews, start, size) + return processESResponseType(resp.data.reviews, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'review\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'review'" + ); } } } - }) + }); this.registerEntityType('category', { gql: './queries/categories.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.categories, start, size) + return processESResponseType(resp.data.categories, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'category\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'category'" + ); } } } - }) + }); this.registerEntityType('taxrule', { gql: './queries/taxrule.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.taxrule, start, size) + return processESResponseType(resp.data.taxrule, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'taxrule\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'taxrule'" + ); } } } - }) + }); this.registerEntityType('cms_page', { gql: './queries/cmsPage.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processCmsType(resp.data.cmsPages, start, size) + return processCmsType(resp.data.cmsPages, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'cmsPage\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'cmsPage'" + ); } } } - }) + }); this.registerEntityType('cms_block', { gql: './queries/cmsBlock.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processCmsType(resp.data.cmsBlocks, start, size) + return processCmsType(resp.data.cmsBlocks, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'cmsBlock\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'cmsBlock'" + ); } } } - }) + }); this.registerEntityType('cms_hierarchy', { gql: './queries/cmsHierarchy.gql', - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, - resultPorcessor: (resp, start, size) => { + resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid graphQl result - null not exepcted') + throw new Error('Invalid graphQl result - null not exepcted'); } if (resp.hasOwnProperty('data')) { - return processCmsType(resp.data.cmsHierarchies, start, size) + return processCmsType(resp.data.cmsHierarchies, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with graphQl result in resultPorcessor for entity type \'cmsHierarchy\'') + throw new Error( + "Unknown error with graphQl result in resultPorcessor for entity type 'cmsHierarchy'" + ); } } } - }) + }); } } diff --git a/core/lib/search/adapter/searchAdapterFactory.js b/core/lib/search/adapter/searchAdapterFactory.js index a85636d741..9204ff6175 100644 --- a/core/lib/search/adapter/searchAdapterFactory.js +++ b/core/lib/search/adapter/searchAdapterFactory.js @@ -1,22 +1,30 @@ -import { server } from 'config' +import { server } from 'config'; export const getSearchAdapter = async (adapterName = server.api) => { - const SearchAdapterModule = await import(/* webpackChunkName: "vsf-search-adapter-" */ `./${adapterName}/searchAdapter`) - const SearchAdapter = SearchAdapterModule.SearchAdapter + const SearchAdapterModule = await import( + /* webpackChunkName: "vsf-search-adapter-" */ `./${adapterName}/searchAdapter` + ); + const SearchAdapter = SearchAdapterModule.SearchAdapter; if (!SearchAdapter) { - throw new Error('Search adapter class is not provided') + throw new Error('Search adapter class is not provided'); } else { - let adapterInstance = new SearchAdapter() + let adapterInstance = new SearchAdapter(); - if (typeof adapterInstance.isValidFor === 'function' && typeof adapterInstance.search === 'function' && typeof adapterInstance.handleResult === 'function') { - throw new Error('Not valid search adapter class provided. Search Adapter must have search() and handleResult() methods') + if ( + typeof adapterInstance.isValidFor === 'function' && + typeof adapterInstance.search === 'function' && + typeof adapterInstance.handleResult === 'function' + ) { + throw new Error( + 'Not valid search adapter class provided. Search Adapter must have search() and handleResult() methods' + ); } - return adapterInstance + return adapterInstance; } -} +}; export default { getSearchAdapter -} +}; diff --git a/core/lib/search/searchQuery.js b/core/lib/search/searchQuery.js index 27ea8dfd5c..348c3909ea 100644 --- a/core/lib/search/searchQuery.js +++ b/core/lib/search/searchQuery.js @@ -1,80 +1,80 @@ class SearchQuery { /** - */ - constructor () { - this._availableFilters = [] - this._appliedFilters = [] - this._searchText = '' + */ + constructor() { + this._availableFilters = []; + this._appliedFilters = []; + this._searchText = ''; } /** - * @return {Array} array of all available filters objects - */ - getAvailableFilters () { - return this._availableFilters + * @return {Array} array of all available filters objects + */ + getAvailableFilters() { + return this._availableFilters; } /** - * @return {Array} array of applied filters objects - */ - getAppliedFilters () { - return this._appliedFilters + * @return {Array} array of applied filters objects + */ + getAppliedFilters() { + return this._appliedFilters; } /** - * @return {String} - */ - getSearchText () { - return this._searchText + * @return {String} + */ + getSearchText() { + return this._searchText; } /** - * @param {Object} - * @return {Object} - */ - applyFilter ({key, value, scope = 'default', options = Object}) { + * @param {Object} + * @return {Object} + */ + applyFilter({ key, value, scope = 'default', options = Object }) { this._appliedFilters.push({ attribute: key, value: value, scope: scope, options: options - }) + }); - return this + return this; } /** - * @param {Object} - * @return {Object} - */ - addAvailableFilter ({field, scope = 'default', options = {}}) { + * @param {Object} + * @return {Object} + */ + addAvailableFilter({ field, scope = 'default', options = {} }) { // value can has only String, Array or numeric type this._availableFilters.push({ field: field, scope: scope, options: options - }) + }); - return this + return this; } /** - * @param {Array} filters - * @return {Object} - */ - setAvailableFilters (filters) { - this._availableFilters = filters - return this + * @param {Array} filters + * @return {Object} + */ + setAvailableFilters(filters) { + this._availableFilters = filters; + return this; } /** - * @param {String} searchText - * @return {Object} - */ - setSearchText (searchText) { - this._searchText = searchText - return this + * @param {String} searchText + * @return {Object} + */ + setSearchText(searchText) { + this._searchText = searchText; + return this; } } -export default SearchQuery +export default SearchQuery; diff --git a/core/lib/sync/index.ts b/core/lib/sync/index.ts index cfa5c40a1a..6142c4c2fd 100644 --- a/core/lib/sync/index.ts +++ b/core/lib/sync/index.ts @@ -1,91 +1,113 @@ - -import Vue from 'vue' -import rootStore from '@vue-storefront/core/store' -import { Logger } from '@vue-storefront/core/lib/logger' -import { execute as taskExecute, _prepareTask } from './task' -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '../multistore' -import { isServer } from '@vue-storefront/core/helpers' +import Vue from 'vue'; +import rootStore from '@vue-storefront/core/store'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { execute as taskExecute, _prepareTask } from './task'; +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '../multistore'; +import { isServer } from '@vue-storefront/core/helpers'; /** Syncs given task. If user is offline requiest will be sent to the server after restored connection */ -function queue (task) { - const tasksCollection = Vue.prototype.$db.syncTaskCollection - task = _prepareTask(task) - Logger.info('Sync task queued ' + task.url, 'sync', { task })() +function queue(task) { + const tasksCollection = Vue.prototype.$db.syncTaskCollection; + task = _prepareTask(task); + Logger.info('Sync task queued ' + task.url, 'sync', { task })(); return new Promise((resolve, reject) => { - tasksCollection.setItem(task.task_id.toString(), task, (err, resp) => { - if (err) Logger.error(err, 'sync')() - Vue.prototype.$bus.$emit('sync/PROCESS_QUEUE', { config: rootStore.state.config }) // process checkout queue - resolve(task) - }).catch((reason) => { - Logger.error(reason, 'sync')() // it doesn't work on SSR - reject(reason) - }) - }) + tasksCollection + .setItem(task.task_id.toString(), task, (err, resp) => { + if (err) Logger.error(err, 'sync')(); + Vue.prototype.$bus.$emit('sync/PROCESS_QUEUE', { + config: rootStore.state.config + }); // process checkout queue + resolve(task); + }) + .catch(reason => { + Logger.error(reason, 'sync')(); // it doesn't work on SSR + reject(reason); + }); + }); } /** Runs given task. If user is offline request will fail */ -function execute (task) { // not offline task - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - task = _prepareTask(task) +function execute(task) { + // not offline task + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; + task = _prepareTask(task); // Logger.info('New sync task [execute] ' + task.url, 'sync', task)() - const usersCollection = new UniversalStorage(localForage.createInstance({ - name: (rootStore.state.config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'user', - driver: localForage[rootStore.state.config.localForage.defaultDrivers['user']] - })) - const cartsCollection = new UniversalStorage(localForage.createInstance({ - name: (rootStore.state.config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'carts', - driver: localForage[rootStore.state.config.localForage.defaultDrivers['carts']] - })) + const usersCollection = new UniversalStorage( + localForage.createInstance({ + name: + (rootStore.state.config.storeViews.commonCache ? '' : dbNamePrefix) + + 'shop', + storeName: 'user', + driver: + localForage[rootStore.state.config.localForage.defaultDrivers['user']] + }) + ); + const cartsCollection = new UniversalStorage( + localForage.createInstance({ + name: + (rootStore.state.config.storeViews.commonCache ? '' : dbNamePrefix) + + 'shop', + storeName: 'carts', + driver: + localForage[rootStore.state.config.localForage.defaultDrivers['carts']] + }) + ); return new Promise((resolve, reject) => { if (isServer) { - taskExecute(task, null, null).then((result) => { - resolve(result) - }).catch(err => { - reject(err) - }) + taskExecute(task, null, null) + .then(result => { + resolve(result); + }) + .catch(err => { + reject(err); + }); } else { - usersCollection.getItem('current-token', (err, currentToken) => { // TODO: if current token is null we should postpone the queue and force re-login - only if the task requires LOGIN! + usersCollection.getItem('current-token', (err, currentToken) => { + // TODO: if current token is null we should postpone the queue and force re-login - only if the task requires LOGIN! if (err) { - Logger.error(err, 'sync')() + Logger.error(err, 'sync')(); } cartsCollection.getItem('current-cart-token', (err, currentCartId) => { if (err) { - Logger.error(err, 'sync')() + Logger.error(err, 'sync')(); } - if (!currentCartId && rootStore.state.cart.cartServerToken) { // this is workaround; sometimes after page is loaded indexedb returns null despite the cart token is properly set - currentCartId = rootStore.state.cart.cartServerToken + if (!currentCartId && rootStore.state.cart.cartServerToken) { + // this is workaround; sometimes after page is loaded indexedb returns null despite the cart token is properly set + currentCartId = rootStore.state.cart.cartServerToken; } - const token = currentToken ? currentToken : rootStore.getters['user/getUserToken'] + const token = currentToken + ? currentToken + : rootStore.getters['user/getUserToken']; - taskExecute(task, token, currentCartId).then((result) => { - resolve(result) - }).catch(err => { - reject(err) - }) - }) - }) + taskExecute(task, token, currentCartId) + .then(result => { + resolve(result); + }) + .catch(err => { + reject(err); + }); + }); + }); } - }) + }); } /** Clear sync tasks that were not transmitted yet */ -function clearNotTransmited () { - const storeView = currentStoreView() - const syncTaskCollection = Vue.prototype.$db.syncTaskCollection +function clearNotTransmited() { + const storeView = currentStoreView(); + const syncTaskCollection = Vue.prototype.$db.syncTaskCollection; syncTaskCollection.iterate((task, id, iterationNumber) => { if (!task.transmited) { - syncTaskCollection.removeItem(id) + syncTaskCollection.removeItem(id); } - }) + }); } export const TaskQueue = { queue, execute, clearNotTransmited -} +}; diff --git a/core/lib/sync/task.ts b/core/lib/sync/task.ts index 630fab8c8a..dec94f9eeb 100644 --- a/core/lib/sync/task.ts +++ b/core/lib/sync/task.ts @@ -1,175 +1,291 @@ -import Vue from 'vue' -import i18n from '@vue-storefront/i18n' -import isNaN from 'lodash-es/isNaN' -import isUndefined from 'lodash-es/isUndefined' -import toString from 'lodash-es/toString' -import fetch from 'isomorphic-fetch' -import * as localForage from 'localforage' -import rootStore from '@vue-storefront/core/store' -import { adjustMultistoreApiUrl, currentStoreView } from '@vue-storefront/core/lib/multistore' -import Task from '@vue-storefront/core/lib/sync/types/Task' -import { Logger } from '@vue-storefront/core/lib/logger' -import { TaskQueue } from '@vue-storefront/core/lib/sync' -import * as entities from '@vue-storefront/core/store/lib/entities' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' +import Vue from 'vue'; +import i18n from '@vue-storefront/i18n'; +import isNaN from 'lodash-es/isNaN'; +import isUndefined from 'lodash-es/isUndefined'; +import toString from 'lodash-es/toString'; +import fetch from 'isomorphic-fetch'; +import * as localForage from 'localforage'; +import rootStore from '@vue-storefront/core/store'; +import { + adjustMultistoreApiUrl, + currentStoreView +} from '@vue-storefront/core/lib/multistore'; +import Task from '@vue-storefront/core/lib/sync/types/Task'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { TaskQueue } from '@vue-storefront/core/lib/sync'; +import * as entities from '@vue-storefront/core/store/lib/entities'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; -const AUTO_REFRESH_MAX_ATTEMPTS = 20 +const AUTO_REFRESH_MAX_ATTEMPTS = 20; -export function _prepareTask (task) { - const taskId = entities.uniqueEntityId(task) // timestamp as a order id is not the best we can do but it's enough - task.task_id = taskId.toString() - task.transmited = false - task.created_at = new Date() - task.updated_at = new Date() - return task +export function _prepareTask(task) { + const taskId = entities.uniqueEntityId(task); // timestamp as a order id is not the best we can do but it's enough + task.task_id = taskId.toString(); + task.transmited = false; + task.created_at = new Date(); + task.updated_at = new Date(); + return task; } -function _sleep (time) { - return new Promise((resolve) => setTimeout(resolve, time)) +function _sleep(time) { + return new Promise(resolve => setTimeout(resolve, time)); } -function _internalExecute (resolve, reject, task: Task, currentToken, currentCartId) { - - if (currentToken !== null && rootStore.state.userTokenInvalidateLock > 0) { // invalidate lock set - Logger.log('Waiting for rootStore.state.userTokenInvalidateLock to release for '+ task.url, 'sync')() +function _internalExecute( + resolve, + reject, + task: Task, + currentToken, + currentCartId +) { + if (currentToken !== null && rootStore.state.userTokenInvalidateLock > 0) { + // invalidate lock set + Logger.log( + 'Waiting for rootStore.state.userTokenInvalidateLock to release for ' + + task.url, + 'sync' + )(); _sleep(1000).then(() => { - Logger.log('Another try for rootStore.state.userTokenInvalidateLock for ' + task.url, 'sync')() - _internalExecute(resolve, reject, task, currentToken, currentCartId) - }) - return // return but not resolve + Logger.log( + 'Another try for rootStore.state.userTokenInvalidateLock for ' + + task.url, + 'sync' + )(); + _internalExecute(resolve, reject, task, currentToken, currentCartId); + }); + return; // return but not resolve } else if (rootStore.state.userTokenInvalidateLock < 0) { - Logger.error('Aborting the network task' + task.url + rootStore.state.userTokenInvalidateLock, 'sync')() - resolve({ code: 401, message: i18n.t('Error refreshing user token. User is not authorized to access the resource') })() - return + Logger.error( + 'Aborting the network task' + + task.url + + rootStore.state.userTokenInvalidateLock, + 'sync' + )(); + resolve({ + code: 401, + message: i18n.t( + 'Error refreshing user token. User is not authorized to access the resource' + ) + })(); + return; } else { if (rootStore.state.userTokenInvalidated) { - Logger.log('Using new user token' + rootStore.state.userTokenInvalidated, 'sync')() - currentToken = rootStore.state.userTokenInvalidated + Logger.log( + 'Using new user token' + rootStore.state.userTokenInvalidated, + 'sync' + )(); + currentToken = rootStore.state.userTokenInvalidated; } } - let url = task.url.replace('{{token}}', (currentToken == null) ? '' : currentToken).replace('{{cartId}}', (currentCartId == null) ? '' : currentCartId) + let url = task.url + .replace('{{token}}', currentToken == null ? '' : currentToken) + .replace('{{cartId}}', currentCartId == null ? '' : currentCartId); if (rootStore.state.config.storeViews.multistore) { - url = adjustMultistoreApiUrl(url) + url = adjustMultistoreApiUrl(url); } - let silentMode = false - Logger.info('Executing sync task ' + url, 'sync', task)() - return fetch(url, task.payload).then((response) => { - const contentType = response.headers.get('content-type') - if (contentType && contentType.includes('application/json')) { - return response.json() - } else { - const msg = i18n.t('Error with response - bad content-type!') - Logger.error(msg.toString(), 'sync')() - reject(msg) - } - }).then((jsonResponse) => { - if (jsonResponse) { - if (parseInt(jsonResponse.code) !== 200) { - let resultString = jsonResponse.result ? toString(jsonResponse.result) : null - if (resultString && (resultString.indexOf(i18n.t('not authorized')) >= 0 || resultString.indexOf('not authorized')) >= 0 && currentToken !== null) { // the token is no longer valid, try to invalidate it - Logger.error('Invalid token - need to be revalidated' + currentToken + task.url + rootStore.state.userTokenInvalidateLock, 'sync')() - if (isNaN(rootStore.state.userTokenInvalidateAttemptsCount) || isUndefined(rootStore.state.userTokenInvalidateAttemptsCount)) rootStore.state.userTokenInvalidateAttemptsCount = 0 - if (isNaN(rootStore.state.userTokenInvalidateLock) || isUndefined(rootStore.state.userTokenInvalidateLock)) rootStore.state.userTokenInvalidateLock = 0 + let silentMode = false; + Logger.info('Executing sync task ' + url, 'sync', task)(); + return fetch(url, task.payload) + .then(response => { + const contentType = response.headers.get('content-type'); + if (contentType && contentType.includes('application/json')) { + return response.json(); + } else { + const msg = i18n.t('Error with response - bad content-type!'); + Logger.error(msg.toString(), 'sync')(); + reject(msg); + } + }) + .then(jsonResponse => { + if (jsonResponse) { + if (parseInt(jsonResponse.code) !== 200) { + let resultString = jsonResponse.result + ? toString(jsonResponse.result) + : null; + if ( + resultString && + (resultString.indexOf(i18n.t('not authorized')) >= 0 || + resultString.indexOf('not authorized')) >= 0 && + currentToken !== null + ) { + // the token is no longer valid, try to invalidate it + Logger.error( + 'Invalid token - need to be revalidated' + + currentToken + + task.url + + rootStore.state.userTokenInvalidateLock, + 'sync' + )(); + if ( + isNaN(rootStore.state.userTokenInvalidateAttemptsCount) || + isUndefined(rootStore.state.userTokenInvalidateAttemptsCount) + ) + rootStore.state.userTokenInvalidateAttemptsCount = 0; + if ( + isNaN(rootStore.state.userTokenInvalidateLock) || + isUndefined(rootStore.state.userTokenInvalidateLock) + ) + rootStore.state.userTokenInvalidateLock = 0; - silentMode = true - if (rootStore.state.config.users.autoRefreshTokens) { - if (!rootStore.state.userTokenInvalidateLock) { - rootStore.state.userTokenInvalidateLock++ - if (rootStore.state.userTokenInvalidateAttemptsCount >= AUTO_REFRESH_MAX_ATTEMPTS) { - Logger.error('Internal Application error while refreshing the tokens. Please clear the storage and refresh page.', 'sync')() - rootStore.state.userTokenInvalidateLock = -1 - rootStore.dispatch('user/logout', { silent: true }) - TaskQueue.clearNotTransmited() - Vue.prototype.$bus.$emit('modal-show', 'modal-signup') - rootStore.dispatch('notification/spawnNotification', { - type: 'error', - message: i18n.t('Internal Application error while refreshing the tokens. Please clear the storage and refresh page.'), - action1: { label: i18n.t('OK') } - }) - rootStore.state.userTokenInvalidateAttemptsCount = 0 - } else { - Logger.info('Invalidation process in progress (autoRefreshTokens is set to true)' + rootStore.state.userTokenInvalidateAttemptsCount + rootStore.state.userTokenInvalidateLock, 'sync')() - rootStore.state.userTokenInvalidateAttemptsCount++ - rootStore.dispatch('user/refresh').then((resp) => { - if (resp.code === 200) { - rootStore.state.userTokenInvalidateLock = 0 - rootStore.state.userTokenInvalidated = resp.result - Logger.info('User token refreshed successfully' + resp.result, 'sync')() - } else { - rootStore.state.userTokenInvalidateLock = -1 - rootStore.dispatch('user/logout', { silent: true }) - Vue.prototype.$bus.$emit('modal-show', 'modal-signup') - TaskQueue.clearNotTransmited() - Logger.error('Error refreshing user token' + resp.result, 'sync')() - } - }).catch((excp) => { - rootStore.state.userTokenInvalidateLock = -1 - rootStore.dispatch('user/logout', { silent: true }) - Vue.prototype.$bus.$emit('modal-show', 'modal-signup') - TaskQueue.clearNotTransmited() - Logger.error('Error refreshing user token' + excp, 'sync')() - }) + silentMode = true; + if (rootStore.state.config.users.autoRefreshTokens) { + if (!rootStore.state.userTokenInvalidateLock) { + rootStore.state.userTokenInvalidateLock++; + if ( + rootStore.state.userTokenInvalidateAttemptsCount >= + AUTO_REFRESH_MAX_ATTEMPTS + ) { + Logger.error( + 'Internal Application error while refreshing the tokens. Please clear the storage and refresh page.', + 'sync' + )(); + rootStore.state.userTokenInvalidateLock = -1; + rootStore.dispatch('user/logout', { silent: true }); + TaskQueue.clearNotTransmited(); + Vue.prototype.$bus.$emit('modal-show', 'modal-signup'); + rootStore.dispatch('notification/spawnNotification', { + type: 'error', + message: i18n.t( + 'Internal Application error while refreshing the tokens. Please clear the storage and refresh page.' + ), + action1: { label: i18n.t('OK') } + }); + rootStore.state.userTokenInvalidateAttemptsCount = 0; + } else { + Logger.info( + 'Invalidation process in progress (autoRefreshTokens is set to true)' + + rootStore.state.userTokenInvalidateAttemptsCount + + rootStore.state.userTokenInvalidateLock, + 'sync' + )(); + rootStore.state.userTokenInvalidateAttemptsCount++; + rootStore + .dispatch('user/refresh') + .then(resp => { + if (resp.code === 200) { + rootStore.state.userTokenInvalidateLock = 0; + rootStore.state.userTokenInvalidated = resp.result; + Logger.info( + 'User token refreshed successfully' + resp.result, + 'sync' + )(); + } else { + rootStore.state.userTokenInvalidateLock = -1; + rootStore.dispatch('user/logout', { silent: true }); + Vue.prototype.$bus.$emit('modal-show', 'modal-signup'); + TaskQueue.clearNotTransmited(); + Logger.error( + 'Error refreshing user token' + resp.result, + 'sync' + )(); + } + }) + .catch(excp => { + rootStore.state.userTokenInvalidateLock = -1; + rootStore.dispatch('user/logout', { silent: true }); + Vue.prototype.$bus.$emit('modal-show', 'modal-signup'); + TaskQueue.clearNotTransmited(); + Logger.error( + 'Error refreshing user token' + excp, + 'sync' + )(); + }); + } } + if ( + rootStore.state.userTokenInvalidateAttemptsCount <= + AUTO_REFRESH_MAX_ATTEMPTS + ) + _internalExecute( + resolve, + reject, + task, + currentToken, + currentCartId + ); // retry + } else { + Logger.info( + 'Invalidation process is disabled (autoRefreshTokens is set to false)', + 'sync' + )(); + rootStore.dispatch('user/logout', { silent: true }); + Vue.prototype.$bus.$emit('modal-show', 'modal-signup'); } - if (rootStore.state.userTokenInvalidateAttemptsCount <= AUTO_REFRESH_MAX_ATTEMPTS) _internalExecute(resolve, reject, task, currentToken, currentCartId) // retry - } else { - Logger.info('Invalidation process is disabled (autoRefreshTokens is set to false)', 'sync')() - rootStore.dispatch('user/logout', { silent: true }) - Vue.prototype.$bus.$emit('modal-show', 'modal-signup') + } + if ( + !task.silent && + (jsonResponse.result && + jsonResponse.result.code !== 'ENOTFOUND' && + !silentMode) + ) { + rootStore.dispatch('notification/spawnNotification', { + type: 'error', + message: i18n.t(jsonResponse.result), + action1: { label: i18n.t('OK') } + }); } } - if (!task.silent && (jsonResponse.result && jsonResponse.result.code !== 'ENOTFOUND' && !silentMode)) { - rootStore.dispatch('notification/spawnNotification', { - type: 'error', - message: i18n.t(jsonResponse.result), - action1: { label: i18n.t('OK') } - }) - } - } - Logger.debug('Response for: ' + task.task_id + ' = ' + JSON.stringify(jsonResponse.result), 'sync')() - task.transmited = true - task.transmited_at = new Date() - task.result = jsonResponse.result - task.resultCode = jsonResponse.code - task.code = jsonResponse.code // backward compatibility to fetch() - task.acknowledged = false + Logger.debug( + 'Response for: ' + + task.task_id + + ' = ' + + JSON.stringify(jsonResponse.result), + 'sync' + )(); + task.transmited = true; + task.transmited_at = new Date(); + task.result = jsonResponse.result; + task.resultCode = jsonResponse.code; + task.code = jsonResponse.code; // backward compatibility to fetch() + task.acknowledged = false; - if (task.callback_event) { - if (task.callback_event.startsWith('store:')) { - rootStore.dispatch(task.callback_event.split(':')[1], task) - } else { - Vue.prototype.$bus.$emit(task.callback_event, task) + if (task.callback_event) { + if (task.callback_event.startsWith('store:')) { + rootStore.dispatch(task.callback_event.split(':')[1], task); + } else { + Vue.prototype.$bus.$emit(task.callback_event, task); + } } + if (!rootStore.state.userTokenInvalidateLock) { + // in case we're revalidaing the token - user must wait for it + resolve(task); + } + } else { + const msg = i18n.t('Unhandled error, wrong response format!'); + Logger.error(msg.toString(), 'sync')(); + reject(msg); } - if (!rootStore.state.userTokenInvalidateLock) { // in case we're revalidaing the token - user must wait for it - resolve(task) - } - } else { - const msg = i18n.t('Unhandled error, wrong response format!') - Logger.error(msg.toString(), 'sync')() - reject(msg) - } - }).catch((err) => { - Logger.error(err, 'sync')() - reject(err) - }) + }) + .catch(err => { + Logger.error(err, 'sync')(); + reject(err); + }); } -export function execute (task: Task, currentToken = null, currentCartId = null): Promise { - const taskId = task.task_id +export function execute( + task: Task, + currentToken = null, + currentCartId = null +): Promise { + const taskId = task.task_id; return new Promise((resolve, reject) => { - _internalExecute(resolve, reject, task, currentToken, currentCartId) - }) + _internalExecute(resolve, reject, task, currentToken, currentCartId); + }); } -export function initializeSyncTaskStorage () { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' +export function initializeSyncTaskStorage() { + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.syncTaskCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'syncTasks', - driver: localForage[rootStore.state.config.localForage.defaultDrivers['syncTasks']] - })) + Vue.prototype.$db.syncTaskCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'syncTasks', + driver: + localForage[ + rootStore.state.config.localForage.defaultDrivers['syncTasks'] + ] + }) + ); } diff --git a/core/lib/sync/types/Task.ts b/core/lib/sync/types/Task.ts index 35649e3d56..c1ce527cc6 100644 --- a/core/lib/sync/types/Task.ts +++ b/core/lib/sync/types/Task.ts @@ -1,13 +1,13 @@ export default interface Task { - acknowledged: boolean - callback_event: string - code: number - payload: any - result: any - resultCode: number - silent: boolean - task_id: number - transmited: boolean - transmited_at: Date - url: string + acknowledged: boolean; + callback_event: string; + code: number; + payload: any; + result: any; + resultCode: number; + silent: boolean; + task_id: number; + transmited: boolean; + transmited_at: Date; + url: string; } diff --git a/core/lib/test/unit/logger.spec.ts b/core/lib/test/unit/logger.spec.ts index db04daa4f2..0d031890eb 100644 --- a/core/lib/test/unit/logger.spec.ts +++ b/core/lib/test/unit/logger.spec.ts @@ -1,176 +1,180 @@ -import config from 'config' -import * as coreHelper from '@vue-storefront/core/helpers' +import config from 'config'; +import * as coreHelper from '@vue-storefront/core/helpers'; -jest.mock('config', () => ({})) +jest.mock('config', () => ({})); jest.mock('@vue-storefront/core/helpers', () => ({ - get isServer () { - return true + get isServer() { + return true; } -})) +})); describe('Logger', () => { - const isServerSpy = jest.spyOn((coreHelper as any).default, 'isServer', 'get') - const consoleDebugSpy = jest.spyOn(console, 'debug') - const consoleErrorSpy = jest.spyOn(console, 'error') - const consoleInfoSpy = jest.spyOn(console, 'log') - const consoleWarnSpy = jest.spyOn(console, 'warn') - const env = process.env - - consoleDebugSpy.mockImplementation(() => {}) - consoleErrorSpy.mockImplementation(() => {}) - consoleInfoSpy.mockImplementation(() => {}) - consoleWarnSpy.mockImplementation(() => {}) + const isServerSpy = jest.spyOn( + (coreHelper as any).default, + 'isServer', + 'get' + ); + const consoleDebugSpy = jest.spyOn(console, 'debug'); + const consoleErrorSpy = jest.spyOn(console, 'error'); + const consoleInfoSpy = jest.spyOn(console, 'log'); + const consoleWarnSpy = jest.spyOn(console, 'warn'); + const env = process.env; + + consoleDebugSpy.mockImplementation(() => {}); + consoleErrorSpy.mockImplementation(() => {}); + consoleInfoSpy.mockImplementation(() => {}); + consoleWarnSpy.mockImplementation(() => {}); beforeEach(() => { - jest.clearAllMocks() + jest.clearAllMocks(); config.console = { verbosityLevel: 'display-everything', showErrorOnProduction: true - } - process.env = Object.assign({}, env) - }) + }; + process.env = Object.assign({}, env); + }); it('can be initialized with default settings', () => { jest.isolateModules(() => { - config.console = {} + config.console = {}; - expect(require('../../logger').Logger).toBeTruthy() - }) - }) + expect(require('../../logger').Logger).toBeTruthy(); + }); + }); describe('convertToString', () => { it('serializes objects to string', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - expect(Logger.convertToString({foo: 'bar'})).toBe('{"foo":"bar"}') - }) - }) + expect(Logger.convertToString({ foo: 'bar' })).toBe('{"foo":"bar"}'); + }); + }); it('extracts message from complex objects (i.e. error)', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - expect(Logger.convertToString({message: 'foo'})).toBe('foo') - }) - }) + expect(Logger.convertToString({ message: 'foo' })).toBe('foo'); + }); + }); it('returns primitive payloads unchanged', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - expect(Logger.convertToString('foo')).toBe('foo') - expect(Logger.convertToString(true)).toBe(true) - expect(Logger.convertToString(1337)).toBe(1337) - }) - }) - }) + expect(Logger.convertToString('foo')).toBe('foo'); + expect(Logger.convertToString(true)).toBe(true); + expect(Logger.convertToString(1337)).toBe(1337); + }); + }); + }); describe('canPrint', () => { it('allows all types of logs when verbosity is set to display-everything in dev mode', () => { - expect.assertions(4) + expect.assertions(4); jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; for (let method of ['info', 'warn', 'error', 'debug']) { - expect(Logger.canPrint(method)).toBeTruthy() + expect(Logger.canPrint(method)).toBeTruthy(); } - }) - }) + }); + }); it('allows showing errors when verbosity is set to only-errors in dev mode', () => { jest.isolateModules(() => { - config.console.verbosityLevel = 'only-errors' + config.console.verbosityLevel = 'only-errors'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - expect(Logger.canPrint('error')).toBeTruthy() + expect(Logger.canPrint('error')).toBeTruthy(); for (let method of ['info', 'warn', 'debug']) { - expect(Logger.canPrint(method)).toBeFalsy() + expect(Logger.canPrint(method)).toBeFalsy(); } - }) - }) + }); + }); it('allows showing errors when verbosity is set to only-errors in prod mode but showErrorOnProduction is set', () => { jest.isolateModules(() => { - config.console.verbosityLevel = 'only-errors' - process.env.NODE_ENV = 'production' + config.console.verbosityLevel = 'only-errors'; + process.env.NODE_ENV = 'production'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - expect(Logger.canPrint('error')).toBeTruthy() + expect(Logger.canPrint('error')).toBeTruthy(); for (let method of ['info', 'warn', 'debug']) { - expect(Logger.canPrint(method)).toBeFalsy() + expect(Logger.canPrint(method)).toBeFalsy(); } - }) - }) + }); + }); it('does not show any logs when verbosity is set to none', () => { jest.isolateModules(() => { - config.console.verbosityLevel = 'none' + config.console.verbosityLevel = 'none'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; for (let method of ['info', 'warn', 'debug', 'error']) { - expect(Logger.canPrint(method)).toBeFalsy() + expect(Logger.canPrint(method)).toBeFalsy(); } - }) - }) - }) + }); + }); + }); describe('debug', () => { - it('doesn\'t display message if logger is configured not to log it', () => { + it("doesn't display message if logger is configured not to log it", () => { jest.isolateModules(() => { - config.console.verbosityLevel = 'none' + config.console.verbosityLevel = 'none'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.debug('test', null, null)() - expect(consoleDebugSpy).not.toBeCalled() - }) - }) + Logger.debug('test', null, null)(); + expect(consoleDebugSpy).not.toBeCalled(); + }); + }); it('displays message without tag if none was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.debug('test')() - expect(consoleDebugSpy).toBeCalledWith('test', null) - }) - }) + Logger.debug('test')(); + expect(consoleDebugSpy).toBeCalledWith('test', null); + }); + }); it('displays message with tag if one was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.debug('test', 'tag')() - expect(consoleDebugSpy).toBeCalledWith('[tag] test', null) - }) - }) + Logger.debug('test', 'tag')(); + expect(consoleDebugSpy).toBeCalledWith('[tag] test', null); + }); + }); it('displays message without tag given no tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.debug('test')() + Logger.debug('test')(); expect(consoleDebugSpy).toBeCalledWith( '%cVSF%c test', expect.anything(), expect.anything(), null - ) - }) - }) + ); + }); + }); it('displays message with tag given a tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.debug('test', 'tag')() + Logger.debug('test', 'tag')(); expect(consoleDebugSpy).toBeCalledWith( '%cVSF%c %ctag%c test', expect.anything(), @@ -178,27 +182,27 @@ describe('Logger', () => { expect.anything(), expect.anything(), null - ) - }) - }) - }) + ); + }); + }); + }); describe('log', () => { it('works as an alias of info', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.log('test')() - expect(consoleInfoSpy).toBeCalled() - }) - }) + Logger.log('test')(); + expect(consoleInfoSpy).toBeCalled(); + }); + }); it('can be called with custom tag and context', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.log('test', 'tag', 'context')() + Logger.log('test', 'tag', 'context')(); expect(consoleInfoSpy).toBeCalledWith( '%cVSF%c %ctag%c test', expect.anything(), @@ -206,62 +210,62 @@ describe('Logger', () => { expect.anything(), expect.anything(), 'context' - ) - }) - }) - }) + ); + }); + }); + }); describe('info', () => { - it('doesn\'t display message if logger is configured not to log it', () => { + it("doesn't display message if logger is configured not to log it", () => { jest.isolateModules(() => { - config.console.verbosityLevel = 'none' + config.console.verbosityLevel = 'none'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.info('test', null, null)() - expect(consoleInfoSpy).not.toBeCalled() - }) - }) + Logger.info('test', null, null)(); + expect(consoleInfoSpy).not.toBeCalled(); + }); + }); it('displays message without tag if none was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.info('test')() - expect(consoleInfoSpy).toBeCalledWith('test', null) - }) - }) + Logger.info('test')(); + expect(consoleInfoSpy).toBeCalledWith('test', null); + }); + }); it('displays message with tag if one was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.info('test', 'tag')() - expect(consoleInfoSpy).toBeCalledWith('[tag] test', null) - }) - }) + Logger.info('test', 'tag')(); + expect(consoleInfoSpy).toBeCalledWith('[tag] test', null); + }); + }); it('displays message without tag given no tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.info('test')() + Logger.info('test')(); expect(consoleInfoSpy).toBeCalledWith( '%cVSF%c test', expect.anything(), expect.anything(), null - ) - }) - }) + ); + }); + }); it('displays message with tag given a tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.info('test', 'tag')() + Logger.info('test', 'tag')(); expect(consoleInfoSpy).toBeCalledWith( '%cVSF%c %ctag%c test', expect.anything(), @@ -269,62 +273,62 @@ describe('Logger', () => { expect.anything(), expect.anything(), null - ) - }) - }) - }) + ); + }); + }); + }); describe('warn', () => { - it('doesn\'t display message if logger is configured not to log it', () => { + it("doesn't display message if logger is configured not to log it", () => { jest.isolateModules(() => { - config.console.verbosityLevel = 'none' + config.console.verbosityLevel = 'none'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.warn('test', null, null)() - expect(consoleWarnSpy).not.toBeCalled() - }) - }) + Logger.warn('test', null, null)(); + expect(consoleWarnSpy).not.toBeCalled(); + }); + }); it('displays message without tag if none was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.warn('test')() - expect(consoleWarnSpy).toBeCalledWith('test', null) - }) - }) + Logger.warn('test')(); + expect(consoleWarnSpy).toBeCalledWith('test', null); + }); + }); it('displays message with tag if one was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.warn('test', 'tag')() - expect(consoleWarnSpy).toBeCalledWith('[tag] test', null) - }) - }) + Logger.warn('test', 'tag')(); + expect(consoleWarnSpy).toBeCalledWith('[tag] test', null); + }); + }); it('displays message without tag given no tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.warn('test')() + Logger.warn('test')(); expect(consoleWarnSpy).toBeCalledWith( '%cVSF%c test', expect.anything(), expect.anything(), null - ) - }) - }) + ); + }); + }); it('displays message with tag given a tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.warn('test', 'tag')() + Logger.warn('test', 'tag')(); expect(consoleWarnSpy).toBeCalledWith( '%cVSF%c %ctag%c test', expect.anything(), @@ -332,63 +336,63 @@ describe('Logger', () => { expect.anything(), expect.anything(), null - ) - }) - }) - }) + ); + }); + }); + }); describe('error', () => { it('always displays messages in SSR', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.error('test')() - expect(consoleErrorSpy).toBeCalled() - }) - }) + Logger.error('test')(); + expect(consoleErrorSpy).toBeCalled(); + }); + }); it('displays message with tag if one was given in SSR and logger is configured to log everything', () => { jest.isolateModules(() => { - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.error('test', 'tag')() - expect(consoleErrorSpy).toBeCalledWith('[tag] test', null) - }) - }) + Logger.error('test', 'tag')(); + expect(consoleErrorSpy).toBeCalledWith('[tag] test', null); + }); + }); - it('doesn\'t display message if logger is configured not to log it and not in SSR mode', () => { + it("doesn't display message if logger is configured not to log it and not in SSR mode", () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - config.console.verbosityLevel = 'none' + isServerSpy.mockReturnValueOnce(false); + config.console.verbosityLevel = 'none'; - const Logger = require('../../logger').Logger + const Logger = require('../../logger').Logger; - Logger.error('test', null, null)() - expect(consoleErrorSpy).not.toBeCalled() - }) - }) + Logger.error('test', null, null)(); + expect(consoleErrorSpy).not.toBeCalled(); + }); + }); it('displays message without tag given no tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.error('test')() + Logger.error('test')(); expect(consoleErrorSpy).toBeCalledWith( '%cVSF%c test', expect.anything(), expect.anything(), null - ) - }) - }) + ); + }); + }); it('displays message with tag given a tag and logger is configured to log everything', () => { jest.isolateModules(() => { - isServerSpy.mockReturnValueOnce(false) - const Logger = require('../../logger').Logger + isServerSpy.mockReturnValueOnce(false); + const Logger = require('../../logger').Logger; - Logger.error('test', 'tag')() + Logger.error('test', 'tag')(); expect(consoleErrorSpy).toBeCalledWith( '%cVSF%c %ctag%c test', expect.anything(), @@ -396,8 +400,8 @@ describe('Logger', () => { expect.anything(), expect.anything(), null - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/core/lib/themes.ts b/core/lib/themes.ts index e33b119367..d1f23f2ee9 100644 --- a/core/lib/themes.ts +++ b/core/lib/themes.ts @@ -1,8 +1,15 @@ -export function registerTheme (themeName, app, routes, store, config, ssrContext) { - const themeEntryPoint = require('theme/index.js') +export function registerTheme( + themeName, + app, + routes, + store, + config, + ssrContext +) { + const themeEntryPoint = require('theme/index.js'); if (themeEntryPoint != null && themeEntryPoint.initTheme) { - themeEntryPoint.initTheme(app, routes, store, config, ssrContext) // register theme + themeEntryPoint.initTheme(app, routes, store, config, ssrContext); // register theme } else { - throw new Error('Wrong theme name: ' + themeName) + throw new Error('Wrong theme name: ' + themeName); } } diff --git a/core/mixins/composite.js b/core/mixins/composite.js index fe080fbf3f..f72884ae36 100644 --- a/core/mixins/composite.js +++ b/core/mixins/composite.js @@ -1,27 +1,26 @@ -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -import { Logger } from '@vue-storefront/core/lib/logger' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'; +import { Logger } from '@vue-storefront/core/lib/logger'; // to be deprecated export default { - beforeCreated () { - const eventName = this.$options.name.toLowerCase() + '-before-created' - Logger.debug(eventName, 'event')() - EventBus.$emit(eventName, this) + beforeCreated() { + const eventName = this.$options.name.toLowerCase() + '-before-created'; + Logger.debug(eventName, 'event')(); + EventBus.$emit(eventName, this); }, - created () { - const eventName = this.$options.name.toLowerCase() + '-after-created' - Logger.debug(eventName, 'event')() - EventBus.$emit(eventName, this) + created() { + const eventName = this.$options.name.toLowerCase() + '-after-created'; + Logger.debug(eventName, 'event')(); + EventBus.$emit(eventName, this); }, - beforeMount () { - const eventName = this.$options.name.toLowerCase() + '-before-mount' - Logger.debug(eventName, 'event')() - EventBus.$emit(eventName, this) + beforeMount() { + const eventName = this.$options.name.toLowerCase() + '-before-mount'; + Logger.debug(eventName, 'event')(); + EventBus.$emit(eventName, this); }, - mounted () { - const eventName = this.$options.name.toLowerCase() + '-after-mounted' - Logger.debug(eventName, 'event')() - EventBus.$emit(eventName, this) + mounted() { + const eventName = this.$options.name.toLowerCase() + '-after-mounted'; + Logger.debug(eventName, 'event')(); + EventBus.$emit(eventName, this); } - -} +}; diff --git a/core/mixins/index.js b/core/mixins/index.js index 990684de30..dab40feaa0 100644 --- a/core/mixins/index.js +++ b/core/mixins/index.js @@ -1,7 +1,4 @@ -import { thumbnail } from './thumbnail.js' -import { multistore } from './multistore.js' +import { thumbnail } from './thumbnail.js'; +import { multistore } from './multistore.js'; -export { - thumbnail, - multistore -} +export { thumbnail, multistore }; diff --git a/core/mixins/multistore.js b/core/mixins/multistore.js index b3adb383a0..befb813c95 100644 --- a/core/mixins/multistore.js +++ b/core/mixins/multistore.js @@ -1,4 +1,8 @@ -import { localizedRoute as localizedRouteHelper, localizedDispatcherRoute as localizedDispatcherRouteHelper, currentStoreView } from '@vue-storefront/core/lib/multistore' +import { + localizedRoute as localizedRouteHelper, + localizedDispatcherRoute as localizedDispatcherRouteHelper, + currentStoreView +} from '@vue-storefront/core/lib/multistore'; export const multistore = { methods: { @@ -8,9 +12,9 @@ export const multistore = { * @param {Int} width * @param {Int} height */ - localizedRoute (routeObj) { - const storeView = currentStoreView() - return localizedRouteHelper(routeObj, storeView.storeCode) + localizedRoute(routeObj) { + const storeView = currentStoreView(); + return localizedRouteHelper(routeObj, storeView.storeCode); }, /** * Return localized route params for URL Dispatcher @@ -18,9 +22,9 @@ export const multistore = { * @param {Int} width * @param {Int} height */ - localizedDispatcherRoute (routeObj) { - const storeView = currentStoreView() - return localizedDispatcherRouteHelper(routeObj, storeView.storeCode) + localizedDispatcherRoute(routeObj) { + const storeView = currentStoreView(); + return localizedDispatcherRouteHelper(routeObj, storeView.storeCode); } } -} +}; diff --git a/core/mixins/onEscapePress.js b/core/mixins/onEscapePress.js index 0876333d89..c821bc9974 100644 --- a/core/mixins/onEscapePress.js +++ b/core/mixins/onEscapePress.js @@ -1,14 +1,14 @@ export default { - mounted () { - const keydownHandler = (e) => { + mounted() { + const keydownHandler = e => { // for old browser support as a fallback if (e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27) { - this.onEscapePress() + this.onEscapePress(); } - } - document.addEventListener('keydown', keydownHandler) + }; + document.addEventListener('keydown', keydownHandler); this.$once('hook:destroyed', () => { - document.removeEventListener('keydown', keydownHandler) - }) + document.removeEventListener('keydown', keydownHandler); + }); } -} +}; diff --git a/core/mixins/thumbnail.js b/core/mixins/thumbnail.js index 0dafcc09e3..0cd80d474a 100644 --- a/core/mixins/thumbnail.js +++ b/core/mixins/thumbnail.js @@ -1,4 +1,4 @@ -import { getThumbnailPath as _thumbnailHelper } from '@vue-storefront/core/helpers' +import { getThumbnailPath as _thumbnailHelper } from '@vue-storefront/core/helpers'; export const thumbnail = { methods: { @@ -8,8 +8,8 @@ export const thumbnail = { * @param {Int} width * @param {Int} height */ - getThumbnail (relativeUrl, width, height) { - return _thumbnailHelper(relativeUrl, width, height) + getThumbnail(relativeUrl, width, height) { + return _thumbnailHelper(relativeUrl, width, height); } } -} +}; diff --git a/core/modules-entry.ts b/core/modules-entry.ts index 2d2671b588..de095dceb5 100644 --- a/core/modules-entry.ts +++ b/core/modules-entry.ts @@ -1,14 +1,13 @@ - -import { VueStorefrontModule } from '@vue-storefront/core/lib/module' -import { Cms } from './modules/cms' -import { Order } from './modules/order' -import { User } from './modules/user' -import { registerModules } from 'src/modules' -import { Breadcrumbs } from './modules/breadcrumbs' +import { VueStorefrontModule } from '@vue-storefront/core/lib/module'; +import { Cms } from './modules/cms'; +import { Order } from './modules/order'; +import { User } from './modules/user'; +import { registerModules } from 'src/modules'; +import { Breadcrumbs } from './modules/breadcrumbs'; export const enabledModules: VueStorefrontModule[] = [ Breadcrumbs, Cms, Order, User, ...registerModules -] +]; diff --git a/core/modules/breadcrumbs/components/Breadcrumbs.ts b/core/modules/breadcrumbs/components/Breadcrumbs.ts index d2b21903b4..1e0f212d1a 100644 --- a/core/modules/breadcrumbs/components/Breadcrumbs.ts +++ b/core/modules/breadcrumbs/components/Breadcrumbs.ts @@ -1,10 +1,10 @@ export const Breadcrumbs = { computed: { - routes () { - return this.$store.state.breadcrumbs.routes + routes() { + return this.$store.state.breadcrumbs.routes; }, - current () { - return this.$store.state.breadcrumbs.current + current() { + return this.$store.state.breadcrumbs.current; } } -} \ No newline at end of file +}; diff --git a/core/modules/breadcrumbs/helpers/index.ts b/core/modules/breadcrumbs/helpers/index.ts index 0a3bf05257..ac897e05fa 100644 --- a/core/modules/breadcrumbs/helpers/index.ts +++ b/core/modules/breadcrumbs/helpers/index.ts @@ -1,15 +1,15 @@ -import { formatCategoryLink } from '@vue-storefront/core/modules/url/helpers' +import { formatCategoryLink } from '@vue-storefront/core/modules/url/helpers'; -// Duplicate of breadCrumbRoutes, to repalce it soon. +// Duplicate of breadCrumbRoutes, to repalce it soon. /** Parse category path for product/category */ -export function parseCategoryPath (categoryPath) { - let routesArray = [] +export function parseCategoryPath(categoryPath) { + let routesArray = []; for (let category of categoryPath) { routesArray.push({ name: category.name, route_link: formatCategoryLink(category) - }) + }); } - return routesArray -} \ No newline at end of file + return routesArray; +} diff --git a/core/modules/breadcrumbs/index.ts b/core/modules/breadcrumbs/index.ts index d9d58af87a..638f0cda03 100644 --- a/core/modules/breadcrumbs/index.ts +++ b/core/modules/breadcrumbs/index.ts @@ -1,10 +1,8 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; -export const KEY = 'breadcrumbs' +export const KEY = 'breadcrumbs'; export const Breadcrumbs = createModule({ key: KEY, - store: { modules: [ - { key: KEY, module: module } - ] }, -}) + store: { modules: [{ key: KEY, module: module }] } +}); diff --git a/core/modules/breadcrumbs/store/index.ts b/core/modules/breadcrumbs/store/index.ts index 236652dd7d..72b2809bfa 100644 --- a/core/modules/breadcrumbs/store/index.ts +++ b/core/modules/breadcrumbs/store/index.ts @@ -1,5 +1,3 @@ - - export const module = { namespaced: true, state: { @@ -7,14 +5,14 @@ export const module = { current: null }, mutations: { - set (state, payload) { - state.routes = payload.routes - state.current = payload.current + set(state, payload) { + state.routes = payload.routes; + state.current = payload.current; } }, actions: { - set ({ commit }, payload) { - commit('set', payload) + set({ commit }, payload) { + commit('set', payload); } } -} \ No newline at end of file +}; diff --git a/core/modules/cart/components/AddToCart.ts b/core/modules/cart/components/AddToCart.ts index 437fca5d4e..6e2264c38a 100644 --- a/core/modules/cart/components/AddToCart.ts +++ b/core/modules/cart/components/AddToCart.ts @@ -1,4 +1,4 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; export const AddToCart = { name: 'AddToCart', @@ -13,8 +13,8 @@ export const AddToCart = { } }, methods: { - addToCart (product: Product) { - this.$store.dispatch('cart/addItem', { productToAdd: product }) + addToCart(product: Product) { + this.$store.dispatch('cart/addItem', { productToAdd: product }); } } -} +}; diff --git a/core/modules/cart/components/Microcart.ts b/core/modules/cart/components/Microcart.ts index fe7a3e2d6d..aa21b3d158 100644 --- a/core/modules/cart/components/Microcart.ts +++ b/core/modules/cart/components/Microcart.ts @@ -1,32 +1,32 @@ -import AppliedCoupon from '../types/AppliedCoupon' -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import CartTotalSegments from '../types/CartTotalSegments' +import AppliedCoupon from '../types/AppliedCoupon'; +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import CartTotalSegments from '../types/CartTotalSegments'; export const Microcart = { name: 'Microcart', computed: { - productsInCart () : Product[] { - return this.$store.state.cart.cartItems + productsInCart(): Product[] { + return this.$store.state.cart.cartItems; }, - appliedCoupon () : AppliedCoupon | false { - return this.$store.getters['cart/coupon'] + appliedCoupon(): AppliedCoupon | false { + return this.$store.getters['cart/coupon']; }, - totals () : CartTotalSegments { - return this.$store.getters['cart/totals'] + totals(): CartTotalSegments { + return this.$store.getters['cart/totals']; }, - isOpen () : boolean { - return this.$store.state.cart.isMicrocartOpen + isOpen(): boolean { + return this.$store.state.cart.isMicrocartOpen; } }, methods: { - applyCoupon (code: String) : Promise { - return this.$store.dispatch('cart/applyCoupon', code) + applyCoupon(code: String): Promise { + return this.$store.dispatch('cart/applyCoupon', code); }, - removeCoupon () : Promise { - return this.$store.dispatch('cart/removeCoupon') + removeCoupon(): Promise { + return this.$store.dispatch('cart/removeCoupon'); }, - toggleMicrocart () : void { - this.$store.dispatch('ui/toggleMicrocart') + toggleMicrocart(): void { + this.$store.dispatch('ui/toggleMicrocart'); } } -} +}; diff --git a/core/modules/cart/components/MicrocartButton.ts b/core/modules/cart/components/MicrocartButton.ts index 8a94dd9b69..cd8c7d5f38 100644 --- a/core/modules/cart/components/MicrocartButton.ts +++ b/core/modules/cart/components/MicrocartButton.ts @@ -1,21 +1,20 @@ - export const MicrocartButton = { name: 'MicrocartButton', - mounted () { + mounted() { document.addEventListener('visibilitychange', () => { if (!document.hidden) { - this.$store.dispatch('cart/load') + this.$store.dispatch('cart/load'); } - }) + }); }, methods: { - toggleMicrocart () { - this.$store.dispatch('cart/toggleMicrocart') + toggleMicrocart() { + this.$store.dispatch('cart/toggleMicrocart'); } }, computed: { - quantity () { - return this.$store.getters['cart/totalQuantity'] + quantity() { + return this.$store.getters['cart/totalQuantity']; } } -} +}; diff --git a/core/modules/cart/components/Product.ts b/core/modules/cart/components/Product.ts index 4f7154b7dc..b4437fd42d 100644 --- a/core/modules/cart/components/Product.ts +++ b/core/modules/cart/components/Product.ts @@ -1,4 +1,4 @@ -import { productThumbnailPath } from '@vue-storefront/core/helpers' +import { productThumbnailPath } from '@vue-storefront/core/helpers'; export const MicrocartProduct = { name: 'MicrocartProduct', @@ -9,19 +9,22 @@ export const MicrocartProduct = { } }, computed: { - thumbnail () { - const thumbnail = productThumbnailPath(this.product) + thumbnail() { + const thumbnail = productThumbnailPath(this.product); if (typeof navigator !== 'undefined' && !navigator.onLine) { - return this.getThumbnail(thumbnail, 310, 300) // for offline support we do need to have ProductTile version - } else return this.getThumbnail(thumbnail, 150, 150) + return this.getThumbnail(thumbnail, 310, 300); // for offline support we do need to have ProductTile version + } else return this.getThumbnail(thumbnail, 150, 150); } }, methods: { - removeFromCart () { - this.$store.dispatch('cart/removeItem', { product: this.product }) + removeFromCart() { + this.$store.dispatch('cart/removeItem', { product: this.product }); }, - updateQuantity (quantity) { - this.$store.dispatch('cart/updateQuantity', { product: this.product, qty: quantity }) + updateQuantity(quantity) { + this.$store.dispatch('cart/updateQuantity', { + product: this.product, + qty: quantity + }); } } -} +}; diff --git a/core/modules/cart/helpers/cartCacheHandler.ts b/core/modules/cart/helpers/cartCacheHandler.ts index 39309a5381..ffa6e57ca5 100644 --- a/core/modules/cart/helpers/cartCacheHandler.ts +++ b/core/modules/cart/helpers/cartCacheHandler.ts @@ -1,4 +1,4 @@ -import * as types from "../store/mutation-types"; +import * as types from '../store/mutation-types'; export function cartCacheHandlerFactory(Vue) { return (mutation, state) => { @@ -11,15 +11,17 @@ export function cartCacheHandlerFactory(Vue) { type.endsWith(types.CART_UPD_ITEM) || type.endsWith(types.CART_UPD_ITEM_PROPS) ) { - return Vue.prototype.$db.cartsCollection.setItem('current-cart', state.cart.cartItems).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache - } else if ( - type.endsWith(types.CART_LOAD_CART_SERVER_TOKEN) - ) { - return Vue.prototype.$db.cartsCollection.setItem('current-cart-token', state.cart.cartServerToken).catch((reason) => { - console.error(reason) - }) + return Vue.prototype.$db.cartsCollection + .setItem('current-cart', state.cart.cartItems) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache + } else if (type.endsWith(types.CART_LOAD_CART_SERVER_TOKEN)) { + return Vue.prototype.$db.cartsCollection + .setItem('current-cart-token', state.cart.cartServerToken) + .catch(reason => { + console.error(reason); + }); } - } + }; } diff --git a/core/modules/cart/hooks/afterRegistration.ts b/core/modules/cart/hooks/afterRegistration.ts index 37d20f93ef..04e7e864ad 100644 --- a/core/modules/cart/hooks/afterRegistration.ts +++ b/core/modules/cart/hooks/afterRegistration.ts @@ -1,7 +1,7 @@ -import { cartCacheHandlerFactory } from "../helpers/cartCacheHandler"; +import { cartCacheHandlerFactory } from '../helpers/cartCacheHandler'; export function afterRegistration({ Vue, config, store, isServer }) { - if (!isServer) store.dispatch('cart/load') + if (!isServer) store.dispatch('cart/load'); - store.subscribe(cartCacheHandlerFactory(Vue)) -} \ No newline at end of file + store.subscribe(cartCacheHandlerFactory(Vue)); +} diff --git a/core/modules/cart/hooks/beforeRegistration.ts b/core/modules/cart/hooks/beforeRegistration.ts index c2a41b8430..d78191f9da 100644 --- a/core/modules/cart/hooks/beforeRegistration.ts +++ b/core/modules/cart/hooks/beforeRegistration.ts @@ -1,14 +1,16 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.cartsCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'carts', - driver: localForage[config.localForage.defaultDrivers['carts']] - })) -} \ No newline at end of file + Vue.prototype.$db.cartsCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'carts', + driver: localForage[config.localForage.defaultDrivers['carts']] + }) + ); +} diff --git a/core/modules/cart/index.ts b/core/modules/cart/index.ts index 051741d917..2e03a45160 100644 --- a/core/modules/cart/index.ts +++ b/core/modules/cart/index.ts @@ -1,12 +1,12 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; -export const KEY = 'cart' +export const KEY = 'cart'; export const Cart = createModule({ key: KEY, store: { modules: [{ key: KEY, module }] }, beforeRegistration, afterRegistration -}) +}); diff --git a/core/modules/cart/store/actions.ts b/core/modules/cart/store/actions.ts index b5a7a2f33e..dc18e0eeb9 100644 --- a/core/modules/cart/store/actions.ts +++ b/core/modules/cart/store/actions.ts @@ -1,70 +1,103 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import rootStore from '@vue-storefront/core/store' -import config from 'config' -import i18n from '@vue-storefront/i18n' -import { sha3_224 } from 'js-sha3' -import { currentStoreView, localizedRoute} from '@vue-storefront/core/lib/multistore' -import omit from 'lodash-es/omit' -import RootState from '@vue-storefront/core/types/RootState' -import CartState from '../types/CartState' -import isString from 'lodash-es/isString' -import toString from 'lodash-es/toString' -import { Logger } from '@vue-storefront/core/lib/logger' -import { TaskQueue } from '@vue-storefront/core/lib/sync' -import { router } from '@vue-storefront/core/app' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { isServer, onlineHelper } from '@vue-storefront/core/helpers' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import rootStore from '@vue-storefront/core/store'; +import config from 'config'; +import i18n from '@vue-storefront/i18n'; +import { sha3_224 } from 'js-sha3'; +import { + currentStoreView, + localizedRoute +} from '@vue-storefront/core/lib/multistore'; +import omit from 'lodash-es/omit'; +import RootState from '@vue-storefront/core/types/RootState'; +import CartState from '../types/CartState'; +import isString from 'lodash-es/isString'; +import toString from 'lodash-es/toString'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { TaskQueue } from '@vue-storefront/core/lib/sync'; +import { router } from '@vue-storefront/core/app'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { isServer, onlineHelper } from '@vue-storefront/core/helpers'; -const CART_PULL_INTERVAL_MS = 2000 -const CART_CREATE_INTERVAL_MS = 1000 -const CART_TOTALS_INTERVAL_MS = 200 -const CART_METHODS_INTERVAL_MS = 1000 * 60 * 10 // refresh methods each 10 min -const MAX_BYPASS_COUNT = 10 +const CART_PULL_INTERVAL_MS = 2000; +const CART_CREATE_INTERVAL_MS = 1000; +const CART_TOTALS_INTERVAL_MS = 200; +const CART_METHODS_INTERVAL_MS = 1000 * 60 * 10; // refresh methods each 10 min +const MAX_BYPASS_COUNT = 10; -function _updateClientItem (event, clientItem) { +function _updateClientItem(event, clientItem) { if (typeof event.result.item_id !== 'undefined') { - rootStore.dispatch('cart/updateItem', { product: { server_item_id: event.result.item_id, sku: clientItem.sku, server_cart_id: event.result.quote_id, prev_qty: clientItem.qty } }, { root: true }) // update the server_id reference - Vue.prototype.$bus.$emit('cart-after-itemchanged', { item: clientItem }) + rootStore.dispatch( + 'cart/updateItem', + { + product: { + server_item_id: event.result.item_id, + sku: clientItem.sku, + server_cart_id: event.result.quote_id, + prev_qty: clientItem.qty + } + }, + { root: true } + ); // update the server_id reference + Vue.prototype.$bus.$emit('cart-after-itemchanged', { item: clientItem }); } } -function _afterServerItemUpdated (event, clientItem = null) { - Logger.debug('Cart item server sync' + event, 'cart')() +function _afterServerItemUpdated(event, clientItem = null) { + Logger.debug('Cart item server sync' + event, 'cart')(); if (clientItem === null) { - rootStore.dispatch('cart/getItem', event.result.sku, { root: true }).then((cartItem) => { - if (cartItem) { - _updateClientItem(event, cartItem) - } - }) + rootStore + .dispatch('cart/getItem', event.result.sku, { root: true }) + .then(cartItem => { + if (cartItem) { + _updateClientItem(event, cartItem); + } + }); } else { - _updateClientItem(event, clientItem) + _updateClientItem(event, clientItem); } } const actions: ActionTree = { - serverTokenClear (context) { - context.commit(types.CART_LOAD_CART_SERVER_TOKEN, null) + serverTokenClear(context) { + context.commit(types.CART_LOAD_CART_SERVER_TOKEN, null); }, - clear (context) { - context.commit(types.CART_LOAD_CART, []) - context.commit(types.CART_LOAD_CART_SERVER_TOKEN, null) + clear(context) { + context.commit(types.CART_LOAD_CART, []); + context.commit(types.CART_LOAD_CART_SERVER_TOKEN, null); if (config.cart.synchronize) { - context.dispatch('serverCreate', { guestCart: !config.orders.directBackendSync }) // guest cart when not using directBackendSync because when the order hasn't been passed to Magento yet it will repopulate your cart + context.dispatch('serverCreate', { + guestCart: !config.orders.directBackendSync + }); // guest cart when not using directBackendSync because when the order hasn't been passed to Magento yet it will repopulate your cart } }, - save (context) { - context.commit(types.CART_SAVE) + save(context) { + context.commit(types.CART_SAVE); }, - serverPull (context, { forceClientState = false, dryRun = false }) { // pull current cart FROM the server - if (config.cart.synchronize && !isServer && onlineHelper.isOnline && context.state.cartServerToken) { - const newItemsHash = sha3_224(JSON.stringify({ items: context.state.cartItems, token: context.state.cartServerToken })) - if ((Date.now() - context.state.cartServerPullAt) >= CART_PULL_INTERVAL_MS || (newItemsHash !== context.state.cartItemsHash)) { - context.state.cartServerPullAt = Date.now() - context.state.cartItemsHash = newItemsHash - return TaskQueue.execute({ url: config.cart.pull_endpoint, // sync the cart + serverPull(context, { forceClientState = false, dryRun = false }) { + // pull current cart FROM the server + if ( + config.cart.synchronize && + !isServer && + onlineHelper.isOnline && + context.state.cartServerToken + ) { + const newItemsHash = sha3_224( + JSON.stringify({ + items: context.state.cartItems, + token: context.state.cartServerToken + }) + ); + if ( + Date.now() - context.state.cartServerPullAt >= CART_PULL_INTERVAL_MS || + newItemsHash !== context.state.cartItemsHash + ) { + context.state.cartServerPullAt = Date.now(); + context.state.cartItemsHash = newItemsHash; + return TaskQueue.execute({ + url: config.cart.pull_endpoint, // sync the cart payload: { method: 'GET', headers: { 'Content-Type': 'application/json' }, @@ -75,28 +108,48 @@ const actions: ActionTree = { dry_run: dryRun, callback_event: 'store:cart/servercartAfterPulled' }).then(task => { - const storeView = currentStoreView() - if ((Date.now() - context.state.cartServerMethodsRefreshAt) >= CART_METHODS_INTERVAL_MS) { - context.state.cartServerMethodsRefreshAt = Date.now() - Logger.debug('Refreshing payment & shipping methods', 'cart')() - rootStore.dispatch('cart/getPaymentMethods') + const storeView = currentStoreView(); + if ( + Date.now() - context.state.cartServerMethodsRefreshAt >= + CART_METHODS_INTERVAL_MS + ) { + context.state.cartServerMethodsRefreshAt = Date.now(); + Logger.debug('Refreshing payment & shipping methods', 'cart')(); + rootStore.dispatch('cart/getPaymentMethods'); if (context.state.cartItems.length > 0) { - let country = rootStore.state.checkout.shippingDetails.country ? rootStore.state.checkout.shippingDetails.country : storeView.tax.defaultCountry + let country = rootStore.state.checkout.shippingDetails.country + ? rootStore.state.checkout.shippingDetails.country + : storeView.tax.defaultCountry; rootStore.dispatch('cart/getShippingMethods', { country_id: country - }) + }); } } - }) + }); } else { - Logger.log('Too short interval for refreshing the cart or items not changed' + newItemsHash + context.state.cartItemsHash, 'cart')() + Logger.log( + 'Too short interval for refreshing the cart or items not changed' + + newItemsHash + + context.state.cartItemsHash, + 'cart' + )(); } } }, - serverTotals (context, { forceClientState = false }) { // pull current cart FROM the server - if (config.cart.synchronize_totals && !isServer && onlineHelper.isOnline && context.state.cartServerToken) { - if ((Date.now() - context.state.cartServerTotalsAt) >= CART_TOTALS_INTERVAL_MS) { - TaskQueue.execute({ url: config.cart.totals_endpoint, // sync the cart + serverTotals(context, { forceClientState = false }) { + // pull current cart FROM the server + if ( + config.cart.synchronize_totals && + !isServer && + onlineHelper.isOnline && + context.state.cartServerToken + ) { + if ( + Date.now() - context.state.cartServerTotalsAt >= + CART_TOTALS_INTERVAL_MS + ) { + TaskQueue.execute({ + url: config.cart.totals_endpoint, // sync the cart payload: { method: 'GET', headers: { 'Content-Type': 'application/json' }, @@ -105,16 +158,25 @@ const actions: ActionTree = { silent: true, force_client_state: forceClientState, callback_event: 'store:cart/servercartAfterTotals' - }) + }); } else { - Logger.log('Too short interval for refreshing the cart totals', 'cart')() + Logger.log( + 'Too short interval for refreshing the cart totals', + 'cart' + )(); } } }, - serverCreate (context, { guestCart = false }) { + serverCreate(context, { guestCart = false }) { if (config.cart.synchronize && !isServer) { - if ((Date.now() - context.state.cartServerCreatedAt) >= CART_CREATE_INTERVAL_MS) { - const task = { url: guestCart ? config.cart.create_endpoint.replace('{{token}}', '') : config.cart.create_endpoint, // sync the cart + if ( + Date.now() - context.state.cartServerCreatedAt >= + CART_CREATE_INTERVAL_MS + ) { + const task = { + url: guestCart + ? config.cart.create_endpoint.replace('{{token}}', '') + : config.cart.create_endpoint, // sync the cart payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -122,18 +184,21 @@ const actions: ActionTree = { }, silent: true, callback_event: 'store:cart/servercartAfterCreated' - } - TaskQueue.execute(task) - return task + }; + TaskQueue.execute(task); + return task; } } }, - serverUpdateItem (context, cartItem) { + serverUpdateItem(context, cartItem) { if (!cartItem.quoteId) { - cartItem = Object.assign(cartItem, { quoteId: context.state.cartServerToken }) + cartItem = Object.assign(cartItem, { + quoteId: context.state.cartServerToken + }); } - return TaskQueue.execute({ url: config.cart.updateitem_endpoint, // sync the cart + return TaskQueue.execute({ + url: config.cart.updateitem_endpoint, // sync the cart payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -145,18 +210,26 @@ const actions: ActionTree = { callback_event: 'store:cart/servercartAfterItemUpdated' }).then(task => { // eslint-disable-next-line no-useless-return - if (config.cart.synchronize_totals && context.state.cartItems.length > 0) { - context.dispatch('refreshTotals') + if ( + config.cart.synchronize_totals && + context.state.cartItems.length > 0 + ) { + context.dispatch('refreshTotals'); } - return task - }) + return task; + }); }, - serverDeleteItem (context, cartItem) { + serverDeleteItem(context, cartItem) { if (!cartItem.quoteId) { - cartItem = Object.assign(cartItem, { quoteId: context.state.cartServerToken }) + cartItem = Object.assign(cartItem, { + quoteId: context.state.cartServerToken + }); } - cartItem = Object.assign(cartItem, { quoteId: context.state.cartServerToken }) - return TaskQueue.execute({ url: config.cart.deleteitem_endpoint, // sync the cart + cartItem = Object.assign(cartItem, { + quoteId: context.state.cartServerToken + }); + return TaskQueue.execute({ + url: config.cart.deleteitem_endpoint, // sync the cart payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -169,204 +242,307 @@ const actions: ActionTree = { callback_event: 'store:cart/servercartAfterItemDeleted' }).then(task => { // eslint-disable-next-line no-useless-return - if (config.cart.synchronize_totals && context.state.cartItems.length > 0) { - context.dispatch('refreshTotals') + if ( + config.cart.synchronize_totals && + context.state.cartItems.length > 0 + ) { + context.dispatch('refreshTotals'); } - return task - }) + return task; + }); }, - load (context) { + load(context) { return new Promise((resolve, reject) => { - if (isServer) return - const commit = context.commit - const state = context.state + if (isServer) return; + const commit = context.commit; + const state = context.state; - if ((!state.shipping || !state.shipping.method_code) && (Array.isArray(context.rootGetters['shipping/shippingMethods']))) { - let shippingMethod = context.rootGetters['shipping/shippingMethods'].find(item => item.default) - commit(types.CART_UPD_SHIPPING, shippingMethod) + if ( + (!state.shipping || !state.shipping.method_code) && + Array.isArray(context.rootGetters['shipping/shippingMethods']) + ) { + let shippingMethod = context.rootGetters[ + 'shipping/shippingMethods' + ].find(item => item.default); + commit(types.CART_UPD_SHIPPING, shippingMethod); } - if ((!state.payment || !state.payment.code) && Array.isArray(context.rootGetters['payment/paymentMethods'])) { - let paymentMethod = context.rootGetters['payment/paymentMethods'].find(item => item.default) - commit(types.CART_UPD_PAYMENT, paymentMethod) + if ( + (!state.payment || !state.payment.code) && + Array.isArray(context.rootGetters['payment/paymentMethods']) + ) { + let paymentMethod = context.rootGetters['payment/paymentMethods'].find( + item => item.default + ); + commit(types.CART_UPD_PAYMENT, paymentMethod); } - Vue.prototype.$db.cartsCollection.getItem('current-cart', (err, storedItems) => { - if (err) throw new Error(err) + Vue.prototype.$db.cartsCollection.getItem( + 'current-cart', + (err, storedItems) => { + if (err) throw new Error(err); - if (config.cart.synchronize) { - Vue.prototype.$db.cartsCollection.getItem('current-cart-token', (err, token) => { - if (err) throw new Error(err) - // TODO: if token is null create cart server side and store the token! - if (token) { // previously set token - commit(types.CART_LOAD_CART_SERVER_TOKEN, token) - Logger.info('Cart token received from cache.', 'cache', token)() - Logger.info('Pulling cart from server.','cart')() - context.dispatch('serverPull', { forceClientState: false, dryRun: !config.cart.serverMergeByDefault }) - } else { - Logger.info('Creating server cart token', 'cart')() - context.dispatch('serverCreate', { guestCart: false }) - } - }) + if (config.cart.synchronize) { + Vue.prototype.$db.cartsCollection.getItem( + 'current-cart-token', + (err, token) => { + if (err) throw new Error(err); + // TODO: if token is null create cart server side and store the token! + if (token) { + // previously set token + commit(types.CART_LOAD_CART_SERVER_TOKEN, token); + Logger.info( + 'Cart token received from cache.', + 'cache', + token + )(); + Logger.info('Pulling cart from server.', 'cart')(); + context.dispatch('serverPull', { + forceClientState: false, + dryRun: !config.cart.serverMergeByDefault + }); + } else { + Logger.info('Creating server cart token', 'cart')(); + context.dispatch('serverCreate', { guestCart: false }); + } + } + ); + } + commit(types.CART_LOAD_CART, storedItems); + resolve(storedItems); } - commit(types.CART_LOAD_CART, storedItems) - resolve(storedItems) - }) - }) + ); + }); }, // This should be a getter, just sayin - getItem ({ commit, dispatch, state }, sku) { - return state.cartItems.find(p => p.sku === sku) + getItem({ commit, dispatch, state }, sku) { + return state.cartItems.find(p => p.sku === sku); }, - goToCheckout (context) { - router.push(localizedRoute('/checkout', currentStoreView().storeCode)) + goToCheckout(context) { + router.push(localizedRoute('/checkout', currentStoreView().storeCode)); }, - addItem ({ commit, dispatch, state }, { productToAdd, forceServerSilence = false }) { - let productsToAdd = [] - if (productToAdd.type_id === 'grouped') { // TODO: add bundle support - productsToAdd = productToAdd.product_links.filter((pl) => { return pl.link_type === 'associated' }).map((pl) => { return pl.product }) + addItem( + { commit, dispatch, state }, + { productToAdd, forceServerSilence = false } + ) { + let productsToAdd = []; + if (productToAdd.type_id === 'grouped') { + // TODO: add bundle support + productsToAdd = productToAdd.product_links + .filter(pl => { + return pl.link_type === 'associated'; + }) + .map(pl => { + return pl.product; + }); } else { - productsToAdd.push(productToAdd) + productsToAdd.push(productToAdd); } - let productHasBeenAdded = false - let productIndex = 0 + let productHasBeenAdded = false; + let productIndex = 0; for (let product of productsToAdd) { - if (typeof product === 'undefined' || product === null) continue - if (product.qty && typeof product.qty !== 'number') product.qty = parseInt(product.qty) - if ((config.useZeroPriceProduct)? product.priceInclTax < 0 : product.priceInclTax <= 0 ) { + if (typeof product === 'undefined' || product === null) continue; + if (product.qty && typeof product.qty !== 'number') + product.qty = parseInt(product.qty); + if ( + config.useZeroPriceProduct + ? product.priceInclTax < 0 + : product.priceInclTax <= 0 + ) { rootStore.dispatch('notification/spawnNotification', { type: 'error', - message: i18n.t('Product price is unknown, product cannot be added to the cart!'), + message: i18n.t( + 'Product price is unknown, product cannot be added to the cart!' + ), action1: { label: i18n.t('OK') } - }) - continue + }); + continue; } if (config.entities.optimize && config.entities.optimizeShoppingCart) { - product = omit(product, ['configurable_children', 'configurable_options', 'media_gallery', 'description', 'category', 'category_ids', 'product_links', 'stock', 'description']) + product = omit(product, [ + 'configurable_children', + 'configurable_options', + 'media_gallery', + 'description', + 'category', + 'category_ids', + 'product_links', + 'stock', + 'description' + ]); } if (product.errors !== null && typeof product.errors !== 'undefined') { - let productCanBeAdded = true + let productCanBeAdded = true; for (let errKey in product.errors) { if (product.errors[errKey]) { - productCanBeAdded = false + productCanBeAdded = false; rootStore.dispatch('notification/spawnNotification', { type: 'error', message: product.errors[errKey], action1: { label: i18n.t('OK') } - }) + }); } } if (!productCanBeAdded) { - continue + continue; } } - const record = state.cartItems.find(p => p.sku === product.sku) - dispatch('stock/check', { product: product, qty: record ? record.qty + 1 : (product.qty ? product.qty : 1) }, {root: true}).then(result => { - product.onlineStockCheckid = result.onlineCheckTaskId // used to get the online check result + const record = state.cartItems.find(p => p.sku === product.sku); + dispatch( + 'stock/check', + { + product: product, + qty: record ? record.qty + 1 : product.qty ? product.qty : 1 + }, + { root: true } + ).then(result => { + product.onlineStockCheckid = result.onlineCheckTaskId; // used to get the online check result if (result.status === 'volatile') { rootStore.dispatch('notification/spawnNotification', { type: 'warning', - message: i18n.t('The system is not sure about the stock quantity (volatile). Product has been added to the cart for pre-reservation.'), + message: i18n.t( + 'The system is not sure about the stock quantity (volatile). Product has been added to the cart for pre-reservation.' + ), action1: { label: i18n.t('OK') } - }) + }); } if (result.status === 'out_of_stock') { rootStore.dispatch('notification/spawnNotification', { type: 'error', - message: i18n.t('The product is out of stock and cannot be added to the cart!'), + message: i18n.t( + 'The product is out of stock and cannot be added to the cart!' + ), action1: { label: i18n.t('OK') } - }) + }); } if (result.status === 'ok' || result.status === 'volatile') { - commit(types.CART_ADD_ITEM, { product }) - productHasBeenAdded = true + commit(types.CART_ADD_ITEM, { product }); + productHasBeenAdded = true; } - if (productIndex === (productsToAdd.length - 1) && productHasBeenAdded) { + if (productIndex === productsToAdd.length - 1 && productHasBeenAdded) { let notificationData = { type: 'success', message: i18n.t('Product has been added to the cart!'), action1: { label: i18n.t('OK') }, action2: null - } - if (!config.externalCheckout) { // if there is externalCheckout enabled we don't offer action to go to checkout as it can generate cart desync - notificationData.action2 = { label: i18n.t('Proceed to checkout'), action: () => { - dispatch('goToCheckout') - }} + }; + if (!config.externalCheckout) { + // if there is externalCheckout enabled we don't offer action to go to checkout as it can generate cart desync + notificationData.action2 = { + label: i18n.t('Proceed to checkout'), + action: () => { + dispatch('goToCheckout'); + } + }; } if (config.cart.synchronize && !forceServerSilence) { - dispatch('serverPull', { forceClientState: true }) + dispatch('serverPull', { forceClientState: true }); } else { - rootStore.dispatch('notification/spawnNotification', notificationData) + rootStore.dispatch( + 'notification/spawnNotification', + notificationData + ); } } - productIndex++ - }) + productIndex++; + }); } }, - removeItem ({ commit, dispatch }, payload) { - let removeByParentSku = true // backward compatibility call format - let product = payload - if(payload.product) { // new call format since 1.4 - product = payload.product - removeByParentSku = payload.removeByParentSku + removeItem({ commit, dispatch }, payload) { + let removeByParentSku = true; // backward compatibility call format + let product = payload; + if (payload.product) { + // new call format since 1.4 + product = payload.product; + removeByParentSku = payload.removeByParentSku; } - commit(types.CART_DEL_ITEM, { product, removeByParentSku }) + commit(types.CART_DEL_ITEM, { product, removeByParentSku }); if (config.cart.synchronize && product.server_item_id) { - dispatch('serverPull', { forceClientState: true }) + dispatch('serverPull', { forceClientState: true }); } }, - removeNonConfirmedVariants ({ commit, dispatch }, payload) { - let removeByParentSku = true // backward compatibility call format - let product = payload - if(payload.product) { // new call format since 1.4 - product = payload.product - removeByParentSku = payload.removeByParentSku + removeNonConfirmedVariants({ commit, dispatch }, payload) { + let removeByParentSku = true; // backward compatibility call format + let product = payload; + if (payload.product) { + // new call format since 1.4 + product = payload.product; + removeByParentSku = payload.removeByParentSku; } - commit(types.CART_DEL_NON_CONFIRMED_ITEM, { product }) + commit(types.CART_DEL_NON_CONFIRMED_ITEM, { product }); if (config.cart.synchronize && product.server_item_id) { - dispatch('serverPull', { forceClientState: true }) + dispatch('serverPull', { forceClientState: true }); } }, - updateQuantity ({ commit, dispatch }, { product, qty, forceServerSilence = false }) { - commit(types.CART_UPD_ITEM, { product, qty }) - if (config.cart.synchronize && product.server_item_id && !forceServerSilence) { - dispatch('serverPull', { forceClientState: true }) + updateQuantity( + { commit, dispatch }, + { product, qty, forceServerSilence = false } + ) { + commit(types.CART_UPD_ITEM, { product, qty }); + if ( + config.cart.synchronize && + product.server_item_id && + !forceServerSilence + ) { + dispatch('serverPull', { forceClientState: true }); } }, - updateItem ({ commit }, { product }) { - commit(types.CART_UPD_ITEM_PROPS, { product }) + updateItem({ commit }, { product }) { + commit(types.CART_UPD_ITEM_PROPS, { product }); }, - getPaymentMethods (context) { - if (config.cart.synchronize_totals && onlineHelper.isOnline && context.state.cartServerToken) { - TaskQueue.execute({ url: config.cart.paymentmethods_endpoint, + getPaymentMethods(context) { + if ( + config.cart.synchronize_totals && + onlineHelper.isOnline && + context.state.cartServerToken + ) { + TaskQueue.execute({ + url: config.cart.paymentmethods_endpoint, payload: { method: 'GET', headers: { 'Content-Type': 'application/json' }, mode: 'cors' }, silent: true - }).then((task: any) => { - let backendMethods = task.result - let paymentMethods = context.rootGetters['payment/paymentMethods'].slice(0).filter((itm) => { - return (typeof itm !== 'object' || !itm.is_server_method) - }) // copy - let uniqueBackendMethods = [] - for (let i = 0; i < backendMethods.length; i++) { - if (typeof backendMethods[i] === 'object' && !paymentMethods.find(item => item.code === backendMethods[i].code)) { - backendMethods[i].is_server_method = true - paymentMethods.push(backendMethods[i]) - uniqueBackendMethods.push(backendMethods[i]) - } - } - rootStore.dispatch('payment/replaceMethods', paymentMethods, { root: true }) - Vue.prototype.$bus.$emit('set-unique-payment-methods', uniqueBackendMethods) - }).catch(e => { - Logger.error(e, 'cart')() }) + .then((task: any) => { + let backendMethods = task.result; + let paymentMethods = context.rootGetters['payment/paymentMethods'] + .slice(0) + .filter(itm => { + return typeof itm !== 'object' || !itm.is_server_method; + }); // copy + let uniqueBackendMethods = []; + for (let i = 0; i < backendMethods.length; i++) { + if ( + typeof backendMethods[i] === 'object' && + !paymentMethods.find(item => item.code === backendMethods[i].code) + ) { + backendMethods[i].is_server_method = true; + paymentMethods.push(backendMethods[i]); + uniqueBackendMethods.push(backendMethods[i]); + } + } + rootStore.dispatch('payment/replaceMethods', paymentMethods, { + root: true + }); + Vue.prototype.$bus.$emit( + 'set-unique-payment-methods', + uniqueBackendMethods + ); + }) + .catch(e => { + Logger.error(e, 'cart')(); + }); } }, - getShippingMethods (context, address) { + getShippingMethods(context, address) { return new Promise((resolve, reject) => { - if (config.cart.synchronize_totals && onlineHelper.isOnline && context.state.cartServerToken) { - TaskQueue.execute({ url: config.cart.shippingmethods_endpoint, + if ( + config.cart.synchronize_totals && + onlineHelper.isOnline && + context.state.cartServerToken + ) { + TaskQueue.execute({ + url: config.cart.shippingmethods_endpoint, payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -376,43 +552,61 @@ const actions: ActionTree = { }) }, silent: true - }).then((task: any) => { - if (task.result.length > 0) { - rootStore.dispatch('shipping/replaceMethods', task.result, { root: true }) - resolve(task.result) - } - }).catch(e => { - Logger.error(e, 'cart')() - reject(e) }) + .then((task: any) => { + if (task.result.length > 0) { + rootStore.dispatch('shipping/replaceMethods', task.result, { + root: true + }); + resolve(task.result); + } + }) + .catch(e => { + Logger.error(e, 'cart')(); + reject(e); + }); } - }) + }); }, - refreshTotals (context, methodsData) { + refreshTotals(context, methodsData) { return new Promise((resolve, reject) => { - const storeView = currentStoreView() - if (config.cart.synchronize_totals && onlineHelper.isOnline && context.state.cartServerToken) { + const storeView = currentStoreView(); + if ( + config.cart.synchronize_totals && + onlineHelper.isOnline && + context.state.cartServerToken + ) { if (!methodsData) { - let country = rootStore.state.checkout.shippingDetails.country ? rootStore.state.checkout.shippingDetails.country : storeView.tax.defaultCountry - const shippingMethods = context.rootGetters['shipping/shippingMethods'] - const paymentMethods = context.rootGetters['payment/paymentMethods'] - let shipping = shippingMethods && Array.isArray(shippingMethods) ? shippingMethods.find(item => item.default) : null - let payment = paymentMethods && Array.isArray(paymentMethods) ? paymentMethods.find(item => item.default) : null + let country = rootStore.state.checkout.shippingDetails.country + ? rootStore.state.checkout.shippingDetails.country + : storeView.tax.defaultCountry; + const shippingMethods = + context.rootGetters['shipping/shippingMethods']; + const paymentMethods = context.rootGetters['payment/paymentMethods']; + let shipping = + shippingMethods && Array.isArray(shippingMethods) + ? shippingMethods.find(item => item.default) + : null; + let payment = + paymentMethods && Array.isArray(paymentMethods) + ? paymentMethods.find(item => item.default) + : null; if (!shipping && shippingMethods && shippingMethods.length > 0) { - shipping = shippingMethods[0] + shipping = shippingMethods[0]; } if (!payment && paymentMethods && paymentMethods.length > 0) { - payment = paymentMethods[0] + payment = paymentMethods[0]; } methodsData = { country: country, method_code: shipping ? shipping.method_code : null, carrier_code: shipping ? shipping.carrier_code : null, payment_method: payment.code - } + }; } if (methodsData.country && methodsData.carrier_code) { - TaskQueue.execute({ url: config.cart.shippinginfo_endpoint, + TaskQueue.execute({ + url: config.cart.shippinginfo_endpoint, payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -429,279 +623,482 @@ const actions: ActionTree = { }, silent: true, callback_event: 'store:cart/servercartAfterTotals' - }).then((task : any) => { - if (task.result) { - resolve(task.result) - } - }).catch(e => { - Logger.error(e, 'cart')() - reject(e) }) + .then((task: any) => { + if (task.result) { + resolve(task.result); + } + }) + .catch(e => { + Logger.error(e, 'cart')(); + reject(e); + }); } else { - context.dispatch('cart/serverTotals', {}, { root: true }) - resolve() + context.dispatch('cart/serverTotals', {}, { root: true }); + resolve(); } } - }) + }); }, - removeCoupon (context) { + removeCoupon(context) { return new Promise((resolve, reject) => { if (config.cart.synchronize_totals && onlineHelper.isOnline) { - TaskQueue.execute({ url: config.cart.deletecoupon_endpoint, + TaskQueue.execute({ + url: config.cart.deletecoupon_endpoint, payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, mode: 'cors' }, silent: true - }).then((task : any) => { - if (task.result) { - context.dispatch('refreshTotals') - resolve(task.result) - } - }).catch(e => { - Logger.error(e, 'cart')() - reject(e) }) + .then((task: any) => { + if (task.result) { + context.dispatch('refreshTotals'); + resolve(task.result); + } + }) + .catch(e => { + Logger.error(e, 'cart')(); + reject(e); + }); } }); }, - applyCoupon (context, couponCode) { + applyCoupon(context, couponCode) { return new Promise((resolve, reject) => { if (config.cart.synchronize_totals && onlineHelper.isOnline) { - TaskQueue.execute({ url: config.cart.applycoupon_endpoint.replace('{{coupon}}', couponCode), + TaskQueue.execute({ + url: config.cart.applycoupon_endpoint.replace( + '{{coupon}}', + couponCode + ), payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, mode: 'cors' }, silent: true - }).then((task:any) => { - if (task.result === true) { - context.dispatch('refreshTotals') - resolve(task.result) - } else { - reject(false) - } - }).catch(e => { - Logger.log(e, 'cart')() - reject(e) }) + .then((task: any) => { + if (task.result === true) { + context.dispatch('refreshTotals'); + resolve(task.result); + } else { + reject(false); + } + }) + .catch(e => { + Logger.log(e, 'cart')(); + reject(e); + }); } - }) + }); }, - userAfterLoggedin () { - Vue.prototype.$db.usersCollection.getItem('last-cart-bypass-ts', (err, lastCartBypassTs) => { - if (err) { - Logger.error(err, 'cart')() - } - if (!config.cart.bypassCartLoaderForAuthorizedUsers || (Date.now() - lastCartBypassTs) >= (1000 * 60 * 24)) { // don't refresh the shopping cart id up to 24h after last order - rootStore.dispatch('cart/serverCreate', { guestCart: false }, { root: true }) + userAfterLoggedin() { + Vue.prototype.$db.usersCollection.getItem( + 'last-cart-bypass-ts', + (err, lastCartBypassTs) => { + if (err) { + Logger.error(err, 'cart')(); + } + if ( + !config.cart.bypassCartLoaderForAuthorizedUsers || + Date.now() - lastCartBypassTs >= 1000 * 60 * 24 + ) { + // don't refresh the shopping cart id up to 24h after last order + rootStore.dispatch( + 'cart/serverCreate', + { guestCart: false }, + { root: true } + ); + } } - }) + ); }, - servercartAfterCreated (context, event) { - const cartToken = event.result + servercartAfterCreated(context, event) { + const cartToken = event.result; if (event.resultCode === 200) { - Logger.info('Server cart token created.', 'cart', cartToken)() - rootStore.commit(types.SN_CART + '/' + types.CART_LOAD_CART_SERVER_TOKEN, cartToken) - rootStore.dispatch('cart/serverPull', { forceClientState: false, dryRun: !config.cart.serverMergeByDefault }, { root: true }) + Logger.info('Server cart token created.', 'cart', cartToken)(); + rootStore.commit( + types.SN_CART + '/' + types.CART_LOAD_CART_SERVER_TOKEN, + cartToken + ); + rootStore.dispatch( + 'cart/serverPull', + { forceClientState: false, dryRun: !config.cart.serverMergeByDefault }, + { root: true } + ); } else { - let resultString = event.result ? toString(event.result) : null - if (resultString && (resultString.indexOf(i18n.t('not authorized')) < 0 && resultString.indexOf('not authorized')) < 0) { // not respond to unathorized errors here + let resultString = event.result ? toString(event.result) : null; + if ( + resultString && + (resultString.indexOf(i18n.t('not authorized')) < 0 && + resultString.indexOf('not authorized')) < 0 + ) { + // not respond to unathorized errors here if (rootStore.state.cart.bypassCount < MAX_BYPASS_COUNT) { - Logger.log('Bypassing with guest cart' + rootStore.state.cart.bypassCount, 'cart')() - rootStore.state.cart.bypassCount = rootStore.state.cart.bypassCount + 1 - rootStore.dispatch('cart/serverCreate', { guestCart: true }, { root: true }) - Logger.error(event.result, 'cart')() + Logger.log( + 'Bypassing with guest cart' + rootStore.state.cart.bypassCount, + 'cart' + )(); + rootStore.state.cart.bypassCount = + rootStore.state.cart.bypassCount + 1; + rootStore.dispatch( + 'cart/serverCreate', + { guestCart: true }, + { root: true } + ); + Logger.error(event.result, 'cart')(); } } } }, - servercartAfterTotals (context, event) { + servercartAfterTotals(context, event) { if (event.resultCode === 200) { - const totalsObj = event.result.totals ? event.result.totals : event.result - Logger.info('Overriding server totals. ', 'cart', totalsObj)() - let itemsAfterTotal = {} - let platformTotalSegments = totalsObj.total_segments + const totalsObj = event.result.totals + ? event.result.totals + : event.result; + Logger.info('Overriding server totals. ', 'cart', totalsObj)(); + let itemsAfterTotal = {}; + let platformTotalSegments = totalsObj.total_segments; for (let item of totalsObj.items) { - if (item.options && isString(item.options)) item.options = JSON.parse(item.options) - itemsAfterTotal[item.item_id] = item - rootStore.dispatch('cart/updateItem', { product: { server_item_id: item.item_id, totals: item, qty: item.qty } }, { root: true }) // update the server_id reference + if (item.options && isString(item.options)) + item.options = JSON.parse(item.options); + itemsAfterTotal[item.item_id] = item; + rootStore.dispatch( + 'cart/updateItem', + { + product: { + server_item_id: item.item_id, + totals: item, + qty: item.qty + } + }, + { root: true } + ); // update the server_id reference } - rootStore.commit(types.SN_CART + '/' + types.CART_UPD_TOTALS, { itemsAfterTotal: itemsAfterTotal, totals: totalsObj, platformTotalSegments: platformTotalSegments }) + rootStore.commit(types.SN_CART + '/' + types.CART_UPD_TOTALS, { + itemsAfterTotal: itemsAfterTotal, + totals: totalsObj, + platformTotalSegments: platformTotalSegments + }); } else { - Logger.error(event.result, 'cart')() + Logger.error(event.result, 'cart')(); } }, - servercartAfterPulled (context, event) { + servercartAfterPulled(context, event) { if (event.resultCode === 200) { - let diffLog = [] - let serverCartUpdateRequired = false - let clientCartUpdateRequired = false - let cartHasItems = false - let clientCartAddItems = [] - let productActionOptions = ((serverItem) => { + let diffLog = []; + let serverCartUpdateRequired = false; + let clientCartUpdateRequired = false; + let cartHasItems = false; + let clientCartAddItems = []; + let productActionOptions = serverItem => { return new Promise(resolve => { if (serverItem.product_type === 'configurable') { - let searchQuery = new SearchQuery() - searchQuery = searchQuery.applyFilter({key: 'configurable_children.sku', value: {'eq': serverItem.sku}}) - rootStore.dispatch('product/list', {query: searchQuery, start: 0, size: 1, updateState: false}).then((resp) => { - if (resp.items.length >= 1) { - resolve({ sku: resp.items[0].sku, childSku: serverItem.sku }) - } - }) + let searchQuery = new SearchQuery(); + searchQuery = searchQuery.applyFilter({ + key: 'configurable_children.sku', + value: { eq: serverItem.sku } + }); + rootStore + .dispatch('product/list', { + query: searchQuery, + start: 0, + size: 1, + updateState: false + }) + .then(resp => { + if (resp.items.length >= 1) { + resolve({ sku: resp.items[0].sku, childSku: serverItem.sku }); + } + }); } else { - resolve({ sku: serverItem.sku }) + resolve({ sku: serverItem.sku }); } - }) - }) - const serverItems = event.result - const clientItems = rootStore.state.cart.cartItems + }); + }; + const serverItems = event.result; + const clientItems = rootStore.state.cart.cartItems; for (const clientItem of clientItems) { - cartHasItems = true - const serverItem = serverItems.find((itm) => { - return itm.sku === clientItem.sku || itm.sku.indexOf(clientItem.sku + '-') === 0 /* bundle products */ - }) + cartHasItems = true; + const serverItem = serverItems.find(itm => { + return ( + itm.sku === clientItem.sku || + itm.sku.indexOf(clientItem.sku + '-') === 0 + ); /* bundle products */ + }); if (!serverItem) { - Logger.warn('No server item with sku ' + clientItem.sku + ' on stock.', 'cart')() - diffLog.push({ 'party': 'server', 'sku': clientItem.sku, 'status': 'no_item' }) + Logger.warn( + 'No server item with sku ' + clientItem.sku + ' on stock.', + 'cart' + )(); + diffLog.push({ + party: 'server', + sku: clientItem.sku, + status: 'no_item' + }); if (!event.dry_run) { - if (event.force_client_state || !config.cart.serverSyncCanRemoveLocalItems) { - rootStore.dispatch('cart/serverUpdateItem', { - sku: clientItem.parentSku && config.cart.setConfigurableProductOptions ? clientItem.parentSku : clientItem.sku, - qty: clientItem.qty, - product_option: clientItem.product_option - }, { root: true }).then((event) => { - _afterServerItemUpdated(event, clientItem) - }) - serverCartUpdateRequired = true + if ( + event.force_client_state || + !config.cart.serverSyncCanRemoveLocalItems + ) { + rootStore + .dispatch( + 'cart/serverUpdateItem', + { + sku: + clientItem.parentSku && + config.cart.setConfigurableProductOptions + ? clientItem.parentSku + : clientItem.sku, + qty: clientItem.qty, + product_option: clientItem.product_option + }, + { root: true } + ) + .then(event => { + _afterServerItemUpdated(event, clientItem); + }); + serverCartUpdateRequired = true; } else { - rootStore.dispatch('cart/removeItem', { - product: clientItem - }, { root: true }) + rootStore.dispatch( + 'cart/removeItem', + { + product: clientItem + }, + { root: true } + ); } } } else if (serverItem.qty !== clientItem.qty) { - Logger.log('Wrong qty for ' + clientItem.sku, clientItem.qty, serverItem.qty)() - diffLog.push({ 'party': 'server', 'sku': clientItem.sku, 'status': 'wrong_qty', 'client_qty': clientItem.qty, 'server_qty': serverItem.qty }) + Logger.log( + 'Wrong qty for ' + clientItem.sku, + clientItem.qty, + serverItem.qty + )(); + diffLog.push({ + party: 'server', + sku: clientItem.sku, + status: 'wrong_qty', + client_qty: clientItem.qty, + server_qty: serverItem.qty + }); if (!event.dry_run) { - if (event.force_client_state || !config.cart.serverSyncCanModifyLocalItems) { - rootStore.dispatch('cart/serverUpdateItem', { - sku: clientItem.parentSku && config.cart.setConfigurableProductOptions ? clientItem.parentSku : clientItem.sku, - qty: clientItem.qty, - item_id: serverItem.item_id, - quoteId: serverItem.quote_id, - product_option: clientItem.product_option - }, { root: true }).then((event) => { - _afterServerItemUpdated(event, clientItem) - }) - serverCartUpdateRequired = true + if ( + event.force_client_state || + !config.cart.serverSyncCanModifyLocalItems + ) { + rootStore + .dispatch( + 'cart/serverUpdateItem', + { + sku: + clientItem.parentSku && + config.cart.setConfigurableProductOptions + ? clientItem.parentSku + : clientItem.sku, + qty: clientItem.qty, + item_id: serverItem.item_id, + quoteId: serverItem.quote_id, + product_option: clientItem.product_option + }, + { root: true } + ) + .then(event => { + _afterServerItemUpdated(event, clientItem); + }); + serverCartUpdateRequired = true; } else { - rootStore.dispatch('cart/updateItem', { - product: serverItem - }, { root: true }) + rootStore.dispatch( + 'cart/updateItem', + { + product: serverItem + }, + { root: true } + ); } } } else { - Logger.info('Server and client item with SKU ' + clientItem.sku + ' synced. Updating cart.', 'cart', 'cart')() + Logger.info( + 'Server and client item with SKU ' + + clientItem.sku + + ' synced. Updating cart.', + 'cart', + 'cart' + )(); // Logger.log('Updating server id to ', { sku: clientItem.sku, server_cart_id: serverItem.quote_id, server_item_id: serverItem.item_id, product_option: serverItem.product_option })() if (!event.dry_run) { - rootStore.dispatch('cart/updateItem', { product: { sku: clientItem.sku, server_cart_id: serverItem.quote_id, server_item_id: serverItem.item_id, product_option: serverItem.product_option } }, { root: true }) + rootStore.dispatch( + 'cart/updateItem', + { + product: { + sku: clientItem.sku, + server_cart_id: serverItem.quote_id, + server_item_id: serverItem.item_id, + product_option: serverItem.product_option + } + }, + { root: true } + ); } } } for (const serverItem of serverItems) { if (serverItem) { - const clientItem = clientItems.find((itm) => { - return itm.sku === serverItem.sku || serverItem.sku.indexOf(itm.sku + '-') === 0 /* bundle products */ - }) + const clientItem = clientItems.find(itm => { + return ( + itm.sku === serverItem.sku || + serverItem.sku.indexOf(itm.sku + '-') === 0 + ); /* bundle products */ + }); if (!clientItem) { - Logger.info('No client item for' + serverItem.sku, 'cart')() - diffLog.push({ 'party': 'client', 'sku': serverItem.sku, 'status': 'no_item' }) + Logger.info('No client item for' + serverItem.sku, 'cart')(); + diffLog.push({ + party: 'client', + sku: serverItem.sku, + status: 'no_item' + }); if (!event.dry_run) { if (event.force_client_state) { - Logger.info('Removing product from cart', 'cart', serverItem)() + Logger.info('Removing product from cart', 'cart', serverItem)(); - Logger.log('Removing item' + serverItem.sku + serverItem.item_id, 'cart')() - serverCartUpdateRequired = true - rootStore.dispatch('cart/serverDeleteItem', { - sku: serverItem.sku, - item_id: serverItem.item_id, - quoteId: serverItem.quote_id - }, { root: true }) + Logger.log( + 'Removing item' + serverItem.sku + serverItem.item_id, + 'cart' + )(); + serverCartUpdateRequired = true; + rootStore.dispatch( + 'cart/serverDeleteItem', + { + sku: serverItem.sku, + item_id: serverItem.item_id, + quoteId: serverItem.quote_id + }, + { root: true } + ); } else { clientCartAddItems.push( new Promise(resolve => { - productActionOptions(serverItem).then((actionOtions) => { - rootStore.dispatch('product/single', { options: actionOtions, assignDefaultVariant: true, setCurrentProduct: false, selectDefaultVariant: false }).then((product) => { - resolve({ product: product, serverItem: serverItem }) - }) - }) + productActionOptions(serverItem).then(actionOtions => { + rootStore + .dispatch('product/single', { + options: actionOtions, + assignDefaultVariant: true, + setCurrentProduct: false, + selectDefaultVariant: false + }) + .then(product => { + resolve({ product: product, serverItem: serverItem }); + }); + }); }) - ) + ); } } } } } if (clientCartAddItems.length) { - clientCartUpdateRequired = true - cartHasItems = true + clientCartUpdateRequired = true; + cartHasItems = true; } - Promise.all(clientCartAddItems).then((items) => { + Promise.all(clientCartAddItems).then(items => { items.map(({ product, serverItem }) => { - product.server_item_id = serverItem.item_id - product.qty = serverItem.qty - product.server_cart_id = serverItem.quote_id + product.server_item_id = serverItem.item_id; + product.qty = serverItem.qty; + product.server_cart_id = serverItem.quote_id; if (serverItem.product_option) { - product.product_option = serverItem.product_option + product.product_option = serverItem.product_option; } - rootStore.dispatch('cart/addItem', { productToAdd: product, forceServerSilence: true }).then(() => { - // rootStore.dispatch('cart/updateItem', { product: product }) - }) - }) - }) + rootStore + .dispatch('cart/addItem', { + productToAdd: product, + forceServerSilence: true + }) + .then(() => { + // rootStore.dispatch('cart/updateItem', { product: product }) + }); + }); + }); if (!event.dry_run) { - if ((!serverCartUpdateRequired || clientCartUpdateRequired) && cartHasItems) { - rootStore.dispatch('cart/refreshTotals') + if ( + (!serverCartUpdateRequired || clientCartUpdateRequired) && + cartHasItems + ) { + rootStore.dispatch('cart/refreshTotals'); } } - Vue.prototype.$bus.$emit('servercart-after-diff', { diffLog: diffLog, serverItems: serverItems, clientItems: clientItems, dryRun: event.dry_run, event: event }) // send the difflog - Logger.info('Client/Server cart synchronised ', 'cart', diffLog)() + Vue.prototype.$bus.$emit('servercart-after-diff', { + diffLog: diffLog, + serverItems: serverItems, + clientItems: clientItems, + dryRun: event.dry_run, + event: event + }); // send the difflog + Logger.info('Client/Server cart synchronised ', 'cart', diffLog)(); } else { - Logger.error(event.result, 'cart') // override with guest cart() + Logger.error(event.result, 'cart'); // override with guest cart() if (rootStore.state.cart.bypassCount < MAX_BYPASS_COUNT) { - Logger.log('Bypassing with guest cart' + rootStore.state.cart.bypassCount, 'cart')() - rootStore.state.cart.bypassCount = rootStore.state.cart.bypassCount + 1 - rootStore.dispatch('cart/serverCreate', { guestCart: true }, { root: true }) - Logger.error(event.result, 'cart')() + Logger.log( + 'Bypassing with guest cart' + rootStore.state.cart.bypassCount, + 'cart' + )(); + rootStore.state.cart.bypassCount = rootStore.state.cart.bypassCount + 1; + rootStore.dispatch( + 'cart/serverCreate', + { guestCart: true }, + { root: true } + ); + Logger.error(event.result, 'cart')(); } } }, - servercartAfterItemUpdated (context, event) { - const originalCartItem = JSON.parse(event.payload.body).cartItem + servercartAfterItemUpdated(context, event) { + const originalCartItem = JSON.parse(event.payload.body).cartItem; if (event.resultCode !== 200) { // TODO: add the strategy to configure behaviour if the product is (confirmed) out of the stock if (originalCartItem.item_id) { - rootStore.dispatch('cart/getItem', originalCartItem.sku, { root: true }).then((cartItem) => { - if (cartItem) { - Logger.log('Restoring qty after error' + originalCartItem.sku + cartItem.prev_qty, 'cart')() - if (cartItem.prev_qty > 0) { - rootStore.dispatch('cart/updateItem', { product: { qty: cartItem.prev_qty } }, { root: true }) // update the server_id reference - Vue.prototype.$bus.$emit('cart-after-itemchanged', { item: cartItem }) - } else { - rootStore.dispatch('cart/removeItem', { product: cartItem, removeByParentSku: false }, { root: true }) // update the server_id reference + rootStore + .dispatch('cart/getItem', originalCartItem.sku, { root: true }) + .then(cartItem => { + if (cartItem) { + Logger.log( + 'Restoring qty after error' + + originalCartItem.sku + + cartItem.prev_qty, + 'cart' + )(); + if (cartItem.prev_qty > 0) { + rootStore.dispatch( + 'cart/updateItem', + { product: { qty: cartItem.prev_qty } }, + { root: true } + ); // update the server_id reference + Vue.prototype.$bus.$emit('cart-after-itemchanged', { + item: cartItem + }); + } else { + rootStore.dispatch( + 'cart/removeItem', + { product: cartItem, removeByParentSku: false }, + { root: true } + ); // update the server_id reference + } } - } - }) + }); } else { - Logger.warn('Removing product from cart', 'cart', originalCartItem)() - rootStore.commit('cart/' + types.CART_DEL_NON_CONFIRMED_ITEM, { product: originalCartItem }, {root: true}) + Logger.warn('Removing product from cart', 'cart', originalCartItem)(); + rootStore.commit( + 'cart/' + types.CART_DEL_NON_CONFIRMED_ITEM, + { product: originalCartItem }, + { root: true } + ); } } else { let notificationData = { @@ -709,20 +1106,23 @@ const actions: ActionTree = { message: i18n.t('Product has been added to the cart!'), action1: { label: i18n.t('OK') }, action2: null + }; + if (!config.externalCheckout) { + // if there is externalCheckout enabled we don't offer action to go to checkout as it can generate cart desync + notificationData.action2 = { + label: i18n.t('Proceed to checkout'), + action: () => { + context.dispatch('goToCheckout'); + } + }; } - if (!config.externalCheckout) { // if there is externalCheckout enabled we don't offer action to go to checkout as it can generate cart desync - notificationData.action2 = { label: i18n.t('Proceed to checkout'), action: () => { - context.dispatch('goToCheckout') - }} - } - rootStore.dispatch('notification/spawnNotification', notificationData) + rootStore.dispatch('notification/spawnNotification', notificationData); } }, - toggleMicrocart ({ commit }) { - commit(types.CART_TOGGLE_MICROCART) + toggleMicrocart({ commit }) { + commit(types.CART_TOGGLE_MICROCART); }, - servercartAfterItemDeleted (context, event) { - } -} + servercartAfterItemDeleted(context, event) {} +}; -export default actions +export default actions; diff --git a/core/modules/cart/store/getters.ts b/core/modules/cart/store/getters.ts index 6d9962e893..e740a00357 100644 --- a/core/modules/cart/store/getters.ts +++ b/core/modules/cart/store/getters.ts @@ -1,74 +1,83 @@ -import { GetterTree } from 'vuex' -import sumBy from 'lodash-es/sumBy' -import i18n from '@vue-storefront/i18n' -import CartState from '../types/CartState' -import RootState from '@vue-storefront/core/types/RootState' -import AppliedCoupon from '../types/AppliedCoupon' -import { onlineHelper } from '@vue-storefront/core/helpers' +import { GetterTree } from 'vuex'; +import sumBy from 'lodash-es/sumBy'; +import i18n from '@vue-storefront/i18n'; +import CartState from '../types/CartState'; +import RootState from '@vue-storefront/core/types/RootState'; +import AppliedCoupon from '../types/AppliedCoupon'; +import { onlineHelper } from '@vue-storefront/core/helpers'; const getters: GetterTree = { - totals (state) { + totals(state) { if (state.platformTotalSegments && onlineHelper.isOnline) { - return state.platformTotalSegments + return state.platformTotalSegments; } else { - let shipping = state.shipping instanceof Array ? state.shipping[0] : state.shipping - let payment = state.payment instanceof Array ? state.payment[0] : state.payment + let shipping = + state.shipping instanceof Array ? state.shipping[0] : state.shipping; + let payment = + state.payment instanceof Array ? state.payment[0] : state.payment; const totalsArray = [ - { - code: 'subtotalInclTax', - title: i18n.t('Subtotal incl. tax'), - value: sumBy(state.cartItems, (p) => { - return p.qty * p.priceInclTax - }) - }, - { - code: 'grand_total', - title: i18n.t('Grand total'), - value: sumBy(state.cartItems, (p) => { - return p.qty * p.priceInclTax + (shipping ? shipping.price_incl_tax : 0) - }) - } - ] + { + code: 'subtotalInclTax', + title: i18n.t('Subtotal incl. tax'), + value: sumBy(state.cartItems, p => { + return p.qty * p.priceInclTax; + }) + }, + { + code: 'grand_total', + title: i18n.t('Grand total'), + value: sumBy(state.cartItems, p => { + return ( + p.qty * p.priceInclTax + (shipping ? shipping.price_incl_tax : 0) + ); + }) + } + ]; if (payment) { totalsArray.push({ code: 'payment', title: i18n.t(payment.title), value: payment.costInclTax - }) + }); } if (shipping) { totalsArray.push({ code: 'shipping', title: i18n.t(shipping.method_title), value: shipping.price_incl_tax - }) + }); } - return totalsArray + return totalsArray; } }, - totalQuantity (state, getters, rootStore) { + totalQuantity(state, getters, rootStore) { if (rootStore.config.cart.minicartCountType === 'items') { - return state.cartItems.length + return state.cartItems.length; } - return sumBy(state.cartItems, (p) => { - return p.qty - }) + return sumBy(state.cartItems, p => { + return p.qty; + }); }, - coupon (state) : AppliedCoupon | false { - if (!(state.platformTotals && state.platformTotals.hasOwnProperty('coupon_code'))) { - return false + coupon(state): AppliedCoupon | false { + if ( + !( + state.platformTotals && + state.platformTotals.hasOwnProperty('coupon_code') + ) + ) { + return false; } return { code: state.platformTotals.coupon_code, discount: state.platformTotals.discount_amount - } + }; }, - isVirtualCart (state) { - return state.cartItems.every((itm) => { - return itm.type_id === 'downloadable' || itm.type_id === 'virtual' // check for downloadable & virtual products - }) + isVirtualCart(state) { + return state.cartItems.every(itm => { + return itm.type_id === 'downloadable' || itm.type_id === 'virtual'; // check for downloadable & virtual products + }); } -} +}; -export default getters \ No newline at end of file +export default getters; diff --git a/core/modules/cart/store/index.ts b/core/modules/cart/store/index.ts index c4068983de..67a94646e5 100644 --- a/core/modules/cart/store/index.ts +++ b/core/modules/cart/store/index.ts @@ -1,8 +1,8 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import CartState from '../types/CartState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import CartState from '../types/CartState'; export const module: Module = { namespaced: true, @@ -28,6 +28,5 @@ export const module: Module = { }, getters, actions, - mutations, -} - + mutations +}; diff --git a/core/modules/cart/store/mutation-types.ts b/core/modules/cart/store/mutation-types.ts index 34bc34d446..e7d77bc7f2 100644 --- a/core/modules/cart/store/mutation-types.ts +++ b/core/modules/cart/store/mutation-types.ts @@ -1,13 +1,13 @@ -export const SN_CART = 'cart' -export const CART_ADD_ITEM = SN_CART + '/ADD' -export const CART_DEL_ITEM = SN_CART + '/DEL' -export const CART_DEL_NON_CONFIRMED_ITEM = SN_CART + '/DEL_NONCONFIRMED' -export const CART_UPD_ITEM = SN_CART + '/UPD' -export const CART_LOAD_CART = SN_CART + '/LOAD' -export const CART_UPD_SHIPPING = SN_CART + '/SHIPPING' -export const CART_SAVE = SN_CART + '/SAVE' -export const CART_UPD_ITEM_PROPS = SN_CART + '/UPD_PROPS' -export const CART_UPD_TOTALS = SN_CART + '/UPD_TOTALS' -export const CART_LOAD_CART_SERVER_TOKEN = SN_CART + '/SRV_TOKEN' -export const CART_UPD_PAYMENT = SN_CART + '/UPD_PAYMENT' -export const CART_TOGGLE_MICROCART = SN_CART + '/TOGGLE_MICROCART' \ No newline at end of file +export const SN_CART = 'cart'; +export const CART_ADD_ITEM = SN_CART + '/ADD'; +export const CART_DEL_ITEM = SN_CART + '/DEL'; +export const CART_DEL_NON_CONFIRMED_ITEM = SN_CART + '/DEL_NONCONFIRMED'; +export const CART_UPD_ITEM = SN_CART + '/UPD'; +export const CART_LOAD_CART = SN_CART + '/LOAD'; +export const CART_UPD_SHIPPING = SN_CART + '/SHIPPING'; +export const CART_SAVE = SN_CART + '/SAVE'; +export const CART_UPD_ITEM_PROPS = SN_CART + '/UPD_PROPS'; +export const CART_UPD_TOTALS = SN_CART + '/UPD_TOTALS'; +export const CART_LOAD_CART_SERVER_TOKEN = SN_CART + '/SRV_TOKEN'; +export const CART_UPD_PAYMENT = SN_CART + '/UPD_PAYMENT'; +export const CART_TOGGLE_MICROCART = SN_CART + '/TOGGLE_MICROCART'; diff --git a/core/modules/cart/store/mutations.ts b/core/modules/cart/store/mutations.ts index 24f129188e..41444fc39b 100644 --- a/core/modules/cart/store/mutations.ts +++ b/core/modules/cart/store/mutations.ts @@ -1,94 +1,118 @@ -import Vue from 'vue' -import { MutationTree } from 'vuex' -import rootStore from '@vue-storefront/core/store' -import * as types from './mutation-types' -import CartState from '../types/CartState' +import Vue from 'vue'; +import { MutationTree } from 'vuex'; +import rootStore from '@vue-storefront/core/store'; +import * as types from './mutation-types'; +import CartState from '../types/CartState'; const mutations: MutationTree = { /** * Add product to cart * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ - [types.CART_ADD_ITEM] (state, { product }) { - const record = state.cartItems.find(p => p.sku === product.sku) + [types.CART_ADD_ITEM](state, { product }) { + const record = state.cartItems.find(p => p.sku === product.sku); if (!record) { let item = { ...product, qty: parseInt(product.qty ? product.qty : 1) - } - Vue.prototype.$bus.$emit('cart-before-add', { product: item }) - state.cartItems.push(item) + }; + Vue.prototype.$bus.$emit('cart-before-add', { product: item }); + state.cartItems.push(item); } else { - Vue.prototype.$bus.$emit('cart-before-update', { product: record }) - record.qty += parseInt((product.qty ? product.qty : 1)) + Vue.prototype.$bus.$emit('cart-before-update', { product: record }); + record.qty += parseInt(product.qty ? product.qty : 1); } }, - [types.CART_SAVE] (state) { - Vue.prototype.$bus.$emit('cart-before-save', { items: state.cartItems }) - state.cartSavedAt = Date.now() + [types.CART_SAVE](state) { + Vue.prototype.$bus.$emit('cart-before-save', { items: state.cartItems }); + state.cartSavedAt = Date.now(); }, - [types.CART_DEL_ITEM] (state, { product, removeByParentSku = true }) { - Vue.prototype.$bus.$emit('cart-before-delete', { items: state.cartItems }) - state.cartItems = state.cartItems.filter(p => p.sku !== product.sku && (p.parentSku !== product.sku || removeByParentSku === false)) - Vue.prototype.$bus.$emit('cart-after-delete', { items: state.cartItems }) - state.cartSavedAt = Date.now() + [types.CART_DEL_ITEM](state, { product, removeByParentSku = true }) { + Vue.prototype.$bus.$emit('cart-before-delete', { items: state.cartItems }); + state.cartItems = state.cartItems.filter( + p => + p.sku !== product.sku && + (p.parentSku !== product.sku || removeByParentSku === false) + ); + Vue.prototype.$bus.$emit('cart-after-delete', { items: state.cartItems }); + state.cartSavedAt = Date.now(); }, - [types.CART_DEL_NON_CONFIRMED_ITEM] (state, { product, removeByParentSku = true }) { - Vue.prototype.$bus.$emit('cart-before-delete', { items: state.cartItems }) - state.cartItems = state.cartItems.filter(p => (p.sku !== product.sku && (p.parentSku !== product.sku || removeByParentSku === false)) || p.server_item_id/* it's confirmed if server_item_id is set */) - Vue.prototype.$bus.$emit('cart-after-delete', { items: state.cartItems }) - state.cartSavedAt = Date.now() - }, - [types.CART_UPD_ITEM] (state, { product, qty }) { - const record = state.cartItems.find(p => p.sku === product.sku) + [types.CART_DEL_NON_CONFIRMED_ITEM]( + state, + { product, removeByParentSku = true } + ) { + Vue.prototype.$bus.$emit('cart-before-delete', { items: state.cartItems }); + state.cartItems = state.cartItems.filter( + p => + (p.sku !== product.sku && + (p.parentSku !== product.sku || removeByParentSku === false)) || + p.server_item_id /* it's confirmed if server_item_id is set */ + ); + Vue.prototype.$bus.$emit('cart-after-delete', { items: state.cartItems }); + state.cartSavedAt = Date.now(); + }, + [types.CART_UPD_ITEM](state, { product, qty }) { + const record = state.cartItems.find(p => p.sku === product.sku); if (record) { - Vue.prototype.$bus.$emit('cart-before-update', { product: record }) - record.qty = parseInt(qty) - Vue.prototype.$bus.$emit('cart-after-update', { product: record }) - state.cartSavedAt = Date.now() + Vue.prototype.$bus.$emit('cart-before-update', { product: record }); + record.qty = parseInt(qty); + Vue.prototype.$bus.$emit('cart-after-update', { product: record }); + state.cartSavedAt = Date.now(); } }, - [types.CART_UPD_ITEM_PROPS] (state, { product }) { - let record = state.cartItems.find(p => (p.sku === product.sku || (p.server_item_id && p.server_item_id === product.server_item_id))) + [types.CART_UPD_ITEM_PROPS](state, { product }) { + let record = state.cartItems.find( + p => + p.sku === product.sku || + (p.server_item_id && p.server_item_id === product.server_item_id) + ); if (record) { - Vue.prototype.$bus.$emit('cart-before-itemchanged', { item: record }) - record = Object.assign(record, product) - Vue.prototype.$bus.$emit('cart-after-itemchanged', { item: record }) - state.cartSavedAt = Date.now() + Vue.prototype.$bus.$emit('cart-before-itemchanged', { item: record }); + record = Object.assign(record, product); + Vue.prototype.$bus.$emit('cart-after-itemchanged', { item: record }); + state.cartSavedAt = Date.now(); } }, - [types.CART_UPD_SHIPPING] (state, shippingMethod) { - state.shipping = shippingMethod - state.cartSavedAt = Date.now() + [types.CART_UPD_SHIPPING](state, shippingMethod) { + state.shipping = shippingMethod; + state.cartSavedAt = Date.now(); }, - [types.CART_LOAD_CART] (state, storedItems) { - state.cartItems = storedItems || [] - state.cartIsLoaded = true - state.cartSavedAt = Date.now() + [types.CART_LOAD_CART](state, storedItems) { + state.cartItems = storedItems || []; + state.cartIsLoaded = true; + state.cartSavedAt = Date.now(); // Vue.prototype.$bus.$emit('order/PROCESS_QUEUE', { config: rootStore.state.config }) // process checkout queue - Vue.prototype.$bus.$emit('sync/PROCESS_QUEUE', { config: rootStore.state.config }) // process checkout queue - Vue.prototype.$bus.$emit('application-after-loaded') - Vue.prototype.$bus.$emit('cart-after-loaded') + Vue.prototype.$bus.$emit('sync/PROCESS_QUEUE', { + config: rootStore.state.config + }); // process checkout queue + Vue.prototype.$bus.$emit('application-after-loaded'); + Vue.prototype.$bus.$emit('cart-after-loaded'); }, - [types.CART_LOAD_CART_SERVER_TOKEN] (state, token) { - state.cartServerToken = token + [types.CART_LOAD_CART_SERVER_TOKEN](state, token) { + state.cartServerToken = token; }, - [types.CART_UPD_TOTALS] (state, { itemsAfterTotals, totals, platformTotalSegments }) { - state.cartServerTotalsAt = Date.now() - state.itemsAfterPlatformTotals = itemsAfterTotals - state.platformTotals = totals - state.platformTotalSegments = platformTotalSegments - Vue.prototype.$bus.$emit('cart-after-updatetotals', { platformTotals: totals, platformTotalSegments: platformTotalSegments }) + [types.CART_UPD_TOTALS]( + state, + { itemsAfterTotals, totals, platformTotalSegments } + ) { + state.cartServerTotalsAt = Date.now(); + state.itemsAfterPlatformTotals = itemsAfterTotals; + state.platformTotals = totals; + state.platformTotalSegments = platformTotalSegments; + Vue.prototype.$bus.$emit('cart-after-updatetotals', { + platformTotals: totals, + platformTotalSegments: platformTotalSegments + }); }, - [types.CART_UPD_PAYMENT] (state, paymentMethod) { - state.payment = paymentMethod - state.cartSavedAt = Date.now() + [types.CART_UPD_PAYMENT](state, paymentMethod) { + state.payment = paymentMethod; + state.cartSavedAt = Date.now(); }, - [types.CART_TOGGLE_MICROCART] (state) { - state.isMicrocartOpen = !state.isMicrocartOpen + [types.CART_TOGGLE_MICROCART](state) { + state.isMicrocartOpen = !state.isMicrocartOpen; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/cart/test/unit/components/AddToCart.spec.ts b/core/modules/cart/test/unit/components/AddToCart.spec.ts index 2ca018ef13..5ca9cbf810 100644 --- a/core/modules/cart/test/unit/components/AddToCart.spec.ts +++ b/core/modules/cart/test/unit/components/AddToCart.spec.ts @@ -1,8 +1,8 @@ -import { mountMixinWithStore } from "@vue-storefront/unit-tests/utils"; +import { mountMixinWithStore } from '@vue-storefront/unit-tests/utils'; -import Product from "@vue-storefront/core/modules/catalog/types/Product"; +import Product from '@vue-storefront/core/modules/catalog/types/Product'; -import { AddToCart } from '../../../components/AddToCart' +import { AddToCart } from '../../../components/AddToCart'; describe('AddToCart', () => { it('addToCart dispatches addItem action', () => { @@ -19,10 +19,16 @@ describe('AddToCart', () => { } }; - const wrapper = mountMixinWithStore(AddToCart, storeMock, { propsData: { product } }); + const wrapper = mountMixinWithStore(AddToCart, storeMock, { + propsData: { product } + }); - ( wrapper.vm).addToCart(product); + (wrapper.vm).addToCart(product); - expect(storeMock.modules.cart.actions.addItem).toBeCalledWith(expect.anything(), { productToAdd: product }, undefined); - }) + expect(storeMock.modules.cart.actions.addItem).toBeCalledWith( + expect.anything(), + { productToAdd: product }, + undefined + ); + }); }); diff --git a/core/modules/cart/test/unit/components/Microcart.spec.ts b/core/modules/cart/test/unit/components/Microcart.spec.ts index b74cafb3da..91de0f8afb 100644 --- a/core/modules/cart/test/unit/components/Microcart.spec.ts +++ b/core/modules/cart/test/unit/components/Microcart.spec.ts @@ -1,13 +1,12 @@ -import { mountMixinWithStore } from "@vue-storefront/unit-tests/utils"; +import { mountMixinWithStore } from '@vue-storefront/unit-tests/utils'; -import AppliedCoupon from '../../../types/AppliedCoupon' -import CartTotalSegments from '../../../types/CartTotalSegments' -import Product from "@vue-storefront/core/modules/catalog/types/Product"; +import AppliedCoupon from '../../../types/AppliedCoupon'; +import CartTotalSegments from '../../../types/CartTotalSegments'; +import Product from '@vue-storefront/core/modules/catalog/types/Product'; -import { Microcart } from '../../../components/Microcart' +import { Microcart } from '../../../components/Microcart'; describe('Microcart', () => { - beforeEach(() => { jest.clearAllMocks(); }); @@ -26,7 +25,9 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - expect(( wrapper.vm).productsInCart).toBe(storeMock.modules.cart.state.cartItems); + expect((wrapper.vm).productsInCart).toBe( + storeMock.modules.cart.state.cartItems + ); }); it('appliedCoupon returns currently set coupon', () => { @@ -43,7 +44,9 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - expect(( wrapper.vm).appliedCoupon).toEqual(storeMock.modules.cart.getters.coupon()); + expect((wrapper.vm).appliedCoupon).toEqual( + storeMock.modules.cart.getters.coupon() + ); }); it('totals returns cart totals', () => { @@ -60,7 +63,9 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - expect(( wrapper.vm).totals).toEqual(storeMock.modules.cart.getters.totals()); + expect((wrapper.vm).totals).toEqual( + storeMock.modules.cart.getters.totals() + ); }); it('isOpen returns cart state if it is open', () => { @@ -77,7 +82,9 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - expect(( wrapper.vm).isOpen).toBe(storeMock.modules.cart.state.isMicrocartOpen); + expect((wrapper.vm).isOpen).toBe( + storeMock.modules.cart.state.isMicrocartOpen + ); }); it('applyCoupon dispatches applyCupon action to save it', () => { @@ -95,9 +102,13 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - ( wrapper.vm).applyCoupon(couponCode); + (wrapper.vm).applyCoupon(couponCode); - expect(storeMock.modules.cart.actions.applyCoupon).toBeCalledWith(expect.anything(), "foo", undefined); + expect(storeMock.modules.cart.actions.applyCoupon).toBeCalledWith( + expect.anything(), + 'foo', + undefined + ); }); it('removeCoupon dispatches removeCoupon action to delete it', () => { @@ -114,7 +125,7 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - ( wrapper.vm).removeCoupon(); + (wrapper.vm).removeCoupon(); expect(storeMock.modules.cart.actions.removeCoupon).toBeCalled(); }); @@ -133,7 +144,7 @@ describe('Microcart', () => { const wrapper = mountMixinWithStore(Microcart, storeMock); - ( wrapper.vm).toggleMicrocart(); + (wrapper.vm).toggleMicrocart(); expect(storeMock.modules.ui.actions.toggleMicrocart).toBeCalled(); }); diff --git a/core/modules/cart/test/unit/components/MicrocartButton.spec.ts b/core/modules/cart/test/unit/components/MicrocartButton.spec.ts index 4065ec7da0..a3b6f11b8a 100644 --- a/core/modules/cart/test/unit/components/MicrocartButton.spec.ts +++ b/core/modules/cart/test/unit/components/MicrocartButton.spec.ts @@ -1,9 +1,8 @@ -import { mountMixinWithStore } from "@vue-storefront/unit-tests/utils"; +import { mountMixinWithStore } from '@vue-storefront/unit-tests/utils'; -import { MicrocartButton } from '../../../components/MicrocartButton' +import { MicrocartButton } from '../../../components/MicrocartButton'; describe('MicrocartButton', () => { - beforeEach(() => { jest.clearAllMocks(); }); @@ -22,7 +21,9 @@ describe('MicrocartButton', () => { const wrapper = mountMixinWithStore(MicrocartButton, storeMock); - expect(( wrapper.vm).quantity).toEqual(storeMock.modules.cart.getters.totalQuantity()); + expect((wrapper.vm).quantity).toEqual( + storeMock.modules.cart.getters.totalQuantity() + ); }); it('toggleMicrocart dispatches toggleMicrocart to change its state', () => { @@ -39,9 +40,8 @@ describe('MicrocartButton', () => { const wrapper = mountMixinWithStore(MicrocartButton, storeMock); - ( wrapper.vm).toggleMicrocart(); + (wrapper.vm).toggleMicrocart(); expect(storeMock.modules.cart.actions.toggleMicrocart).toBeCalled(); }); - }); diff --git a/core/modules/cart/test/unit/components/Product.spec.ts b/core/modules/cart/test/unit/components/Product.spec.ts index aaf510f4aa..8b4e27c0b1 100644 --- a/core/modules/cart/test/unit/components/Product.spec.ts +++ b/core/modules/cart/test/unit/components/Product.spec.ts @@ -1,6 +1,9 @@ -import {mountMixin, mountMixinWithStore} from "@vue-storefront/unit-tests/utils"; +import { + mountMixin, + mountMixinWithStore +} from '@vue-storefront/unit-tests/utils'; -import Product from "@vue-storefront/core/modules/catalog/types/Product"; +import Product from '@vue-storefront/core/modules/catalog/types/Product'; import { productThumbnailPath } from '@vue-storefront/core/helpers'; import { MicrocartProduct } from '../../../components/Product'; @@ -11,15 +14,17 @@ jest.mock('@vue-storefront/core/helpers', () => ({ })); describe('MicrocartProduct', () => { - beforeEach(() => { jest.clearAllMocks(); }); it('thumbnail in online mode returns thumbnail in lower size', () => { - ( productThumbnailPath).mockReturnValueOnce('thumbnail-path'); + (productThumbnailPath).mockReturnValueOnce('thumbnail-path'); - Object.defineProperty(navigator, 'onLine', { value: true, configurable: true}); + Object.defineProperty(navigator, 'onLine', { + value: true, + configurable: true + }); const product = {} as Product; const wrapper = mountMixin(MicrocartProduct, { propsData: { product } }); @@ -27,14 +32,17 @@ describe('MicrocartProduct', () => { wrapper.setMethods({ getThumbnail }); - expect(( wrapper.vm).thumbnail).toEqual('resized-thumbnail-path'); + expect((wrapper.vm).thumbnail).toEqual('resized-thumbnail-path'); expect(getThumbnail).toBeCalledWith('thumbnail-path', 150, 150); }); it('thumbnail in offline mode returns thumbnail in greater size', () => { - ( productThumbnailPath).mockReturnValueOnce('thumbnail-path'); + (productThumbnailPath).mockReturnValueOnce('thumbnail-path'); - Object.defineProperty(navigator, 'onLine', { value: false, configurable: true}); + Object.defineProperty(navigator, 'onLine', { + value: false, + configurable: true + }); const product = {} as Product; const wrapper = mountMixin(MicrocartProduct, { propsData: { product } }); @@ -42,7 +50,7 @@ describe('MicrocartProduct', () => { wrapper.setMethods({ getThumbnail }); - expect(( wrapper.vm).thumbnail).toEqual('resized-thumbnail-path'); + expect((wrapper.vm).thumbnail).toEqual('resized-thumbnail-path'); expect(getThumbnail).toBeCalledWith('thumbnail-path', 310, 300); }); @@ -59,11 +67,17 @@ describe('MicrocartProduct', () => { } }; - const wrapper = mountMixinWithStore(MicrocartProduct, storeMock, { propsData: { product } }); + const wrapper = mountMixinWithStore(MicrocartProduct, storeMock, { + propsData: { product } + }); - ( wrapper.vm).removeFromCart(); + (wrapper.vm).removeFromCart(); - expect(storeMock.modules.cart.actions.removeItem).toBeCalledWith(expect.anything(), { product } , undefined); + expect(storeMock.modules.cart.actions.removeItem).toBeCalledWith( + expect.anything(), + { product }, + undefined + ); }); it('updateQuantity dispatches updateQuantity update product quantity in cart', () => { @@ -80,13 +94,15 @@ describe('MicrocartProduct', () => { } }; - const wrapper = mountMixinWithStore(MicrocartProduct, storeMock, { propsData: { product } }); + const wrapper = mountMixinWithStore(MicrocartProduct, storeMock, { + propsData: { product } + }); - ( wrapper.vm).updateQuantity(qty); + (wrapper.vm).updateQuantity(qty); expect(storeMock.modules.cart.actions.updateQuantity).toBeCalledWith( expect.anything(), - { product, qty}, + { product, qty }, undefined ); }); diff --git a/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts b/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts index 0a11917054..1af7544c4f 100644 --- a/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts +++ b/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts @@ -1,8 +1,8 @@ -import Vue from 'vue' -import Vuex from 'vuex' -import * as types from '../../../store/mutation-types' +import Vue from 'vue'; +import Vuex from 'vuex'; +import * as types from '../../../store/mutation-types'; -import { cartCacheHandlerFactory } from "../../../helpers/cartCacheHandler"; +import { cartCacheHandlerFactory } from '../../../helpers/cartCacheHandler'; Vue.use(Vuex); @@ -13,7 +13,6 @@ Vue.prototype.$db = { }; describe('Cart afterRegistration', () => { - beforeEach(() => { jest.clearAllMocks(); }); @@ -24,33 +23,47 @@ describe('Cart afterRegistration', () => { types.CART_DEL_ITEM, types.CART_UPD_ITEM, types.CART_UPD_ITEM_PROPS - ])('handler populates cart cache on mutation %s that modifies cart items', async (mutationType) => { - const stateMock = { - cart: { - cartItems : [{}] - } - }; - - Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => Promise.resolve('foo')); - - await cartCacheHandlerFactory(Vue)({ type: mutationType }, stateMock); - - expect(Vue.prototype.$db.cartsCollection.setItem) - .toBeCalledWith('current-cart', stateMock.cart.cartItems); - }); + ])( + 'handler populates cart cache on mutation %s that modifies cart items', + async mutationType => { + const stateMock = { + cart: { + cartItems: [{}] + } + }; + + Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => + Promise.resolve('foo') + ); + + await cartCacheHandlerFactory(Vue)({ type: mutationType }, stateMock); + + expect(Vue.prototype.$db.cartsCollection.setItem).toBeCalledWith( + 'current-cart', + stateMock.cart.cartItems + ); + } + ); it('handler logs error when populating cart cache with items fails', async () => { const stateMock = { cart: { - cartItems : [{}] + cartItems: [{}] } }; - const consoleErrorSpy = jest.spyOn(console, "error").mockImplementationOnce(() => {}); + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementationOnce(() => {}); - Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => Promise.reject('foo')); + Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => + Promise.reject('foo') + ); - await cartCacheHandlerFactory(Vue)({ type: types.CART_LOAD_CART }, stateMock); + await cartCacheHandlerFactory(Vue)( + { type: types.CART_LOAD_CART }, + stateMock + ); expect(consoleErrorSpy).toBeCalled(); }); @@ -58,30 +71,44 @@ describe('Cart afterRegistration', () => { it('hook updates cart token in cache on mutation changing cart token', async () => { const stateMock = { cart: { - cartServerToken : 'token' + cartServerToken: 'token' } }; - Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => Promise.resolve('foo')); + Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => + Promise.resolve('foo') + ); - await cartCacheHandlerFactory(Vue)({ type: types.CART_LOAD_CART_SERVER_TOKEN }, stateMock); + await cartCacheHandlerFactory(Vue)( + { type: types.CART_LOAD_CART_SERVER_TOKEN }, + stateMock + ); - expect(Vue.prototype.$db.cartsCollection.setItem) - .toBeCalledWith('current-cart-token', stateMock.cart.cartServerToken); + expect(Vue.prototype.$db.cartsCollection.setItem).toBeCalledWith( + 'current-cart-token', + stateMock.cart.cartServerToken + ); }); it('handler logs error when changing cached token fails', async () => { const stateMock = { cart: { - cartServerToken : 'token' + cartServerToken: 'token' } }; - const consoleErrorSpy = jest.spyOn(console, "error").mockImplementationOnce(() => {}); + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementationOnce(() => {}); - Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => Promise.reject('foo')); + Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => + Promise.reject('foo') + ); - await cartCacheHandlerFactory(Vue)({ type: types.CART_LOAD_CART_SERVER_TOKEN }, stateMock); + await cartCacheHandlerFactory(Vue)( + { type: types.CART_LOAD_CART_SERVER_TOKEN }, + stateMock + ); expect(consoleErrorSpy).toBeCalled(); }); @@ -89,13 +116,17 @@ describe('Cart afterRegistration', () => { it('handler ignores mutation not related to cart cache', async () => { const stateMock = { cart: { - cartServerToken : 'token' + cartServerToken: 'token' } }; - const consoleErrorSpy = jest.spyOn(console, "error").mockImplementationOnce(() => {}); + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementationOnce(() => {}); - Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => Promise.reject('foo')); + Vue.prototype.$db.cartsCollection.setItem.mockImplementationOnce(() => + Promise.reject('foo') + ); await cartCacheHandlerFactory(Vue)({ type: 'bar' }, stateMock); diff --git a/core/modules/cart/test/unit/hooks/afterRegistration.spec.ts b/core/modules/cart/test/unit/hooks/afterRegistration.spec.ts index 1a8414db40..450573b726 100644 --- a/core/modules/cart/test/unit/hooks/afterRegistration.spec.ts +++ b/core/modules/cart/test/unit/hooks/afterRegistration.spec.ts @@ -1,13 +1,15 @@ -import Vue from 'vue' -import Vuex from 'vuex' +import Vue from 'vue'; +import Vuex from 'vuex'; import { cartCacheHandlerFactory } from '../../../helpers/cartCacheHandler'; -import { afterRegistration } from "../../../hooks/afterRegistration"; +import { afterRegistration } from '../../../hooks/afterRegistration'; import Mock = jest.Mock; Vue.use(Vuex); -jest.mock('../../../helpers/cartCacheHandler', () => ({ cartCacheHandlerFactory: jest.fn() }) ); +jest.mock('../../../helpers/cartCacheHandler', () => ({ + cartCacheHandlerFactory: jest.fn() +})); Vue.prototype.$db = { cartsCollection: { @@ -16,7 +18,6 @@ Vue.prototype.$db = { }; describe('Cart afterRegistration', () => { - beforeEach(() => { jest.clearAllMocks(); }); @@ -33,17 +34,22 @@ describe('Cart afterRegistration', () => { } }; - afterRegistration({ Vue, config: {}, store: new Vuex.Store(storeMock), isServer: false}); + afterRegistration({ + Vue, + config: {}, + store: new Vuex.Store(storeMock), + isServer: false + }); - expect(storeMock.modules.cart.actions.load).toBeCalled() + expect(storeMock.modules.cart.actions.load).toBeCalled(); }); - it ('hook subscribes to mutations with cartCacheHandler', () => { + it('hook subscribes to mutations with cartCacheHandler', () => { const store = new Vuex.Store({}); - const storeSpy = jest.spyOn(store,'subscribe'); + const storeSpy = jest.spyOn(store, 'subscribe'); const cartCacheHandler = jest.fn(); - ( cartCacheHandlerFactory).mockReturnValueOnce(cartCacheHandler); + (cartCacheHandlerFactory).mockReturnValueOnce(cartCacheHandler); afterRegistration({ Vue, config: {}, store, isServer: true }); diff --git a/core/modules/cart/test/unit/hooks/beforeRegistration.spec.ts b/core/modules/cart/test/unit/hooks/beforeRegistration.spec.ts index 417027c306..dd838c77f2 100644 --- a/core/modules/cart/test/unit/hooks/beforeRegistration.spec.ts +++ b/core/modules/cart/test/unit/hooks/beforeRegistration.spec.ts @@ -1,19 +1,20 @@ -import Vue from 'vue' +import Vue from 'vue'; import UniversalStorage from '@vue-storefront/core/store/lib/storage'; import { currentStoreView } from '@vue-storefront/core/lib/multistore'; import { beforeRegistration } from '../../../hooks/beforeRegistration'; import Mock = jest.Mock; -import * as localForage from "localforage"; +import * as localForage from 'localforage'; -jest.mock('localforage', () => ({ createInstance: jest.fn(), someDriver: {}} )); +jest.mock('localforage', () => ({ createInstance: jest.fn(), someDriver: {} })); jest.mock('@vue-storefront/core/store/lib/storage', () => jest.fn()); -jest.mock('@vue-storefront/core/lib/multistore', () => ({ currentStoreView: jest.fn() })); +jest.mock('@vue-storefront/core/lib/multistore', () => ({ + currentStoreView: jest.fn() +})); Vue.prototype.$db = {}; describe('Cart beforeRegistration', () => { - beforeEach(() => { jest.clearAllMocks(); }); @@ -29,10 +30,12 @@ describe('Cart beforeRegistration', () => { } } }; - const storageMock = {foo: 'bar'}; + const storageMock = { foo: 'bar' }; - ( currentStoreView).mockReturnValueOnce({}); - ( UniversalStorage).mockImplementationOnce(() => storageMock); + (currentStoreView).mockReturnValueOnce({}); + ((UniversalStorage)).mockImplementationOnce( + () => storageMock + ); beforeRegistration({ Vue, config, store: undefined, isServer: undefined }); @@ -50,10 +53,12 @@ describe('Cart beforeRegistration', () => { } } }; - const storageMock = {foo: 'bar'}; + const storageMock = { foo: 'bar' }; - ( currentStoreView).mockReturnValueOnce({ storeCode: 'baz'}); - ( UniversalStorage).mockImplementationOnce(() => storageMock); + (currentStoreView).mockReturnValueOnce({ storeCode: 'baz' }); + ((UniversalStorage)).mockImplementationOnce( + () => storageMock + ); beforeRegistration({ Vue, config, store: undefined, isServer: undefined }); diff --git a/core/modules/cart/test/unit/index.spec.ts b/core/modules/cart/test/unit/index.spec.ts index 4f7d1bf53e..7c85c9935a 100644 --- a/core/modules/cart/test/unit/index.spec.ts +++ b/core/modules/cart/test/unit/index.spec.ts @@ -1,12 +1,14 @@ jest.mock('../../store', () => ({})); -jest.mock('@vue-storefront/core/lib/module', () => ({ createModule: jest.fn(() => ({ module: 'cart'}) )})); +jest.mock('@vue-storefront/core/lib/module', () => ({ + createModule: jest.fn(() => ({ module: 'cart' })) +})); jest.mock('../../hooks/beforeRegistration', () => jest.fn()); jest.mock('../../hooks/afterRegistration', () => jest.fn()); -import { Cart } from '../../index' +import { Cart } from '../../index'; describe('Cart Module', () => { it('can be initialized', () => { - expect(Cart).toBeTruthy() - }) + expect(Cart).toBeTruthy(); + }); }); diff --git a/core/modules/cart/test/unit/store/actions.spec.ts b/core/modules/cart/test/unit/store/actions.spec.ts index a42a384dea..1b94527d68 100644 --- a/core/modules/cart/test/unit/store/actions.spec.ts +++ b/core/modules/cart/test/unit/store/actions.spec.ts @@ -1,23 +1,23 @@ -import Vue from 'vue' +import Vue from 'vue'; import * as types from '../../../store/mutation-types'; import cartActions from '../../../store/actions'; import config from 'config'; import rootStore from '@vue-storefront/core/store'; import { sha3_224 } from 'js-sha3'; -import { TaskQueue } from "../../../../../lib/sync"; +import { TaskQueue } from '../../../../../lib/sync'; import * as coreHelper from '@vue-storefront/core/helpers'; import { currentStoreView } from '@vue-storefront/core/lib/multistore'; import { onlineHelper } from '@vue-storefront/core/helpers'; -jest.mock('@vue-storefront/core/store',() => ({ +jest.mock('@vue-storefront/core/store', () => ({ dispatch: jest.fn(), state: {} })); jest.mock('config', () => ({})); jest.mock('@vue-storefront/i18n', () => ({ t: jest.fn(str => str) })); -jest.mock('js-sha3',() => ({ sha3_224: jest.fn() })); -jest.mock('@vue-storefront/core/lib/multistore',() => ({ +jest.mock('js-sha3', () => ({ sha3_224: jest.fn() })); +jest.mock('@vue-storefront/core/lib/multistore', () => ({ currentStoreView: jest.fn(), localizedRoute: jest.fn() })); @@ -27,18 +27,20 @@ jest.mock('@vue-storefront/core/lib/logger', () => ({ debug: jest.fn(() => () => {}) } })); -jest.mock('@vue-storefront/core/lib/sync', () => ({ TaskQueue: { - execute: jest.fn() -}})); +jest.mock('@vue-storefront/core/lib/sync', () => ({ + TaskQueue: { + execute: jest.fn() + } +})); jest.mock('@vue-storefront/core/app', () => ({ router: jest.fn() })); jest.mock('@vue-storefront/core/lib/search/searchQuery', () => jest.fn()); jest.mock('@vue-storefront/core/helpers', () => ({ get isServer() { - return true + return true; }, onlineHelper: { get isOnline() { - return true + return true; } } })); @@ -48,14 +50,19 @@ Vue.prototype.$bus = { }; describe('Cart actions', () => { - - const isServerSpy = jest.spyOn((coreHelper as any).default, 'isServer', 'get'); + const isServerSpy = jest.spyOn( + (coreHelper as any).default, + 'isServer', + 'get' + ); const isOnlineSpy = jest.spyOn(onlineHelper, 'isOnline', 'get'); beforeEach(() => { jest.clearAllMocks(); (rootStore as any).state = {}; - Object.keys(config).forEach(function(key) { delete config[key]; }); + Object.keys(config).forEach(function(key) { + delete config[key]; + }); }); it('serverTokenClear clears cart token', () => { @@ -66,7 +73,10 @@ describe('Cart actions', () => { wrapper(cartActions); - expect(contextMock.commit).toBeCalledWith(types.CART_LOAD_CART_SERVER_TOKEN, null); + expect(contextMock.commit).toBeCalledWith( + types.CART_LOAD_CART_SERVER_TOKEN, + null + ); }); it('clear deletes all cart products and token', () => { @@ -80,7 +90,10 @@ describe('Cart actions', () => { wrapper(cartActions); expect(contextMock.commit).toBeCalledWith(types.CART_LOAD_CART, []); - expect(contextMock.commit).toBeCalledWith(types.CART_LOAD_CART_SERVER_TOKEN, null); + expect(contextMock.commit).toBeCalledWith( + types.CART_LOAD_CART_SERVER_TOKEN, + null + ); }); it('clear dispatches creating a new cart on server with direct backend sync when its configured', () => { @@ -96,7 +109,9 @@ describe('Cart actions', () => { wrapper(cartActions); - expect(contextMock.dispatch).toBeCalledWith('serverCreate', { guestCart: false}); + expect(contextMock.dispatch).toBeCalledWith('serverCreate', { + guestCart: false + }); }); it('clear dispatches creating a new cart on server with queuing when direct backend sync is not configured', () => { @@ -112,7 +127,9 @@ describe('Cart actions', () => { wrapper(cartActions); - expect(contextMock.dispatch).toBeCalledWith('serverCreate', { guestCart: true}); + expect(contextMock.dispatch).toBeCalledWith('serverCreate', { + guestCart: true + }); }); it('save dispatches cart save mutation', () => { @@ -127,7 +144,6 @@ describe('Cart actions', () => { }); describe('serverPull', () => { - it('pulls latest cart data and refreshes payment/shipping methods when there are products in cart', async () => { isOnlineSpy.mockReturnValueOnce(true); const contextMock = { @@ -137,7 +153,7 @@ describe('Cart actions', () => { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 0, + cartServerMethodsRefreshAt: 0 } }; @@ -151,19 +167,21 @@ describe('Cart actions', () => { }; const expectedState = { - cartItems: [{sku: 'foo'}], + cartItems: [{ sku: 'foo' }], cartServerToken: 'some-token', cartItemsHash: 'new-hash', cartServerPullAt: 1000003000, - cartServerMethodsRefreshAt: 1000003000, + cartServerMethodsRefreshAt: 1000003000 }; isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => expectedState.cartServerPullAt); (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => { - contextMock.state.cartItems = contextMock.state.cartItems.concat(expectedState.cartItems); - return Promise.resolve({}) + contextMock.state.cartItems = contextMock.state.cartItems.concat( + expectedState.cartItems + ); + return Promise.resolve({}); }); const wrapper = (actions: any) => actions.serverPull(contextMock, {}); @@ -172,10 +190,9 @@ describe('Cart actions', () => { expect(TaskQueue.execute).toBeCalled(); expect(rootStore.dispatch).toBeCalledWith('cart/getPaymentMethods'); - expect(rootStore.dispatch).toBeCalledWith( - 'cart/getShippingMethods', - { country_id: rootStore.state.checkout.shippingDetails.country } - ); + expect(rootStore.dispatch).toBeCalledWith('cart/getShippingMethods', { + country_id: rootStore.state.checkout.shippingDetails.country + }); expect(contextMock.state).toEqual(expectedState); }); @@ -188,43 +205,46 @@ describe('Cart actions', () => { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 0, + cartServerMethodsRefreshAt: 0 } }; config.cart = { synchronize: true }; (rootStore as any).state = { checkout: { - shippingDetails: { } + shippingDetails: {} } }; const expectedState = { - cartItems: [{sku: 'foo'}], + cartItems: [{ sku: 'foo' }], cartItemsHash: 'new-hash', - cartServerPullAt: 1000003000, + cartServerPullAt: 1000003000 }; isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => expectedState.cartServerPullAt); (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => { - contextMock.state.cartItems = contextMock.state.cartItems.concat(expectedState.cartItems); - return Promise.resolve({}) + contextMock.state.cartItems = contextMock.state.cartItems.concat( + expectedState.cartItems + ); + return Promise.resolve({}); + }); + (currentStoreView as jest.Mock).mockReturnValueOnce({ + tax: { defaultCountry: 'us' } }); - (currentStoreView as jest.Mock).mockReturnValueOnce({ tax: { defaultCountry: 'us' } }); const wrapper = (actions: any) => actions.serverPull(contextMock, {}); await wrapper(cartActions); - expect(rootStore.dispatch).toBeCalledWith( - 'cart/getShippingMethods', - { country_id: 'us' } - ); + expect(rootStore.dispatch).toBeCalledWith('cart/getShippingMethods', { + country_id: 'us' + }); }); - it('doesn\'t update shipping methods if cart is empty', async () => { + it("doesn't update shipping methods if cart is empty", async () => { const contextMock = { dispatch: jest.fn(), state: { @@ -232,7 +252,7 @@ describe('Cart actions', () => { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 0, + cartServerMethodsRefreshAt: 0 } }; @@ -248,25 +268,26 @@ describe('Cart actions', () => { const expectedState = { cartItems: [], cartItemsHash: 'new-hash', - cartServerPullAt: 1000003000, + cartServerPullAt: 1000003000 }; isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => expectedState.cartServerPullAt); (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); const wrapper = (actions: any) => actions.serverPull(contextMock, {}); await wrapper(cartActions); - expect(rootStore.dispatch).not.toBeCalledWith( - 'cart/getShippingMethods', - { country_id: 'us' } - ); + expect(rootStore.dispatch).not.toBeCalledWith('cart/getShippingMethods', { + country_id: 'us' + }); }); - it('doesn\'t update payment methods if they were synced recently', async () => { + it("doesn't update payment methods if they were synced recently", async () => { const contextMock = { dispatch: jest.fn(), state: { @@ -274,7 +295,7 @@ describe('Cart actions', () => { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 1000000000, + cartServerMethodsRefreshAt: 1000000000 } }; @@ -283,13 +304,15 @@ describe('Cart actions', () => { const expectedState = { cartItems: [], cartItemsHash: 'new-hash', - cartServerPullAt: 1000003000, + cartServerPullAt: 1000003000 }; isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => expectedState.cartServerPullAt); (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); const wrapper = (actions: any) => actions.serverPull(contextMock, {}); @@ -298,7 +321,7 @@ describe('Cart actions', () => { expect(rootStore.dispatch).not.toBeCalled(); }); - it('doesn\'t update payment methods if they were synced recently', async () => { + it("doesn't update payment methods if they were synced recently", async () => { const contextMock = { dispatch: jest.fn(), state: { @@ -306,7 +329,7 @@ describe('Cart actions', () => { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 1000000000, + cartServerMethodsRefreshAt: 1000000000 } }; @@ -315,13 +338,15 @@ describe('Cart actions', () => { const expectedState = { cartItems: [], cartItemsHash: 'new-hash', - cartServerPullAt: 1000003000, + cartServerPullAt: 1000003000 }; isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => expectedState.cartServerPullAt); (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); const wrapper = (actions: any) => actions.serverPull(contextMock, {}); @@ -330,38 +355,43 @@ describe('Cart actions', () => { expect(rootStore.dispatch).not.toBeCalled(); }); - it('pulls latest cart data and even when the cart was updated recently but the hash has changed' + - '(so cart items or token wer modified)', () => { - const contextMock = { - dispatch: jest.fn(), - state: { - cartItems: [], - cartServerToken: 'some-token', - cartItemsHash: 'some-sha-hash', - cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 1000000000, - } - }; + it( + 'pulls latest cart data and even when the cart was updated recently but the hash has changed' + + '(so cart items or token wer modified)', + () => { + const contextMock = { + dispatch: jest.fn(), + state: { + cartItems: [], + cartServerToken: 'some-token', + cartItemsHash: 'some-sha-hash', + cartServerPullAt: 1000000000, + cartServerMethodsRefreshAt: 1000000000 + } + }; - config.cart = { synchronize: true }; + config.cart = { synchronize: true }; - const expectedState = { - cartItems: [], - cartItemsHash: 'new-hash', - cartServerPullAt: 1000000050, - }; + const expectedState = { + cartItems: [], + cartItemsHash: 'new-hash', + cartServerPullAt: 1000000050 + }; - isServerSpy.mockReturnValueOnce(false); - Date.now = jest.fn(() => expectedState.cartServerPullAt); - (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + isServerSpy.mockReturnValueOnce(false); + Date.now = jest.fn(() => expectedState.cartServerPullAt); + (sha3_224 as any).mockReturnValueOnce(expectedState.cartItemsHash); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverPull(contextMock, {}); + const wrapper = (actions: any) => actions.serverPull(contextMock, {}); - wrapper(cartActions); + wrapper(cartActions); - expect(TaskQueue.execute).toBeCalled(); - }); + expect(TaskQueue.execute).toBeCalled(); + } + ); it('performs a cart update request with dry run and forcing client state if its configured to do so', () => { const contextMock = { @@ -371,7 +401,7 @@ describe('Cart actions', () => { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', cartServerPullAt: 1000000000, - cartServerMethodsRefreshAt: 1000000000, + cartServerMethodsRefreshAt: 1000000000 } }; @@ -380,22 +410,30 @@ describe('Cart actions', () => { isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => 1000003000); (sha3_224 as any).mockReturnValueOnce(contextMock.state.cartItemsHash); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverPull(contextMock, { forceClientState: true, dryRun: true }); + const wrapper = (actions: any) => + actions.serverPull(contextMock, { + forceClientState: true, + dryRun: true + }); wrapper(cartActions); - expect(TaskQueue.execute).toBeCalledWith(expect.objectContaining({ dry_run: true, force_client_state: true, })); + expect(TaskQueue.execute).toBeCalledWith( + expect.objectContaining({ dry_run: true, force_client_state: true }) + ); }); - it('does not do anything if last cart sync was recently and the cart state hasn\'t been changed since then', () => { + it("does not do anything if last cart sync was recently and the cart state hasn't been changed since then", () => { const contextMock = { dispatch: jest.fn(), state: { cartServerToken: 'some-token', cartItemsHash: 'some-sha-hash', - cartServerPullAt: 1000000000, + cartServerPullAt: 1000000000 } }; @@ -414,7 +452,7 @@ describe('Cart actions', () => { it('does not do anything if synchronization is off', () => { const contextMock = { - dispatch: jest.fn(), + dispatch: jest.fn() }; config.cart = { synchronize: false }; @@ -442,12 +480,11 @@ describe('Cart actions', () => { }); describe('serverTotals', () => { - it('pulls latest totals from server', async () => { const contextMock = { state: { cartServerToken: 'some-token', - cartServerTotalsAt: 1000000000, + cartServerTotalsAt: 1000000000 } }; @@ -455,7 +492,9 @@ describe('Cart actions', () => { isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => 1000003000); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); const wrapper = (actions: any) => actions.serverTotals(contextMock, {}); @@ -464,11 +503,11 @@ describe('Cart actions', () => { expect(TaskQueue.execute).toBeCalled(); }); - it('pulls latest totals from server forcing client state if it\'s configured to do so', async () => { + it("pulls latest totals from server forcing client state if it's configured to do so", async () => { const contextMock = { state: { cartServerToken: 'some-token', - cartServerTotalsAt: 1000000000, + cartServerTotalsAt: 1000000000 } }; @@ -476,20 +515,25 @@ describe('Cart actions', () => { isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => 1000003000); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverTotals(contextMock, { forceClientState: true }); + const wrapper = (actions: any) => + actions.serverTotals(contextMock, { forceClientState: true }); await wrapper(cartActions); - expect(TaskQueue.execute).toBeCalledWith(expect.objectContaining({ force_client_state: true })) + expect(TaskQueue.execute).toBeCalledWith( + expect.objectContaining({ force_client_state: true }) + ); }); it('does not do anything if last totals sync was done recently', () => { const contextMock = { state: { cartServerToken: 'some-token', - cartServerTotalsAt: 1000000000, + cartServerTotalsAt: 1000000000 } }; @@ -535,11 +579,10 @@ describe('Cart actions', () => { }); describe('serverCreate', () => { - it('requests to backend for creation of a new cart', async () => { const contextMock = { state: { - cartServerCreatedAt: 1000000000, + cartServerCreatedAt: 1000000000 } }; @@ -547,7 +590,9 @@ describe('Cart actions', () => { isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => 1000003000); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); const wrapper = (actions: any) => actions.serverCreate(contextMock, {}); @@ -559,7 +604,7 @@ describe('Cart actions', () => { it('requests to backend for creation of guest cart', async () => { const contextMock = { state: { - cartServerCreatedAt: 1000000000, + cartServerCreatedAt: 1000000000 } }; @@ -570,18 +615,23 @@ describe('Cart actions', () => { isServerSpy.mockReturnValueOnce(false); Date.now = jest.fn(() => 1000003000); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverCreate(contextMock, { guestCart: true }); + const wrapper = (actions: any) => + actions.serverCreate(contextMock, { guestCart: true }); await wrapper(cartActions); - expect(TaskQueue.execute).toBeCalledWith(expect.objectContaining({ url: 'http://example.url/guest-cart/' })) + expect(TaskQueue.execute).toBeCalledWith( + expect.objectContaining({ url: 'http://example.url/guest-cart/' }) + ); }); it('does not do anything if last totals sync was done recently', () => { const contextMock = { state: { - cartServerCreatedAt: 1000000000, + cartServerCreatedAt: 1000000000 } }; @@ -623,13 +673,12 @@ describe('Cart actions', () => { }); describe('serverUpdateItem', () => { - it('sends an item update request to backend server and updates totals', async () => { const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", - cartItems: [{sku: '123'}] + cartServerToken: 'SOME-TOKEN', + cartItems: [{ sku: '123' }] } }; @@ -644,21 +693,24 @@ describe('Cart actions', () => { }; isServerSpy.mockReturnValueOnce(false); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverUpdateItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverUpdateItem(contextMock, cartItemMock); await wrapper(cartActions); expect(TaskQueue.execute).toBeCalled(); - expect(contextMock.dispatch).toBeCalledWith('refreshTotals') + expect(contextMock.dispatch).toBeCalledWith('refreshTotals'); }); it('sends an item update request to backend server and sets its quoteId to cart token, if none has been set before', async () => { const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", + cartServerToken: 'SOME-TOKEN' } }; @@ -672,29 +724,34 @@ describe('Cart actions', () => { }; isServerSpy.mockReturnValueOnce(false); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverUpdateItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverUpdateItem(contextMock, cartItemMock); await wrapper(cartActions); - expect(TaskQueue.execute).toBeCalledWith(expect.objectContaining({ - payload: { - body: '{"cartItem":{"sku":"123","quoteId":"SOME-TOKEN"}}', - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - mode: 'cors' - } - })); + expect(TaskQueue.execute).toBeCalledWith( + expect.objectContaining({ + payload: { + body: '{"cartItem":{"sku":"123","quoteId":"SOME-TOKEN"}}', + headers: { + 'Content-Type': 'application/json' + }, + method: 'POST', + mode: 'cors' + } + }) + ); }); - it('sends an item update request but doesn\'t call refresh totals if the cart after update is empty', async () => { + it("sends an item update request but doesn't call refresh totals if the cart after update is empty", async () => { const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", + cartServerToken: 'SOME-TOKEN', cartItems: [] } }; @@ -710,9 +767,12 @@ describe('Cart actions', () => { }; isServerSpy.mockReturnValueOnce(false); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverUpdateItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverUpdateItem(contextMock, cartItemMock); await wrapper(cartActions); @@ -720,12 +780,12 @@ describe('Cart actions', () => { expect(contextMock.dispatch).not.toBeCalled(); }); - it('sends an item update request but doesn\'t call refresh totals if totals sync is configured off', async () => { + it("sends an item update request but doesn't call refresh totals if totals sync is configured off", async () => { const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", - cartItems: [{sku: '123'}] + cartServerToken: 'SOME-TOKEN', + cartItems: [{ sku: '123' }] } }; @@ -739,9 +799,12 @@ describe('Cart actions', () => { }; isServerSpy.mockReturnValueOnce(false); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverUpdateItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverUpdateItem(contextMock, cartItemMock); await wrapper(cartActions); @@ -751,14 +814,13 @@ describe('Cart actions', () => { }); describe('serverDeleteItem', () => { - it('sends a delete item from cart request to backend server and updates totals', async () => { isOnlineSpy.mockReturnValueOnce(true); const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", - cartItems: [{sku: '123'}] + cartServerToken: 'SOME-TOKEN', + cartItems: [{ sku: '123' }] } }; @@ -773,62 +835,73 @@ describe('Cart actions', () => { }; isServerSpy.mockReturnValueOnce(false); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); - const wrapper = (actions: any) => actions.serverDeleteItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverDeleteItem(contextMock, cartItemMock); await wrapper(cartActions); expect(TaskQueue.execute).toBeCalled(); - expect(contextMock.dispatch).toBeCalledWith('refreshTotals') + expect(contextMock.dispatch).toBeCalledWith('refreshTotals'); }); - it('sends a delete item from cart request to backend server and sets its quoteId to cart token, ' + - 'if none has been set before', async () => { - const contextMock = { - dispatch: jest.fn(), - state: { - cartServerToken: "SOME-TOKEN", - } - }; - - config.cart = { - synchronize_totals: false, - deleteitem_endpoint: 'http://endpoint.com/cart/delete-item' - }; - + it( + 'sends a delete item from cart request to backend server and sets its quoteId to cart token, ' + + 'if none has been set before', + async () => { + const contextMock = { + dispatch: jest.fn(), + state: { + cartServerToken: 'SOME-TOKEN' + } + }; + + config.cart = { + synchronize_totals: false, + deleteitem_endpoint: 'http://endpoint.com/cart/delete-item' + }; + + const cartItemMock = { + sku: '123' + }; + + isServerSpy.mockReturnValueOnce(false); + (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => + Promise.resolve({}) + ); + + const wrapper = (actions: any) => + actions.serverDeleteItem(contextMock, cartItemMock); + + await wrapper(cartActions); + + expect(TaskQueue.execute).toBeCalledWith( + expect.objectContaining({ + payload: { + body: '{"cartItem":{"sku":"123","quoteId":"SOME-TOKEN"}}', + headers: { + 'Content-Type': 'application/json' + }, + method: 'POST', + mode: 'cors' + } + }) + ); + } + ); + + it("sends a delete item from cart request but doesn't call refresh totals if the cart after update is empty", async () => { const cartItemMock = { sku: '123' }; - isServerSpy.mockReturnValueOnce(false); - (TaskQueue.execute as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); - - const wrapper = (actions: any) => actions.serverDeleteItem(contextMock, cartItemMock); - - await wrapper(cartActions); - - expect(TaskQueue.execute).toBeCalledWith(expect.objectContaining({ - payload: { - body: '{"cartItem":{"sku":"123","quoteId":"SOME-TOKEN"}}', - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - mode: 'cors' - } - })); - }); - - it('sends a delete item from cart request but doesn\'t call refresh totals if the cart after update is empty', async () => { - const cartItemMock = { - sku: '123', - }; - const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", + cartServerToken: 'SOME-TOKEN', cartItems: [cartItemMock] } }; @@ -844,7 +917,8 @@ describe('Cart actions', () => { return Promise.resolve({}); }); - const wrapper = (actions: any) => actions.serverDeleteItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverDeleteItem(contextMock, cartItemMock); await wrapper(cartActions); @@ -852,7 +926,7 @@ describe('Cart actions', () => { expect(contextMock.dispatch).not.toBeCalled(); }); - it('sends a delete item from cart request but doesn\'t call refresh totals if totals sync is configured off', async () => { + it("sends a delete item from cart request but doesn't call refresh totals if totals sync is configured off", async () => { const cartItemMock = { sku: '123' }; @@ -860,7 +934,7 @@ describe('Cart actions', () => { const contextMock = { dispatch: jest.fn(), state: { - cartServerToken: "SOME-TOKEN", + cartServerToken: 'SOME-TOKEN', cartItems: [cartItemMock] } }; @@ -876,7 +950,8 @@ describe('Cart actions', () => { return Promise.resolve({}); }); - const wrapper = (actions: any) => actions.serverDeleteItem(contextMock, cartItemMock); + const wrapper = (actions: any) => + actions.serverDeleteItem(contextMock, cartItemMock); await wrapper(cartActions); diff --git a/core/modules/cart/test/unit/store/getters.spec.ts b/core/modules/cart/test/unit/store/getters.spec.ts index a94514a2e7..8010463144 100644 --- a/core/modules/cart/test/unit/store/getters.spec.ts +++ b/core/modules/cart/test/unit/store/getters.spec.ts @@ -1,11 +1,11 @@ import cartGetters from '../../../store/getters'; -import { onlineHelper } from '@vue-storefront/core/helpers' +import { onlineHelper } from '@vue-storefront/core/helpers'; jest.mock('@vue-storefront/i18n', () => ({ t: jest.fn(str => str) })); jest.mock('@vue-storefront/core/helpers', () => ({ onlineHelper: { get isOnline() { - return true + return true; } } })); @@ -20,18 +20,34 @@ describe('Cart getters', () => { it('totals returns platform total segments if they has been saved in store and client is online', () => { const stateMock = { platformTotalSegments: [ - {'code': 'subtotal', 'title': 'Subtotal', 'value': 39.36}, - {'code': 'shipping', 'title': 'Shipping & Handling (Flat Rate - Fixed)', 'value': 5}, - {'code': 'discount', 'title': 'Discount', 'value': -4.8}, - {'code': 'tax', 'title': 'Tax', 'value': 6.26, 'area': 'taxes', - 'extension_attributes': { - 'tax_grandtotal_details': [{ - 'amount': 6.26, - 'rates': [{'percent': '23', 'title': 'VAT23-PL'}], - 'group_id': 1 - }] - }}, - {'code': 'grand_total', 'title': 'Grand Total', 'value': 38.46, 'area': 'footer'} + { code: 'subtotal', title: 'Subtotal', value: 39.36 }, + { + code: 'shipping', + title: 'Shipping & Handling (Flat Rate - Fixed)', + value: 5 + }, + { code: 'discount', title: 'Discount', value: -4.8 }, + { + code: 'tax', + title: 'Tax', + value: 6.26, + area: 'taxes', + extension_attributes: { + tax_grandtotal_details: [ + { + amount: 6.26, + rates: [{ percent: '23', title: 'VAT23-PL' }], + group_id: 1 + } + ] + } + }, + { + code: 'grand_total', + title: 'Grand Total', + value: 38.46, + area: 'footer' + } ] }; const wrapper = (getters: any) => getters.totals(stateMock); @@ -42,16 +58,13 @@ describe('Cart getters', () => { it(`totals returns totals without shipping and payment prices having neither platformTotalSegments nor additional prices`, () => { const stateMock = { - cartItems: [ - {qty: 1, priceInclTax: 1}, - {qty: 2, priceInclTax: 2} - ] + cartItems: [{ qty: 1, priceInclTax: 1 }, { qty: 2, priceInclTax: 2 }] }; const wrapper = (getters: any) => getters.totals(stateMock); expect(wrapper(cartGetters)).toEqual([ - {"code": "subtotalInclTax", "title": "Subtotal incl. tax", "value": 5}, - {"code": "grand_total", "title": "Grand total", "value": 5} + { code: 'subtotalInclTax', title: 'Subtotal incl. tax', value: 5 }, + { code: 'grand_total', title: 'Grand total', value: 5 } ]); }); @@ -59,92 +72,84 @@ describe('Cart getters', () => { isOnlineSpy.mockReturnValueOnce(false); const stateMock = { platformTotalSegments: [ - {'code': 'subtotal', 'title': 'Subtotal', 'value': 39.36}, - {'code': 'shipping', 'title': 'Shipping & Handling (Flat Rate - Fixed)', 'value': 5} + { code: 'subtotal', title: 'Subtotal', value: 39.36 }, + { + code: 'shipping', + title: 'Shipping & Handling (Flat Rate - Fixed)', + value: 5 + } ], - cartItems: [ - {qty: 1, priceInclTax: 1}, - {qty: 2, priceInclTax: 2} - ] + cartItems: [{ qty: 1, priceInclTax: 1 }, { qty: 2, priceInclTax: 2 }] }; const wrapper = (getters: any) => getters.totals(stateMock); expect(wrapper(cartGetters)).toEqual([ - {"code": "subtotalInclTax", "title": "Subtotal incl. tax", "value": 5}, - {"code": "grand_total", "title": "Grand total", "value": 5} + { code: 'subtotalInclTax', title: 'Subtotal incl. tax', value: 5 }, + { code: 'grand_total', title: 'Grand total', value: 5 } ]); }); it(`totals returns totals including shipping and payment prices having these prices in store but no platformTotalSegments`, () => { const stateMock = { - cartItems: [ - {qty: 1, priceInclTax: 1}, - {qty: 2, priceInclTax: 2} - ], + cartItems: [{ qty: 1, priceInclTax: 1 }, { qty: 2, priceInclTax: 2 }], payment: { title: 'payment', - costInclTax: 4, + costInclTax: 4 }, shipping: { method_title: 'shipping', - price_incl_tax: 8, + price_incl_tax: 8 } }; const wrapper = (getters: any) => getters.totals(stateMock); expect(wrapper(cartGetters)).toEqual([ - {"code": "subtotalInclTax", "title": "Subtotal incl. tax", "value": 5}, - {"code": "grand_total", "title": "Grand total", "value": 21}, - {"code": "payment", "title": "payment", "value": 4}, - {"code": "shipping", "title": "shipping", "value": 8} + { code: 'subtotalInclTax', title: 'Subtotal incl. tax', value: 5 }, + { code: 'grand_total', title: 'Grand total', value: 21 }, + { code: 'payment', title: 'payment', value: 4 }, + { code: 'shipping', title: 'shipping', value: 8 } ]); }); it(`totals returns totals including first shipping and first payment prices having multiple prices in store but no platformTotalSegments`, () => { const stateMock = { - cartItems: [ - {qty: 1, priceInclTax: 1}, - {qty: 2, priceInclTax: 2} - ], + cartItems: [{ qty: 1, priceInclTax: 1 }, { qty: 2, priceInclTax: 2 }], payment: [ { title: 'payment', - costInclTax: 4, + costInclTax: 4 }, { title: 'another-payment', - costInclTax: 16, + costInclTax: 16 } ], shipping: [ { method_title: 'shipping', - price_incl_tax: 8, + price_incl_tax: 8 }, { method_title: 'another-shipping', - price_incl_tax: 32, + price_incl_tax: 32 } ] }; const wrapper = (getters: any) => getters.totals(stateMock); expect(wrapper(cartGetters)).toEqual([ - {"code": "subtotalInclTax", "title": "Subtotal incl. tax", "value": 5}, - {"code": "grand_total", "title": "Grand total", "value": 21}, - {"code": "payment", "title": "payment", "value": 4}, - {"code": "shipping", "title": "shipping", "value": 8} + { code: 'subtotalInclTax', title: 'Subtotal incl. tax', value: 5 }, + { code: 'grand_total', title: 'Grand total', value: 21 }, + { code: 'payment', title: 'payment', value: 4 }, + { code: 'shipping', title: 'shipping', value: 8 } ]); }); it('totalQuantity returns total quantity of all products in cart if minicart configuration is set to quantities', () => { const stateMock = { - cartItems: [ - {qty: 1}, - {qty: 2} - ] + cartItems: [{ qty: 1 }, { qty: 2 }] }; const rootStoreMock = { @@ -155,17 +160,15 @@ describe('Cart getters', () => { } }; - const wrapper = (getters: any) => getters.totalQuantity(stateMock, {}, rootStoreMock); + const wrapper = (getters: any) => + getters.totalQuantity(stateMock, {}, rootStoreMock); expect(wrapper(cartGetters)).toBe(3); }); it('totalQuantity returns number of different products instead of their sum if minicart configuration is set to items', () => { const stateMock = { - cartItems: [ - {qty: 1}, - {qty: 2} - ] + cartItems: [{ qty: 1 }, { qty: 2 }] }; const rootStoreMock = { @@ -176,7 +179,8 @@ describe('Cart getters', () => { } }; - const wrapper = (getters: any) => getters.totalQuantity(stateMock, {}, rootStoreMock); + const wrapper = (getters: any) => + getters.totalQuantity(stateMock, {}, rootStoreMock); expect(wrapper(cartGetters)).toBe(2); }); @@ -205,10 +209,7 @@ describe('Cart getters', () => { it('isVirtualCart returns true given only virtual items in cart', () => { const stateMock = { - cartItems: [ - {type_id: 'virtual'}, - {type_id: 'downloadable'} - ] + cartItems: [{ type_id: 'virtual' }, { type_id: 'downloadable' }] }; const wrapper = (getters: any) => getters.isVirtualCart(stateMock); @@ -217,10 +218,7 @@ describe('Cart getters', () => { it('isVirtualCart returns false given any non virtual items in cart', () => { const stateMock = { - cartItems: [ - {type_id: 'virtual'}, - {type_id: 'definitely-not-virtual'} - ] + cartItems: [{ type_id: 'virtual' }, { type_id: 'definitely-not-virtual' }] }; const wrapper = (getters: any) => getters.isVirtualCart(stateMock); diff --git a/core/modules/cart/test/unit/store/index.spec.ts b/core/modules/cart/test/unit/store/index.spec.ts index fbd42d8836..5813c2ffea 100644 --- a/core/modules/cart/test/unit/store/index.spec.ts +++ b/core/modules/cart/test/unit/store/index.spec.ts @@ -1,4 +1,4 @@ -import { module } from '../../../store' +import { module } from '../../../store'; jest.mock('../../../store/actions', () => ({})); jest.mock('../../../store/getters', () => ({})); @@ -6,6 +6,6 @@ jest.mock('../../../store/mutations', () => ({})); describe('Cart Module', () => { it('can be loaded', () => { - expect(module).toBeTruthy() - }) + expect(module).toBeTruthy(); + }); }); diff --git a/core/modules/cart/test/unit/store/mutations.spec.ts b/core/modules/cart/test/unit/store/mutations.spec.ts index 7ec3b8d096..c9f225a0cc 100644 --- a/core/modules/cart/test/unit/store/mutations.spec.ts +++ b/core/modules/cart/test/unit/store/mutations.spec.ts @@ -1,32 +1,32 @@ -import Vue from 'vue' +import Vue from 'vue'; -import * as types from '../../../store/mutation-types' -import cartMutations from '../../../store/mutations' +import * as types from '../../../store/mutation-types'; +import cartMutations from '../../../store/mutations'; Vue.prototype.$bus = { $emit: jest.fn() -} +}; jest.mock('@vue-storefront/core/store', () => ({ state: { config: {} } -})) +})); describe('Cart mutations', () => { beforeEach(() => { - jest.clearAllMocks() - }) + jest.clearAllMocks(); + }); describe('CART_ADD_ITEM', () => { it('adds a product to cart if none of its sku is there yet', () => { const stateMock = { cartItems: [] - } + }; const product = { qty: 123, sku: 'foo' - } + }; const expectedState = { cartItems: [ { @@ -34,22 +34,25 @@ describe('Cart mutations', () => { sku: 'foo' } ] - } - const wrapper = (mutations: any) => mutations[types.CART_ADD_ITEM](stateMock, { product }) + }; + const wrapper = (mutations: any) => + mutations[types.CART_ADD_ITEM](stateMock, { product }); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-add', { product }) - expect(stateMock).toEqual(expectedState) - }) + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-add', { + product + }); + expect(stateMock).toEqual(expectedState); + }); it('adds a product to cart with quantity of 1 if none of its sku is there yet and product qty is not provided', () => { const stateMock = { cartItems: [] - } + }; const product = { sku: 'foo' - } + }; const expectedState = { cartItems: [ { @@ -57,14 +60,17 @@ describe('Cart mutations', () => { sku: 'foo' } ] - } - const wrapper = (mutations: any) => mutations[types.CART_ADD_ITEM](stateMock, { product }) + }; + const wrapper = (mutations: any) => + mutations[types.CART_ADD_ITEM](stateMock, { product }); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-add', { product: { ...product, qty: 1 } }) - expect(stateMock).toEqual(expectedState) - }) + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-add', { + product: { ...product, qty: 1 } + }); + expect(stateMock).toEqual(expectedState); + }); it('increases quantity of a a product in cart if one of its sku is already there', () => { const stateMock = { @@ -74,11 +80,11 @@ describe('Cart mutations', () => { sku: 'foo' } ] - } + }; const product = { qty: 10, sku: 'foo' - } + }; const expectedState = { cartItems: [ { @@ -86,13 +92,14 @@ describe('Cart mutations', () => { sku: 'foo' } ] - } - const wrapper = (mutations: any) => mutations[types.CART_ADD_ITEM](stateMock, { product }) + }; + const wrapper = (mutations: any) => + mutations[types.CART_ADD_ITEM](stateMock, { product }); - wrapper(cartMutations) + wrapper(cartMutations); - expect(stateMock).toEqual(expectedState) - }) + expect(stateMock).toEqual(expectedState); + }); it('increases quantity of a a product in cart by 1 if quantity was not provided', () => { const stateMock = { @@ -102,10 +109,10 @@ describe('Cart mutations', () => { sku: 'foo' } ] - } + }; const product = { sku: 'foo' - } + }; const expectedState = { cartItems: [ { @@ -113,14 +120,15 @@ describe('Cart mutations', () => { sku: 'foo' } ] - } - const wrapper = (mutations: any) => mutations[types.CART_ADD_ITEM](stateMock, {product}) + }; + const wrapper = (mutations: any) => + mutations[types.CART_ADD_ITEM](stateMock, { product }); - wrapper(cartMutations) + wrapper(cartMutations); - expect(stateMock).toEqual(expectedState) - }) - }) + expect(stateMock).toEqual(expectedState); + }); + }); it('CART_SAVE emits cart-before-save and updates save date', () => { const stateMock = { @@ -131,7 +139,7 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [ { @@ -140,16 +148,18 @@ describe('Cart mutations', () => { } ], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_SAVE](stateMock) + }; + const wrapper = (mutations: any) => mutations[types.CART_SAVE](stateMock); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-save', {items: stateMock.cartItems}) - expect(stateMock).toEqual(expectedState) - }) + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-save', { + items: stateMock.cartItems + }); + expect(stateMock).toEqual(expectedState); + }); describe('CART_DEL_ITEM', () => { it('removes product from cart by sku', () => { @@ -161,32 +171,34 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_DEL_ITEM]( - stateMock, - { - product: {sku: 'foo'}, + }; + const wrapper = (mutations: any) => + mutations[types.CART_DEL_ITEM](stateMock, { + product: { sku: 'foo' }, removeByParentSku: false - } - ) + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-delete', { - items: [{ - qty: 10, - sku: 'foo' - }] - }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', {items: expectedState.cartItems}) - expect(stateMock).toEqual(expectedState) - }) + items: [ + { + qty: 10, + sku: 'foo' + } + ] + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', { + items: expectedState.cartItems + }); + expect(stateMock).toEqual(expectedState); + }); it('removes product from cart by parent sku', () => { const stateMock = { @@ -197,32 +209,34 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_DEL_ITEM]( - stateMock, - { - product: {parentSku: 'foo'} - } - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_DEL_ITEM](stateMock, { + product: { parentSku: 'foo' } + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-delete', { - items: [{ - qty: 10, - sku: 'foo' - }] - }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', {items: expectedState.cartItems}) - expect(stateMock).toEqual(expectedState) - }) - }) + items: [ + { + qty: 10, + sku: 'foo' + } + ] + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', { + items: expectedState.cartItems + }); + expect(stateMock).toEqual(expectedState); + }); + }); describe('CART_DEL_NON_CONFIRMED_ITEM', () => { it('removes product from cart by sku', () => { @@ -234,32 +248,34 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_DEL_NON_CONFIRMED_ITEM]( - stateMock, - { - product: {sku: 'foo'}, + }; + const wrapper = (mutations: any) => + mutations[types.CART_DEL_NON_CONFIRMED_ITEM](stateMock, { + product: { sku: 'foo' }, removeByParentSku: false - } - ) + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-delete', { - items: [{ - qty: 10, - sku: 'foo' - }] - }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', {items: expectedState.cartItems}) - expect(stateMock).toEqual(expectedState) - }) + items: [ + { + qty: 10, + sku: 'foo' + } + ] + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', { + items: expectedState.cartItems + }); + expect(stateMock).toEqual(expectedState); + }); it('removes product from cart by parent sku', () => { const stateMock = { @@ -270,31 +286,33 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_DEL_NON_CONFIRMED_ITEM]( - stateMock, - { - product: {parentSku: 'foo'} - } - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_DEL_NON_CONFIRMED_ITEM](stateMock, { + product: { parentSku: 'foo' } + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-delete', { - items: [{ - qty: 10, - sku: 'foo' - }] - }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', {items: expectedState.cartItems}) - expect(stateMock).toEqual(expectedState) - }) + items: [ + { + qty: 10, + sku: 'foo' + } + ] + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', { + items: expectedState.cartItems + }); + expect(stateMock).toEqual(expectedState); + }); it('does not remove a product that has server_item_id set, so it surely exists in the backend', () => { const stateMock = { @@ -306,7 +324,7 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [ { @@ -316,24 +334,26 @@ describe('Cart mutations', () => { } ], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_DEL_NON_CONFIRMED_ITEM]( - stateMock, - { - product: {sku: 'foo'}, + }; + const wrapper = (mutations: any) => + mutations[types.CART_DEL_NON_CONFIRMED_ITEM](stateMock, { + product: { sku: 'foo' }, removeByParentSku: false - } - ) + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-delete', {items: stateMock.cartItems}) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', {items: expectedState.cartItems}) - expect(stateMock).toEqual(expectedState) - }) - }) + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-delete', { + items: stateMock.cartItems + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-delete', { + items: expectedState.cartItems + }); + expect(stateMock).toEqual(expectedState); + }); + }); describe('CART_UPD_ITEM', () => { it('updates product quantity by sku', () => { @@ -345,7 +365,7 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [ { @@ -354,27 +374,29 @@ describe('Cart mutations', () => { } ], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_UPD_ITEM]( - stateMock, - { + }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_ITEM](stateMock, { product: { sku: 'foo' }, qty: 20 - } - ) + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); // unfortunately before and after events return a reference to the same object, therefore // after performing this mutation after event return same object with same, updated value as before event - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-update', { product: expectedState.cartItems[0] }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-update', { product: expectedState.cartItems[0] }) - expect(stateMock).toEqual(expectedState) - }) - - it('doesn\'t update anything if product is not found in cart', () => { + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-before-update', { + product: expectedState.cartItems[0] + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-update', { + product: expectedState.cartItems[0] + }); + expect(stateMock).toEqual(expectedState); + }); + + it("doesn't update anything if product is not found in cart", () => { const stateMock = { cartItems: [ { @@ -383,24 +405,22 @@ describe('Cart mutations', () => { } ], cartSavedAt: 0 - } - const expectedState = { ...stateMock } - const wrapper = (mutations: any) => mutations[types.CART_UPD_ITEM]( - stateMock, - { - product: {sku: 'qux'}, + }; + const expectedState = { ...stateMock }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_ITEM](stateMock, { + product: { sku: 'qux' }, qty: 20 - } - ) + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).not.toBeCalled() - expect(stateMock).toEqual(expectedState) - }) - }) + expect(Vue.prototype.$bus.$emit).not.toBeCalled(); + expect(stateMock).toEqual(expectedState); + }); + }); describe('CART_UPD_ITEM_PROPS', () => { it('updates product properties by sku', () => { @@ -413,7 +433,7 @@ describe('Cart mutations', () => { } ], cartSavedAt: new Date(0) - } + }; const expectedState = { cartItems: [ { @@ -423,27 +443,31 @@ describe('Cart mutations', () => { } ], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_UPD_ITEM_PROPS]( - stateMock, - { - product: {sku: 'foo', someProp: 'baz', qty: 20} - } - ) - let firstEmitCall = [] + }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_ITEM_PROPS](stateMock, { + product: { sku: 'foo', someProp: 'baz', qty: 20 } + }); + let firstEmitCall = []; Vue.prototype.$bus.$emit.mockImplementationOnce((eventName, args) => { - firstEmitCall.push(eventName) - firstEmitCall.push(args) - }) - Date.now = jest.fn(() => expectedState.cartSavedAt) - - wrapper(cartMutations) - - expect(firstEmitCall).toEqual(['cart-before-itemchanged', { item: expectedState.cartItems[0] }]) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-itemchanged', { item: expectedState.cartItems[0] }) - expect(stateMock).toEqual(expectedState) - }) + firstEmitCall.push(eventName); + firstEmitCall.push(args); + }); + Date.now = jest.fn(() => expectedState.cartSavedAt); + + wrapper(cartMutations); + + expect(firstEmitCall).toEqual([ + 'cart-before-itemchanged', + { item: expectedState.cartItems[0] } + ]); + expect(Vue.prototype.$bus.$emit).toBeCalledWith( + 'cart-after-itemchanged', + { item: expectedState.cartItems[0] } + ); + expect(stateMock).toEqual(expectedState); + }); it('updates product properties by server_item_id', () => { const stateMock = { @@ -456,7 +480,7 @@ describe('Cart mutations', () => { } ], cartSavedAt: 0 - } + }; const expectedState = { cartItems: [ { @@ -467,29 +491,33 @@ describe('Cart mutations', () => { } ], cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_UPD_ITEM_PROPS]( - stateMock, - { - product: {server_item_id: 123, sku: 'bar', someProp: 'baz', qty: 20} - } - ) - let firstEmitCall = [] + }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_ITEM_PROPS](stateMock, { + product: { server_item_id: 123, sku: 'bar', someProp: 'baz', qty: 20 } + }); + let firstEmitCall = []; Vue.prototype.$bus.$emit.mockImplementationOnce((eventName, args) => { - firstEmitCall.push(eventName) - firstEmitCall.push(args) - }) - Date.now = jest.fn(() => expectedState.cartSavedAt) - - wrapper(cartMutations) - - expect(firstEmitCall).toEqual(['cart-before-itemchanged', { item: expectedState.cartItems[0] }]) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-itemchanged', { item: expectedState.cartItems[0] }) - expect(stateMock).toEqual(expectedState) - }) - - it('doesn\'t update anything if product is not found in cart', () => { + firstEmitCall.push(eventName); + firstEmitCall.push(args); + }); + Date.now = jest.fn(() => expectedState.cartSavedAt); + + wrapper(cartMutations); + + expect(firstEmitCall).toEqual([ + 'cart-before-itemchanged', + { item: expectedState.cartItems[0] } + ]); + expect(Vue.prototype.$bus.$emit).toBeCalledWith( + 'cart-after-itemchanged', + { item: expectedState.cartItems[0] } + ); + expect(stateMock).toEqual(expectedState); + }); + + it("doesn't update anything if product is not found in cart", () => { const stateMock = { cartItems: [ { @@ -499,47 +527,43 @@ describe('Cart mutations', () => { } ], cartSavedAt: 0 - } - const expectedState = { ...stateMock } - const wrapper = (mutations: any) => mutations[types.CART_UPD_ITEM_PROPS]( - stateMock, - { - product: {sku: 'qux', someProp: 'baz', qty: 20} - } - ) + }; + const expectedState = { ...stateMock }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_ITEM_PROPS](stateMock, { + product: { sku: 'qux', someProp: 'baz', qty: 20 } + }); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).not.toBeCalled() - expect(stateMock).toEqual(expectedState) - }) - }) + expect(Vue.prototype.$bus.$emit).not.toBeCalled(); + expect(stateMock).toEqual(expectedState); + }); + }); it('CART_UPD_SHIPPING sets given shipping method', () => { const stateMock = { shipping: 'foo', cartSavedAt: 0 - } + }; const expectedState = { shipping: 'bar', cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_UPD_SHIPPING]( - stateMock, - expectedState.shipping - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_SHIPPING](stateMock, expectedState.shipping); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(stateMock).toEqual(expectedState) - }) + expect(stateMock).toEqual(expectedState); + }); it('CART_LOAD_CART initializes cart with given products', () => { - const stateMock = {} + const stateMock = {}; const expectedState = { cartItems: [ { @@ -549,60 +573,62 @@ describe('Cart mutations', () => { ], cartIsLoaded: true, cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_LOAD_CART]( - stateMock, - expectedState.cartItems - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_LOAD_CART](stateMock, expectedState.cartItems); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).toBeCalledWith('sync/PROCESS_QUEUE', { config: {} }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('application-after-loaded') - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-loaded') - expect(stateMock).toEqual(expectedState) - }) + expect(Vue.prototype.$bus.$emit).toBeCalledWith('sync/PROCESS_QUEUE', { + config: {} + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('application-after-loaded'); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-loaded'); + expect(stateMock).toEqual(expectedState); + }); it('CART_LOAD_CART initializes an empty cart when no products are given', () => { - const stateMock = {} + const stateMock = {}; const expectedState = { cartItems: [], cartIsLoaded: true, cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_LOAD_CART]( - stateMock - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_LOAD_CART](stateMock); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(Vue.prototype.$bus.$emit).toBeCalledWith('sync/PROCESS_QUEUE', { config: {} }) - expect(Vue.prototype.$bus.$emit).toBeCalledWith('application-after-loaded') - expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-loaded') - expect(stateMock).toEqual(expectedState) - }) + expect(Vue.prototype.$bus.$emit).toBeCalledWith('sync/PROCESS_QUEUE', { + config: {} + }); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('application-after-loaded'); + expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-loaded'); + expect(stateMock).toEqual(expectedState); + }); it('CART_LOAD_CART_SERVER_TOKEN saves given cart token in cart data', () => { - const stateMock = {} + const stateMock = {}; const expectedState = { cartServerToken: 'foo' - } - const wrapper = (mutations: any) => mutations[types.CART_LOAD_CART_SERVER_TOKEN]( - stateMock, - expectedState.cartServerToken - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_LOAD_CART_SERVER_TOKEN]( + stateMock, + expectedState.cartServerToken + ); - wrapper(cartMutations) + wrapper(cartMutations); - expect(stateMock).toEqual(expectedState) - }) + expect(stateMock).toEqual(expectedState); + }); it('CART_UPD_TOTALS updates totals related data', () => { - const stateMock = {} + const stateMock = {}; const expectedState = { cartServerTotalsAt: 1445412480000, itemsAfterPlatformTotals: ['foo'], @@ -610,64 +636,64 @@ describe('Cart mutations', () => { bar: 1 /** @todo replace with real alike data to show what it can be filled with */ }, platformTotalSegments: [ - {'code': 'subtotal', 'title': 'Subtotal', 'value': 39.36}, - {'code': 'grand_total', 'title': 'Grand Total', 'value': 39.36, 'area': 'footer'} + { code: 'subtotal', title: 'Subtotal', value: 39.36 }, + { + code: 'grand_total', + title: 'Grand Total', + value: 39.36, + area: 'footer' + } ] - } - const wrapper = (mutations: any) => mutations[types.CART_UPD_TOTALS]( - stateMock, - { + }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_TOTALS](stateMock, { itemsAfterTotals: expectedState.itemsAfterPlatformTotals, totals: expectedState.platformTotals, platformTotalSegments: expectedState.platformTotalSegments - } - ) + }); - Date.now = jest.fn(() => expectedState.cartServerTotalsAt) + Date.now = jest.fn(() => expectedState.cartServerTotalsAt); - wrapper(cartMutations) + wrapper(cartMutations); expect(Vue.prototype.$bus.$emit).toBeCalledWith('cart-after-updatetotals', { platformTotals: expectedState.platformTotals, platformTotalSegments: expectedState.platformTotalSegments - }) - expect(stateMock).toEqual(expectedState) - }) + }); + expect(stateMock).toEqual(expectedState); + }); it('CART_UPD_PAYMENT sets given payment method', () => { const stateMock = { payment: 'foo', cartSavedAt: 0 - } + }; const expectedState = { payment: 'bar', cartSavedAt: 1445412480000 - } - const wrapper = (mutations: any) => mutations[types.CART_UPD_PAYMENT]( - stateMock, - expectedState.payment - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_UPD_PAYMENT](stateMock, expectedState.payment); - Date.now = jest.fn(() => expectedState.cartSavedAt) + Date.now = jest.fn(() => expectedState.cartSavedAt); - wrapper(cartMutations) + wrapper(cartMutations); - expect(stateMock).toEqual(expectedState) - }) + expect(stateMock).toEqual(expectedState); + }); it('CART_TOGGLE_MICROCART changes microcart open status to the opposite one', () => { const stateMock = { isMicrocartOpen: true - } + }; const expectedState = { isMicrocartOpen: false - } - const wrapper = (mutations: any) => mutations[types.CART_TOGGLE_MICROCART]( - stateMock - ) + }; + const wrapper = (mutations: any) => + mutations[types.CART_TOGGLE_MICROCART](stateMock); - wrapper(cartMutations) + wrapper(cartMutations); - expect(stateMock).toEqual(expectedState) - }) -}) + expect(stateMock).toEqual(expectedState); + }); +}); diff --git a/core/modules/cart/types/AppliedCoupon.ts b/core/modules/cart/types/AppliedCoupon.ts index 9a958258f3..c9ebaf8961 100644 --- a/core/modules/cart/types/AppliedCoupon.ts +++ b/core/modules/cart/types/AppliedCoupon.ts @@ -1,4 +1,4 @@ export default interface AppliedCoupon { - code: string, - discount: number -} \ No newline at end of file + code: string; + discount: number; +} diff --git a/core/modules/cart/types/CartItem.ts b/core/modules/cart/types/CartItem.ts index 70251edfb3..38da9dbbe2 100644 --- a/core/modules/cart/types/CartItem.ts +++ b/core/modules/cart/types/CartItem.ts @@ -1,12 +1,12 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; -import CartItemOption from './CartItemOption' -import CartItemTotals from './CartItemTotals' +import CartItemOption from './CartItemOption'; +import CartItemTotals from './CartItemTotals'; export default interface CartItem extends Product { - qty: number, - options: CartItemOption[], - totals: CartItemTotals, - server_item_id: number, - server_cart_id: any + qty: number; + options: CartItemOption[]; + totals: CartItemTotals; + server_item_id: number; + server_cart_id: any; } diff --git a/core/modules/cart/types/CartItemOption.ts b/core/modules/cart/types/CartItemOption.ts index 58bbafb038..6f368ba6b7 100644 --- a/core/modules/cart/types/CartItemOption.ts +++ b/core/modules/cart/types/CartItemOption.ts @@ -1,4 +1,4 @@ export default interface CartItemOption { - label: string, - value: string + label: string; + value: string; } diff --git a/core/modules/cart/types/CartItemTotals.ts b/core/modules/cart/types/CartItemTotals.ts index 969fb4bed6..4ed503323b 100644 --- a/core/modules/cart/types/CartItemTotals.ts +++ b/core/modules/cart/types/CartItemTotals.ts @@ -1,24 +1,23 @@ - -import CartItemOption from './CartItemOption' +import CartItemOption from './CartItemOption'; export default interface CartItemTotals { - base_discount_amount: number, - base_price: number, - base_price_incl_tax: number, - base_row_total: number, - base_row_total_incl_tax: number, - base_tax_amount: number, - discount_amount: number, - discount_percent: number, - item_id: number, - name: string, - options: CartItemOption[], - price: number, - price_incl_tax: number, - qty: number, - row_total: number, - row_total_incl_tax: number, - row_total_with_discount: number, - tax_amount: number, - tax_percent: number -} \ No newline at end of file + base_discount_amount: number; + base_price: number; + base_price_incl_tax: number; + base_row_total: number; + base_row_total_incl_tax: number; + base_tax_amount: number; + discount_amount: number; + discount_percent: number; + item_id: number; + name: string; + options: CartItemOption[]; + price: number; + price_incl_tax: number; + qty: number; + row_total: number; + row_total_incl_tax: number; + row_total_with_discount: number; + tax_amount: number; + tax_percent: number; +} diff --git a/core/modules/cart/types/CartState.ts b/core/modules/cart/types/CartState.ts index 06970d27fc..a7db736975 100644 --- a/core/modules/cart/types/CartState.ts +++ b/core/modules/cart/types/CartState.ts @@ -1,20 +1,20 @@ export default interface CartState { - isMicrocartOpen: boolean, - itemsAfterPlatformTotals: any, - platformTotals: any, - platformTotalSegments: any, - cartIsLoaded: boolean, - cartServerPullAt: number, - cartServerTotalsAt: number, - cartServerCreatedAt: number, - cartServerMethodsRefreshAt: number, - cartServerBypassAt: number, - cartSavedAt: number, - bypassToAnon: boolean, - cartServerToken: string, - shipping: any, - payment: any, - cartItemsHash: string, - bypassCount: number, - cartItems: any[] + isMicrocartOpen: boolean; + itemsAfterPlatformTotals: any; + platformTotals: any; + platformTotalSegments: any; + cartIsLoaded: boolean; + cartServerPullAt: number; + cartServerTotalsAt: number; + cartServerCreatedAt: number; + cartServerMethodsRefreshAt: number; + cartServerBypassAt: number; + cartSavedAt: number; + bypassToAnon: boolean; + cartServerToken: string; + shipping: any; + payment: any; + cartItemsHash: string; + bypassCount: number; + cartItems: any[]; } diff --git a/core/modules/cart/types/CartTotalSegments.ts b/core/modules/cart/types/CartTotalSegments.ts index 5c8756a510..66033abc83 100644 --- a/core/modules/cart/types/CartTotalSegments.ts +++ b/core/modules/cart/types/CartTotalSegments.ts @@ -1,2 +1,3 @@ -import CartTotalSegmentsItem from './CartTotalSegmentsItem' -export default interface CartTotalSegments extends Array{} +import CartTotalSegmentsItem from './CartTotalSegmentsItem'; +export default interface CartTotalSegments + extends Array {} diff --git a/core/modules/cart/types/CartTotalSegmentsItem.ts b/core/modules/cart/types/CartTotalSegmentsItem.ts index cb818b885a..daa5078d1b 100644 --- a/core/modules/cart/types/CartTotalSegmentsItem.ts +++ b/core/modules/cart/types/CartTotalSegmentsItem.ts @@ -1,7 +1,7 @@ export default interface CartTotalSegmentsItem { - code: string, - title: string, - value: number, - area?: string, - extension_attributes?: object + code: string; + title: string; + value: number; + area?: string; + extension_attributes?: object; } diff --git a/core/modules/catalog/components/CategoryFilters.ts b/core/modules/catalog/components/CategoryFilters.ts index 75b9baf952..966c8dba3f 100644 --- a/core/modules/catalog/components/CategoryFilters.ts +++ b/core/modules/catalog/components/CategoryFilters.ts @@ -1,31 +1,43 @@ -import { buildFilterProductsQuery } from '@vue-storefront/core/helpers' +import { buildFilterProductsQuery } from '@vue-storefront/core/helpers'; import { mapGetters } from 'vuex'; export default { name: 'CategoryFilters', computed: { - ...mapGetters('category', ['getActiveCategoryFilters', 'getCurrentCategoryProductQuery', 'getAllCategoryFilters']), - filters () { - return this.getAllCategoryFilters + ...mapGetters('category', [ + 'getActiveCategoryFilters', + 'getCurrentCategoryProductQuery', + 'getAllCategoryFilters' + ]), + filters() { + return this.getAllCategoryFilters; }, - activeFilters () { - return this.getActiveCategoryFilters + activeFilters() { + return this.getActiveCategoryFilters; } }, methods: { /** used to sort filters descending by id */ - sortById (filters) { - return [...filters].sort((a, b) => { return a.id - b.id }) + sortById(filters) { + return [...filters].sort((a, b) => { + return a.id - b.id; + }); }, - resetAllFilters () { + resetAllFilters() { // todo: get rid of this one - this.$bus.$emit('filter-reset') - this.$store.dispatch('category/resetFilters') - this.$store.dispatch('category/searchProductQuery', {}) + this.$bus.$emit('filter-reset'); + this.$store.dispatch('category/resetFilters'); + this.$store.dispatch('category/searchProductQuery', {}); this.$store.dispatch('category/mergeSearchOptions', { - searchProductQuery: buildFilterProductsQuery(this.category, this.activeFilters) - }) - this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery) + searchProductQuery: buildFilterProductsQuery( + this.category, + this.activeFilters + ) + }); + this.$store.dispatch( + 'category/products', + this.getCurrentCategoryProductQuery + ); } } -} +}; diff --git a/core/modules/catalog/components/CategorySort.ts b/core/modules/catalog/components/CategorySort.ts index 9c867979dc..94b9e6e467 100644 --- a/core/modules/catalog/components/CategorySort.ts +++ b/core/modules/catalog/components/CategorySort.ts @@ -1,19 +1,19 @@ export const CategorySort = { name: 'SortBy', - data () { + data() { return { sortby: '' - } + }; }, methods: { // emit to category, todo: move all logic inside - sort () { - this.$bus.$emit('list-change-sort', { attribute: this.sortby }) + sort() { + this.$bus.$emit('list-change-sort', { attribute: this.sortby }); } }, computed: { - sortingOptions () { - return this.$store.state.config.products.sortByAttributes + sortingOptions() { + return this.$store.state.config.products.sortByAttributes; } } -} +}; diff --git a/core/modules/catalog/components/ProductAttribute.ts b/core/modules/catalog/components/ProductAttribute.ts index d3ab9d01a3..ea328e5525 100644 --- a/core/modules/catalog/components/ProductAttribute.ts +++ b/core/modules/catalog/components/ProductAttribute.ts @@ -15,41 +15,49 @@ export const ProductAttribute = { } }, computed: { - label () { - return (this.attribute && this.attribute.default_frontend_label) ? this.attribute.default_frontend_label : '' + label() { + return this.attribute && this.attribute.default_frontend_label + ? this.attribute.default_frontend_label + : ''; }, - value () { - let parsedValues = this.product[this.attribute.attribute_code] + value() { + let parsedValues = this.product[this.attribute.attribute_code]; if (!parsedValues) { - return this.emptyPlaceholder - } else if (this.attribute.frontend_input !== 'multiselect' && this.attribute.frontend_input !== 'select') { - return parsedValues.toString() + return this.emptyPlaceholder; + } else if ( + this.attribute.frontend_input !== 'multiselect' && + this.attribute.frontend_input !== 'select' + ) { + return parsedValues.toString(); } else { - parsedValues = typeof parsedValues === 'string' ? parsedValues.split(',') : parsedValues + parsedValues = + typeof parsedValues === 'string' + ? parsedValues.split(',') + : parsedValues; if (!Array.isArray(parsedValues)) { - parsedValues = [parsedValues] + parsedValues = [parsedValues]; } - let results = [] + let results = []; for (let parsedVal of parsedValues) { if (this.attribute.options) { let option = this.attribute.options.find(av => { /* eslint eqeqeq: "off" */ - return av.value == parsedVal - }) + return av.value == parsedVal; + }); if (option) { - results.push(option.label) + results.push(option.label); } else { - results.push(parsedVal) + results.push(parsedVal); } } else { - results.push(parsedVal) + results.push(parsedVal); } } - return results.join(', ') + return results.join(', '); } } } -} +}; diff --git a/core/modules/catalog/components/ProductBundleOption.ts b/core/modules/catalog/components/ProductBundleOption.ts index a0821a8f76..a7b807bff0 100644 --- a/core/modules/catalog/components/ProductBundleOption.ts +++ b/core/modules/catalog/components/ProductBundleOption.ts @@ -1,4 +1,4 @@ -import rootStore from '@vue-storefront/core/store' +import rootStore from '@vue-storefront/core/store'; export const ProductBundleOption = { name: 'ProductBundleOption', @@ -12,63 +12,69 @@ export const ProductBundleOption = { default: null } }, - data () { + data() { return { productOptionId: null, quantity: 1 - } + }; }, computed: { productBundleOption() { - return `bundleOption_${this.option.option_id}` + return `bundleOption_${this.option.option_id}`; }, bundleOptionName() { - return `bundleOption_${this._uid}_${this.option.option_id}_` + return `bundleOption_${this._uid}_${this.option.option_id}_`; }, quantityName() { - return `bundleOptionQty_${this.option.option_id}` + return `bundleOptionQty_${this.option.option_id}`; }, value() { - return this.option.product_links.find(product => product.id === this.productOptionId) + return this.option.product_links.find( + product => product.id === this.productOptionId + ); }, errorMessage() { - return this.errorMessages ? this.errorMessages[this.quantityName] : "" + return this.errorMessages ? this.errorMessages[this.quantityName] : ''; } }, mounted() { - this.setDefaultValues() + this.setDefaultValues(); if (rootStore.state.config.usePriceTiers) { - this.$bus.$on('product-after-setup-associated', this.setDefaultValues) + this.$bus.$on('product-after-setup-associated', this.setDefaultValues); } }, - beforeDestroy () { + beforeDestroy() { if (rootStore.state.config.usePriceTiers) { - this.$bus.$off('product-after-setup-associated', this.setDefaultValues) + this.$bus.$off('product-after-setup-associated', this.setDefaultValues); } }, watch: { productOptionId(value) { - this.bundleOptionChanged() + this.bundleOptionChanged(); }, quantity(value) { - this.bundleOptionChanged() + this.bundleOptionChanged(); } }, methods: { setDefaultValues() { - if(this.option.product_links) { - const defaultOption = this.option.product_links.find(pl => { return pl.is_default }) - this.productOptionId = defaultOption ? defaultOption.id : this.option.product_links[0].id - this.quantity = defaultOption ? defaultOption.qty : 1 + if (this.option.product_links) { + const defaultOption = this.option.product_links.find(pl => { + return pl.is_default; + }); + this.productOptionId = defaultOption + ? defaultOption.id + : this.option.product_links[0].id; + this.quantity = defaultOption ? defaultOption.qty : 1; } }, bundleOptionChanged() { this.$emit('optionChanged', { option: this.option, - fieldName: this.productBundleOption, + fieldName: this.productBundleOption, qty: this.quantity, value: this.value - }) + }); } } -} +}; diff --git a/core/modules/catalog/components/ProductBundleOptions.ts b/core/modules/catalog/components/ProductBundleOptions.ts index bf77899d8b..a8a28e385b 100644 --- a/core/modules/catalog/components/ProductBundleOptions.ts +++ b/core/modules/catalog/components/ProductBundleOptions.ts @@ -1,11 +1,11 @@ -import { mapMutations } from 'vuex' -import * as types from '../store/product/mutation-types' -import rootStore from '@vue-storefront/core/store' -import i18n from '@vue-storefront/i18n' -import { Logger } from '@vue-storefront/core/lib/logger' +import { mapMutations } from 'vuex'; +import * as types from '../store/product/mutation-types'; +import rootStore from '@vue-storefront/core/store'; +import i18n from '@vue-storefront/i18n'; +import { Logger } from '@vue-storefront/core/lib/logger'; -function _fieldName (co) { - return ['bundleOption_' + co.option_id, 'bundleOptionQty_' + co.option_id] +function _fieldName(co) { + return ['bundleOption_' + co.option_id, 'bundleOptionQty_' + co.option_id]; } export const ProductBundleOptions = { @@ -16,95 +16,122 @@ export const ProductBundleOptions = { required: true } }, - data () { + data() { return { selectedOptions: {}, validationRules: {}, validationResults: {} - } + }; }, computed: { /** * Error messages map for validation options */ - errorMessages () { - let messages = {} + errorMessages() { + let messages = {}; Object.keys(this.validationResults).map(optionKey => { - const validationResult = this.validationResults[optionKey] + const validationResult = this.validationResults[optionKey]; if (validationResult.error) { - messages[optionKey] = validationResult.message + messages[optionKey] = validationResult.message; } - }) - return messages + }); + return messages; } }, - beforeMount () { - this.setupValidationRules() + beforeMount() { + this.setupValidationRules(); }, methods: { ...mapMutations('product', { setBundleOptionValue: types.CATALOG_UPD_BUNDLE_OPTION // map `this.add()` to `this.$store.commit('increment')` }), - setupValidationRules () { + setupValidationRules() { rootStore.dispatch('product/addCustomOptionValidator', { validationRule: 'gtzero', // You may add your own custom fields validators elsewhere in the theme - validatorFunction: (value) => { - return { error: (value === null || value === '') || (value === false) || (value <= 0), message: i18n.t('Must be greater than 0') } + validatorFunction: value => { + return { + error: + value === null || value === '' || value === false || value <= 0, + message: i18n.t('Must be greater than 0') + }; } - }) + }); for (let co of this.product.bundle_options) { for (let fieldName of _fieldName(co)) { - if (co.required) { // validation rules are very basic - this.validationRules[fieldName] = 'gtzero' // TODO: add custom validators for the custom options + if (co.required) { + // validation rules are very basic + this.validationRules[fieldName] = 'gtzero'; // TODO: add custom validators for the custom options } } } }, - optionChanged({fieldName, option, qty, value}) { - if (!fieldName) return - this.setBundleOptionValue({ optionId: option.option_id, optionQty: parseInt(qty), optionSelections: [value.id] }) - this.$store.dispatch('product/setBundleOptions', { product: this.product, bundleOptions: this.$store.state.product.current_bundle_options }) // TODO: move it to "AddToCart" - this.selectedOptions[fieldName] = {qty, value} - const valueId = value ? value.id : null + optionChanged({ fieldName, option, qty, value }) { + if (!fieldName) return; + this.setBundleOptionValue({ + optionId: option.option_id, + optionQty: parseInt(qty), + optionSelections: [value.id] + }); + this.$store.dispatch('product/setBundleOptions', { + product: this.product, + bundleOptions: this.$store.state.product.current_bundle_options + }); // TODO: move it to "AddToCart" + this.selectedOptions[fieldName] = { qty, value }; + const valueId = value ? value.id : null; if (this.validateField(option, qty, valueId)) { - this.$bus.$emit('product-after-bundleoptions', { product: this.product, option: option, optionValues: this.selectedOptions }) + this.$bus.$emit('product-after-bundleoptions', { + product: this.product, + option: option, + optionValues: this.selectedOptions + }); } }, - isValid () { - let isValid = true - this.validationResults.map((res) => { if (res.error) isValid = false }) - return isValid + isValid() { + let isValid = true; + this.validationResults.map(res => { + if (res.error) isValid = false; + }); + return isValid; }, - validateField (option, qty, optionId) { - let result = true - let validationResult = { error: false, message: '' } + validateField(option, qty, optionId) { + let result = true; + let validationResult = { error: false, message: '' }; for (let fieldName of _fieldName(option)) { - const validationRule = this.validationRules[fieldName] - this.product.errors.custom_options = null + const validationRule = this.validationRules[fieldName]; + this.product.errors.custom_options = null; if (validationRule) { - const validator = this.$store.state.product.custom_options_validators[validationRule] + const validator = this.$store.state.product.custom_options_validators[ + validationRule + ]; if (typeof validator === 'function') { - const quantityValidationResult = validator(qty) - if(quantityValidationResult.error) validationResult = quantityValidationResult - const optionValidationResult = validator(optionId) - if(optionValidationResult.error) validationResult = optionValidationResult - this.$set(this.validationResults, fieldName, validationResult) + const quantityValidationResult = validator(qty); + if (quantityValidationResult.error) + validationResult = quantityValidationResult; + const optionValidationResult = validator(optionId); + if (optionValidationResult.error) + validationResult = optionValidationResult; + this.$set(this.validationResults, fieldName, validationResult); if (validationResult.error) { - this.product.errors['bundle_options_' + fieldName] = i18n.t('Please configure product bundle options and fix the validation errors') - result = false + this.product.errors['bundle_options_' + fieldName] = i18n.t( + 'Please configure product bundle options and fix the validation errors' + ); + result = false; } else { - this.product.errors['bundle_options_' + fieldName] = null + this.product.errors['bundle_options_' + fieldName] = null; } } else { - Logger.error('No validation rule found for ' + validationRule, 'components-product-bundle-options')() - this.$set(this.validationResults, fieldName, validationResult) + Logger.error( + 'No validation rule found for ' + validationRule, + 'components-product-bundle-options' + )(); + this.$set(this.validationResults, fieldName, validationResult); } } else { - this.$set(this.validationResults, fieldName, validationResult) + this.$set(this.validationResults, fieldName, validationResult); } } - return result + return result; } } -} +}; diff --git a/core/modules/catalog/components/ProductCustomOption.ts b/core/modules/catalog/components/ProductCustomOption.ts index 898fd6a93a..5baf4f7083 100644 --- a/core/modules/catalog/components/ProductCustomOption.ts +++ b/core/modules/catalog/components/ProductCustomOption.ts @@ -22,35 +22,39 @@ export const ProductCustomOption = { default: () => false } }, - data () { + data() { return { active: false - } + }; }, - beforeMount () { - this.$bus.$on('filter-reset', this.filterReset) - this.$bus.$on('filter-changed-' + this.context, this.filterChanged) + beforeMount() { + this.$bus.$on('filter-reset', this.filterReset); + this.$bus.$on('filter-changed-' + this.context, this.filterChanged); }, - beforeDestroy () { - this.$bus.$off('filter-reset', this.filterReset) - this.$bus.$off('filter-changed-' + this.context, this.filterChanged) + beforeDestroy() { + this.$bus.$off('filter-reset', this.filterReset); + this.$bus.$off('filter-changed-' + this.context, this.filterChanged); }, methods: { - filterChanged (filterOption) { + filterChanged(filterOption) { if (filterOption.attribute_code === this.code) { if (filterOption.id === this.id) { - this.active = !this.active + this.active = !this.active; } else { - this.active = false + this.active = false; } // filterOption.id === this.id ? this.active = true : this.active = false } }, - filterReset (filterOption) { - this.active = false + filterReset(filterOption) { + this.active = false; }, - switchFilter (id, label) { - this.$bus.$emit('filter-changed-' + this.context, { attribute_code: this.code, id: id, label: label }) + switchFilter(id, label) { + this.$bus.$emit('filter-changed-' + this.context, { + attribute_code: this.code, + id: id, + label: label + }); } } -} +}; diff --git a/core/modules/catalog/components/ProductCustomOptions.ts b/core/modules/catalog/components/ProductCustomOptions.ts index 8a0d8e1aa4..93509047e4 100644 --- a/core/modules/catalog/components/ProductCustomOptions.ts +++ b/core/modules/catalog/components/ProductCustomOptions.ts @@ -1,19 +1,22 @@ -import { mapMutations } from 'vuex' -import * as types from '../store/product/mutation-types' -import rootStore from '@vue-storefront/core/store' -import i18n from '@vue-storefront/i18n' -import { Logger } from '@vue-storefront/core/lib/logger' +import { mapMutations } from 'vuex'; +import * as types from '../store/product/mutation-types'; +import rootStore from '@vue-storefront/core/store'; +import i18n from '@vue-storefront/i18n'; +import { Logger } from '@vue-storefront/core/lib/logger'; -function _defaultOptionValue (co) { +function _defaultOptionValue(co) { switch (co.type) { - case 'radio': return co.values && co.values.length ? co.values[0].option_type_id : 0 - case 'checkbox': return false - default: return '' + case 'radio': + return co.values && co.values.length ? co.values[0].option_type_id : 0; + case 'checkbox': + return false; + default: + return ''; } } -function _fieldName (co) { - return 'customOption_' + co.option_id +function _fieldName(co) { + return 'customOption_' + co.option_id; } export const ProductCustomOptions = { @@ -24,76 +27,102 @@ export const ProductCustomOptions = { required: true } }, - data () { + data() { return { - inputValues: { - }, - selectedOptions: { - }, + inputValues: {}, + selectedOptions: {}, validation: { rules: {}, results: {} } - } + }; }, - created () { + created() { rootStore.dispatch('product/addCustomOptionValidator', { validationRule: 'required', // You may add your own custom fields validators elsewhere in the theme - validatorFunction: (value) => { - return { error: (value === null || value === '') || (value === false) || (value === 0), message: i18n.t('Field is required.') } + validatorFunction: value => { + return { + error: + value === null || value === '' || value === false || value === 0, + message: i18n.t('Field is required.') + }; } - }) - this.setupInputFields() + }); + this.setupInputFields(); }, methods: { ...mapMutations('product', { setCustomOptionValue: types.CATALOG_UPD_CUSTOM_OPTION // map `this.add()` to `this.$store.commit('increment')` }), - setupInputFields () { + setupInputFields() { for (let co of this.product.custom_options) { - const fieldName = _fieldName(co) - this['inputValues'][fieldName] = _defaultOptionValue(co) - if (co.is_require) { // validation rules are very basic - this.validation.rules[fieldName] = 'required' // TODO: add custom validators for the custom options + const fieldName = _fieldName(co); + this['inputValues'][fieldName] = _defaultOptionValue(co); + if (co.is_require) { + // validation rules are very basic + this.validation.rules[fieldName] = 'required'; // TODO: add custom validators for the custom options } - this.optionChanged(co, co.values && co.values.length > 0 ? co.values[0] : null) + this.optionChanged( + co, + co.values && co.values.length > 0 ? co.values[0] : null + ); } }, - optionChanged (option, opval = null) { - const fieldName = _fieldName(option) - const value = opval === null ? this.inputValues[fieldName] : opval.option_type_id - this.validateField(option) - this.setCustomOptionValue({ optionId: option.option_id, optionValue: value }) - this.$store.dispatch('product/setCustomOptions', { product: this.product, customOptions: this.$store.state.product.current_custom_options }) // TODO: move it to "AddToCart" - this.selectedOptions[fieldName] = (opval === null ? value : opval) - this.$bus.$emit('product-after-customoptions', { product: this.product, option: option, optionValues: this.selectedOptions }) + optionChanged(option, opval = null) { + const fieldName = _fieldName(option); + const value = + opval === null ? this.inputValues[fieldName] : opval.option_type_id; + this.validateField(option); + this.setCustomOptionValue({ + optionId: option.option_id, + optionValue: value + }); + this.$store.dispatch('product/setCustomOptions', { + product: this.product, + customOptions: this.$store.state.product.current_custom_options + }); // TODO: move it to "AddToCart" + this.selectedOptions[fieldName] = opval === null ? value : opval; + this.$bus.$emit('product-after-customoptions', { + product: this.product, + option: option, + optionValues: this.selectedOptions + }); }, - validateField (option) { - const fieldName = _fieldName(option) - const validationRule = this.validation.rules[fieldName] - this.product.errors.custom_options = null + validateField(option) { + const fieldName = _fieldName(option); + const validationRule = this.validation.rules[fieldName]; + this.product.errors.custom_options = null; if (validationRule) { - const validator = this.$store.state.product.custom_options_validators[validationRule] + const validator = this.$store.state.product.custom_options_validators[ + validationRule + ]; if (typeof validator === 'function') { - const validationResult = validator(this['inputValues'][fieldName]) - this.validation.results[fieldName] = validationResult + const validationResult = validator(this['inputValues'][fieldName]); + this.validation.results[fieldName] = validationResult; if (validationResult.error) { - this.product.errors['custom_options_' + fieldName] = i18n.t('Please configure product custom options and fix the validation errors') + this.product.errors['custom_options_' + fieldName] = i18n.t( + 'Please configure product custom options and fix the validation errors' + ); } else { - this.product.errors['custom_options_' + fieldName] = null + this.product.errors['custom_options_' + fieldName] = null; } } else { - Logger.error('No validation rule found for ' + validationRule, 'components-product-custom-options')() - this.validation.results[fieldName] = { error: false, message: '' } + Logger.error( + 'No validation rule found for ' + validationRule, + 'components-product-custom-options' + )(); + this.validation.results[fieldName] = { error: false, message: '' }; } } else { - this.validation.results[fieldName] = { error: false, message: '' } + this.validation.results[fieldName] = { error: false, message: '' }; } }, - isValid () { - let isValid = true - this.validation.results.map((res) => { if (res.error) isValid = false }) - return isValid + isValid() { + let isValid = true; + this.validation.results.map(res => { + if (res.error) isValid = false; + }); + return isValid; } } -} +}; diff --git a/core/modules/catalog/components/ProductGallery.ts b/core/modules/catalog/components/ProductGallery.ts index dc85cfcb6e..a13d3f85fc 100644 --- a/core/modules/catalog/components/ProductGallery.ts +++ b/core/modules/catalog/components/ProductGallery.ts @@ -1,4 +1,4 @@ -import VueOffline from 'vue-offline' +import VueOffline from 'vue-offline'; export const ProductGallery = { name: 'ProductGallery', @@ -23,6 +23,5 @@ export const ProductGallery = { required: true } }, - computed: { - } -} + computed: {} +}; diff --git a/core/modules/catalog/components/ProductTile.ts b/core/modules/catalog/components/ProductTile.ts index c58a17701f..b1309d7c66 100644 --- a/core/modules/catalog/components/ProductTile.ts +++ b/core/modules/catalog/components/ProductTile.ts @@ -1,6 +1,6 @@ -import { productThumbnailPath } from '@vue-storefront/core/helpers' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { formatProductLink } from '@vue-storefront/core/modules/url/helpers' +import { productThumbnailPath } from '@vue-storefront/core/helpers'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { formatProductLink } from '@vue-storefront/core/modules/url/helpers'; export const ProductTile = { name: 'ProductTile', @@ -10,33 +10,33 @@ export const ProductTile = { required: true } }, - data () { + data() { return { clicks: 0, placeholder: '/assets/placeholder.jpg' - } + }; }, computed: { - productLink () { - return formatProductLink(this.product, currentStoreView().storeCode) - }, - thumbnail () { + productLink() { + return formatProductLink(this.product, currentStoreView().storeCode); + }, + thumbnail() { // todo: play with the image based on category page filters - eg. when 'red' color is chosen, the image is going to be 'red' - let thumbnail = productThumbnailPath(this.product) - return this.getThumbnail(thumbnail, 310, 300) + let thumbnail = productThumbnailPath(this.product); + return this.getThumbnail(thumbnail, 310, 300); }, - thumbnailObj () { + thumbnailObj() { return { src: this.thumbnail, loading: this.placeholder, error: this.placeholder - } + }; }, - isOnSale () { - return this.product.sale === '1' ? 'sale' : '' + isOnSale() { + return this.product.sale === '1' ? 'sale' : ''; }, - isNew () { - return this.product.new === '1' ? 'new' : '' + isNew() { + return this.product.new === '1' ? 'new' : ''; } } -} +}; diff --git a/core/modules/catalog/components/ProductVideo.ts b/core/modules/catalog/components/ProductVideo.ts index b4140dc4ed..37cbee664a 100644 --- a/core/modules/catalog/components/ProductVideo.ts +++ b/core/modules/catalog/components/ProductVideo.ts @@ -19,31 +19,31 @@ export const ProductVideo = { default: 0 } }, - data () { + data() { return { videoStarted: false, iframeLoaded: false - } + }; }, methods: { - initVideo () { - this.videoStarted = true - this.$emit('video-started', this.index) + initVideo() { + this.videoStarted = true; + this.$emit('video-started', this.index); }, - iframeIsLoaded () { - this.iframeLoaded = true + iframeIsLoaded() { + this.iframeLoaded = true; } }, computed: { - embedUrl () { + embedUrl() { switch (this.type) { - case "youtube": - return `https://www.youtube.com/embed/${this.id}?autoplay=1` - case "vimeo": - return `https://player.vimeo.com/video/${this.id}?autoplay=1` + case 'youtube': + return `https://www.youtube.com/embed/${this.id}?autoplay=1`; + case 'vimeo': + return `https://player.vimeo.com/video/${this.id}?autoplay=1`; default: - return + return; } } } -} +}; diff --git a/core/modules/catalog/components/Search.ts b/core/modules/catalog/components/Search.ts index 199a460935..575ffb5e70 100644 --- a/core/modules/catalog/components/Search.ts +++ b/core/modules/catalog/components/Search.ts @@ -1,13 +1,13 @@ -import { mapState } from 'vuex' -import i18n from '@vue-storefront/i18n' -import onEscapePress from '@vue-storefront/core/mixins/onEscapePress' -import { prepareQuickSearchQuery } from '@vue-storefront/core/modules/catalog/queries/searchPanel' -import RootState from '@vue-storefront/core/types/RootState' -import { Logger } from '@vue-storefront/core/lib/logger' +import { mapState } from 'vuex'; +import i18n from '@vue-storefront/i18n'; +import onEscapePress from '@vue-storefront/core/mixins/onEscapePress'; +import { prepareQuickSearchQuery } from '@vue-storefront/core/modules/catalog/queries/searchPanel'; +import RootState from '@vue-storefront/core/types/RootState'; +import { Logger } from '@vue-storefront/core/lib/logger'; export const Search = { name: 'SearchPanel', - data () { + data() { return { products: [], search: '', @@ -16,66 +16,82 @@ export const Search = { placeholder: i18n.t('Type what you are looking for...'), emptyResults: false, readMore: true - } + }; }, methods: { - onEscapePress () { - this.closeSearchpanel() + onEscapePress() { + this.closeSearchpanel(); }, - closeSearchpanel () { - this.$store.commit('ui/setSidebar', false) - this.$store.commit('ui/setMicrocart', false) - this.$store.commit('ui/setSearchpanel', false) + closeSearchpanel() { + this.$store.commit('ui/setSidebar', false); + this.$store.commit('ui/setMicrocart', false); + this.$store.commit('ui/setSearchpanel', false); }, - buildSearchQuery (queryText) { - let searchQuery = prepareQuickSearchQuery(queryText) - return searchQuery + buildSearchQuery(queryText) { + let searchQuery = prepareQuickSearchQuery(queryText); + return searchQuery; }, - makeSearch () { + makeSearch() { if (this.search !== '' && this.search !== undefined) { - let query = this.buildSearchQuery(this.search) - this.start = 0 - this.readMore = true - this.$store.dispatch('product/list', { query, start: this.start, size: this.size, updateState: false }).then(resp => { - this.products = resp.items - this.start = this.start + this.size - this.emptyResults = resp.items.length < 1 - }).catch((err) => { - Logger.error(err, 'components-search')() - }) + let query = this.buildSearchQuery(this.search); + this.start = 0; + this.readMore = true; + this.$store + .dispatch('product/list', { + query, + start: this.start, + size: this.size, + updateState: false + }) + .then(resp => { + this.products = resp.items; + this.start = this.start + this.size; + this.emptyResults = resp.items.length < 1; + }) + .catch(err => { + Logger.error(err, 'components-search')(); + }); } else { - this.products = [] - this.emptyResults = 0 + this.products = []; + this.emptyResults = 0; } }, - seeMore () { + seeMore() { if (this.search !== '' && this.search !== undefined) { - let query = this.buildSearchQuery(this.search) - this.$store.dispatch('product/list', { query, start: this.start, size: this.size, updateState: false }).then((resp) => { - let page = Math.floor(resp.total / this.size) - let exceeed = resp.total - this.size * page - if (resp.start === resp.total - exceeed) { - this.readMore = false - } - this.products = this.products.concat(resp.items) - this.start = this.start + this.size - this.emptyResults = this.products.length < 1 - }).catch((err) => { - Logger.error(err, 'components-search')() - }) + let query = this.buildSearchQuery(this.search); + this.$store + .dispatch('product/list', { + query, + start: this.start, + size: this.size, + updateState: false + }) + .then(resp => { + let page = Math.floor(resp.total / this.size); + let exceeed = resp.total - this.size * page; + if (resp.start === resp.total - exceeed) { + this.readMore = false; + } + this.products = this.products.concat(resp.items); + this.start = this.start + this.size; + this.emptyResults = this.products.length < 1; + }) + .catch(err => { + Logger.error(err, 'components-search')(); + }); } else { - this.products = [] - this.emptyResults = 0 + this.products = []; + this.emptyResults = 0; } } }, computed: { - items () { - return this.$store.state.search + items() { + return this.$store.state.search; }, ...mapState({ isOpen: (state: RootState) => state.ui.searchpanel }) }, mixins: [onEscapePress] -} +}; diff --git a/core/modules/catalog/helpers/index.ts b/core/modules/catalog/helpers/index.ts index 81dd1735e3..5c45f0b2b9 100644 --- a/core/modules/catalog/helpers/index.ts +++ b/core/modules/catalog/helpers/index.ts @@ -1,520 +1,745 @@ -import Vue from 'vue' -import rootStore from '@vue-storefront/core/store' -import { calculateProductTax } from '../helpers/tax' -import flattenDeep from 'lodash-es/flattenDeep' -import omit from 'lodash-es/omit' -import remove from 'lodash-es/remove' -import groupBy from 'lodash-es/groupBy' -import toString from 'lodash-es/toString' -import union from 'lodash-es/union' +import Vue from 'vue'; +import rootStore from '@vue-storefront/core/store'; +import { calculateProductTax } from '../helpers/tax'; +import flattenDeep from 'lodash-es/flattenDeep'; +import omit from 'lodash-es/omit'; +import remove from 'lodash-es/remove'; +import groupBy from 'lodash-es/groupBy'; +import toString from 'lodash-es/toString'; +import union from 'lodash-es/union'; // TODO: Remove this dependency -import { optionLabel } from './optionLabel' -import i18n from '@vue-storefront/i18n' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { getThumbnailPath } from '@vue-storefront/core/helpers' -import { Logger } from '@vue-storefront/core/lib/logger' -import { isServer } from '@vue-storefront/core/helpers' - -function _filterRootProductByStockitem (context, stockItem, product, errorCallback) { +import { optionLabel } from './optionLabel'; +import i18n from '@vue-storefront/i18n'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { getThumbnailPath } from '@vue-storefront/core/helpers'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { isServer } from '@vue-storefront/core/helpers'; + +function _filterRootProductByStockitem( + context, + stockItem, + product, + errorCallback +) { if (stockItem) { - product.stock = stockItem + product.stock = stockItem; if (stockItem.is_in_stock === false) { - product.errors.variants = i18n.t('No available product variants') - context.state.current.errors = product.errors - Vue.prototype.$bus.$emit('product-after-removevariant', { product: product }) + product.errors.variants = i18n.t('No available product variants'); + context.state.current.errors = product.errors; + Vue.prototype.$bus.$emit('product-after-removevariant', { + product: product + }); if (rootStore.state.config.products.listOutOfStockProducts === false) { - errorCallback(new Error('Product query returned an empty result')) + errorCallback(new Error('Product query returned an empty result')); } } } } -export function isOptionAvailableAsync (context, { product, configuration }) { - const variant = findConfigurableChildAsync({ product: product, configuration: configuration, availabilityCheck: true }) - return typeof variant !== 'undefined' && variant !== null +export function isOptionAvailableAsync(context, { product, configuration }) { + const variant = findConfigurableChildAsync({ + product: product, + configuration: configuration, + availabilityCheck: true + }); + return typeof variant !== 'undefined' && variant !== null; } -function _filterChildrenByStockitem (context, stockItems, product, diffLog) { +function _filterChildrenByStockitem(context, stockItems, product, diffLog) { if (rootStore.state.config.products.filterUnavailableVariants) { if (product.type_id === 'configurable' && product.configurable_children) { for (const stockItem of stockItems) { - const confChild = product.configurable_children.find(p => { return p.id === stockItem.product_id }) - if (stockItem.is_in_stock === false || (confChild && confChild.status >= 2/* conf child is disabled */)) { - product.configurable_children = product.configurable_children.filter((p) => { return p.id !== stockItem.product_id }) - diffLog.push(stockItem.product_id) + const confChild = product.configurable_children.find(p => { + return p.id === stockItem.product_id; + }); + if ( + stockItem.is_in_stock === false || + (confChild && confChild.status >= 2) /* conf child is disabled */ + ) { + product.configurable_children = product.configurable_children.filter( + p => { + return p.id !== stockItem.product_id; + } + ); + diffLog.push(stockItem.product_id); } else { if (confChild) { - confChild.stock = stockItem + confChild.stock = stockItem; } } } - let totalOptions = 0 - let removedOptions = 0 + let totalOptions = 0; + let removedOptions = 0; for (const optionKey in context.state.current_options) { - let optionsAvailable = context.state.current_options[optionKey] // TODO: it should take the attribute combinations into consideration + let optionsAvailable = context.state.current_options[optionKey]; // TODO: it should take the attribute combinations into consideration if (optionsAvailable && optionsAvailable.length > 0) { - optionsAvailable = optionsAvailable.filter((opt) => { - const config = {} - config[optionKey] = opt - const variant = isOptionAvailableAsync(context, { product: product, configuration: config }) + optionsAvailable = optionsAvailable.filter(opt => { + const config = {}; + config[optionKey] = opt; + const variant = isOptionAvailableAsync(context, { + product: product, + configuration: config + }); if (!variant) { - Logger.log('No variant for' + opt, 'helper')() - Vue.prototype.$bus.$emit('product-after-removevariant', { product: product }) - removedOptions++ - return false + Logger.log('No variant for' + opt, 'helper')(); + Vue.prototype.$bus.$emit('product-after-removevariant', { + product: product + }); + removedOptions++; + return false; } else { - totalOptions++ - return true + totalOptions++; + return true; } - }) - Logger.debug('Options still available' + optionsAvailable + removedOptions, 'helper')() - context.state.current_options[optionKey] = optionsAvailable + }); + Logger.debug( + 'Options still available' + optionsAvailable + removedOptions, + 'helper' + )(); + context.state.current_options[optionKey] = optionsAvailable; } } - configureProductAsync(context, { product, configuration: context.state.current_configuration, selectDefaultVariant: true, fallbackToDefaultWhenNoAvailable: true }) + configureProductAsync(context, { + product, + configuration: context.state.current_configuration, + selectDefaultVariant: true, + fallbackToDefaultWhenNoAvailable: true + }); if (totalOptions === 0) { - product.errors.variants = i18n.t('No available product variants') - context.state.current.errors = product.errors - Vue.prototype.$bus.$emit('product-after-removevariant', { product: product }) + product.errors.variants = i18n.t('No available product variants'); + context.state.current.errors = product.errors; + Vue.prototype.$bus.$emit('product-after-removevariant', { + product: product + }); } } } } -export function filterOutUnavailableVariants (context, product) { +export function filterOutUnavailableVariants(context, product) { return new Promise((resolve, reject) => { if (rootStore.state.config.products.filterUnavailableVariants) { const _filterConfigurableHelper = () => { - if (product.type_id === 'configurable' && product.configurable_children) { - const stockItems = [] - let confChildSkus = product.configurable_children.map((c) => { return c.sku }) + if ( + product.type_id === 'configurable' && + product.configurable_children + ) { + const stockItems = []; + let confChildSkus = product.configurable_children.map(c => { + return c.sku; + }); for (const confChild of product.configurable_children) { - const stockCached = context.rootState.stock.cache[confChild.id] + const stockCached = context.rootState.stock.cache[confChild.id]; if (stockCached) { - stockItems.push(stockCached) - confChildSkus = remove(confChildSkus, (skuToCheck) => skuToCheck === confChild.sku) + stockItems.push(stockCached); + confChildSkus = remove( + confChildSkus, + skuToCheck => skuToCheck === confChild.sku + ); } } - Logger.debug('Cached stock items and delta' + stockItems + confChildSkus)() + Logger.debug( + 'Cached stock items and delta' + stockItems + confChildSkus + )(); if (confChildSkus.length > 0) { - context.dispatch('stock/list', { skus: confChildSkus }, {root: true}).then((task) => { - if (task && task.resultCode === 200) { - const diffLog = [] - _filterChildrenByStockitem(context, union(task.result, stockItems), product, diffLog) - Logger.debug('Filtered configurable_children with the network call' + diffLog, 'helper')() - resolve() - } else { - Logger.error('Cannot sync the availability of the product options. Please update the vue-storefront-api or switch on the Internet', 'helper')() - } - }).catch(err => { - Logger.error(err, 'helper')() - }) + context + .dispatch('stock/list', { skus: confChildSkus }, { root: true }) + .then(task => { + if (task && task.resultCode === 200) { + const diffLog = []; + _filterChildrenByStockitem( + context, + union(task.result, stockItems), + product, + diffLog + ); + Logger.debug( + 'Filtered configurable_children with the network call' + + diffLog, + 'helper' + )(); + resolve(); + } else { + Logger.error( + 'Cannot sync the availability of the product options. Please update the vue-storefront-api or switch on the Internet', + 'helper' + )(); + } + }) + .catch(err => { + Logger.error(err, 'helper')(); + }); } else { - const diffLog = [] - _filterChildrenByStockitem(context, stockItems, product, diffLog) - Logger.debug('Filtered configurable_children without the network call' + diffLog, 'helper')() - resolve() + const diffLog = []; + _filterChildrenByStockitem(context, stockItems, product, diffLog); + Logger.debug( + 'Filtered configurable_children without the network call' + + diffLog, + 'helper' + )(); + resolve(); } } else { - resolve() + resolve(); } - } - const rootStockCached = context.rootState.stock.cache[product.id] + }; + const rootStockCached = context.rootState.stock.cache[product.id]; if (!rootStockCached) { - context.dispatch('stock/list', { skus: [product.sku] }, {root: true}).then((task) => { - _filterRootProductByStockitem(context, task && task.result && task.result.length ? task.result[0] : null, product, reject) - Logger.debug('Filtered root product stock with the network call')() - _filterConfigurableHelper() - }) + context + .dispatch('stock/list', { skus: [product.sku] }, { root: true }) + .then(task => { + _filterRootProductByStockitem( + context, + task && task.result && task.result.length ? task.result[0] : null, + product, + reject + ); + Logger.debug('Filtered root product stock with the network call')(); + _filterConfigurableHelper(); + }); } else { - _filterRootProductByStockitem(context, rootStockCached, product, reject) - Logger.debug('Filtered root product stock without the network call')() - _filterConfigurableHelper() + _filterRootProductByStockitem( + context, + rootStockCached, + product, + reject + ); + Logger.debug('Filtered root product stock without the network call')(); + _filterConfigurableHelper(); } } else { - resolve() + resolve(); } - }) + }); } -export function syncProductPrice (product, backProduct) { // TODO: we probably need to update the Net prices here as well - product.sgn = backProduct.sgn // copy the signature for the modified price - product.priceInclTax = backProduct.price_info.final_price - product.originalPriceInclTax = backProduct.price_info.regular_price - product.specialPriceInclTax = backProduct.price_info.special_price - - product.special_price = backProduct.price_info.extension_attributes.tax_adjustments.special_price - product.price = backProduct.price_info.extension_attributes.tax_adjustments.final_price - product.originalPrice = backProduct.price_info.extension_attributes.tax_adjustments.regular_price - - product.priceTax = product.priceInclTax - product.price - product.specialPriceTax = product.specialPriceInclTax - product.special_price - product.originalPriceTax = product.originalPriceInclTax - product.originalPrice +export function syncProductPrice(product, backProduct) { + // TODO: we probably need to update the Net prices here as well + product.sgn = backProduct.sgn; // copy the signature for the modified price + product.priceInclTax = backProduct.price_info.final_price; + product.originalPriceInclTax = backProduct.price_info.regular_price; + product.specialPriceInclTax = backProduct.price_info.special_price; + + product.special_price = + backProduct.price_info.extension_attributes.tax_adjustments.special_price; + product.price = + backProduct.price_info.extension_attributes.tax_adjustments.final_price; + product.originalPrice = + backProduct.price_info.extension_attributes.tax_adjustments.regular_price; + + product.priceTax = product.priceInclTax - product.price; + product.specialPriceTax = product.specialPriceInclTax - product.special_price; + product.originalPriceTax = + product.originalPriceInclTax - product.originalPrice; if (product.priceInclTax >= product.originalPriceInclTax) { - product.specialPriceInclTax = 0 - product.special_price = 0 + product.specialPriceInclTax = 0; + product.special_price = 0; } else { - product.special_price = 0 // the same price as original; it's not a promotion + product.special_price = 0; // the same price as original; it's not a promotion } - Vue.prototype.$bus.$emit('product-after-priceupdate', product) + Vue.prototype.$bus.$emit('product-after-priceupdate', product); // Logger.log(product.sku, product, backProduct)() - return product + return product; } /** * Synchronize / override prices got from ElasticSearch with current one's from Magento2 or other platform backend * @param {Array} products */ -export function doPlatformPricesSync (products) { +export function doPlatformPricesSync(products) { return new Promise((resolve, reject) => { if (rootStore.state.config.products.alwaysSyncPlatformPricesOver) { if (rootStore.state.config.products.clearPricesBeforePlatformSync) { - for (let product of products) { // clear out the prices as we need to sync them with Magento - product.priceInclTax = null - product.originalPriceInclTax = null - product.specialPriceInclTax = null + for (let product of products) { + // clear out the prices as we need to sync them with Magento + product.priceInclTax = null; + product.originalPriceInclTax = null; + product.specialPriceInclTax = null; - product.special_price = null - product.price = null - product.originalPrice = null + product.special_price = null; + product.price = null; + product.originalPrice = null; - product.priceTax = null - product.specialPriceTax = null - product.originalPriceTax = null + product.priceTax = null; + product.specialPriceTax = null; + product.originalPriceTax = null; if (product.configurable_children) { for (let sc of product.configurable_children) { - sc.priceInclTax = null - sc.originalPriceInclTax = null - sc.specialPriceInclTax = null + sc.priceInclTax = null; + sc.originalPriceInclTax = null; + sc.specialPriceInclTax = null; - sc.special_price = null - sc.price = null - sc.originalPrice = null + sc.special_price = null; + sc.price = null; + sc.originalPrice = null; - sc.priceTax = null - sc.specialPriceTax = null - sc.originalPriceTax = null + sc.priceTax = null; + sc.specialPriceTax = null; + sc.originalPriceTax = null; } } } } - let skus = products.map((p) => { return p.sku }) - - if (products.length === 1) { // single product - download child data - const childSkus = flattenDeep(products.map((p) => { return (p.configurable_children) ? p.configurable_children.map((cc) => { return cc.sku }) : null })) - skus = union(skus, childSkus) + let skus = products.map(p => { + return p.sku; + }); + + if (products.length === 1) { + // single product - download child data + const childSkus = flattenDeep( + products.map(p => { + return p.configurable_children + ? p.configurable_children.map(cc => { + return cc.sku; + }) + : null; + }) + ); + skus = union(skus, childSkus); } if (skus && skus.length > 0) { - Logger.log('Starting platform prices sync for', skus) // TODO: add option for syncro and non syncro return() - rootStore.dispatch('product/syncPlatformPricesOver', { skus: skus }, { root: true }).then((syncResult) => { - if (syncResult) { - syncResult = syncResult.items - - for (let product of products) { - const backProduct = syncResult.find((itm) => { return itm.id === product.id }) - if (backProduct) { - product.price_is_current = true // in case we're syncing up the prices we should mark if we do have current or not - product.price_refreshed_at = new Date() - product = syncProductPrice(product, backProduct) - - if (product.configurable_children) { - for (let configurableChild of product.configurable_children) { - const backProductChild = syncResult.find((itm) => { return itm.id === configurableChild.id }) - if (backProductChild) { - configurableChild = syncProductPrice(configurableChild, backProductChild) + Logger.log('Starting platform prices sync for', skus); // TODO: add option for syncro and non syncro return() + rootStore + .dispatch( + 'product/syncPlatformPricesOver', + { skus: skus }, + { root: true } + ) + .then(syncResult => { + if (syncResult) { + syncResult = syncResult.items; + + for (let product of products) { + const backProduct = syncResult.find(itm => { + return itm.id === product.id; + }); + if (backProduct) { + product.price_is_current = true; // in case we're syncing up the prices we should mark if we do have current or not + product.price_refreshed_at = new Date(); + product = syncProductPrice(product, backProduct); + + if (product.configurable_children) { + for (let configurableChild of product.configurable_children) { + const backProductChild = syncResult.find(itm => { + return itm.id === configurableChild.id; + }); + if (backProductChild) { + configurableChild = syncProductPrice( + configurableChild, + backProductChild + ); + } } } + // TODO: shall we update local storage here for the main product? } - // TODO: shall we update local storage here for the main product? } } - } - resolve(products) - }) - } else { // empty list of products - resolve(products) + resolve(products); + }); + } else { + // empty list of products + resolve(products); } if (!rootStore.state.config.products.waitForPlatformSync && !isServer) { - Logger.log('Returning products, the prices yet to come from backend!')() + Logger.log( + 'Returning products, the prices yet to come from backend!' + )(); for (let product of products) { - product.price_is_current = false // in case we're syncing up the prices we should mark if we do have current or not - product.price_refreshed_at = null + product.price_is_current = false; // in case we're syncing up the prices we should mark if we do have current or not + product.price_refreshed_at = null; } - resolve(products) + resolve(products); } } else { - resolve(products) + resolve(products); } - }) + }); } // TODO: should be moved to tax /** * Calculate taxes for specific product collection */ -export function calculateTaxes (products, store) { +export function calculateTaxes(products, store) { return new Promise((resolve, reject) => { if (rootStore.state.config.tax.calculateServerSide) { - Logger.debug('Taxes calculated server side, skipping')() - doPlatformPricesSync(products).then((products) => { - resolve(products) - }) + Logger.debug('Taxes calculated server side, skipping')(); + doPlatformPricesSync(products).then(products => { + resolve(products); + }); } else { - const storeView = currentStoreView() - store.dispatch('tax/list', { query: '' }, { root: true }).then((tcs) => { // TODO: move it to the server side for one requests OR cache in indexedDb + const storeView = currentStoreView(); + store.dispatch('tax/list', { query: '' }, { root: true }).then(tcs => { + // TODO: move it to the server side for one requests OR cache in indexedDb for (let product of products) { - product = calculateProductTax(product, tcs.items, storeView.tax.defaultCountry, storeView.tax.defaultRegion, storeView.tax.sourcePriceIncludesTax) + product = calculateProductTax( + product, + tcs.items, + storeView.tax.defaultCountry, + storeView.tax.defaultRegion, + storeView.tax.sourcePriceIncludesTax + ); } - doPlatformPricesSync(products).then((products) => { - resolve(products) - }) - }) // TODO: run Magento2 prices request here if configured so in the config + doPlatformPricesSync(products).then(products => { + resolve(products); + }); + }); // TODO: run Magento2 prices request here if configured so in the config } - }) + }); } -function _prepareProductOption (product) { +function _prepareProductOption(product) { let product_option = { extension_attributes: { custom_options: [], configurable_item_options: [], bundle_options: [] } - } + }; /* if (product.product_option) { product_option = product.product_option } */ - return product_option + return product_option; } -export function setConfigurableProductOptionsAsync (context, { product, configuration }) { +export function setConfigurableProductOptionsAsync( + context, + { product, configuration } +) { if (product.configurable_options) { - const product_option = _prepareProductOption(product) + const product_option = _prepareProductOption(product); /* eslint camelcase: "off" */ - const configurable_item_options = product_option.extension_attributes.configurable_item_options + const configurable_item_options = + product_option.extension_attributes.configurable_item_options; for (const configKey of Object.keys(configuration)) { - const configOption = configuration[configKey] - if (configOption.attribute_code && configOption.attribute_code !== 'price') { + const configOption = configuration[configKey]; + if ( + configOption.attribute_code && + configOption.attribute_code !== 'price' + ) { const option = product.configurable_options.find(co => { - return (co.attribute_code === configOption.attribute_code) - }) + return co.attribute_code === configOption.attribute_code; + }); if (!option) { - Logger.error('Wrong option id for setProductOptions', configOption.attribute_code)() - return null + Logger.error( + 'Wrong option id for setProductOptions', + configOption.attribute_code + )(); + return null; } let existingOption = configurable_item_options.find(cop => { - return cop.option_id === option.attribute_id - }) + return cop.option_id === option.attribute_id; + }); if (!existingOption) { existingOption = { option_id: option.attribute_id, option_value: configOption.id, label: i18n.t(configOption.attribute_code), value: configOption.label - } - configurable_item_options.push(existingOption) + }; + configurable_item_options.push(existingOption); } - existingOption.option_value = configOption.id - existingOption.label = i18n.t(configOption.attribute_code) - existingOption.value = configOption.label + existingOption.option_value = configOption.id; + existingOption.label = i18n.t(configOption.attribute_code); + existingOption.value = configOption.label; } } // Logger.debug('Server product options object', product_option)() - return product_option + return product_option; } else { - return null + return null; } } -export function setCustomProductOptionsAsync (context, { product, customOptions }) { - const productOption = _prepareProductOption(product) - productOption.extension_attributes.custom_options = customOptions - return productOption +export function setCustomProductOptionsAsync( + context, + { product, customOptions } +) { + const productOption = _prepareProductOption(product); + productOption.extension_attributes.custom_options = customOptions; + return productOption; } -export function setBundleProductOptionsAsync (context, { product, bundleOptions }) { - const productOption = _prepareProductOption(product) - productOption.extension_attributes.bundle_options = bundleOptions - return productOption +export function setBundleProductOptionsAsync( + context, + { product, bundleOptions } +) { + const productOption = _prepareProductOption(product); + productOption.extension_attributes.bundle_options = bundleOptions; + return productOption; } -function _internalMapOptions (productOption) { - const optionsMapped = [] - for (let option of productOption.extension_attributes.configurable_item_options) { +function _internalMapOptions(productOption) { + const optionsMapped = []; + for (let option of productOption.extension_attributes + .configurable_item_options) { optionsMapped.push({ label: option.label, value: option.value - }) + }); } - productOption.extension_attributes.configurable_item_options = productOption.extension_attributes.configurable_item_options.map((op) => { - return omit(op, ['label', 'value']) - }) - return optionsMapped + productOption.extension_attributes.configurable_item_options = productOption.extension_attributes.configurable_item_options.map( + op => { + return omit(op, ['label', 'value']); + } + ); + return optionsMapped; } -export function populateProductConfigurationAsync (context, { product, selectedVariant }) { +export function populateProductConfigurationAsync( + context, + { product, selectedVariant } +) { if (product.configurable_options) { for (let option of product.configurable_options) { - let attribute_code - let attribute_label + let attribute_code; + let attribute_label; if (option.attribute_code) { - attribute_code = option.attribute_code - attribute_label = option.label ? option.label : (option.frontend_label ? option.frontend_label : option.default_frontend_label) + attribute_code = option.attribute_code; + attribute_label = option.label + ? option.label + : option.frontend_label + ? option.frontend_label + : option.default_frontend_label; } else { if (option.attribute_id) { - let attr = context.rootState.attribute.list_by_id[option.attribute_id] + let attr = + context.rootState.attribute.list_by_id[option.attribute_id]; if (!attr) { - Logger.error('Wrong attribute given in configurable_options - can not find by attribute_id', option)() - continue + Logger.error( + 'Wrong attribute given in configurable_options - can not find by attribute_id', + option + )(); + continue; } else { - attribute_code = attr.attribute_code - attribute_label = attr.frontend_label ? attr.frontend_label : attr.default_frontend_label + attribute_code = attr.attribute_code; + attribute_label = attr.frontend_label + ? attr.frontend_label + : attr.default_frontend_label; } } else { - Logger.error('Wrong attribute given in configurable_options - no attribute_code / attribute_id', option)() + Logger.error( + 'Wrong attribute given in configurable_options - no attribute_code / attribute_id', + option + )(); } } - let selectedOption = null + let selectedOption = null; if (selectedVariant.custom_attributes) { - selectedOption = selectedVariant.custom_attributes.find((a) => { // this is without the "label" - return (a.attribute_code === attribute_code) - }) + selectedOption = selectedVariant.custom_attributes.find(a => { + // this is without the "label" + return a.attribute_code === attribute_code; + }); } else { selectedOption = { attribute_code: attribute_code, value: selectedVariant[attribute_code] - } + }; } - const selectedOptionMeta = option.values.find(ov => { return ov.value_index === selectedOption.value }) + const selectedOptionMeta = option.values.find(ov => { + return ov.value_index === selectedOption.value; + }); if (selectedOptionMeta) { - selectedOption.label = selectedOptionMeta.label ? selectedOptionMeta.label : selectedOptionMeta.default_label - selectedOption.value_data = selectedOptionMeta.value_data + selectedOption.label = selectedOptionMeta.label + ? selectedOptionMeta.label + : selectedOptionMeta.default_label; + selectedOption.value_data = selectedOptionMeta.value_data; } const confVal = { attribute_code: attribute_code, id: selectedOption.value, - label: selectedOption.label ? selectedOption.label : /*if not set - find by attribute */optionLabel(context.rootState.attribute, { attributeKey: selectedOption.attribute_code, searchBy: 'code', optionId: selectedOption.value }) - } - context.state.current_configuration[attribute_code] = confVal + label: selectedOption.label + ? selectedOption.label + : /*if not set - find by attribute */ optionLabel( + context.rootState.attribute, + { + attributeKey: selectedOption.attribute_code, + searchBy: 'code', + optionId: selectedOption.value + } + ) + }; + context.state.current_configuration[attribute_code] = confVal; // @deprecated fallback for VS <= 1.0RC - if (!('setupVariantByAttributeCode' in rootStore.state.config.products) || rootStore.state.config.products.setupVariantByAttributeCode === false) { - const fallbackKey = attribute_label - context.state.current_configuration[fallbackKey.toLowerCase()] = confVal // @deprecated fallback for VS <= 1.0RC + if ( + !('setupVariantByAttributeCode' in rootStore.state.config.products) || + rootStore.state.config.products.setupVariantByAttributeCode === false + ) { + const fallbackKey = attribute_label; + context.state.current_configuration[ + fallbackKey.toLowerCase() + ] = confVal; // @deprecated fallback for VS <= 1.0RC } } if (rootStore.state.config.cart.setConfigurableProductOptions) { - const productOption = setConfigurableProductOptionsAsync(context, { product: product, configuration: context.state.current_configuration }) // set the custom options + const productOption = setConfigurableProductOptionsAsync(context, { + product: product, + configuration: context.state.current_configuration + }); // set the custom options if (productOption) { - product.options = _internalMapOptions(productOption) - product.product_option = productOption + product.options = _internalMapOptions(productOption); + product.product_option = productOption; } } } - return selectedVariant + return selectedVariant; } -export function findConfigurableChildAsync({ product, configuration = null, selectDefaultChildren = false, availabilityCheck = true }) { - let selectedVariant = product.configurable_children.find((configurableChild) => { - - if (availabilityCheck) { - if (configurableChild.stock && !rootStore.state.config.products.listOutOfStockProducts) { - if (!configurableChild.stock.is_in_stock) { - return false +export function findConfigurableChildAsync({ + product, + configuration = null, + selectDefaultChildren = false, + availabilityCheck = true +}) { + let selectedVariant = product.configurable_children.find( + configurableChild => { + if (availabilityCheck) { + if ( + configurableChild.stock && + !rootStore.state.config.products.listOutOfStockProducts + ) { + if (!configurableChild.stock.is_in_stock) { + return false; + } } } + if (configurableChild.status >= 2 /**disabled product*/) { + return false; + } + if (selectDefaultChildren) { + return true; // return first + } + if (configuration.sku) { + return configurableChild.sku === configuration.sku; // by sku or first one + } else { + return Object.keys(omit(configuration, ['price'])).every( + configProperty => { + if ( + !configuration[configProperty] || + typeof configuration[configProperty].id === 'undefined' + ) + return true; // skip empty + return ( + toString(configurableChild[configProperty]) === + toString(configuration[configProperty].id) + ); + } + ); + } } - if (configurableChild.status >= 2/**disabled product*/) { - return false - } - if (selectDefaultChildren) { - return true // return first - } - if (configuration.sku) { - return configurableChild.sku === configuration.sku // by sku or first one - } else { - return Object.keys(omit(configuration, ['price'])).every((configProperty) => { - if (!configuration[configProperty] || typeof configuration[configProperty].id === 'undefined') return true // skip empty - return toString(configurableChild[configProperty]) === toString(configuration[configProperty].id) - }) - } - }) - return selectedVariant + ); + return selectedVariant; } -export function configureProductAsync (context, { product, configuration, selectDefaultVariant = true, fallbackToDefaultWhenNoAvailable = true, setProductErorrs = false }) { +export function configureProductAsync( + context, + { + product, + configuration, + selectDefaultVariant = true, + fallbackToDefaultWhenNoAvailable = true, + setProductErorrs = false + } +) { // use current product if product wasn't passed - if (product === null) product = context.getters.productCurrent - const hasConfigurableChildren = (product.configurable_children && product.configurable_children.length > 0) + if (product === null) product = context.getters.productCurrent; + const hasConfigurableChildren = + product.configurable_children && product.configurable_children.length > 0; if (hasConfigurableChildren) { // handle custom_attributes for easier comparing in the future - product.configurable_children.forEach((child) => { - let customAttributesAsObject = {} + product.configurable_children.forEach(child => { + let customAttributesAsObject = {}; if (child.custom_attributes) { - child.custom_attributes.forEach((attr) => { - customAttributesAsObject[attr.attribute_code] = attr.value - }) + child.custom_attributes.forEach(attr => { + customAttributesAsObject[attr.attribute_code] = attr.value; + }); // add values from custom_attributes in a different form - Object.assign(child, customAttributesAsObject) + Object.assign(child, customAttributesAsObject); } - }) + }); // find selected variant - let desiredProductFound = false - let selectedVariant = findConfigurableChildAsync({ product, configuration, availabilityCheck: true }) + let desiredProductFound = false; + let selectedVariant = findConfigurableChildAsync({ + product, + configuration, + availabilityCheck: true + }); if (!selectedVariant) { if (fallbackToDefaultWhenNoAvailable) { - selectedVariant = findConfigurableChildAsync({ product, selectDefaultChildren: true, availabilityCheck: true }) // return first available child - desiredProductFound = false + selectedVariant = findConfigurableChildAsync({ + product, + selectDefaultChildren: true, + availabilityCheck: true + }); // return first available child + desiredProductFound = false; } else { - desiredProductFound = false + desiredProductFound = false; } } else { - desiredProductFound = true + desiredProductFound = true; } if (selectedVariant) { - if (!desiredProductFound) { // update the configuration - populateProductConfigurationAsync(context, { product: product, selectedVariant: selectedVariant }) - configuration = context.state.current_configuration + if (!desiredProductFound) { + // update the configuration + populateProductConfigurationAsync(context, { + product: product, + selectedVariant: selectedVariant + }); + configuration = context.state.current_configuration; } if (setProductErorrs) { - product.errors = {} // clear the product errors + product.errors = {}; // clear the product errors } - product.is_configured = true + product.is_configured = true; - if (rootStore.state.config.cart.setConfigurableProductOptions && !selectDefaultVariant && !(Object.keys(configuration).length === 1 && configuration.sku)) { + if ( + rootStore.state.config.cart.setConfigurableProductOptions && + !selectDefaultVariant && + !(Object.keys(configuration).length === 1 && configuration.sku) + ) { // the condition above: if selectDefaultVariant - then "setCurrent" is seeting the configurable options; if configuration = { sku: '' } -> this is a special case when not configuring the product but just searching by sku - const productOption = setConfigurableProductOptionsAsync(context, { product: product, configuration: configuration }) // set the custom options + const productOption = setConfigurableProductOptionsAsync(context, { + product: product, + configuration: configuration + }); // set the custom options if (productOption) { - selectedVariant.product_option = productOption - selectedVariant.options = _internalMapOptions(productOption) + selectedVariant.product_option = productOption; + selectedVariant.options = _internalMapOptions(productOption); } - }/* else { + } /* else { Logger.debug('Skipping configurable options setup', configuration)() } */ - const fieldsToOmit = ['name'] - if (selectedVariant.image === "") fieldsToOmit.push('image') - selectedVariant = omit(selectedVariant, fieldsToOmit) // We need to send the parent SKU to the Magento cart sync but use the child SKU internally in this case + const fieldsToOmit = ['name']; + if (selectedVariant.image === '') fieldsToOmit.push('image'); + selectedVariant = omit(selectedVariant, fieldsToOmit); // We need to send the parent SKU to the Magento cart sync but use the child SKU internally in this case // use chosen variant if (selectDefaultVariant) { - context.dispatch('setCurrent', selectedVariant) + context.dispatch('setCurrent', selectedVariant); } - Vue.prototype.$bus.$emit('product-after-configure', { product: product, configuration: configuration, selectedVariant: selectedVariant }) + Vue.prototype.$bus.$emit('product-after-configure', { + product: product, + configuration: configuration, + selectedVariant: selectedVariant + }); } - if (!selectedVariant && setProductErorrs) { // can not find variant anyway, even the default one - product.errors.variants = i18n.t('No available product variants') + if (!selectedVariant && setProductErorrs) { + // can not find variant anyway, even the default one + product.errors.variants = i18n.t('No available product variants'); if (selectDefaultVariant) { - context.dispatch('setCurrent', product) // without the configuration + context.dispatch('setCurrent', product); // without the configuration } } - return selectedVariant + return selectedVariant; } else { if (fallbackToDefaultWhenNoAvailable) { - return product + return product; } else { - return null + return null; } } } @@ -523,28 +748,32 @@ export function configureProductAsync (context, { product, configuration, select * Get media Gallery images from product */ -export function getMediaGallery (product) { - let mediaGallery = [] +export function getMediaGallery(product) { + let mediaGallery = []; if (product.media_gallery) { for (let mediaItem of product.media_gallery) { if (mediaItem.image) { - let video = mediaItem.vid + let video = mediaItem.vid; if (video && video.video_id) { - video.id = video.video_id - delete video.video_id + video.id = video.video_id; + delete video.video_id; } mediaGallery.push({ - 'src': getThumbnailPath(mediaItem.image, rootStore.state.config.products.gallery.width, rootStore.state.config.products.gallery.height), - 'loading': getThumbnailPath(mediaItem.image, 310, 300), - 'error': getThumbnailPath(mediaItem.image, 310, 300), - 'video': video - }) + src: getThumbnailPath( + mediaItem.image, + rootStore.state.config.products.gallery.width, + rootStore.state.config.products.gallery.height + ), + loading: getThumbnailPath(mediaItem.image, 310, 300), + error: getThumbnailPath(mediaItem.image, 310, 300), + video: video + }); } } } - return mediaGallery + return mediaGallery; } /** @@ -553,23 +782,30 @@ export function getMediaGallery (product) { */ export function configurableChildrenImages(product) { - let configurableChildrenImages = [] - if (product.configurable_children && product.configurable_children.length > 0) { - let configurableAttributes = product.configurable_options.map(option => option.attribute_code) - configurableChildrenImages = product.configurable_children.map(child => - ({ - 'src': getThumbnailPath(child.image, rootStore.state.config.products.gallery.width, rootStore.state.config.products.gallery.height), - 'loading': getThumbnailPath(product.image, 310, 300), - 'id': configurableAttributes.reduce((result, attribute) => { - result[attribute] = child[attribute] - return result - }, {}) - }) - ) + let configurableChildrenImages = []; + if ( + product.configurable_children && + product.configurable_children.length > 0 + ) { + let configurableAttributes = product.configurable_options.map( + option => option.attribute_code + ); + configurableChildrenImages = product.configurable_children.map(child => ({ + src: getThumbnailPath( + child.image, + rootStore.state.config.products.gallery.width, + rootStore.state.config.products.gallery.height + ), + loading: getThumbnailPath(product.image, 310, 300), + id: configurableAttributes.reduce((result, attribute) => { + result[attribute] = child[attribute]; + return result; + }, {}) + })); } else { - configurableChildrenImages = attributeImages(product) + configurableChildrenImages = attributeImages(product); } - return configurableChildrenImages + return configurableChildrenImages; } /** @@ -577,18 +813,22 @@ export function configurableChildrenImages(product) { */ export function attributeImages(product) { - let attributeImages = [] - if (rootStore.state.config.products.gallery.imageAttributes) { - for (let attribute of rootStore.state.config.products.gallery.imageAttributes) { - if(product[attribute]) { - attributeImages.push({ - 'src': getThumbnailPath(product[attribute], rootStore.state.config.products.gallery.width, rootStore.state.config.products.gallery.height), - 'loading': getThumbnailPath(product[attribute], 310, 300), - 'error': getThumbnailPath(product[attribute], 310, 300) - }) - } - } + let attributeImages = []; + if (rootStore.state.config.products.gallery.imageAttributes) { + for (let attribute of rootStore.state.config.products.gallery + .imageAttributes) { + if (product[attribute]) { + attributeImages.push({ + src: getThumbnailPath( + product[attribute], + rootStore.state.config.products.gallery.width, + rootStore.state.config.products.gallery.height + ), + loading: getThumbnailPath(product[attribute], 310, 300), + error: getThumbnailPath(product[attribute], 310, 300) + }); + } } - return attributeImages + } + return attributeImages; } - diff --git a/core/modules/catalog/helpers/optionLabel.ts b/core/modules/catalog/helpers/optionLabel.ts index 12549b6585..915d848414 100644 --- a/core/modules/catalog/helpers/optionLabel.ts +++ b/core/modules/catalog/helpers/optionLabel.ts @@ -4,36 +4,40 @@ * @param {String} attributeCode * @param {String} optionId - value to get label for */ -import toString from 'lodash-es/toString' +import toString from 'lodash-es/toString'; -export function optionLabel (state, { attributeKey, searchBy = 'code', optionId }) { - let attrCache = state.labels[attributeKey] +export function optionLabel( + state, + { attributeKey, searchBy = 'code', optionId } +) { + let attrCache = state.labels[attributeKey]; if (attrCache) { - let label = attrCache[optionId] + let label = attrCache[optionId]; if (label) { - return label + return label; } } - let attr = state['list_by_' + searchBy][attributeKey] + let attr = state['list_by_' + searchBy][attributeKey]; if (attr) { - let opt = attr.options.find((op) => { // TODO: cache it in memory + let opt = attr.options.find(op => { + // TODO: cache it in memory if (toString(op.value) === toString(optionId)) { - return op + return op; } - }) // TODO: i18n support with multi-website attribute names + }); // TODO: i18n support with multi-website attribute names if (opt) { if (!state.labels[attributeKey]) { - state.labels[attributeKey] = {} + state.labels[attributeKey] = {}; } - state.labels[attributeKey][optionId] = opt.label - return opt ? opt.label : optionId + state.labels[attributeKey][optionId] = opt.label; + return opt ? opt.label : optionId; } else { - return optionId + return optionId; } } else { - return optionId + return optionId; } } diff --git a/core/modules/catalog/helpers/tax.ts b/core/modules/catalog/helpers/tax.ts index 067d536172..d1ac69798b 100644 --- a/core/modules/catalog/helpers/tax.ts +++ b/core/modules/catalog/helpers/tax.ts @@ -1,155 +1,211 @@ -import { Logger } from '@vue-storefront/core/lib/logger' +import { Logger } from '@vue-storefront/core/lib/logger'; function isSpecialPriceActive(fromDate, toDate) { - const now = new Date() - fromDate = new Date(fromDate) || false - toDate = new Date(toDate) || false + const now = new Date(); + fromDate = new Date(fromDate) || false; + toDate = new Date(toDate) || false; if (fromDate && toDate) { - return fromDate < now && toDate > now + return fromDate < now && toDate > now; } if (fromDate && !toDate) { - return fromDate < now + return fromDate < now; } if (!fromDate && toDate) { - return toDate > now + return toDate > now; } } -export function updateProductPrices (product, rate, sourcePriceInclTax = false) { - const rateFactor = parseFloat(rate.rate) / 100 - product.price = parseFloat(product.price) - product.special_price = parseFloat(product.special_price) +export function updateProductPrices(product, rate, sourcePriceInclTax = false) { + const rateFactor = parseFloat(rate.rate) / 100; + product.price = parseFloat(product.price); + product.special_price = parseFloat(product.special_price); - let priceExclTax = product.price + let priceExclTax = product.price; if (sourcePriceInclTax) { - priceExclTax = product.price / (1 + rateFactor) - product.price = priceExclTax + priceExclTax = product.price / (1 + rateFactor); + product.price = priceExclTax; } - product.priceTax = priceExclTax * rateFactor - product.priceInclTax = priceExclTax + product.priceTax + product.priceTax = priceExclTax * rateFactor; + product.priceInclTax = priceExclTax + product.priceTax; - let specialPriceExclTax = product.special_price + let specialPriceExclTax = product.special_price; if (sourcePriceInclTax) { - specialPriceExclTax = product.special_price / (1 + rateFactor) - product.special_price = specialPriceExclTax + specialPriceExclTax = product.special_price / (1 + rateFactor); + product.special_price = specialPriceExclTax; } - product.specialPriceTax = specialPriceExclTax * rateFactor - product.specialPriceInclTax = specialPriceExclTax + product.specialPriceTax + product.specialPriceTax = specialPriceExclTax * rateFactor; + product.specialPriceInclTax = specialPriceExclTax + product.specialPriceTax; - if (product.special_price && (product.special_price < product.price)) { - if (!isSpecialPriceActive(product.special_from_date, product.special_to_date)) { - product.special_price = 0 // out of the dates period + if (product.special_price && product.special_price < product.price) { + if ( + !isSpecialPriceActive(product.special_from_date, product.special_to_date) + ) { + product.special_price = 0; // out of the dates period } else { - product.originalPrice = priceExclTax - product.originalPriceInclTax = product.priceInclTax - product.originalPriceTax = product.priceTax + product.originalPrice = priceExclTax; + product.originalPriceInclTax = product.priceInclTax; + product.originalPriceTax = product.priceTax; - product.price = specialPriceExclTax - product.priceInclTax = product.specialPriceInclTax - product.priceTax = product.specialPriceTax + product.price = specialPriceExclTax; + product.priceInclTax = product.specialPriceInclTax; + product.priceTax = product.specialPriceTax; } } else { - product.special_price = 0 // the same price as original; it's not a promotion + product.special_price = 0; // the same price as original; it's not a promotion } if (product.configurable_children) { for (let configurableChild of product.configurable_children) { if (configurableChild.custom_attributes) { for (let opt of configurableChild.custom_attributes) { - configurableChild[opt.attribute_code] = opt.value + configurableChild[opt.attribute_code] = opt.value; } } - configurableChild.price = parseFloat(configurableChild.price) - configurableChild.special_price = parseFloat(configurableChild.special_price) + configurableChild.price = parseFloat(configurableChild.price); + configurableChild.special_price = parseFloat( + configurableChild.special_price + ); - let priceExclTax = configurableChild.price + let priceExclTax = configurableChild.price; if (sourcePriceInclTax) { - priceExclTax = configurableChild.price / (1 + rateFactor) - configurableChild.price = priceExclTax + priceExclTax = configurableChild.price / (1 + rateFactor); + configurableChild.price = priceExclTax; } - configurableChild.priceTax = priceExclTax * rateFactor - configurableChild.priceInclTax = priceExclTax + configurableChild.priceTax + configurableChild.priceTax = priceExclTax * rateFactor; + configurableChild.priceInclTax = + priceExclTax + configurableChild.priceTax; - let specialPriceExclTax = parseFloat(configurableChild.special_price) + let specialPriceExclTax = parseFloat(configurableChild.special_price); if (sourcePriceInclTax) { - specialPriceExclTax = configurableChild.special_price / (1 + rateFactor) - configurableChild.special_price = specialPriceExclTax + specialPriceExclTax = + configurableChild.special_price / (1 + rateFactor); + configurableChild.special_price = specialPriceExclTax; } - configurableChild.specialPriceTax = specialPriceExclTax * rateFactor - configurableChild.specialPriceInclTax = specialPriceExclTax + configurableChild.specialPriceTax - - if (configurableChild.special_price && (configurableChild.special_price < configurableChild.price)) { - if (!isSpecialPriceActive(configurableChild.special_from_date, configurableChild.special_to_date)) { - configurableChild.special_price = 0 // out of the dates period + configurableChild.specialPriceTax = specialPriceExclTax * rateFactor; + configurableChild.specialPriceInclTax = + specialPriceExclTax + configurableChild.specialPriceTax; + + if ( + configurableChild.special_price && + configurableChild.special_price < configurableChild.price + ) { + if ( + !isSpecialPriceActive( + configurableChild.special_from_date, + configurableChild.special_to_date + ) + ) { + configurableChild.special_price = 0; // out of the dates period } else { - configurableChild.originalPrice = priceExclTax - configurableChild.originalPriceInclTax = configurableChild.priceInclTax - configurableChild.originalPriceTax = configurableChild.priceTax - - configurableChild.price = specialPriceExclTax - configurableChild.priceInclTax = configurableChild.specialPriceInclTax - configurableChild.priceTax = configurableChild.specialPriceTax + configurableChild.originalPrice = priceExclTax; + configurableChild.originalPriceInclTax = + configurableChild.priceInclTax; + configurableChild.originalPriceTax = configurableChild.priceTax; + + configurableChild.price = specialPriceExclTax; + configurableChild.priceInclTax = + configurableChild.specialPriceInclTax; + configurableChild.priceTax = configurableChild.specialPriceTax; } } else { - configurableChild.special_price = 0 + configurableChild.special_price = 0; } - if (configurableChild.priceInclTax < product.priceInclTax || product.price === 0) { // always show the lowest price - product.priceInclTax = configurableChild.priceInclTax - product.priceTax = configurableChild.priceTax - product.price = configurableChild.price - product.special_price = configurableChild.special_price - product.specialPriceInclTax = configurableChild.specialPriceInclTax - product.specialPriceTax = configurableChild.specialPriceTax - product.originalPrice = configurableChild.originalPrice - product.originalPriceInclTax = configurableChild.originalPriceInclTax - product.originalPriceTax = configurableChild.originalPriceTax + if ( + configurableChild.priceInclTax < product.priceInclTax || + product.price === 0 + ) { + // always show the lowest price + product.priceInclTax = configurableChild.priceInclTax; + product.priceTax = configurableChild.priceTax; + product.price = configurableChild.price; + product.special_price = configurableChild.special_price; + product.specialPriceInclTax = configurableChild.specialPriceInclTax; + product.specialPriceTax = configurableChild.specialPriceTax; + product.originalPrice = configurableChild.originalPrice; + product.originalPriceInclTax = configurableChild.originalPriceInclTax; + product.originalPriceTax = configurableChild.originalPriceTax; } } } } -export function calculateProductTax (product, taxClasses, taxCountry = 'PL', taxRegion = '', sourcePriceInclTax = false) { - let rateFound = false +export function calculateProductTax( + product, + taxClasses, + taxCountry = 'PL', + taxRegion = '', + sourcePriceInclTax = false +) { + let rateFound = false; if (product.tax_class_id > 0) { - let taxClass = taxClasses.find((el) => el.product_tax_class_ids.indexOf(parseInt(product.tax_class_id) >= 0)) + let taxClass = taxClasses.find(el => + el.product_tax_class_ids.indexOf(parseInt(product.tax_class_id) >= 0) + ); if (taxClass) { - for (let rate of taxClass.rates) { // TODO: add check for zip code ranges (!) - if (rate.tax_country_id === taxCountry && (rate.region_name === taxRegion || rate.tax_region_id === 0 || !rate.region_name)) { - updateProductPrices(product, rate, sourcePriceInclTax) - rateFound = true - Logger.debug('Tax rate ' + rate.code + ' = ' + rate.rate + '% found for ' + taxCountry + ' / ' + taxRegion, 'helper-tax')() - break + for (let rate of taxClass.rates) { + // TODO: add check for zip code ranges (!) + if ( + rate.tax_country_id === taxCountry && + (rate.region_name === taxRegion || + rate.tax_region_id === 0 || + !rate.region_name) + ) { + updateProductPrices(product, rate, sourcePriceInclTax); + rateFound = true; + Logger.debug( + 'Tax rate ' + + rate.code + + ' = ' + + rate.rate + + '% found for ' + + taxCountry + + ' / ' + + taxRegion, + 'helper-tax' + )(); + break; } } } else { - Logger.debug('No such tax class id: ' + product.tax_class_id, 'helper-tax')() + Logger.debug( + 'No such tax class id: ' + product.tax_class_id, + 'helper-tax' + )(); } - } else { - Logger.debug('No tax class set for: ' + product.sku, 'helper-tax')() + } else { + Logger.debug('No tax class set for: ' + product.sku, 'helper-tax')(); } if (!rateFound) { - Logger.log('No such tax class id: ' + product.tax_class_id + ' or rate not found for ' + taxCountry + ' / ' + taxRegion, 'helper-tax')() - updateProductPrices(product, {rate: 0}) - - product.priceInclTax = product.price - product.priceTax = 0 - product.specialPriceInclTax = 0 - product.specialPriceTax = 0 + Logger.log( + 'No such tax class id: ' + + product.tax_class_id + + ' or rate not found for ' + + taxCountry + + ' / ' + + taxRegion, + 'helper-tax' + )(); + updateProductPrices(product, { rate: 0 }); + + product.priceInclTax = product.price; + product.priceTax = 0; + product.specialPriceInclTax = 0; + product.specialPriceTax = 0; if (product.configurable_children) { for (let configurableChildren of product.configurable_children) { - configurableChildren.priceInclTax = configurableChildren.price - configurableChildren.priceTax = 0 - configurableChildren.specialPriceInclTax = 0 - configurableChildren.specialPriceTax = 0 + configurableChildren.priceInclTax = configurableChildren.price; + configurableChildren.priceTax = 0; + configurableChildren.specialPriceInclTax = 0; + configurableChildren.specialPriceTax = 0; } } } diff --git a/core/modules/catalog/hooks/beforeRegistration.ts b/core/modules/catalog/hooks/beforeRegistration.ts index dbb6fc83ba..30bdaf81c3 100644 --- a/core/modules/catalog/hooks/beforeRegistration.ts +++ b/core/modules/catalog/hooks/beforeRegistration.ts @@ -1,32 +1,42 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.categoriesCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'categories', - driver: localForage[config.localForage.defaultDrivers['categories']] - })) + Vue.prototype.$db.categoriesCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'categories', + driver: localForage[config.localForage.defaultDrivers['categories']] + }) + ); - Vue.prototype.$db.attributesCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'attributes', - driver: localForage[config.localForage.defaultDrivers['attributes']] - })) + Vue.prototype.$db.attributesCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'attributes', + driver: localForage[config.localForage.defaultDrivers['attributes']] + }) + ); - Vue.prototype.$db.elasticCacheCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'elasticCache', - driver: localForage[config.localForage.defaultDrivers['elasticCache']] - }), true, config.server.elasticCacheQuota) + Vue.prototype.$db.elasticCacheCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'elasticCache', + driver: localForage[config.localForage.defaultDrivers['elasticCache']] + }), + true, + config.server.elasticCacheQuota + ); - Vue.prototype.$db.productsCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'products', - driver: localForage[config.localForage.defaultDrivers['products']] - })) -} \ No newline at end of file + Vue.prototype.$db.productsCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'products', + driver: localForage[config.localForage.defaultDrivers['products']] + }) + ); +} diff --git a/core/modules/catalog/index.ts b/core/modules/catalog/index.ts index edf19d1830..91e4155aba 100644 --- a/core/modules/catalog/index.ts +++ b/core/modules/catalog/index.ts @@ -1,20 +1,22 @@ -import { productModule } from './store/product' -import { attributeModule } from './store/attribute' -import { stockModule } from './store/stock' -import { taxModule } from './store/tax' -import { categoryModule } from './store/category' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' +import { productModule } from './store/product'; +import { attributeModule } from './store/attribute'; +import { stockModule } from './store/stock'; +import { taxModule } from './store/tax'; +import { categoryModule } from './store/category'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; -export const KEY = 'catalog' +export const KEY = 'catalog'; export const Catalog = createModule({ key: KEY, - store: { modules: [ - { key: 'product', module: productModule }, - { key: 'attribute', module: attributeModule }, - { key: 'stock', module: stockModule }, - { key: 'tax', module: taxModule }, - { key: 'category', module: categoryModule } - ] }, + store: { + modules: [ + { key: 'product', module: productModule }, + { key: 'attribute', module: attributeModule }, + { key: 'stock', module: stockModule }, + { key: 'tax', module: taxModule }, + { key: 'category', module: categoryModule } + ] + }, beforeRegistration -}) \ No newline at end of file +}); diff --git a/core/modules/catalog/queries/common.js b/core/modules/catalog/queries/common.js index 6870a69b3b..7be0e3e05d 100644 --- a/core/modules/catalog/queries/common.js +++ b/core/modules/catalog/queries/common.js @@ -1,38 +1,50 @@ -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import store from '@vue-storefront/core/store' +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import store from '@vue-storefront/core/store'; -export function prepareQuery ({queryText = '', filters = [], queryConfig = ''}) { - let query = new SearchQuery() +export function prepareQuery({ + queryText = '', + filters = [], + queryConfig = '' +}) { + let query = new SearchQuery(); // prepare filters and searchText if (filters.length === 0 && queryConfig !== '') { // try get filters from config - if (store.state.config.hasOwnProperty('query') && store.state.config.query.hasOwnProperty(queryConfig) && store.state.config.query[queryConfig].hasOwnProperty('filter')) { - filters = store.state.config.query[queryConfig].filter + if ( + store.state.config.hasOwnProperty('query') && + store.state.config.query.hasOwnProperty(queryConfig) && + store.state.config.query[queryConfig].hasOwnProperty('filter') + ) { + filters = store.state.config.query[queryConfig].filter; } } if (queryText === '') { // try to get searchText from config - if (store.state.config.hasOwnProperty('query') && store.state.config.query.hasOwnProperty(queryConfig) && store.state.config.query[queryConfig].hasOwnProperty('searchText')) { - queryText = store.state.config.query[queryConfig].searchText + if ( + store.state.config.hasOwnProperty('query') && + store.state.config.query.hasOwnProperty(queryConfig) && + store.state.config.query[queryConfig].hasOwnProperty('searchText') + ) { + queryText = store.state.config.query[queryConfig].searchText; } } // Process filters and searchText if exists if (filters.length > 0) { filters.forEach(filter => { - query = query.applyFilter({key: filter.key, value: filter.value}) // Tees category - }) + query = query.applyFilter({ key: filter.key, value: filter.value }); // Tees category + }); } if (queryText !== '') { - query = query.setSearchText(queryText) + query = query.setSearchText(queryText); } // Add basic filters query = query - .applyFilter({key: 'visibility', value: {'in': [2, 3, 4]}}) - .applyFilter({key: 'status', value: {'in': [0, 1]}}) + .applyFilter({ key: 'visibility', value: { in: [2, 3, 4] } }) + .applyFilter({ key: 'status', value: { in: [0, 1] } }); - return query + return query; } diff --git a/core/modules/catalog/queries/related.js b/core/modules/catalog/queries/related.js index 5d340f3074..d0c4321e23 100644 --- a/core/modules/catalog/queries/related.js +++ b/core/modules/catalog/queries/related.js @@ -1,18 +1,24 @@ -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import store from '@vue-storefront/core/store' +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import store from '@vue-storefront/core/store'; -export function prepareRelatedQuery (key, sku) { - let relatedProductsQuery = new SearchQuery() +export function prepareRelatedQuery(key, sku) { + let relatedProductsQuery = new SearchQuery(); - relatedProductsQuery = relatedProductsQuery.applyFilter({key: key, value: {'in': sku}}) + relatedProductsQuery = relatedProductsQuery.applyFilter({ + key: key, + value: { in: sku } + }); relatedProductsQuery = relatedProductsQuery - .applyFilter({key: 'visibility', value: {'in': [2, 3, 4]}}) - .applyFilter({key: 'status', value: {'in': [1]}}) + .applyFilter({ key: 'visibility', value: { in: [2, 3, 4] } }) + .applyFilter({ key: 'status', value: { in: [1] } }); if (store.state.config.products.listOutOfStockProducts === false) { - relatedProductsQuery = relatedProductsQuery.applyFilter({key: 'stock.is_in_stock', value: {'eq': true}}) + relatedProductsQuery = relatedProductsQuery.applyFilter({ + key: 'stock.is_in_stock', + value: { eq: true } + }); } - return relatedProductsQuery + return relatedProductsQuery; } diff --git a/core/modules/catalog/queries/searchPanel.js b/core/modules/catalog/queries/searchPanel.js index 289dc18bb2..6a4d9e8e85 100644 --- a/core/modules/catalog/queries/searchPanel.js +++ b/core/modules/catalog/queries/searchPanel.js @@ -1,17 +1,23 @@ -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import store from '@vue-storefront/core/store' +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import store from '@vue-storefront/core/store'; -export function prepareQuickSearchQuery (queryText) { - let searchQuery = new SearchQuery() +export function prepareQuickSearchQuery(queryText) { + let searchQuery = new SearchQuery(); searchQuery = searchQuery .setSearchText(queryText) - .applyFilter({key: 'visibility', value: {'in': [3, 4]}}) - .applyFilter({key: 'status', value: {'in': [0, 1]}})/* 2 = disabled, 3 = out of stock */ + .applyFilter({ key: 'visibility', value: { in: [3, 4] } }) + .applyFilter({ + key: 'status', + value: { in: [0, 1] } + }); /* 2 = disabled, 3 = out of stock */ if (store.state.config.products.listOutOfStockProducts === false) { - searchQuery = searchQuery.applyFilter({key: 'stock.is_in_stock', value: {'eq': true}}) + searchQuery = searchQuery.applyFilter({ + key: 'stock.is_in_stock', + value: { eq: true } + }); } - return searchQuery + return searchQuery; } diff --git a/core/modules/catalog/store/attribute/actions.ts b/core/modules/catalog/store/attribute/actions.ts index 8bdb1ff000..145723361d 100644 --- a/core/modules/catalog/store/attribute/actions.ts +++ b/core/modules/catalog/store/attribute/actions.ts @@ -1,11 +1,11 @@ -import * as types from './mutation-types' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import AttributeState from '../../types/AttributeState' -import RootState from '@vue-storefront/core/types/RootState' -import { ActionTree } from 'vuex' -import rootStore from '@vue-storefront/core/store' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as types from './mutation-types'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import AttributeState from '../../types/AttributeState'; +import RootState from '@vue-storefront/core/types/RootState'; +import { ActionTree } from 'vuex'; +import rootStore from '@vue-storefront/core/store'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { /** @@ -13,42 +13,92 @@ const actions: ActionTree = { * @param {Object} context * @param {Array} attrCodes attribute codes to load */ - list (context, { filterValues = null, filterField = 'attribute_code', only_user_defined = false, only_visible = false, size = 150, start = 0, includeFields = rootStore.state.config.entities.optimize ? rootStore.state.config.entities.attribute.includeFields : null }) { - const commit = context.commit + list( + context, + { + filterValues = null, + filterField = 'attribute_code', + only_user_defined = false, + only_visible = false, + size = 150, + start = 0, + includeFields = rootStore.state.config.entities.optimize + ? rootStore.state.config.entities.attribute.includeFields + : null + } + ) { + const commit = context.commit; - let searchQuery = new SearchQuery() - const orgFilterValues = filterValues ? [...filterValues] : [] + let searchQuery = new SearchQuery(); + const orgFilterValues = filterValues ? [...filterValues] : []; if (filterValues) { - filterValues = filterValues.filter(fv => { // check the already loaded - if (context.state.blacklist !== null && context.state.blacklist.includes(fv)) return false // return that this attribute is not on our blacklist - if (filterField === 'attribute_id') return (typeof context.state.list_by_id[fv] === 'undefined' || context.state.list_by_id[fv] === null) - if (filterField === 'attribute_code') return (typeof context.state.list_by_code[fv] === 'undefined' || context.state.list_by_code[fv] === null) - }) + filterValues = filterValues.filter(fv => { + // check the already loaded + if ( + context.state.blacklist !== null && + context.state.blacklist.includes(fv) + ) + return false; // return that this attribute is not on our blacklist + if (filterField === 'attribute_id') + return ( + typeof context.state.list_by_id[fv] === 'undefined' || + context.state.list_by_id[fv] === null + ); + if (filterField === 'attribute_code') + return ( + typeof context.state.list_by_code[fv] === 'undefined' || + context.state.list_by_code[fv] === null + ); + }); if (!filterValues || filterValues.length === 0) { - Logger.info('Skipping attribute load - attributes already loaded', 'attr', { orgFilterValues, filterField})() + Logger.info( + 'Skipping attribute load - attributes already loaded', + 'attr', + { orgFilterValues, filterField } + )(); return Promise.resolve({ items: Object.values(context.state.list_by_code) - }) + }); } - searchQuery = searchQuery.applyFilter({key: filterField, value: {'in': filterValues}}) + searchQuery = searchQuery.applyFilter({ + key: filterField, + value: { in: filterValues } + }); } if (only_user_defined) { - searchQuery = searchQuery.applyFilter({key: 'is_user_defined', value: {'in': [true]}}) + searchQuery = searchQuery.applyFilter({ + key: 'is_user_defined', + value: { in: [true] } + }); } if (only_visible) { - searchQuery = searchQuery.applyFilter({key: 'is_visible', value: {'in': [true]}}) + searchQuery = searchQuery.applyFilter({ + key: 'is_visible', + value: { in: [true] } + }); } - return quickSearchByQuery({ entityType: 'attribute', query: searchQuery, includeFields: includeFields }).then((resp) => { - if (resp && Array.isArray(orgFilterValues) && orgFilterValues.length > 0) { - const foundValues = resp.items.map(attr => attr[filterField]) - const toBlackList = filterValues.filter(ofv => !foundValues.includes(ofv)) + return quickSearchByQuery({ + entityType: 'attribute', + query: searchQuery, + includeFields: includeFields + }).then(resp => { + if ( + resp && + Array.isArray(orgFilterValues) && + orgFilterValues.length > 0 + ) { + const foundValues = resp.items.map(attr => attr[filterField]); + const toBlackList = filterValues.filter( + ofv => !foundValues.includes(ofv) + ); toBlackList.map(tbl => { - if (!context.state.blacklist.includes(tbl)) context.state.blacklist.push(tbl) - }) // extend the black list of not-found atrbiutes + if (!context.state.blacklist.includes(tbl)) + context.state.blacklist.push(tbl); + }); // extend the black list of not-found atrbiutes } - commit(types.ATTRIBUTE_UPD_ATTRIBUTES, resp) - }) + commit(types.ATTRIBUTE_UPD_ATTRIBUTES, resp); + }); } -} +}; -export default actions +export default actions; diff --git a/core/modules/catalog/store/attribute/getters.ts b/core/modules/catalog/store/attribute/getters.ts index 920d0fbf76..0364b65f1b 100644 --- a/core/modules/catalog/store/attribute/getters.ts +++ b/core/modules/catalog/store/attribute/getters.ts @@ -1,10 +1,10 @@ -import { GetterTree } from 'vuex' -import AttributeState from '../../types/AttributeState' -import RootState from '@vue-storefront/core/types/RootState' +import { GetterTree } from 'vuex'; +import AttributeState from '../../types/AttributeState'; +import RootState from '@vue-storefront/core/types/RootState'; const getters: GetterTree = { - attributeListByCode: (state) => state.list_by_code, - attributeListById: (state) => state.list_by_id -} + attributeListByCode: state => state.list_by_code, + attributeListById: state => state.list_by_id +}; -export default getters +export default getters; diff --git a/core/modules/catalog/store/attribute/index.ts b/core/modules/catalog/store/attribute/index.ts index 9a747e3aba..796780e603 100644 --- a/core/modules/catalog/store/attribute/index.ts +++ b/core/modules/catalog/store/attribute/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import AttributeState from '../../types/AttributeState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import AttributeState from '../../types/AttributeState'; export const attributeModule: Module = { namespaced: true, @@ -16,4 +16,4 @@ export const attributeModule: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/catalog/store/attribute/mutation-types.ts b/core/modules/catalog/store/attribute/mutation-types.ts index 018e93ca03..0462fbb5ff 100644 --- a/core/modules/catalog/store/attribute/mutation-types.ts +++ b/core/modules/catalog/store/attribute/mutation-types.ts @@ -1,2 +1,2 @@ -export const SN_ATTRIBUTE = 'attribute' -export const ATTRIBUTE_UPD_ATTRIBUTES = SN_ATTRIBUTE + '/UPD_ATTRIBUTES' +export const SN_ATTRIBUTE = 'attribute'; +export const ATTRIBUTE_UPD_ATTRIBUTES = SN_ATTRIBUTE + '/UPD_ATTRIBUTES'; diff --git a/core/modules/catalog/store/attribute/mutations.ts b/core/modules/catalog/store/attribute/mutations.ts index 79c0c94a3c..18e7cabe49 100644 --- a/core/modules/catalog/store/attribute/mutations.ts +++ b/core/modules/catalog/store/attribute/mutations.ts @@ -1,9 +1,9 @@ -import Vue from 'vue' -import { MutationTree } from 'vuex' -import { entityKeyName } from '@vue-storefront/core/store/lib/entities' -import * as types from './mutation-types' -import AttributeState from '../../types/AttributeState' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { MutationTree } from 'vuex'; +import { entityKeyName } from '@vue-storefront/core/store/lib/entities'; +import * as types from './mutation-types'; +import AttributeState from '../../types/AttributeState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const mutations: MutationTree = { /** @@ -11,31 +11,41 @@ const mutations: MutationTree = { * @param {} state * @param {Array} attributes */ - [types.ATTRIBUTE_UPD_ATTRIBUTES] (state, attributes) { - let attrList = attributes.items // extract fields from ES _source - let attrHashByCode = state.list_by_code - let attrHashById = state.list_by_id + [types.ATTRIBUTE_UPD_ATTRIBUTES](state, attributes) { + let attrList = attributes.items; // extract fields from ES _source + let attrHashByCode = state.list_by_code; + let attrHashById = state.list_by_id; for (let attr of attrList) { - attrHashByCode[attr.attribute_code] = attr - attrHashById[attr.attribute_id] = attr + attrHashByCode[attr.attribute_code] = attr; + attrHashById[attr.attribute_id] = attr; - const attrCollection = Vue.prototype.$db.attributesCollection + const attrCollection = Vue.prototype.$db.attributesCollection; try { - attrCollection.setItem(entityKeyName('attribute_code', attr.attribute_code.toLowerCase()), attr).catch((reason) => { - Logger.error(reason, 'mutations') // it doesn't work on SSR - }) // populate cache by slug - attrCollection.setItem(entityKeyName('attribute_id', attr.attribute_id.toString()), attr).catch((reason) => { - Logger.error(reason, 'mutations') // it doesn't work on SSR - }) // populate cache by id + attrCollection + .setItem( + entityKeyName('attribute_code', attr.attribute_code.toLowerCase()), + attr + ) + .catch(reason => { + Logger.error(reason, 'mutations'); // it doesn't work on SSR + }); // populate cache by slug + attrCollection + .setItem( + entityKeyName('attribute_id', attr.attribute_id.toString()), + attr + ) + .catch(reason => { + Logger.error(reason, 'mutations'); // it doesn't work on SSR + }); // populate cache by id } catch (e) { - Logger.error(e, 'mutations')() + Logger.error(e, 'mutations')(); } } - Vue.set(state, 'list_by_code', attrHashByCode) - Vue.set(state, 'list_by_id', attrHashById) - Vue.prototype.$bus.$emit('product-after-attributes-loaded') + Vue.set(state, 'list_by_code', attrHashByCode); + Vue.set(state, 'list_by_id', attrHashById); + Vue.prototype.$bus.$emit('product-after-attributes-loaded'); } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/catalog/store/category/actions.ts b/core/modules/catalog/store/category/actions.ts index d6d1ae8cf3..d5dedc6772 100644 --- a/core/modules/catalog/store/category/actions.ts +++ b/core/modules/catalog/store/category/actions.ts @@ -1,98 +1,177 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import { entityKeyName } from '@vue-storefront/core/store/lib/entities' -import rootStore from '@vue-storefront/core/store' -import i18n from '@vue-storefront/i18n' -import chunk from 'lodash-es/chunk' -import trim from 'lodash-es/trim' -import toString from 'lodash-es/toString' -import { optionLabel } from '../../helpers/optionLabel' -import RootState from '@vue-storefront/core/types/RootState' -import CategoryState from '../../types/CategoryState' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { Logger } from '@vue-storefront/core/lib/logger' -import { isServer } from '@vue-storefront/core/helpers' - +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import { entityKeyName } from '@vue-storefront/core/store/lib/entities'; +import rootStore from '@vue-storefront/core/store'; +import i18n from '@vue-storefront/i18n'; +import chunk from 'lodash-es/chunk'; +import trim from 'lodash-es/trim'; +import toString from 'lodash-es/toString'; +import { optionLabel } from '../../helpers/optionLabel'; +import RootState from '@vue-storefront/core/types/RootState'; +import CategoryState from '../../types/CategoryState'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { isServer } from '@vue-storefront/core/helpers'; const actions: ActionTree = { /** * Reset current category and path * @param {Object} context */ - reset (context) { - context.commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, []) - context.commit(types.CATEGORY_UPD_CURRENT_CATEGORY, {}) - rootStore.dispatch('stock/clearCache') - Vue.prototype.$bus.$emit('category-after-reset', { }) + reset(context) { + context.commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, []); + context.commit(types.CATEGORY_UPD_CURRENT_CATEGORY, {}); + rootStore.dispatch('stock/clearCache'); + Vue.prototype.$bus.$emit('category-after-reset', {}); }, /** * Load categories within specified parent * @param {Object} commit promise * @param {Object} parent parent category */ - list (context, { parent = null, key = null, value = null, level = null, onlyActive = true, onlyNotEmpty = false, size = 4000, start = 0, sort = 'position:asc', includeFields = rootStore.state.config.entities.optimize ? rootStore.state.config.entities.category.includeFields : null, excludeFields = rootStore.state.config.entities.optimize ? rootStore.state.config.entities.category.excludeFields : null, skipCache = false, updateState = true }) { - const commit = context.commit - let customizedQuery = false // that means the parameteres are != defaults; with defaults parameter the data could be get from window.__INITIAL_STATE__ - this is optimisation trick - let searchQuery = new SearchQuery() + list( + context, + { + parent = null, + key = null, + value = null, + level = null, + onlyActive = true, + onlyNotEmpty = false, + size = 4000, + start = 0, + sort = 'position:asc', + includeFields = rootStore.state.config.entities.optimize + ? rootStore.state.config.entities.category.includeFields + : null, + excludeFields = rootStore.state.config.entities.optimize + ? rootStore.state.config.entities.category.excludeFields + : null, + skipCache = false, + updateState = true + } + ) { + const commit = context.commit; + let customizedQuery = false; // that means the parameteres are != defaults; with defaults parameter the data could be get from window.__INITIAL_STATE__ - this is optimisation trick + let searchQuery = new SearchQuery(); if (parent && typeof parent !== 'undefined') { - searchQuery = searchQuery.applyFilter({key: 'parent_id', value: {'eq': typeof parent === 'object' ? parent.id : parent }}) - customizedQuery = true + searchQuery = searchQuery.applyFilter({ + key: 'parent_id', + value: { eq: typeof parent === 'object' ? parent.id : parent } + }); + customizedQuery = true; } if (level !== null) { - searchQuery = searchQuery.applyFilter({key: 'level', value: {'eq': level}}) - if (level !== rootStore.state.config.entities.category.categoriesDynamicPrefetchLevel && !isServer) // if this is the default level we're getting the results from window.__INITIAL_STATE__ not querying the server - customizedQuery = true + searchQuery = searchQuery.applyFilter({ + key: 'level', + value: { eq: level } + }); + if ( + level !== + rootStore.state.config.entities.category + .categoriesDynamicPrefetchLevel && + !isServer + ) + // if this is the default level we're getting the results from window.__INITIAL_STATE__ not querying the server + customizedQuery = true; } if (key !== null) { if (Array.isArray(value)) { - searchQuery = searchQuery.applyFilter({key: key, value: {'in': value}}) + searchQuery = searchQuery.applyFilter({ + key: key, + value: { in: value } + }); } else { - searchQuery = searchQuery.applyFilter({key: key, value: {'eq': value}}) + searchQuery = searchQuery.applyFilter({ + key: key, + value: { eq: value } + }); } - customizedQuery = true + customizedQuery = true; } if (onlyActive === true) { - searchQuery = searchQuery.applyFilter({key: 'is_active', value: {'eq': true}}) + searchQuery = searchQuery.applyFilter({ + key: 'is_active', + value: { eq: true } + }); } if (onlyNotEmpty === true) { - searchQuery = searchQuery.applyFilter({key: 'product_count', value: {'gt': 0}}) - customizedQuery = true + searchQuery = searchQuery.applyFilter({ + key: 'product_count', + value: { gt: 0 } + }); + customizedQuery = true; } - if (skipCache || ((!context.state.list || context.state.list.length === 0) || customizedQuery)) { - return quickSearchByQuery({ entityType: 'category', query: searchQuery, sort: sort, size: size, start: start, includeFields: includeFields, excludeFields: excludeFields }).then((resp) => { - for (let category of resp.items) { - if (category.url_path && updateState) { - rootStore.dispatch('url/registerMapping', { - url: category.url_path, - routeData: { - params: { - 'slug': category.slug + if ( + skipCache || + (!context.state.list || + context.state.list.length === 0 || + customizedQuery) + ) { + return quickSearchByQuery({ + entityType: 'category', + query: searchQuery, + sort: sort, + size: size, + start: start, + includeFields: includeFields, + excludeFields: excludeFields + }).then(resp => { + for (let category of resp.items) { + if (category.url_path && updateState) { + rootStore.dispatch( + 'url/registerMapping', + { + url: category.url_path, + routeData: { + params: { + slug: category.slug + }, + name: 'category' + } }, - 'name': 'category' - } - }, { root: true }) + { root: true } + ); + } } - } - if (updateState) { - commit(types.CATEGORY_UPD_CATEGORIES, Object.assign(resp, { includeFields, excludeFields })) - Vue.prototype.$bus.$emit('category-after-list', { query: searchQuery, sort: sort, size: size, start: start, list: resp }) - } - return resp - }) + if (updateState) { + commit( + types.CATEGORY_UPD_CATEGORIES, + Object.assign(resp, { includeFields, excludeFields }) + ); + Vue.prototype.$bus.$emit('category-after-list', { + query: searchQuery, + sort: sort, + size: size, + start: start, + list: resp + }); + } + return resp; + }); } else { return new Promise((resolve, reject) => { - let resp = { items: context.state.list, total: context.state.list.length } + let resp = { + items: context.state.list, + total: context.state.list.length + }; if (updateState) { - Vue.prototype.$bus.$emit('category-after-list', { query: searchQuery, sort: sort, size: size, start: start, list: resp }) + Vue.prototype.$bus.$emit('category-after-list', { + query: searchQuery, + sort: sort, + size: size, + start: start, + list: resp + }); } - resolve(resp) - }) + resolve(resp); + }); } }, @@ -104,106 +183,187 @@ const actions: ActionTree = { * @param {String} value * @param {Bool} setCurrentCategory default=true and means that state.current_category is set to the one loaded */ - single (context, { key, value, setCurrentCategory = true, setCurrentCategoryPath = true, populateRequestCacheTags = true, skipCache = false }) { - const state = context.state - const commit = context.commit - const dispatch = context.dispatch + single( + context, + { + key, + value, + setCurrentCategory = true, + setCurrentCategoryPath = true, + populateRequestCacheTags = true, + skipCache = false + } + ) { + const state = context.state; + const commit = context.commit; + const dispatch = context.dispatch; return new Promise((resolve, reject) => { const fetchCat = ({ key, value }) => { - if (key !== 'id' || value >= rootStore.state.config.entities.category.categoriesRootCategorylId/* root category */) { - context.dispatch('list', { key: key, value: value }).then(res => { - if (res && res.items && res.items.length) { - setcat(null, res.items[0]) - } else { - reject(new Error('Category query returned empty result ' + key + ' = ' + value)) - } - }).catch(reject) + if ( + key !== 'id' || + value >= + rootStore.state.config.entities.category + .categoriesRootCategorylId /* root category */ + ) { + context + .dispatch('list', { key: key, value: value }) + .then(res => { + if (res && res.items && res.items.length) { + setcat(null, res.items[0]); + } else { + reject( + new Error( + 'Category query returned empty result ' + + key + + ' = ' + + value + ) + ); + } + }) + .catch(reject); } else { - reject(new Error('Category query returned empty result ' + key + ' = ' + value)) - return + reject( + new Error( + 'Category query returned empty result ' + key + ' = ' + value + ) + ); + return; } - } + }; let setcat = (error, mainCategory) => { - if (!mainCategory) { - fetchCat({ key, value }) - return + fetchCat({ key, value }); + return; } if (error) { - Logger.error(error)() - reject(error) + Logger.error(error)(); + reject(error); } if (setCurrentCategory) { - commit(types.CATEGORY_UPD_CURRENT_CATEGORY, mainCategory) + commit(types.CATEGORY_UPD_CURRENT_CATEGORY, mainCategory); } - if (populateRequestCacheTags && mainCategory && Vue.prototype.$ssrRequestContext) { - Vue.prototype.$ssrRequestContext.output.cacheTags.add(`C${mainCategory.id}`) + if ( + populateRequestCacheTags && + mainCategory && + Vue.prototype.$ssrRequestContext + ) { + Vue.prototype.$ssrRequestContext.output.cacheTags.add( + `C${mainCategory.id}` + ); } if (setCurrentCategoryPath) { - let currentPath = [] - let recurCatFinder = (category) => { + let currentPath = []; + let recurCatFinder = category => { if (!category) { - return + return; } - if (category.parent_id >= rootStore.state.config.entities.category.categoriesRootCategorylId) { - dispatch('single', { key: 'id', value: category.parent_id, setCurrentCategory: false, setCurrentCategoryPath: false }).then((sc) => { // TODO: move it to the server side for one requests OR cache in indexedDb - if (!sc) { - commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, currentPath) - Vue.prototype.$bus.$emit('category-after-single', { category: mainCategory }) - return resolve(mainCategory) - } - currentPath.unshift(sc) - if (sc.parent_id) { - recurCatFinder(sc) - } - }).catch(err => { - Logger.error(err)() - commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, currentPath) // this is the case when category is not binded to the root tree - for example 'Erin Recommends' - resolve(mainCategory) + if ( + category.parent_id >= + rootStore.state.config.entities.category.categoriesRootCategorylId + ) { + dispatch('single', { + key: 'id', + value: category.parent_id, + setCurrentCategory: false, + setCurrentCategoryPath: false }) + .then(sc => { + // TODO: move it to the server side for one requests OR cache in indexedDb + if (!sc) { + commit( + types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, + currentPath + ); + Vue.prototype.$bus.$emit('category-after-single', { + category: mainCategory + }); + return resolve(mainCategory); + } + currentPath.unshift(sc); + if (sc.parent_id) { + recurCatFinder(sc); + } + }) + .catch(err => { + Logger.error(err)(); + commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, currentPath); // this is the case when category is not binded to the root tree - for example 'Erin Recommends' + resolve(mainCategory); + }); } else { - commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, currentPath) - Vue.prototype.$bus.$emit('category-after-single', { category: mainCategory }) - resolve(mainCategory) + commit(types.CATEGORY_UPD_CURRENT_CATEGORY_PATH, currentPath); + Vue.prototype.$bus.$emit('category-after-single', { + category: mainCategory + }); + resolve(mainCategory); } - } + }; if (typeof mainCategory !== 'undefined') { - recurCatFinder(mainCategory) // TODO: Store breadcrumbs in IndexedDb for further usage to optimize speed? + recurCatFinder(mainCategory); // TODO: Store breadcrumbs in IndexedDb for further usage to optimize speed? } else { - reject(new Error('Category query returned empty result ' + key + ' = ' + value)) + reject( + new Error( + 'Category query returned empty result ' + key + ' = ' + value + ) + ); } } else { - Vue.prototype.$bus.$emit('category-after-single', { category: mainCategory }) - resolve(mainCategory) + Vue.prototype.$bus.$emit('category-after-single', { + category: mainCategory + }); + resolve(mainCategory); } - } + }; - let foundInLocalCache = false - if (state.list.length > 0 && !skipCache) { // SSR - there were some issues with using localForage, so it's the reason to use local state instead, when possible - let category = state.list.find((itm) => { return itm[key] === value }) + let foundInLocalCache = false; + if (state.list.length > 0 && !skipCache) { + // SSR - there were some issues with using localForage, so it's the reason to use local state instead, when possible + let category = state.list.find(itm => { + return itm[key] === value; + }); // Check if category exists in the store OR we have recursively reached Default category (id=1) - if (category && value >= rootStore.state.config.entities.category.categoriesRootCategorylId/** root category parent */) { - foundInLocalCache = true - setcat(null, category) + if ( + category && + value >= + rootStore.state.config.entities.category + .categoriesRootCategorylId /** root category parent */ + ) { + foundInLocalCache = true; + setcat(null, category); } } if (!foundInLocalCache) { if (skipCache || isServer) { - fetchCat({ key, value }) + fetchCat({ key, value }); } else { - const catCollection = Vue.prototype.$db.categoriesCollection + const catCollection = Vue.prototype.$db.categoriesCollection; // Check if category does not exist in the store AND we haven't recursively reached Default category (id=1) - catCollection.getItem(entityKeyName(key, value), setcat) + catCollection.getItem(entityKeyName(key, value), setcat); } } - }) + }); }, /** * Filter category products */ - products (context, { populateAggregations = false, filters = [], searchProductQuery, current = 0, perPage = 50, sort = '', includeFields = null, excludeFields = null, configuration = null, append = false, skipCache = false }) { + products( + context, + { + populateAggregations = false, + filters = [], + searchProductQuery, + current = 0, + perPage = 50, + sort = '', + includeFields = null, + excludeFields = null, + configuration = null, + append = false, + skipCache = false + } + ) { context.dispatch('setSearchOptions', { populateAggregations, filters, @@ -214,176 +374,264 @@ const actions: ActionTree = { configuration, append, sort - }) + }); - let prefetchGroupProducts = true - if (rootStore.state.config.entities.twoStageCaching && rootStore.state.config.entities.optimize && !isServer && !rootStore.state.twoStageCachingDisabled) { // only client side, only when two stage caching enabled - includeFields = rootStore.state.config.entities.productListWithChildren.includeFields // we need configurable_children for filters to work - excludeFields = rootStore.state.config.entities.productListWithChildren.excludeFields - prefetchGroupProducts = false - Logger.log('Using two stage caching for performance optimization - executing first stage product pre-fetching')() + let prefetchGroupProducts = true; + if ( + rootStore.state.config.entities.twoStageCaching && + rootStore.state.config.entities.optimize && + !isServer && + !rootStore.state.twoStageCachingDisabled + ) { + // only client side, only when two stage caching enabled + includeFields = + rootStore.state.config.entities.productListWithChildren.includeFields; // we need configurable_children for filters to work + excludeFields = + rootStore.state.config.entities.productListWithChildren.excludeFields; + prefetchGroupProducts = false; + Logger.log( + 'Using two stage caching for performance optimization - executing first stage product pre-fetching' + )(); } else { - prefetchGroupProducts = true + prefetchGroupProducts = true; if (rootStore.state.twoStageCachingDisabled) { - Logger.log('Two stage caching is disabled runtime because of no performance gain')() + Logger.log( + 'Two stage caching is disabled runtime because of no performance gain' + )(); } else { - Logger.log('Two stage caching is disabled by the config')() + Logger.log('Two stage caching is disabled by the config')(); } } - let t0 = new Date().getTime() + let t0 = new Date().getTime(); - const precachedQuery = searchProductQuery - let productPromise = rootStore.dispatch('product/list', { - query: precachedQuery, - start: current, - size: perPage, - excludeFields: excludeFields, - includeFields: includeFields, - configuration: configuration, - append: append, - sort: sort, - updateState: true, - prefetchGroupProducts: prefetchGroupProducts - }).then((res) => { - let t1 = new Date().getTime() - rootStore.state.twoStageCachingDelta1 = t1 - t0 + const precachedQuery = searchProductQuery; + let productPromise = rootStore + .dispatch('product/list', { + query: precachedQuery, + start: current, + size: perPage, + excludeFields: excludeFields, + includeFields: includeFields, + configuration: configuration, + append: append, + sort: sort, + updateState: true, + prefetchGroupProducts: prefetchGroupProducts + }) + .then(res => { + let t1 = new Date().getTime(); + rootStore.state.twoStageCachingDelta1 = t1 - t0; - let subloaders = [] - if (!res || (res.noresults)) { - rootStore.dispatch('notification/spawnNotification', { - type: 'warning', - message: i18n.t('No products synchronized for this category. Please come back while online!'), - action1: { label: i18n.t('OK') } - }) - if (!append) rootStore.dispatch('product/reset') - rootStore.state.product.list = { items: [] } // no products to show TODO: refactor to rootStore.state.category.reset() and rootStore.state.product.reset() - // rootStore.state.category.filters = { color: [], size: [], price: [] } - return [] - } else { - if (rootStore.state.config.products.filterUnavailableVariants && rootStore.state.config.products.configurableChildrenStockPrefetchStatic) { // prefetch the stock items - const skus = [] - let prefetchIndex = 0 - res.items.map(i => { - if (rootStore.state.config.products.configurableChildrenStockPrefetchStaticPrefetchCount > 0) { - if (prefetchIndex > rootStore.state.config.products.configurableChildrenStockPrefetchStaticPrefetchCount) return - } - skus.push(i.sku) // main product sku to be checked anyway - if (i.type_id === 'configurable' && i.configurable_children && i.configurable_children.length > 0) { - for (const confChild of i.configurable_children) { - const cachedItem = context.rootState.stock.cache[confChild.id] - if (typeof cachedItem === 'undefined' || cachedItem === null) { - skus.push(confChild.sku) + let subloaders = []; + if (!res || res.noresults) { + rootStore.dispatch('notification/spawnNotification', { + type: 'warning', + message: i18n.t( + 'No products synchronized for this category. Please come back while online!' + ), + action1: { label: i18n.t('OK') } + }); + if (!append) rootStore.dispatch('product/reset'); + rootStore.state.product.list = { items: [] }; // no products to show TODO: refactor to rootStore.state.category.reset() and rootStore.state.product.reset() + // rootStore.state.category.filters = { color: [], size: [], price: [] } + return []; + } else { + if ( + rootStore.state.config.products.filterUnavailableVariants && + rootStore.state.config.products + .configurableChildrenStockPrefetchStatic + ) { + // prefetch the stock items + const skus = []; + let prefetchIndex = 0; + res.items.map(i => { + if ( + rootStore.state.config.products + .configurableChildrenStockPrefetchStaticPrefetchCount > 0 + ) { + if ( + prefetchIndex > + rootStore.state.config.products + .configurableChildrenStockPrefetchStaticPrefetchCount + ) + return; + } + skus.push(i.sku); // main product sku to be checked anyway + if ( + i.type_id === 'configurable' && + i.configurable_children && + i.configurable_children.length > 0 + ) { + for (const confChild of i.configurable_children) { + const cachedItem = + context.rootState.stock.cache[confChild.id]; + if ( + typeof cachedItem === 'undefined' || + cachedItem === null + ) { + skus.push(confChild.sku); + } } + prefetchIndex++; } - prefetchIndex++ + }); + for (const chunkItem of chunk(skus, 15)) { + rootStore.dispatch('stock/list', { skus: chunkItem, skipCache }); // store it in the cache } - }) - for (const chunkItem of chunk(skus, 15)) { - rootStore.dispatch('stock/list', { skus: chunkItem, skipCache }) // store it in the cache } - } - if (populateAggregations === true && res.aggregations) { // populate filter aggregates - for (let attrToFilter of filters) { // fill out the filter options - let filterOptions = [] + if (populateAggregations === true && res.aggregations) { + // populate filter aggregates + for (let attrToFilter of filters) { + // fill out the filter options + let filterOptions = []; - let uniqueFilterValues = new Set() - if (attrToFilter !== 'price') { - if (res.aggregations['agg_terms_' + attrToFilter]) { - let buckets = res.aggregations['agg_terms_' + attrToFilter].buckets - if (res.aggregations['agg_terms_' + attrToFilter + '_options']) { - buckets = buckets.concat(res.aggregations['agg_terms_' + attrToFilter + '_options'].buckets) - } + let uniqueFilterValues = new Set(); + if (attrToFilter !== 'price') { + if (res.aggregations['agg_terms_' + attrToFilter]) { + let buckets = + res.aggregations['agg_terms_' + attrToFilter].buckets; + if ( + res.aggregations['agg_terms_' + attrToFilter + '_options'] + ) { + buckets = buckets.concat( + res.aggregations['agg_terms_' + attrToFilter + '_options'] + .buckets + ); + } - for (let option of buckets) { - uniqueFilterValues.add(toString(option.key)) + for (let option of buckets) { + uniqueFilterValues.add(toString(option.key)); + } } - } - uniqueFilterValues.forEach(key => { - const label = optionLabel(rootStore.state.attribute, { attributeKey: attrToFilter, optionId: key }) - if (trim(label) !== '') { // is there any situation when label could be empty and we should still support it? - filterOptions.push({ - id: key, - label: label - }) - } - }); - } else { // special case is range filter for prices - const storeView = currentStoreView() - const currencySign = storeView.i18n.currencySign - if (res.aggregations['agg_range_' + attrToFilter]) { - let index = 0 - let count = res.aggregations['agg_range_' + attrToFilter].buckets.length - for (let option of res.aggregations['agg_range_' + attrToFilter].buckets) { - filterOptions.push({ - id: option.key, - from: option.from, - to: option.to, - label: (index === 0 || (index === count - 1)) ? (option.to ? '< ' + currencySign + option.to : '> ' + currencySign + option.from) : currencySign + option.from + (option.to ? ' - ' + option.to : '')// TODO: add better way for formatting, extract currency sign - }) - index++ + uniqueFilterValues.forEach(key => { + const label = optionLabel(rootStore.state.attribute, { + attributeKey: attrToFilter, + optionId: key + }); + if (trim(label) !== '') { + // is there any situation when label could be empty and we should still support it? + filterOptions.push({ + id: key, + label: label + }); + } + }); + } else { + // special case is range filter for prices + const storeView = currentStoreView(); + const currencySign = storeView.i18n.currencySign; + if (res.aggregations['agg_range_' + attrToFilter]) { + let index = 0; + let count = + res.aggregations['agg_range_' + attrToFilter].buckets + .length; + for (let option of res.aggregations[ + 'agg_range_' + attrToFilter + ].buckets) { + filterOptions.push({ + id: option.key, + from: option.from, + to: option.to, + label: + index === 0 || index === count - 1 + ? option.to + ? '< ' + currencySign + option.to + : '> ' + currencySign + option.from + : currencySign + + option.from + + (option.to ? ' - ' + option.to : '') // TODO: add better way for formatting, extract currency sign + }); + index++; + } } } + context.dispatch('addAvailableFilter', { + key: attrToFilter, + options: filterOptions + }); } - context.dispatch('addAvailableFilter', { - key: attrToFilter, - options: filterOptions - }) } } - } - return subloaders - }).catch((err) => { - Logger.error(err)() - rootStore.dispatch('notification/spawnNotification', { - type: 'warning', - message: i18n.t('No products synchronized for this category. Please come back while online!'), - action1: { label: i18n.t('OK') } + return subloaders; }) - }) + .catch(err => { + Logger.error(err)(); + rootStore.dispatch('notification/spawnNotification', { + type: 'warning', + message: i18n.t( + 'No products synchronized for this category. Please come back while online!' + ), + action1: { label: i18n.t('OK') } + }); + }); - if (rootStore.state.config.entities.twoStageCaching && rootStore.state.config.entities.optimize && !isServer && !rootStore.state.twoStageCachingDisabled) { // second stage - request for caching entities - Logger.log('Using two stage caching for performance optimization - executing second stage product caching', 'category') // TODO: in this case we can pre-fetch products in advance getting more products than set by pageSize() - rootStore.dispatch('product/list', { - query: precachedQuery, - start: current, - size: perPage, - excludeFields: null, - includeFields: null, - configuration: configuration, - sort: sort, - updateState: false, // not update the product listing - this request is only for caching - prefetchGroupProducts: prefetchGroupProducts - }).catch((err) => { - Logger.info("Problem with second stage caching - couldn't store the data", 'category')() - Logger.info(err, 'category')() - }).then((res) => { - let t2 = new Date().getTime() - rootStore.state.twoStageCachingDelta2 = t2 - t0 - Logger.log('Using two stage caching for performance optimization - Time comparison stage1 vs stage2' + rootStore.state.twoStageCachingDelta1 + rootStore.state.twoStageCachingDelta2, 'category')() - if (rootStore.state.twoStageCachingDelta1 > rootStore.state.twoStageCachingDelta2) { // two stage caching is not making any good - rootStore.state.twoStageCachingDisabled = true - Logger.log('Disabling two stage caching', 'category')() - } - }) + if ( + rootStore.state.config.entities.twoStageCaching && + rootStore.state.config.entities.optimize && + !isServer && + !rootStore.state.twoStageCachingDisabled + ) { + // second stage - request for caching entities + Logger.log( + 'Using two stage caching for performance optimization - executing second stage product caching', + 'category' + ); // TODO: in this case we can pre-fetch products in advance getting more products than set by pageSize() + rootStore + .dispatch('product/list', { + query: precachedQuery, + start: current, + size: perPage, + excludeFields: null, + includeFields: null, + configuration: configuration, + sort: sort, + updateState: false, // not update the product listing - this request is only for caching + prefetchGroupProducts: prefetchGroupProducts + }) + .catch(err => { + Logger.info( + "Problem with second stage caching - couldn't store the data", + 'category' + )(); + Logger.info(err, 'category')(); + }) + .then(res => { + let t2 = new Date().getTime(); + rootStore.state.twoStageCachingDelta2 = t2 - t0; + Logger.log( + 'Using two stage caching for performance optimization - Time comparison stage1 vs stage2' + + rootStore.state.twoStageCachingDelta1 + + rootStore.state.twoStageCachingDelta2, + 'category' + )(); + if ( + rootStore.state.twoStageCachingDelta1 > + rootStore.state.twoStageCachingDelta2 + ) { + // two stage caching is not making any good + rootStore.state.twoStageCachingDisabled = true; + Logger.log('Disabling two stage caching', 'category')(); + } + }); } - return productPromise + return productPromise; }, - addAvailableFilter ({commit}, {key, options} = {}) { - if(key) commit(types.CATEGORY_ADD_AVAILABLE_FILTER, {key, options}) + addAvailableFilter({ commit }, { key, options } = {}) { + if (key) commit(types.CATEGORY_ADD_AVAILABLE_FILTER, { key, options }); }, - resetFilters (context) { - context.commit(types.CATEGORY_REMOVE_FILTERS) + resetFilters(context) { + context.commit(types.CATEGORY_REMOVE_FILTERS); }, - searchProductQuery (context, productQuery) { - context.commit(types.CATEGORY_UPD_SEARCH_PRODUCT_QUERY, productQuery) + searchProductQuery(context, productQuery) { + context.commit(types.CATEGORY_UPD_SEARCH_PRODUCT_QUERY, productQuery); }, - setSearchOptions ({commit}, searchOptions) { - commit(types.CATEGORY_SET_SEARCH_OPTIONS, searchOptions) + setSearchOptions({ commit }, searchOptions) { + commit(types.CATEGORY_SET_SEARCH_OPTIONS, searchOptions); }, - mergeSearchOptions ({commit}, searchOptions) { - commit(types.CATEGORY_MERGE_SEARCH_OPTIONS, searchOptions) + mergeSearchOptions({ commit }, searchOptions) { + commit(types.CATEGORY_MERGE_SEARCH_OPTIONS, searchOptions); } -} +}; -export default actions +export default actions; diff --git a/core/modules/catalog/store/category/getters.ts b/core/modules/catalog/store/category/getters.ts index df3c5e2929..60c67e8219 100644 --- a/core/modules/catalog/store/category/getters.ts +++ b/core/modules/catalog/store/category/getters.ts @@ -1,6 +1,6 @@ -import { GetterTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import CategoryState from '../../types/CategoryState' +import { GetterTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import CategoryState from '../../types/CategoryState'; const getters: GetterTree = { getCurrentCategory: state => state.current, @@ -19,6 +19,6 @@ const getters: GetterTree = { * @deprecated use getCategories instead */ list: (state, getters) => getters.getCategories -} +}; -export default getters +export default getters; diff --git a/core/modules/catalog/store/category/index.ts b/core/modules/catalog/store/category/index.ts index 5030f514cd..69a4fa6ea7 100644 --- a/core/modules/catalog/store/category/index.ts +++ b/core/modules/catalog/store/category/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import CategoryState from '../../types/CategoryState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import CategoryState from '../../types/CategoryState'; export const categoryModule: Module = { namespaced: true, @@ -23,4 +23,4 @@ export const categoryModule: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/catalog/store/category/mutation-types.ts b/core/modules/catalog/store/category/mutation-types.ts index c6bf9e8411..98954de8e0 100644 --- a/core/modules/catalog/store/category/mutation-types.ts +++ b/core/modules/catalog/store/category/mutation-types.ts @@ -1,9 +1,12 @@ -export const SN_CATEGORY = 'category' -export const CATEGORY_UPD_CATEGORIES = SN_CATEGORY + '/UPD_CATEGORIES' -export const CATEGORY_UPD_CURRENT_CATEGORY = SN_CATEGORY + '/UPD_CURRENT_CATEGORY' -export const CATEGORY_UPD_CURRENT_CATEGORY_PATH = SN_CATEGORY + '/UPD_CURRENT_CATEGORY_PATH' -export const CATEGORY_UPD_SEARCH_PRODUCT_QUERY = SN_CATEGORY + '/UPD_SEARCH_PRODUCT_QUERY' -export const CATEGORY_ADD_AVAILABLE_FILTER = `${SN_CATEGORY}/ADD_AVAILABLE_FILTER` -export const CATEGORY_REMOVE_FILTERS = SN_CATEGORY + '/REMOVE_FILTERS' -export const CATEGORY_SET_SEARCH_OPTIONS = `${SN_CATEGORY}/SET_SEARCH_OPTIONS` -export const CATEGORY_MERGE_SEARCH_OPTIONS = `${SN_CATEGORY}/MERGE_SEARCH_OPTIONS` \ No newline at end of file +export const SN_CATEGORY = 'category'; +export const CATEGORY_UPD_CATEGORIES = SN_CATEGORY + '/UPD_CATEGORIES'; +export const CATEGORY_UPD_CURRENT_CATEGORY = + SN_CATEGORY + '/UPD_CURRENT_CATEGORY'; +export const CATEGORY_UPD_CURRENT_CATEGORY_PATH = + SN_CATEGORY + '/UPD_CURRENT_CATEGORY_PATH'; +export const CATEGORY_UPD_SEARCH_PRODUCT_QUERY = + SN_CATEGORY + '/UPD_SEARCH_PRODUCT_QUERY'; +export const CATEGORY_ADD_AVAILABLE_FILTER = `${SN_CATEGORY}/ADD_AVAILABLE_FILTER`; +export const CATEGORY_REMOVE_FILTERS = SN_CATEGORY + '/REMOVE_FILTERS'; +export const CATEGORY_SET_SEARCH_OPTIONS = `${SN_CATEGORY}/SET_SEARCH_OPTIONS`; +export const CATEGORY_MERGE_SEARCH_OPTIONS = `${SN_CATEGORY}/MERGE_SEARCH_OPTIONS`; diff --git a/core/modules/catalog/store/category/mutations.ts b/core/modules/catalog/store/category/mutations.ts index e1e4fb63cf..af63ffc736 100644 --- a/core/modules/catalog/store/category/mutations.ts +++ b/core/modules/catalog/store/category/mutations.ts @@ -1,75 +1,92 @@ -import Vue from 'vue' -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import { slugify, formatBreadCrumbRoutes } from '@vue-storefront/core/helpers' -import { entityKeyName } from '@vue-storefront/core/store/lib/entities' -import CategoryState from '../../types/CategoryState' -import rootStore from '@vue-storefront/core/store' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import { slugify, formatBreadCrumbRoutes } from '@vue-storefront/core/helpers'; +import { entityKeyName } from '@vue-storefront/core/store/lib/entities'; +import CategoryState from '../../types/CategoryState'; +import rootStore from '@vue-storefront/core/store'; +import { Logger } from '@vue-storefront/core/lib/logger'; const mutations: MutationTree = { - [types.CATEGORY_UPD_CURRENT_CATEGORY] (state, category) { - state.current = category - Vue.prototype.$bus.$emit('category-after-current', { category: category }) + [types.CATEGORY_UPD_CURRENT_CATEGORY](state, category) { + state.current = category; + Vue.prototype.$bus.$emit('category-after-current', { category: category }); }, - [types.CATEGORY_UPD_CURRENT_CATEGORY_PATH] (state, path) { - state.current_path = path // TODO: store to cache - state.breadcrumbs.routes = formatBreadCrumbRoutes(state.current_path) + [types.CATEGORY_UPD_CURRENT_CATEGORY_PATH](state, path) { + state.current_path = path; // TODO: store to cache + state.breadcrumbs.routes = formatBreadCrumbRoutes(state.current_path); }, - [types.CATEGORY_UPD_CATEGORIES] (state, categories) { + [types.CATEGORY_UPD_CATEGORIES](state, categories) { for (let category of categories.items) { - let catSlugSetter = (category) => { + let catSlugSetter = category => { if (category.children_data) { - for (let subcat of category.children_data) { // TODO: fixme and move slug setting to vue-storefront-api + for (let subcat of category.children_data) { + // TODO: fixme and move slug setting to vue-storefront-api if (subcat.name) { - subcat = Object.assign(subcat, { slug: subcat.slug ? subcat.slug : ((subcat.hasOwnProperty('url_key') && rootStore.state.config.products.useMagentoUrlKeys) ? subcat.url_key : (subcat.hasOwnProperty('name') ? slugify(subcat.name) + '-' + subcat.id : '')) }) - catSlugSetter(subcat) + subcat = Object.assign(subcat, { + slug: subcat.slug + ? subcat.slug + : subcat.hasOwnProperty('url_key') && + rootStore.state.config.products.useMagentoUrlKeys + ? subcat.url_key + : subcat.hasOwnProperty('name') + ? slugify(subcat.name) + '-' + subcat.id + : '' + }); + catSlugSetter(subcat); } } } - } - catSlugSetter(category) + }; + catSlugSetter(category); if (categories.includeFields == null) { - const catCollection = Vue.prototype.$db.categoriesCollection + const catCollection = Vue.prototype.$db.categoriesCollection; try { - catCollection.setItem(entityKeyName('slug', category.slug.toLowerCase()), category).catch((reason) => { - Logger.error(reason, 'category') // it doesn't work on SSR - }) // populate cache by slug - catCollection.setItem(entityKeyName('id', category.id), category).catch((reason) => { - Logger.error(reason, 'category') // it doesn't work on SSR - }) // populate cache by id + catCollection + .setItem( + entityKeyName('slug', category.slug.toLowerCase()), + category + ) + .catch(reason => { + Logger.error(reason, 'category'); // it doesn't work on SSR + }); // populate cache by slug + catCollection + .setItem(entityKeyName('id', category.id), category) + .catch(reason => { + Logger.error(reason, 'category'); // it doesn't work on SSR + }); // populate cache by id } catch (e) { - Logger.error(e, 'category')() + Logger.error(e, 'category')(); } } } if (state.list) { categories.items.map(newCat => { if (!state.list.find(existingCat => existingCat.id == newCat.id)) { - state.list.push(newCat) + state.list.push(newCat); } - }) + }); } else { - state.list = categories.items + state.list = categories.items; } }, - [types.CATEGORY_ADD_AVAILABLE_FILTER] (state, {key, options = []}) { - Vue.set(state.filters.available, key, options) + [types.CATEGORY_ADD_AVAILABLE_FILTER](state, { key, options = [] }) { + Vue.set(state.filters.available, key, options); }, - [types.CATEGORY_REMOVE_FILTERS] (state) { - state.filters.chosen = {} - state.current_product_query.configuration = {} + [types.CATEGORY_REMOVE_FILTERS](state) { + state.filters.chosen = {}; + state.current_product_query.configuration = {}; }, - [types.CATEGORY_UPD_SEARCH_PRODUCT_QUERY] (state, newQuery) { - state.current_product_query = newQuery + [types.CATEGORY_UPD_SEARCH_PRODUCT_QUERY](state, newQuery) { + state.current_product_query = newQuery; }, - [types.CATEGORY_SET_SEARCH_OPTIONS] (state, searchOptions) { - state.current_product_query = searchOptions || null + [types.CATEGORY_SET_SEARCH_OPTIONS](state, searchOptions) { + state.current_product_query = searchOptions || null; }, - [types.CATEGORY_MERGE_SEARCH_OPTIONS] (state, searchOptions = {}) { - let currentOptions = state.current_product_query || {} - state.current_product_query = Object.assign(currentOptions, searchOptions) + [types.CATEGORY_MERGE_SEARCH_OPTIONS](state, searchOptions = {}) { + let currentOptions = state.current_product_query || {}; + state.current_product_query = Object.assign(currentOptions, searchOptions); } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/catalog/store/product/actions.ts b/core/modules/catalog/store/product/actions.ts index 497bb3b5d4..d7ccc6f415 100644 --- a/core/modules/catalog/store/product/actions.ts +++ b/core/modules/catalog/store/product/actions.ts @@ -1,9 +1,14 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import { formatBreadCrumbRoutes, productThumbnailPath, isServer } from '@vue-storefront/core/helpers' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { configureProductAsync, +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import { + formatBreadCrumbRoutes, + productThumbnailPath, + isServer +} from '@vue-storefront/core/helpers'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { + configureProductAsync, doPlatformPricesSync, filterOutUnavailableVariants, calculateTaxes, @@ -12,99 +17,141 @@ import { configureProductAsync, setBundleProductOptionsAsync, getMediaGallery, configurableChildrenImages, - attributeImages } from '../../helpers' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { entityKeyName } from '@vue-storefront/core/store/lib/entities' -import { optionLabel } from '../../helpers/optionLabel' -import { quickSearchByQuery, isOnline } from '@vue-storefront/core/lib/search' -import omit from 'lodash-es/omit' -import trim from 'lodash-es/trim' -import uniqBy from 'lodash-es/uniqBy' -import rootStore from '@vue-storefront/core/store' -import RootState from '@vue-storefront/core/types/RootState' -import ProductState from '../../types/ProductState' + attributeImages +} from '../../helpers'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { entityKeyName } from '@vue-storefront/core/store/lib/entities'; +import { optionLabel } from '../../helpers/optionLabel'; +import { quickSearchByQuery, isOnline } from '@vue-storefront/core/lib/search'; +import omit from 'lodash-es/omit'; +import trim from 'lodash-es/trim'; +import uniqBy from 'lodash-es/uniqBy'; +import rootStore from '@vue-storefront/core/store'; +import RootState from '@vue-storefront/core/types/RootState'; +import ProductState from '../../types/ProductState'; import { Logger } from '@vue-storefront/core/lib/logger'; -import { TaskQueue } from '@vue-storefront/core/lib/sync' -import toString from 'lodash-es/toString' +import { TaskQueue } from '@vue-storefront/core/lib/sync'; +import toString from 'lodash-es/toString'; -const PRODUCT_REENTER_TIMEOUT = 20000 +const PRODUCT_REENTER_TIMEOUT = 20000; const actions: ActionTree = { /** * Reset current configuration and selected variatnts */ - reset (context) { - const productOriginal = context.getters.productOriginal - context.commit(types.CATALOG_RESET_PRODUCT, productOriginal) + reset(context) { + const productOriginal = context.getters.productOriginal; + context.commit(types.CATALOG_RESET_PRODUCT, productOriginal); }, /** * Setup product breadcrumbs path */ - async setupBreadcrumbs (context, { product }) { - let breadcrumbsName = null - let setBreadcrumbRoutesFromPath = (path) => { - if (path.findIndex(itm => { - return itm.slug === context.rootGetters['category/getCurrentCategory'].slug - }) < 0) { + async setupBreadcrumbs(context, { product }) { + let breadcrumbsName = null; + let setBreadcrumbRoutesFromPath = path => { + if ( + path.findIndex(itm => { + return ( + itm.slug === context.rootGetters['category/getCurrentCategory'].slug + ); + }) < 0 + ) { path.push({ url_path: context.rootGetters['category/getCurrentCategory'].url_path, slug: context.rootGetters['category/getCurrentCategory'].slug, name: context.rootGetters['category/getCurrentCategory'].name - }) // current category at the end + }); // current category at the end } // deprecated, TODO: base on breadcrumbs module - breadcrumbsName = product.name + breadcrumbsName = product.name; const breadcrumbs = { routes: formatBreadCrumbRoutes(path), current: breadcrumbsName, name: breadcrumbsName - } - context.commit(types.CATALOG_SET_BREADCRUMBS, breadcrumbs) - } + }; + context.commit(types.CATALOG_SET_BREADCRUMBS, breadcrumbs); + }; if (product.category && product.category.length > 0) { - const categoryIds = product.category.reverse().map((cat => cat.category_id)) - await context.dispatch('category/list', { key: 'id', value: categoryIds }, { root: true }).then(async (categories) => { - const catList = [] + const categoryIds = product.category + .reverse() + .map(cat => cat.category_id); + await context + .dispatch( + 'category/list', + { key: 'id', value: categoryIds }, + { root: true } + ) + .then(async categories => { + const catList = []; for (let catId of categoryIds) { - let category = categories.items.find((itm) => { return toString(itm['id']) === toString(catId) }) + let category = categories.items.find(itm => { + return toString(itm['id']) === toString(catId); + }); if (category) { - catList.push(category) + catList.push(category); } } - const rootCat = catList.shift() - let catForBreadcrumbs = rootCat + const rootCat = catList.shift(); + let catForBreadcrumbs = rootCat; for (let cat of catList) { - const catPath = cat.path - if (catPath && catPath.includes(rootCat.path) && (catPath.split('/').length > catForBreadcrumbs.path.split('/').length)) { - catForBreadcrumbs = cat + const catPath = cat.path; + if ( + catPath && + catPath.includes(rootCat.path) && + catPath.split('/').length > + catForBreadcrumbs.path.split('/').length + ) { + catForBreadcrumbs = cat; } } if (typeof catForBreadcrumbs !== 'undefined') { - await context.dispatch('category/single', { key: 'id', value: catForBreadcrumbs.id }, { root: true }).then(() => { // this sets up category path and current category - setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) - }).catch(err => { - setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) - Logger.error(err)() - }) + await context + .dispatch( + 'category/single', + { key: 'id', value: catForBreadcrumbs.id }, + { root: true } + ) + .then(() => { + // this sets up category path and current category + setBreadcrumbRoutesFromPath( + context.rootGetters['category/getCurrentCategoryPath'] + ); + }) + .catch(err => { + setBreadcrumbRoutesFromPath( + context.rootGetters['category/getCurrentCategoryPath'] + ); + Logger.error(err)(); + }); } else { - setBreadcrumbRoutesFromPath(context.rootGetters['category/getCurrentCategoryPath']) + setBreadcrumbRoutesFromPath( + context.rootGetters['category/getCurrentCategoryPath'] + ); } - }) + }); } }, - doPlatformPricesSync (context, { products }) { - return doPlatformPricesSync(products) + doPlatformPricesSync(context, { products }) { + return doPlatformPricesSync(products); }, /** * Download Magento2 / other platform prices to put them over ElasticSearch prices */ - syncPlatformPricesOver (context, { skus }) { - const storeView = currentStoreView() - return TaskQueue.execute({ url: rootStore.state.config.products.endpoint + '/render-list?skus=' + encodeURIComponent(skus.join(',')) + '¤cyCode=' + encodeURIComponent(storeView.i18n.currencyCode) + '&storeId=' + encodeURIComponent(storeView.storeId), // sync the cart + syncPlatformPricesOver(context, { skus }) { + const storeView = currentStoreView(); + return TaskQueue.execute({ + url: + rootStore.state.config.products.endpoint + + '/render-list?skus=' + + encodeURIComponent(skus.join(',')) + + '¤cyCode=' + + encodeURIComponent(storeView.i18n.currencyCode) + + '&storeId=' + + encodeURIComponent(storeView.storeId), // sync the cart payload: { method: 'GET', headers: { 'Content-Type': 'application/json' }, @@ -112,158 +159,232 @@ const actions: ActionTree = { }, callback_event: 'prices-after-sync' }).then((task: any) => { - return task.result - }) + return task.result; + }); }, /** * Setup associated products */ - setupAssociated (context, { product, skipCache = true }) { - let subloaders = [] + setupAssociated(context, { product, skipCache = true }) { + let subloaders = []; if (product.type_id === 'grouped') { - product.price = 0 - product.priceInclTax = 0 - Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)() + product.price = 0; + product.priceInclTax = 0; + Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)(); if (product.product_links && product.product_links.length > 0) { for (let pl of product.product_links) { - if (pl.link_type === 'associated' && pl.linked_product_type === 'simple') { // prefetch links - Logger.debug('Prefetching grouped product link for ' + pl.sku + ' = ' + pl.linked_product_sku)() - subloaders.push(context.dispatch('single', { - options: { sku: pl.linked_product_sku }, - setCurrentProduct: false, - selectDefaultVariant: false, - skipCache: skipCache - }).catch(err => { Logger.error(err) }).then((asocProd) => { - if (asocProd) { - pl.product = asocProd - pl.product.qty = 1 - product.price += pl.product.price - product.priceInclTax += pl.product.priceInclTax - product.tax += pl.product.tax - } else { - Logger.error('Product link not found', pl.linked_product_sku)() - } - })) + if ( + pl.link_type === 'associated' && + pl.linked_product_type === 'simple' + ) { + // prefetch links + Logger.debug( + 'Prefetching grouped product link for ' + + pl.sku + + ' = ' + + pl.linked_product_sku + )(); + subloaders.push( + context + .dispatch('single', { + options: { sku: pl.linked_product_sku }, + setCurrentProduct: false, + selectDefaultVariant: false, + skipCache: skipCache + }) + .catch(err => { + Logger.error(err); + }) + .then(asocProd => { + if (asocProd) { + pl.product = asocProd; + pl.product.qty = 1; + product.price += pl.product.price; + product.priceInclTax += pl.product.priceInclTax; + product.tax += pl.product.tax; + } else { + Logger.error( + 'Product link not found', + pl.linked_product_sku + )(); + } + }) + ); } } } else { - Logger.error('Product with type grouped has no product_links set!', product)() + Logger.error( + 'Product with type grouped has no product_links set!', + product + )(); } } if (product.type_id === 'bundle') { - product.price = 0 - product.priceInclTax = 0 - Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)() + product.price = 0; + product.priceInclTax = 0; + Logger.debug(product.name + ' SETUP ASSOCIATED', product.type_id)(); if (product.bundle_options && product.bundle_options.length > 0) { for (let bo of product.bundle_options) { - let defaultOption = bo.product_links.find((p) => { return p.is_default }) - if (!defaultOption) defaultOption = bo.product_links[0] + let defaultOption = bo.product_links.find(p => { + return p.is_default; + }); + if (!defaultOption) defaultOption = bo.product_links[0]; for (let pl of bo.product_links) { - Logger.debug('Prefetching bundle product link for ' + bo.sku + ' = ' + pl.sku)() - subloaders.push(context.dispatch('single', { - options: { sku: pl.sku }, - setCurrentProduct: false, - selectDefaultVariant: false, - skipCache: skipCache - }).catch(err => { Logger.error(err) }).then((asocProd) => { - if (asocProd) { - pl.product = asocProd - pl.product.qty = pl.qty - - if (pl.id === defaultOption.id) { - product.price += pl.product.price * pl.product.qty - product.priceInclTax += pl.product.priceInclTax * pl.product.qty - product.tax += pl.product.tax * pl.product.qty - } - } else { - Logger.error('Product link not found', pl.sku)() - } - })) + Logger.debug( + 'Prefetching bundle product link for ' + bo.sku + ' = ' + pl.sku + )(); + subloaders.push( + context + .dispatch('single', { + options: { sku: pl.sku }, + setCurrentProduct: false, + selectDefaultVariant: false, + skipCache: skipCache + }) + .catch(err => { + Logger.error(err); + }) + .then(asocProd => { + if (asocProd) { + pl.product = asocProd; + pl.product.qty = pl.qty; + + if (pl.id === defaultOption.id) { + product.price += pl.product.price * pl.product.qty; + product.priceInclTax += + pl.product.priceInclTax * pl.product.qty; + product.tax += pl.product.tax * pl.product.qty; + } + } else { + Logger.error('Product link not found', pl.sku)(); + } + }) + ); } } } } - return Promise.all(subloaders) + return Promise.all(subloaders); }, /** * This is fix for https://github.com/DivanteLtd/vue-storefront/issues/508 * TODO: probably it would be better to have "parent_id" for simple products or to just ensure configurable variants are not visible in categories/search */ - checkConfigurableParent (context, {product}) { + checkConfigurableParent(context, { product }) { if (product.type_id === 'simple') { - Logger.log('Checking configurable parent')() + Logger.log('Checking configurable parent')(); - let searchQuery = new SearchQuery() - searchQuery = searchQuery.applyFilter({key: 'configurable_children.sku', value: {'eq': context.state.current.sku}}) + let searchQuery = new SearchQuery(); + searchQuery = searchQuery.applyFilter({ + key: 'configurable_children.sku', + value: { eq: context.state.current.sku } + }); - return context.dispatch('list', {query: searchQuery, start: 0, size: 1, updateState: false}).then((resp) => { - if (resp.items.length >= 1) { - const parentProduct = resp.items[0] - context.commit(types.CATALOG_SET_PRODUCT_PARENT, parentProduct) - } - }).catch((err) => { - Logger.error(err)() - }) + return context + .dispatch('list', { + query: searchQuery, + start: 0, + size: 1, + updateState: false + }) + .then(resp => { + if (resp.items.length >= 1) { + const parentProduct = resp.items[0]; + context.commit(types.CATALOG_SET_PRODUCT_PARENT, parentProduct); + } + }) + .catch(err => { + Logger.error(err)(); + }); } }, /** * Load required configurable attributes - * @param context + * @param context * @param product */ loadConfigurableAttributes(context, { product }) { - let attributeKey = 'attribute_id' + let attributeKey = 'attribute_id'; const configurableAttrKeys = product.configurable_options.map(opt => { if (opt.attribute_id) { - attributeKey = 'attribute_id' - return opt.attribute_id + attributeKey = 'attribute_id'; + return opt.attribute_id; } else { - attributeKey = 'attribute_code' - return opt.attribute_code + attributeKey = 'attribute_code'; + return opt.attribute_code; } - }) - return context.dispatch('attribute/list', { - filterValues: configurableAttrKeys, - filterField: attributeKey - }, { root: true }) + }); + return context.dispatch( + 'attribute/list', + { + filterValues: configurableAttrKeys, + filterField: attributeKey + }, + { root: true } + ); }, /** * Setup product current variants */ - setupVariants (context, { product }) { - let subloaders = [] - if (product.type_id === 'configurable' && product.hasOwnProperty('configurable_options')) { - - subloaders.push(context.dispatch('product/loadConfigurableAttributes', { product }, { root: true }).then((attributes) => { - context.state.current_options = { - } - for (let option of product.configurable_options) { - for (let ov of option.values) { - let lb = ov.label ? ov.label : optionLabel(context.rootState.attribute, { attributeKey: option.attribute_id, searchBy: 'id', optionId: ov.value_index }) - if (trim(lb) !== '') { - let optionKey = option.attribute_code ? option.attribute_code : option.label.toLowerCase() - if (!context.state.current_options[optionKey]) { - context.state.current_options[optionKey] = [] + setupVariants(context, { product }) { + let subloaders = []; + if ( + product.type_id === 'configurable' && + product.hasOwnProperty('configurable_options') + ) { + subloaders.push( + context + .dispatch( + 'product/loadConfigurableAttributes', + { product }, + { root: true } + ) + .then(attributes => { + context.state.current_options = {}; + for (let option of product.configurable_options) { + for (let ov of option.values) { + let lb = ov.label + ? ov.label + : optionLabel(context.rootState.attribute, { + attributeKey: option.attribute_id, + searchBy: 'id', + optionId: ov.value_index + }); + if (trim(lb) !== '') { + let optionKey = option.attribute_code + ? option.attribute_code + : option.label.toLowerCase(); + if (!context.state.current_options[optionKey]) { + context.state.current_options[optionKey] = []; + } + context.state.current_options[optionKey].push({ + label: lb, + id: ov.value_index, + attribute_code: option.attribute_code + }); + } } - context.state.current_options[optionKey].push({ - label: lb, - id: ov.value_index, - attribute_code: option.attribute_code - }) } - } - } - Vue.set(context.state, 'current_options', context.state.current_options) - let selectedVariant = context.state.current - populateProductConfigurationAsync(context, { selectedVariant: selectedVariant, product: product }) - }).catch(err => { - Logger.error(err)() - })) + Vue.set( + context.state, + 'current_options', + context.state.current_options + ); + let selectedVariant = context.state.current; + populateProductConfigurationAsync(context, { + selectedVariant: selectedVariant, + product: product + }); + }) + .catch(err => { + Logger.error(err)(); + }) + ); } - return Promise.all(subloaders) + return Promise.all(subloaders); }, - filterUnavailableVariants (context, { product }) { - return filterOutUnavailableVariants(context, product) + filterUnavailableVariants(context, { product }) { + return filterOutUnavailableVariants(context, product); }, /** @@ -274,89 +395,148 @@ const actions: ActionTree = { * @param {Int} size page size * @return {Promise} */ - list (context, { query, start = 0, size = 50, entityType = 'product', sort = '', cacheByKey = 'sku', prefetchGroupProducts = !isServer, updateState = false, meta = {}, excludeFields = null, includeFields = null, configuration = null, append = false, populateRequestCacheTags = true }) { - let isCacheable = (includeFields === null && excludeFields === null) + list( + context, + { + query, + start = 0, + size = 50, + entityType = 'product', + sort = '', + cacheByKey = 'sku', + prefetchGroupProducts = !isServer, + updateState = false, + meta = {}, + excludeFields = null, + includeFields = null, + configuration = null, + append = false, + populateRequestCacheTags = true + } + ) { + let isCacheable = includeFields === null && excludeFields === null; if (isCacheable) { - Logger.debug('Entity cache is enabled for productList')() + Logger.debug('Entity cache is enabled for productList')(); } else { - Logger.debug('Entity cache is disabled for productList')() + Logger.debug('Entity cache is disabled for productList')(); } if (rootStore.state.config.entities.optimize) { - if (excludeFields === null) { // if not set explicitly we do optimize the amount of data by using some default field list; this is cacheable - excludeFields = rootStore.state.config.entities.product.excludeFields + if (excludeFields === null) { + // if not set explicitly we do optimize the amount of data by using some default field list; this is cacheable + excludeFields = rootStore.state.config.entities.product.excludeFields; } - if (includeFields === null) { // if not set explicitly we do optimize the amount of data by using some default field list; this is cacheable - includeFields = rootStore.state.config.entities.product.includeFields + if (includeFields === null) { + // if not set explicitly we do optimize the amount of data by using some default field list; this is cacheable + includeFields = rootStore.state.config.entities.product.includeFields; } } - return quickSearchByQuery({ query, start, size, entityType, sort, excludeFields, includeFields }).then((resp) => { - if (resp.items && resp.items.length) { // preconfigure products; eg: after filters + return quickSearchByQuery({ + query, + start, + size, + entityType, + sort, + excludeFields, + includeFields + }).then(resp => { + if (resp.items && resp.items.length) { + // preconfigure products; eg: after filters for (let product of resp.items) { if (populateRequestCacheTags && Vue.prototype.$ssrRequestContext) { - Vue.prototype.$ssrRequestContext.output.cacheTags.add(`P${product.id}`) + Vue.prototype.$ssrRequestContext.output.cacheTags.add( + `P${product.id}` + ); } - product.errors = {} // this is an object to store validation result for custom options and others - product.info = {} + product.errors = {}; // this is an object to store validation result for custom options and others + product.info = {}; if (!product.parentSku) { - product.parentSku = product.sku + product.parentSku = product.sku; } - if (rootStore.state.config.products.setFirstVarianAsDefaultInURL && product.hasOwnProperty('configurable_children') && product.configurable_children.length > 0) { - product.sku = product.configurable_children[0].sku + if ( + rootStore.state.config.products.setFirstVarianAsDefaultInURL && + product.hasOwnProperty('configurable_children') && + product.configurable_children.length > 0 + ) { + product.sku = product.configurable_children[0].sku; } if (configuration) { - let selectedVariant = configureProductAsync(context, { product: product, configuration: configuration, selectDefaultVariant: false }) - Object.assign(product, selectedVariant) + let selectedVariant = configureProductAsync(context, { + product: product, + configuration: configuration, + selectDefaultVariant: false + }); + Object.assign(product, selectedVariant); } if (product.url_path) { - rootStore.dispatch('url/registerMapping', { - url: product.url_path, - routeData: { - params: { - 'parentSku': product.parentSku, - 'slug': product.slug - }, - 'name': product.type_id + '-product' - } - }, { root: true }) + rootStore.dispatch( + 'url/registerMapping', + { + url: product.url_path, + routeData: { + params: { + parentSku: product.parentSku, + slug: product.slug + }, + name: product.type_id + '-product' + } + }, + { root: true } + ); } } } - return calculateTaxes(resp.items, context).then((updatedProducts) => { + return calculateTaxes(resp.items, context).then(updatedProducts => { // handle cache - const cache = Vue.prototype.$db.elasticCacheCollection - for (let prod of resp.items) { // we store each product separately in cache to have offline access to products/single method + const cache = Vue.prototype.$db.elasticCacheCollection; + for (let prod of resp.items) { + // we store each product separately in cache to have offline access to products/single method if (prod.configurable_children) { for (let configurableChild of prod.configurable_children) { if (configurableChild.custom_attributes) { for (let opt of configurableChild.custom_attributes) { - configurableChild[opt.attribute_code] = opt.value + configurableChild[opt.attribute_code] = opt.value; } } } } if (!prod[cacheByKey]) { - cacheByKey = 'id' + cacheByKey = 'id'; } - const cacheKey = entityKeyName(cacheByKey, prod[cacheByKey]) - if (isCacheable) { // store cache only for full loads - cache.setItem(cacheKey, prod) - .catch((err) => { - Logger.error('Cannot store cache for ' + cacheKey, err)() - }) + const cacheKey = entityKeyName(cacheByKey, prod[cacheByKey]); + if (isCacheable) { + // store cache only for full loads + cache.setItem(cacheKey, prod).catch(err => { + Logger.error('Cannot store cache for ' + cacheKey, err)(); + }); } - if ((prod.type_id === 'grouped' || prod.type_id === 'bundle') && prefetchGroupProducts && !isServer) { - context.dispatch('setupAssociated', { product: prod }) + if ( + (prod.type_id === 'grouped' || prod.type_id === 'bundle') && + prefetchGroupProducts && + !isServer + ) { + context.dispatch('setupAssociated', { product: prod }); } } // commit update products list mutation if (updateState) { - context.commit(types.CATALOG_UPD_PRODUCTS, { products: resp, append: append }) + context.commit(types.CATALOG_UPD_PRODUCTS, { + products: resp, + append: append + }); } - Vue.prototype.$bus.$emit('product-after-list', { query: query, start: start, size: size, sort: sort, entityType: entityType, meta: meta, result: resp }) - return resp - }) - }) + Vue.prototype.$bus.$emit('product-after-list', { + query: query, + start: start, + size: size, + sort: sort, + entityType: entityType, + meta: meta, + result: resp + }); + return resp; + }); + }); }, /** @@ -365,13 +545,17 @@ const actions: ActionTree = { * @param product */ configureBundleAsync(context, product) { - return context.dispatch( - 'setupAssociated', { - product: product , + return context + .dispatch('setupAssociated', { + product: product, skipCache: true }) - .then(() => {context.dispatch('setCurrent', product)}) - .then(() => {Vue.prototype.$bus.$emit('product-after-setup-associated')}) + .then(() => { + context.dispatch('setCurrent', product); + }) + .then(() => { + Vue.prototype.$bus.$emit('product-after-setup-associated'); + }); }, /** @@ -380,147 +564,219 @@ const actions: ActionTree = { * @param product */ configureGroupedAsync(context, product) { - return context.dispatch( - 'setupAssociated', { + return context + .dispatch('setupAssociated', { product: product, skipCache: true }) - .then(() => {context.dispatch('setCurrent', product)}) + .then(() => { + context.dispatch('setCurrent', product); + }); }, /** * Search products by specific field * @param {Object} options */ - single (context, { options, setCurrentProduct = true, selectDefaultVariant = true, assignDefaultVariant = false, key = 'sku', skipCache = false }) { + single( + context, + { + options, + setCurrentProduct = true, + selectDefaultVariant = true, + assignDefaultVariant = false, + key = 'sku', + skipCache = false + } + ) { if (!options[key]) { - throw Error('Please provide the search key ' + key + ' for product/single action!') + throw Error( + 'Please provide the search key ' + key + ' for product/single action!' + ); } - const cacheKey = entityKeyName(key, options[key]) + const cacheKey = entityKeyName(key, options[key]); return new Promise((resolve, reject) => { - const benchmarkTime = new Date() - const cache = Vue.prototype.$db.elasticCacheCollection + const benchmarkTime = new Date(); + const cache = Vue.prototype.$db.elasticCacheCollection; - const setupProduct = (prod) => { + const setupProduct = prod => { // set product quantity to 1 - if(!prod.qty) { - prod.qty = 1 + if (!prod.qty) { + prod.qty = 1; } // set original product if (setCurrentProduct) { - context.dispatch('setOriginal', prod) + context.dispatch('setOriginal', prod); } // check is prod has configurable children - const hasConfigurableChildren = prod && prod.configurable_children && prod.configurable_children.length - if (prod.type_id === 'simple' && hasConfigurableChildren) { // workaround for #983 - prod = omit(prod, ['configurable_children', 'configurable_options']) + const hasConfigurableChildren = + prod && + prod.configurable_children && + prod.configurable_children.length; + if (prod.type_id === 'simple' && hasConfigurableChildren) { + // workaround for #983 + prod = omit(prod, ['configurable_children', 'configurable_options']); } // set current product - configurable or not if (prod.type_id === 'configurable' && hasConfigurableChildren) { // set first available configuration // todo: probably a good idea is to change this [0] to specific id - const selectedVariant = configureProductAsync(context, { product: prod, configuration: { sku: options.childSku }, selectDefaultVariant: selectDefaultVariant, setProductErorrs: true }) + const selectedVariant = configureProductAsync(context, { + product: prod, + configuration: { sku: options.childSku }, + selectDefaultVariant: selectDefaultVariant, + setProductErorrs: true + }); if (selectedVariant && assignDefaultVariant) { - prod = Object.assign(prod, selectedVariant) + prod = Object.assign(prod, selectedVariant); } - } else if (!skipCache || ('simple' === prod.type_id || 'downloadable' === prod.type_id)) { - if (setCurrentProduct) context.dispatch('setCurrent', prod) + } else if ( + !skipCache || + ('simple' === prod.type_id || 'downloadable' === prod.type_id) + ) { + if (setCurrentProduct) context.dispatch('setCurrent', prod); } - return prod - } + return prod; + }; const syncProducts = () => { - let searchQuery = new SearchQuery() - searchQuery = searchQuery.applyFilter({key: key, value: {'eq': options[key]}}) - - return context.dispatch('list', { // product list syncs the platform price on it's own - query: searchQuery, - prefetchGroupProducts: false, - updateState: false - }).then((res) => { - if (res && res.items && res.items.length) { - let prd = res.items[0] - const _returnProductNoCacheHelper = (subresults) => { - Vue.prototype.$bus.$emitFilter('product-after-single', { key: key, options: options, product: prd }) - resolve(setupProduct(prd)) - } - if (setCurrentProduct || selectDefaultVariant) { - const subConfigPromises = [] - if ('bundle' === prd.type_id) { - subConfigPromises.push(context.dispatch('configureBundleAsync', prd)) - } + let searchQuery = new SearchQuery(); + searchQuery = searchQuery.applyFilter({ + key: key, + value: { eq: options[key] } + }); + + return context + .dispatch('list', { + // product list syncs the platform price on it's own + query: searchQuery, + prefetchGroupProducts: false, + updateState: false + }) + .then(res => { + if (res && res.items && res.items.length) { + let prd = res.items[0]; + const _returnProductNoCacheHelper = subresults => { + Vue.prototype.$bus.$emitFilter('product-after-single', { + key: key, + options: options, + product: prd + }); + resolve(setupProduct(prd)); + }; + if (setCurrentProduct || selectDefaultVariant) { + const subConfigPromises = []; + if ('bundle' === prd.type_id) { + subConfigPromises.push( + context.dispatch('configureBundleAsync', prd) + ); + } - if ('grouped' === prd.type_id) { - subConfigPromises.push(context.dispatch('configureGroupedAsync', prd)) + if ('grouped' === prd.type_id) { + subConfigPromises.push( + context.dispatch('configureGroupedAsync', prd) + ); + } + subConfigPromises.push( + context.dispatch('setupVariants', { product: prd }) + ); + Promise.all(subConfigPromises).then( + _returnProductNoCacheHelper + ); + } else { + _returnProductNoCacheHelper(null); } - subConfigPromises.push(context.dispatch('setupVariants', { product: prd })) - Promise.all(subConfigPromises).then(_returnProductNoCacheHelper) } else { - _returnProductNoCacheHelper(null) + reject(new Error('Product query returned empty result')); } - } else { - reject(new Error('Product query returned empty result')) - } - }) - } + }); + }; const getProductFromCache = () => { cache.getItem(cacheKey, (err, res) => { // report errors if (!skipCache && err) { - Logger.error(err, 'product')() + Logger.error(err, 'product')(); } if (res !== null) { - Logger.debug('Product:single - result from localForage (for ' + cacheKey + '), ms=' + (new Date().getTime() - benchmarkTime.getTime()), 'product')() - const _returnProductFromCacheHelper = (subresults) => { - const cachedProduct = setupProduct(res) - if (rootStore.state.config.products.alwaysSyncPlatformPricesOver) { - doPlatformPricesSync([cachedProduct]).then((products) => { - Vue.prototype.$bus.$emitFilter('product-after-single', { key: key, options: options, product: products[0] }) - resolve(products[0]) - }) + Logger.debug( + 'Product:single - result from localForage (for ' + + cacheKey + + '), ms=' + + (new Date().getTime() - benchmarkTime.getTime()), + 'product' + )(); + const _returnProductFromCacheHelper = subresults => { + const cachedProduct = setupProduct(res); + if ( + rootStore.state.config.products.alwaysSyncPlatformPricesOver + ) { + doPlatformPricesSync([cachedProduct]).then(products => { + Vue.prototype.$bus.$emitFilter('product-after-single', { + key: key, + options: options, + product: products[0] + }); + resolve(products[0]); + }); if (!rootStore.state.config.products.waitForPlatformSync) { - Vue.prototype.$bus.$emitFilter('product-after-single', { key: key, options: options, product: cachedProduct }) - resolve(cachedProduct) + Vue.prototype.$bus.$emitFilter('product-after-single', { + key: key, + options: options, + product: cachedProduct + }); + resolve(cachedProduct); } } else { - Vue.prototype.$bus.$emitFilter('product-after-single', { key: key, options: options, product: cachedProduct }) - resolve(cachedProduct) + Vue.prototype.$bus.$emitFilter('product-after-single', { + key: key, + options: options, + product: cachedProduct + }); + resolve(cachedProduct); } - } + }; if (setCurrentProduct || selectDefaultVariant) { - const subConfigPromises = [] - subConfigPromises.push(context.dispatch('setupVariants', { product: res })) + const subConfigPromises = []; + subConfigPromises.push( + context.dispatch('setupVariants', { product: res }) + ); if ('bundle' === res.type_id) { - subConfigPromises.push(context.dispatch('configureBundleAsync', res)) + subConfigPromises.push( + context.dispatch('configureBundleAsync', res) + ); } if ('grouped' === res.type_id) { - subConfigPromises.push(context.dispatch('configureGroupedAsync', res)) + subConfigPromises.push( + context.dispatch('configureGroupedAsync', res) + ); } - Promise.all(subConfigPromises).then(_returnProductFromCacheHelper) + Promise.all(subConfigPromises).then( + _returnProductFromCacheHelper + ); } else { - _returnProductFromCacheHelper(null) + _returnProductFromCacheHelper(null); } } else { - syncProducts() + syncProducts(); } - }) - } + }); + }; if (!skipCache) { - getProductFromCache() + getProductFromCache(); } else { if (!isOnline()) { skipCache = false; } - syncProducts() + syncProducts(); } - }) + }); }, /** * Configure product with given configuration and set it as current @@ -528,35 +784,75 @@ const actions: ActionTree = { * @param {Object} product * @param {Array} configuration */ - configure (context, { product = null, configuration, selectDefaultVariant = true, fallbackToDefaultWhenNoAvailable = true }) { - return configureProductAsync(context, { product: product, configuration: configuration, selectDefaultVariant: selectDefaultVariant, fallbackToDefaultWhenNoAvailable: fallbackToDefaultWhenNoAvailable }) + configure( + context, + { + product = null, + configuration, + selectDefaultVariant = true, + fallbackToDefaultWhenNoAvailable = true + } + ) { + return configureProductAsync(context, { + product: product, + configuration: configuration, + selectDefaultVariant: selectDefaultVariant, + fallbackToDefaultWhenNoAvailable: fallbackToDefaultWhenNoAvailable + }); }, - setCurrentOption (context, productOption) { - if (productOption && typeof productOption === 'object') { // TODO: this causes some kind of recurrency error - context.commit(types.CATALOG_SET_PRODUCT_CURRENT, Object.assign({}, context.state.current, { product_option: productOption })) + setCurrentOption(context, productOption) { + if (productOption && typeof productOption === 'object') { + // TODO: this causes some kind of recurrency error + context.commit( + types.CATALOG_SET_PRODUCT_CURRENT, + Object.assign({}, context.state.current, { + product_option: productOption + }) + ); } }, - setCurrentErrors (context, errors) { + setCurrentErrors(context, errors) { if (errors && typeof errors === 'object') { - context.commit(types.CATALOG_SET_PRODUCT_CURRENT, Object.assign({}, context.state.current, { errors: errors })) + context.commit( + types.CATALOG_SET_PRODUCT_CURRENT, + Object.assign({}, context.state.current, { errors: errors }) + ); } }, /** * Assign the custom options object to the currentl product */ - setCustomOptions (context, { customOptions, product }) { - if (customOptions) { // TODO: this causes some kind of recurrency error - context.commit(types.CATALOG_SET_PRODUCT_CURRENT, Object.assign({}, product, { product_option: setCustomProductOptionsAsync(context, { product: context.state.current, customOptions: customOptions }) })) + setCustomOptions(context, { customOptions, product }) { + if (customOptions) { + // TODO: this causes some kind of recurrency error + context.commit( + types.CATALOG_SET_PRODUCT_CURRENT, + Object.assign({}, product, { + product_option: setCustomProductOptionsAsync(context, { + product: context.state.current, + customOptions: customOptions + }) + }) + ); } }, /** * Assign the bundle options object to the vurrent product */ - setBundleOptions (context, { bundleOptions, product }) { - if (bundleOptions) { // TODO: this causes some kind of recurrency error - context.commit(types.CATALOG_SET_PRODUCT_CURRENT, Object.assign({}, product, { product_option: setBundleProductOptionsAsync(context, { product: context.state.current, bundleOptions: bundleOptions }) })) + setBundleOptions(context, { bundleOptions, product }) { + if (bundleOptions) { + // TODO: this causes some kind of recurrency error + context.commit( + types.CATALOG_SET_PRODUCT_CURRENT, + Object.assign({}, product, { + product_option: setBundleProductOptionsAsync(context, { + product: context.state.current, + bundleOptions: bundleOptions + }) + }) + ); } }, /** @@ -564,97 +860,148 @@ const actions: ActionTree = { * @param {Object} context * @param {Object} productVariant */ - setCurrent (context, productVariant) { + setCurrent(context, productVariant) { if (productVariant && typeof productVariant === 'object') { // get original product - const productOriginal = context.getters.productOriginal + const productOriginal = context.getters.productOriginal; // check if passed variant is the same as original - const productUpdated = Object.assign({}, productOriginal, productVariant) - populateProductConfigurationAsync(context, { product: productUpdated, selectedVariant: productVariant }) + const productUpdated = Object.assign({}, productOriginal, productVariant); + populateProductConfigurationAsync(context, { + product: productUpdated, + selectedVariant: productVariant + }); if (!rootStore.state.config.products.gallery.mergeConfigurableChildren) { - context.commit(types.CATALOG_UPD_GALLERY, attributeImages(productVariant)) + context.commit( + types.CATALOG_UPD_GALLERY, + attributeImages(productVariant) + ); } - context.commit(types.CATALOG_SET_PRODUCT_CURRENT, productUpdated) - return productUpdated - } else Logger.debug('Unable to update current product.', 'product')() + context.commit(types.CATALOG_SET_PRODUCT_CURRENT, productUpdated); + return productUpdated; + } else Logger.debug('Unable to update current product.', 'product')(); }, /** * Set given product as original * @param {Object} context * @param {Object} originalProduct */ - setOriginal (context, originalProduct) { - if (originalProduct && typeof originalProduct === 'object') context.commit(types.CATALOG_SET_PRODUCT_ORIGINAL, originalProduct) - else Logger.debug('Unable to setup original product.', 'product')() + setOriginal(context, originalProduct) { + if (originalProduct && typeof originalProduct === 'object') + context.commit(types.CATALOG_SET_PRODUCT_ORIGINAL, originalProduct); + else Logger.debug('Unable to setup original product.', 'product')(); }, /** * Set related products */ - related (context, { key = 'related-products', items }) { - context.commit(types.CATALOG_UPD_RELATED, { key, items }) + related(context, { key = 'related-products', items }) { + context.commit(types.CATALOG_UPD_RELATED, { key, items }); }, /** * Load the product data */ - fetch (context, { parentSku, childSku = null }) { + fetch(context, { parentSku, childSku = null }) { // pass both id and sku to render a product const productSingleOptions = { sku: parentSku, childSku: childSku - } - return context.dispatch('single', { options: productSingleOptions }).then((product) => { - if (product.status >= 2) { - throw new Error(`Product query returned empty result product status = ${product.status}`) - } - if (product.visibility === 1) { // not visible individually (https://magento.stackexchange.com/questions/171584/magento-2-table-name-for-product-visibility) - throw new Error(`Product query returned empty result product visibility = ${product.visibility}`) - } - - let subloaders = [] - if (product) { - const productFields = Object.keys(product).filter(fieldName => { - return rootStore.state.config.entities.product.standardSystemFields.indexOf(fieldName) < 0 // don't load metadata info for standard fields - }) - const attributesPromise = context.dispatch('attribute/list', { // load attributes to be shown on the product details - the request is now async - filterValues: rootStore.state.config.entities.product.useDynamicAttributeLoader ? productFields : null, - only_visible: rootStore.state.config.entities.product.useDynamicAttributeLoader ? true : false, - only_user_defined: true, - includeFields: rootStore.state.config.entities.optimize ? rootStore.state.config.entities.attribute.includeFields : null - }, { root: true }) // TODO: it might be refactored to kind of: `await context.dispatch('attributes/list) - or using new Promise() .. to wait for attributes to be loaded before executing the next action. However it may decrease the performance - so for now we're just waiting with the breadcrumbs - if (isServer) { - subloaders.push(context.dispatch('setupBreadcrumbs', { product: product })) - subloaders.push(context.dispatch('filterUnavailableVariants', { product: product })) - } else { - attributesPromise.then(() => context.dispatch('setupBreadcrumbs', { product: product })) // if this is client's side request postpone breadcrumbs setup till attributes are loaded to avoid too-early breadcrumb switch #2469 - context.dispatch('filterUnavailableVariants', { product: product }) // exec async + }; + return context + .dispatch('single', { options: productSingleOptions }) + .then(product => { + if (product.status >= 2) { + throw new Error( + `Product query returned empty result product status = ${ + product.status + }` + ); + } + if (product.visibility === 1) { + // not visible individually (https://magento.stackexchange.com/questions/171584/magento-2-table-name-for-product-visibility) + throw new Error( + `Product query returned empty result product visibility = ${ + product.visibility + }` + ); } - subloaders.push(attributesPromise) - // subloaders.push(context.dispatch('setupVariants', { product: product })) -- moved to "product/single" - /* if (product.type_id === 'grouped' || product.type_id === 'bundle') { -- moved to "product/single" + let subloaders = []; + if (product) { + const productFields = Object.keys(product).filter(fieldName => { + return ( + rootStore.state.config.entities.product.standardSystemFields.indexOf( + fieldName + ) < 0 + ); // don't load metadata info for standard fields + }); + const attributesPromise = context.dispatch( + 'attribute/list', + { + // load attributes to be shown on the product details - the request is now async + filterValues: rootStore.state.config.entities.product + .useDynamicAttributeLoader + ? productFields + : null, + only_visible: rootStore.state.config.entities.product + .useDynamicAttributeLoader + ? true + : false, + only_user_defined: true, + includeFields: rootStore.state.config.entities.optimize + ? rootStore.state.config.entities.attribute.includeFields + : null + }, + { root: true } + ); // TODO: it might be refactored to kind of: `await context.dispatch('attributes/list) - or using new Promise() .. to wait for attributes to be loaded before executing the next action. However it may decrease the performance - so for now we're just waiting with the breadcrumbs + if (isServer) { + subloaders.push( + context.dispatch('setupBreadcrumbs', { product: product }) + ); + subloaders.push( + context.dispatch('filterUnavailableVariants', { + product: product + }) + ); + } else { + attributesPromise.then(() => + context.dispatch('setupBreadcrumbs', { product: product }) + ); // if this is client's side request postpone breadcrumbs setup till attributes are loaded to avoid too-early breadcrumb switch #2469 + context.dispatch('filterUnavailableVariants', { product: product }); // exec async + } + subloaders.push(attributesPromise); + + // subloaders.push(context.dispatch('setupVariants', { product: product })) -- moved to "product/single" + /* if (product.type_id === 'grouped' || product.type_id === 'bundle') { -- moved to "product/single" subloaders.push(context.dispatch('setupAssociated', { product: product }).then((subloaderresults) => { context.dispatch('setCurrent', product) // because setup Associated can modify the product price we need to update the current product })) } */ - context.dispatch('setProductGallery', { product: product }) + context.dispatch('setProductGallery', { product: product }); - if (rootStore.state.config.products.preventConfigurableChildrenDirectAccess) { - subloaders.push(context.dispatch('checkConfigurableParent', { product: product })) + if ( + rootStore.state.config.products + .preventConfigurableChildrenDirectAccess + ) { + subloaders.push( + context.dispatch('checkConfigurableParent', { product: product }) + ); + } + } else { + // error or redirect } - } else { // error or redirect - - } - return subloaders - }) + return subloaders; + }); }, /** * Add custom option validator for product custom options */ - addCustomOptionValidator (context, { validationRule, validatorFunction }) { - context.commit(types.CATALOG_ADD_CUSTOM_OPTION_VALIDATOR, { validationRule, validatorFunction }) + addCustomOptionValidator(context, { validationRule, validatorFunction }) { + context.commit(types.CATALOG_ADD_CUSTOM_OPTION_VALIDATOR, { + validationRule, + validatorFunction + }); }, /** @@ -662,56 +1009,93 @@ const actions: ActionTree = { */ setProductGallery(context, { product }) { - if (product.type_id === 'configurable' && product.hasOwnProperty('configurable_children')) { - if (!rootStore.state.config.products.gallery.mergeConfigurableChildren && product.is_configured) { - context.commit(types.CATALOG_UPD_GALLERY, attributeImages(context.state.current)) - } else { - let productGallery = uniqBy(configurableChildrenImages(product).concat(getMediaGallery(product)), 'src').filter(f => { return f.src && f.src !== rootStore.state.config.images.productPlaceholder }) - context.commit(types.CATALOG_UPD_GALLERY, productGallery) - } + if ( + product.type_id === 'configurable' && + product.hasOwnProperty('configurable_children') + ) { + if ( + !rootStore.state.config.products.gallery.mergeConfigurableChildren && + product.is_configured + ) { + context.commit( + types.CATALOG_UPD_GALLERY, + attributeImages(context.state.current) + ); } else { - context.commit(types.CATALOG_UPD_GALLERY, getMediaGallery(product)) + let productGallery = uniqBy( + configurableChildrenImages(product).concat(getMediaGallery(product)), + 'src' + ).filter(f => { + return ( + f.src && f.src !== rootStore.state.config.images.productPlaceholder + ); + }); + context.commit(types.CATALOG_UPD_GALLERY, productGallery); } + } else { + context.commit(types.CATALOG_UPD_GALLERY, getMediaGallery(product)); + } }, /** * Load the product data - async version for asyncData() */ - fetchAsync (context, { parentSku, childSku = null, route = null }) { - if (context.state.productLoadStart && (Date.now() - context.state.productLoadStart) < PRODUCT_REENTER_TIMEOUT) { - Logger.log('Product is being fetched ...', 'product')() + fetchAsync(context, { parentSku, childSku = null, route = null }) { + if ( + context.state.productLoadStart && + Date.now() - context.state.productLoadStart < PRODUCT_REENTER_TIMEOUT + ) { + Logger.log('Product is being fetched ...', 'product')(); } else { context.state.productLoadPromise = new Promise((resolve, reject) => { - context.state.productLoadStart = Date.now() - Logger.info('Fetching product data asynchronously' , 'product', {parentSku, childSku})() - Vue.prototype.$bus.$emit('product-before-load', { store: rootStore, route: route }) + context.state.productLoadStart = Date.now(); + Logger.info('Fetching product data asynchronously', 'product', { + parentSku, + childSku + })(); + Vue.prototype.$bus.$emit('product-before-load', { + store: rootStore, + route: route + }); context.dispatch('reset').then(() => { - context.dispatch('fetch', { parentSku: parentSku, childSku: childSku }).then((subpromises) => { - Promise.all(subpromises).then(subresults => { - Vue.prototype.$bus.$emitFilter('product-after-load', { store: rootStore, route: route }).then((results) => { - context.state.productLoadStart = null - return resolve() - }).catch((err) => { - context.state.productLoadStart = null - Logger.error(err, 'product')() - return resolve() - }) - }).catch(errs => { - context.state.productLoadStart = null - reject(errs) + context + .dispatch('fetch', { parentSku: parentSku, childSku: childSku }) + .then(subpromises => { + Promise.all(subpromises) + .then(subresults => { + Vue.prototype.$bus + .$emitFilter('product-after-load', { + store: rootStore, + route: route + }) + .then(results => { + context.state.productLoadStart = null; + return resolve(); + }) + .catch(err => { + context.state.productLoadStart = null; + Logger.error(err, 'product')(); + return resolve(); + }); + }) + .catch(errs => { + context.state.productLoadStart = null; + reject(errs); + }); }) - }).catch(err => { - context.state.productLoadStart = null - reject(err) - }).catch(err => { - context.state.productLoadStart = null - reject(err) - }) - }) - }) + .catch(err => { + context.state.productLoadStart = null; + reject(err); + }) + .catch(err => { + context.state.productLoadStart = null; + reject(err); + }); + }); + }); } - return context.state.productLoadPromise + return context.state.productLoadPromise; } -} +}; -export default actions +export default actions; diff --git a/core/modules/catalog/store/product/getters.ts b/core/modules/catalog/store/product/getters.ts index 6455e7b3de..2f345694d4 100644 --- a/core/modules/catalog/store/product/getters.ts +++ b/core/modules/catalog/store/product/getters.ts @@ -1,15 +1,15 @@ -import { GetterTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import ProductState from '../../types/ProductState' +import { GetterTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import ProductState from '../../types/ProductState'; const getters: GetterTree = { - productParent: (state) => state.parent, - productCurrent: (state) => state.current, - currentConfiguration: (state) => state.current_configuration, - productOriginal: (state) => state.original, - currentOptions: (state) => state.current_options, - breadcrumbs: (state) => state.breadcrumbs, - productGallery: (state) => state.productGallery -} + productParent: state => state.parent, + productCurrent: state => state.current, + currentConfiguration: state => state.current_configuration, + productOriginal: state => state.original, + currentOptions: state => state.current_options, + breadcrumbs: state => state.breadcrumbs, + productGallery: state => state.productGallery +}; -export default getters +export default getters; diff --git a/core/modules/catalog/store/product/index.ts b/core/modules/catalog/store/product/index.ts index f59e2cbe94..8d3c001849 100644 --- a/core/modules/catalog/store/product/index.ts +++ b/core/modules/catalog/store/product/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import ProductState from '../../types/ProductState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import ProductState from '../../types/ProductState'; export const productModule: Module = { namespaced: true, @@ -33,4 +33,4 @@ export const productModule: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/catalog/store/product/mutation-types.ts b/core/modules/catalog/store/product/mutation-types.ts index 2e08a15e94..031a55c88d 100644 --- a/core/modules/catalog/store/product/mutation-types.ts +++ b/core/modules/catalog/store/product/mutation-types.ts @@ -1,13 +1,15 @@ -export const SN_PRODUCT = 'product' -export const CATALOG_UPD_PRODUCTS = SN_PRODUCT + '/UPD_PRODUCTS' -export const CATALOG_UPD_RELATED = SN_PRODUCT + '/UPD_RELATED' -export const CATALOG_UPD_SEARCH_QUERY = SN_PRODUCT + '/UPD_SEARCH_QUERY' -export const CATALOG_SET_PRODUCT_CURRENT = SN_PRODUCT + '/SET_PRODUCT_CURRENT' -export const CATALOG_SET_PRODUCT_ORIGINAL = SN_PRODUCT + '/SET_PRODUCT_ORIGINAL' -export const CATALOG_RESET_PRODUCT = SN_PRODUCT + '/RESET_PRODUCT_ORIGINAL' -export const CATALOG_SET_PRODUCT_PARENT = SN_PRODUCT + '/SET_PARENT' -export const CATALOG_UPD_CUSTOM_OPTION = SN_PRODUCT + '/SET_CUSTOM_OPTION' -export const CATALOG_UPD_BUNDLE_OPTION = SN_PRODUCT + '/SET_BUNDLE_OPTION' -export const CATALOG_ADD_CUSTOM_OPTION_VALIDATOR = SN_PRODUCT + '/ADD_CUSTOM_OPTION_VALIDATOR' -export const CATALOG_UPD_GALLERY = SN_PRODUCT + '/SET_GALLERY' -export const CATALOG_SET_BREADCRUMBS = SN_PRODUCT + '/SET_BREADCRUMBS' \ No newline at end of file +export const SN_PRODUCT = 'product'; +export const CATALOG_UPD_PRODUCTS = SN_PRODUCT + '/UPD_PRODUCTS'; +export const CATALOG_UPD_RELATED = SN_PRODUCT + '/UPD_RELATED'; +export const CATALOG_UPD_SEARCH_QUERY = SN_PRODUCT + '/UPD_SEARCH_QUERY'; +export const CATALOG_SET_PRODUCT_CURRENT = SN_PRODUCT + '/SET_PRODUCT_CURRENT'; +export const CATALOG_SET_PRODUCT_ORIGINAL = + SN_PRODUCT + '/SET_PRODUCT_ORIGINAL'; +export const CATALOG_RESET_PRODUCT = SN_PRODUCT + '/RESET_PRODUCT_ORIGINAL'; +export const CATALOG_SET_PRODUCT_PARENT = SN_PRODUCT + '/SET_PARENT'; +export const CATALOG_UPD_CUSTOM_OPTION = SN_PRODUCT + '/SET_CUSTOM_OPTION'; +export const CATALOG_UPD_BUNDLE_OPTION = SN_PRODUCT + '/SET_BUNDLE_OPTION'; +export const CATALOG_ADD_CUSTOM_OPTION_VALIDATOR = + SN_PRODUCT + '/ADD_CUSTOM_OPTION_VALIDATOR'; +export const CATALOG_UPD_GALLERY = SN_PRODUCT + '/SET_GALLERY'; +export const CATALOG_SET_BREADCRUMBS = SN_PRODUCT + '/SET_BREADCRUMBS'; diff --git a/core/modules/catalog/store/product/mutations.ts b/core/modules/catalog/store/product/mutations.ts index ccef6d5e99..ccebac0dd0 100644 --- a/core/modules/catalog/store/product/mutations.ts +++ b/core/modules/catalog/store/product/mutations.ts @@ -1,65 +1,76 @@ -import Vue from 'vue' -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import ProductState, { PagedProductList } from '../../types/ProductState' +import Vue from 'vue'; +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import ProductState, { PagedProductList } from '../../types/ProductState'; const mutations: MutationTree = { - [types.CATALOG_SET_BREADCRUMBS] (state, payload) { - state.breadcrumbs = payload + [types.CATALOG_SET_BREADCRUMBS](state, payload) { + state.breadcrumbs = payload; }, - [types.CATALOG_UPD_RELATED] (state, { key, items }) { - state.related[key] = items - Vue.prototype.$bus.$emit('product-after-related', { key: key, items: items }) + [types.CATALOG_UPD_RELATED](state, { key, items }) { + state.related[key] = items; + Vue.prototype.$bus.$emit('product-after-related', { + key: key, + items: items + }); }, - [types.CATALOG_ADD_CUSTOM_OPTION_VALIDATOR] (state, { validationRule, validatorFunction }) { - state.custom_options_validators[validationRule] = validatorFunction + [types.CATALOG_ADD_CUSTOM_OPTION_VALIDATOR]( + state, + { validationRule, validatorFunction } + ) { + state.custom_options_validators[validationRule] = validatorFunction; }, - [types.CATALOG_UPD_CUSTOM_OPTION] (state, { optionId, optionValue }) { + [types.CATALOG_UPD_CUSTOM_OPTION](state, { optionId, optionValue }) { state.current_custom_options[optionId] = { option_id: optionId, option_value: optionValue - } + }; }, - [types.CATALOG_UPD_BUNDLE_OPTION] (state, { optionId, optionQty, optionSelections }) { + [types.CATALOG_UPD_BUNDLE_OPTION]( + state, + { optionId, optionQty, optionSelections } + ) { state.current_bundle_options[optionId] = { option_id: optionId, option_qty: optionQty, option_selections: optionSelections - } + }; }, - [types.CATALOG_UPD_PRODUCTS] (state, { products, append }) { + [types.CATALOG_UPD_PRODUCTS](state, { products, append }) { if (append === false) { - state.list = products + state.list = products; } else { - (state.list as PagedProductList).start = products.start as number - (state.list as PagedProductList).perPage = products.perPage as number - (state.list as PagedProductList).items = (state.list as PagedProductList).items.concat(products.items) + (state.list as PagedProductList).start = products.start as number; + (state.list as PagedProductList).perPage = products.perPage as number; + (state.list as PagedProductList).items = (state.list as PagedProductList).items.concat( + products.items + ); } }, - [types.CATALOG_SET_PRODUCT_CURRENT] (state, product) { - state.current = product + [types.CATALOG_SET_PRODUCT_CURRENT](state, product) { + state.current = product; }, - [types.CATALOG_SET_PRODUCT_ORIGINAL] (state, product) { - state.original = product - Vue.prototype.$bus.$emit('product-after-original', { original: product }) + [types.CATALOG_SET_PRODUCT_ORIGINAL](state, product) { + state.original = product; + Vue.prototype.$bus.$emit('product-after-original', { original: product }); }, - [types.CATALOG_SET_PRODUCT_PARENT] (state, product) { - state.parent = product - Vue.prototype.$bus.$emit('product-after-parent', { parent: product }) + [types.CATALOG_SET_PRODUCT_PARENT](state, product) { + state.parent = product; + Vue.prototype.$bus.$emit('product-after-parent', { parent: product }); }, - [types.CATALOG_RESET_PRODUCT] (state, productOriginal) { - state.current = productOriginal || {} - state.current_configuration = {} - state.offlineImage = null - state.parent = null - state.current_options = {color: [], size: []} - state.current_bundle_options = {} - state.current_custom_options = {} - Vue.prototype.$bus.$emit('product-after-reset', { }) + [types.CATALOG_RESET_PRODUCT](state, productOriginal) { + state.current = productOriginal || {}; + state.current_configuration = {}; + state.offlineImage = null; + state.parent = null; + state.current_options = { color: [], size: [] }; + state.current_bundle_options = {}; + state.current_custom_options = {}; + Vue.prototype.$bus.$emit('product-after-reset', {}); }, - [types.CATALOG_UPD_GALLERY] (state, productGallery) { - state.productGallery = productGallery + [types.CATALOG_UPD_GALLERY](state, productGallery) { + state.productGallery = productGallery; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/catalog/store/stock/actions.ts b/core/modules/catalog/store/stock/actions.ts index bb732d4718..e14bba2108 100644 --- a/core/modules/catalog/store/stock/actions.ts +++ b/core/modules/catalog/store/stock/actions.ts @@ -1,22 +1,26 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import i18n from '@vue-storefront/i18n' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import i18n from '@vue-storefront/i18n'; // requires cart module -import * as types from '@vue-storefront/core/modules/cart/store/mutation-types' -import RootState from '@vue-storefront/core/types/RootState' -import StockState from '../../types/StockState' -import rootStore from '@vue-storefront/core/store' -import { TaskQueue } from '@vue-storefront/core/lib/sync' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as types from '@vue-storefront/core/modules/cart/store/mutation-types'; +import RootState from '@vue-storefront/core/types/RootState'; +import StockState from '../../types/StockState'; +import rootStore from '@vue-storefront/core/store'; +import { TaskQueue } from '@vue-storefront/core/lib/sync'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { /** * Reset current configuration and selected variatnts */ - check (context, { product, qty = 1 }) { + check(context, { product, qty = 1 }) { return new Promise((resolve, reject) => { if (rootStore.state.config.stock.synchronize) { - TaskQueue.queue({ url: rootStore.state.config.stock.endpoint + '/check?sku=' + encodeURIComponent(product.sku), + TaskQueue.queue({ + url: + rootStore.state.config.stock.endpoint + + '/check?sku=' + + encodeURIComponent(product.sku), payload: { method: 'GET', headers: { 'Content-Type': 'application/json' }, @@ -24,68 +28,121 @@ const actions: ActionTree = { }, product_sku: product.sku, callback_event: 'store:stock/stockAfterCheck' - }).then((task:any) => { - resolve({ qty: product.stock ? product.stock.qty : 0, status: product.stock ? (product.stock.is_in_stock ? 'ok' : 'out_of_stock') : 'ok', onlineCheckTaskId: task.task_id }) // if online we can return ok because it will be verified anyway - }) + }).then((task: any) => { + resolve({ + qty: product.stock ? product.stock.qty : 0, + status: product.stock + ? product.stock.is_in_stock + ? 'ok' + : 'out_of_stock' + : 'ok', + onlineCheckTaskId: task.task_id + }); // if online we can return ok because it will be verified anyway + }); } else { - resolve({ qty: product.stock ? product.stock.qty : 0, status: product.stock ? (product.stock.is_in_stock ? 'ok' : 'out_of_stock') : 'volatile' }) // if not online, cannot check the source of true here + resolve({ + qty: product.stock ? product.stock.qty : 0, + status: product.stock + ? product.stock.is_in_stock + ? 'ok' + : 'out_of_stock' + : 'volatile' + }); // if not online, cannot check the source of true here } - }) + }); }, /** * Reset current configuration and selected variatnts */ - list (context, { skus }) { + list(context, { skus }) { return new Promise((resolve, reject) => { if (rootStore.state.config.stock.synchronize) { - TaskQueue.execute({ url: rootStore.state.config.stock.endpoint + '/list?skus=' + encodeURIComponent(skus.join(',')), + TaskQueue.execute({ + url: + rootStore.state.config.stock.endpoint + + '/list?skus=' + + encodeURIComponent(skus.join(',')), payload: { method: 'GET', headers: { 'Content-Type': 'application/json' }, mode: 'cors' }, skus: skus - }).then((task: any) => { - if (task.resultCode === 200) { - for (const si of task.result) { - context.state.cache[si.product_id] = { is_in_stock: si.is_in_stock, qty: si.qty, product_id: si.product_id } // TODO: should be moved to mutation - } - } - resolve(task) // if online we can return ok because it will be verified anyway - }).catch((err) => { - Logger.error(err, 'stock')() - resolve(null) }) + .then((task: any) => { + if (task.resultCode === 200) { + for (const si of task.result) { + context.state.cache[si.product_id] = { + is_in_stock: si.is_in_stock, + qty: si.qty, + product_id: si.product_id + }; // TODO: should be moved to mutation + } + } + resolve(task); // if online we can return ok because it will be verified anyway + }) + .catch(err => { + Logger.error(err, 'stock')(); + resolve(null); + }); } else { - resolve(null) // if not online, cannot check the source of true here + resolve(null); // if not online, cannot check the source of true here } - }) + }); }, - clearCache (context) { - context.state.cache = {} + clearCache(context) { + context.state.cache = {}; }, - stockAfterCheck (context, event) { + stockAfterCheck(context, event) { setTimeout(() => { // TODO: Move to cart module - rootStore.dispatch('cart/getItem', event.product_sku).then((cartItem) => { + rootStore.dispatch('cart/getItem', event.product_sku).then(cartItem => { if (cartItem && event.result.code !== 'ENOTFOUND') { if (!event.result.is_in_stock) { if (!rootStore.state.config.stock.allowOutOfStockInCart) { - Logger.log('Removing product from cart' + event.product_sku, 'stock')() - rootStore.commit('cart/' + types.CART_DEL_ITEM, { product: { sku: event.product_sku } }, {root: true}) + Logger.log( + 'Removing product from cart' + event.product_sku, + 'stock' + )(); + rootStore.commit( + 'cart/' + types.CART_DEL_ITEM, + { product: { sku: event.product_sku } }, + { root: true } + ); } else { - rootStore.dispatch('cart/updateItem', { product: { errors: { stock: i18n.t('Out of the stock!') }, sku: event.product_sku, is_in_stock: false } }) + rootStore.dispatch('cart/updateItem', { + product: { + errors: { stock: i18n.t('Out of the stock!') }, + sku: event.product_sku, + is_in_stock: false + } + }); } } else { - rootStore.dispatch('cart/updateItem', { product: { info: { stock: i18n.t('In stock!') }, sku: event.product_sku, is_in_stock: true } }) + rootStore.dispatch('cart/updateItem', { + product: { + info: { stock: i18n.t('In stock!') }, + sku: event.product_sku, + is_in_stock: true + } + }); } - Vue.prototype.$bus.$emit('cart-after-itemchanged', { item: cartItem }) + Vue.prototype.$bus.$emit('cart-after-itemchanged', { + item: cartItem + }); } - }) - Logger.debug('Stock quantity checked for ' + event.result.product_id + ', response time: ' + (event.transmited_at - event.created_at) + ' ms', 'stock')() - Logger.debug(event, 'stock')() - }, 500) + }); + Logger.debug( + 'Stock quantity checked for ' + + event.result.product_id + + ', response time: ' + + (event.transmited_at - event.created_at) + + ' ms', + 'stock' + )(); + Logger.debug(event, 'stock')(); + }, 500); } -} +}; -export default actions +export default actions; diff --git a/core/modules/catalog/store/stock/index.ts b/core/modules/catalog/store/stock/index.ts index b94bc7b841..584fb347ab 100644 --- a/core/modules/catalog/store/stock/index.ts +++ b/core/modules/catalog/store/stock/index.ts @@ -1,7 +1,7 @@ -import { Module } from 'vuex' -import actions from './actions' -import RootState from '@vue-storefront/core/types/RootState' -import StockState from '../../types/StockState' +import { Module } from 'vuex'; +import actions from './actions'; +import RootState from '@vue-storefront/core/types/RootState'; +import StockState from '../../types/StockState'; export const stockModule: Module = { namespaced: true, @@ -9,5 +9,4 @@ export const stockModule: Module = { state: { cache: {} } -} - +}; diff --git a/core/modules/catalog/store/tax/actions.ts b/core/modules/catalog/store/tax/actions.ts index c304cc6a11..c2ed2ba06a 100644 --- a/core/modules/catalog/store/tax/actions.ts +++ b/core/modules/catalog/store/tax/actions.ts @@ -1,32 +1,36 @@ -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import RootState from '@vue-storefront/core/types/RootState' -import TaxState from '../../types/TaxState' -import { Logger } from '@vue-storefront/core/lib/logger' +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import RootState from '@vue-storefront/core/types/RootState'; +import TaxState from '../../types/TaxState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { /** * Load the tax rules */ - list (context, { entityType = 'taxrule' }) { + list(context, { entityType = 'taxrule' }) { if (context.state.rules.length > 0) { - Logger.info('Tax rules served from local memory', 'tax')() + Logger.info('Tax rules served from local memory', 'tax')(); return new Promise((resolve, reject) => { - resolve({ items: context.state.rules }) - }) + resolve({ items: context.state.rules }); + }); } else { - const searchQuery = new SearchQuery() - return quickSearchByQuery({ query: searchQuery, entityType }).then((resp) => { - context.commit(types.TAX_UPDATE_RULES, resp) - return resp - }) + const searchQuery = new SearchQuery(); + return quickSearchByQuery({ query: searchQuery, entityType }).then( + resp => { + context.commit(types.TAX_UPDATE_RULES, resp); + return resp; + } + ); } }, - single (context, { productTaxClassId }) { - return context.state.rules.find((e) => { return e.product_tax_class_ids.indexOf(parseInt(productTaxClassId)) >= 0 }) + single(context, { productTaxClassId }) { + return context.state.rules.find(e => { + return e.product_tax_class_ids.indexOf(parseInt(productTaxClassId)) >= 0; + }); } -} +}; -export default actions +export default actions; diff --git a/core/modules/catalog/store/tax/index.ts b/core/modules/catalog/store/tax/index.ts index bbac489707..a64b9236df 100644 --- a/core/modules/catalog/store/tax/index.ts +++ b/core/modules/catalog/store/tax/index.ts @@ -1,8 +1,8 @@ -import { Module } from 'vuex' -import actions from './actions' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import TaxState from '../../types/TaxState' +import { Module } from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import TaxState from '../../types/TaxState'; export const taxModule: Module = { namespaced: true, @@ -11,4 +11,4 @@ export const taxModule: Module = { }, actions, mutations -} \ No newline at end of file +}; diff --git a/core/modules/catalog/store/tax/mutation-types.ts b/core/modules/catalog/store/tax/mutation-types.ts index a3d53fe2cc..594f5d6ad0 100644 --- a/core/modules/catalog/store/tax/mutation-types.ts +++ b/core/modules/catalog/store/tax/mutation-types.ts @@ -1,2 +1,2 @@ -export const SN_TAX = 'tax' -export const TAX_UPDATE_RULES = SN_TAX + '/UPDATE_RULES' \ No newline at end of file +export const SN_TAX = 'tax'; +export const TAX_UPDATE_RULES = SN_TAX + '/UPDATE_RULES'; diff --git a/core/modules/catalog/store/tax/mutations.ts b/core/modules/catalog/store/tax/mutations.ts index 78d0d8b4a1..6694b826da 100644 --- a/core/modules/catalog/store/tax/mutations.ts +++ b/core/modules/catalog/store/tax/mutations.ts @@ -1,21 +1,22 @@ -import Vue from 'vue' -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import { entityKeyName } from '@vue-storefront/core/store/lib/entities' -import TaxState from '../../types/TaxState' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import { entityKeyName } from '@vue-storefront/core/store/lib/entities'; +import TaxState from '../../types/TaxState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const mutations: MutationTree = { - [types.TAX_UPDATE_RULES] (state, taxClasses) { - const cache = Vue.prototype.$db.elasticCacheCollection - for (let tc of taxClasses.items) { // we store each product separately in cache to have offline acces for products/single method - const cacheKey = entityKeyName('tc', tc.id) - cache.setItem(cacheKey, tc).catch((err) => { - Logger.error('Cannot store cache for ' + cacheKey + ', ' + err)() - }) + [types.TAX_UPDATE_RULES](state, taxClasses) { + const cache = Vue.prototype.$db.elasticCacheCollection; + for (let tc of taxClasses.items) { + // we store each product separately in cache to have offline acces for products/single method + const cacheKey = entityKeyName('tc', tc.id); + cache.setItem(cacheKey, tc).catch(err => { + Logger.error('Cannot store cache for ' + cacheKey + ', ' + err)(); + }); } - state.rules = taxClasses.items // extract fields from ES _source + state.rules = taxClasses.items; // extract fields from ES _source } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/catalog/types/AttributeState.ts b/core/modules/catalog/types/AttributeState.ts index 8df8b3bdf3..1d1394548e 100644 --- a/core/modules/catalog/types/AttributeState.ts +++ b/core/modules/catalog/types/AttributeState.ts @@ -1,6 +1,6 @@ export default interface AttributeState { - list_by_code: any - list_by_id: any - labels: any - blacklist: Array + list_by_code: any; + list_by_id: any; + labels: any; + blacklist: Array; } diff --git a/core/modules/catalog/types/CategoryState.ts b/core/modules/catalog/types/CategoryState.ts index ba13ec9c6c..d0a59c5035 100644 --- a/core/modules/catalog/types/CategoryState.ts +++ b/core/modules/catalog/types/CategoryState.ts @@ -1,13 +1,13 @@ export default interface CategoryState { - list: any, - current: any, + list: any; + current: any; filters: { - available: any, - chosen: any - }, + available: any; + chosen: any; + }; breadcrumbs: { - routes: any - }, - current_product_query: any, - current_path: any + routes: any; + }; + current_product_query: any; + current_path: any; } diff --git a/core/modules/catalog/types/Product.ts b/core/modules/catalog/types/Product.ts index 236cb95cad..367a36787a 100644 --- a/core/modules/catalog/types/Product.ts +++ b/core/modules/catalog/types/Product.ts @@ -1,62 +1,62 @@ export default interface Product { - category: Array - category_ids: Array - climate: string - color: string - color_options: Array - configurable_children: Array - configurable_options: Array - custom_attributes: any - description: string - eco_collection: string - erin_recommends: string - errors: Object - final_price: number - gift_message_available: string - has_options: string - id: number - image: string - info: Object - is_configured: true - material: string - max_price: number - max_regular_price: number - media_gallery: Array - minimal_price: number - minimal_regular_price: number - msrp_display_actual_price_type: string - name: string - new: string - options: Array - parentSku: string - pattern: string - performance_fabric: string - price: number - priceInclTax: number - priceTax: number - product_links: Array - product_option: Object - regular_price: number - required_options: string - sale: string - sgn: string - size: string - size_options: Array - sku: string - slug: string - small_image: string - specialPriceInclTax: any - specialPriceTax: any - special_price: number - status: number - stock: Object - style_general: string - tax_class_id: string - thumbnail: string - tsk: number - type_id: string - url_key: string - visibility: number - _score: number - qty: number + category: Array; + category_ids: Array; + climate: string; + color: string; + color_options: Array; + configurable_children: Array; + configurable_options: Array; + custom_attributes: any; + description: string; + eco_collection: string; + erin_recommends: string; + errors: Object; + final_price: number; + gift_message_available: string; + has_options: string; + id: number; + image: string; + info: Object; + is_configured: true; + material: string; + max_price: number; + max_regular_price: number; + media_gallery: Array; + minimal_price: number; + minimal_regular_price: number; + msrp_display_actual_price_type: string; + name: string; + new: string; + options: Array; + parentSku: string; + pattern: string; + performance_fabric: string; + price: number; + priceInclTax: number; + priceTax: number; + product_links: Array; + product_option: Object; + regular_price: number; + required_options: string; + sale: string; + sgn: string; + size: string; + size_options: Array; + sku: string; + slug: string; + small_image: string; + specialPriceInclTax: any; + specialPriceTax: any; + special_price: number; + status: number; + stock: Object; + style_general: string; + tax_class_id: string; + thumbnail: string; + tsk: number; + type_id: string; + url_key: string; + visibility: number; + _score: number; + qty: number; } diff --git a/core/modules/catalog/types/ProductState.ts b/core/modules/catalog/types/ProductState.ts index c157dfdb32..c4a3694381 100644 --- a/core/modules/catalog/types/ProductState.ts +++ b/core/modules/catalog/types/ProductState.ts @@ -1,26 +1,26 @@ export interface PagedProductList { - start: number, - perPage: number, - items: any[] + start: number; + perPage: number; + items: any[]; } export default interface ProductState { breadcrumbs: { - routes: any[], - name: string - }, - current: any, - current_options: any, - current_configuration: any, - parent: any, - list: any[] | PagedProductList, - original: any, - related: any, - offlineImage: any, - current_custom_options: any, - current_bundle_options: any, - custom_options_validators: any, - productLoadStart: number, - productLoadPromise: Promise | null, - productGallery: any + routes: any[]; + name: string; + }; + current: any; + current_options: any; + current_configuration: any; + parent: any; + list: any[] | PagedProductList; + original: any; + related: any; + offlineImage: any; + current_custom_options: any; + current_bundle_options: any; + custom_options_validators: any; + productLoadStart: number; + productLoadPromise: Promise | null; + productGallery: any; } diff --git a/core/modules/catalog/types/StockState.ts b/core/modules/catalog/types/StockState.ts index e7b9333a0a..3f3d488c07 100644 --- a/core/modules/catalog/types/StockState.ts +++ b/core/modules/catalog/types/StockState.ts @@ -1,3 +1,3 @@ export default interface StockState { - cache: any + cache: any; } diff --git a/core/modules/catalog/types/TaxState.ts b/core/modules/catalog/types/TaxState.ts index 4b1210da4c..e865835b63 100644 --- a/core/modules/catalog/types/TaxState.ts +++ b/core/modules/catalog/types/TaxState.ts @@ -1,3 +1,3 @@ export default interface TaxState { - rules: any[] + rules: any[]; } diff --git a/core/modules/checkout/components/CartSummary.ts b/core/modules/checkout/components/CartSummary.ts index ed444a1a91..4ac6ee7399 100644 --- a/core/modules/checkout/components/CartSummary.ts +++ b/core/modules/checkout/components/CartSummary.ts @@ -1,5 +1,5 @@ -import { mapGetters } from 'vuex' -import Microcart from '@vue-storefront/core/compatibility/components/blocks/Microcart/Microcart' +import { mapGetters } from 'vuex'; +import Microcart from '@vue-storefront/core/compatibility/components/blocks/Microcart/Microcart'; export const CartSummary = { name: 'CartSummary', @@ -10,4 +10,4 @@ export const CartSummary = { isVirtualCart: 'cart/isVirtualCart' }) } -} +}; diff --git a/core/modules/checkout/components/OrderReview.ts b/core/modules/checkout/components/OrderReview.ts index 9d6ce4d919..4fed9cffa0 100644 --- a/core/modules/checkout/components/OrderReview.ts +++ b/core/modules/checkout/components/OrderReview.ts @@ -1,8 +1,8 @@ -import { mapGetters } from 'vuex' -import i18n from '@vue-storefront/i18n' -import { Logger } from '@vue-storefront/core/lib/logger' +import { mapGetters } from 'vuex'; +import i18n from '@vue-storefront/i18n'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export const OrderReview ={ +export const OrderReview = { name: 'OrderReview', props: { isActive: { @@ -10,13 +10,13 @@ export const OrderReview ={ required: true } }, - data () { + data() { return { isFilled: false, orderReview: { terms: false } - } + }; }, computed: { ...mapGetters({ @@ -24,41 +24,50 @@ export const OrderReview ={ }) }, methods: { - placeOrder () { + placeOrder() { if (this.$store.state.checkout.personalDetails.createAccount) { - this.register() + this.register(); } else { - this.$bus.$emit('checkout-before-placeOrder') + this.$bus.$emit('checkout-before-placeOrder'); } }, - register () { - this.$bus.$emit('notification-progress-start', i18n.t('Registering the account ...')) - this.$store.dispatch('user/register', { - email: this.$store.state.checkout.personalDetails.emailAddress, - password: this.$store.state.checkout.personalDetails.password, - firstname: this.$store.state.checkout.personalDetails.firstName, - lastname: this.$store.state.checkout.personalDetails.lastName - }).then((result) => { - this.$bus.$emit('notification-progress-stop') - if (result.code !== 200) { - this.onFailure(result) - // If error includes a word 'password', emit event that eventually focuses on a corresponding field - if (result.result.includes(i18n.t('password'))) { - this.$bus.$emit('checkout-after-validationError', 'password') - } - // If error includes a word 'mail', emit event that eventually focuses on a corresponding field - if (result.result.includes(i18n.t('email'))) { - this.$bus.$emit('checkout-after-validationError', 'email-address') + register() { + this.$bus.$emit( + 'notification-progress-start', + i18n.t('Registering the account ...') + ); + this.$store + .dispatch('user/register', { + email: this.$store.state.checkout.personalDetails.emailAddress, + password: this.$store.state.checkout.personalDetails.password, + firstname: this.$store.state.checkout.personalDetails.firstName, + lastname: this.$store.state.checkout.personalDetails.lastName + }) + .then(result => { + this.$bus.$emit('notification-progress-stop'); + if (result.code !== 200) { + this.onFailure(result); + // If error includes a word 'password', emit event that eventually focuses on a corresponding field + if (result.result.includes(i18n.t('password'))) { + this.$bus.$emit('checkout-after-validationError', 'password'); + } + // If error includes a word 'mail', emit event that eventually focuses on a corresponding field + if (result.result.includes(i18n.t('email'))) { + this.$bus.$emit( + 'checkout-after-validationError', + 'email-address' + ); + } + } else { + this.onSuccess(); + this.$bus.$emit('modal-hide', 'modal-signup'); + this.$bus.$emit('checkout-before-placeOrder', result.result.id); } - } else { - this.onSuccess() - this.$bus.$emit('modal-hide', 'modal-signup') - this.$bus.$emit('checkout-before-placeOrder', result.result.id) - } - }).catch(err => { - this.$bus.$emit('notification-progress-stop') - Logger.error(err, 'checkout')() - }) + }) + .catch(err => { + this.$bus.$emit('notification-progress-stop'); + Logger.error(err, 'checkout')(); + }); } } -} +}; diff --git a/core/modules/checkout/components/Payment.ts b/core/modules/checkout/components/Payment.ts index d0eccdd81b..25626ce40c 100644 --- a/core/modules/checkout/components/Payment.ts +++ b/core/modules/checkout/components/Payment.ts @@ -1,7 +1,7 @@ -import { mapState, mapGetters } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import toString from 'lodash-es/toString' -const Countries = require('@vue-storefront/i18n/resource/countries.json') +import { mapState, mapGetters } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import toString from 'lodash-es/toString'; +const Countries = require('@vue-storefront/i18n/resource/countries.json'); export const Payment = { name: 'Payment', @@ -11,7 +11,7 @@ export const Payment = { required: true } }, - data () { + data() { return { isFilled: false, countries: Countries, @@ -19,72 +19,78 @@ export const Payment = { generateInvoice: false, sendToShippingAddress: false, sendToBillingAddress: false - } + }; }, computed: { ...mapState({ currentUser: (state: RootState) => state.user.current, - shippingDetails: (state:RootState) => state.checkout.shippingDetails + shippingDetails: (state: RootState) => state.checkout.shippingDetails }), ...mapGetters({ paymentMethods: 'payment/paymentMethods', isVirtualCart: 'cart/isVirtualCart' }) }, - created () { - if (!this.payment.paymentMethod || this.notInMethods(this.payment.paymentMethod)) { - this.payment.paymentMethod = this.paymentMethods.length > 0 ? this.paymentMethods[0].code : 'cashondelivery' + created() { + if ( + !this.payment.paymentMethod || + this.notInMethods(this.payment.paymentMethod) + ) { + this.payment.paymentMethod = + this.paymentMethods.length > 0 + ? this.paymentMethods[0].code + : 'cashondelivery'; } }, - mounted () { + mounted() { if (this.payment.firstName) { - this.initializeBillingAddress() + this.initializeBillingAddress(); } else { if (this.payment.company) { - this.generateInvoice = true + this.generateInvoice = true; } } - this.changePaymentMethod() + this.changePaymentMethod(); }, watch: { shippingDetails: { - handler () { + handler() { if (this.sendToShippingAddress) { - this.copyShippingToBillingAddress() + this.copyShippingToBillingAddress(); } }, deep: true }, sendToShippingAddress: { - handler () { - this.useShippingAddress() + handler() { + this.useShippingAddress(); } } }, methods: { - sendDataToCheckout () { - this.$bus.$emit('checkout-after-paymentDetails', this.payment, this.$v) - this.isFilled = true + sendDataToCheckout() { + this.$bus.$emit('checkout-after-paymentDetails', this.payment, this.$v); + this.isFilled = true; }, - edit () { + edit() { if (this.isFilled) { - this.$bus.$emit('checkout-before-edit', 'payment') + this.$bus.$emit('checkout-before-edit', 'payment'); } }, - hasBillingData () { + hasBillingData() { if (this.currentUser) { if (this.currentUser.hasOwnProperty('default_billing')) { - return true + return true; } } - return false + return false; }, - initializeBillingAddress () { - let initialized = false + initializeBillingAddress() { + let initialized = false; if (this.currentUser) { if (this.currentUser.hasOwnProperty('default_billing')) { - let id = this.currentUser.default_billing - let addresses = this.currentUser.addresses + let id = this.currentUser.default_billing; + let addresses = this.currentUser.addresses; for (let i = 0; i < addresses.length; i++) { if (toString(addresses[i].id) === toString(id)) { this.payment = { @@ -92,7 +98,9 @@ export const Payment = { lastName: addresses[i].lastname, company: addresses[i].company, country: addresses[i].country_id, - state: addresses[i].region.region ? addresses[i].region.region : '', + state: addresses[i].region.region + ? addresses[i].region.region + : '', city: addresses[i].city, streetAddress: addresses[i].street[0], apartmentNumber: addresses[i].street[1], @@ -100,10 +108,10 @@ export const Payment = { taxId: addresses[i].vat_id, phoneNumber: addresses[i].telephone, paymentMethod: this.paymentMethods[0].code - } - this.generateInvoice = true - this.sendToBillingAddress = true - initialized = true + }; + this.generateInvoice = true; + this.sendToBillingAddress = true; + initialized = true; } } } @@ -122,21 +130,22 @@ export const Payment = { zipCode: '', phoneNumber: '', taxId: '', - paymentMethod: this.paymentMethods.length > 0 ? this.paymentMethods[0].code : '' - } + paymentMethod: + this.paymentMethods.length > 0 ? this.paymentMethods[0].code : '' + }; } }, - useShippingAddress () { + useShippingAddress() { if (this.sendToShippingAddress) { - this.copyShippingToBillingAddress() - this.sendToBillingAddress = false - this.generateInvoice = false + this.copyShippingToBillingAddress(); + this.sendToBillingAddress = false; + this.generateInvoice = false; } else { - this.payment = this.$store.state.checkout.paymentDetails - this.generateInvoice = false + this.payment = this.$store.state.checkout.paymentDetails; + this.generateInvoice = false; } }, - copyShippingToBillingAddress () { + copyShippingToBillingAddress() { this.payment = { firstName: this.shippingDetails.firstName, lastName: this.shippingDetails.lastName, @@ -147,13 +156,14 @@ export const Payment = { apartmentNumber: this.shippingDetails.apartmentNumber, zipCode: this.shippingDetails.zipCode, phoneNumber: this.shippingDetails.phoneNumber, - paymentMethod: this.paymentMethods.length > 0 ? this.paymentMethods[0].code : '' - } + paymentMethod: + this.paymentMethods.length > 0 ? this.paymentMethods[0].code : '' + }; }, - useBillingAddress () { + useBillingAddress() { if (this.sendToBillingAddress) { - let id = this.currentUser.default_billing - let addresses = this.currentUser.addresses + let id = this.currentUser.default_billing; + let addresses = this.currentUser.addresses; for (let i = 0; i < addresses.length; i++) { if (toString(addresses[i].id) === toString(id)) { this.payment = { @@ -161,65 +171,79 @@ export const Payment = { lastName: addresses[i].lastname, company: addresses[i].company, country: addresses[i].country_id, - state: addresses[i].region.region ? addresses[i].region.region : '', + state: addresses[i].region.region + ? addresses[i].region.region + : '', city: addresses[i].city, streetAddress: addresses[i].street[0], apartmentNumber: addresses[i].street[1], zipCode: addresses[i].postcode, taxId: addresses[i].vat_id, phoneNumber: addresses[i].telephone, - paymentMethod: this.paymentMethods.length > 0 ? this.paymentMethods[0].code : '' - } - this.generateInvoice = true + paymentMethod: + this.paymentMethods.length > 0 + ? this.paymentMethods[0].code + : '' + }; + this.generateInvoice = true; } } - this.sendToShippingAddress = false + this.sendToShippingAddress = false; } else { - this.payment = this.$store.state.checkout.paymentDetails - this.generateInvoice = false + this.payment = this.$store.state.checkout.paymentDetails; + this.generateInvoice = false; } }, - useGenerateInvoice () { + useGenerateInvoice() { if (!this.generateInvoice) { - this.payment.company = '' - this.payment.taxId = '' + this.payment.company = ''; + this.payment.taxId = ''; } }, - getCountryName () { + getCountryName() { for (let i = 0; i < this.countries.length; i++) { if (this.countries[i].code === this.payment.country) { - return this.countries[i].name + return this.countries[i].name; } } - return '' + return ''; }, - getPaymentMethod () { + getPaymentMethod() { for (let i = 0; i < this.paymentMethods.length; i++) { if (this.paymentMethods[i].code === this.payment.paymentMethod) { return { - title: this.paymentMethods[i].title ? this.paymentMethods[i].title : this.paymentMethods[i].name - } + title: this.paymentMethods[i].title + ? this.paymentMethods[i].title + : this.paymentMethods[i].name + }; } } return { name: '' - } + }; }, - notInMethods (method) { - let availableMethods = this.paymentMethods + notInMethods(method) { + let availableMethods = this.paymentMethods; if (availableMethods.find(item => item.code === method)) { - return false + return false; } - return true + return true; }, - changePaymentMethod () { + changePaymentMethod() { // reset the additional payment method component container if exists. - if (document.getElementById('checkout-order-review-additional-container')) { - document.getElementById('checkout-order-review-additional-container').innerHTML = '
 
' // reset + if ( + document.getElementById('checkout-order-review-additional-container') + ) { + document.getElementById( + 'checkout-order-review-additional-container' + ).innerHTML = '
 
'; // reset } // Let anyone listening know that we've changed payment method, usually a payment extension. - this.$bus.$emit('checkout-payment-method-changed', this.payment.paymentMethod) + this.$bus.$emit( + 'checkout-payment-method-changed', + this.payment.paymentMethod + ); } } -} +}; diff --git a/core/modules/checkout/components/PersonalDetails.ts b/core/modules/checkout/components/PersonalDetails.ts index d5358f8a0e..18fdfc7bc4 100644 --- a/core/modules/checkout/components/PersonalDetails.ts +++ b/core/modules/checkout/components/PersonalDetails.ts @@ -1,5 +1,5 @@ -import { mapState, mapGetters } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' +import { mapState, mapGetters } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; export const PersonalDetails = { name: 'PersonalDetails', @@ -13,7 +13,7 @@ export const PersonalDetails = { required: false } }, - data () { + data() { return { isFilled: false, personalDetails: this.$store.state.checkout.personalDetails, @@ -22,7 +22,7 @@ export const PersonalDetails = { password: '', rPassword: '', isValidationError: false - } + }; }, computed: { ...mapState({ @@ -33,48 +33,52 @@ export const PersonalDetails = { }) }, methods: { - onLoggedIn (receivedData) { + onLoggedIn(receivedData) { this.personalDetails = { firstName: receivedData.firstname, lastName: receivedData.lastname, emailAddress: receivedData.email - } + }; }, - sendDataToCheckout () { + sendDataToCheckout() { if (this.createAccount) { - this.personalDetails.password = this.password - this.personalDetails.createAccount = true + this.personalDetails.password = this.password; + this.personalDetails.createAccount = true; } else { - this.personalDetails.createAccount = false + this.personalDetails.createAccount = false; } - this.$bus.$emit('checkout-after-personalDetails', this.personalDetails, this.$v) - this.isFilled = true - this.isValidationError = false + this.$bus.$emit( + 'checkout-after-personalDetails', + this.personalDetails, + this.$v + ); + this.isFilled = true; + this.isValidationError = false; }, - edit () { + edit() { if (this.isFilled) { - this.$bus.$emit('checkout-before-edit', 'personalDetails') + this.$bus.$emit('checkout-before-edit', 'personalDetails'); } }, - gotoAccount () { - this.$bus.$emit('modal-show', 'modal-signup') + gotoAccount() { + this.$bus.$emit('modal-show', 'modal-signup'); } }, - updated () { + updated() { // Perform focusing on a field, name of which is passed through 'focusedField' prop if (this.focusedField && !this.isValidationError) { if (this.focusedField === 'password') { - this.isValidationError = true - this.password = '' - this.rPassword = '' - this.$refs['password'].setFocus('password') + this.isValidationError = true; + this.password = ''; + this.rPassword = ''; + this.$refs['password'].setFocus('password'); } } }, - beforeMount () { - this.$bus.$on('user-after-loggedin', this.onLoggedIn) + beforeMount() { + this.$bus.$on('user-after-loggedin', this.onLoggedIn); }, - destroyed () { - this.$bus.$off('user-after-loggedin', this.onLoggedIn) + destroyed() { + this.$bus.$off('user-after-loggedin', this.onLoggedIn); } -} +}; diff --git a/core/modules/checkout/components/Product.ts b/core/modules/checkout/components/Product.ts index 08c0292e14..2e4fbdab59 100644 --- a/core/modules/checkout/components/Product.ts +++ b/core/modules/checkout/components/Product.ts @@ -7,21 +7,21 @@ export const Product = { } }, computed: { - thumbnail () { - return this.getThumbnail(this.product.image, 150, 150) + thumbnail() { + return this.getThumbnail(this.product.image, 150, 150); } }, methods: { - onProductChanged (event) { + onProductChanged(event) { if (event.item.sku === this.product.sku) { - this.$forceUpdate() + this.$forceUpdate(); } } }, - beforeMount () { - this.$bus.$on('cart-after-itemchanged', this.onProductChanged) + beforeMount() { + this.$bus.$on('cart-after-itemchanged', this.onProductChanged); }, - beforeDestroy () { - this.$bus.$off('cart-after-itemchanged', this.onProductChanged) + beforeDestroy() { + this.$bus.$off('cart-after-itemchanged', this.onProductChanged); } -} +}; diff --git a/core/modules/checkout/components/Shipping.ts b/core/modules/checkout/components/Shipping.ts index 30ca34a8ab..f798a69dec 100644 --- a/core/modules/checkout/components/Shipping.ts +++ b/core/modules/checkout/components/Shipping.ts @@ -1,7 +1,7 @@ -import { mapState, mapGetters } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -const Countries = require('@vue-storefront/i18n/resource/countries.json') -import toString from 'lodash-es/toString' +import { mapState, mapGetters } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +const Countries = require('@vue-storefront/i18n/resource/countries.json'); +import toString from 'lodash-es/toString'; export const Shipping = { name: 'Shipping', @@ -11,15 +11,21 @@ export const Shipping = { required: true } }, - beforeDestroy () { - this.$bus.$off('checkout-after-personalDetails', this.onAfterPersonalDetails) - this.$bus.$off('checkout-after-shippingset', this.onAfterShippingSet) + beforeDestroy() { + this.$bus.$off( + 'checkout-after-personalDetails', + this.onAfterPersonalDetails + ); + this.$bus.$off('checkout-after-shippingset', this.onAfterShippingSet); }, - beforeMount () { - this.$bus.$on('checkout-after-personalDetails', this.onAfterPersonalDetails) - this.$bus.$on('checkout-after-shippingset', this.onAfterShippingSet) + beforeMount() { + this.$bus.$on( + 'checkout-after-personalDetails', + this.onAfterPersonalDetails + ); + this.$bus.$on('checkout-after-shippingset', this.onAfterShippingSet); }, - data () { + data() { return { isFilled: false, countries: Countries, @@ -35,7 +41,7 @@ export const Shipping = { postcode: '', telephone: '' } - } + }; }, computed: { ...mapState({ @@ -44,65 +50,80 @@ export const Shipping = { ...mapGetters({ shippingMethods: 'shipping/shippingMethods' }), - checkoutShippingDetails () { - return this.$store.state.checkout.shippingDetails + checkoutShippingDetails() { + return this.$store.state.checkout.shippingDetails; }, - paymentMethod () { - return this.$store.state.payment.methods + paymentMethod() { + return this.$store.state.payment.methods; } }, - mounted () { - if (!this.shipping.shippingMethod || this.notInMethods(this.shipping.shippingMethod)) { - let shipping = this.shippingMethods.find(item => item.default) - if (!shipping && this.shippingMethods && this.shippingMethods.length > 0) { - shipping = this.shippingMethods[0] + mounted() { + if ( + !this.shipping.shippingMethod || + this.notInMethods(this.shipping.shippingMethod) + ) { + let shipping = this.shippingMethods.find(item => item.default); + if ( + !shipping && + this.shippingMethods && + this.shippingMethods.length > 0 + ) { + shipping = this.shippingMethods[0]; } - this.shipping.shippingMethod = shipping.method_code - this.shipping.shippingCarrier = shipping.carrier_code + this.shipping.shippingMethod = shipping.method_code; + this.shipping.shippingCarrier = shipping.carrier_code; } }, methods: { - onAfterShippingSet (receivedData) { - this.shipping = receivedData - this.isFilled = true + onAfterShippingSet(receivedData) { + this.shipping = receivedData; + this.isFilled = true; }, - onAfterPersonalDetails (receivedData) { + onAfterPersonalDetails(receivedData) { if (!this.isFilled) { - this.$store.dispatch('checkout/updatePropValue', ['firstName', receivedData.firstName]) - this.$store.dispatch('checkout/updatePropValue', ['lastName', receivedData.lastName]) + this.$store.dispatch('checkout/updatePropValue', [ + 'firstName', + receivedData.firstName + ]); + this.$store.dispatch('checkout/updatePropValue', [ + 'lastName', + receivedData.lastName + ]); } }, - sendDataToCheckout () { - this.$bus.$emit('checkout-after-shippingDetails', this.shipping, this.$v) - this.isFilled = true + sendDataToCheckout() { + this.$bus.$emit('checkout-after-shippingDetails', this.shipping, this.$v); + this.isFilled = true; }, - edit () { + edit() { if (this.isFilled) { - this.$bus.$emit('checkout-before-edit', 'shipping') + this.$bus.$emit('checkout-before-edit', 'shipping'); } }, - hasShippingDetails () { + hasShippingDetails() { if (this.currentUser) { if (this.currentUser.hasOwnProperty('default_shipping')) { - let id = this.currentUser.default_shipping - let addresses = this.currentUser.addresses + let id = this.currentUser.default_shipping; + let addresses = this.currentUser.addresses; for (let i = 0; i < addresses.length; i++) { if (toString(addresses[i].id) === toString(id)) { - this.myAddressDetails = addresses[i] - return true + this.myAddressDetails = addresses[i]; + return true; } } } } - return false + return false; }, - useMyAddress () { + useMyAddress() { if (this.shipToMyAddress) { this.shipping = { firstName: this.myAddressDetails.firstname, lastName: this.myAddressDetails.lastname, country: this.myAddressDetails.country_id, - state: this.myAddressDetails.region.region ? this.myAddressDetails.region.region : '', + state: this.myAddressDetails.region.region + ? this.myAddressDetails.region.region + : '', city: this.myAddressDetails.city, streetAddress: this.myAddressDetails.street[0], apartmentNumber: this.myAddressDetails.street[1], @@ -110,59 +131,63 @@ export const Shipping = { phoneNumber: this.myAddressDetails.telephone, shippingMethod: this.checkoutShippingDetails.shippingMethod, shippingCarrier: this.checkoutShippingDetails.shippingCarrier - } + }; } else { - this.shipping = this.checkoutShippingDetails + this.shipping = this.checkoutShippingDetails; } - this.changeCountry() + this.changeCountry(); }, - getShippingMethod () { + getShippingMethod() { for (let i = 0; i < this.shippingMethods.length; i++) { - if (this.shippingMethods[i].method_code === this.shipping.shippingMethod) { + if ( + this.shippingMethods[i].method_code === this.shipping.shippingMethod + ) { return { method_title: this.shippingMethods[i].method_title, amount: this.shippingMethods[i].amount - } + }; } } return { method_title: '', amount: '' - } + }; }, - getCountryName () { + getCountryName() { for (let i = 0; i < this.countries.length; i++) { if (this.countries[i].code === this.shipping.country) { - return this.countries[i].name + return this.countries[i].name; } } - return '' + return ''; }, - changeCountry () { - this.$bus.$emit('checkout-before-shippingMethods', this.shipping.country) + changeCountry() { + this.$bus.$emit('checkout-before-shippingMethods', this.shipping.country); }, - getCurrentShippingMethod () { - let shippingCode = this.shipping.shippingMethod - let currentMethod = this.shippingMethods ? this.shippingMethods.find(item => item.method_code === shippingCode) : {} - return currentMethod + getCurrentShippingMethod() { + let shippingCode = this.shipping.shippingMethod; + let currentMethod = this.shippingMethods + ? this.shippingMethods.find(item => item.method_code === shippingCode) + : {}; + return currentMethod; }, - changeShippingMethod () { - let currentShippingMethod = this.getCurrentShippingMethod() + changeShippingMethod() { + let currentShippingMethod = this.getCurrentShippingMethod(); if (currentShippingMethod) { this.$bus.$emit('checkout-after-shippingMethodChanged', { country: this.shipping.country, method_code: currentShippingMethod.method_code, carrier_code: currentShippingMethod.carrier_code, payment_method: this.paymentMethod[0].code - }) + }); } }, - notInMethods (method) { - let availableMethods = this.shippingMethods + notInMethods(method) { + let availableMethods = this.shippingMethods; if (availableMethods.find(item => item.method_code === method)) { - return false + return false; } - return true + return true; } } -} +}; diff --git a/core/modules/checkout/hooks/afterRegistration.ts b/core/modules/checkout/hooks/afterRegistration.ts index caf81963e2..d713c1d2a2 100644 --- a/core/modules/checkout/hooks/afterRegistration.ts +++ b/core/modules/checkout/hooks/afterRegistration.ts @@ -1,31 +1,31 @@ -import * as types from './../store/checkout/mutation-types' +import * as types from './../store/checkout/mutation-types'; export function afterRegistration({ Vue, config, store, isServer }) { store.subscribe((mutation, state) => { - const type = mutation.type + const type = mutation.type; - if ( - type.endsWith(types.CHECKOUT_SAVE_PERSONAL_DETAILS) - ) { - Vue.prototype.$db.checkoutFieldsCollection.setItem('personal-details', state.checkout.personalDetails).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + if (type.endsWith(types.CHECKOUT_SAVE_PERSONAL_DETAILS)) { + Vue.prototype.$db.checkoutFieldsCollection + .setItem('personal-details', state.checkout.personalDetails) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache } - if ( - type.endsWith(types.CHECKOUT_SAVE_SHIPPING_DETAILS) - ) { - Vue.prototype.$db.checkoutFieldsCollection.setItem('shipping-details', state.checkout.shippingDetails).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + if (type.endsWith(types.CHECKOUT_SAVE_SHIPPING_DETAILS)) { + Vue.prototype.$db.checkoutFieldsCollection + .setItem('shipping-details', state.checkout.shippingDetails) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache } - if ( - type.endsWith(types.CHECKOUT_SAVE_PAYMENT_DETAILS) - ) { - Vue.prototype.$db.checkoutFieldsCollection.setItem('payment-details', state.checkout.paymentDetails).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + if (type.endsWith(types.CHECKOUT_SAVE_PAYMENT_DETAILS)) { + Vue.prototype.$db.checkoutFieldsCollection + .setItem('payment-details', state.checkout.paymentDetails) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache } - }) -} \ No newline at end of file + }); +} diff --git a/core/modules/checkout/hooks/beforeRegistration.ts b/core/modules/checkout/hooks/beforeRegistration.ts index d446daf6be..ce9d952f9a 100644 --- a/core/modules/checkout/hooks/beforeRegistration.ts +++ b/core/modules/checkout/hooks/beforeRegistration.ts @@ -1,14 +1,17 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.checkoutFieldsCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'checkoutFieldValues', - driver: localForage[config.localForage.defaultDrivers['checkoutFieldValues']] - })) -} \ No newline at end of file + Vue.prototype.$db.checkoutFieldsCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'checkoutFieldValues', + driver: + localForage[config.localForage.defaultDrivers['checkoutFieldValues']] + }) + ); +} diff --git a/core/modules/checkout/index.ts b/core/modules/checkout/index.ts index 3897c292cb..d30131d091 100644 --- a/core/modules/checkout/index.ts +++ b/core/modules/checkout/index.ts @@ -1,18 +1,20 @@ -import { checkoutModule } from './store/checkout' -import { paymentModule } from './store/payment' -import { shippingModule } from './store/shipping' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' -import { createModule } from '@vue-storefront/core/lib/module' +import { checkoutModule } from './store/checkout'; +import { paymentModule } from './store/payment'; +import { shippingModule } from './store/shipping'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; +import { createModule } from '@vue-storefront/core/lib/module'; -export const KEY = 'checkout' +export const KEY = 'checkout'; export const Checkout = createModule({ key: KEY, - store: { modules: [ - { key: 'shipping', module: shippingModule }, - { key: 'payment', module: paymentModule }, - { key: 'checkout', module: checkoutModule }, - ] }, + store: { + modules: [ + { key: 'shipping', module: shippingModule }, + { key: 'payment', module: paymentModule }, + { key: 'checkout', module: checkoutModule } + ] + }, beforeRegistration, afterRegistration -}) +}); diff --git a/core/modules/checkout/store/checkout/actions.ts b/core/modules/checkout/store/checkout/actions.ts index cbbbbcb1b1..2d8a683b04 100644 --- a/core/modules/checkout/store/checkout/actions.ts +++ b/core/modules/checkout/store/checkout/actions.ts @@ -1,10 +1,10 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import i18n from '@vue-storefront/i18n' -import RootState from '@vue-storefront/core/types/RootState' -import CheckoutState from '../../types/CheckoutState' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import i18n from '@vue-storefront/i18n'; +import RootState from '@vue-storefront/core/types/RootState'; +import CheckoutState from '../../types/CheckoutState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { /** @@ -12,67 +12,89 @@ const actions: ActionTree = { * @param {Object} commit method * @param {Object} order order data to be send */ - async placeOrder ({ state, commit, dispatch }, { order }) { + async placeOrder({ state, commit, dispatch }, { order }) { try { - const result = await dispatch('order/placeOrder', order, {root: true}) + const result = await dispatch('order/placeOrder', order, { root: true }); if (!result.resultCode || result.resultCode === 200) { - Vue.prototype.$db.usersCollection.setItem('last-cart-bypass-ts', new Date().getTime()) - dispatch('cart/clear', {}, {root: true}) + Vue.prototype.$db.usersCollection.setItem( + 'last-cart-bypass-ts', + new Date().getTime() + ); + dispatch('cart/clear', {}, { root: true }); if (state.personalDetails.createAccount) { - commit(types.CHECKOUT_DROP_PASSWORD) + commit(types.CHECKOUT_DROP_PASSWORD); } } } catch (e) { if (e.name === 'ValidationError') { - Logger.error('Internal validation error; Order entity is not compliant with the schema' + e.messages, 'checkout')() - dispatch('notification/spawnNotification', { - type: 'error', - message: i18n.t('Internal validation error. Please check if all required fields are filled in. Please contact us on contributors@vuestorefront.io'), - action1: { label: i18n.t('OK') } - }, {root: true}) + Logger.error( + 'Internal validation error; Order entity is not compliant with the schema' + + e.messages, + 'checkout' + )(); + dispatch( + 'notification/spawnNotification', + { + type: 'error', + message: i18n.t( + 'Internal validation error. Please check if all required fields are filled in. Please contact us on contributors@vuestorefront.io' + ), + action1: { label: i18n.t('OK') } + }, + { root: true } + ); } else { - Logger.error(e, 'checkout')() + Logger.error(e, 'checkout')(); } } }, - savePersonalDetails ({ commit }, personalDetails) { + savePersonalDetails({ commit }, personalDetails) { // todo: create and move perdonal details vuex - commit(types.CHECKOUT_SAVE_PERSONAL_DETAILS, personalDetails) + commit(types.CHECKOUT_SAVE_PERSONAL_DETAILS, personalDetails); }, - saveShippingDetails ({ commit }, shippingDetails) { + saveShippingDetails({ commit }, shippingDetails) { // todo: move to shipping vuex - commit(types.CHECKOUT_SAVE_SHIPPING_DETAILS, shippingDetails) + commit(types.CHECKOUT_SAVE_SHIPPING_DETAILS, shippingDetails); }, - savePaymentDetails ({ commit }, paymentDetails) { + savePaymentDetails({ commit }, paymentDetails) { // todo: move to payment vuex - commit(types.CHECKOUT_SAVE_PAYMENT_DETAILS, paymentDetails) + commit(types.CHECKOUT_SAVE_PAYMENT_DETAILS, paymentDetails); }, - load ({ commit }) { - Vue.prototype.$db.checkoutFieldsCollection.getItem('personal-details', (err, details) => { - if (err) throw new Error(err) - if (details) { - commit(types.CHECKOUT_LOAD_PERSONAL_DETAILS, details) + load({ commit }) { + Vue.prototype.$db.checkoutFieldsCollection.getItem( + 'personal-details', + (err, details) => { + if (err) throw new Error(err); + if (details) { + commit(types.CHECKOUT_LOAD_PERSONAL_DETAILS, details); + } } - }) - Vue.prototype.$db.checkoutFieldsCollection.getItem('shipping-details', (err, details) => { - if (err) throw new Error(err) - if (details) { - commit(types.CHECKOUT_LOAD_SHIPPING_DETAILS, details) + ); + Vue.prototype.$db.checkoutFieldsCollection.getItem( + 'shipping-details', + (err, details) => { + if (err) throw new Error(err); + if (details) { + commit(types.CHECKOUT_LOAD_SHIPPING_DETAILS, details); + } } - }) - Vue.prototype.$db.checkoutFieldsCollection.getItem('payment-details', (err, details) => { - if (err) throw new Error(err) - if (details) { - commit(types.CHECKOUT_LOAD_PAYMENT_DETAILS, details) + ); + Vue.prototype.$db.checkoutFieldsCollection.getItem( + 'payment-details', + (err, details) => { + if (err) throw new Error(err); + if (details) { + commit(types.CHECKOUT_LOAD_PAYMENT_DETAILS, details); + } } - }) + ); }, - updatePropValue ({ commit }, payload) { - commit(types.CHECKOUT_UPDATE_PROP_VALUE, payload) + updatePropValue({ commit }, payload) { + commit(types.CHECKOUT_UPDATE_PROP_VALUE, payload); }, - setThankYouPage ({ commit }, payload) { - commit(types.CHECKOUT_SET_THANKYOU, payload) + setThankYouPage({ commit }, payload) { + commit(types.CHECKOUT_SET_THANKYOU, payload); } -} +}; -export default actions +export default actions; diff --git a/core/modules/checkout/store/checkout/getters.ts b/core/modules/checkout/store/checkout/getters.ts index 993819c590..16e5863b7e 100644 --- a/core/modules/checkout/store/checkout/getters.ts +++ b/core/modules/checkout/store/checkout/getters.ts @@ -1,9 +1,9 @@ -import { GetterTree } from 'vuex' -import CheckoutState from '../../types/CheckoutState' -import RootState from '@vue-storefront/core/types/RootState' +import { GetterTree } from 'vuex'; +import CheckoutState from '../../types/CheckoutState'; +import RootState from '@vue-storefront/core/types/RootState'; const getters: GetterTree = { isThankYouPage: state => state.isThankYouPage -} +}; -export default getters +export default getters; diff --git a/core/modules/checkout/store/checkout/index.ts b/core/modules/checkout/store/checkout/index.ts index 0bad1b5550..8c26c68592 100644 --- a/core/modules/checkout/store/checkout/index.ts +++ b/core/modules/checkout/store/checkout/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import CheckoutState from '../../types/CheckoutState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import CheckoutState from '../../types/CheckoutState'; export const checkoutModule: Module = { namespaced: true, @@ -50,4 +50,4 @@ export const checkoutModule: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/checkout/store/checkout/mutation-types.ts b/core/modules/checkout/store/checkout/mutation-types.ts index 73984eb334..856268103d 100644 --- a/core/modules/checkout/store/checkout/mutation-types.ts +++ b/core/modules/checkout/store/checkout/mutation-types.ts @@ -1,11 +1,17 @@ -export const SN_CHECKOUT = 'checkout' -export const CHECKOUT_PLACE_ORDER = SN_CHECKOUT + '/PLACE_ORDER' -export const CHECKOUT_SAVE_PERSONAL_DETAILS = SN_CHECKOUT + '/SAVE_PERSONAL_DETAILS' -export const CHECKOUT_SAVE_SHIPPING_DETAILS = SN_CHECKOUT + '/SAVE_SHIPPING_DETAILS' -export const CHECKOUT_SAVE_PAYMENT_DETAILS = SN_CHECKOUT + '/SAVE_PAYMENT_DETAILS' -export const CHECKOUT_LOAD_PERSONAL_DETAILS = SN_CHECKOUT + '/LOAD_PERSONAL_DETAILS' -export const CHECKOUT_LOAD_SHIPPING_DETAILS = SN_CHECKOUT + '/LOAD_SHIPPING_DETAILS' -export const CHECKOUT_LOAD_PAYMENT_DETAILS = SN_CHECKOUT + '/LOAD_PAYMENT_DETAILS' -export const CHECKOUT_UPDATE_PROP_VALUE = SN_CHECKOUT + '/UPDATE_PROP_VALUE' -export const CHECKOUT_DROP_PASSWORD = SN_CHECKOUT + '/DROP_PASSWORD' -export const CHECKOUT_SET_THANKYOU = SN_CHECKOUT + '/SET_THANKYOU' \ No newline at end of file +export const SN_CHECKOUT = 'checkout'; +export const CHECKOUT_PLACE_ORDER = SN_CHECKOUT + '/PLACE_ORDER'; +export const CHECKOUT_SAVE_PERSONAL_DETAILS = + SN_CHECKOUT + '/SAVE_PERSONAL_DETAILS'; +export const CHECKOUT_SAVE_SHIPPING_DETAILS = + SN_CHECKOUT + '/SAVE_SHIPPING_DETAILS'; +export const CHECKOUT_SAVE_PAYMENT_DETAILS = + SN_CHECKOUT + '/SAVE_PAYMENT_DETAILS'; +export const CHECKOUT_LOAD_PERSONAL_DETAILS = + SN_CHECKOUT + '/LOAD_PERSONAL_DETAILS'; +export const CHECKOUT_LOAD_SHIPPING_DETAILS = + SN_CHECKOUT + '/LOAD_SHIPPING_DETAILS'; +export const CHECKOUT_LOAD_PAYMENT_DETAILS = + SN_CHECKOUT + '/LOAD_PAYMENT_DETAILS'; +export const CHECKOUT_UPDATE_PROP_VALUE = SN_CHECKOUT + '/UPDATE_PROP_VALUE'; +export const CHECKOUT_DROP_PASSWORD = SN_CHECKOUT + '/DROP_PASSWORD'; +export const CHECKOUT_SET_THANKYOU = SN_CHECKOUT + '/SET_THANKYOU'; diff --git a/core/modules/checkout/store/checkout/mutations.ts b/core/modules/checkout/store/checkout/mutations.ts index 1d80d30862..447c2058a7 100644 --- a/core/modules/checkout/store/checkout/mutations.ts +++ b/core/modules/checkout/store/checkout/mutations.ts @@ -1,44 +1,44 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import CheckoutState from '../../types/CheckoutState' -import { ORDER_PLACE_ORDER } from '@vue-storefront/core/modules/order/store/mutation-types' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import CheckoutState from '../../types/CheckoutState'; +import { ORDER_PLACE_ORDER } from '@vue-storefront/core/modules/order/store/mutation-types'; const mutations: MutationTree = { /** * Setup current order object * @param {Object} order Object */ - [ORDER_PLACE_ORDER] (state, order) { - state.order = order + [ORDER_PLACE_ORDER](state, order) { + state.order = order; }, - [types.CHECKOUT_SAVE_PERSONAL_DETAILS] (state, personalDetails) { - state.personalDetails = personalDetails + [types.CHECKOUT_SAVE_PERSONAL_DETAILS](state, personalDetails) { + state.personalDetails = personalDetails; }, - [types.CHECKOUT_SAVE_SHIPPING_DETAILS] (state, shippingDetails) { - state.shippingDetails = shippingDetails + [types.CHECKOUT_SAVE_SHIPPING_DETAILS](state, shippingDetails) { + state.shippingDetails = shippingDetails; }, - [types.CHECKOUT_SAVE_PAYMENT_DETAILS] (state, paymentDetails) { - state.paymentDetails = paymentDetails + [types.CHECKOUT_SAVE_PAYMENT_DETAILS](state, paymentDetails) { + state.paymentDetails = paymentDetails; }, - [types.CHECKOUT_LOAD_PERSONAL_DETAILS] (state, storedPersonalDetails) { - state.personalDetails = storedPersonalDetails + [types.CHECKOUT_LOAD_PERSONAL_DETAILS](state, storedPersonalDetails) { + state.personalDetails = storedPersonalDetails; }, - [types.CHECKOUT_LOAD_SHIPPING_DETAILS] (state, storedShippingDetails) { - state.shippingDetails = storedShippingDetails + [types.CHECKOUT_LOAD_SHIPPING_DETAILS](state, storedShippingDetails) { + state.shippingDetails = storedShippingDetails; }, - [types.CHECKOUT_LOAD_PAYMENT_DETAILS] (state, storedPaymentDetails) { - state.paymentDetails = storedPaymentDetails + [types.CHECKOUT_LOAD_PAYMENT_DETAILS](state, storedPaymentDetails) { + state.paymentDetails = storedPaymentDetails; }, - [types.CHECKOUT_UPDATE_PROP_VALUE] (state, payload) { - state.shippingDetails[payload[0]] = payload[1] + [types.CHECKOUT_UPDATE_PROP_VALUE](state, payload) { + state.shippingDetails[payload[0]] = payload[1]; }, - [types.CHECKOUT_DROP_PASSWORD] (state) { - state.personalDetails.password = '' - state.personalDetails.createAccount = false + [types.CHECKOUT_DROP_PASSWORD](state) { + state.personalDetails.password = ''; + state.personalDetails.createAccount = false; }, - [types.CHECKOUT_SET_THANKYOU] (state, payload) { - state.isThankYouPage = payload + [types.CHECKOUT_SET_THANKYOU](state, payload) { + state.isThankYouPage = payload; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/checkout/store/payment/index.ts b/core/modules/checkout/store/payment/index.ts index c94ec3a95c..57aa9b0211 100644 --- a/core/modules/checkout/store/payment/index.ts +++ b/core/modules/checkout/store/payment/index.ts @@ -1,35 +1,41 @@ -import { Module } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import PaymentState from '../../types/PaymentState' -import rootStore from '@vue-storefront/core/store' +import { Module } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import PaymentState from '../../types/PaymentState'; +import rootStore from '@vue-storefront/core/store'; export const paymentModule: Module = { namespaced: true, state: { - methods: [{"code":"cashondelivery","title":"Cash On Delivery","is_server_method":false}] + methods: [ + { + code: 'cashondelivery', + title: 'Cash On Delivery', + is_server_method: false + } + ] }, mutations: { - addMethod (state, paymentMethod) { - state.methods.push(paymentMethod) + addMethod(state, paymentMethod) { + state.methods.push(paymentMethod); }, - replaceMethods (state, paymentMethods) { - state.methods = paymentMethods + replaceMethods(state, paymentMethods) { + state.methods = paymentMethods; } }, actions: { - addMethod ({commit}, paymentMethod) { - commit('addMethod', paymentMethod) + addMethod({ commit }, paymentMethod) { + commit('addMethod', paymentMethod); }, - replaceMethods ({commit}, paymentMethods) { - commit('replaceMethods', paymentMethods) + replaceMethods({ commit }, paymentMethods) { + commit('replaceMethods', paymentMethods); } }, getters: { - paymentMethods (state) { - const isVirtualCart = rootStore.getters['cart/isVirtualCart'] - return state.methods.filter(method => { - return (!isVirtualCart || method.code !== 'cashondelivery') - }) + paymentMethods(state) { + const isVirtualCart = rootStore.getters['cart/isVirtualCart']; + return state.methods.filter(method => { + return !isVirtualCart || method.code !== 'cashondelivery'; + }); } } -} +}; diff --git a/core/modules/checkout/store/shipping/index.ts b/core/modules/checkout/store/shipping/index.ts index 07ab6bb9df..d5095b34dc 100644 --- a/core/modules/checkout/store/shipping/index.ts +++ b/core/modules/checkout/store/shipping/index.ts @@ -1,7 +1,7 @@ -import { Module } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import ShippingState from '../../types/ShippingState' -import buildTimeConfig from 'config' +import { Module } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import ShippingState from '../../types/ShippingState'; +import buildTimeConfig from 'config'; export const shippingModule: Module = { namespaced: true, @@ -9,24 +9,24 @@ export const shippingModule: Module = { methods: buildTimeConfig.shipping.methods }, mutations: { - addMethod (state, shippingMethods) { - state.methods.push(shippingMethods) + addMethod(state, shippingMethods) { + state.methods.push(shippingMethods); }, - replaceMethods (state, shippingMethods) { - state.methods = shippingMethods + replaceMethods(state, shippingMethods) { + state.methods = shippingMethods; } }, actions: { - addMethod ({commit}, shippingMethod) { - commit('addMethod', shippingMethod) + addMethod({ commit }, shippingMethod) { + commit('addMethod', shippingMethod); }, - replaceMethods ({commit}, shippingMethods) { - commit('replaceMethods', shippingMethods) + replaceMethods({ commit }, shippingMethods) { + commit('replaceMethods', shippingMethods); } }, getters: { - shippingMethods (state) { - return state.methods + shippingMethods(state) { + return state.methods; } } -} +}; diff --git a/core/modules/checkout/test/unit/components/CartSummary.spec.ts b/core/modules/checkout/test/unit/components/CartSummary.spec.ts index 769ea7d465..61bec3b2a9 100644 --- a/core/modules/checkout/test/unit/components/CartSummary.spec.ts +++ b/core/modules/checkout/test/unit/components/CartSummary.spec.ts @@ -1,17 +1,18 @@ -import {shallowMount} from '@vue/test-utils' +import { shallowMount } from '@vue/test-utils'; -import { CartSummary } from '../../../components/CartSummary' +import { CartSummary } from '../../../components/CartSummary'; -jest.mock('@vue-storefront/core/compatibility/components/blocks/Microcart/Microcart'); +jest.mock( + '@vue-storefront/core/compatibility/components/blocks/Microcart/Microcart' +); describe('CartSummary', () => { - it('can be initialized', () => { const wrapper = shallowMount({ - template: "
", + template: '
', mixins: [CartSummary] }); expect(wrapper.isVueInstance()).toBe(true); - }) -}); \ No newline at end of file + }); +}); diff --git a/core/modules/checkout/types/CheckoutState.ts b/core/modules/checkout/types/CheckoutState.ts index dd8477f495..57e15ae22d 100644 --- a/core/modules/checkout/types/CheckoutState.ts +++ b/core/modules/checkout/types/CheckoutState.ts @@ -1,40 +1,40 @@ export default interface CheckoutState { - order: any, + order: any; personalDetails: { - firstName: string, - lastName: string, - emailAddress: string, - password: string, - createAccount: boolean - }, + firstName: string; + lastName: string; + emailAddress: string; + password: string; + createAccount: boolean; + }; shippingDetails: { - firstName: string, - lastName: string, - country: string, - streetAddress: string, - apartmentNumber: string, - city: string, - state: string, - region_id: number, - zipCode: string, - phoneNumber: string, - shippingMethod: string - }, + firstName: string; + lastName: string; + country: string; + streetAddress: string; + apartmentNumber: string; + city: string; + state: string; + region_id: number; + zipCode: string; + phoneNumber: string; + shippingMethod: string; + }; paymentDetails: { - firstName: string, - lastName: string, - company: string, - country: string, - streetAddress: string, - apartmentNumber: string, - city: string, - region_id: number, - state: string, - zipCode: string, - phoneNumber: string, - taxId: string, - paymentMethod: string, - paymentMethodAdditional: any - }, - isThankYouPage: boolean + firstName: string; + lastName: string; + company: string; + country: string; + streetAddress: string; + apartmentNumber: string; + city: string; + region_id: number; + state: string; + zipCode: string; + phoneNumber: string; + taxId: string; + paymentMethod: string; + paymentMethodAdditional: any; + }; + isThankYouPage: boolean; } diff --git a/core/modules/checkout/types/PaymentState.ts b/core/modules/checkout/types/PaymentState.ts index 4a81f21f44..86c707a3a3 100644 --- a/core/modules/checkout/types/PaymentState.ts +++ b/core/modules/checkout/types/PaymentState.ts @@ -1,3 +1,3 @@ export default interface PaymentState { - methods: any[] + methods: any[]; } diff --git a/core/modules/checkout/types/ShippingState.ts b/core/modules/checkout/types/ShippingState.ts index 98efd39a14..bfa3fd811d 100644 --- a/core/modules/checkout/types/ShippingState.ts +++ b/core/modules/checkout/types/ShippingState.ts @@ -1,3 +1,3 @@ export default interface ShippingState { - methods: any[] + methods: any[]; } diff --git a/core/modules/cms/hooks/beforeRegistration.ts b/core/modules/cms/hooks/beforeRegistration.ts index f9ff55a839..16850b1d53 100644 --- a/core/modules/cms/hooks/beforeRegistration.ts +++ b/core/modules/cms/hooks/beforeRegistration.ts @@ -1,13 +1,15 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.cmsData = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'cms' - })) -} \ No newline at end of file + Vue.prototype.$db.cmsData = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'cms' + }) + ); +} diff --git a/core/modules/cms/index.ts b/core/modules/cms/index.ts index 319066fa07..d0c5003a15 100644 --- a/core/modules/cms/index.ts +++ b/core/modules/cms/index.ts @@ -1,19 +1,22 @@ -import { cmsPageModule } from './store/page' -import { cmsBlockModule } from './store/block' -import { cmsHierarchyModule } from './store/hierarchy' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { plugin } from './store/plugin' +import { cmsPageModule } from './store/page'; +import { cmsBlockModule } from './store/block'; +import { cmsHierarchyModule } from './store/hierarchy'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { plugin } from './store/plugin'; import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; -export const KEY = 'cms' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'cms'; +export const cacheStorage = initCacheStorage(KEY); export const Cms = createModule({ key: KEY, - store: { modules: [ - { key: 'cmsPage', module: cmsPageModule }, - { key: 'cmsBlock', module: cmsBlockModule }, - { key: 'cmsHierarchy', module: cmsHierarchyModule } - ], plugin }, + store: { + modules: [ + { key: 'cmsPage', module: cmsPageModule }, + { key: 'cmsBlock', module: cmsBlockModule }, + { key: 'cmsHierarchy', module: cmsHierarchyModule } + ], + plugin + }, beforeRegistration -}) +}); diff --git a/core/modules/cms/store/block/actions.ts b/core/modules/cms/store/block/actions.ts index ed6f61b738..fc8f261d62 100644 --- a/core/modules/cms/store/block/actions.ts +++ b/core/modules/cms/store/block/actions.ts @@ -1,13 +1,12 @@ -import { ActionTree } from "vuex" -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import * as types from './mutation-types' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' +import { ActionTree } from 'vuex'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import * as types from './mutation-types'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; import RootState from '@vue-storefront/core/types/RootState'; -import CmsBlockState from "../../types/CmsBlockState" -import { Logger } from '@vue-storefront/core/lib/logger' +import CmsBlockState from '../../types/CmsBlockState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { - /** * Retrieve cms blocks * @@ -20,25 +19,47 @@ const actions: ActionTree = { * @param {any} includeFields * @returns {Promise & Promise} */ - list (context, { filterValues = null, filterField = 'identifier', size = 150, start = 0, excludeFields = null, includeFields = null, skipCache = false }) { - let query = new SearchQuery() + list( + context, + { + filterValues = null, + filterField = 'identifier', + size = 150, + start = 0, + excludeFields = null, + includeFields = null, + skipCache = false + } + ) { + let query = new SearchQuery(); if (filterValues) { - query = query.applyFilter({key: filterField, value: {'like': filterValues}}) + query = query.applyFilter({ + key: filterField, + value: { like: filterValues } + }); } - if (skipCache || (!context.state.items || context.state.items.length === 0)) { - return quickSearchByQuery({ query, entityType: 'cms_block', excludeFields, includeFields }) - .then((resp) => { - context.commit(types.CMS_BLOCK_UPDATE_CMS_BLOCKS, resp.items) - return resp.items - }) - .catch(err => { - Logger.error(err, 'cms')() + if ( + skipCache || + (!context.state.items || context.state.items.length === 0) + ) { + return quickSearchByQuery({ + query, + entityType: 'cms_block', + excludeFields, + includeFields }) + .then(resp => { + context.commit(types.CMS_BLOCK_UPDATE_CMS_BLOCKS, resp.items); + return resp.items; + }) + .catch(err => { + Logger.error(err, 'cms')(); + }); } else { return new Promise((resolve, reject) => { - let resp = context.state.items - resolve(resp) - }) + let resp = context.state.items; + resolve(resp); + }); } }, @@ -52,40 +73,60 @@ const actions: ActionTree = { * @param {any} includeFields * @returns {Promise & Promise} */ - single (context, { key = 'identifier', value, excludeFields = null, includeFields = null, skipCache = false }) { - const state = context.state + single( + context, + { + key = 'identifier', + value, + excludeFields = null, + includeFields = null, + skipCache = false + } + ) { + const state = context.state; if (skipCache || (!state.items || state.items.length === 0)) { - let query = new SearchQuery() + let query = new SearchQuery(); if (value) { - query = query.applyFilter({key: key, value: {'like': value}}) + query = query.applyFilter({ key: key, value: { like: value } }); } - return quickSearchByQuery({ query, entityType: 'cms_block', excludeFields, includeFields }) - .then((resp) => { - context.commit(types.CMS_BLOCK_ADD_CMS_BLOCK, resp.items[0]) - return resp.items[0] - }) - .catch(err => { - Logger.error(err, 'cms')() + return quickSearchByQuery({ + query, + entityType: 'cms_block', + excludeFields, + includeFields }) + .then(resp => { + context.commit(types.CMS_BLOCK_ADD_CMS_BLOCK, resp.items[0]); + return resp.items[0]; + }) + .catch(err => { + Logger.error(err, 'cms')(); + }); } else { return new Promise((resolve, reject) => { if (state.items.length > 0) { - let cmsBlock = state.items.find((itm) => { return itm[key] === value }) + let cmsBlock = state.items.find(itm => { + return itm[key] === value; + }); if (cmsBlock) { - resolve(cmsBlock) + resolve(cmsBlock); } else { - reject(new Error('CMS block query returned empty result ' + key + ' = ' + value)) + reject( + new Error( + 'CMS block query returned empty result ' + key + ' = ' + value + ) + ); } } else { - resolve() + resolve(); } - }) + }); } }, - addItem ({ commit }, block) { - commit(types.CMS_BLOCK_ADD_CMS_BLOCK, block ) + addItem({ commit }, block) { + commit(types.CMS_BLOCK_ADD_CMS_BLOCK, block); } -} +}; -export default actions +export default actions; diff --git a/core/modules/cms/store/block/getters.ts b/core/modules/cms/store/block/getters.ts index 0bb4593003..ef5816aa50 100644 --- a/core/modules/cms/store/block/getters.ts +++ b/core/modules/cms/store/block/getters.ts @@ -1,15 +1,15 @@ -import { GetterTree } from 'vuex' -import CmsBlockState from '../../types/CmsBlockState' -import RootState from '@vue-storefront/core/types/RootState' +import { GetterTree } from 'vuex'; +import CmsBlockState from '../../types/CmsBlockState'; +import RootState from '@vue-storefront/core/types/RootState'; const getters: GetterTree = { - cmsBlocks: (state) => state.items, - cmsBlockIdentifier: (state) => (identifier) => { - return state.items.find(item => item.identifier === identifier) + cmsBlocks: state => state.items, + cmsBlockIdentifier: state => identifier => { + return state.items.find(item => item.identifier === identifier); }, - cmsBlockId: (state) => (id) => { - return state.items.find(item => item.id === id) - }, -} + cmsBlockId: state => id => { + return state.items.find(item => item.id === id); + } +}; -export default getters +export default getters; diff --git a/core/modules/cms/store/block/index.ts b/core/modules/cms/store/block/index.ts index 4cfd5b2e85..e2d411cb92 100644 --- a/core/modules/cms/store/block/index.ts +++ b/core/modules/cms/store/block/index.ts @@ -1,18 +1,18 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import CmsBlockState from '../../types/CmsBlockState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import CmsBlockState from '../../types/CmsBlockState'; -export const cmsBlockStorageKey = 'cms-blocks' +export const cmsBlockStorageKey = 'cms-blocks'; export const cmsBlockModule: Module = { namespaced: true, state: { - items: [], + items: [] }, getters, actions, mutations -} \ No newline at end of file +}; diff --git a/core/modules/cms/store/block/mutation-types.ts b/core/modules/cms/store/block/mutation-types.ts index 7cccb68e4a..98a4060c39 100644 --- a/core/modules/cms/store/block/mutation-types.ts +++ b/core/modules/cms/store/block/mutation-types.ts @@ -1,3 +1,3 @@ -export const SN_CMS_BLOCK = 'cmsBlock' -export const CMS_BLOCK_UPDATE_CMS_BLOCKS = SN_CMS_BLOCK + '/UPDATE_CMS_BLOCKS' -export const CMS_BLOCK_ADD_CMS_BLOCK = SN_CMS_BLOCK + '/ADD_CMS_BLOCK' \ No newline at end of file +export const SN_CMS_BLOCK = 'cmsBlock'; +export const CMS_BLOCK_UPDATE_CMS_BLOCKS = SN_CMS_BLOCK + '/UPDATE_CMS_BLOCKS'; +export const CMS_BLOCK_ADD_CMS_BLOCK = SN_CMS_BLOCK + '/ADD_CMS_BLOCK'; diff --git a/core/modules/cms/store/block/mutations.ts b/core/modules/cms/store/block/mutations.ts index 2dac855306..6940bbfa2f 100644 --- a/core/modules/cms/store/block/mutations.ts +++ b/core/modules/cms/store/block/mutations.ts @@ -1,6 +1,6 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import CmsBlockState from '../../types/CmsBlockState' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import CmsBlockState from '../../types/CmsBlockState'; const mutations: MutationTree = { /** @@ -8,15 +8,15 @@ const mutations: MutationTree = { * @param {} state * @param {Array} cmsBlocks */ - [types.CMS_BLOCK_UPDATE_CMS_BLOCKS] (state, cmsBlocks) { - state.items = cmsBlocks || [] + [types.CMS_BLOCK_UPDATE_CMS_BLOCKS](state, cmsBlocks) { + state.items = cmsBlocks || []; }, - [types.CMS_BLOCK_ADD_CMS_BLOCK] (state, cmsBlock ) { - const record = state.items.find(c => c.id === cmsBlock.id) + [types.CMS_BLOCK_ADD_CMS_BLOCK](state, cmsBlock) { + const record = state.items.find(c => c.id === cmsBlock.id); if (!record) { - state.items.push(cmsBlock) + state.items.push(cmsBlock); } } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/cms/store/hierarchy/actions.ts b/core/modules/cms/store/hierarchy/actions.ts index ba2608081c..d669e4c0f1 100644 --- a/core/modules/cms/store/hierarchy/actions.ts +++ b/core/modules/cms/store/hierarchy/actions.ts @@ -1,9 +1,9 @@ -import { ActionTree } from "vuex" -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' +import { ActionTree } from 'vuex'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; import RootState from '@vue-storefront/core/types/RootState'; -import CmsHierarchyState from "../../types/CmsHierarchyState" -import { Logger } from '@vue-storefront/core/lib/logger' +import CmsHierarchyState from '../../types/CmsHierarchyState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { /** @@ -16,17 +16,30 @@ const actions: ActionTree = { * @param {any} includeFields * @returns {Promise & Promise} */ - list (context, { id, entityType = 'cms_hierarchy', excludeFields = null, includeFields = null}) { - let query = new SearchQuery() + list( + context, + { + id, + entityType = 'cms_hierarchy', + excludeFields = null, + includeFields = null + } + ) { + let query = new SearchQuery(); if (id) { - query = query.applyFilter({key: 'identifier', value: {'eq': id}}) + query = query.applyFilter({ key: 'identifier', value: { eq: id } }); } - return quickSearchByQuery({ query, entityType, excludeFields, includeFields }).catch(err => { - Logger.error(err, 'cms')() - }) + return quickSearchByQuery({ + query, + entityType, + excludeFields, + includeFields + }).catch(err => { + Logger.error(err, 'cms')(); + }); } -} +}; -export default actions +export default actions; diff --git a/core/modules/cms/store/hierarchy/index.ts b/core/modules/cms/store/hierarchy/index.ts index bc69755481..db42efd4d5 100644 --- a/core/modules/cms/store/hierarchy/index.ts +++ b/core/modules/cms/store/hierarchy/index.ts @@ -1,13 +1,12 @@ -import { Module } from 'vuex' -import actions from './actions' -import RootState from '@vue-storefront/core/types/RootState' -import CmsHierarchyState from '../../types/CmsHierarchyState' +import { Module } from 'vuex'; +import actions from './actions'; +import RootState from '@vue-storefront/core/types/RootState'; +import CmsHierarchyState from '../../types/CmsHierarchyState'; export const cmsHierarchyModule: Module = { namespaced: true, state: { - items: [], + items: [] }, actions -} - +}; diff --git a/core/modules/cms/store/hierarchy/mutation-types.ts b/core/modules/cms/store/hierarchy/mutation-types.ts index 85b7a479a3..cf0ed72298 100644 --- a/core/modules/cms/store/hierarchy/mutation-types.ts +++ b/core/modules/cms/store/hierarchy/mutation-types.ts @@ -1,2 +1,3 @@ -export const SN_CMS_HIERARCHY = 'cms_hierarchy' -export const CMS_HIERARCHY_UPDATE_CMS_HIERARCHIES = SN_CMS_HIERARCHY + '/UPDATE_CMS_HIERARCHIES' \ No newline at end of file +export const SN_CMS_HIERARCHY = 'cms_hierarchy'; +export const CMS_HIERARCHY_UPDATE_CMS_HIERARCHIES = + SN_CMS_HIERARCHY + '/UPDATE_CMS_HIERARCHIES'; diff --git a/core/modules/cms/store/page/actions.ts b/core/modules/cms/store/page/actions.ts index ffcefad130..8ba146180d 100644 --- a/core/modules/cms/store/page/actions.ts +++ b/core/modules/cms/store/page/actions.ts @@ -1,15 +1,14 @@ -import { ActionTree } from "vuex" -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import * as types from './mutation-types' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' +import { ActionTree } from 'vuex'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import * as types from './mutation-types'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; import RootState from '@vue-storefront/core/types/RootState'; -import CmsPageState from "../../types/CmsPageState" -import { cacheStorage } from '../../' -import { cmsPagesStorageKey } from './' -import { Logger } from '@vue-storefront/core/lib/logger' +import CmsPageState from '../../types/CmsPageState'; +import { cacheStorage } from '../../'; +import { cmsPagesStorageKey } from './'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { - /** * Retrieve cms pages * @@ -22,25 +21,47 @@ const actions: ActionTree = { * @param {any} includeFields * @returns {Promise & Promise} */ - list (context, { filterValues = null, filterField = 'identifier', size = 150, start = 0, excludeFields = null, includeFields = null, skipCache = false }) { - if (skipCache || (!context.state.items || context.state.items.length === 0)) { - let query = new SearchQuery() + list( + context, + { + filterValues = null, + filterField = 'identifier', + size = 150, + start = 0, + excludeFields = null, + includeFields = null, + skipCache = false + } + ) { + if ( + skipCache || + (!context.state.items || context.state.items.length === 0) + ) { + let query = new SearchQuery(); if (filterValues) { - query = query.applyFilter({key: filterField, value: {'like': filterValues}}) + query = query.applyFilter({ + key: filterField, + value: { like: filterValues } + }); } - return quickSearchByQuery({ query, entityType: 'cms_page', excludeFields, includeFields }) - .then((resp) => { - context.commit(types.CMS_PAGE_UPDATE_CMS_PAGES, resp.items) - return resp.items - }) - .catch(err => { - Logger.error(err, 'cms')() + return quickSearchByQuery({ + query, + entityType: 'cms_page', + excludeFields, + includeFields }) + .then(resp => { + context.commit(types.CMS_PAGE_UPDATE_CMS_PAGES, resp.items); + return resp.items; + }) + .catch(err => { + Logger.error(err, 'cms')(); + }); } else { return new Promise((resolve, reject) => { - let resp = context.state.items - resolve(resp) - }) + let resp = context.state.items; + resolve(resp); + }); } }, @@ -54,53 +75,72 @@ const actions: ActionTree = { * @param {any} includeFields * @returns {Promise & Promise} */ - single (context, { key = 'identifier', value, excludeFields = null, includeFields = null, skipCache = false, setCurrent = true }) { - let query = new SearchQuery() + single( + context, + { + key = 'identifier', + value, + excludeFields = null, + includeFields = null, + skipCache = false, + setCurrent = true + } + ) { + let query = new SearchQuery(); if (value) { - query = query.applyFilter({key: key, value: { 'like': value }}) + query = query.applyFilter({ key: key, value: { like: value } }); } - if (skipCache || (!context.state.items || context.state.items.length === 0) || !context.state.items.find(p => p[key] === value)) { - return quickSearchByQuery({ query, entityType: 'cms_page', excludeFields, includeFields }) - .then((resp) => { - if (resp && resp.items && resp.items.length > 0) { - context.commit(types.CMS_PAGE_ADD_CMS_PAGE, resp.items[0]) - if (setCurrent) context.commit(types.CMS_PAGE_SET_CURRENT, resp.items[0]) - return resp.items[0] - } else { - throw new Error('CMS query returned empty result') - } - }) - .catch(err => { - throw err + if ( + skipCache || + (!context.state.items || context.state.items.length === 0) || + !context.state.items.find(p => p[key] === value) + ) { + return quickSearchByQuery({ + query, + entityType: 'cms_page', + excludeFields, + includeFields }) + .then(resp => { + if (resp && resp.items && resp.items.length > 0) { + context.commit(types.CMS_PAGE_ADD_CMS_PAGE, resp.items[0]); + if (setCurrent) + context.commit(types.CMS_PAGE_SET_CURRENT, resp.items[0]); + return resp.items[0]; + } else { + throw new Error('CMS query returned empty result'); + } + }) + .catch(err => { + throw err; + }); } else { return new Promise((resolve, reject) => { - let resp = context.state.items.find(p => p[key] === value) + let resp = context.state.items.find(p => p[key] === value); if (resp) { - if (setCurrent) context.commit(types.CMS_PAGE_SET_CURRENT, resp) - resolve(resp) + if (setCurrent) context.commit(types.CMS_PAGE_SET_CURRENT, resp); + resolve(resp); } else { cacheStorage.getItem(cmsPagesStorageKey, (err, storedItems) => { - if (err) reject(err) + if (err) reject(err); if (storedItems) { - context.commit(types.CMS_PAGE_UPDATE_CMS_PAGES, storedItems) - let resp = storedItems.find(p => p[key] === value) - if (!resp) reject(new Error('CMS query returned empty result')) - if (setCurrent) context.commit(types.CMS_PAGE_SET_CURRENT, resp) - resolve(resp) + context.commit(types.CMS_PAGE_UPDATE_CMS_PAGES, storedItems); + let resp = storedItems.find(p => p[key] === value); + if (!resp) reject(new Error('CMS query returned empty result')); + if (setCurrent) context.commit(types.CMS_PAGE_SET_CURRENT, resp); + resolve(resp); } else { - reject(new Error('CMS query returned empty result')) + reject(new Error('CMS query returned empty result')); } - }) + }); } - }) + }); } }, - addItem ({ commit }, page) { - commit(types.CMS_PAGE_ADD_CMS_PAGE, page ) + addItem({ commit }, page) { + commit(types.CMS_PAGE_ADD_CMS_PAGE, page); } +}; -} - -export default actions +export default actions; diff --git a/core/modules/cms/store/page/getters.ts b/core/modules/cms/store/page/getters.ts index 955fa36b16..ab11447cd0 100644 --- a/core/modules/cms/store/page/getters.ts +++ b/core/modules/cms/store/page/getters.ts @@ -1,9 +1,9 @@ -import { GetterTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import CmsPageState from '../../types/CmsPageState' +import { GetterTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import CmsPageState from '../../types/CmsPageState'; const getters: GetterTree = { - cmsPages: (state) => state.items -} + cmsPages: state => state.items +}; -export default getters +export default getters; diff --git a/core/modules/cms/store/page/index.ts b/core/modules/cms/store/page/index.ts index e79c27d549..14b809697c 100644 --- a/core/modules/cms/store/page/index.ts +++ b/core/modules/cms/store/page/index.ts @@ -1,11 +1,11 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import CmsPageState from '../../types/CmsPageState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import CmsPageState from '../../types/CmsPageState'; -export const cmsPagesStorageKey = 'cms-page' +export const cmsPagesStorageKey = 'cms-page'; export const cmsPageModule: Module = { namespaced: true, @@ -16,4 +16,4 @@ export const cmsPageModule: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/cms/store/page/mutation-types.ts b/core/modules/cms/store/page/mutation-types.ts index c2b9215c6e..104647bb93 100644 --- a/core/modules/cms/store/page/mutation-types.ts +++ b/core/modules/cms/store/page/mutation-types.ts @@ -1,4 +1,4 @@ -export const SN_CMS_PAGE = 'cmsPage' -export const CMS_PAGE_UPDATE_CMS_PAGES = SN_CMS_PAGE + '/UPDATE_CMS_PAGES' -export const CMS_PAGE_ADD_CMS_PAGE = SN_CMS_PAGE + '/ADD_CMS_PAGE' -export const CMS_PAGE_SET_CURRENT = SN_CMS_PAGE + '/SET_CURRENT_CMS_PAGE' \ No newline at end of file +export const SN_CMS_PAGE = 'cmsPage'; +export const CMS_PAGE_UPDATE_CMS_PAGES = SN_CMS_PAGE + '/UPDATE_CMS_PAGES'; +export const CMS_PAGE_ADD_CMS_PAGE = SN_CMS_PAGE + '/ADD_CMS_PAGE'; +export const CMS_PAGE_SET_CURRENT = SN_CMS_PAGE + '/SET_CURRENT_CMS_PAGE'; diff --git a/core/modules/cms/store/page/mutations.ts b/core/modules/cms/store/page/mutations.ts index bbeb0be7f2..66626ef974 100644 --- a/core/modules/cms/store/page/mutations.ts +++ b/core/modules/cms/store/page/mutations.ts @@ -1,6 +1,6 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import CmsPageState from '../../types/CmsPageState' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import CmsPageState from '../../types/CmsPageState'; const mutations: MutationTree = { /** @@ -8,18 +8,18 @@ const mutations: MutationTree = { * @param {} state * @param {Array} cmsPages */ - [types.CMS_PAGE_UPDATE_CMS_PAGES] (state, cmsPages) { - state.items = cmsPages || [] + [types.CMS_PAGE_UPDATE_CMS_PAGES](state, cmsPages) { + state.items = cmsPages || []; }, - [types.CMS_PAGE_SET_CURRENT] (state, current) { - state.current = current + [types.CMS_PAGE_SET_CURRENT](state, current) { + state.current = current; }, - [types.CMS_PAGE_ADD_CMS_PAGE] (state, cmsPage ) { - const record = state.items.find(c => c.id === cmsPage.id) + [types.CMS_PAGE_ADD_CMS_PAGE](state, cmsPage) { + const record = state.items.find(c => c.id === cmsPage.id); if (!record) { - state.items.push(cmsPage) + state.items.push(cmsPage); } } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/cms/store/plugin.ts b/core/modules/cms/store/plugin.ts index 0386444936..c70772f110 100644 --- a/core/modules/cms/store/plugin.ts +++ b/core/modules/cms/store/plugin.ts @@ -1,22 +1,28 @@ -import * as pageTypes from './page/mutation-types' -import * as blockTypes from './block/mutation-types' -import { cmsPagesStorageKey } from './page' -import { cmsBlockStorageKey } from './block' -import { cacheStorage } from '../' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as pageTypes from './page/mutation-types'; +import * as blockTypes from './block/mutation-types'; +import { cmsPagesStorageKey } from './page'; +import { cmsBlockStorageKey } from './block'; +import { cacheStorage } from '../'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export function plugin (mutation, state) { - const type = mutation.type +export function plugin(mutation, state) { + const type = mutation.type; - if (type.startsWith(pageTypes.SN_CMS_PAGE)) { // check if this mutation is pages related - cacheStorage.setItem(cmsPagesStorageKey, state.cmsPage.items).catch((reason) => { - Logger.error(reason, 'cms') // it doesn't work on SSR - }) + if (type.startsWith(pageTypes.SN_CMS_PAGE)) { + // check if this mutation is pages related + cacheStorage + .setItem(cmsPagesStorageKey, state.cmsPage.items) + .catch(reason => { + Logger.error(reason, 'cms'); // it doesn't work on SSR + }); } - if (type.startsWith(blockTypes.SN_CMS_BLOCK)) { // check if this mutation is block related - cacheStorage.setItem(cmsBlockStorageKey, state.cmsBlock.items).catch((reason) => { - Logger.error(reason, 'cms') // it doesn't work on SSR - }) + if (type.startsWith(blockTypes.SN_CMS_BLOCK)) { + // check if this mutation is block related + cacheStorage + .setItem(cmsBlockStorageKey, state.cmsBlock.items) + .catch(reason => { + Logger.error(reason, 'cms'); // it doesn't work on SSR + }); } } diff --git a/core/modules/cms/types/CmsBlockState.ts b/core/modules/cms/types/CmsBlockState.ts index 74bff79245..270d6d2914 100644 --- a/core/modules/cms/types/CmsBlockState.ts +++ b/core/modules/cms/types/CmsBlockState.ts @@ -1,3 +1,3 @@ export default interface CmsBlockState { - items: any[] + items: any[]; } diff --git a/core/modules/cms/types/CmsHierarchyState.ts b/core/modules/cms/types/CmsHierarchyState.ts index 55e3c48e51..208eadd260 100644 --- a/core/modules/cms/types/CmsHierarchyState.ts +++ b/core/modules/cms/types/CmsHierarchyState.ts @@ -1,3 +1,3 @@ export default interface CmsHierarchyState { - items: any[] + items: any[]; } diff --git a/core/modules/cms/types/CmsPageState.ts b/core/modules/cms/types/CmsPageState.ts index ffd592ba3d..fd0e772b4b 100644 --- a/core/modules/cms/types/CmsPageState.ts +++ b/core/modules/cms/types/CmsPageState.ts @@ -1,4 +1,4 @@ export default interface CmsPageState { - items: any[], - current: any + items: any[]; + current: any; } diff --git a/core/modules/compare/components/AddToCompare.ts b/core/modules/compare/components/AddToCompare.ts index 5823da9514..efe9d41957 100644 --- a/core/modules/compare/components/AddToCompare.ts +++ b/core/modules/compare/components/AddToCompare.ts @@ -1,14 +1,14 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin'; export const AddToCompare = { name: 'AddToCompare', mixins: [compareMountedMixin], methods: { - addToCompare (product: Product) { + addToCompare(product: Product) { return this.$store.state['compare'] ? this.$store.dispatch('compare/addItem', product) - : false + : false; } } -} +}; diff --git a/core/modules/compare/components/Compare.ts b/core/modules/compare/components/Compare.ts index 79c265efec..76c6538b98 100644 --- a/core/modules/compare/components/Compare.ts +++ b/core/modules/compare/components/Compare.ts @@ -1,35 +1,40 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin'; export const Compare = { name: 'Compare', mixins: [compareMountedMixin], computed: { - items () : Product[] { - return this.$store.state.compare.items + items(): Product[] { + return this.$store.state.compare.items; }, - allComparableAttributes () { - const attributesByCode = this.$store.getters['attribute/attributeListByCode'] - return Object.values(attributesByCode).filter((a: any) => parseInt(a.is_comparable)) + allComparableAttributes() { + const attributesByCode = this.$store.getters[ + 'attribute/attributeListByCode' + ]; + return Object.values(attributesByCode).filter((a: any) => + parseInt(a.is_comparable) + ); } }, - created () { + created() { this.$store.dispatch('attribute/list', { filterValues: [true], filterField: 'is_user_defined' - }) + }); }, methods: { - removeFromCompare (product: Product) { + removeFromCompare(product: Product) { return this.$store.state['compare'] ? this.$store.dispatch('compare/removeItem', product) - : false + : false; } }, - asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data + asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data return new Promise((resolve, reject) => { - if (context) context.output.cacheTags.add(`compare`) - resolve() - }) + if (context) context.output.cacheTags.add(`compare`); + resolve(); + }); } -} +}; diff --git a/core/modules/compare/components/CompareButton.ts b/core/modules/compare/components/CompareButton.ts index 704aef9fd8..cd1ba7e041 100644 --- a/core/modules/compare/components/CompareButton.ts +++ b/core/modules/compare/components/CompareButton.ts @@ -1,11 +1,11 @@ -import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin' +import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin'; export const CompareButton = { name: 'CompareButton', mixins: [compareMountedMixin], computed: { - isEmpty () : boolean { - return this.$store.getters['compare/isEmpty'] + isEmpty(): boolean { + return this.$store.getters['compare/isEmpty']; } } -} +}; diff --git a/core/modules/compare/components/Product.ts b/core/modules/compare/components/Product.ts index 7099b32b92..1031a2e041 100644 --- a/core/modules/compare/components/Product.ts +++ b/core/modules/compare/components/Product.ts @@ -1,19 +1,19 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import compareMountedMixin from '@vue-storefront/core/modules/compare/mixins/compareMountedMixin'; export const CompareProduct = { name: 'CompareProduct', mixins: [compareMountedMixin], computed: { - isOnCompare () : boolean { - return this.$store.getters['compare/isOnCompare'](this.product) + isOnCompare(): boolean { + return this.$store.getters['compare/isOnCompare'](this.product); } }, methods: { - removeFromCompare (product: Product) { + removeFromCompare(product: Product) { return this.$store.state['compare'] ? this.$store.dispatch('compare/removeItem', product) - : false + : false; } } -} +}; diff --git a/core/modules/compare/hooks/afterRegistration.ts b/core/modules/compare/hooks/afterRegistration.ts index 5fea5863ca..705b6c310f 100644 --- a/core/modules/compare/hooks/afterRegistration.ts +++ b/core/modules/compare/hooks/afterRegistration.ts @@ -1,2 +1 @@ -export function afterRegistration({ Vue, config, store, isServer }){ -} \ No newline at end of file +export function afterRegistration({ Vue, config, store, isServer }) {} diff --git a/core/modules/compare/hooks/beforeRegistration.ts b/core/modules/compare/hooks/beforeRegistration.ts index 632d28bcd0..966ec550c4 100644 --- a/core/modules/compare/hooks/beforeRegistration.ts +++ b/core/modules/compare/hooks/beforeRegistration.ts @@ -1,14 +1,16 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.compareCollection = new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'compare', - driver: localForage[config.localForage.defaultDrivers['compare']] - })) -} \ No newline at end of file + Vue.prototype.$db.compareCollection = new UniversalStorage( + localForage.createInstance({ + name: dbNamePrefix + 'shop', + storeName: 'compare', + driver: localForage[config.localForage.defaultDrivers['compare']] + }) + ); +} diff --git a/core/modules/compare/index.ts b/core/modules/compare/index.ts index e974ceda44..e25c80528d 100644 --- a/core/modules/compare/index.ts +++ b/core/modules/compare/index.ts @@ -1,15 +1,15 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; -import { plugin } from './store/plugin' +import { plugin } from './store/plugin'; -export const KEY = 'compare' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'compare'; +export const cacheStorage = initCacheStorage(KEY); export const Compare = createModule({ key: KEY, store: { modules: [{ key: KEY, module }], plugin }, beforeRegistration, afterRegistration -}) +}); diff --git a/core/modules/compare/mixins/compareMountedMixin.js b/core/modules/compare/mixins/compareMountedMixin.js index 160289ad65..1cb48ac065 100644 --- a/core/modules/compare/mixins/compareMountedMixin.js +++ b/core/modules/compare/mixins/compareMountedMixin.js @@ -4,7 +4,7 @@ */ export default { - mounted () { - this.$store.dispatch('compare/load') + mounted() { + this.$store.dispatch('compare/load'); } -} +}; diff --git a/core/modules/compare/store/actions.ts b/core/modules/compare/store/actions.ts index e3b89b53ee..4caae2a260 100644 --- a/core/modules/compare/store/actions.ts +++ b/core/modules/compare/store/actions.ts @@ -1,39 +1,47 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import { htmlDecode } from '@vue-storefront/core/store/lib/filters' -import i18n from '@vue-storefront/i18n' -import rootStore from '@vue-storefront/core/store' -import RootState from '@vue-storefront/core/types/RootState' -import CompareState from '../types/CompareState' -import { cacheStorage } from '../' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import { htmlDecode } from '@vue-storefront/core/store/lib/filters'; +import i18n from '@vue-storefront/i18n'; +import rootStore from '@vue-storefront/core/store'; +import RootState from '@vue-storefront/core/types/RootState'; +import CompareState from '../types/CompareState'; +import { cacheStorage } from '../'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { - load ({ commit, getters }, force: boolean = false) { - if (!force && getters.isCompareLoaded) return - commit(types.SET_COMPARE_LOADED) + load({ commit, getters }, force: boolean = false) { + if (!force && getters.isCompareLoaded) return; + commit(types.SET_COMPARE_LOADED); cacheStorage.getItem('current-compare', (err, storedItems) => { - if (err) throw new Error(err) - commit(types.COMPARE_LOAD_COMPARE, storedItems) - Logger.info('Compare state loaded from browser cache: ', 'cache', storedItems)() - }) + if (err) throw new Error(err); + commit(types.COMPARE_LOAD_COMPARE, storedItems); + Logger.info( + 'Compare state loaded from browser cache: ', + 'cache', + storedItems + )(); + }); }, - addItem ({commit}, product) { - commit(types.COMPARE_ADD_ITEM, {product}) + addItem({ commit }, product) { + commit(types.COMPARE_ADD_ITEM, { product }); rootStore.dispatch('notification/spawnNotification', { type: 'success', - message: i18n.t('Product {productName} has been added to the compare!', { productName: htmlDecode(product.name) }), + message: i18n.t('Product {productName} has been added to the compare!', { + productName: htmlDecode(product.name) + }), action1: { label: i18n.t('OK') } - }) + }); }, - removeItem ({commit}, product) { - commit(types.COMPARE_DEL_ITEM, {product}) + removeItem({ commit }, product) { + commit(types.COMPARE_DEL_ITEM, { product }); rootStore.dispatch('notification/spawnNotification', { type: 'success', - message: i18n.t('Product {productName} has been removed from compare!', { productName: htmlDecode(product.name) }), + message: i18n.t('Product {productName} has been removed from compare!', { + productName: htmlDecode(product.name) + }), action1: { label: i18n.t('OK') } - }) + }); } -} +}; -export default actions +export default actions; diff --git a/core/modules/compare/store/getters.ts b/core/modules/compare/store/getters.ts index c5aeb19d8b..d5744cfedc 100644 --- a/core/modules/compare/store/getters.ts +++ b/core/modules/compare/store/getters.ts @@ -1,11 +1,11 @@ -import { GetterTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import CompareState from '../types/CompareState' +import { GetterTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import CompareState from '../types/CompareState'; const getters: GetterTree = { - isEmpty: (state) => state.items.length === 0, - isOnCompare: (state) => (product) => state.items.find(p => p.sku === product.sku), + isEmpty: state => state.items.length === 0, + isOnCompare: state => product => state.items.find(p => p.sku === product.sku), isCompareLoaded: state => state.loaded -} +}; -export default getters +export default getters; diff --git a/core/modules/compare/store/index.ts b/core/modules/compare/store/index.ts index 03e5c1536d..cff2c1837b 100644 --- a/core/modules/compare/store/index.ts +++ b/core/modules/compare/store/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from "@vue-storefront/core/types/RootState" -import CompareState from '../types/CompareState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import CompareState from '../types/CompareState'; export const module: Module = { namespaced: true, @@ -14,4 +14,4 @@ export const module: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/compare/store/mutation-types.ts b/core/modules/compare/store/mutation-types.ts index e149cfd1f3..282441fd18 100644 --- a/core/modules/compare/store/mutation-types.ts +++ b/core/modules/compare/store/mutation-types.ts @@ -1,5 +1,5 @@ -export const SN_COMPARE = 'compare' -export const COMPARE_ADD_ITEM = SN_COMPARE + '/ADD' -export const COMPARE_DEL_ITEM = SN_COMPARE + '/DEL' -export const COMPARE_LOAD_COMPARE = SN_COMPARE + '/LOAD' -export const SET_COMPARE_LOADED = `${SN_COMPARE}/SET_COMPARE_LOADED` +export const SN_COMPARE = 'compare'; +export const COMPARE_ADD_ITEM = SN_COMPARE + '/ADD'; +export const COMPARE_DEL_ITEM = SN_COMPARE + '/DEL'; +export const COMPARE_LOAD_COMPARE = SN_COMPARE + '/LOAD'; +export const SET_COMPARE_LOADED = `${SN_COMPARE}/SET_COMPARE_LOADED`; diff --git a/core/modules/compare/store/mutations.ts b/core/modules/compare/store/mutations.ts index 771feb2c3e..c935aef355 100644 --- a/core/modules/compare/store/mutations.ts +++ b/core/modules/compare/store/mutations.ts @@ -1,29 +1,29 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import CompareState from '../types/CompareState' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import CompareState from '../types/CompareState'; const mutations: MutationTree = { /** * Add product to Compare * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ - [types.COMPARE_ADD_ITEM] (state, {product}) { - const record = state.items.find(p => p.sku === product.sku) + [types.COMPARE_ADD_ITEM](state, { product }) { + const record = state.items.find(p => p.sku === product.sku); if (!record) { state.items.push({ ...product - }) + }); } }, - [types.COMPARE_DEL_ITEM] (state, {product}) { - state.items = state.items.filter(p => p.sku !== product.sku) + [types.COMPARE_DEL_ITEM](state, { product }) { + state.items = state.items.filter(p => p.sku !== product.sku); }, - [types.COMPARE_LOAD_COMPARE] (state, storedItems) { - state.items = storedItems || [] + [types.COMPARE_LOAD_COMPARE](state, storedItems) { + state.items = storedItems || []; }, - [types.SET_COMPARE_LOADED] (state, isLoaded: boolean = true) { - state.loaded = isLoaded + [types.SET_COMPARE_LOADED](state, isLoaded: boolean = true) { + state.loaded = isLoaded; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/compare/store/plugin.ts b/core/modules/compare/store/plugin.ts index 6f887e95c5..6db9e61f93 100644 --- a/core/modules/compare/store/plugin.ts +++ b/core/modules/compare/store/plugin.ts @@ -1,13 +1,19 @@ -import * as types from './mutation-types' -import { cacheStorage } from '../' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as types from './mutation-types'; +import { cacheStorage } from '../'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export function plugin (mutation, state) { - const type = mutation.type +export function plugin(mutation, state) { + const type = mutation.type; - if (type.includes(types.COMPARE_ADD_ITEM) || type.includes(types.COMPARE_DEL_ITEM)) { // check if this mutation is comapre related - cacheStorage.setItem('current-compare', state.compare.items).catch((reason) => { - Logger.error(reason, 'compare') // it doesn't work on SSR - }) + if ( + type.includes(types.COMPARE_ADD_ITEM) || + type.includes(types.COMPARE_DEL_ITEM) + ) { + // check if this mutation is comapre related + cacheStorage + .setItem('current-compare', state.compare.items) + .catch(reason => { + Logger.error(reason, 'compare'); // it doesn't work on SSR + }); } } diff --git a/core/modules/compare/types/CompareState.ts b/core/modules/compare/types/CompareState.ts index 8f013bc0f7..ed6101eb67 100644 --- a/core/modules/compare/types/CompareState.ts +++ b/core/modules/compare/types/CompareState.ts @@ -2,6 +2,6 @@ export default interface CompareState { /** * Informs if items to compare are already loaded from local cache. */ - loaded: boolean, - items: any[] + loaded: boolean; + items: any[]; } diff --git a/core/modules/mailer/components/EmailForm.ts b/core/modules/mailer/components/EmailForm.ts index 76c16b5f69..67dd98f0da 100644 --- a/core/modules/mailer/components/EmailForm.ts +++ b/core/modules/mailer/components/EmailForm.ts @@ -1,32 +1,34 @@ -import i18n from '@vue-storefront/i18n' -import MailItem from '../types/MailItem' +import i18n from '@vue-storefront/i18n'; +import MailItem from '../types/MailItem'; export const EmailForm = { name: 'EmailForm', - data () { + data() { return { token: null - } + }; }, methods: { - sendEmail (letter: MailItem, success, failure) { - this.$store.dispatch('mailer/sendEmail', letter) - .then(res => { - if (res.ok) { - if (success) success(i18n.t('Email has successfully been sent')) - } else { - return res.json() - } - }) - .then(errorResponse => { - if (errorResponse) { - const errorMessage = errorResponse.result - if (failure) failure(i18n.t(errorMessage)) - } - }) - .catch(() => { - if (failure) failure(i18n.t('Could not send an email. Please try again later.')) - }) + sendEmail(letter: MailItem, success, failure) { + this.$store + .dispatch('mailer/sendEmail', letter) + .then(res => { + if (res.ok) { + if (success) success(i18n.t('Email has successfully been sent')); + } else { + return res.json(); + } + }) + .then(errorResponse => { + if (errorResponse) { + const errorMessage = errorResponse.result; + if (failure) failure(i18n.t(errorMessage)); + } + }) + .catch(() => { + if (failure) + failure(i18n.t('Could not send an email. Please try again later.')); + }); } } -} +}; diff --git a/core/modules/mailer/index.ts b/core/modules/mailer/index.ts index 504da8a545..2bef152055 100644 --- a/core/modules/mailer/index.ts +++ b/core/modules/mailer/index.ts @@ -1,8 +1,8 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; -export const KEY = 'mailer' +export const KEY = 'mailer'; export const Mailer = createModule({ key: KEY, - store: { modules: [{ key: KEY, module }] }, -}) + store: { modules: [{ key: KEY, module }] } +}); diff --git a/core/modules/mailer/store/index.ts b/core/modules/mailer/store/index.ts index 0bfb321bbf..22200ff45b 100644 --- a/core/modules/mailer/store/index.ts +++ b/core/modules/mailer/store/index.ts @@ -1,37 +1,37 @@ -import config from 'config' -import i18n from '@vue-storefront/i18n' -import MailItem from '../types/MailItem' -import { Module } from 'vuex' +import config from 'config'; +import i18n from '@vue-storefront/i18n'; +import MailItem from '../types/MailItem'; +import { Module } from 'vuex'; export const module: Module = { namespaced: true, actions: { - sendEmail (context, letter: MailItem) { + sendEmail(context, letter: MailItem) { return new Promise((resolve, reject) => { fetch(config.mailer.endpoint.token) - .then(res => res.json()) - .then(res => { - if (res.code === 200) { - fetch(config.mailer.endpoint.send, { - method: 'POST', - mode: 'cors', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - ...letter, - token: res.result + .then(res => res.json()) + .then(res => { + if (res.code === 200) { + fetch(config.mailer.endpoint.send, { + method: 'POST', + mode: 'cors', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + ...letter, + token: res.result + }) }) - }) - .then(res => resolve(res)) - .catch(() => reject()) - } else { - reject() - } - }) - .catch(() => reject()) - }) + .then(res => resolve(res)) + .catch(() => reject()); + } else { + reject(); + } + }) + .catch(() => reject()); + }); } } -} +}; diff --git a/core/modules/mailer/types/MailItem.ts b/core/modules/mailer/types/MailItem.ts index e956a1bd9f..822feeba5c 100644 --- a/core/modules/mailer/types/MailItem.ts +++ b/core/modules/mailer/types/MailItem.ts @@ -1,7 +1,7 @@ export default interface MailItem { - sourceAddress: string, - targetAddress: string, - subject: string, - emailText: string, - confirmation?: boolean + sourceAddress: string; + targetAddress: string; + subject: string; + emailText: string; + confirmation?: boolean; } diff --git a/core/modules/notification/components/Notification.ts b/core/modules/notification/components/Notification.ts index 431434373e..05573e0cc5 100644 --- a/core/modules/notification/components/Notification.ts +++ b/core/modules/notification/components/Notification.ts @@ -1,10 +1,10 @@ -import NotificationItem from '../types/NotificationItem' +import NotificationItem from '../types/NotificationItem'; export const Notification = { name: 'Notification', computed: { - notifications () : NotificationItem[] { - return this.$store.getters['notification/notifications'] + notifications(): NotificationItem[] { + return this.$store.getters['notification/notifications']; } } -} +}; diff --git a/core/modules/notification/index.ts b/core/modules/notification/index.ts index d958372548..43ab839ac2 100644 --- a/core/modules/notification/index.ts +++ b/core/modules/notification/index.ts @@ -1,8 +1,8 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; -export const KEY = 'notification' +export const KEY = 'notification'; export const Notification = createModule({ key: KEY, - store: { modules: [{ key: KEY, module }] }, -}) \ No newline at end of file + store: { modules: [{ key: KEY, module }] } +}); diff --git a/core/modules/notification/store/index.ts b/core/modules/notification/store/index.ts index 2d377d7f60..43cd3649ad 100644 --- a/core/modules/notification/store/index.ts +++ b/core/modules/notification/store/index.ts @@ -1,6 +1,6 @@ -import { Module } from 'vuex' -import NotificationItem from '../types/NotificationItem' -import NotificationState from '../types/NotificationState' +import { Module } from 'vuex'; +import NotificationItem from '../types/NotificationItem'; +import NotificationState from '../types/NotificationState'; export const module: Module = { namespaced: true, @@ -11,33 +11,38 @@ export const module: Module = { notifications: state => state.notifications }, mutations: { - add (state, payload) { - state.notifications.push(payload) + add(state, payload) { + state.notifications.push(payload); }, - remove (state, index) { - state.notifications.splice(index, 1) + remove(state, index) { + state.notifications.splice(index, 1); } }, actions: { - spawnNotification ({ commit, state, dispatch }, notification: NotificationItem) { - if (state.notifications.length > 0 - && state.notifications[state.notifications.length - 1].message === notification.message + spawnNotification( + { commit, state, dispatch }, + notification: NotificationItem + ) { + if ( + state.notifications.length > 0 && + state.notifications[state.notifications.length - 1].message === + notification.message ) { - return + return; } - commit('add', notification) + commit('add', notification); if (!notification.hasNoTimeout) { setTimeout(() => { - dispatch('removeNotification') - }, notification.timeToLive || 5000) + dispatch('removeNotification'); + }, notification.timeToLive || 5000); } }, - removeNotification ({ commit, state }, index?: number) { + removeNotification({ commit, state }, index?: number) { if (!index) { - commit('remove', state.notifications.length - 1) + commit('remove', state.notifications.length - 1); } else { - commit('remove', index) + commit('remove', index); } } } -} +}; diff --git a/core/modules/notification/types/NotificationItem.ts b/core/modules/notification/types/NotificationItem.ts index 8bb6b8fa5d..625296466f 100644 --- a/core/modules/notification/types/NotificationItem.ts +++ b/core/modules/notification/types/NotificationItem.ts @@ -1,13 +1,13 @@ interface ActionItem { - label: string, - action?(): any + label: string; + action?(): any; } export default interface NotificationItem { - type: string, - message: string, - timeToLive?: number, - action1: ActionItem, - action2?: ActionItem, - hasNoTimeout?: boolean + type: string; + message: string; + timeToLive?: number; + action1: ActionItem; + action2?: ActionItem; + hasNoTimeout?: boolean; } diff --git a/core/modules/notification/types/NotificationState.ts b/core/modules/notification/types/NotificationState.ts index 332922be3e..1be25a4123 100644 --- a/core/modules/notification/types/NotificationState.ts +++ b/core/modules/notification/types/NotificationState.ts @@ -1,5 +1,5 @@ -import NotificationItem from './NotificationItem' +import NotificationItem from './NotificationItem'; export default interface NotificationState { - notifications: NotificationItem[] + notifications: NotificationItem[]; } diff --git a/core/modules/offline-order/components/CancelOrders.ts b/core/modules/offline-order/components/CancelOrders.ts index 036ddc02da..9108182365 100644 --- a/core/modules/offline-order/components/CancelOrders.ts +++ b/core/modules/offline-order/components/CancelOrders.ts @@ -1,26 +1,34 @@ -import * as localForage from 'localforage' -import store from '@vue-storefront/core/store' +import * as localForage from 'localforage'; +import store from '@vue-storefront/core/store'; -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { Logger } from '@vue-storefront/core/lib/logger' +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { Logger } from '@vue-storefront/core/lib/logger'; export const CancelOrders = { methods: { - cancelOrders () { - const ordersCollection = new UniversalStorage(localForage.createInstance({ - name: 'shop', - storeName: 'orders', - driver: localForage[store.state.config.localForage.defaultDrivers['orders']] - })) + cancelOrders() { + const ordersCollection = new UniversalStorage( + localForage.createInstance({ + name: 'shop', + storeName: 'orders', + driver: + localForage[store.state.config.localForage.defaultDrivers['orders']] + }) + ); - ordersCollection.iterate((order, id, iterationNumber) => { - if (!order.transmited) { - ordersCollection.removeItem(id) - } - }).catch(err => { - Logger.error(err, 'offline-order')() - Logger.log('Not transmitted orders have been deleted', 'offline-order')() - }) + ordersCollection + .iterate((order, id, iterationNumber) => { + if (!order.transmited) { + ordersCollection.removeItem(id); + } + }) + .catch(err => { + Logger.error(err, 'offline-order')(); + Logger.log( + 'Not transmitted orders have been deleted', + 'offline-order' + )(); + }); } } -} +}; diff --git a/core/modules/offline-order/components/ConfirmOrders.ts b/core/modules/offline-order/components/ConfirmOrders.ts index db9c9ac022..ab212eb2ef 100644 --- a/core/modules/offline-order/components/ConfirmOrders.ts +++ b/core/modules/offline-order/components/ConfirmOrders.ts @@ -1,11 +1,11 @@ -import config from 'config' +import config from 'config'; export const ConfirmOrders = { methods: { - confirmOrders () { - this.$bus.$emit('order/PROCESS_QUEUE', { config: config }) - this.$bus.$emit('sync/PROCESS_QUEUE', { config: config }) - this.$store.dispatch('cart/load') + confirmOrders() { + this.$bus.$emit('order/PROCESS_QUEUE', { config: config }); + this.$bus.$emit('sync/PROCESS_QUEUE', { config: config }); + this.$store.dispatch('cart/load'); } } -} +}; diff --git a/core/modules/offline-order/extends/service-worker.js b/core/modules/offline-order/extends/service-worker.js index 587217eb57..c7800288a4 100644 --- a/core/modules/offline-order/extends/service-worker.js +++ b/core/modules/offline-order/extends/service-worker.js @@ -1,30 +1,30 @@ // Offline order notification object -import config from 'config' +import config from 'config'; -function sendNotification () { - const title = config.orders.offline_orders.notification.title - const message = config.orders.offline_orders.notification.message - const icon = config.orders.offline_orders.notification.icon +function sendNotification() { + const title = config.orders.offline_orders.notification.title; + const message = config.orders.offline_orders.notification.message; + const icon = config.orders.offline_orders.notification.icon; self.registration.showNotification(title, { body: message, icon: icon, requireInteraction: true - }) + }); } -function openShop (notification) { - const pageUrl = '/?order=offline' - self.clients.openWindow(pageUrl) - notification.close() +function openShop(notification) { + const pageUrl = '/?order=offline'; + self.clients.openWindow(pageUrl); + notification.close(); } self.addEventListener('sync', event => { if (event.tag === 'orderSync') { - event.waitUntil(sendNotification()) + event.waitUntil(sendNotification()); } -}) +}); self.addEventListener('notificationclick', event => { - event.waitUntil(openShop(event.notification)) -}) + event.waitUntil(openShop(event.notification)); +}); diff --git a/core/modules/offline-order/helpers/onNetworkStatusChange.ts b/core/modules/offline-order/helpers/onNetworkStatusChange.ts index d993558120..597a8781a0 100644 --- a/core/modules/offline-order/helpers/onNetworkStatusChange.ts +++ b/core/modules/offline-order/helpers/onNetworkStatusChange.ts @@ -1,41 +1,49 @@ -import * as localForage from 'localforage' -import store from '@vue-storefront/core/store' +import * as localForage from 'localforage'; +import store from '@vue-storefront/core/store'; -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index'; -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { Logger } from '@vue-storefront/core/lib/logger' +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export function onNetworkStatusChange (store) { - Logger.log('Are we online: ' + navigator.onLine, 'offline-order')() +export function onNetworkStatusChange(store) { + Logger.log('Are we online: ' + navigator.onLine, 'offline-order')(); if (typeof navigator !== 'undefined' && navigator.onLine) { - EventBus.$emit('sync/PROCESS_QUEUE', { config: store.state.config }) // process checkout queue - store.dispatch('cart/load') + EventBus.$emit('sync/PROCESS_QUEUE', { config: store.state.config }); // process checkout queue + store.dispatch('cart/load'); - if (store.state.config.orders.offline_orders.automatic_transmission_enabled || store.getters['checkout/isThankYouPage']) { - EventBus.$emit('order/PROCESS_QUEUE', { config: store.state.config }) // process checkout queue + if ( + store.state.config.orders.offline_orders.automatic_transmission_enabled || + store.getters['checkout/isThankYouPage'] + ) { + EventBus.$emit('order/PROCESS_QUEUE', { config: store.state.config }); // process checkout queue // store.dispatch('cart/serverPull', { forceClientState: false }) } else { - const ordersToConfirm = [] - const storeView = currentStoreView() - const ordersCollection = new UniversalStorage(localForage.createInstance({ - name: 'shop', - storeName: 'orders', - driver: localForage[store.state.config.localForage.defaultDrivers['orders']] - })) + const ordersToConfirm = []; + const storeView = currentStoreView(); + const ordersCollection = new UniversalStorage( + localForage.createInstance({ + name: 'shop', + storeName: 'orders', + driver: + localForage[store.state.config.localForage.defaultDrivers['orders']] + }) + ); - ordersCollection.iterate((order, id, iterationNumber) => { - if (!order.transmited) { - ordersToConfirm.push(order) - } - }).catch(err => { - Logger.error(err, 'offline-order')() - }) + ordersCollection + .iterate((order, id, iterationNumber) => { + if (!order.transmited) { + ordersToConfirm.push(order); + } + }) + .catch(err => { + Logger.error(err, 'offline-order')(); + }); if (ordersToConfirm.length > 0) { - EventBus.$emit('offline-order-confirmation', ordersToConfirm) + EventBus.$emit('offline-order-confirmation', ordersToConfirm); } } } diff --git a/core/modules/order/components/UserOrders.ts b/core/modules/order/components/UserOrders.ts index edd40cbb5c..ea5b888e88 100644 --- a/core/modules/order/components/UserOrders.ts +++ b/core/modules/order/components/UserOrders.ts @@ -1,30 +1,37 @@ - /** * Component responsible for displaying user orders. Requires User module. */ export const UserOrders = { name: 'UserOrders', computed: { - ordersHistory () { - return this.$store.state.user.orders_history.items + ordersHistory() { + return this.$store.state.user.orders_history.items; }, - isHistoryEmpty () { - return this.$store.state.user.orders_history.items.length < 1 + isHistoryEmpty() { + return this.$store.state.user.orders_history.items.length < 1; } }, methods: { - remakeOrder (products) { + remakeOrder(products) { products.forEach(item => { - this.$store.dispatch('product/single', { options: { sku: item.sku }, setCurrentProduct: false, selectDefaultVariant: false }).then((product) => { - product.qty = item.qty_ordered - this.$store.dispatch('cart/addItem', { productToAdd: product }).then(() => { }) - }) - }) + this.$store + .dispatch('product/single', { + options: { sku: item.sku }, + setCurrentProduct: false, + selectDefaultVariant: false + }) + .then(product => { + product.qty = item.qty_ordered; + this.$store + .dispatch('cart/addItem', { productToAdd: product }) + .then(() => {}); + }); + }); }, - skipGrouped (items) { - return items.filter((item) => { - return !item.parent_item_id - }) + skipGrouped(items) { + return items.filter(item => { + return !item.parent_item_id; + }); } } -} +}; diff --git a/core/modules/order/components/UserSingleOrder.ts b/core/modules/order/components/UserSingleOrder.ts index 4f9b5c1209..269d2e0427 100644 --- a/core/modules/order/components/UserSingleOrder.ts +++ b/core/modules/order/components/UserSingleOrder.ts @@ -4,37 +4,48 @@ export const UserSingleOrder = { name: 'UserSingleOrder', computed: { - ordersHistory () { - return this.$store.state.user.orders_history.items + ordersHistory() { + return this.$store.state.user.orders_history.items; }, - order () { + order() { return this.ordersHistory.find(order => { - return parseInt(order.entity_id) === parseInt(this.$route.params.orderId) - }, (this)) + return ( + parseInt(order.entity_id) === parseInt(this.$route.params.orderId) + ); + }, this); }, - paymentMethod () { - return this.order.payment.additional_information[0] + paymentMethod() { + return this.order.payment.additional_information[0]; }, - billingAddress () { - return this.order.billing_address + billingAddress() { + return this.order.billing_address; }, - shippingAddress () { - return this.order.extension_attributes.shipping_assignments[0].shipping.address + shippingAddress() { + return this.order.extension_attributes.shipping_assignments[0].shipping + .address; } }, methods: { - remakeOrder (items) { + remakeOrder(items) { items.forEach(item => { - this.$store.dispatch('product/single', { options: { sku: item.sku }, setCurrentProduct: false, selectDefaultVariant: false }).then((product) => { - product.qty = item.qty_ordered - this.$store.dispatch('cart/addItem', { productToAdd: product }).then(() => { }) - }) - }) + this.$store + .dispatch('product/single', { + options: { sku: item.sku }, + setCurrentProduct: false, + selectDefaultVariant: false + }) + .then(product => { + product.qty = item.qty_ordered; + this.$store + .dispatch('cart/addItem', { productToAdd: product }) + .then(() => {}); + }); + }); }, - skipGrouped (items) { - return items.filter((item) => { - return !item.parent_item_id - }) + skipGrouped(items) { + return items.filter(item => { + return !item.parent_item_id; + }); } } -} +}; diff --git a/core/modules/order/hooks/beforeRegistration.ts b/core/modules/order/hooks/beforeRegistration.ts index 49b7df2c32..20aa51d7c8 100644 --- a/core/modules/order/hooks/beforeRegistration.ts +++ b/core/modules/order/hooks/beforeRegistration.ts @@ -1,10 +1,12 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; export function beforeRegistration({ Vue, config, store, isServer }) { - Vue.prototype.$db.ordersCollection = new UniversalStorage(localForage.createInstance({ - name: 'shop', - storeName: 'orders', - driver: localForage[config.localForage.defaultDrivers['orders']] - })) -} \ No newline at end of file + Vue.prototype.$db.ordersCollection = new UniversalStorage( + localForage.createInstance({ + name: 'shop', + storeName: 'orders', + driver: localForage[config.localForage.defaultDrivers['orders']] + }) + ); +} diff --git a/core/modules/order/index.ts b/core/modules/order/index.ts index 3499cbb764..57b6a8dc85 100644 --- a/core/modules/order/index.ts +++ b/core/modules/order/index.ts @@ -1,10 +1,10 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { module } from './store' -import { beforeRegistration } from './hooks/beforeRegistration' +import { createModule } from '@vue-storefront/core/lib/module'; +import { module } from './store'; +import { beforeRegistration } from './hooks/beforeRegistration'; -export const KEY = 'order' +export const KEY = 'order'; export const Order = createModule({ key: KEY, store: { modules: [{ key: KEY, module }] }, beforeRegistration -}) \ No newline at end of file +}); diff --git a/core/modules/order/store/actions.ts b/core/modules/order/store/actions.ts index 57b3e02cde..8a89b14732 100644 --- a/core/modules/order/store/actions.ts +++ b/core/modules/order/store/actions.ts @@ -1,15 +1,15 @@ -import Vue from 'vue' -import * as types from './mutation-types' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { ActionTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import OrderState from '../types/OrderState' -import { Order } from '../types/Order' -import rootStore from '@vue-storefront/core/store' -import { isOnline } from '@vue-storefront/core/lib/search' -import i18n from '@vue-storefront/i18n' -import { TaskQueue } from '@vue-storefront/core/lib/sync' -import { sha3_224 } from 'js-sha3' +import Vue from 'vue'; +import * as types from './mutation-types'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { ActionTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import OrderState from '../types/OrderState'; +import { Order } from '../types/Order'; +import rootStore from '@vue-storefront/core/store'; +import { isOnline } from '@vue-storefront/core/lib/search'; +import i18n from '@vue-storefront/i18n'; +import { TaskQueue } from '@vue-storefront/core/lib/sync'; +import { sha3_224 } from 'js-sha3'; const actions: ActionTree = { /** @@ -17,58 +17,72 @@ const actions: ActionTree = { * @param {Object} commit method * @param {Order} order order data to be send */ - async placeOrder ({ commit, getters }, order:Order) { + async placeOrder({ commit, getters }, order: Order) { // Check if order is already processed/processing - const currentOrderHash = sha3_224(JSON.stringify(order)) - const isAlreadyProcessed = getters.getSessionOrderHashes.includes(currentOrderHash) - if (isAlreadyProcessed) return - commit(types.ORDER_ADD_SESSION_ORDER_HASH, currentOrderHash) + const currentOrderHash = sha3_224(JSON.stringify(order)); + const isAlreadyProcessed = getters.getSessionOrderHashes.includes( + currentOrderHash + ); + if (isAlreadyProcessed) return; + commit(types.ORDER_ADD_SESSION_ORDER_HASH, currentOrderHash); - const storeView = currentStoreView() + const storeView = currentStoreView(); if (storeView.storeCode) { - order.store_code = storeView.storeCode + order.store_code = storeView.storeCode; } - Vue.prototype.$bus.$emit('order-before-placed', { order: order }) + Vue.prototype.$bus.$emit('order-before-placed', { order: order }); if (!rootStore.state.config.orders.directBackendSync || !isOnline()) { - commit(types.ORDER_PLACE_ORDER, order) - Vue.prototype.$bus.$emit('order-after-placed', { order: order }) + commit(types.ORDER_PLACE_ORDER, order); + Vue.prototype.$bus.$emit('order-after-placed', { order: order }); return { resultCode: 200 - } + }; } else { - Vue.prototype.$bus.$emit('notification-progress-start', i18n.t('Processing order...')) + Vue.prototype.$bus.$emit( + 'notification-progress-start', + i18n.t('Processing order...') + ); try { - const task:any = await TaskQueue.execute({ url: rootStore.state.config.orders.endpoint, // sync the order + const task: any = await TaskQueue.execute({ + url: rootStore.state.config.orders.endpoint, // sync the order payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, mode: 'cors', body: JSON.stringify(order) - }, - }) - Vue.prototype.$bus.$emit('notification-progress-stop') + } + }); + Vue.prototype.$bus.$emit('notification-progress-stop'); if (task.resultCode !== 500) { - order.transmited = true - commit(types.ORDER_PLACE_ORDER, order) // archive this order but not trasmit it second time - commit(types.ORDER_LAST_ORDER_WITH_CONFIRMATION, { order: order, confirmation: task.result }) - Vue.prototype.$bus.$emit('order-after-placed', { order: order, confirmation: task.result }) + order.transmited = true; + commit(types.ORDER_PLACE_ORDER, order); // archive this order but not trasmit it second time + commit(types.ORDER_LAST_ORDER_WITH_CONFIRMATION, { + order: order, + confirmation: task.result + }); + Vue.prototype.$bus.$emit('order-after-placed', { + order: order, + confirmation: task.result + }); } - return task + return task; } catch (e) { - commit(types.ORDER_REMOVE_SESSION_ORDER_HASH, currentOrderHash) + commit(types.ORDER_REMOVE_SESSION_ORDER_HASH, currentOrderHash); rootStore.dispatch('notification/spawnNotification', { type: 'error', - message: i18n.t('The order can not be transfered because of server error. Order has been queued'), + message: i18n.t( + 'The order can not be transfered because of server error. Order has been queued' + ), action1: { label: i18n.t('OK') } - }) - order.transmited = false // queue order - commit(types.ORDER_PLACE_ORDER, order) // archive this order but not trasmit it second time - Vue.prototype.$bus.$emit('notification-progress-stop') - throw e + }); + order.transmited = false; // queue order + commit(types.ORDER_PLACE_ORDER, order); // archive this order but not trasmit it second time + Vue.prototype.$bus.$emit('notification-progress-stop'); + throw e; } } } -} +}; -export default actions +export default actions; diff --git a/core/modules/order/store/getters.ts b/core/modules/order/store/getters.ts index 8b73ef39c3..a366d5786f 100644 --- a/core/modules/order/store/getters.ts +++ b/core/modules/order/store/getters.ts @@ -1,9 +1,9 @@ -import { GetterTree } from 'vuex' -import OrderState from '../types/OrderState' -import RootState from '@vue-storefront/core/types/RootState' +import { GetterTree } from 'vuex'; +import OrderState from '../types/OrderState'; +import RootState from '@vue-storefront/core/types/RootState'; const getters: GetterTree = { getSessionOrderHashes: state => state.session_order_hashes -} +}; -export default getters +export default getters; diff --git a/core/modules/order/store/index.ts b/core/modules/order/store/index.ts index 39cfb9779c..1f17b8d4dc 100644 --- a/core/modules/order/store/index.ts +++ b/core/modules/order/store/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import mutations from './mutations' -import getters from './getters' -import RootState from '@vue-storefront/core/types/RootState' -import OrderState from '../types/OrderState' +import { Module } from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; +import getters from './getters'; +import RootState from '@vue-storefront/core/types/RootState'; +import OrderState from '../types/OrderState'; export const module: Module = { namespaced: true, @@ -14,5 +14,4 @@ export const module: Module = { actions, mutations, getters -} - +}; diff --git a/core/modules/order/store/mutation-types.ts b/core/modules/order/store/mutation-types.ts index cb9dba69a1..a996f96aa5 100644 --- a/core/modules/order/store/mutation-types.ts +++ b/core/modules/order/store/mutation-types.ts @@ -1,6 +1,9 @@ -export const SN_ORDER = 'order' -export const ORDER_PLACE_ORDER = SN_ORDER + '/PLACE_ORDER' -export const ORDER_PROCESS_QUEUE = SN_ORDER + '/PROCESS_QUEUE' -export const ORDER_LAST_ORDER_WITH_CONFIRMATION = SN_ORDER + '/LAST_ORDER_CONFIRMATION' -export const ORDER_ADD_SESSION_ORDER_HASH = SN_ORDER + '/ADD_SESSION_ORDER_HASH' -export const ORDER_REMOVE_SESSION_ORDER_HASH = SN_ORDER + '/REMOVE_SESSION_ORDER_HASH' \ No newline at end of file +export const SN_ORDER = 'order'; +export const ORDER_PLACE_ORDER = SN_ORDER + '/PLACE_ORDER'; +export const ORDER_PROCESS_QUEUE = SN_ORDER + '/PROCESS_QUEUE'; +export const ORDER_LAST_ORDER_WITH_CONFIRMATION = + SN_ORDER + '/LAST_ORDER_CONFIRMATION'; +export const ORDER_ADD_SESSION_ORDER_HASH = + SN_ORDER + '/ADD_SESSION_ORDER_HASH'; +export const ORDER_REMOVE_SESSION_ORDER_HASH = + SN_ORDER + '/REMOVE_SESSION_ORDER_HASH'; diff --git a/core/modules/order/store/mutations.ts b/core/modules/order/store/mutations.ts index bb6780e52c..3592523148 100644 --- a/core/modules/order/store/mutations.ts +++ b/core/modules/order/store/mutations.ts @@ -1,42 +1,48 @@ -import Vue from 'vue' -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import * as entities from '@vue-storefront/core/store/lib/entities' -import OrderState from '../types/OrderState' -import rootStore from '@vue-storefront/core/store' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import * as entities from '@vue-storefront/core/store/lib/entities'; +import OrderState from '../types/OrderState'; +import rootStore from '@vue-storefront/core/store'; +import { Logger } from '@vue-storefront/core/lib/logger'; const mutations: MutationTree = { /** * Add order to sync. queue * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ - [types.ORDER_PLACE_ORDER] (state, order) { - const ordersCollection = Vue.prototype.$db.ordersCollection - const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough - order.order_id = orderId.toString() - order.created_at = new Date() - order.updated_at = new Date() + [types.ORDER_PLACE_ORDER](state, order) { + const ordersCollection = Vue.prototype.$db.ordersCollection; + const orderId = entities.uniqueEntityId(order); // timestamp as a order id is not the best we can do but it's enough + order.order_id = orderId.toString(); + order.created_at = new Date(); + order.updated_at = new Date(); - ordersCollection.setItem(orderId.toString(), order, (err, resp) => { - if (err) Logger.error(err, 'order')() - if (!order.transmited) { - Vue.prototype.$bus.$emit('order/PROCESS_QUEUE', { config: rootStore.state.config }) // process checkout queue - } - Logger.info('Order placed, orderId = ' + orderId, 'order')() - }).catch((reason) => { - Logger.error(reason, 'order') // it doesn't work on SSR - }) // populate cache + ordersCollection + .setItem(orderId.toString(), order, (err, resp) => { + if (err) Logger.error(err, 'order')(); + if (!order.transmited) { + Vue.prototype.$bus.$emit('order/PROCESS_QUEUE', { + config: rootStore.state.config + }); // process checkout queue + } + Logger.info('Order placed, orderId = ' + orderId, 'order')(); + }) + .catch(reason => { + Logger.error(reason, 'order'); // it doesn't work on SSR + }); // populate cache }, - [types.ORDER_LAST_ORDER_WITH_CONFIRMATION] (state, payload) { - state.last_order_confirmation = payload + [types.ORDER_LAST_ORDER_WITH_CONFIRMATION](state, payload) { + state.last_order_confirmation = payload; }, - [types.ORDER_ADD_SESSION_ORDER_HASH] (state, hash: string) { - state.session_order_hashes.push(hash) + [types.ORDER_ADD_SESSION_ORDER_HASH](state, hash: string) { + state.session_order_hashes.push(hash); }, - [types.ORDER_REMOVE_SESSION_ORDER_HASH] (state, hash: string) { - state.session_order_hashes = state.session_order_hashes.filter(sessionHash => sessionHash !== hash) + [types.ORDER_REMOVE_SESSION_ORDER_HASH](state, hash: string) { + state.session_order_hashes = state.session_order_hashes.filter( + sessionHash => sessionHash !== hash + ); } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/order/store/order.schema.json b/core/modules/order/store/order.schema.json index d5910dcd4b..7afa9fc0b3 100644 --- a/core/modules/order/store/order.schema.json +++ b/core/modules/order/store/order.schema.json @@ -1,89 +1,118 @@ // DEPRECATED -> Moved to Order.ts { - "additionalProperties": false, - "required": [ "products", "addressInformation" ], - "properties": { - "order_id" : { "type": "string" }, - "created_at" : { "type": "string" }, - "updated_at": { "type": "string" }, - "transmited" : { "type": "boolean" }, - "transmited_at": { "type": "string" }, - "status": { "type": "string" }, - "state": { "type": "string" }, - "user_id": { "type": "string" }, - "cart_id": { "type": "string" }, - "store_code": { "type": "string" }, - "store_id": { "type": "number" }, - "products": { - "description": "Products list", - "type": "array", - "minItems": 1, - "items": [ - { - "required": [ "sku", "price", "qty" ], - "properties": { - "sku": { "type": "string", "minLength": 1, "pattern": "[a-zA-Z0-9_]+" }, - "qty": { "type" : "number", "minimum": 1 }, - "name": { "type": "string", "minLength": 1, "pattern": "[a-zA-Z0-9_]+" }, - "price": { "type" : "number", "minimum": 1 }, - "product_type": { "type": "string", "minLength": 1, "pattern": "[a-zA-Z]+" } - } - } - ] - }, - "addressInformation": { - - "properties": { - "shippingAddress": { - "required": [ "street", "city", "postcode", "firstname", "lastname" ], - "properties": { - "region": { "type": "string" }, - "region_id": { "type": "number" }, - "country_id": { "type": "string", "pattern": "[a-zA-Z]" }, - "street": { - "description": "Street name", - "minItems": 1, - "items": { "minLength": 1, "description": "Street name"} - }, - "company": { "type": "string" }, - "telephone": { "type": "string" }, - "postcode": { "type": "string", "minLength": 3, "pattern": "[a-zA-Z0-9_]+" }, - "city": { "type": "string", "pattern": "[a-zA-Z]+" }, - "firstname": { "type": "string", "pattern": "[a-zA-Z]+", "description": "First name" }, - "lastname": { "type": "string", "pattern": "[a-zA-Z]+" }, - "email": { "type": "string", "pattern": "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" }, - "region_code":{ "type": "string" }, - "sameAsBilling": { "type": "number"} - } - }, - "billingAddress": { - "required": [ "street", "city", "postcode", "firstname", "lastname" ], - "properties": { - "properties": { - "region": { "type": "string" }, - "region_id": { "type": "number" }, - "country_id": { "type": "string", "pattern": "[a-zA-Z]" }, - "street": { - "minItems": 1, - "items": { "minLength": 1} - }, - "company": { "type": "string" }, - "telephone": { "type": "string" }, - "postcode": { "type": "string", "minLength": 3, "pattern": "[a-zA-Z0-9_]+" }, - "city": { "type": "string", "pattern": "[a-zA-Z]+" }, - "firstname": { "type": "string", "pattern": "[a-zA-Z]+" }, - "lastname": { "type": "string", "pattern": "[a-zA-Z]+" }, - "email": { "type": "string", "pattern": "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" }, - "region_code":{ "type": "string" }, - "sameAsBilling": { "type": "number"} - } - } - }, - "shipping_method_code": { "type": "string", "pattern": "[a-zA-Z]+" }, - "shipping_carrier_code": { "type": "string", "pattern": "[a-zA-Z]+" }, - "payment_method_code": { "type": "string", "pattern": "[a-zA-Z]+" }, - "payment_method_additional": {} + "additionalProperties": false, + "required": ["products", "addressInformation"], + "properties": { + "order_id": { "type": "string" }, + "created_at": { "type": "string" }, + "updated_at": { "type": "string" }, + "transmited": { "type": "boolean" }, + "transmited_at": { "type": "string" }, + "status": { "type": "string" }, + "state": { "type": "string" }, + "user_id": { "type": "string" }, + "cart_id": { "type": "string" }, + "store_code": { "type": "string" }, + "store_id": { "type": "number" }, + "products": { + "description": "Products list", + "type": "array", + "minItems": 1, + "items": [ + { + "required": ["sku", "price", "qty"], + "properties": { + "sku": { + "type": "string", + "minLength": 1, + "pattern": "[a-zA-Z0-9_]+" + }, + "qty": { "type": "number", "minimum": 1 }, + "name": { + "type": "string", + "minLength": 1, + "pattern": "[a-zA-Z0-9_]+" + }, + "price": { "type": "number", "minimum": 1 }, + "product_type": { + "type": "string", + "minLength": 1, + "pattern": "[a-zA-Z]+" } + } } + ] + }, + "addressInformation": { + "properties": { + "shippingAddress": { + "required": ["street", "city", "postcode", "firstname", "lastname"], + "properties": { + "region": { "type": "string" }, + "region_id": { "type": "number" }, + "country_id": { "type": "string", "pattern": "[a-zA-Z]" }, + "street": { + "description": "Street name", + "minItems": 1, + "items": { "minLength": 1, "description": "Street name" } + }, + "company": { "type": "string" }, + "telephone": { "type": "string" }, + "postcode": { + "type": "string", + "minLength": 3, + "pattern": "[a-zA-Z0-9_]+" + }, + "city": { "type": "string", "pattern": "[a-zA-Z]+" }, + "firstname": { + "type": "string", + "pattern": "[a-zA-Z]+", + "description": "First name" + }, + "lastname": { "type": "string", "pattern": "[a-zA-Z]+" }, + "email": { + "type": "string", + "pattern": "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" + }, + "region_code": { "type": "string" }, + "sameAsBilling": { "type": "number" } + } + }, + "billingAddress": { + "required": ["street", "city", "postcode", "firstname", "lastname"], + "properties": { + "properties": { + "region": { "type": "string" }, + "region_id": { "type": "number" }, + "country_id": { "type": "string", "pattern": "[a-zA-Z]" }, + "street": { + "minItems": 1, + "items": { "minLength": 1 } + }, + "company": { "type": "string" }, + "telephone": { "type": "string" }, + "postcode": { + "type": "string", + "minLength": 3, + "pattern": "[a-zA-Z0-9_]+" + }, + "city": { "type": "string", "pattern": "[a-zA-Z]+" }, + "firstname": { "type": "string", "pattern": "[a-zA-Z]+" }, + "lastname": { "type": "string", "pattern": "[a-zA-Z]+" }, + "email": { + "type": "string", + "pattern": "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" + }, + "region_code": { "type": "string" }, + "sameAsBilling": { "type": "number" } + } + } + }, + "shipping_method_code": { "type": "string", "pattern": "[a-zA-Z]+" }, + "shipping_carrier_code": { "type": "string", "pattern": "[a-zA-Z]+" }, + "payment_method_code": { "type": "string", "pattern": "[a-zA-Z]+" }, + "payment_method_additional": {} + } } -} \ No newline at end of file + } +} diff --git a/core/modules/order/types/Order.ts b/core/modules/order/types/Order.ts index 66ea7b00fb..d5b0f1e8f5 100644 --- a/core/modules/order/types/Order.ts +++ b/core/modules/order/types/Order.ts @@ -60,4 +60,4 @@ export interface Order { payment_method_additional?: any; [k: string]: any; }; -} \ No newline at end of file +} diff --git a/core/modules/order/types/OrderState.ts b/core/modules/order/types/OrderState.ts index b46794fc79..04e3bd9114 100644 --- a/core/modules/order/types/OrderState.ts +++ b/core/modules/order/types/OrderState.ts @@ -1,4 +1,4 @@ export default interface OrderState { - last_order_confirmation: any, - session_order_hashes: Array, + last_order_confirmation: any; + session_order_hashes: Array; } diff --git a/core/modules/recently-viewed/components/RecentlyViewed.js b/core/modules/recently-viewed/components/RecentlyViewed.js index c222f233c9..3e55e838c3 100644 --- a/core/modules/recently-viewed/components/RecentlyViewed.js +++ b/core/modules/recently-viewed/components/RecentlyViewed.js @@ -1,10 +1,8 @@ -import {mapState} from 'vuex' +import { mapState } from 'vuex'; export default { name: 'RecentlyViewed', computed: { - ...mapState('recently-viewed', [ - 'items' - ]) + ...mapState('recently-viewed', ['items']) } -} +}; diff --git a/core/modules/recently-viewed/hooks/afterRegistration.ts b/core/modules/recently-viewed/hooks/afterRegistration.ts index 8470789e3a..c4b9894d89 100644 --- a/core/modules/recently-viewed/hooks/afterRegistration.ts +++ b/core/modules/recently-viewed/hooks/afterRegistration.ts @@ -1,4 +1,4 @@ // This function will be fired both on server and client side context after registering other parts of the module -export function afterRegistration({ Vue, config, store, isServer }){ - if (!isServer) store.dispatch('recently-viewed/load') -} \ No newline at end of file +export function afterRegistration({ Vue, config, store, isServer }) { + if (!isServer) store.dispatch('recently-viewed/load'); +} diff --git a/core/modules/recently-viewed/index.ts b/core/modules/recently-viewed/index.ts index 49e45b0f80..c43f5976f0 100644 --- a/core/modules/recently-viewed/index.ts +++ b/core/modules/recently-viewed/index.ts @@ -1,13 +1,13 @@ -import { module } from './store' -import { plugin } from './store/plugin' -import { createModule } from '@vue-storefront/core/lib/module' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -import { afterRegistration } from './hooks/afterRegistration' +import { module } from './store'; +import { plugin } from './store/plugin'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { afterRegistration } from './hooks/afterRegistration'; -export const KEY = 'recently-viewed' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'recently-viewed'; +export const cacheStorage = initCacheStorage(KEY); export const RecentlyViewed = createModule({ key: KEY, store: { modules: [{ key: KEY, module }], plugin }, afterRegistration -}) +}); diff --git a/core/modules/recently-viewed/store/actions.ts b/core/modules/recently-viewed/store/actions.ts index 33915ed4a7..e979182d7f 100644 --- a/core/modules/recently-viewed/store/actions.ts +++ b/core/modules/recently-viewed/store/actions.ts @@ -1,19 +1,19 @@ -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import RootState from '@vue-storefront/core/types/RootState' -import RecentlyViewedState from '../types/RecentlyViewedState' -import { cacheStorage } from '../' +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import RootState from '@vue-storefront/core/types/RootState'; +import RecentlyViewedState from '../types/RecentlyViewedState'; +import { cacheStorage } from '../'; const actions: ActionTree = { load({ commit }) { cacheStorage.getItem('recently-viewed', (err, storedItems) => { - if (err) throw new Error(err) - commit(types.RECENTLY_VIEWED_LOAD, storedItems) - }) + if (err) throw new Error(err); + commit(types.RECENTLY_VIEWED_LOAD, storedItems); + }); }, addItem({ commit }, product) { - commit(types.RECENTLY_VIEWED_ADD_ITEM, { product }) + commit(types.RECENTLY_VIEWED_ADD_ITEM, { product }); } -} +}; -export default actions +export default actions; diff --git a/core/modules/recently-viewed/store/index.ts b/core/modules/recently-viewed/store/index.ts index c9f6824e25..1ea5ae6a44 100644 --- a/core/modules/recently-viewed/store/index.ts +++ b/core/modules/recently-viewed/store/index.ts @@ -1,8 +1,8 @@ -import { Module } from 'vuex' -import actions from './actions' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import RecentlyViewedState from '../types/RecentlyViewedState' +import { Module } from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import RecentlyViewedState from '../types/RecentlyViewedState'; export const module: Module = { namespaced: true, @@ -11,5 +11,4 @@ export const module: Module = { }, actions, mutations -} - +}; diff --git a/core/modules/recently-viewed/store/mutation-types.ts b/core/modules/recently-viewed/store/mutation-types.ts index df1361e485..b881307cd3 100644 --- a/core/modules/recently-viewed/store/mutation-types.ts +++ b/core/modules/recently-viewed/store/mutation-types.ts @@ -1,3 +1,3 @@ -export const SN_RECENTLY_VIEWED = 'recently-viewed' -export const RECENTLY_VIEWED_ADD_ITEM = SN_RECENTLY_VIEWED + '/ADD' -export const RECENTLY_VIEWED_LOAD = SN_RECENTLY_VIEWED + '/LOAD' +export const SN_RECENTLY_VIEWED = 'recently-viewed'; +export const RECENTLY_VIEWED_ADD_ITEM = SN_RECENTLY_VIEWED + '/ADD'; +export const RECENTLY_VIEWED_LOAD = SN_RECENTLY_VIEWED + '/LOAD'; diff --git a/core/modules/recently-viewed/store/mutations.ts b/core/modules/recently-viewed/store/mutations.ts index b81db83709..66758b4242 100644 --- a/core/modules/recently-viewed/store/mutations.ts +++ b/core/modules/recently-viewed/store/mutations.ts @@ -1,21 +1,21 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import RecentlyViewedState from '../types/RecentlyViewedState' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import RecentlyViewedState from '../types/RecentlyViewedState'; const mutations: MutationTree = { /** - * Add product to Recently Viewed Products - * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md - */ - [types.RECENTLY_VIEWED_ADD_ITEM] (state, { product }) { - const record = state.items.find(p => p.sku === product.sku) + * Add product to Recently Viewed Products + * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md + */ + [types.RECENTLY_VIEWED_ADD_ITEM](state, { product }) { + const record = state.items.find(p => p.sku === product.sku); if (!record) { - state.items.unshift(product) + state.items.unshift(product); } }, - [types.RECENTLY_VIEWED_LOAD] (state, storedItems) { - state.items = storedItems || [] + [types.RECENTLY_VIEWED_LOAD](state, storedItems) { + state.items = storedItems || []; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/recently-viewed/store/plugin.ts b/core/modules/recently-viewed/store/plugin.ts index aa7cd8a955..6a4f5d0735 100644 --- a/core/modules/recently-viewed/store/plugin.ts +++ b/core/modules/recently-viewed/store/plugin.ts @@ -1,13 +1,16 @@ -import * as types from './mutation-types' -import { cacheStorage } from '../' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as types from './mutation-types'; +import { cacheStorage } from '../'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export function plugin (mutation, state) { - const type = mutation.type +export function plugin(mutation, state) { + const type = mutation.type; - if (type.startsWith(types.SN_RECENTLY_VIEWED)) { // check if this mutation is recently-viewed related - cacheStorage.setItem('recently-viewed', state['recently-viewed'].items).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) + if (type.startsWith(types.SN_RECENTLY_VIEWED)) { + // check if this mutation is recently-viewed related + cacheStorage + .setItem('recently-viewed', state['recently-viewed'].items) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); } } diff --git a/core/modules/recently-viewed/types/RecentlyViewedState.ts b/core/modules/recently-viewed/types/RecentlyViewedState.ts index b857e32f74..387b9dc3ba 100644 --- a/core/modules/recently-viewed/types/RecentlyViewedState.ts +++ b/core/modules/recently-viewed/types/RecentlyViewedState.ts @@ -1,3 +1,3 @@ export default interface RecentlyViewedState { - items: any[] + items: any[]; } diff --git a/core/modules/review/components/AddReview.ts b/core/modules/review/components/AddReview.ts index 7fe9da2776..8fbd91cf7f 100644 --- a/core/modules/review/components/AddReview.ts +++ b/core/modules/review/components/AddReview.ts @@ -1,10 +1,10 @@ -import Review from '@vue-storefront/core/modules/review/types/Review' +import Review from '@vue-storefront/core/modules/review/types/Review'; export const AddReview = { name: 'AddReview', methods: { - addReview (review: Review) { - this.$store.dispatch('review/add', review) + addReview(review: Review) { + this.$store.dispatch('review/add', review); } } -} +}; diff --git a/core/modules/review/components/Reviews.ts b/core/modules/review/components/Reviews.ts index 26cea8f3ac..23fd5ae380 100644 --- a/core/modules/review/components/Reviews.ts +++ b/core/modules/review/components/Reviews.ts @@ -1,10 +1,10 @@ -import Review from '../types/Review' +import Review from '../types/Review'; export const Reviews = { name: 'Reviews', computed: { - reviews () : Review[] { - return this.$store.state.review.items.items + reviews(): Review[] { + return this.$store.state.review.items.items; } } -} +}; diff --git a/core/modules/review/index.ts b/core/modules/review/index.ts index 36c7f5da3a..a6da09e65d 100644 --- a/core/modules/review/index.ts +++ b/core/modules/review/index.ts @@ -1,8 +1,8 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; -export const KEY = 'review' +export const KEY = 'review'; export const Review = createModule({ key: KEY, - store: { modules: [{ key: KEY, module }] }, -}) \ No newline at end of file + store: { modules: [{ key: KEY, module }] } +}); diff --git a/core/modules/review/store/actions.ts b/core/modules/review/store/actions.ts index e4cdb2f1b4..cf01057d3c 100644 --- a/core/modules/review/store/actions.ts +++ b/core/modules/review/store/actions.ts @@ -1,16 +1,16 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import { quickSearchByQuery } from '@vue-storefront/core/lib/search' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { adjustMultistoreApiUrl } from '@vue-storefront/core/lib/multistore' -import RootState from '@vue-storefront/core/types/RootState' -import ReviewState from '../types/ReviewState' -import * as types from './mutation-types' -import i18n from '@vue-storefront/i18n' -import rootStore from '@vue-storefront/core/store' -import Review from '@vue-storefront/core/modules/review/types/Review' -import { ReviewRequest } from '@vue-storefront/core/modules/review/types/ReviewRequest' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import { quickSearchByQuery } from '@vue-storefront/core/lib/search'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { adjustMultistoreApiUrl } from '@vue-storefront/core/lib/multistore'; +import RootState from '@vue-storefront/core/types/RootState'; +import ReviewState from '../types/ReviewState'; +import * as types from './mutation-types'; +import i18n from '@vue-storefront/i18n'; +import rootStore from '@vue-storefront/core/store'; +import Review from '@vue-storefront/core/modules/review/types/Review'; +import { ReviewRequest } from '@vue-storefront/core/modules/review/types/ReviewRequest'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { /** @@ -26,22 +26,47 @@ const actions: ActionTree = { * @param {any} includeFields * @returns {Promise & Promise} */ - list (context, { productId, approved = true, start = 0, size = 50, entityType = 'review', sort = '', excludeFields = null, includeFields = null}) { - let query = new SearchQuery() + list( + context, + { + productId, + approved = true, + start = 0, + size = 50, + entityType = 'review', + sort = '', + excludeFields = null, + includeFields = null + } + ) { + let query = new SearchQuery(); if (productId) { - query = query.applyFilter({key: 'product_id', value: {'eq': productId}}) + query = query.applyFilter({ + key: 'product_id', + value: { eq: productId } + }); } if (approved) { - query = query.applyFilter({key: 'review_status', value: {'eq': 1}}) + query = query.applyFilter({ key: 'review_status', value: { eq: 1 } }); } - quickSearchByQuery({ query, start, size, entityType, sort, excludeFields, includeFields }).then((resp) => { - context.commit(types.REVIEW_UPD_REVIEWS, resp) - }).catch(err => { - Logger.error(err, 'review')() + quickSearchByQuery({ + query, + start, + size, + entityType, + sort, + excludeFields, + includeFields }) + .then(resp => { + context.commit(types.REVIEW_UPD_REVIEWS, resp); + }) + .catch(err => { + Logger.error(err, 'review')(); + }); }, /** @@ -51,42 +76,45 @@ const actions: ActionTree = { * @param {Review} reviewData * @returns {Promise} */ - async add (context, reviewData: Review) { - const review:ReviewRequest = {review: reviewData} + async add(context, reviewData: Review) { + const review: ReviewRequest = { review: reviewData }; - Vue.prototype.$bus.$emit('notification-progress-start', i18n.t('Adding a review ...')) + Vue.prototype.$bus.$emit( + 'notification-progress-start', + i18n.t('Adding a review ...') + ); - let url = rootStore.state.config.reviews.create_endpoint + let url = rootStore.state.config.reviews.create_endpoint; if (rootStore.state.config.storeViews.multistore) { - url = adjustMultistoreApiUrl(url) + url = adjustMultistoreApiUrl(url); } try { await fetch(url, { method: 'POST', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify(review) - }) - Vue.prototype.$bus.$emit('notification-progress-stop') + }); + Vue.prototype.$bus.$emit('notification-progress-stop'); rootStore.dispatch('notification/spawnNotification', { type: 'success', message: i18n.t('You submitted your review for moderation.'), action1: { label: i18n.t('OK') } - }) - Vue.prototype.$bus.$emit('clear-add-review-form') + }); + Vue.prototype.$bus.$emit('clear-add-review-form'); } catch (e) { - Vue.prototype.$bus.$emit('notification-progress-stop') + Vue.prototype.$bus.$emit('notification-progress-stop'); rootStore.dispatch('notification/spawnNotification', { type: 'error', message: i18n.t('Something went wrong. Try again in a few seconds.'), action1: { label: i18n.t('OK') } - }) - }; + }); + } } -} +}; -export default actions +export default actions; diff --git a/core/modules/review/store/index.ts b/core/modules/review/store/index.ts index e2fb7e6ed9..559b276fc3 100644 --- a/core/modules/review/store/index.ts +++ b/core/modules/review/store/index.ts @@ -1,14 +1,14 @@ -import { Module } from 'vuex' -import actions from './actions' -import mutations from "./mutations"; -import RootState from "@vue-storefront/core/types/RootState"; -import ReviewState from "../types/ReviewState"; +import { Module } from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import ReviewState from '../types/ReviewState'; export const module: Module = { namespaced: true, state: { - items: [], + items: [] }, actions, mutations -} +}; diff --git a/core/modules/review/store/mutation-types.ts b/core/modules/review/store/mutation-types.ts index 33b5fccc72..916a563654 100644 --- a/core/modules/review/store/mutation-types.ts +++ b/core/modules/review/store/mutation-types.ts @@ -1,2 +1,2 @@ -export const SN_REVIEW = 'review' -export const REVIEW_UPD_REVIEWS = SN_REVIEW + '/UPD_REVIEWS' +export const SN_REVIEW = 'review'; +export const REVIEW_UPD_REVIEWS = SN_REVIEW + '/UPD_REVIEWS'; diff --git a/core/modules/review/store/mutations.ts b/core/modules/review/store/mutations.ts index c6b9c43a40..32ae1124b0 100644 --- a/core/modules/review/store/mutations.ts +++ b/core/modules/review/store/mutations.ts @@ -1,11 +1,11 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import ReviewState from '../types/ReviewState' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import ReviewState from '../types/ReviewState'; const mutations: MutationTree = { - [types.REVIEW_UPD_REVIEWS] (state, items) { - state.items = items + [types.REVIEW_UPD_REVIEWS](state, items) { + state.items = items; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/review/types/ReviewRequest.ts b/core/modules/review/types/ReviewRequest.ts index 2d34f6419f..a35b038709 100644 --- a/core/modules/review/types/ReviewRequest.ts +++ b/core/modules/review/types/ReviewRequest.ts @@ -3,4 +3,4 @@ import Review from './Review'; export interface ReviewRequest { review: Review; [k: string]: any; -} \ No newline at end of file +} diff --git a/core/modules/review/types/ReviewState.ts b/core/modules/review/types/ReviewState.ts index b0fc96348f..8673cd9788 100644 --- a/core/modules/review/types/ReviewState.ts +++ b/core/modules/review/types/ReviewState.ts @@ -1,3 +1,3 @@ export default interface ReviewState { - items: any[] + items: any[]; } diff --git a/core/modules/social-share/components/WebShare.vue b/core/modules/social-share/components/WebShare.vue index 3cdda8837f..b9f97741bd 100644 --- a/core/modules/social-share/components/WebShare.vue +++ b/core/modules/social-share/components/WebShare.vue @@ -2,15 +2,25 @@ - + + + + diff --git a/core/modules/url/helpers/index.ts b/core/modules/url/helpers/index.ts index a9e7aa114e..6c8a59764d 100644 --- a/core/modules/url/helpers/index.ts +++ b/core/modules/url/helpers/index.ts @@ -1,84 +1,129 @@ -import { router } from '@vue-storefront/core/app' -import rootStore from '@vue-storefront/core/store' -import { localizedDispatcherRoute, localizedRoute, LocalizedRoute } from '@vue-storefront/core/lib/multistore' +import { router } from '@vue-storefront/core/app'; +import rootStore from '@vue-storefront/core/store'; +import { + localizedDispatcherRoute, + localizedRoute, + LocalizedRoute +} from '@vue-storefront/core/lib/multistore'; import { RouteConfig } from 'vue-router/types/router'; -import { RouterManager } from '@vue-storefront/core/lib/router-manager' +import { RouterManager } from '@vue-storefront/core/lib/router-manager'; -export function parametrizeRouteData (routeData: LocalizedRoute, query: { [id: string]: any } | string, storeCodeInPath: string): LocalizedRoute { - const parametrizedRoute = Object.assign({}, routeData) - parametrizedRoute.params = Object.assign({}, parametrizedRoute.params || {}, query) - if (storeCodeInPath && !parametrizedRoute.name.startsWith(storeCodeInPath + '-')) { - parametrizedRoute.name = storeCodeInPath + '-' + parametrizedRoute.name +export function parametrizeRouteData( + routeData: LocalizedRoute, + query: { [id: string]: any } | string, + storeCodeInPath: string +): LocalizedRoute { + const parametrizedRoute = Object.assign({}, routeData); + parametrizedRoute.params = Object.assign( + {}, + parametrizedRoute.params || {}, + query + ); + if ( + storeCodeInPath && + !parametrizedRoute.name.startsWith(storeCodeInPath + '-') + ) { + parametrizedRoute.name = storeCodeInPath + '-' + parametrizedRoute.name; } - return parametrizedRoute + return parametrizedRoute; } -export function processDynamicRoute(routeData: LocalizedRoute, fullPath: string, addToRoutes: boolean = true): LocalizedRoute[] { - const userRoute = RouterManager.findByName(routeData.name) +export function processDynamicRoute( + routeData: LocalizedRoute, + fullPath: string, + addToRoutes: boolean = true +): LocalizedRoute[] { + const userRoute = RouterManager.findByName(routeData.name); if (userRoute) { - const config = rootStore.state.config + const config = rootStore.state.config; if (addToRoutes) { - const routes = [] - const rootDynamicRoute = Object.assign({}, userRoute, routeData, { path: '/' + fullPath, name: `urldispatcher-${fullPath}` }) - routes.push(rootDynamicRoute) - if (config.storeViews.mapStoreUrlsFor.length > 0 && config.storeViews.multistore === true) { + const routes = []; + const rootDynamicRoute = Object.assign({}, userRoute, routeData, { + path: '/' + fullPath, + name: `urldispatcher-${fullPath}` + }); + routes.push(rootDynamicRoute); + if ( + config.storeViews.mapStoreUrlsFor.length > 0 && + config.storeViews.multistore === true + ) { for (let storeCode of config.storeViews.mapStoreUrlsFor) { if (storeCode) { - const dynamicRoute = Object.assign({}, userRoute, routeData, { path: '/' + ((rootStore.state.config.defaultStoreCode !== storeCode) ? (storeCode + '/') : '') + fullPath, name: `urldispatcher-${fullPath}-${storeCode}` }) - routes.push(dynamicRoute) + const dynamicRoute = Object.assign({}, userRoute, routeData, { + path: + '/' + + (rootStore.state.config.defaultStoreCode !== storeCode + ? storeCode + '/' + : '') + + fullPath, + name: `urldispatcher-${fullPath}-${storeCode}` + }); + routes.push(dynamicRoute); } } } - RouterManager.addRoutes(routes, router) - return routes + RouterManager.addRoutes(routes, router); + return routes; } else { - const dynamicRoute = Object.assign({}, userRoute, routeData, { path: '/' + fullPath, name: `urldispatcher-${fullPath}` }) - return [dynamicRoute] + const dynamicRoute = Object.assign({}, userRoute, routeData, { + path: '/' + fullPath, + name: `urldispatcher-${fullPath}` + }); + return [dynamicRoute]; } } else { - return null + return null; } } export function findRouteByPath(fullPath: string): RouteConfig { - return RouterManager.findByPath(fullPath) + return RouterManager.findByPath(fullPath); } export function normalizeUrlPath(url: string): string { if (url && url.length > 0) { - if (url[0] === '/') url = url.slice(1) - const queryPos = url.indexOf('?') - if (queryPos > 0) url = url.slice(0, queryPos) + if (url[0] === '/') url = url.slice(1); + const queryPos = url.indexOf('?'); + if (queryPos > 0) url = url.slice(0, queryPos); } - return url + return url; } -export function formatCategoryLink(category: { url_path: string, slug: string }): string { - return rootStore.state.config.seo.useUrlDispatcher ? ('/' + category.url_path) : ((rootStore.state.config.products.useShortCatalogUrls ? '/' : '/c/') + category.slug) +export function formatCategoryLink(category: { + url_path: string; + slug: string; +}): string { + return rootStore.state.config.seo.useUrlDispatcher + ? '/' + category.url_path + : (rootStore.state.config.products.useShortCatalogUrls ? '/' : '/c/') + + category.slug; } export function formatProductLink( product: { - parentSku?: string, - sku: string, - url_path?: string, - type_id: string, - slug: string, - configurable_children: [] + parentSku?: string; + sku: string; + url_path?: string; + type_id: string; + slug: string; + configurable_children: []; }, storeCode ): string | LocalizedRoute { if (rootStore.state.config.seo.useUrlDispatcher && product.url_path) { let routeData: LocalizedRoute; - if (product.configurable_children && product.configurable_children.length > 0) { + if ( + product.configurable_children && + product.configurable_children.length > 0 + ) { routeData = { fullPath: product.url_path, params: { childSku: product.sku } - } + }; } else { - routeData = { fullPath: product.url_path } + routeData = { fullPath: product.url_path }; } - return localizedDispatcherRoute(routeData, storeCode) + return localizedDispatcherRoute(routeData, storeCode); } else { const routeData: LocalizedRoute = { name: product.type_id + '-product', @@ -87,7 +132,7 @@ export function formatProductLink( slug: product.slug, childSku: product.sku } - } - return localizedRoute(routeData, storeCode) + }; + return localizedRoute(routeData, storeCode); } } diff --git a/core/modules/url/index.ts b/core/modules/url/index.ts index e952f9ad65..20d7e2d656 100644 --- a/core/modules/url/index.ts +++ b/core/modules/url/index.ts @@ -1,16 +1,18 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -import { beforeEach } from './router/beforeEach' +import { + VueStorefrontModule, + VueStorefrontModuleConfig +} from '@vue-storefront/core/lib/module'; +import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { beforeEach } from './router/beforeEach'; -export const KEY = 'url' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'url'; +export const cacheStorage = initCacheStorage(KEY); export const Url = createModule({ key: KEY, store: { modules: [{ key: KEY, module }] }, router: { beforeEach } -}) - +}); diff --git a/core/modules/url/router/beforeEach.ts b/core/modules/url/router/beforeEach.ts index b7585c0b2a..e904560b88 100644 --- a/core/modules/url/router/beforeEach.ts +++ b/core/modules/url/router/beforeEach.ts @@ -1,56 +1,81 @@ // This function will be executed before entering each route. // It's important to have 'next()'. It enables navigation to new route. // See https://router.vuejs.org/guide/advanced/navigation-guards.html#global-guards -import { Route } from 'vue-router' -import store from '@vue-storefront/core/store' -import { Logger } from '@vue-storefront/core/lib/logger' -import { processDynamicRoute, normalizeUrlPath } from '../helpers' -import { isServer } from '@vue-storefront/core/helpers' -import { storeCodeFromRoute, prepareStoreView, currentStoreView, LocalizedRoute } from '@vue-storefront/core/lib/multistore' -import Vue from 'vue' +import { Route } from 'vue-router'; +import store from '@vue-storefront/core/store'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { processDynamicRoute, normalizeUrlPath } from '../helpers'; +import { isServer } from '@vue-storefront/core/helpers'; +import { + storeCodeFromRoute, + prepareStoreView, + currentStoreView, + LocalizedRoute +} from '@vue-storefront/core/lib/multistore'; +import Vue from 'vue'; -export const UrlDispatchMapper = async (to) => { - const routeData = await store.dispatch('url/mapUrl', { url: to.fullPath, query: to.query }) - return Object.assign({}, to, routeData) -} +export const UrlDispatchMapper = async to => { + const routeData = await store.dispatch('url/mapUrl', { + url: to.fullPath, + query: to.query + }); + return Object.assign({}, to, routeData); +}; export function beforeEach(to: Route, from: Route, next) { if (isServer) { - if (store.state.config.storeViews.multistore) { // this is called before server-entry.ts router.onReady - so we have to make sure we're in the right store context - const storeCode = storeCodeFromRoute(to) + if (store.state.config.storeViews.multistore) { + // this is called before server-entry.ts router.onReady - so we have to make sure we're in the right store context + const storeCode = storeCodeFromRoute(to); if (storeCode) { - prepareStoreView(storeCode) + prepareStoreView(storeCode); } } } - const fullPath = normalizeUrlPath(to.fullPath) - const hasRouteParams = to.hasOwnProperty('params') && Object.values(to.params).length > 0 - const isPreviouslyDispatchedDynamicRoute = to.matched.length > 0 && to.name && to.name.startsWith('urldispatcher') - if (!to.matched.length || (isPreviouslyDispatchedDynamicRoute && !hasRouteParams)) { - UrlDispatchMapper(to).then((routeData) => { - if (routeData) { - let dynamicRoutes: LocalizedRoute[] = processDynamicRoute(routeData, fullPath, !isPreviouslyDispatchedDynamicRoute) - if (dynamicRoutes && dynamicRoutes.length > 0) { - next(dynamicRoutes[0]) + const fullPath = normalizeUrlPath(to.fullPath); + const hasRouteParams = + to.hasOwnProperty('params') && Object.values(to.params).length > 0; + const isPreviouslyDispatchedDynamicRoute = + to.matched.length > 0 && to.name && to.name.startsWith('urldispatcher'); + if ( + !to.matched.length || + (isPreviouslyDispatchedDynamicRoute && !hasRouteParams) + ) { + UrlDispatchMapper(to) + .then(routeData => { + if (routeData) { + let dynamicRoutes: LocalizedRoute[] = processDynamicRoute( + routeData, + fullPath, + !isPreviouslyDispatchedDynamicRoute + ); + if (dynamicRoutes && dynamicRoutes.length > 0) { + next(dynamicRoutes[0]); + } else { + Logger.error( + 'Route not found ' + routeData['name'], + 'dispatcher' + )(); + next('/page-not-found'); + } } else { - Logger.error('Route not found ' + routeData['name'], 'dispatcher')() - next('/page-not-found') + Logger.error('No mapping found for ' + fullPath, 'dispatcher')(); + next('/page-not-found'); } - } else { - Logger.error('No mapping found for ' + fullPath, 'dispatcher')() - next('/page-not-found') - } - }).catch(e => { - Logger.error(e, 'dispatcher')() - if (!isServer) { - next('/page-not-found') - } else { - const storeCode = currentStoreView().storeCode - Vue.prototype.$ssrRequestContext.server.response.redirect((storeCode !== '' ? ('/' + storeCode) : '') + '/page-not-found') // TODO: Refactor this one after @filrak will give us a way to access ServerContext from Modules directly :-) - // ps. we can't use the next() call here as it's not doing the real redirect in SSR mode (just processing different component without changing the URL and that causes the CSR / SSR DOM mismatch while hydrating) - } - }) + }) + .catch(e => { + Logger.error(e, 'dispatcher')(); + if (!isServer) { + next('/page-not-found'); + } else { + const storeCode = currentStoreView().storeCode; + Vue.prototype.$ssrRequestContext.server.response.redirect( + (storeCode !== '' ? '/' + storeCode : '') + '/page-not-found' + ); // TODO: Refactor this one after @filrak will give us a way to access ServerContext from Modules directly :-) + // ps. we can't use the next() call here as it's not doing the real redirect in SSR mode (just processing different component without changing the URL and that causes the CSR / SSR DOM mismatch while hydrating) + } + }); } else { - next() + next(); } } diff --git a/core/modules/url/store/actions.ts b/core/modules/url/store/actions.ts index 82ea5c88d4..bbda97a03f 100644 --- a/core/modules/url/store/actions.ts +++ b/core/modules/url/store/actions.ts @@ -1,65 +1,94 @@ -import { UrlState } from '../types/UrlState' +import { UrlState } from '../types/UrlState'; import { ActionTree } from 'vuex'; -import * as types from './mutation-types' +import * as types from './mutation-types'; // you can use this storage if you want to enable offline capabilities -import { cacheStorage } from '../' -import queryString from 'query-string' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { processDynamicRoute, normalizeUrlPath, parametrizeRouteData } from '../helpers' -import { storeCodeFromRoute, removeStoreCodeFromRoute } from '@vue-storefront/core/lib/multistore' +import { cacheStorage } from '../'; +import queryString from 'query-string'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { + processDynamicRoute, + normalizeUrlPath, + parametrizeRouteData +} from '../helpers'; +import { + storeCodeFromRoute, + removeStoreCodeFromRoute +} from '@vue-storefront/core/lib/multistore'; // it's a good practice for all actions to return Promises with effect of their execution export const actions: ActionTree = { // if you want to use cache in your module you can load cached data like this - async registerMapping ({ commit }, { url, routeData }: { url: string, routeData: any}) { - commit(types.REGISTER_MAPPING, { url, routeData }) - await cacheStorage.setItem(url, routeData) - return routeData + async registerMapping( + { commit }, + { url, routeData }: { url: string; routeData: any } + ) { + commit(types.REGISTER_MAPPING, { url, routeData }); + await cacheStorage.setItem(url, routeData); + return routeData; }, /** * Register dynamic vue-router routes */ - async registerDynamicRoutes ({ state, dispatch }) { + async registerDynamicRoutes({ state, dispatch }) { if (state.dispatcherMap) { for (const [url, routeData] of Object.entries(state.dispatcherMap)) { - processDynamicRoute (routeData, url) - dispatch('registerMapping', { url, routeData }) + processDynamicRoute(routeData, url); + dispatch('registerMapping', { url, routeData }); } } }, - mapUrl ({ state, dispatch }, { url, query }: { url: string, query: string}) { - const parsedQuery = typeof query === 'string' ? queryString.parse(query) : query - const storeCodeInPath = storeCodeFromRoute(url) - url = normalizeUrlPath(url) + mapUrl({ state, dispatch }, { url, query }: { url: string; query: string }) { + const parsedQuery = + typeof query === 'string' ? queryString.parse(query) : query; + const storeCodeInPath = storeCodeFromRoute(url); + url = normalizeUrlPath(url); - return new Promise ((resolve, reject) => { + return new Promise((resolve, reject) => { if (state.dispatcherMap[url]) { - return resolve (parametrizeRouteData(state.dispatcherMap[url], query, storeCodeInPath)) + return resolve( + parametrizeRouteData(state.dispatcherMap[url], query, storeCodeInPath) + ); } - cacheStorage.getItem(url).then(routeData => { - if (routeData !== null) { - return resolve(parametrizeRouteData(routeData, query, storeCodeInPath)) - } else { - dispatch('mappingFallback', { url, params: parsedQuery }).then((routeData) => { - dispatch('registerMapping', { url, routeData }) // register mapping for further usage - resolve(parametrizeRouteData(routeData, query, storeCodeInPath)) - }).catch(reject) - } - }).catch(reject) - }) + cacheStorage + .getItem(url) + .then(routeData => { + if (routeData !== null) { + return resolve( + parametrizeRouteData(routeData, query, storeCodeInPath) + ); + } else { + dispatch('mappingFallback', { url, params: parsedQuery }) + .then(routeData => { + dispatch('registerMapping', { url, routeData }); // register mapping for further usage + resolve( + parametrizeRouteData(routeData, query, storeCodeInPath) + ); + }) + .catch(reject); + } + }) + .catch(reject); + }); }, - + /** * Router mapping fallback - get the proper URL from API * This method could be overriden in custom module to provide custom URL mapping logic */ - async mappingFallback ({ dispatch }, { url, params }: { url: string, params: any}) { - const productQuery = new SearchQuery() - url = (removeStoreCodeFromRoute(url) as string) - productQuery.applyFilter({key: 'url_path', value: {'eq': url}}) // Tees category - const products = await dispatch('product/list', { query: productQuery }, { root: true }) + async mappingFallback( + { dispatch }, + { url, params }: { url: string; params: any } + ) { + const productQuery = new SearchQuery(); + url = removeStoreCodeFromRoute(url) as string; + productQuery.applyFilter({ key: 'url_path', value: { eq: url } }); // Tees category + const products = await dispatch( + 'product/list', + { query: productQuery }, + { root: true } + ); if (products && products.items && products.items.length) { - const product = products.items[0] + const product = products.items[0]; return { name: product.type_id + '-product', params: { @@ -67,17 +96,21 @@ export const actions: ActionTree = { parentSku: product.sku, childSku: params['childSku'] ? params['childSku'] : product.sku } - } + }; } else { - const category = await dispatch('category/single', { key: 'url_path', value: url }, { root: true }) + const category = await dispatch( + 'category/single', + { key: 'url_path', value: url }, + { root: true } + ); if (category !== null) { return { name: 'category', params: { slug: category.slug } - } + }; } } } -} +}; diff --git a/core/modules/url/store/index.ts b/core/modules/url/store/index.ts index 0c18776f1d..bbd4238fa9 100644 --- a/core/modules/url/store/index.ts +++ b/core/modules/url/store/index.ts @@ -1,12 +1,12 @@ -import { Module } from 'vuex' -import { UrlState } from '../types/UrlState' -import { mutations } from './mutations' -import { actions } from './actions' -import { state } from './state' +import { Module } from 'vuex'; +import { UrlState } from '../types/UrlState'; +import { mutations } from './mutations'; +import { actions } from './actions'; +import { state } from './state'; export const module: Module = { namespaced: true, mutations, actions, state -} \ No newline at end of file +}; diff --git a/core/modules/url/store/mutation-types.ts b/core/modules/url/store/mutation-types.ts index 5f047c63b8..392d1757cc 100644 --- a/core/modules/url/store/mutation-types.ts +++ b/core/modules/url/store/mutation-types.ts @@ -1 +1 @@ -export const REGISTER_MAPPING = 'URL/REGISTER_MAPPING' +export const REGISTER_MAPPING = 'URL/REGISTER_MAPPING'; diff --git a/core/modules/url/store/mutations.ts b/core/modules/url/store/mutations.ts index 9dcae4e7b5..62f4ec70af 100644 --- a/core/modules/url/store/mutations.ts +++ b/core/modules/url/store/mutations.ts @@ -1,8 +1,8 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; export const mutations: MutationTree = { - [types.REGISTER_MAPPING] (state, payload) { - state.dispatcherMap[payload.url] = payload.routeData + [types.REGISTER_MAPPING](state, payload) { + state.dispatcherMap[payload.url] = payload.routeData; } -} \ No newline at end of file +}; diff --git a/core/modules/url/store/state.ts b/core/modules/url/store/state.ts index ad5e784b78..789b2bb959 100644 --- a/core/modules/url/store/state.ts +++ b/core/modules/url/store/state.ts @@ -1,5 +1,5 @@ -import { UrlState } from '../types/UrlState' +import { UrlState } from '../types/UrlState'; export const state: UrlState = { dispatcherMap: {} -} \ No newline at end of file +}; diff --git a/core/modules/url/types/UrlState.ts b/core/modules/url/types/UrlState.ts index 276cd754d8..f263d9a1d8 100644 --- a/core/modules/url/types/UrlState.ts +++ b/core/modules/url/types/UrlState.ts @@ -3,5 +3,5 @@ import { LocalizedRoute } from 'core/lib/multistore'; // This object should represent structure of your modules Vuex state // It's a good practice is to name this interface accordingly to the KET (for example mailchimpState) export interface UrlState { - dispatcherMap: { [path: string]: LocalizedRoute} -} \ No newline at end of file + dispatcherMap: { [path: string]: LocalizedRoute }; +} diff --git a/core/modules/user/components/AccountButton.ts b/core/modules/user/components/AccountButton.ts index 366130aa2d..4511ec140e 100644 --- a/core/modules/user/components/AccountButton.ts +++ b/core/modules/user/components/AccountButton.ts @@ -1,26 +1,25 @@ - export const AccountButton = { name: 'AccountButton', computed: { - isLoggedIn () { - return this.$store.getters['user/isLoggedIn'] + isLoggedIn() { + return this.$store.getters['user/isLoggedIn']; }, - user () { - return this.$store.state.user.current + user() { + return this.$store.state.user.current; } }, methods: { - goToAccount () { + goToAccount() { if (this.currentUser) { - this.$router.push(this.localizedRoute('/my-account')) + this.$router.push(this.localizedRoute('/my-account')); } else { - this.$store.commit('ui/setAuthElem', 'login') - this.$bus.$emit('modal-show', 'modal-signup') + this.$store.commit('ui/setAuthElem', 'login'); + this.$bus.$emit('modal-show', 'modal-signup'); } }, - logout () { - this.$bus.$emit('user-before-logout') - this.$router.push(this.localizedRoute('/')) + logout() { + this.$bus.$emit('user-before-logout'); + this.$router.push(this.localizedRoute('/')); } } -} +}; diff --git a/core/modules/user/components/Login.ts b/core/modules/user/components/Login.ts index 192483ad27..33b08c66af 100644 --- a/core/modules/user/components/Login.ts +++ b/core/modules/user/components/Login.ts @@ -1,40 +1,49 @@ -import i18n from '@vue-storefront/i18n' -import { Logger } from '@vue-storefront/core/lib/logger' +import i18n from '@vue-storefront/i18n'; +import { Logger } from '@vue-storefront/core/lib/logger'; export const Login = { name: 'Login', - data () { + data() { return { remember: false, email: '', password: '' - } + }; }, methods: { - callLogin () { - this.$bus.$emit('notification-progress-start', i18n.t('Authorization in progress ...')) - this.$store.dispatch('user/login', { username: this.email, password: this.password }).then((result) => { - this.$bus.$emit('notification-progress-stop', {}) + callLogin() { + this.$bus.$emit( + 'notification-progress-start', + i18n.t('Authorization in progress ...') + ); + this.$store + .dispatch('user/login', { + username: this.email, + password: this.password + }) + .then(result => { + this.$bus.$emit('notification-progress-stop', {}); - if (result.code !== 200) { - this.onFailure(result) - } else { - this.onSuccess() - this.close() - } - }).catch(err => { - Logger.error(err, 'user')() - // TODO Move to theme - this.$bus.$emit('notification-progress-stop') - }) + if (result.code !== 200) { + this.onFailure(result); + } else { + this.onSuccess(); + this.close(); + } + }) + .catch(err => { + Logger.error(err, 'user')(); + // TODO Move to theme + this.$bus.$emit('notification-progress-stop'); + }); }, - switchElem () { + switchElem() { // TODO Move to theme - this.$store.commit('ui/setAuthElem', 'register') + this.$store.commit('ui/setAuthElem', 'register'); }, - callForgotPassword () { + callForgotPassword() { // TODO Move to theme - this.$store.commit('ui/setAuthElem', 'forgot-pass') + this.$store.commit('ui/setAuthElem', 'forgot-pass'); } } -} +}; diff --git a/core/modules/user/components/Register.ts b/core/modules/user/components/Register.ts index 41caa69304..aae240c9ef 100644 --- a/core/modules/user/components/Register.ts +++ b/core/modules/user/components/Register.ts @@ -1,9 +1,9 @@ -import i18n from '@vue-storefront/i18n' -import { Logger } from '@vue-storefront/core/lib/logger' +import i18n from '@vue-storefront/i18n'; +import { Logger } from '@vue-storefront/core/lib/logger'; export const Register = { name: 'Register', - data () { + data() { return { email: '', firstName: '', @@ -11,41 +11,52 @@ export const Register = { password: '', rPassword: '', conditions: false - } + }; }, methods: { - switchElem () { + switchElem() { // TODO Move to theme - this.$store.commit('ui/setAuthElem', 'login') + this.$store.commit('ui/setAuthElem', 'login'); }, - close () { + close() { // TODO Move to theme - this.$bus.$emit('modal-hide', 'modal-signup') + this.$bus.$emit('modal-hide', 'modal-signup'); }, - callRegister () { + callRegister() { // TODO Move to theme - this.$bus.$emit('notification-progress-start', i18n.t('Registering the account ...')) - this.$store.dispatch('user/register', { email: this.email, password: this.password, firstname: this.firstName, lastname: this.lastName }).then((result) => { - Logger.debug(result, 'user')() - // TODO Move to theme - this.$bus.$emit('notification-progress-stop') - if (result.code !== 200) { - this.onFailure(result) - // If error includes a word 'password', focus on a corresponding field - if (result.result.includes('password')) { - this.$refs['password'].setFocus('password') - this.password = '' - this.rPassword = '' + this.$bus.$emit( + 'notification-progress-start', + i18n.t('Registering the account ...') + ); + this.$store + .dispatch('user/register', { + email: this.email, + password: this.password, + firstname: this.firstName, + lastname: this.lastName + }) + .then(result => { + Logger.debug(result, 'user')(); + // TODO Move to theme + this.$bus.$emit('notification-progress-stop'); + if (result.code !== 200) { + this.onFailure(result); + // If error includes a word 'password', focus on a corresponding field + if (result.result.includes('password')) { + this.$refs['password'].setFocus('password'); + this.password = ''; + this.rPassword = ''; + } + } else { + this.onSuccess(); + this.close(); } - } else { - this.onSuccess() - this.close() - } - }).catch(err => { - // TODO Move to theme - this.$bus.$emit('notification-progress-stop') - Logger.error(err, 'user')() - }) + }) + .catch(err => { + // TODO Move to theme + this.$bus.$emit('notification-progress-stop'); + Logger.error(err, 'user')(); + }); } } -} +}; diff --git a/core/modules/user/components/UserAccount.ts b/core/modules/user/components/UserAccount.ts index bce8d0d0a5..ec4e9479a2 100644 --- a/core/modules/user/components/UserAccount.ts +++ b/core/modules/user/components/UserAccount.ts @@ -1,9 +1,9 @@ -const Countries = require('@vue-storefront/core/i18n/resource/countries.json') -import toString from 'lodash-es/toString' +const Countries = require('@vue-storefront/core/i18n/resource/countries.json'); +import toString from 'lodash-es/toString'; export const UserAccount = { name: 'UserAccount', - data () { + data() { return { currentUser: Object.assign({}, this.$store.state.user.current), userCompany: { @@ -25,94 +25,122 @@ export const UserAccount = { addCompany: false, isEdited: false, remainInEditMode: false - } + }; }, - beforeMount () { - this.$bus.$on('user-after-loggedin', this.onLoggedIn) + beforeMount() { + this.$bus.$on('user-after-loggedin', this.onLoggedIn); this.$bus.$on('myAccount-before-remainInEditMode', block => { if (block === 'MyProfile') { - this.remainInEditMode = true + this.remainInEditMode = true; } - }) + }); }, - beforeDestroy () { - this.$bus.$off('user-after-loggedin', this.onLoggedIn) - this.$bus.$off('myAccount-before-remainInEditMode') + beforeDestroy() { + this.$bus.$off('user-after-loggedin', this.onLoggedIn); + this.$bus.$off('myAccount-before-remainInEditMode'); }, - mounted () { - this.userCompany = this.getUserCompany() + mounted() { + this.userCompany = this.getUserCompany(); if (this.userCompany.company) { - this.addCompany = true + this.addCompany = true; } }, methods: { - onLoggedIn () { - this.currentUser = Object.assign({}, this.$store.state.user.current) - this.userCompany = this.getUserCompany() + onLoggedIn() { + this.currentUser = Object.assign({}, this.$store.state.user.current); + this.userCompany = this.getUserCompany(); if (this.userCompany.company) { - this.addCompany = true + this.addCompany = true; } }, - edit () { - this.isEdited = true + edit() { + this.isEdited = true; }, - objectsEqual (a, b, excludedFields = []) { - const aProps = Object.keys(a) - const bProps = Object.keys(b) + objectsEqual(a, b, excludedFields = []) { + const aProps = Object.keys(a); + const bProps = Object.keys(b); if (aProps.length !== bProps.length) { - return false + return false; } for (let i = 0; i < aProps.length; i++) { - let propName = aProps[i] + let propName = aProps[i]; if (!b.hasOwnProperty(propName)) { - return false + return false; } else { - if (a[propName] !== null && b[propName] !== null && a[propName] === 'object' && b[propName] === 'object') { + if ( + a[propName] !== null && + b[propName] !== null && + a[propName] === 'object' && + b[propName] === 'object' + ) { if (!this.objectsEqual(a[propName], b[propName])) { - return false + return false; } - } else if (!excludedFields.includes(propName) && a[propName] !== b[propName]) { - return false + } else if ( + !excludedFields.includes(propName) && + a[propName] !== b[propName] + ) { + return false; } } } - return true + return true; }, - updateProfile () { - let updatedProfile - if (!this.objectsEqual(this.currentUser, this.$store.state.user.current, ['updated_at', 'addresses']) || + updateProfile() { + let updatedProfile; + if ( + !this.objectsEqual(this.currentUser, this.$store.state.user.current, [ + 'updated_at', + 'addresses' + ]) || !this.objectsEqual(this.userCompany, this.getUserCompany()) || (this.userCompany.company && !this.addCompany) ) { - updatedProfile = JSON.parse(JSON.stringify(this.$store.state.user.current)) - updatedProfile.firstname = this.currentUser.firstname - updatedProfile.lastname = this.currentUser.lastname - updatedProfile.email = this.currentUser.email + updatedProfile = JSON.parse( + JSON.stringify(this.$store.state.user.current) + ); + updatedProfile.firstname = this.currentUser.firstname; + updatedProfile.lastname = this.currentUser.lastname; + updatedProfile.email = this.currentUser.email; if (updatedProfile.hasOwnProperty('default_billing')) { - let index + let index; for (let i = 0; i < updatedProfile.addresses.length; i++) { - if (toString(updatedProfile.addresses[i].id) === toString(updatedProfile.default_billing)) { - index = i + if ( + toString(updatedProfile.addresses[i].id) === + toString(updatedProfile.default_billing) + ) { + index = i; } } if (index >= 0) { if (this.addCompany) { - updatedProfile.addresses[index].firstname = this.currentUser.firstname || '' - updatedProfile.addresses[index].lastname = this.currentUser.lastname || '' - updatedProfile.addresses[index].company = this.userCompany.company || '' - updatedProfile.addresses[index].street = [this.userCompany.street, this.userCompany.house] || ['', ''] - updatedProfile.addresses[index].city = this.userCompany.city || '' + updatedProfile.addresses[index].firstname = + this.currentUser.firstname || ''; + updatedProfile.addresses[index].lastname = + this.currentUser.lastname || ''; + updatedProfile.addresses[index].company = + this.userCompany.company || ''; + updatedProfile.addresses[index].street = [ + this.userCompany.street, + this.userCompany.house + ] || ['', '']; + updatedProfile.addresses[index].city = + this.userCompany.city || ''; updatedProfile.addresses[index].region = { region: this.userCompany.region ? this.userCompany.region : null - } - updatedProfile.addresses[index].country_id = this.userCompany.country || '' - updatedProfile.addresses[index].postcode = this.userCompany.postcode || '' - updatedProfile.addresses[index].vat_id = this.userCompany.taxId || '' - updatedProfile.addresses[index].telephone = this.userCompany.phone || '' + }; + updatedProfile.addresses[index].country_id = + this.userCompany.country || ''; + updatedProfile.addresses[index].postcode = + this.userCompany.postcode || ''; + updatedProfile.addresses[index].vat_id = + this.userCompany.taxId || ''; + updatedProfile.addresses[index].telephone = + this.userCompany.phone || ''; } else { - updatedProfile.addresses.splice(index, 1) + updatedProfile.addresses.splice(index, 1); this.userCompany = { company: '', street: '', @@ -123,7 +151,7 @@ export const UserAccount = { postcode: '', taxId: '', phone: '' - } + }; } } } else if (this.addCompany) { @@ -133,48 +161,52 @@ export const UserAccount = { company: this.userCompany.company, street: [this.userCompany.street, this.userCompany.house], city: this.userCompany.city, - ...(this.userCompany.region ? { region: { region: this.userCompany.region } } : {}), + ...(this.userCompany.region + ? { region: { region: this.userCompany.region } } + : {}), country_id: this.userCompany.country, postcode: this.userCompany.postcode, vat_id: this.userCompany.taxId, telephone: this.userCompany.phone, default_billing: true - }) + }); } } if (this.password) { this.$bus.$emit('myAccount-before-changePassword', { currentPassword: this.oldPassword, newPassword: this.password - }) + }); } - this.exitSection(null, updatedProfile) + this.exitSection(null, updatedProfile); }, - exitSection (event, updatedProfile) { - this.$bus.$emit('myAccount-before-updateUser', updatedProfile) + exitSection(event, updatedProfile) { + this.$bus.$emit('myAccount-before-updateUser', updatedProfile); if (!updatedProfile) { - this.currentUser = Object.assign({}, this.$store.state.user.current) - this.userCompany = this.getUserCompany() - this.changePassword = false - this.oldPassword = '' - this.password = '' - this.rPassword = '' + this.currentUser = Object.assign({}, this.$store.state.user.current); + this.userCompany = this.getUserCompany(); + this.changePassword = false; + this.oldPassword = ''; + this.password = ''; + this.rPassword = ''; if (!this.userCompany.company) { - this.addCompany = false + this.addCompany = false; } - this.remainInEditMode = false + this.remainInEditMode = false; } if (!this.remainInEditMode) { - this.isEdited = false + this.isEdited = false; } }, - getUserCompany () { - let user = this.$store.state.user.current + getUserCompany() { + let user = this.$store.state.user.current; if (user.hasOwnProperty('default_billing')) { - let index + let index; for (let i = 0; i < this.currentUser.addresses.length; i++) { - if (toString(user.addresses[i].id) === toString(user.default_billing)) { - index = i + if ( + toString(user.addresses[i].id) === toString(user.default_billing) + ) { + index = i; } } if (index >= 0) { @@ -183,12 +215,14 @@ export const UserAccount = { street: user.addresses[index].street[0] || '', house: user.addresses[index].street[1] || '', city: user.addresses[index].city || '', - region: user.addresses[index].region.region ? user.addresses[index].region.region : '', + region: user.addresses[index].region.region + ? user.addresses[index].region.region + : '', country: user.addresses[index].country_id || '', postcode: user.addresses[index].postcode || '', taxId: user.addresses[index].vat_id || '', phone: user.addresses[index].telephone || '' - } + }; } } else { return { @@ -201,16 +235,16 @@ export const UserAccount = { postcode: '', taxId: '', phone: '' - } + }; } }, - getCountryName () { + getCountryName() { for (let i = 0; i < this.countries.length; i++) { if (this.countries[i].code === this.userCompany.country) { - return this.countries[i].name + return this.countries[i].name; } } - return '' + return ''; } } -} +}; diff --git a/core/modules/user/components/UserShippingDetails.ts b/core/modules/user/components/UserShippingDetails.ts index d385a97dec..2146242b5c 100644 --- a/core/modules/user/components/UserShippingDetails.ts +++ b/core/modules/user/components/UserShippingDetails.ts @@ -1,9 +1,9 @@ -const Countries = require('@vue-storefront/i18n/resource/countries.json') -import toString from 'lodash-es/toString' +const Countries = require('@vue-storefront/i18n/resource/countries.json'); +import toString from 'lodash-es/toString'; export const UserShippingDetails = { name: 'MyShippingDetails', - data () { + data() { return { shippingDetails: { firstName: '', @@ -21,79 +21,107 @@ export const UserShippingDetails = { currentUser: Object.assign({}, this.$store.state.user.current), isEdited: false, remainInEditMode: false - } + }; }, - beforeMount () { - this.$bus.$on('user-after-loggedin', this.onLoggedIn) + beforeMount() { + this.$bus.$on('user-after-loggedin', this.onLoggedIn); this.$bus.$on('myAccount-before-remainInEditMode', block => { if (block === 'MyShippingDetails') { - this.remainInEditMode = true + this.remainInEditMode = true; } - }) + }); }, - beforeDestroy () { - this.$bus.$off('user-after-loggedin', this.onLoggedIn) - this.$bus.$off('myAccount-before-remainInEditMode') + beforeDestroy() { + this.$bus.$off('user-after-loggedin', this.onLoggedIn); + this.$bus.$off('myAccount-before-remainInEditMode'); }, - mounted () { - this.shippingDetails = this.getShippingDetails() + mounted() { + this.shippingDetails = this.getShippingDetails(); }, methods: { - onLoggedIn () { - this.currentUser = Object.assign({}, this.$store.state.user.current) - this.shippingDetails = this.getShippingDetails() + onLoggedIn() { + this.currentUser = Object.assign({}, this.$store.state.user.current); + this.shippingDetails = this.getShippingDetails(); }, - edit () { - this.isEdited = true + edit() { + this.isEdited = true; }, - objectsEqual (a, b) { - const aProps = Object.keys(a) - const bProps = Object.keys(b) + objectsEqual(a, b) { + const aProps = Object.keys(a); + const bProps = Object.keys(b); if (aProps.length !== bProps.length) { - return false + return false; } for (let i = 0; i < aProps.length; i++) { - let propName = aProps[i] + let propName = aProps[i]; if (!b.hasOwnProperty(propName)) { - return false + return false; } else { - if (a[propName] !== null && b[propName] !== null && a[propName] === 'object' && b[propName] === 'object') { + if ( + a[propName] !== null && + b[propName] !== null && + a[propName] === 'object' && + b[propName] === 'object' + ) { if (!this.objectsEqual(a[propName], b[propName])) { - return false + return false; } } else if (a[propName] !== b[propName]) { - return false + return false; } } } - return true + return true; }, - updateDetails () { - let updatedShippingDetails + updateDetails() { + let updatedShippingDetails; if (!this.objectsEqual(this.shippingDetails, this.getShippingDetails())) { - updatedShippingDetails = JSON.parse(JSON.stringify(this.$store.state.user.current)) + updatedShippingDetails = JSON.parse( + JSON.stringify(this.$store.state.user.current) + ); if (this.currentUser.hasOwnProperty('default_shipping')) { - let index + let index; for (let i = 0; i < this.currentUser.addresses.length; i++) { - if (toString(this.currentUser.addresses[i].id) === toString(this.currentUser.default_shipping)) { - index = i + if ( + toString(this.currentUser.addresses[i].id) === + toString(this.currentUser.default_shipping) + ) { + index = i; } } if (index >= 0) { - updatedShippingDetails.addresses[index].firstname = this.shippingDetails.firstName - updatedShippingDetails.addresses[index].lastname = this.shippingDetails.lastName - updatedShippingDetails.addresses[index].street = [this.shippingDetails.street, this.shippingDetails.house] - updatedShippingDetails.addresses[index].city = this.shippingDetails.city + updatedShippingDetails.addresses[ + index + ].firstname = this.shippingDetails.firstName; + updatedShippingDetails.addresses[ + index + ].lastname = this.shippingDetails.lastName; + updatedShippingDetails.addresses[index].street = [ + this.shippingDetails.street, + this.shippingDetails.house + ]; + updatedShippingDetails.addresses[ + index + ].city = this.shippingDetails.city; updatedShippingDetails.addresses[index].region = { - region: this.shippingDetails.region ? this.shippingDetails.region : null - } - updatedShippingDetails.addresses[index].country_id = this.shippingDetails.country - updatedShippingDetails.addresses[index].postcode = this.shippingDetails.postcode - updatedShippingDetails.addresses[index].telephone = this.shippingDetails.phone ? this.shippingDetails.phone : '' + region: this.shippingDetails.region + ? this.shippingDetails.region + : null + }; + updatedShippingDetails.addresses[ + index + ].country_id = this.shippingDetails.country; + updatedShippingDetails.addresses[ + index + ].postcode = this.shippingDetails.postcode; + updatedShippingDetails.addresses[index].telephone = this + .shippingDetails.phone + ? this.shippingDetails.phone + : ''; } else { - updatedShippingDetails = null + updatedShippingDetails = null; } } else { updatedShippingDetails.addresses.push({ @@ -101,58 +129,86 @@ export const UserShippingDetails = { lastname: this.shippingDetails.lastName, street: [this.shippingDetails.street, this.shippingDetails.house], city: this.shippingDetails.city, - ...(this.shippingDetails.region ? { region: { region: this.shippingDetails.region } } : {}), + ...(this.shippingDetails.region + ? { region: { region: this.shippingDetails.region } } + : {}), country_id: this.shippingDetails.country, postcode: this.shippingDetails.postcode, - ...(this.shippingDetails.phone ? { telephone: this.shippingDetails.phone } : {}), + ...(this.shippingDetails.phone + ? { telephone: this.shippingDetails.phone } + : {}), default_shipping: true - }) + }); } } - this.exitSection(null, updatedShippingDetails) + this.exitSection(null, updatedShippingDetails); }, - exitSection (event, updatedShippingDetails) { - this.$bus.$emit('myAccount-before-updateUser', updatedShippingDetails) + exitSection(event, updatedShippingDetails) { + this.$bus.$emit('myAccount-before-updateUser', updatedShippingDetails); if (!updatedShippingDetails) { - this.shippingDetails = this.getShippingDetails() - this.useCompanyAddress = false - this.remainInEditMode = false + this.shippingDetails = this.getShippingDetails(); + this.useCompanyAddress = false; + this.remainInEditMode = false; } if (!this.remainInEditMode) { - this.isEdited = false + this.isEdited = false; } }, - fillCompanyAddress () { - this.useCompanyAddress = !this.useCompanyAddress + fillCompanyAddress() { + this.useCompanyAddress = !this.useCompanyAddress; if (this.useCompanyAddress) { - let index + let index; for (let i = 0; i < this.currentUser.addresses.length; i++) { - if (toString(this.currentUser.addresses[i].id) === toString(this.currentUser.default_billing)) { - index = i + if ( + toString(this.currentUser.addresses[i].id) === + toString(this.currentUser.default_billing) + ) { + index = i; } } if (index >= 0) { - this.shippingDetails.firstName = this.currentUser.addresses[index].firstname - this.shippingDetails.lastName = this.currentUser.addresses[index].lastname - this.shippingDetails.street = this.currentUser.addresses[index].street[0] - this.shippingDetails.house = this.currentUser.addresses[index].street[1] - this.shippingDetails.city = this.currentUser.addresses[index].city - this.shippingDetails.postcode = this.currentUser.addresses[index].postcode - this.shippingDetails.region = this.currentUser.addresses[index].region.region ? this.currentUser.addresses[index].region.region : '' - this.shippingDetails.country = this.currentUser.addresses[index].country_id + this.shippingDetails.firstName = this.currentUser.addresses[ + index + ].firstname; + this.shippingDetails.lastName = this.currentUser.addresses[ + index + ].lastname; + this.shippingDetails.street = this.currentUser.addresses[ + index + ].street[0]; + this.shippingDetails.house = this.currentUser.addresses[ + index + ].street[1]; + this.shippingDetails.city = this.currentUser.addresses[index].city; + this.shippingDetails.postcode = this.currentUser.addresses[ + index + ].postcode; + this.shippingDetails.region = this.currentUser.addresses[index].region + .region + ? this.currentUser.addresses[index].region.region + : ''; + this.shippingDetails.country = this.currentUser.addresses[ + index + ].country_id; } } else { - this.shippingDetails = this.getShippingDetails() + this.shippingDetails = this.getShippingDetails(); } }, - getShippingDetails () { - this.currentUser = Object.assign({}, this.$store.state.user.current) + getShippingDetails() { + this.currentUser = Object.assign({}, this.$store.state.user.current); if (this.currentUser) { - if (this.currentUser && this.currentUser.hasOwnProperty('default_shipping')) { - let index + if ( + this.currentUser && + this.currentUser.hasOwnProperty('default_shipping') + ) { + let index; for (let i = 0; i < this.currentUser.addresses.length; i++) { - if (toString(this.currentUser.addresses[i].id) === toString(this.currentUser.default_shipping)) { - index = i + if ( + toString(this.currentUser.addresses[i].id) === + toString(this.currentUser.default_shipping) + ) { + index = i; } } if (index >= 0) { @@ -163,10 +219,16 @@ export const UserShippingDetails = { house: this.currentUser.addresses[index].street[1], city: this.currentUser.addresses[index].city, postcode: this.currentUser.addresses[index].postcode, - region: this.currentUser.addresses[index].region.region ? this.currentUser.addresses[index].region.region : '', + region: this.currentUser.addresses[index].region.region + ? this.currentUser.addresses[index].region.region + : '', country: this.currentUser.addresses[index].country_id, - phone: this.currentUser.addresses[index].hasOwnProperty('telephone') ? this.currentUser.addresses[index].telephone : '' - } + phone: this.currentUser.addresses[index].hasOwnProperty( + 'telephone' + ) + ? this.currentUser.addresses[index].telephone + : '' + }; } } else { return { @@ -179,7 +241,7 @@ export const UserShippingDetails = { region: '', country: '', phone: '' - } + }; } } else { return { @@ -192,24 +254,24 @@ export const UserShippingDetails = { region: '', country: '', phone: '' - } + }; } }, - getCountryName () { + getCountryName() { for (let i = 0; i < this.countries.length; i++) { if (this.countries[i].code === this.shippingDetails.country) { - return this.countries[i].name + return this.countries[i].name; } } - return '' + return ''; }, - hasBillingAddress () { + hasBillingAddress() { if (this.currentUser) { if (this.currentUser.hasOwnProperty('default_billing')) { - return true + return true; } } - return false + return false; } } -} \ No newline at end of file +}; diff --git a/core/modules/user/hooks/afterRegistration.ts b/core/modules/user/hooks/afterRegistration.ts index 465db31f58..47dc2ae9af 100644 --- a/core/modules/user/hooks/afterRegistration.ts +++ b/core/modules/user/hooks/afterRegistration.ts @@ -1,17 +1,17 @@ -import Vue from 'vue' -import * as types from './../store/mutation-types' +import Vue from 'vue'; +import * as types from './../store/mutation-types'; -export function afterRegistration({ Vue, config, store, isServer }){ +export function afterRegistration({ Vue, config, store, isServer }) { if (!isServer) { - store.dispatch('user/startSession') + store.dispatch('user/startSession'); Vue.prototype.$bus.$on('user-before-logout', () => { - store.dispatch('user/logout', { silent: false }) + store.dispatch('user/logout', { silent: false }); //TODO: Move it to theme store.commit('ui/setSubmenu', { depth: 0 - }) - }) + }); + }); Vue.prototype.$bus.$on('user-after-loggedin', receivedData => { //TODO: Make independent of checkout module @@ -19,40 +19,42 @@ export function afterRegistration({ Vue, config, store, isServer }){ firstName: receivedData.firstname, lastName: receivedData.lastname, emailAddress: receivedData.email - }) - }) + }); + }); } store.subscribe((mutation, state) => { - const type = mutation.type + const type = mutation.type; - if ( - type.endsWith(types.USER_INFO_LOADED) - ) { - Vue.prototype.$db.usersCollection.setItem('current-user', state.user.current).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + if (type.endsWith(types.USER_INFO_LOADED)) { + Vue.prototype.$db.usersCollection + .setItem('current-user', state.user.current) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache } - if ( - type.endsWith(types.USER_ORDERS_HISTORY_LOADED) - ) { - Vue.prototype.$db.ordersHistoryCollection.setItem('orders-history', state.user.orders_history).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + if (type.endsWith(types.USER_ORDERS_HISTORY_LOADED)) { + Vue.prototype.$db.ordersHistoryCollection + .setItem('orders-history', state.user.orders_history) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache } - if ( - type.endsWith(types.USER_TOKEN_CHANGED) - ) { - Vue.prototype.$db.usersCollection.setItem('current-token', state.user.token).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + if (type.endsWith(types.USER_TOKEN_CHANGED)) { + Vue.prototype.$db.usersCollection + .setItem('current-token', state.user.token) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache if (state.user.refreshToken) { - Vue.prototype.$db.usersCollection.setItem('current-refresh-token', state.user.refreshToken).catch((reason) => { - console.error(reason) // it doesn't work on SSR - }) // populate cache + Vue.prototype.$db.usersCollection + .setItem('current-refresh-token', state.user.refreshToken) + .catch(reason => { + console.error(reason); // it doesn't work on SSR + }); // populate cache } } - }) -} \ No newline at end of file + }); +} diff --git a/core/modules/user/hooks/beforeRegistration.ts b/core/modules/user/hooks/beforeRegistration.ts index 401b398e5f..e45c1d9079 100644 --- a/core/modules/user/hooks/beforeRegistration.ts +++ b/core/modules/user/hooks/beforeRegistration.ts @@ -1,20 +1,24 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.usersCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'user', - driver: localForage[config.localForage.defaultDrivers['user']] - })) + Vue.prototype.$db.usersCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'user', + driver: localForage[config.localForage.defaultDrivers['user']] + }) + ); - Vue.prototype.$db.ordersHistoryCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'ordersHistory', - driver: localForage[config.localForage.defaultDrivers['ordersHistory']] - })) -} \ No newline at end of file + Vue.prototype.$db.ordersHistoryCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'ordersHistory', + driver: localForage[config.localForage.defaultDrivers['ordersHistory']] + }) + ); +} diff --git a/core/modules/user/index.ts b/core/modules/user/index.ts index 4e75e98d25..2822669b6b 100644 --- a/core/modules/user/index.ts +++ b/core/modules/user/index.ts @@ -1,14 +1,14 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeEach } from './router/beforeEach' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import { module } from './store'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeEach } from './router/beforeEach'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; -export const KEY = 'user' +export const KEY = 'user'; export const User = createModule({ key: KEY, store: { modules: [{ key: KEY, module }] }, beforeRegistration, afterRegistration, router: { beforeEach } -}) +}); diff --git a/core/modules/user/router/beforeEach.ts b/core/modules/user/router/beforeEach.ts index cd9b323356..b6513b8306 100644 --- a/core/modules/user/router/beforeEach.ts +++ b/core/modules/user/router/beforeEach.ts @@ -1,30 +1,30 @@ -import { Route } from 'vue-router' -import rootStore from '@vue-storefront/core/store' -import i18n from '@vue-storefront/i18n' -import { isServer } from '@vue-storefront/core/helpers' -import { router } from '@vue-storefront/core/app' +import { Route } from 'vue-router'; +import rootStore from '@vue-storefront/core/store'; +import i18n from '@vue-storefront/i18n'; +import { isServer } from '@vue-storefront/core/helpers'; +import { router } from '@vue-storefront/core/app'; export function beforeEach(to: Route, from: Route, next) { - const requiresAuth = to.matched.some(route => route.meta.requiresAuth) + const requiresAuth = to.matched.some(route => route.meta.requiresAuth); if (requiresAuth) { if (isServer) { - next('/') + next('/'); } else { if (!rootStore.getters['user/isLoggedIn']) { - next('/') - localStorage.setItem('redirect', from.path) + next('/'); + localStorage.setItem('redirect', from.path); } else { if (!from.name) { - next('/') - setTimeout(()=> { - router.push(to.path) - }, 0) + next('/'); + setTimeout(() => { + router.push(to.path); + }, 0); } else { - next() + next(); } } } } else { - next() + next(); } } diff --git a/core/modules/user/store/actions.ts b/core/modules/user/store/actions.ts index f47fb2067e..a5b93d0bef 100644 --- a/core/modules/user/store/actions.ts +++ b/core/modules/user/store/actions.ts @@ -1,156 +1,186 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import rootStore from '@vue-storefront/core/store' -import i18n from '@vue-storefront/i18n' -import { adjustMultistoreApiUrl } from '@vue-storefront/core/lib/multistore' -import RootState from '@vue-storefront/core/types/RootState' -import UserState from '../types/UserState' -import { Logger } from '@vue-storefront/core/lib/logger' -import { TaskQueue } from '@vue-storefront/core/lib/sync' -import { UserProfile } from '../types/UserProfile' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import rootStore from '@vue-storefront/core/store'; +import i18n from '@vue-storefront/i18n'; +import { adjustMultistoreApiUrl } from '@vue-storefront/core/lib/multistore'; +import RootState from '@vue-storefront/core/types/RootState'; +import UserState from '../types/UserState'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { TaskQueue } from '@vue-storefront/core/lib/sync'; +import { UserProfile } from '../types/UserProfile'; // import router from '@vue-storefront/core/router' const actions: ActionTree = { - startSession (context) { - const cache = Vue.prototype.$db.usersCollection + startSession(context) { + const cache = Vue.prototype.$db.usersCollection; cache.getItem('current-user', (err, user) => { if (err) { - Logger.error(err, 'user')() - return + Logger.error(err, 'user')(); + return; } if (user) { - context.commit(types.USER_INFO_LOADED, user) + context.commit(types.USER_INFO_LOADED, user); } - }) + }); - context.commit(types.USER_START_SESSION) + context.commit(types.USER_START_SESSION); cache.getItem('current-token', (err, res) => { if (err) { - Logger.error(err, 'user')() - return + Logger.error(err, 'user')(); + return; } if (res) { - context.commit(types.USER_TOKEN_CHANGED, { newToken: res }) - context.dispatch('sessionAfterAuthorized') + context.commit(types.USER_TOKEN_CHANGED, { newToken: res }); + context.dispatch('sessionAfterAuthorized'); if (rootStore.state.config.usePriceTiers) { cache.getItem('current-user', (err, userData) => { if (err) { - Logger.error(err, 'user')() - return + Logger.error(err, 'user')(); + return; } if (userData) { - context.dispatch('setUserGroup', userData) + context.dispatch('setUserGroup', userData); } - }) + }); } } else { - Vue.prototype.$bus.$emit('session-after-nonauthorized') + Vue.prototype.$bus.$emit('session-after-nonauthorized'); } - Vue.prototype.$bus.$emit('session-after-started') - }) + Vue.prototype.$bus.$emit('session-after-started'); + }); }, /** * Send password reset link for specific e-mail */ - resetPassword (context, { email }) { - return TaskQueue.execute({ url: rootStore.state.config.users.resetPassword_endpoint, + resetPassword(context, { email }) { + return TaskQueue.execute({ + url: rootStore.state.config.users.resetPassword_endpoint, payload: { method: 'POST', mode: 'cors', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({ email: email }) } - }) + }); }, /** * Login user and return user profile and current token */ - login (context, { username, password }) { - let url = rootStore.state.config.users.login_endpoint + login(context, { username, password }) { + let url = rootStore.state.config.users.login_endpoint; if (rootStore.state.config.storeViews.multistore) { - url = adjustMultistoreApiUrl(url) + url = adjustMultistoreApiUrl(url); } - return fetch(url, { method: 'POST', + return fetch(url, { + method: 'POST', mode: 'cors', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({ username: username, password: password }) - }).then(resp => { return resp.json() }) - .then((resp) => { + }) + .then(resp => { + return resp.json(); + }) + .then(resp => { if (resp.code === 200) { - rootStore.state.userTokenInvalidateLock = 0 - context.commit(types.USER_TOKEN_CHANGED, { newToken: resp.result, meta: resp.meta }) // TODO: handle the "Refresh-token" header - context.dispatch('me', { refresh: true, useCache: false }).then(result => {}) - context.dispatch('getOrdersHistory', { refresh: true, useCache: false }).then(result => {}) + rootStore.state.userTokenInvalidateLock = 0; + context.commit(types.USER_TOKEN_CHANGED, { + newToken: resp.result, + meta: resp.meta + }); // TODO: handle the "Refresh-token" header + context + .dispatch('me', { refresh: true, useCache: false }) + .then(result => {}); + context + .dispatch('getOrdersHistory', { refresh: true, useCache: false }) + .then(result => {}); } - return resp - }) + return resp; + }); }, /** * Login user and return user profile and current token */ - register (context, { email, firstname, lastname, password }) { - let url = rootStore.state.config.users.create_endpoint + register(context, { email, firstname, lastname, password }) { + let url = rootStore.state.config.users.create_endpoint; if (rootStore.state.config.storeViews.multistore) { - url = adjustMultistoreApiUrl(url) + url = adjustMultistoreApiUrl(url); } - return fetch(url, { method: 'POST', + return fetch(url, { + method: 'POST', mode: 'cors', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, - body: JSON.stringify({ customer: { email: email, firstname: firstname, lastname: lastname }, password: password }) - }).then(resp => { return resp.json() }) - .then((resp) => { + body: JSON.stringify({ + customer: { email: email, firstname: firstname, lastname: lastname }, + password: password + }) + }) + .then(resp => { + return resp.json(); + }) + .then(resp => { if (resp.code === 200) { - context.dispatch('login', { username: email, password: password }).then(result => { // login user - }) + context + .dispatch('login', { username: email, password: password }) + .then(result => { + // login user + }); } - return resp - }) + return resp; + }); }, /** - * Invalidate user token - */ - refresh (context) { + * Invalidate user token + */ + refresh(context) { return new Promise((resolve, reject) => { - const usersCollection = Vue.prototype.$db.usersCollection + const usersCollection = Vue.prototype.$db.usersCollection; usersCollection.getItem('current-refresh-token', (err, refreshToken) => { if (err) { - Logger.error(err, 'user')() + Logger.error(err, 'user')(); } - let url = rootStore.state.config.users.refresh_endpoint + let url = rootStore.state.config.users.refresh_endpoint; if (rootStore.state.config.storeViews.multistore) { - url = adjustMultistoreApiUrl(url) + url = adjustMultistoreApiUrl(url); } - return fetch(url, { method: 'POST', + return fetch(url, { + method: 'POST', mode: 'cors', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken: refreshToken }) - }).then(resp => { return resp.json() }) - .then((resp) => { + }) + .then(resp => { + return resp.json(); + }) + .then(resp => { if (resp.code === 200) { - context.commit(types.USER_TOKEN_CHANGED, { newToken: resp.result, meta: resp.meta ? resp.meta : null }) // TODO: handle the "Refresh-token" header + context.commit(types.USER_TOKEN_CHANGED, { + newToken: resp.result, + meta: resp.meta ? resp.meta : null + }); // TODO: handle the "Refresh-token" header } - resolve(resp) - }).catch((exc) => reject(exc)) - }) - }) + resolve(resp); + }) + .catch(exc => reject(exc)); + }); + }); }, /** * Update user groupToken and groupId in state @@ -160,85 +190,88 @@ const actions: ActionTree = { setUserGroup(context, userData) { if (rootStore.state.config.usePriceTiers) { if (userData.groupToken) { - context.commit(types.USER_GROUP_TOKEN_CHANGED, userData.groupToken) + context.commit(types.USER_GROUP_TOKEN_CHANGED, userData.groupToken); } if (userData.group_id) { - context.commit(types.USER_GROUP_CHANGED, userData.group_id) + context.commit(types.USER_GROUP_CHANGED, userData.group_id); } } else { - context.commit(types.USER_GROUP_TOKEN_CHANGED, '') - context.commit(types.USER_GROUP_CHANGED, null) + context.commit(types.USER_GROUP_TOKEN_CHANGED, ''); + context.commit(types.USER_GROUP_CHANGED, null); } }, /** * Load current user profile */ - me (context, { refresh = true, useCache = true }) { + me(context, { refresh = true, useCache = true }) { return new Promise((resolve, reject) => { if (!context.state.token) { - Logger.warn('No User token, user unauthorized', 'user')() - return resolve(null) + Logger.warn('No User token, user unauthorized', 'user')(); + return resolve(null); } - const cache = Vue.prototype.$db.usersCollection - let resolvedFromCache = false + const cache = Vue.prototype.$db.usersCollection; + let resolvedFromCache = false; - if (useCache === true) { // after login for example we shouldn't use cache to be sure we're loading currently logged in user + if (useCache === true) { + // after login for example we shouldn't use cache to be sure we're loading currently logged in user cache.getItem('current-user', (err, res) => { if (err) { - Logger.error(err, 'user')() - return + Logger.error(err, 'user')(); + return; } if (res) { - context.commit(types.USER_INFO_LOADED, res) - context.dispatch('setUserGroup', res) - Vue.prototype.$bus.$emit('user-after-loggedin', res) - rootStore.dispatch('cart/userAfterLoggedin') + context.commit(types.USER_INFO_LOADED, res); + context.dispatch('setUserGroup', res); + Vue.prototype.$bus.$emit('user-after-loggedin', res); + rootStore.dispatch('cart/userAfterLoggedin'); - resolve(res) - resolvedFromCache = true - Logger.log('Current user served from cache', 'user')() + resolve(res); + resolvedFromCache = true; + Logger.log('Current user served from cache', 'user')(); } - }) + }); } if (refresh) { - TaskQueue.execute({ url: rootStore.state.config.users.me_endpoint, - payload: { method: 'GET', + TaskQueue.execute({ + url: rootStore.state.config.users.me_endpoint, + payload: { + method: 'GET', mode: 'cors', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' } } - }) - .then((resp: any) => { - if (resp.resultCode === 200) { - context.commit(types.USER_INFO_LOADED, resp.result) // this also stores the current user to localForage - context.dispatch('setUserGroup', resp.result) - } - if (!resolvedFromCache && resp.resultCode === 200) { - Vue.prototype.$bus.$emit('user-after-loggedin', resp.result) - rootStore.dispatch('cart/userAfterLoggedin') - resolve(resp) - } else { - resolve(null) - } - return resp - }) + }).then((resp: any) => { + if (resp.resultCode === 200) { + context.commit(types.USER_INFO_LOADED, resp.result); // this also stores the current user to localForage + context.dispatch('setUserGroup', resp.result); + } + if (!resolvedFromCache && resp.resultCode === 200) { + Vue.prototype.$bus.$emit('user-after-loggedin', resp.result); + rootStore.dispatch('cart/userAfterLoggedin'); + resolve(resp); + } else { + resolve(null); + } + return resp; + }); } else { if (!resolvedFromCache) { - resolve(null) + resolve(null); } } - }) + }); }, /** * Update user profile with data from My Account page */ - async update (context, userData:UserProfile) { - await TaskQueue.queue({ url: rootStore.state.config.users.me_endpoint, + async update(context, userData: UserProfile) { + await TaskQueue.queue({ + url: rootStore.state.config.users.me_endpoint, payload: { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -246,16 +279,17 @@ const actions: ActionTree = { body: JSON.stringify(userData) }, callback_event: 'store:user/userAfterUpdate' - }) + }); }, - refreshCurrentUser (context, userData) { - context.commit(types.USER_INFO_LOADED, userData) + refreshCurrentUser(context, userData) { + context.commit(types.USER_INFO_LOADED, userData); }, /** * Change user password */ - changePassword (context, passwordData) { - return TaskQueue.execute({ url: rootStore.state.config.users.changePassword_endpoint, + changePassword(context, passwordData) { + return TaskQueue.execute({ + url: rootStore.state.config.users.changePassword_endpoint, payload: { method: 'POST', mode: 'cors', @@ -268,48 +302,55 @@ const actions: ActionTree = { type: 'success', message: 'Password has successfully been changed', action1: { label: i18n.t('OK') } - }) + }); rootStore.dispatch('user/login', { username: context.state.current.email, password: passwordData.newPassword - }) + }); } else { rootStore.dispatch('notification/spawnNotification', { type: 'error', message: i18n.t(resp.result), action1: { label: i18n.t('OK') } - }) + }); } - }) + }); }, - clearCurrentUser (context) { - context.commit(types.USER_GROUP_TOKEN_CHANGED, '') - context.commit(types.USER_GROUP_CHANGED, null) - context.commit(types.USER_INFO_LOADED, null) - context.dispatch('wishlist/clear', null, {root: true}) - context.dispatch('checkout/savePersonalDetails', {}, {root: true}) - context.dispatch('checkout/saveShippingDetails', {}, {root: true}) - context.dispatch('checkout/savePaymentDetails', {}, {root: true}) + clearCurrentUser(context) { + context.commit(types.USER_GROUP_TOKEN_CHANGED, ''); + context.commit(types.USER_GROUP_CHANGED, null); + context.commit(types.USER_INFO_LOADED, null); + context.dispatch('wishlist/clear', null, { root: true }); + context.dispatch('checkout/savePersonalDetails', {}, { root: true }); + context.dispatch('checkout/saveShippingDetails', {}, { root: true }); + context.dispatch('checkout/savePaymentDetails', {}, { root: true }); }, /** * Logout user */ - logout (context, { silent = false }) { - context.commit(types.USER_END_SESSION) - context.dispatch('cart/serverTokenClear', {}, { root: true }) - .then(() => {context.dispatch('clearCurrentUser')}) - .then(() => {Vue.prototype.$bus.$emit('user-after-logout')}) - .then(() => {context.dispatch('cart/clear', {}, { root: true })}) + logout(context, { silent = false }) { + context.commit(types.USER_END_SESSION); + context + .dispatch('cart/serverTokenClear', {}, { root: true }) + .then(() => { + context.dispatch('clearCurrentUser'); + }) + .then(() => { + Vue.prototype.$bus.$emit('user-after-logout'); + }) + .then(() => { + context.dispatch('cart/clear', {}, { root: true }); + }); if (!silent) { rootStore.dispatch('notification/spawnNotification', { type: 'success', message: i18n.t("You're logged out"), action1: { label: i18n.t('OK') } - }) + }); } - const usersCollection = Vue.prototype.$db.usersCollection - usersCollection.setItem('current-token', '') + const usersCollection = Vue.prototype.$db.usersCollection; + usersCollection.setItem('current-token', ''); if (rootStore.state.route.path === '/my-account') { // router.push('/') @@ -318,59 +359,65 @@ const actions: ActionTree = { /** * Load user's orders history */ - getOrdersHistory (context, { refresh = true, useCache = true }) { + getOrdersHistory(context, { refresh = true, useCache = true }) { // TODO: Make it as an extension from users module return new Promise((resolve, reject) => { if (!context.state.token) { - Logger.debug('No User token, user unathorized', 'user')() - return resolve(null) + Logger.debug('No User token, user unathorized', 'user')(); + return resolve(null); } - const cache = Vue.prototype.$db.ordersHistoryCollection - let resolvedFromCache = false + const cache = Vue.prototype.$db.ordersHistoryCollection; + let resolvedFromCache = false; - if (useCache === true) { // after login for example we shouldn't use cache to be sure we're loading currently logged in user + if (useCache === true) { + // after login for example we shouldn't use cache to be sure we're loading currently logged in user cache.getItem('orders-history', (err, res) => { if (err) { - Logger.error(err, 'user')() - return + Logger.error(err, 'user')(); + return; } if (res) { - context.commit(types.USER_ORDERS_HISTORY_LOADED, res) - Vue.prototype.$bus.$emit('user-after-loaded-orders', res) + context.commit(types.USER_ORDERS_HISTORY_LOADED, res); + Vue.prototype.$bus.$emit('user-after-loaded-orders', res); - resolve(res) - resolvedFromCache = true - Logger.log('Current user order history served from cache', 'user')() + resolve(res); + resolvedFromCache = true; + Logger.log( + 'Current user order history served from cache', + 'user' + )(); } - }) + }); } if (refresh) { - return TaskQueue.execute({ url: rootStore.state.config.users.history_endpoint, - payload: { method: 'GET', + return TaskQueue.execute({ + url: rootStore.state.config.users.history_endpoint, + payload: { + method: 'GET', mode: 'cors', headers: { - 'Accept': 'application/json, text/plain, */*', + Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' } } }).then((resp: any) => { if (resp.code === 200) { - context.commit(types.USER_ORDERS_HISTORY_LOADED, resp.result) // this also stores the current user to localForage - Vue.prototype.$bus.$emit('user-after-loaded-orders', resp.result) + context.commit(types.USER_ORDERS_HISTORY_LOADED, resp.result); // this also stores the current user to localForage + Vue.prototype.$bus.$emit('user-after-loaded-orders', resp.result); } if (!resolvedFromCache) { - resolve(resp.code === 200 ? resp : null) + resolve(resp.code === 200 ? resp : null); } - return resp - }) + return resp; + }); } else { if (!resolvedFromCache) { - resolve(null) + resolve(null); } } - }) + }); }, userAfterUpdate(context, event) { if (event.resultCode === 200) { @@ -378,15 +425,23 @@ const actions: ActionTree = { type: 'success', message: i18n.t('Account data has successfully been updated'), action1: { label: i18n.t('OK') } - }) - rootStore.dispatch('user/refreshCurrentUser', event.result) + }); + rootStore.dispatch('user/refreshCurrentUser', event.result); } }, - sessionAfterAuthorized (context, event) { - Logger.info('User session authorised ', 'user')() - rootStore.dispatch('user/me', { refresh: navigator.onLine }, { root: true }).then((us) => {}) // this will load user cart - rootStore.dispatch('user/getOrdersHistory', { refresh: navigator.onLine }, { root: true }).then((us) => {}) + sessionAfterAuthorized(context, event) { + Logger.info('User session authorised ', 'user')(); + rootStore + .dispatch('user/me', { refresh: navigator.onLine }, { root: true }) + .then(us => {}); // this will load user cart + rootStore + .dispatch( + 'user/getOrdersHistory', + { refresh: navigator.onLine }, + { root: true } + ) + .then(us => {}); } -} +}; -export default actions +export default actions; diff --git a/core/modules/user/store/getters.ts b/core/modules/user/store/getters.ts index d2536b0214..174a00c007 100644 --- a/core/modules/user/store/getters.ts +++ b/core/modules/user/store/getters.ts @@ -1,14 +1,14 @@ -import { GetterTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import UserState from '../types/UserState' +import { GetterTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import UserState from '../types/UserState'; const getters: GetterTree = { - isLoggedIn (state) { - return state.current !== null + isLoggedIn(state) { + return state.current !== null; }, - getUserToken (state) { - return state.token + getUserToken(state) { + return state.token; } -} +}; -export default getters +export default getters; diff --git a/core/modules/user/store/index.ts b/core/modules/user/store/index.ts index 925432063b..dae27a634f 100644 --- a/core/modules/user/store/index.ts +++ b/core/modules/user/store/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import getters from './getters' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import UserState from '../types/UserState' +import { Module } from 'vuex'; +import actions from './actions'; +import getters from './getters'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import UserState from '../types/UserState'; export const module: Module = { namespaced: true, @@ -20,4 +20,4 @@ export const module: Module = { getters, actions, mutations -} +}; diff --git a/core/modules/user/store/mutation-types.ts b/core/modules/user/store/mutation-types.ts index 36df46cc36..f4e899f53e 100644 --- a/core/modules/user/store/mutation-types.ts +++ b/core/modules/user/store/mutation-types.ts @@ -1,10 +1,10 @@ -export const SN_USER = 'user' -export const USER_NEWSLETTER_SIGNUP = SN_USER + '/NEWSLETTER_SIGNUP' -export const USER_TOKEN_CHANGED = SN_USER + '/TOKEN_CHANGED' -export const USER_INFO_LOADED = SN_USER + '/INFO_LOADED' -export const USER_ORDERS_HISTORY_LOADED = SN_USER + '/ORDERS_HISTORY_LOADED' -export const USER_START_SESSION = SN_USER + '/START_SESSION' -export const USER_END_SESSION = SN_USER + '/END_SESSION' -export const USER_UPDATE_PREFERENCES = SN_USER + '/UPDATE_PREFERENCES' -export const USER_GROUP_TOKEN_CHANGED = SN_USER + '/GROUP_TOKEN_CHANGED' -export const USER_GROUP_CHANGED = SN_USER + 'GROUP_ID_CHANGED' \ No newline at end of file +export const SN_USER = 'user'; +export const USER_NEWSLETTER_SIGNUP = SN_USER + '/NEWSLETTER_SIGNUP'; +export const USER_TOKEN_CHANGED = SN_USER + '/TOKEN_CHANGED'; +export const USER_INFO_LOADED = SN_USER + '/INFO_LOADED'; +export const USER_ORDERS_HISTORY_LOADED = SN_USER + '/ORDERS_HISTORY_LOADED'; +export const USER_START_SESSION = SN_USER + '/START_SESSION'; +export const USER_END_SESSION = SN_USER + '/END_SESSION'; +export const USER_UPDATE_PREFERENCES = SN_USER + '/UPDATE_PREFERENCES'; +export const USER_GROUP_TOKEN_CHANGED = SN_USER + '/GROUP_TOKEN_CHANGED'; +export const USER_GROUP_CHANGED = SN_USER + 'GROUP_ID_CHANGED'; diff --git a/core/modules/user/store/mutations.ts b/core/modules/user/store/mutations.ts index 8d71c0dfac..4c71039abb 100644 --- a/core/modules/user/store/mutations.ts +++ b/core/modules/user/store/mutations.ts @@ -1,36 +1,36 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import UserState from '../types/UserState' -import { Logger } from '@vue-storefront/core/lib/logger' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import UserState from '../types/UserState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const mutations: MutationTree = { - [types.USER_TOKEN_CHANGED] (state, payload) { - state.token = payload.newToken + [types.USER_TOKEN_CHANGED](state, payload) { + state.token = payload.newToken; if (payload.meta && payload.meta.refreshToken) { - state.refreshToken = payload.meta.refreshToken // store the refresh token - Logger.log('Refresh token is set to' + state.refreshToken, 'user')() + state.refreshToken = payload.meta.refreshToken; // store the refresh token + Logger.log('Refresh token is set to' + state.refreshToken, 'user')(); } }, - [types.USER_START_SESSION] (state) { - state.session_started = new Date() + [types.USER_START_SESSION](state) { + state.session_started = new Date(); }, - [types.USER_GROUP_TOKEN_CHANGED] (state, token) { - state.groupToken = token + [types.USER_GROUP_TOKEN_CHANGED](state, token) { + state.groupToken = token; }, - [types.USER_GROUP_CHANGED] (state, groupId) { - state.groupId = groupId + [types.USER_GROUP_CHANGED](state, groupId) { + state.groupId = groupId; }, - [types.USER_INFO_LOADED] (state, currentUser) { - state.current = currentUser + [types.USER_INFO_LOADED](state, currentUser) { + state.current = currentUser; }, - [types.USER_ORDERS_HISTORY_LOADED] (state, ordersHistory) { - state.orders_history = ordersHistory + [types.USER_ORDERS_HISTORY_LOADED](state, ordersHistory) { + state.orders_history = ordersHistory; }, - [types.USER_END_SESSION] (state) { - state.token = '' - state.current = null - state.session_started = null + [types.USER_END_SESSION](state) { + state.token = ''; + state.current = null; + state.session_started = null; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/user/types/UserProfile.ts b/core/modules/user/types/UserProfile.ts index a80b1045ee..a86c2f075c 100644 --- a/core/modules/user/types/UserProfile.ts +++ b/core/modules/user/types/UserProfile.ts @@ -1,17 +1,17 @@ export interface UserProfile { customer: { - email: string; - firstname: string; - lastname: string; - website_id?: number; - addresses?: { + email: string; + firstname: string; + lastname: string; + website_id?: number; + addresses?: { firstname: string; lastname: string; street: (string | number)[]; city: string; region?: { - region: string | null; - [k: string]: any; + region: string | null; + [k: string]: any; }; country_id: string | null; postcode: string | null; @@ -20,12 +20,12 @@ export interface UserProfile { default_billing?: boolean; default_shipping?: boolean; [k: string]: any; - }[]; - custom_attributes?: { + }[]; + custom_attributes?: { attribute_code: string; value: string | null; [k: string]: any; - }[]; - [k: string]: any; + }[]; + [k: string]: any; }; } diff --git a/core/modules/user/types/UserState.ts b/core/modules/user/types/UserState.ts index 706937beb2..cb96de619c 100644 --- a/core/modules/user/types/UserState.ts +++ b/core/modules/user/types/UserState.ts @@ -1,12 +1,12 @@ export default interface UserState { - token: string, - refreshToken: string, - groupToken: string, - groupId: any, + token: string; + refreshToken: string; + groupToken: string; + groupId: any; current: { - email: string - } | null, - current_storecode: string, - session_started: Date, - orders_history: any + email: string; + } | null; + current_storecode: string; + session_started: Date; + orders_history: any; } diff --git a/core/modules/wishlist/components/AddToWishlist.ts b/core/modules/wishlist/components/AddToWishlist.ts index 00508abc85..366df8136e 100644 --- a/core/modules/wishlist/components/AddToWishlist.ts +++ b/core/modules/wishlist/components/AddToWishlist.ts @@ -1,6 +1,6 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import { Wishlist as WishlistModule } from '../' -import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import { Wishlist as WishlistModule } from '../'; +import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin'; export const AddToWishlist = { name: 'AddToWishlist', @@ -11,12 +11,14 @@ export const AddToWishlist = { type: Object } }, - created () { - WishlistModule.register() + created() { + WishlistModule.register(); }, methods: { - addToWishlist (product: Product) { - return this.$store.state['wishlist'] ? this.$store.dispatch('wishlist/addItem', product) : false + addToWishlist(product: Product) { + return this.$store.state['wishlist'] + ? this.$store.dispatch('wishlist/addItem', product) + : false; } } -} +}; diff --git a/core/modules/wishlist/components/IsOnWishlist.ts b/core/modules/wishlist/components/IsOnWishlist.ts index db825c489a..67508e08f4 100644 --- a/core/modules/wishlist/components/IsOnWishlist.ts +++ b/core/modules/wishlist/components/IsOnWishlist.ts @@ -1,5 +1,5 @@ -import { Wishlist as WishlistModule } from '../' -import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import { Wishlist as WishlistModule } from '../'; +import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin'; export const IsOnWishlist = { name: 'isOnWishlist', @@ -10,12 +10,16 @@ export const IsOnWishlist = { type: Object } }, - created () { - WishlistModule.register() + created() { + WishlistModule.register(); }, computed: { - isOnWishlist (): boolean { - return !!this.$store.state.wishlist.items.find(p => p.sku === this.product.sku) || false + isOnWishlist(): boolean { + return ( + !!this.$store.state.wishlist.items.find( + p => p.sku === this.product.sku + ) || false + ); } - }, -} \ No newline at end of file + } +}; diff --git a/core/modules/wishlist/components/Product.ts b/core/modules/wishlist/components/Product.ts index cc2af11e2a..52acc7689c 100644 --- a/core/modules/wishlist/components/Product.ts +++ b/core/modules/wishlist/components/Product.ts @@ -1,5 +1,5 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin'; export const WishlistProduct = { name: 'Product', @@ -11,13 +11,15 @@ export const WishlistProduct = { } }, computed: { - thumbnail () { - return this.getThumbnail(this.product.image, 150, 150) + thumbnail() { + return this.getThumbnail(this.product.image, 150, 150); } }, methods: { - removeFromWishlist (product: Product) { - return this.$store.state['wishlist'] ? this.$store.dispatch('wishlist/removeItem', product) : false + removeFromWishlist(product: Product) { + return this.$store.state['wishlist'] + ? this.$store.dispatch('wishlist/removeItem', product) + : false; } } -} +}; diff --git a/core/modules/wishlist/components/RemoveFromWishlist.ts b/core/modules/wishlist/components/RemoveFromWishlist.ts index 7c3c843c3f..0285c5c375 100644 --- a/core/modules/wishlist/components/RemoveFromWishlist.ts +++ b/core/modules/wishlist/components/RemoveFromWishlist.ts @@ -1,6 +1,6 @@ -import Product from '@vue-storefront/core/modules/catalog/types/Product' -import { Wishlist as WishlistModule } from '../' -import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import Product from '@vue-storefront/core/modules/catalog/types/Product'; +import { Wishlist as WishlistModule } from '../'; +import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin'; export const RemoveFromWishlist = { name: 'RemoveFromWishlist', @@ -12,9 +12,9 @@ export const RemoveFromWishlist = { } }, methods: { - removeFromWishlist (product: Product) { - WishlistModule.register() - this.$store.dispatch('wishlist/removeItem', product) + removeFromWishlist(product: Product) { + WishlistModule.register(); + this.$store.dispatch('wishlist/removeItem', product); } } -} +}; diff --git a/core/modules/wishlist/components/Wishlist.ts b/core/modules/wishlist/components/Wishlist.ts index 8087a2a890..68fe69d2f4 100644 --- a/core/modules/wishlist/components/Wishlist.ts +++ b/core/modules/wishlist/components/Wishlist.ts @@ -1,23 +1,23 @@ -import { Wishlist as WishlistModule } from '../' -import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import { Wishlist as WishlistModule } from '../'; +import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin'; export const Wishlist = { name: 'Wishlist', mixins: [wishlistMountedMixin], - created () { - WishlistModule.register() + created() { + WishlistModule.register(); }, computed: { - isWishlistOpen () { - return this.$store.state.ui.wishlist + isWishlistOpen() { + return this.$store.state.ui.wishlist; }, - productsInWishlist () { - return this.$store.state.wishlist.items + productsInWishlist() { + return this.$store.state.wishlist.items; } }, methods: { - closeWishlist () { - this.$store.dispatch('ui/toggleWishlist') + closeWishlist() { + this.$store.dispatch('ui/toggleWishlist'); } } -} +}; diff --git a/core/modules/wishlist/components/WishlistButton.ts b/core/modules/wishlist/components/WishlistButton.ts index d3555c3aae..9af64dec56 100644 --- a/core/modules/wishlist/components/WishlistButton.ts +++ b/core/modules/wishlist/components/WishlistButton.ts @@ -1,7 +1,7 @@ export const WishlistButton = { methods: { - toggleWishlist () { - this.$store.dispatch('ui/toggleWishlist') + toggleWishlist() { + this.$store.dispatch('ui/toggleWishlist'); } } -} \ No newline at end of file +}; diff --git a/core/modules/wishlist/index.ts b/core/modules/wishlist/index.ts index 53bfb84445..3b8e4c846e 100644 --- a/core/modules/wishlist/index.ts +++ b/core/modules/wishlist/index.ts @@ -1,12 +1,11 @@ -import { module } from './store' -import { plugin } from './store/plugin' -import { createModule } from '@vue-storefront/core/lib/module' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { module } from './store'; +import { plugin } from './store/plugin'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; -export const KEY = 'wishlist' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'wishlist'; +export const cacheStorage = initCacheStorage(KEY); export const Wishlist = createModule({ key: KEY, - store: { modules: [{ key: KEY, module }], plugin }, -} -) \ No newline at end of file + store: { modules: [{ key: KEY, module }], plugin } +}); diff --git a/core/modules/wishlist/mixins/wishlistMountedMixin.js b/core/modules/wishlist/mixins/wishlistMountedMixin.js index c73cd7feb2..3ecbf026e3 100644 --- a/core/modules/wishlist/mixins/wishlistMountedMixin.js +++ b/core/modules/wishlist/mixins/wishlistMountedMixin.js @@ -4,7 +4,7 @@ */ export default { - mounted () { - this.$store.dispatch('wishlist/load') + mounted() { + this.$store.dispatch('wishlist/load'); } -} +}; diff --git a/core/modules/wishlist/store/actions.ts b/core/modules/wishlist/store/actions.ts index e072d5e5ed..17b9c108d1 100644 --- a/core/modules/wishlist/store/actions.ts +++ b/core/modules/wishlist/store/actions.ts @@ -1,43 +1,51 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import * as types from './mutation-types' -import i18n from '@vue-storefront/i18n' -import { htmlDecode } from '@vue-storefront/core/store/lib/filters' -import rootStore from '@vue-storefront/core/store' -import RootState from '@vue-storefront/core/types/RootState' -import WishlistState from '../types/WishlistState' -import { cacheStorage } from '../' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import * as types from './mutation-types'; +import i18n from '@vue-storefront/i18n'; +import { htmlDecode } from '@vue-storefront/core/store/lib/filters'; +import rootStore from '@vue-storefront/core/store'; +import RootState from '@vue-storefront/core/types/RootState'; +import WishlistState from '../types/WishlistState'; +import { cacheStorage } from '../'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { - clear (context) { - context.commit(types.WISH_LOAD_WISH, []) + clear(context) { + context.commit(types.WISH_LOAD_WISH, []); }, - load ({ commit, getters }, force: boolean = false) { - if (!force && getters.isWishlistLoaded) return - commit(types.SET_WISHLIST_LOADED) + load({ commit, getters }, force: boolean = false) { + if (!force && getters.isWishlistLoaded) return; + commit(types.SET_WISHLIST_LOADED); cacheStorage.getItem('current-wishlist', (err, storedItems) => { - if (err) throw new Error(err) - commit(types.WISH_LOAD_WISH, storedItems) - Logger.info('Wishlist state loaded from browser cache. ', 'cache', storedItems)() - }) + if (err) throw new Error(err); + commit(types.WISH_LOAD_WISH, storedItems); + Logger.info( + 'Wishlist state loaded from browser cache. ', + 'cache', + storedItems + )(); + }); }, - addItem ({ commit }, product) { - commit(types.WISH_ADD_ITEM, { product }) + addItem({ commit }, product) { + commit(types.WISH_ADD_ITEM, { product }); rootStore.dispatch('notification/spawnNotification', { type: 'success', - message: i18n.t('Product {productName} has been added to wishlist!', { productName: htmlDecode(product.name) }), + message: i18n.t('Product {productName} has been added to wishlist!', { + productName: htmlDecode(product.name) + }), action1: { label: i18n.t('OK') } - }) + }); }, - removeItem ({ commit }, product) { - commit(types.WISH_DEL_ITEM, { product }) + removeItem({ commit }, product) { + commit(types.WISH_DEL_ITEM, { product }); rootStore.dispatch('notification/spawnNotification', { type: 'success', - message: i18n.t('Product {productName} has been removed from wishlit!', { productName: htmlDecode(product.name) }), + message: i18n.t('Product {productName} has been removed from wishlit!', { + productName: htmlDecode(product.name) + }), action1: { label: i18n.t('OK') } - }) + }); } -} +}; -export default actions +export default actions; diff --git a/core/modules/wishlist/store/index.ts b/core/modules/wishlist/store/index.ts index c770df0e70..1268b1b538 100644 --- a/core/modules/wishlist/store/index.ts +++ b/core/modules/wishlist/store/index.ts @@ -1,10 +1,10 @@ -import { Module } from 'vuex' -import actions from './actions' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import WishlistState from '../types/WishlistState' +import { Module } from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import WishlistState from '../types/WishlistState'; -export const module:Module = { +export const module: Module = { namespaced: true, state: { loaded: false, @@ -15,5 +15,4 @@ export const module:Module = { getters: { isWishlistLoaded: state => state.loaded } -} - +}; diff --git a/core/modules/wishlist/store/mutation-types.ts b/core/modules/wishlist/store/mutation-types.ts index 9278c74337..6c55985134 100644 --- a/core/modules/wishlist/store/mutation-types.ts +++ b/core/modules/wishlist/store/mutation-types.ts @@ -1,5 +1,5 @@ -export const SN_WISHLIST = 'wishlist' -export const WISH_ADD_ITEM = SN_WISHLIST + '/ADD' -export const WISH_DEL_ITEM = SN_WISHLIST + '/DEL' -export const WISH_LOAD_WISH = SN_WISHLIST + '/LOAD' -export const SET_WISHLIST_LOADED = `${SN_WISHLIST}/SET_WISHLIST_LOADED` \ No newline at end of file +export const SN_WISHLIST = 'wishlist'; +export const WISH_ADD_ITEM = SN_WISHLIST + '/ADD'; +export const WISH_DEL_ITEM = SN_WISHLIST + '/DEL'; +export const WISH_LOAD_WISH = SN_WISHLIST + '/LOAD'; +export const SET_WISHLIST_LOADED = `${SN_WISHLIST}/SET_WISHLIST_LOADED`; diff --git a/core/modules/wishlist/store/mutations.ts b/core/modules/wishlist/store/mutations.ts index a4ede21607..cbd850868e 100644 --- a/core/modules/wishlist/store/mutations.ts +++ b/core/modules/wishlist/store/mutations.ts @@ -1,30 +1,30 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' -import WishlistState from '../types/WishlistState' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; +import WishlistState from '../types/WishlistState'; const mutations: MutationTree = { /** - * Add product to Wishlist - * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md - */ - [types.WISH_ADD_ITEM] (state, { product }) { - const record = state.items.find(p => p.sku === product.sku) + * Add product to Wishlist + * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md + */ + [types.WISH_ADD_ITEM](state, { product }) { + const record = state.items.find(p => p.sku === product.sku); if (!record) { state.items.push({ ...product, qty: 1 - }) + }); } }, - [types.WISH_DEL_ITEM] (state, { product }) { - state.items = state.items.filter(p => p.sku !== product.sku) + [types.WISH_DEL_ITEM](state, { product }) { + state.items = state.items.filter(p => p.sku !== product.sku); }, - [types.WISH_LOAD_WISH] (state, storedItems) { - state.items = storedItems || [] + [types.WISH_LOAD_WISH](state, storedItems) { + state.items = storedItems || []; }, - [types.SET_WISHLIST_LOADED] (state, isLoaded: boolean = true) { - state.loaded = isLoaded + [types.SET_WISHLIST_LOADED](state, isLoaded: boolean = true) { + state.loaded = isLoaded; } -} +}; -export default mutations +export default mutations; diff --git a/core/modules/wishlist/store/plugin.ts b/core/modules/wishlist/store/plugin.ts index e5354c1e45..dd9c2b93bd 100644 --- a/core/modules/wishlist/store/plugin.ts +++ b/core/modules/wishlist/store/plugin.ts @@ -1,12 +1,18 @@ -import * as types from './mutation-types' -import { cacheStorage } from '../' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as types from './mutation-types'; +import { cacheStorage } from '../'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export function plugin (mutation, state) { - const type = mutation.type - if (type.includes(types.WISH_ADD_ITEM) || type.includes(types.WISH_DEL_ITEM)) { // check if this mutation is wishlist related - cacheStorage.setItem('current-wishlist', state.wishlist.items).catch((reason) => { - Logger.error(reason, 'wishlist') // it doesn't work on SSR - }) +export function plugin(mutation, state) { + const type = mutation.type; + if ( + type.includes(types.WISH_ADD_ITEM) || + type.includes(types.WISH_DEL_ITEM) + ) { + // check if this mutation is wishlist related + cacheStorage + .setItem('current-wishlist', state.wishlist.items) + .catch(reason => { + Logger.error(reason, 'wishlist'); // it doesn't work on SSR + }); } } diff --git a/core/modules/wishlist/types/WishlistState.ts b/core/modules/wishlist/types/WishlistState.ts index 38e55fe9c3..508d7852ab 100644 --- a/core/modules/wishlist/types/WishlistState.ts +++ b/core/modules/wishlist/types/WishlistState.ts @@ -2,6 +2,6 @@ export default interface WishlistState { /** * Informs if wishlist is already loaded from local cache. */ - loaded: boolean, - items: any[] + loaded: boolean; + items: any[]; } diff --git a/core/pages/Category.js b/core/pages/Category.js index ffa2884d47..f62d15b274 100644 --- a/core/pages/Category.js +++ b/core/pages/Category.js @@ -1,20 +1,27 @@ -import Vue from 'vue' -import toString from 'lodash-es/toString' +import Vue from 'vue'; +import toString from 'lodash-es/toString'; -import i18n from '@vue-storefront/i18n' -import store from '@vue-storefront/core/store' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -import { baseFilterProductsQuery, buildFilterProductsQuery, isServer } from '@vue-storefront/core/helpers' -import { htmlDecode } from '@vue-storefront/core/filters/html-decode' -import { currentStoreView, localizedRoute } from '@vue-storefront/core/lib/multistore' -import Composite from '@vue-storefront/core/mixins/composite' -import { Logger } from '@vue-storefront/core/lib/logger' -import { mapGetters, mapActions } from 'vuex' +import i18n from '@vue-storefront/i18n'; +import store from '@vue-storefront/core/store'; +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'; +import { + baseFilterProductsQuery, + buildFilterProductsQuery, + isServer +} from '@vue-storefront/core/helpers'; +import { htmlDecode } from '@vue-storefront/core/filters/html-decode'; +import { + currentStoreView, + localizedRoute +} from '@vue-storefront/core/lib/multistore'; +import Composite from '@vue-storefront/core/mixins/composite'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { mapGetters, mapActions } from 'vuex'; export default { name: 'Category', mixins: [Composite], - data () { + data() { return { pagination: { perPage: 50, @@ -23,50 +30,61 @@ export default { }, bottom: false, lazyLoadProductsOnscroll: true - } + }; }, computed: { - ...mapGetters('category', ['getCurrentCategory', 'getCurrentCategoryProductQuery', 'getAllCategoryFilters', 'getCategoryBreadcrumbs', 'getCurrentCategoryPath']), - products () { - return this.$store.state.product.list.items + ...mapGetters('category', [ + 'getCurrentCategory', + 'getCurrentCategoryProductQuery', + 'getAllCategoryFilters', + 'getCategoryBreadcrumbs', + 'getCurrentCategoryPath' + ]), + products() { + return this.$store.state.product.list.items; }, - productsCounter () { - return this.$store.state.product.list.items ? this.$store.state.product.list.items.length : 0 + productsCounter() { + return this.$store.state.product.list.items + ? this.$store.state.product.list.items.length + : 0; }, - productsTotal () { - return this.$store.state.product.list.total + productsTotal() { + return this.$store.state.product.list.total; }, - currentQuery () { - return this.getCurrentCategoryProductQuery + currentQuery() { + return this.getCurrentCategoryProductQuery; }, - isCategoryEmpty () { - return (!(this.$store.state.product.list.items) || this.$store.state.product.list.items.length === 0) + isCategoryEmpty() { + return ( + !this.$store.state.product.list.items || + this.$store.state.product.list.items.length === 0 + ); }, - category () { - return this.getCurrentCategory + category() { + return this.getCurrentCategory; }, - categoryName () { - return this.getCurrentCategory ? this.getCurrentCategory.name : '' + categoryName() { + return this.getCurrentCategory ? this.getCurrentCategory.name : ''; }, - categoryId () { - return this.getCurrentCategory ? this.getCurrentCategory.id : '' + categoryId() { + return this.getCurrentCategory ? this.getCurrentCategory.id : ''; }, - filters () { - return this.getAllCategoryFilters + filters() { + return this.getAllCategoryFilters; }, - breadcrumbs () { - return this.getCategoryBreadcrumbs + breadcrumbs() { + return this.getCategoryBreadcrumbs; } }, watch: { - bottom (bottom) { + bottom(bottom) { if (bottom) { - this.pullMoreProducts() + this.pullMoreProducts(); } } }, - preAsyncData ({ store, route }) { - Logger.log('preAsyncData query setup')() + preAsyncData({ store, route }) { + Logger.log('preAsyncData query setup')(); store.dispatch('category/setSearchOptions', { populateAggregations: true, store: store, @@ -75,121 +93,167 @@ export default { perPage: 50, sort: store.state.config.entities.productList.sort, filters: store.state.config.products.defaultFilters, - includeFields: store.state.config.entities.optimize && isServer ? store.state.config.entities.productList.includeFields : null, - excludeFields: store.state.config.entities.optimize && isServer ? store.state.config.entities.productList.excludeFields : null, + includeFields: + store.state.config.entities.optimize && isServer + ? store.state.config.entities.productList.includeFields + : null, + excludeFields: + store.state.config.entities.optimize && isServer + ? store.state.config.entities.productList.excludeFields + : null, append: false - }) + }); }, - async asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data - Logger.info('Entering asyncData in Category Page (core)')() + async asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data + Logger.info('Entering asyncData in Category Page (core)')(); try { - if (context) context.output.cacheTags.add(`category`) - const defaultFilters = store.state.config.products.defaultFilters - store.dispatch('category/resetFilters') - EventBus.$emit('filter-reset') - await store.dispatch('attribute/list', { // load filter attributes for this specific category + if (context) context.output.cacheTags.add(`category`); + const defaultFilters = store.state.config.products.defaultFilters; + store.dispatch('category/resetFilters'); + EventBus.$emit('filter-reset'); + await store.dispatch('attribute/list', { + // load filter attributes for this specific category filterValues: defaultFilters, // TODO: assign specific filters/ attribute codes dynamicaly to specific categories - includeFields: store.state.config.entities.optimize && isServer ? store.state.config.entities.attribute.includeFields : null - }) - const parentCategory = await store.dispatch('category/single', { key: store.state.config.products.useMagentoUrlKeys ? 'url_key' : 'slug', value: route.params.slug }) - let query = store.getters['category/getCurrentCategoryProductQuery'] + includeFields: + store.state.config.entities.optimize && isServer + ? store.state.config.entities.attribute.includeFields + : null + }); + const parentCategory = await store.dispatch('category/single', { + key: store.state.config.products.useMagentoUrlKeys ? 'url_key' : 'slug', + value: route.params.slug + }); + let query = store.getters['category/getCurrentCategoryProductQuery']; if (!query.searchProductQuery) { store.dispatch('category/mergeSearchOptions', { - searchProductQuery: baseFilterProductsQuery(parentCategory, defaultFilters) - }) + searchProductQuery: baseFilterProductsQuery( + parentCategory, + defaultFilters + ) + }); } - const subloaders = await store.dispatch('category/products', query) + const subloaders = await store.dispatch('category/products', query); if (subloaders) { - await Promise.all(subloaders) - await EventBus.$emitFilter('category-after-load', { store: store, route: route }) + await Promise.all(subloaders); + await EventBus.$emitFilter('category-after-load', { + store: store, + route: route + }); } else { - throw new Error('Category query returned empty result') + throw new Error('Category query returned empty result'); } } catch (err) { - Logger.error(err)() - throw err + Logger.error(err)(); + throw err; } }, - async beforeRouteEnter (to, from, next) { - if (!isServer && !from.name) { // Loading category products to cache on SSR render + async beforeRouteEnter(to, from, next) { + if (!isServer && !from.name) { + // Loading category products to cache on SSR render next(vm => { - const defaultFilters = store.state.config.products.defaultFilters - let parentCategory = store.getters['category/getCurrentCategory'] - let query = store.getters['category/getCurrentCategoryProductQuery'] + const defaultFilters = store.state.config.products.defaultFilters; + let parentCategory = store.getters['category/getCurrentCategory']; + let query = store.getters['category/getCurrentCategoryProductQuery']; if (!query.searchProductQuery) { store.dispatch('category/mergeSearchOptions', { - searchProductQuery: baseFilterProductsQuery(parentCategory, defaultFilters) - }) + searchProductQuery: baseFilterProductsQuery( + parentCategory, + defaultFilters + ) + }); } - store.dispatch('category/products', query) - }) + store.dispatch('category/products', query); + }); } else { - next() + next(); } }, - beforeMount () { - this.$bus.$on('filter-changed-category', this.onFilterChanged) - this.$bus.$on('list-change-sort', this.onSortOrderChanged) + beforeMount() { + this.$bus.$on('filter-changed-category', this.onFilterChanged); + this.$bus.$on('list-change-sort', this.onSortOrderChanged); if (store.state.config.usePriceTiers) { - this.$bus.$on('user-after-loggedin', this.onUserPricesRefreshed) - this.$bus.$on('user-after-logout', this.onUserPricesRefreshed) + this.$bus.$on('user-after-loggedin', this.onUserPricesRefreshed); + this.$bus.$on('user-after-logout', this.onUserPricesRefreshed); } if (!isServer && this.lazyLoadProductsOnscroll) { - window.addEventListener('scroll', () => { - this.bottom = this.bottomVisible() - }, {passive: true}) + window.addEventListener( + 'scroll', + () => { + this.bottom = this.bottomVisible(); + }, + { passive: true } + ); } }, - beforeDestroy () { - this.$bus.$off('list-change-sort', this.onSortOrderChanged) - this.$bus.$off('filter-changed-category', this.onFilterChanged) + beforeDestroy() { + this.$bus.$off('list-change-sort', this.onSortOrderChanged); + this.$bus.$off('filter-changed-category', this.onFilterChanged); if (store.state.config.usePriceTiers) { - this.$bus.$off('user-after-loggedin', this.onUserPricesRefreshed) - this.$bus.$off('user-after-logout', this.onUserPricesRefreshed) + this.$bus.$off('user-after-loggedin', this.onUserPricesRefreshed); + this.$bus.$off('user-after-logout', this.onUserPricesRefreshed); } }, - beforeRouteUpdate (to, from, next) { - this.validateRoute(to) - next() + beforeRouteUpdate(to, from, next) { + this.validateRoute(to); + next(); }, methods: { ...mapActions('category', ['mergeSearchOptions']), - bottomVisible () { - const scrollY = window.scrollY - const visible = window.innerHeight - const pageHeight = document.documentElement.scrollHeight - const bottomOfPage = visible + scrollY >= pageHeight - return bottomOfPage || pageHeight < visible + bottomVisible() { + const scrollY = window.scrollY; + const visible = window.innerHeight; + const pageHeight = document.documentElement.scrollHeight; + const bottomOfPage = visible + scrollY >= pageHeight; + return bottomOfPage || pageHeight < visible; }, - pullMoreProducts () { - if (typeof navigator !== 'undefined' && !navigator.onLine) return - let current = this.getCurrentCategoryProductQuery.current + this.getCurrentCategoryProductQuery.perPage + pullMoreProducts() { + if (typeof navigator !== 'undefined' && !navigator.onLine) return; + let current = + this.getCurrentCategoryProductQuery.current + + this.getCurrentCategoryProductQuery.perPage; this.mergeSearchOptions({ append: true, route: this.$route, store: this.$store, current - }) - this.pagination.current = this.getCurrentCategoryProductQuery.current - this.pagination.perPage = this.getCurrentCategoryProductQuery.perPage + }); + this.pagination.current = this.getCurrentCategoryProductQuery.current; + this.pagination.perPage = this.getCurrentCategoryProductQuery.perPage; if (this.getCurrentCategoryProductQuery.current <= this.productsTotal) { this.mergeSearchOptions({ - searchProductQuery: buildFilterProductsQuery(this.category, this.filters.chosen) - }) - return this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery) + searchProductQuery: buildFilterProductsQuery( + this.category, + this.filters.chosen + ) + }); + return this.$store.dispatch( + 'category/products', + this.getCurrentCategoryProductQuery + ); } }, - onFilterChanged (filterOption) { - this.pagination.current = 0 - if (this.filters.chosen[filterOption.attribute_code] && ((toString(filterOption.id) === toString(this.filters.chosen[filterOption.attribute_code].id)) || filterOption.id === this.filters.chosen[filterOption.attribute_code].id)) { // for price filter it's a string - Vue.delete(this.filters.chosen, filterOption.attribute_code) + onFilterChanged(filterOption) { + this.pagination.current = 0; + if ( + this.filters.chosen[filterOption.attribute_code] && + (toString(filterOption.id) === + toString(this.filters.chosen[filterOption.attribute_code].id) || + filterOption.id === + this.filters.chosen[filterOption.attribute_code].id) + ) { + // for price filter it's a string + Vue.delete(this.filters.chosen, filterOption.attribute_code); } else { - Vue.set(this.filters.chosen, filterOption.attribute_code, filterOption) + Vue.set(this.filters.chosen, filterOption.attribute_code, filterOption); } - let filterQr = buildFilterProductsQuery(this.category, this.filters.chosen) + let filterQr = buildFilterProductsQuery( + this.category, + this.filters.chosen + ); - const filtersConfig = Object.assign({}, this.filters.chosen) // create a copy because it will be used asynchronously (take a look below) + const filtersConfig = Object.assign({}, this.filters.chosen); // create a copy because it will be used asynchronously (take a look below) this.mergeSearchOptions({ populateAggregations: false, searchProductQuery: filterQr, @@ -199,15 +263,19 @@ export default { append: false, includeFields: null, excludeFields: null - }) - this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery).then((res) => { - }) // because already aggregated + }); + this.$store + .dispatch('category/products', this.getCurrentCategoryProductQuery) + .then(res => {}); // because already aggregated }, - onSortOrderChanged (param) { - this.pagination.current = 0 + onSortOrderChanged(param) { + this.pagination.current = 0; if (param.attribute) { - const filtersConfig = Object.assign({}, this.filters.chosen) // create a copy because it will be used asynchronously (take a look below) - let filterQr = buildFilterProductsQuery(this.category, this.filters.chosen) + const filtersConfig = Object.assign({}, this.filters.chosen); // create a copy because it will be used asynchronously (take a look below) + let filterQr = buildFilterProductsQuery( + this.category, + this.filters.chosen + ); this.mergeSearchOptions({ sort: param.attribute, searchProductQuery: filterQr, @@ -217,82 +285,131 @@ export default { append: false, includeFields: null, excludeFields: null - }) - this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery).then((res) => { - }) + }); + this.$store + .dispatch('category/products', this.getCurrentCategoryProductQuery) + .then(res => {}); } else { - this.notify() + this.notify(); } }, - validateRoute (route = this.$route) { - this.$store.dispatch('category/resetFilters') - this.$bus.$emit('filter-reset') + validateRoute(route = this.$route) { + this.$store.dispatch('category/resetFilters'); + this.$bus.$emit('filter-reset'); - this.$store.dispatch('category/single', { key: this.$store.state.config.products.useMagentoUrlKeys ? 'url_key' : 'slug', value: route.params.slug }).then(category => { - if (!category) { - this.$router.push(this.localizedRoute('/')) - } else { - this.pagination.current = 0 - let searchProductQuery = baseFilterProductsQuery(this.getCurrentCategory, store.state.config.products.defaultFilters) - this.$bus.$emit('current-category-changed', this.getCurrentCategoryPath) - this.mergeSearchOptions({ // base prototype from the asyncData is being used here - current: this.pagination.current, - perPage: this.pagination.perPage, - store: this.$store, - route: this.$route, - append: false, - populateAggregations: true - }) - if (!this.getCurrentCategoryProductQuery.searchProductQuery) { + this.$store + .dispatch('category/single', { + key: this.$store.state.config.products.useMagentoUrlKeys + ? 'url_key' + : 'slug', + value: route.params.slug + }) + .then(category => { + if (!category) { + this.$router.push(this.localizedRoute('/')); + } else { + this.pagination.current = 0; + let searchProductQuery = baseFilterProductsQuery( + this.getCurrentCategory, + store.state.config.products.defaultFilters + ); + this.$bus.$emit( + 'current-category-changed', + this.getCurrentCategoryPath + ); this.mergeSearchOptions({ - searchProductQuery - }) + // base prototype from the asyncData is being used here + current: this.pagination.current, + perPage: this.pagination.perPage, + store: this.$store, + route: this.$route, + append: false, + populateAggregations: true + }); + if (!this.getCurrentCategoryProductQuery.searchProductQuery) { + this.mergeSearchOptions({ + searchProductQuery + }); + } + this.$store.dispatch( + 'category/products', + this.getCurrentCategoryProductQuery + ); + this.$bus.$emitFilter('category-after-load', { + store: this.$store, + route: route + }); } - this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery) - this.$bus.$emitFilter('category-after-load', { store: this.$store, route: route }) - } - }).catch(err => { - if (err.message.indexOf('query returned empty result') > 0) { - this.$store.dispatch('notification/spawnNotification', { - type: 'error', - message: i18n.t('The product, category or CMS page is not available in Offline mode. Redirecting to Home.'), - action1: { label: i18n.t('OK') } - }) - this.$router.push(localizedRoute('/', currentStoreView().storeCode)) - } - }) + }) + .catch(err => { + if (err.message.indexOf('query returned empty result') > 0) { + this.$store.dispatch('notification/spawnNotification', { + type: 'error', + message: i18n.t( + 'The product, category or CMS page is not available in Offline mode. Redirecting to Home.' + ), + action1: { label: i18n.t('OK') } + }); + this.$router.push( + localizedRoute('/', currentStoreView().storeCode) + ); + } + }); }, - onUserPricesRefreshed () { - const defaultFilters = store.state.config.products.defaultFilters - this.$store.dispatch('category/single', { - key: this.$store.state.config.products.useMagentoUrlKeys ? 'url_key' : 'slug', - value: this.$route.params.slug - }).then((parentCategory) => { - if (!this.getCurrentCategoryProductQuery.searchProductQuery) { - this.mergeSearchOptions({ - searchProductQuery: baseFilterProductsQuery(parentCategory, defaultFilters), - skipCache: true - }) - } - this.$store.dispatch('category/products', this.getCurrentCategoryProductQuery) - }) + onUserPricesRefreshed() { + const defaultFilters = store.state.config.products.defaultFilters; + this.$store + .dispatch('category/single', { + key: this.$store.state.config.products.useMagentoUrlKeys + ? 'url_key' + : 'slug', + value: this.$route.params.slug + }) + .then(parentCategory => { + if (!this.getCurrentCategoryProductQuery.searchProductQuery) { + this.mergeSearchOptions({ + searchProductQuery: baseFilterProductsQuery( + parentCategory, + defaultFilters + ), + skipCache: true + }); + } + this.$store.dispatch( + 'category/products', + this.getCurrentCategoryProductQuery + ); + }); } }, - metaInfo () { - const storeView = currentStoreView() + metaInfo() { + const storeView = currentStoreView(); return { link: [ - { rel: 'amphtml', - href: this.$router.resolve(localizedRoute({ - name: 'category-amp', - params: { - slug: this.category.slug - } - }, storeView.storeCode)).href + { + rel: 'amphtml', + href: this.$router.resolve( + localizedRoute( + { + name: 'category-amp', + params: { + slug: this.category.slug + } + }, + storeView.storeCode + ) + ).href } ], title: htmlDecode(this.category.meta_title || this.categoryName), - meta: this.category.meta_description ? [{ vmid: 'description', description: htmlDecode(this.category.meta_description) }] : [] - } + meta: this.category.meta_description + ? [ + { + vmid: 'description', + description: htmlDecode(this.category.meta_description) + } + ] + : [] + }; } -} +}; diff --git a/core/pages/Checkout.js b/core/pages/Checkout.js index fcf770e4ca..6dda019c32 100644 --- a/core/pages/Checkout.js +++ b/core/pages/Checkout.js @@ -1,18 +1,18 @@ -import Vue from 'vue' -import i18n from '@vue-storefront/i18n' -import store from '@vue-storefront/core/store' -import VueOfflineMixin from 'vue-offline/mixin' -import { mapGetters } from 'vuex' +import Vue from 'vue'; +import i18n from '@vue-storefront/i18n'; +import store from '@vue-storefront/core/store'; +import VueOfflineMixin from 'vue-offline/mixin'; +import { mapGetters } from 'vuex'; -import Composite from '@vue-storefront/core/mixins/composite' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { isServer } from '@vue-storefront/core/helpers' -import { Logger } from '@vue-storefront/core/lib/logger' +import Composite from '@vue-storefront/core/mixins/composite'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import { isServer } from '@vue-storefront/core/helpers'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'Checkout', mixins: [Composite, VueOfflineMixin], - data () { + data() { return { stockCheckCompleted: false, stockCheckOK: false, @@ -37,7 +37,7 @@ export default { }, userId: null, focusedField: null - } + }; }, computed: { ...mapGetters({ @@ -45,162 +45,197 @@ export default { isThankYouPage: 'checkout/isThankYouPage' }) }, - beforeMount () { + beforeMount() { // TO-DO: Use one event with name as apram - this.$bus.$on('cart-after-update', this.onCartAfterUpdate) - this.$bus.$on('cart-after-delete', this.onCartAfterUpdate) - this.$bus.$on('checkout-after-personalDetails', this.onAfterPersonalDetails) - this.$bus.$on('checkout-after-shippingDetails', this.onAfterShippingDetails) - this.$bus.$on('checkout-after-paymentDetails', this.onAfterPaymentDetails) - this.$bus.$on('checkout-after-cartSummary', this.onAfterCartSummary) - this.$bus.$on('checkout-before-placeOrder', this.onBeforePlaceOrder) - this.$bus.$on('checkout-do-placeOrder', this.onDoPlaceOrder) - this.$bus.$on('checkout-before-edit', this.onBeforeEdit) - this.$bus.$on('order-after-placed', this.onAfterPlaceOrder) - this.$bus.$on('checkout-before-shippingMethods', this.onBeforeShippingMethods) - this.$bus.$on('checkout-after-shippingMethodChanged', this.onAfterShippingMethodChanged) - this.$bus.$on('checkout-after-validationError', this.focusField) + this.$bus.$on('cart-after-update', this.onCartAfterUpdate); + this.$bus.$on('cart-after-delete', this.onCartAfterUpdate); + this.$bus.$on( + 'checkout-after-personalDetails', + this.onAfterPersonalDetails + ); + this.$bus.$on( + 'checkout-after-shippingDetails', + this.onAfterShippingDetails + ); + this.$bus.$on('checkout-after-paymentDetails', this.onAfterPaymentDetails); + this.$bus.$on('checkout-after-cartSummary', this.onAfterCartSummary); + this.$bus.$on('checkout-before-placeOrder', this.onBeforePlaceOrder); + this.$bus.$on('checkout-do-placeOrder', this.onDoPlaceOrder); + this.$bus.$on('checkout-before-edit', this.onBeforeEdit); + this.$bus.$on('order-after-placed', this.onAfterPlaceOrder); + this.$bus.$on( + 'checkout-before-shippingMethods', + this.onBeforeShippingMethods + ); + this.$bus.$on( + 'checkout-after-shippingMethodChanged', + this.onAfterShippingMethodChanged + ); + this.$bus.$on('checkout-after-validationError', this.focusField); if (!this.isThankYouPage) { this.$store.dispatch('cart/load').then(() => { if (this.$store.state.cart.cartItems.length === 0) { - this.notifyEmptyCart() - this.$router.push(this.localizedRoute('/')) + this.notifyEmptyCart(); + this.$router.push(this.localizedRoute('/')); } else { - this.stockCheckCompleted = false - const checkPromises = [] - for (let product of this.$store.state.cart.cartItems) { // check the results of online stock check + this.stockCheckCompleted = false; + const checkPromises = []; + for (let product of this.$store.state.cart.cartItems) { + // check the results of online stock check if (product.onlineStockCheckid) { - checkPromises.push(new Promise((resolve, reject) => { - Vue.prototype.$db.syncTaskCollection.getItem(product.onlineStockCheckid, (err, item) => { - if (err || !item) { - if (err) Logger.error(err)() - resolve(null) - } else { - product.stock = item.result - resolve(product) - } + checkPromises.push( + new Promise((resolve, reject) => { + Vue.prototype.$db.syncTaskCollection.getItem( + product.onlineStockCheckid, + (err, item) => { + if (err || !item) { + if (err) Logger.error(err)(); + resolve(null); + } else { + product.stock = item.result; + resolve(product); + } + } + ); }) - })) + ); } } - Promise.all(checkPromises).then((checkedProducts) => { - this.stockCheckCompleted = true - this.stockCheckOK = true + Promise.all(checkPromises).then(checkedProducts => { + this.stockCheckCompleted = true; + this.stockCheckOK = true; for (let chp of checkedProducts) { if (chp && chp.stock) { if (!chp.stock.is_in_stock) { - this.stockCheckOK = false - chp.errors.stock = i18n.t('Out of stock!') - this.notifyOutStock(chp) + this.stockCheckOK = false; + chp.errors.stock = i18n.t('Out of stock!'); + this.notifyOutStock(chp); } } } - }) + }); } - }) + }); } - const storeView = currentStoreView() - let country = this.$store.state.checkout.shippingDetails.country - if (!country) country = storeView.i18n.defaultCountry - this.$bus.$emit('checkout-before-shippingMethods', country) - this.$store.dispatch('cart/getPaymentMethods') + const storeView = currentStoreView(); + let country = this.$store.state.checkout.shippingDetails.country; + if (!country) country = storeView.i18n.defaultCountry; + this.$bus.$emit('checkout-before-shippingMethods', country); + this.$store.dispatch('cart/getPaymentMethods'); }, - beforeDestroy () { - this.$bus.$off('cart-after-update', this.onCartAfterUpdate) - this.$bus.$off('cart-after-delete', this.onCartAfterUpdate) - this.$bus.$off('checkout-after-personalDetails', this.onAfterPersonalDetails) - this.$bus.$off('checkout-after-shippingDetails', this.onAfterShippingDetails) - this.$bus.$off('checkout-after-paymentDetails', this.onAfterPaymentDetails) - this.$bus.$off('checkout-after-cartSummary', this.onAfterCartSummary) - this.$bus.$off('checkout-before-placeOrder', this.onBeforePlaceOrder) - this.$bus.$off('checkout-do-placeOrder', this.onDoPlaceOrder) - this.$bus.$off('checkout-before-edit', this.onBeforeEdit) - this.$bus.$off('order-after-placed', this.onAfterPlaceOrder) - this.$bus.$off('checkout-before-shippingMethods', this.onBeforeShippingMethods) - this.$bus.$off('checkout-after-shippingMethodChanged', this.onAfterShippingMethodChanged) - this.$bus.$off('checkout-after-validationError', this.focusField) + beforeDestroy() { + this.$bus.$off('cart-after-update', this.onCartAfterUpdate); + this.$bus.$off('cart-after-delete', this.onCartAfterUpdate); + this.$bus.$off( + 'checkout-after-personalDetails', + this.onAfterPersonalDetails + ); + this.$bus.$off( + 'checkout-after-shippingDetails', + this.onAfterShippingDetails + ); + this.$bus.$off('checkout-after-paymentDetails', this.onAfterPaymentDetails); + this.$bus.$off('checkout-after-cartSummary', this.onAfterCartSummary); + this.$bus.$off('checkout-before-placeOrder', this.onBeforePlaceOrder); + this.$bus.$off('checkout-do-placeOrder', this.onDoPlaceOrder); + this.$bus.$off('checkout-before-edit', this.onBeforeEdit); + this.$bus.$off('order-after-placed', this.onAfterPlaceOrder); + this.$bus.$off( + 'checkout-before-shippingMethods', + this.onBeforeShippingMethods + ); + this.$bus.$off( + 'checkout-after-shippingMethodChanged', + this.onAfterShippingMethodChanged + ); + this.$bus.$off('checkout-after-validationError', this.focusField); }, watch: { - '$route': 'activateHashSection', - 'OnlineOnly': 'onNetworkStatusCheck' + $route: 'activateHashSection', + OnlineOnly: 'onNetworkStatusCheck' }, methods: { - onCartAfterUpdate (payload) { + onCartAfterUpdate(payload) { if (this.$store.state.cart.cartItems.length === 0) { - this.notifyEmptyCart() - this.$router.push(this.localizedRoute('/')) + this.notifyEmptyCart(); + this.$router.push(this.localizedRoute('/')); } }, - onAfterShippingMethodChanged (payload) { - this.$store.dispatch('cart/refreshTotals', payload) - this.shippingMethod = payload + onAfterShippingMethodChanged(payload) { + this.$store.dispatch('cart/refreshTotals', payload); + this.shippingMethod = payload; }, - onBeforeShippingMethods (country) { - this.$store.dispatch('cart/getShippingMethods', { - country_id: country - }).then(() => { - this.$store.dispatch('cart/refreshTotals') - this.$forceUpdate() - }) + onBeforeShippingMethods(country) { + this.$store + .dispatch('cart/getShippingMethods', { + country_id: country + }) + .then(() => { + this.$store.dispatch('cart/refreshTotals'); + this.$forceUpdate(); + }); }, - onAfterPlaceOrder (payload) { - this.confirmation = payload.confirmation - this.$store.dispatch('checkout/setThankYouPage', true) - this.$store.dispatch('user/getOrdersHistory', { refresh: true, useCache: true }) - Logger.debug(payload.order)() + onAfterPlaceOrder(payload) { + this.confirmation = payload.confirmation; + this.$store.dispatch('checkout/setThankYouPage', true); + this.$store.dispatch('user/getOrdersHistory', { + refresh: true, + useCache: true + }); + Logger.debug(payload.order)(); }, - onBeforeEdit (section) { - this.activateSection(section) + onBeforeEdit(section) { + this.activateSection(section); }, - onBeforePlaceOrder (userId) { + onBeforePlaceOrder(userId) { if (userId) { - this.userId = userId.toString() + this.userId = userId.toString(); } }, - onAfterCartSummary (receivedData) { - this.cartSummary = receivedData + onAfterCartSummary(receivedData) { + this.cartSummary = receivedData; }, - onDoPlaceOrder (additionalPayload) { + onDoPlaceOrder(additionalPayload) { if (this.$store.state.cart.cartItems.length === 0) { - this.notifyEmptyCart() - this.$router.push(this.localizedRoute('/')) + this.notifyEmptyCart(); + this.$router.push(this.localizedRoute('/')); } else { - this.payment.paymentMethodAdditional = additionalPayload - this.placeOrder() + this.payment.paymentMethodAdditional = additionalPayload; + this.placeOrder(); } }, - onAfterPaymentDetails (receivedData, validationResult) { - this.payment = receivedData - this.validationResults.payment = validationResult - this.activateSection('orderReview') - this.savePaymentDetails() + onAfterPaymentDetails(receivedData, validationResult) { + this.payment = receivedData; + this.validationResults.payment = validationResult; + this.activateSection('orderReview'); + this.savePaymentDetails(); }, - onAfterShippingDetails (receivedData, validationResult) { - this.shipping = receivedData - this.validationResults.shipping = validationResult - this.activateSection('payment') - this.saveShippingDetails() + onAfterShippingDetails(receivedData, validationResult) { + this.shipping = receivedData; + this.validationResults.shipping = validationResult; + this.activateSection('payment'); + this.saveShippingDetails(); - const storeView = currentStoreView() - storeView.tax.defaultCountry = this.shipping.country + const storeView = currentStoreView(); + storeView.tax.defaultCountry = this.shipping.country; }, - onAfterPersonalDetails (receivedData, validationResult) { - this.personalDetails = receivedData - this.validationResults.personalDetails = validationResult + onAfterPersonalDetails(receivedData, validationResult) { + this.personalDetails = receivedData; + this.validationResults.personalDetails = validationResult; if (this.isVirtualCart === true) { - this.activateSection('payment') + this.activateSection('payment'); } else { - this.activateSection('shipping') + this.activateSection('shipping'); } - this.savePersonalDetails() - this.focusedField = null + this.savePersonalDetails(); + this.focusedField = null; }, - onNetworkStatusCheck (isOnline) { - this.checkConnection(isOnline) + onNetworkStatusCheck(isOnline) { + this.checkConnection(isOnline); }, - checkStocks () { - let isValid = true + checkStocks() { + let isValid = true; for (let child of this.$children) { if (child.hasOwnProperty('$v')) { if (child.$v.$invalid) { @@ -208,12 +243,12 @@ export default { // If so, then ignore validation of account creation fields. if (child.$v.hasOwnProperty('personalDetails')) { if (child.$v.personalDetails.$invalid) { - isValid = false - break + isValid = false; + break; } } else { - isValid = false - break + isValid = false; + break; } } } @@ -222,50 +257,69 @@ export default { if (typeof navigator !== 'undefined' && navigator.onLine) { if (this.stockCheckCompleted) { if (!this.stockCheckOK) { - isValid = false - this.notifyNotAvailable() + isValid = false; + this.notifyNotAvailable(); } } else { - this.notifyStockCheck() - isValid = false + this.notifyStockCheck(); + isValid = false; } } - return isValid + return isValid; }, - activateHashSection () { + activateHashSection() { if (!isServer) { - var urlStep = window.location.hash.replace('#', '') - if (this.activeSection.hasOwnProperty(urlStep) && this.activeSection[urlStep] === false) { - this.activateSection(urlStep) + var urlStep = window.location.hash.replace('#', ''); + if ( + this.activeSection.hasOwnProperty(urlStep) && + this.activeSection[urlStep] === false + ) { + this.activateSection(urlStep); } else if (urlStep === '') { - this.activateSection('personalDetails') + this.activateSection('personalDetails'); } } }, - checkConnection (isOnline) { + checkConnection(isOnline) { if (!isOnline) { - this.notifyNoConnection() + this.notifyNoConnection(); } }, - activateSection (sectionToActivate) { + activateSection(sectionToActivate) { for (let section in this.activeSection) { - this.activeSection[section] = false + this.activeSection[section] = false; } - this.activeSection[sectionToActivate] = true - if (!isServer) window.location.href = window.location.origin + window.location.pathname + '#' + sectionToActivate + this.activeSection[sectionToActivate] = true; + if (!isServer) + window.location.href = + window.location.origin + + window.location.pathname + + '#' + + sectionToActivate; }, // This method checks if there exists a mapping of chosen payment method to one of Magento's payment methods. - getPaymentMethod () { - let paymentMethod = this.payment.paymentMethod - if (store.state.config.orders.payment_methods_mapping.hasOwnProperty(paymentMethod)) { - paymentMethod = store.state.config.orders.payment_methods_mapping[paymentMethod] + getPaymentMethod() { + let paymentMethod = this.payment.paymentMethod; + if ( + store.state.config.orders.payment_methods_mapping.hasOwnProperty( + paymentMethod + ) + ) { + paymentMethod = + store.state.config.orders.payment_methods_mapping[paymentMethod]; } - return paymentMethod + return paymentMethod; }, - prepareOrder () { + prepareOrder() { this.order = { - user_id: this.$store.state.user.current ? this.$store.state.user.current.id.toString() : (this.userId ? this.userId : ''), - cart_id: this.$store.state.cart.cartServerToken ? this.$store.state.cart.cartServerToken : '', + user_id: this.$store.state.user.current + ? this.$store.state.user.current.id.toString() + : this.userId + ? this.userId + : '', + cart_id: this.$store.state.cart.cartServerToken + ? this.$store.state.cart.cartServerToken + : '', products: this.$store.state.cart.cartItems, addressInformation: { billingAddress: { @@ -280,16 +334,22 @@ export default { firstname: this.payment.firstName, lastname: this.payment.lastName, email: this.personalDetails.emailAddress, - region_code: this.payment.region_code ? this.payment.region_code : '', + region_code: this.payment.region_code + ? this.payment.region_code + : '', vat_id: this.payment.taxId }, - shipping_method_code: this.shippingMethod.method_code ? this.shippingMethod.method_code : this.shipping.shippingMethod, - shipping_carrier_code: this.shippingMethod.carrier_code ? this.shippingMethod.carrier_code : this.shipping.shippingCarrier, + shipping_method_code: this.shippingMethod.method_code + ? this.shippingMethod.method_code + : this.shipping.shippingMethod, + shipping_carrier_code: this.shippingMethod.carrier_code + ? this.shippingMethod.carrier_code + : this.shipping.shippingCarrier, payment_method_code: this.getPaymentMethod(), payment_method_additional: this.payment.paymentMethodAdditional, shippingExtraFields: this.shipping.extraFields } - } + }; if (!this.isVirtualCart) { this.order.addressInformation.shippingAddress = { region: this.shipping.state, @@ -303,52 +363,64 @@ export default { firstname: this.shipping.firstName, lastname: this.shipping.lastName, email: this.personalDetails.emailAddress, - region_code: this.shipping.region_code ? this.shipping.region_code : '' - } + region_code: this.shipping.region_code + ? this.shipping.region_code + : '' + }; } - return this.order + return this.order; }, - placeOrder () { - this.checkConnection({ online: typeof navigator !== 'undefined' ? navigator.onLine : true }) + placeOrder() { + this.checkConnection({ + online: typeof navigator !== 'undefined' ? navigator.onLine : true + }); if (this.checkStocks()) { - this.$store.dispatch('checkout/placeOrder', { order: this.prepareOrder() }) + this.$store.dispatch('checkout/placeOrder', { + order: this.prepareOrder() + }); } else { - this.notifyNotAvailable() + this.notifyNotAvailable(); } }, - savePersonalDetails () { - this.$store.dispatch('checkout/savePersonalDetails', this.personalDetails) + savePersonalDetails() { + this.$store.dispatch( + 'checkout/savePersonalDetails', + this.personalDetails + ); }, - saveShippingDetails () { - this.$store.dispatch('checkout/saveShippingDetails', this.shipping) + saveShippingDetails() { + this.$store.dispatch('checkout/saveShippingDetails', this.shipping); }, - savePaymentDetails () { - this.$store.dispatch('checkout/savePaymentDetails', this.payment) + savePaymentDetails() { + this.$store.dispatch('checkout/savePaymentDetails', this.payment); }, - focusField (fieldName) { + focusField(fieldName) { if (fieldName === 'password') { - window.scrollTo(0, 0) - this.activateSection('personalDetails') - this.focusedField = fieldName + window.scrollTo(0, 0); + this.activateSection('personalDetails'); + this.focusedField = fieldName; } if (fieldName === 'email-address') { - window.scrollTo(0, 0) - this.activateSection('personalDetails') - this.focusedField = fieldName + window.scrollTo(0, 0); + this.activateSection('personalDetails'); + this.focusedField = fieldName; } } }, - metaInfo () { + metaInfo() { return { title: this.$route.meta.title || i18n.t('Checkout'), - meta: this.$route.meta.description ? [{ vmid: 'description', description: this.$route.meta.description }] : [] - } + meta: this.$route.meta.description + ? [{ vmid: 'description', description: this.$route.meta.description }] + : [] + }; }, - asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data + asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data return new Promise((resolve, reject) => { - if (context) context.output.cacheTags.add(`checkout`) - if (context) context.server.response.redirect('/') - resolve() - }) + if (context) context.output.cacheTags.add(`checkout`); + if (context) context.server.response.redirect('/'); + resolve(); + }); } -} +}; diff --git a/core/pages/CmsPage.js b/core/pages/CmsPage.js index 1b6027dd50..43bd5419e4 100644 --- a/core/pages/CmsPage.js +++ b/core/pages/CmsPage.js @@ -1,45 +1,63 @@ -import { htmlDecode } from '@vue-storefront/core/filters/html-decode' -import Composite from '@vue-storefront/core/mixins/composite' -import { Logger } from '@vue-storefront/core/lib/logger' +import { htmlDecode } from '@vue-storefront/core/filters/html-decode'; +import Composite from '@vue-storefront/core/mixins/composite'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'CmsPage', mixins: [Composite], computed: { - pageTitle () { - return this.$store.state.cmsPage.current ? this.$store.state.cmsPage.current.title : '' + pageTitle() { + return this.$store.state.cmsPage.current + ? this.$store.state.cmsPage.current.title + : ''; } }, watch: { - '$route': 'validateRoute' + $route: 'validateRoute' }, - asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data + asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data return new Promise((resolve, reject) => { - if (context) context.output.cacheTags.add(`cmsPage`) - store.dispatch('cmsPage/single', { - value: route.params.slug, - setCurrent: true - }).then(page => { - resolve(page) - }).catch(err => { - Logger.error(err)() - reject(err) - }) - }) + if (context) context.output.cacheTags.add(`cmsPage`); + store + .dispatch('cmsPage/single', { + value: route.params.slug, + setCurrent: true + }) + .then(page => { + resolve(page); + }) + .catch(err => { + Logger.error(err)(); + reject(err); + }); + }); }, methods: { - validateRoute () { - this.$store.dispatch('cmsPage/single', { value: this.$route.params.slug, setCurrent: true }).then(cmsPage => { - if (!cmsPage) { - this.$router.push(this.localizedRoute('/')) - } - }) + validateRoute() { + this.$store + .dispatch('cmsPage/single', { + value: this.$route.params.slug, + setCurrent: true + }) + .then(cmsPage => { + if (!cmsPage) { + this.$router.push(this.localizedRoute('/')); + } + }); } }, - metaInfo () { + metaInfo() { return { title: htmlDecode(this.pageTitle || this.$route.meta.title), - meta: this.$route.meta.description ? [{ vmid: 'description', description: htmlDecode(this.$route.meta.description) }] : [] - } + meta: this.$route.meta.description + ? [ + { + vmid: 'description', + description: htmlDecode(this.$route.meta.description) + } + ] + : [] + }; } -} +}; diff --git a/core/pages/Compare.js b/core/pages/Compare.js index 31ecaed2d1..57be8cd044 100644 --- a/core/pages/Compare.js +++ b/core/pages/Compare.js @@ -1,12 +1,12 @@ -import { Compare } from '@vue-storefront/core/modules/compare/components/Compare.ts' +import { Compare } from '@vue-storefront/core/modules/compare/components/Compare.ts'; export default { name: 'Compare', mixins: [Compare], computed: { - all_comparable_attributes () { + all_comparable_attributes() { // Computed Property renamed to 'allComparableAttributes' - return this.allComparableAttributes + return this.allComparableAttributes; } } -} +}; diff --git a/core/pages/Compilation.js b/core/pages/Compilation.js index 8d42237910..0c3bf3e170 100644 --- a/core/pages/Compilation.js +++ b/core/pages/Compilation.js @@ -73,4 +73,4 @@ module.exports = `
Waiting for compilation...
-` +`; diff --git a/core/pages/Error.js b/core/pages/Error.js index a71248b9dd..382c39dedb 100644 --- a/core/pages/Error.js +++ b/core/pages/Error.js @@ -1,21 +1,24 @@ -import i18n from '@vue-storefront/i18n' -import { Logger } from '@vue-storefront/core/lib/logger' +import i18n from '@vue-storefront/i18n'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'Error', - asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data + asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data return new Promise((resolve, reject) => { - Logger.log('Calling asyncData for Error page ' + new Date())() + Logger.log('Calling asyncData for Error page ' + new Date())(); if (context) { - context.output.cacheTags.add(`error`) + context.output.cacheTags.add(`error`); } - resolve() - }) + resolve(); + }); }, - metaInfo () { + metaInfo() { return { title: this.$route.meta.title || i18n.t('Internal Server Error 500'), - meta: this.$route.meta.description ? [{ vmid: 'description', description: this.$route.meta.description }] : [] - } + meta: this.$route.meta.description + ? [{ vmid: 'description', description: this.$route.meta.description }] + : [] + }; } -} +}; diff --git a/core/pages/Home.js b/core/pages/Home.js index fba85241e3..2ffb89b632 100644 --- a/core/pages/Home.js +++ b/core/pages/Home.js @@ -1,37 +1,43 @@ -import { mapGetters } from 'vuex' +import { mapGetters } from 'vuex'; -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -import i18n from '@vue-storefront/i18n' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'; +import i18n from '@vue-storefront/i18n'; -import Composite from '@vue-storefront/core/mixins/composite' -import { Logger } from '@vue-storefront/core/lib/logger' +import Composite from '@vue-storefront/core/mixins/composite'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'Home', mixins: [Composite], computed: { ...mapGetters('category', ['getCategories']), - rootCategories () { - return this.getCategories + rootCategories() { + return this.getCategories; } }, - async asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data - if (context) context.output.cacheTags.add(`home`) - Logger.info('Calling asyncData in Home Page (core)')() + async asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data + if (context) context.output.cacheTags.add(`home`); + Logger.info('Calling asyncData in Home Page (core)')(); try { - await EventBus.$emitFilter('home-after-load', { store: store, route: route }) + await EventBus.$emitFilter('home-after-load', { + store: store, + route: route + }); } catch (e) { - Logger.error(e)() - throw e + Logger.error(e)(); + throw e; } }, - beforeMount () { - this.$store.dispatch('category/reset') + beforeMount() { + this.$store.dispatch('category/reset'); }, - metaInfo () { + metaInfo() { return { title: this.$route.meta.title || i18n.t('Home Page'), - meta: this.$route.meta.description ? [{ vmid: 'description', description: this.$route.meta.description }] : [] - } + meta: this.$route.meta.description + ? [{ vmid: 'description', description: this.$route.meta.description }] + : [] + }; } -} +}; diff --git a/core/pages/MyAccount.js b/core/pages/MyAccount.js index f4fc098a54..0063f85c1f 100644 --- a/core/pages/MyAccount.js +++ b/core/pages/MyAccount.js @@ -1,7 +1,7 @@ -import i18n from '@vue-storefront/i18n' +import i18n from '@vue-storefront/i18n'; -import Composite from '@vue-storefront/core/mixins/composite' -import { Logger } from '@vue-storefront/core/lib/logger' +import Composite from '@vue-storefront/core/mixins/composite'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'MyAccount', @@ -12,45 +12,57 @@ export default { default: 'MyProfile' } }, - data () { + data() { return { navigation: [], returnEditMode: false - } + }; }, - beforeMount () { - this.$bus.$on('myAccount-before-updateUser', this.onBeforeUpdateUser) - this.$bus.$on('myAccount-before-changePassword', this.onBeforeChangePassword) + beforeMount() { + this.$bus.$on('myAccount-before-updateUser', this.onBeforeUpdateUser); + this.$bus.$on( + 'myAccount-before-changePassword', + this.onBeforeChangePassword + ); }, - destroyed () { - this.$bus.$off('myAccount-before-updateUser', this.onBeforeUpdateUser) - this.$bus.$off('myAccount-before-changePassword', this.onBeforeChangePassword) + destroyed() { + this.$bus.$off('myAccount-before-updateUser', this.onBeforeUpdateUser); + this.$bus.$off( + 'myAccount-before-changePassword', + this.onBeforeChangePassword + ); }, methods: { - onBeforeChangePassword (passwordData) { - this.$store.dispatch('user/changePassword', passwordData) + onBeforeChangePassword(passwordData) { + this.$store.dispatch('user/changePassword', passwordData); }, - onBeforeUpdateUser (updatedData) { + onBeforeUpdateUser(updatedData) { if (updatedData) { try { - this.$store.dispatch('user/update', { customer: updatedData }) + this.$store.dispatch('user/update', { customer: updatedData }); } catch (err) { - this.$bus.$emit('myAccount-before-remainInEditMode', this.$props.activeBlock) - Logger.error(err)() + this.$bus.$emit( + 'myAccount-before-remainInEditMode', + this.$props.activeBlock + ); + Logger.error(err)(); } } } }, - metaInfo () { + metaInfo() { return { title: this.$route.meta.title || i18n.t('My Account'), - meta: this.$route.meta.description ? [{ vmid: 'description', description: this.$route.meta.description }] : [] - } + meta: this.$route.meta.description + ? [{ vmid: 'description', description: this.$route.meta.description }] + : [] + }; }, - asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data + asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data return new Promise((resolve, reject) => { - if (context) context.output.cacheTags.add(`my-account`) - resolve() - }) + if (context) context.output.cacheTags.add(`my-account`); + resolve(); + }); } -} +}; diff --git a/core/pages/PageNotFound.js b/core/pages/PageNotFound.js index b527956720..ad916b1bd2 100644 --- a/core/pages/PageNotFound.js +++ b/core/pages/PageNotFound.js @@ -1,29 +1,32 @@ -import { prepareQuery } from '@vue-storefront/core/modules/catalog/queries/common' +import { prepareQuery } from '@vue-storefront/core/modules/catalog/queries/common'; -import i18n from '@vue-storefront/i18n' -import Composite from '@vue-storefront/core/mixins/composite' -import { Logger } from '@vue-storefront/core/lib/logger' +import i18n from '@vue-storefront/i18n'; +import Composite from '@vue-storefront/core/mixins/composite'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'PageNotFound', mixins: [Composite], - async asyncData ({ store, routlo, context }) { // this is for SSR purposes to prefetch data - Logger.log('Entering asyncData for PageNotFound ' + new Date())() - if (context) context.output.cacheTags.add(`page-not-found`) - let ourBestsellersQuery = prepareQuery({ queryConfig: 'bestSellers' }) + async asyncData({ store, routlo, context }) { + // this is for SSR purposes to prefetch data + Logger.log('Entering asyncData for PageNotFound ' + new Date())(); + if (context) context.output.cacheTags.add(`page-not-found`); + let ourBestsellersQuery = prepareQuery({ queryConfig: 'bestSellers' }); const response = await store.dispatch('product/list', { query: ourBestsellersQuery, size: 8, sort: 'created_at:desc' - }) + }); if (response) { - store.state.homepage.bestsellers = response.items + store.state.homepage.bestsellers = response.items; } }, - metaInfo () { + metaInfo() { return { title: this.$route.meta.title || i18n.t('404 Page Not Found'), - meta: this.$route.meta.description ? [{ vmid: 'description', description: this.$route.meta.description }] : [] - } + meta: this.$route.meta.description + ? [{ vmid: 'description', description: this.$route.meta.description }] + : [] + }; } -} +}; diff --git a/core/pages/Product.js b/core/pages/Product.js index 42811e993d..2fe4e2f1bc 100644 --- a/core/pages/Product.js +++ b/core/pages/Product.js @@ -1,23 +1,26 @@ -import { mapGetters } from 'vuex' +import { mapGetters } from 'vuex'; -import store from '@vue-storefront/core/store' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -import { htmlDecode } from '@vue-storefront/core/filters' -import { currentStoreView, localizedRoute } from '@vue-storefront/core/lib/multistore' -import { CompareProduct } from '@vue-storefront/core/modules/compare/components/Product.ts' -import { AddToCompare } from '@vue-storefront/core/modules/compare/components/AddToCompare.ts' -import { isOptionAvailableAsync } from '@vue-storefront/core/modules/catalog/helpers/index' -import omit from 'lodash-es/omit' -import Composite from '@vue-storefront/core/mixins/composite' -import { Logger } from '@vue-storefront/core/lib/logger' +import store from '@vue-storefront/core/store'; +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'; +import { htmlDecode } from '@vue-storefront/core/filters'; +import { + currentStoreView, + localizedRoute +} from '@vue-storefront/core/lib/multistore'; +import { CompareProduct } from '@vue-storefront/core/modules/compare/components/Product.ts'; +import { AddToCompare } from '@vue-storefront/core/modules/compare/components/AddToCompare.ts'; +import { isOptionAvailableAsync } from '@vue-storefront/core/modules/catalog/helpers/index'; +import omit from 'lodash-es/omit'; +import Composite from '@vue-storefront/core/mixins/composite'; +import { Logger } from '@vue-storefront/core/lib/logger'; export default { name: 'Product', mixins: [Composite, AddToCompare, CompareProduct], - data () { + data() { return { loading: false - } + }; }, computed: { ...mapGetters({ @@ -32,215 +35,303 @@ export default { category: 'category/getCurrentCategory', gallery: 'product/productGallery' }), - productName () { - return this.product ? this.product.name : '' + productName() { + return this.product ? this.product.name : ''; }, - productId () { - return this.product ? this.product.id : '' + productId() { + return this.product ? this.product.id : ''; }, - offlineImage () { + offlineImage() { return { src: this.getThumbnail(this.product.image, 310, 300), error: this.getThumbnail(this.product.image, 310, 300), loading: this.getThumbnail(this.product.image, 310, 300) - } + }; }, - image () { - return this.gallery.length ? this.gallery[0] : false + image() { + return this.gallery.length ? this.gallery[0] : false; }, - customAttributes () { + customAttributes() { return Object.values(this.attributesByCode).filter(a => { - return a.is_visible && a.is_user_defined && (parseInt(a.is_visible_on_front) || a.is_visible_on_front === true) && this.product[a.attribute_code] - }) + return ( + a.is_visible && + a.is_user_defined && + (parseInt(a.is_visible_on_front) || a.is_visible_on_front === true) && + this.product[a.attribute_code] + ); + }); }, - currentStore () { - return currentStoreView() + currentStore() { + return currentStoreView(); } }, - asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data - EventBus.$emit('product-before-load', { store: store, route: route }) - if (context) context.output.cacheTags.add(`product`) - return store.dispatch('product/fetchAsync', { parentSku: route.params.parentSku, childSku: route && route.params && route.params.childSku ? route.params.childSku : null }) + asyncData({ store, route, context }) { + // this is for SSR purposes to prefetch data + EventBus.$emit('product-before-load', { store: store, route: route }); + if (context) context.output.cacheTags.add(`product`); + return store.dispatch('product/fetchAsync', { + parentSku: route.params.parentSku, + childSku: + route && route.params && route.params.childSku + ? route.params.childSku + : null + }); }, - beforeRouteUpdate (to, from, next) { - this.validateRoute(to) // TODO: remove because client-entry.ts is executing `asyncData` anyway - next() + beforeRouteUpdate(to, from, next) { + this.validateRoute(to); // TODO: remove because client-entry.ts is executing `asyncData` anyway + next(); }, - beforeDestroy () { - this.$bus.$off('product-after-removevariant') - this.$bus.$off('filter-changed-product') - this.$bus.$off('product-after-priceupdate', this.onAfterPriceUpdate) - this.$bus.$off('product-after-customoptions') - this.$bus.$off('product-after-bundleoptions') + beforeDestroy() { + this.$bus.$off('product-after-removevariant'); + this.$bus.$off('filter-changed-product'); + this.$bus.$off('product-after-priceupdate', this.onAfterPriceUpdate); + this.$bus.$off('product-after-customoptions'); + this.$bus.$off('product-after-bundleoptions'); if (store.state.usePriceTiers) { - this.$bus.$off('user-after-loggedin', this.onUserPricesRefreshed) - this.$bus.$off('user-after-logout', this.onUserPricesRefreshed) + this.$bus.$off('user-after-loggedin', this.onUserPricesRefreshed); + this.$bus.$off('user-after-logout', this.onUserPricesRefreshed); } }, - beforeMount () { - this.$bus.$on('product-after-removevariant', this.onAfterVariantChanged) - this.$bus.$on('product-after-priceupdate', this.onAfterPriceUpdate) - this.$bus.$on('filter-changed-product', this.onAfterFilterChanged) - this.$bus.$on('product-after-customoptions', this.onAfterCustomOptionsChanged) - this.$bus.$on('product-after-bundleoptions', this.onAfterBundleOptionsChanged) + beforeMount() { + this.$bus.$on('product-after-removevariant', this.onAfterVariantChanged); + this.$bus.$on('product-after-priceupdate', this.onAfterPriceUpdate); + this.$bus.$on('filter-changed-product', this.onAfterFilterChanged); + this.$bus.$on( + 'product-after-customoptions', + this.onAfterCustomOptionsChanged + ); + this.$bus.$on( + 'product-after-bundleoptions', + this.onAfterBundleOptionsChanged + ); if (store.state.config.usePriceTiers) { - this.$bus.$on('user-after-loggedin', this.onUserPricesRefreshed) - this.$bus.$on('user-after-logout', this.onUserPricesRefreshed) + this.$bus.$on('user-after-loggedin', this.onUserPricesRefreshed); + this.$bus.$on('user-after-logout', this.onUserPricesRefreshed); } - this.onStateCheck() - this.$store.dispatch('recently-viewed/addItem', this.product) + this.onStateCheck(); + this.$store.dispatch('recently-viewed/addItem', this.product); }, methods: { - validateRoute (route = this.$route) { + validateRoute(route = this.$route) { if (!this.loading) { - this.loading = true - this.$store.dispatch('product/fetchAsync', { parentSku: route.params.parentSku, childSku: route && route.params && route.params.childSku ? route.params.childSku : null }).then(res => { - this.loading = false - this.defaultOfflineImage = this.product.image - this.onStateCheck() - this.$store.dispatch('recently-viewed/addItem', this.product) - }).catch((err) => { - this.loading = false - Logger.error(err)() - this.notifyOutStock() - this.$router.back() - }) + this.loading = true; + this.$store + .dispatch('product/fetchAsync', { + parentSku: route.params.parentSku, + childSku: + route && route.params && route.params.childSku + ? route.params.childSku + : null + }) + .then(res => { + this.loading = false; + this.defaultOfflineImage = this.product.image; + this.onStateCheck(); + this.$store.dispatch('recently-viewed/addItem', this.product); + }) + .catch(err => { + this.loading = false; + Logger.error(err)(); + this.notifyOutStock(); + this.$router.back(); + }); } else { - Logger.error('Error with loading = true in Product.vue; Reload page')() + Logger.error('Error with loading = true in Product.vue; Reload page')(); } }, - addToWishlist (product) { - return this.$store.state['wishlist'] ? this.$store.dispatch('wishlist/addItem', product) : false + addToWishlist(product) { + return this.$store.state['wishlist'] + ? this.$store.dispatch('wishlist/addItem', product) + : false; }, - removeFromWishlist (product) { - return this.$store.state['wishlist'] ? this.$store.dispatch('wishlist/removeItem', product) : false + removeFromWishlist(product) { + return this.$store.state['wishlist'] + ? this.$store.dispatch('wishlist/removeItem', product) + : false; }, - addToList (list) { + addToList(list) { // Method renamed to 'addToCompare(product)', product is an Object - AddToCompare.methods.addToCompare.call(this, this.product) + AddToCompare.methods.addToCompare.call(this, this.product); }, - removeFromList (list) { + removeFromList(list) { // Method renamed to 'removeFromCompare(product)', product is an Object - CompareProduct.methods.removeFromCompare.call(this, this.product) + CompareProduct.methods.removeFromCompare.call(this, this.product); }, - isOptionAvailable (option) { // check if the option is available - let currentConfig = Object.assign({}, this.configuration) - currentConfig[option.attribute_code] = option - return isOptionAvailableAsync(this.$store, { product: this.product, configuration: currentConfig }) + isOptionAvailable(option) { + // check if the option is available + let currentConfig = Object.assign({}, this.configuration); + currentConfig[option.attribute_code] = option; + return isOptionAvailableAsync(this.$store, { + product: this.product, + configuration: currentConfig + }); }, - onAfterCustomOptionsChanged (payload) { - let priceDelta = 0 - let priceDeltaInclTax = 0 + onAfterCustomOptionsChanged(payload) { + let priceDelta = 0; + let priceDeltaInclTax = 0; for (const optionValue of Object.values(payload.optionValues)) { - if (typeof optionValue === 'object' && parseInt(optionValue.option_type_id) > 0) { + if ( + typeof optionValue === 'object' && + parseInt(optionValue.option_type_id) > 0 + ) { if (optionValue.price_type === 'fixed' && optionValue.price !== 0) { - priceDelta += optionValue.price - priceDeltaInclTax += optionValue.price + priceDelta += optionValue.price; + priceDeltaInclTax += optionValue.price; } if (optionValue.price_type === 'percent' && optionValue.price !== 0) { - priceDelta += ((optionValue.price / 100) * this.originalProduct.price) - priceDeltaInclTax += ((optionValue.price / 100) * this.originalProduct.priceInclTax) + priceDelta += + (optionValue.price / 100) * this.originalProduct.price; + priceDeltaInclTax += + (optionValue.price / 100) * this.originalProduct.priceInclTax; } } } - this.product.price = this.originalProduct.price + priceDelta - this.product.priceInclTax = this.originalProduct.priceInclTax + priceDeltaInclTax + this.product.price = this.originalProduct.price + priceDelta; + this.product.priceInclTax = + this.originalProduct.priceInclTax + priceDeltaInclTax; }, - onAfterBundleOptionsChanged (payload) { - let priceDelta = 0 - let priceDeltaInclTax = 0 + onAfterBundleOptionsChanged(payload) { + let priceDelta = 0; + let priceDeltaInclTax = 0; for (const optionValue of Object.values(payload.optionValues)) { - if (typeof optionValue.value.product !== 'undefined' && parseInt(optionValue.qty) >= 0) { - priceDelta += optionValue.value.product.price * parseInt(optionValue.qty) - priceDeltaInclTax += optionValue.value.product.priceInclTax * parseInt(optionValue.qty) + if ( + typeof optionValue.value.product !== 'undefined' && + parseInt(optionValue.qty) >= 0 + ) { + priceDelta += + optionValue.value.product.price * parseInt(optionValue.qty); + priceDeltaInclTax += + optionValue.value.product.priceInclTax * parseInt(optionValue.qty); } } if (priceDelta > 0) { - this.product.price = priceDelta - this.product.priceInclTax = priceDeltaInclTax + this.product.price = priceDelta; + this.product.priceInclTax = priceDeltaInclTax; } }, - onStateCheck () { + onStateCheck() { if (this.parentProduct && this.parentProduct.id !== this.product.id) { - Logger.log('Redirecting to parent, configurable product', this.parentProduct.sku)() - this.$router.replace({ name: 'product', params: { parentSku: this.parentProduct.sku, childSku: this.product.sku, slug: this.parentProduct.slug } }) + Logger.log( + 'Redirecting to parent, configurable product', + this.parentProduct.sku + )(); + this.$router.replace({ + name: 'product', + params: { + parentSku: this.parentProduct.sku, + childSku: this.product.sku, + slug: this.parentProduct.slug + } + }); } }, - onAfterPriceUpdate (product) { + onAfterPriceUpdate(product) { if (product.sku === this.product.sku) { // join selected variant object to the store - this.$store.dispatch('product/setCurrent', omit(product, ['name'])) - .catch(err => Logger.error({ - info: 'Dispatch product/setCurrent in Product.vue', - err - })) + this.$store + .dispatch('product/setCurrent', omit(product, ['name'])) + .catch(err => + Logger.error({ + info: 'Dispatch product/setCurrent in Product.vue', + err + }) + ); } }, - onAfterVariantChanged (payload) { - this.$forceUpdate() + onAfterVariantChanged(payload) { + this.$forceUpdate(); }, - onAfterFilterChanged (filterOption) { - this.$bus.$emit('product-before-configure', { filterOption: filterOption, configuration: this.configuration }) - const prevOption = this.configuration[filterOption.attribute_code] - this.configuration[filterOption.attribute_code] = filterOption - this.$forceUpdate() // this is to update the available options regarding current selection - this.$store.dispatch('product/configure', { - product: this.product, - configuration: this.configuration, - selectDefaultVariant: true, - fallbackToDefaultWhenNoAvailable: false, - setProductErorrs: true - }).then((selectedVariant) => { - if (store.state.config.products.setFirstVarianAsDefaultInURL) { - this.$router.push({params: { childSku: selectedVariant.sku }}) - } - if (!selectedVariant) { - if (typeof prevOption !== 'undefined' && prevOption) { - this.configuration[filterOption.attribute_code] = prevOption - } else { - delete this.configuration[filterOption.attribute_code] + onAfterFilterChanged(filterOption) { + this.$bus.$emit('product-before-configure', { + filterOption: filterOption, + configuration: this.configuration + }); + const prevOption = this.configuration[filterOption.attribute_code]; + this.configuration[filterOption.attribute_code] = filterOption; + this.$forceUpdate(); // this is to update the available options regarding current selection + this.$store + .dispatch('product/configure', { + product: this.product, + configuration: this.configuration, + selectDefaultVariant: true, + fallbackToDefaultWhenNoAvailable: false, + setProductErorrs: true + }) + .then(selectedVariant => { + if (store.state.config.products.setFirstVarianAsDefaultInURL) { + this.$router.push({ params: { childSku: selectedVariant.sku } }); } - this.notifyWrongAttributes() - } - }).catch(err => Logger.error({ - info: 'Dispatch product/configure in Product.vue', - err - })) + if (!selectedVariant) { + if (typeof prevOption !== 'undefined' && prevOption) { + this.configuration[filterOption.attribute_code] = prevOption; + } else { + delete this.configuration[filterOption.attribute_code]; + } + this.notifyWrongAttributes(); + } + }) + .catch(err => + Logger.error({ + info: 'Dispatch product/configure in Product.vue', + err + }) + ); }, /** * Reload product to get correct prices (including tier prices for group) */ - onUserPricesRefreshed () { + onUserPricesRefreshed() { if (this.$route.params.parentSku) { - this.$store.dispatch('product/reset') - this.$bus.$emit('product-before-load', { store: this.$store, route: this.$route }) + this.$store.dispatch('product/reset'); + this.$bus.$emit('product-before-load', { + store: this.$store, + route: this.$route + }); this.$store.dispatch('product/single', { options: { sku: this.$route.params.parentSku, - childSku: this.$route && this.$route.params && this.$route.params.childSku ? this.$route.params.childSku : null + childSku: + this.$route && this.$route.params && this.$route.params.childSku + ? this.$route.params.childSku + : null }, skipCache: true - }) + }); } } }, - metaInfo () { - const storeView = currentStoreView() + metaInfo() { + const storeView = currentStoreView(); return { link: [ - { rel: 'amphtml', - href: this.$router.resolve(localizedRoute({ - name: this.product.type_id + '-product-amp', - params: { - parentSku: this.product.parentSku ? this.product.parentSku : this.product.sku, - slug: this.product.slug, - childSku: this.product.sku - } - }, storeView.storeCode)).href + { + rel: 'amphtml', + href: this.$router.resolve( + localizedRoute( + { + name: this.product.type_id + '-product-amp', + params: { + parentSku: this.product.parentSku + ? this.product.parentSku + : this.product.sku, + slug: this.product.slug, + childSku: this.product.sku + } + }, + storeView.storeCode + ) + ).href } ], title: htmlDecode(this.product.meta_title || this.productName), - meta: this.product.meta_description ? [{ vmid: 'description', description: htmlDecode(this.product.meta_description) }] : [] - } + meta: this.product.meta_description + ? [ + { + vmid: 'description', + description: htmlDecode(this.product.meta_description) + } + ] + : [] + }; } -} +}; diff --git a/core/scripts/all.js b/core/scripts/all.js index 37dba7b24b..a32104652f 100644 --- a/core/scripts/all.js +++ b/core/scripts/all.js @@ -1,61 +1,69 @@ -'use strict' +'use strict'; -const shell = require('shelljs') -const jsonFile = require('jsonfile') -const installer = require('./installer') +const shell = require('shelljs'); +const jsonFile = require('jsonfile'); +const installer = require('./installer'); class Manager extends installer.Manager { /** * {@inheritDoc} */ - initBackend () { + initBackend() { if (Manager.isBackendInstalledLocally()) { - return this.backend.goToDirectory(Manager.getBackendDirectory()) + return this.backend + .goToDirectory(Manager.getBackendDirectory()) .then(this.backend.dockerComposeUp.bind(this.backend)) - .then(this.backend.runDevEnvironment.bind(this.backend)) + .then(this.backend.runDevEnvironment.bind(this.backend)); } else { - return Promise.resolve() + return Promise.resolve(); } } /** * {@inheritDoc} */ - initStorefront () { - return this.storefront.goToDirectory() + initStorefront() { + return this.storefront + .goToDirectory() .then(this.storefront.npmBuild.bind(this.storefront)) - .then(this.storefront.runDevEnvironment.bind(this.storefront)) + .then(this.storefront.runDevEnvironment.bind(this.storefront)); } /** * {@inheritDoc} */ - static showWelcomeMessage () { + static showWelcomeMessage() { installer.Message.greeting([ 'Hi, seat, relax...', - 'I\'ll start everything for you ;)' - ]) + "I'll start everything for you ;)" + ]); } /** * {@inheritDoc} */ - showGoodbyeMessage () { + showGoodbyeMessage() { return new Promise((resolve, reject) => { - installer.Message.greeting([ - 'Congratulations!', - '', - 'You\'ve just successfully started vue-storefront.', - 'All required servers are running in the background', - '', - 'Storefront: http://localhost:3000', - 'Backend: ' + (Manager.isBackendInstalledLocally() ? 'http://localhost:8080' : installer.STOREFRONT_REMOTE_BACKEND_URL), - '', - 'Good Luck!' - ], true) - - resolve() - }) + installer.Message.greeting( + [ + 'Congratulations!', + '', + "You've just successfully started vue-storefront.", + 'All required servers are running in the background', + '', + 'Storefront: http://localhost:3000', + 'Backend: ' + + (Manager.isBackendInstalledLocally() + ? 'http://localhost:8080' + : installer.STOREFRONT_REMOTE_BACKEND_URL), + '', + 'Good Luck!' + ], + true + ); + + resolve(); + }); } /** @@ -63,14 +71,16 @@ class Manager extends installer.Manager { * * @returns {boolean} */ - static isBackendInstalledLocally () { + static isBackendInstalledLocally() { if (typeof installer.Abstract.wasLocalBackendInstalled === 'undefined') { - let config = jsonFile.readFileSync(installer.TARGET_BACKEND_CONFIG_FILE) + let config = jsonFile.readFileSync(installer.TARGET_BACKEND_CONFIG_FILE); - installer.Abstract.wasLocalBackendInstalled = Boolean(config.install.is_local_backend) + installer.Abstract.wasLocalBackendInstalled = Boolean( + config.install.is_local_backend + ); } - return Boolean(installer.Abstract.wasLocalBackendInstalled) + return Boolean(installer.Abstract.wasLocalBackendInstalled); } /** @@ -78,40 +88,41 @@ class Manager extends installer.Manager { * * @returns {string} */ - static getBackendDirectory () { + static getBackendDirectory() { if (typeof installer.Abstract.backendDir === 'undefined') { - let config = jsonFile.readFileSync(installer.TARGET_BACKEND_CONFIG_FILE) + let config = jsonFile.readFileSync(installer.TARGET_BACKEND_CONFIG_FILE); - installer.Abstract.backendDir = config.install.backend_dir + installer.Abstract.backendDir = config.install.backend_dir; } - return installer.Abstract.backendDir + return installer.Abstract.backendDir; } } /** * Predefine class static variables */ -installer.Abstract.wasLocalBackendInstalled = undefined -installer.Abstract.backendDir = undefined +installer.Abstract.wasLocalBackendInstalled = undefined; +installer.Abstract.backendDir = undefined; /** * Pre-loading staff */ -Manager.checkUserOS() +Manager.checkUserOS(); Manager.showWelcomeMessage(); /** * This is where all the magic happens */ -(async function () { - let manager = new Manager() +(async function() { + let manager = new Manager(); - await manager.tryToCreateLogFiles() + await manager + .tryToCreateLogFiles() .then(manager.initBackend.bind(manager)) .then(manager.initStorefront.bind(manager)) .then(manager.showGoodbyeMessage.bind(manager)) - .catch(installer.Message.error) + .catch(installer.Message.error); - shell.exit(0) -})() + shell.exit(0); +})(); diff --git a/core/scripts/cache.js b/core/scripts/cache.js index 4038647ad9..8148656f53 100644 --- a/core/scripts/cache.js +++ b/core/scripts/cache.js @@ -1,41 +1,53 @@ -const program = require('commander') -const config = require('config') -const cache = require('./utils/cache-instance') +const program = require('commander'); +const config = require('config'); +const cache = require('./utils/cache-instance'); program .command('clear') - .option('-t|--tag ', 'tag name, available tags: ' + config.server.availableCacheTags.join(', '), '*') - .action((cmd) => { // TODO: add parallel processing + .option( + '-t|--tag ', + 'tag name, available tags: ' + config.server.availableCacheTags.join(', '), + '*' + ) + .action(cmd => { + // TODO: add parallel processing if (!cmd.tag) { - console.error('error: tag must be specified') - process.exit(1) + console.error('error: tag must be specified'); + process.exit(1); } else { - console.log(`Clear cache request for [${cmd.tag}]`) - let tags = [] + console.log(`Clear cache request for [${cmd.tag}]`); + let tags = []; if (cmd.tag === '*') { - tags = config.server.availableCacheTags + tags = config.server.availableCacheTags; } else { - tags = cmd.tag.split(',') + tags = cmd.tag.split(','); } - const subPromises = [] + const subPromises = []; tags.forEach(tag => { - if (config.server.availableCacheTags.indexOf(tag) >= 0 || config.server.availableCacheTags.find(t => { - return tag.indexOf(t) === 0 - })) { - subPromises.push(cache.invalidate(tag).then(() => { - console.log(`Tags invalidated successfully for [${tag}]`) - })) + if ( + config.server.availableCacheTags.indexOf(tag) >= 0 || + config.server.availableCacheTags.find(t => { + return tag.indexOf(t) === 0; + }) + ) { + subPromises.push( + cache.invalidate(tag).then(() => { + console.log(`Tags invalidated successfully for [${tag}]`); + }) + ); } else { - console.error(`Invalid tag name ${tag}`) + console.error(`Invalid tag name ${tag}`); } - }) - Promise.all(subPromises).then(r => { - console.log(`All tags invalidated successfully [${cmd.tag}]`) - process.exit(0) - }).catch(error => { - console.error(error) - }) + }); + Promise.all(subPromises) + .then(r => { + console.log(`All tags invalidated successfully [${cmd.tag}]`); + process.exit(0); + }) + .catch(error => { + console.error(error); + }); } - }) + }); -program.parse(process.argv) +program.parse(process.argv); diff --git a/core/scripts/installer.js b/core/scripts/installer.js index 186b73df94..04168b32d2 100644 --- a/core/scripts/installer.js +++ b/core/scripts/installer.js @@ -1,35 +1,37 @@ -'use strict' - -const path = require('path') -const shell = require('shelljs') -const mkdirp = require('mkdirp') -const exists = require('fs-exists-sync') -const message = require('print-message') -const inquirer = require('inquirer') -const jsonFile = require('jsonfile') -const urlParser = require('url-parse') -const isWindows = require('is-windows') -const isEmptyDir = require('empty-dir') -const commandExists = require('command-exists') -const program = require('commander') - -const SAMPLE_DATA_PATH = 'var/magento2-sample-data' -const TARGET_FRONTEND_CONFIG_FILE = 'config/local.json' -const SOURCE_FRONTEND_CONFIG_FILE = 'config/default.json' - -const TARGET_BACKEND_CONFIG_FILE = 'config/local.json' -const SOURCE_BACKEND_CONFIG_FILE = 'config/default.json' - -const STOREFRONT_BACKEND_GIT_URL = 'https://github.com/DivanteLtd/vue-storefront-api' -const MAGENTO_SAMPLE_DATA_GIT_URL = 'https://github.com/magento/magento2-sample-data.git' -const STOREFRONT_REMOTE_BACKEND_URL = 'https://demo.vuestorefront.io' - -const STOREFRONT_DIRECTORY = shell.pwd() - -const LOG_DIR = `${STOREFRONT_DIRECTORY}/var/log` -const INSTALL_LOG_FILE = `${STOREFRONT_DIRECTORY}/var/log/install.log` -const VUE_STOREFRONT_LOG_FILE = `${STOREFRONT_DIRECTORY}/var/log/vue-storefront.log` -const VUE_STOREFRONT_BACKEND_LOG_FILE = `${STOREFRONT_DIRECTORY}/var/log/vue-storefront-api.log` +'use strict'; + +const path = require('path'); +const shell = require('shelljs'); +const mkdirp = require('mkdirp'); +const exists = require('fs-exists-sync'); +const message = require('print-message'); +const inquirer = require('inquirer'); +const jsonFile = require('jsonfile'); +const urlParser = require('url-parse'); +const isWindows = require('is-windows'); +const isEmptyDir = require('empty-dir'); +const commandExists = require('command-exists'); +const program = require('commander'); + +const SAMPLE_DATA_PATH = 'var/magento2-sample-data'; +const TARGET_FRONTEND_CONFIG_FILE = 'config/local.json'; +const SOURCE_FRONTEND_CONFIG_FILE = 'config/default.json'; + +const TARGET_BACKEND_CONFIG_FILE = 'config/local.json'; +const SOURCE_BACKEND_CONFIG_FILE = 'config/default.json'; + +const STOREFRONT_BACKEND_GIT_URL = + 'https://github.com/DivanteLtd/vue-storefront-api'; +const MAGENTO_SAMPLE_DATA_GIT_URL = + 'https://github.com/magento/magento2-sample-data.git'; +const STOREFRONT_REMOTE_BACKEND_URL = 'https://demo.vuestorefront.io'; + +const STOREFRONT_DIRECTORY = shell.pwd(); + +const LOG_DIR = `${STOREFRONT_DIRECTORY}/var/log`; +const INSTALL_LOG_FILE = `${STOREFRONT_DIRECTORY}/var/log/install.log`; +const VUE_STOREFRONT_LOG_FILE = `${STOREFRONT_DIRECTORY}/var/log/vue-storefront.log`; +const VUE_STOREFRONT_BACKEND_LOG_FILE = `${STOREFRONT_DIRECTORY}/var/log/vue-storefront-api.log`; /** * Message management @@ -40,12 +42,10 @@ class Message { * * @param text */ - static info (text) { - text = Array.isArray(text) ? text : [text] + static info(text) { + text = Array.isArray(text) ? text : [text]; - message([ - ...text - ], {color: 'blue', border: false, marginTop: 1}) + message([...text], { color: 'blue', border: false, marginTop: 1 }); } /** @@ -54,29 +54,26 @@ class Message { * @param text * @param logFile */ - static error (text, logFile = INSTALL_LOG_FILE) { - text = Array.isArray(text) ? text : [text] + static error(text, logFile = INSTALL_LOG_FILE) { + text = Array.isArray(text) ? text : [text]; // show trace if exception occurred if (text[0] instanceof Error) { - text = text[0].stack.split('\n') + text = text[0].stack.split('\n'); } - let logDetailsInfo = `Please check log file for details: ${logFile}` + let logDetailsInfo = `Please check log file for details: ${logFile}`; if (!Abstract.logsWereCreated) { - logDetailsInfo = 'Try to fix problem with logs to see the error details.' + logDetailsInfo = 'Try to fix problem with logs to see the error details.'; } - message([ - 'ERROR', - '', - ...text, - '', - logDetailsInfo - ], {borderColor: 'red', marginBottom: 1}) + message(['ERROR', '', ...text, '', logDetailsInfo], { + borderColor: 'red', + marginBottom: 1 + }); - shell.exit(1) + shell.exit(1); } /** @@ -84,13 +81,14 @@ class Message { * * @param text */ - static warning (text) { - text = Array.isArray(text) ? text : [text] - - message([ - 'WARNING:', - ...text - ], {color: 'yellow', border: false, marginTop: 1}) + static warning(text) { + text = Array.isArray(text) ? text : [text]; + + message(['WARNING:', ...text], { + color: 'yellow', + border: false, + marginTop: 1 + }); } /** @@ -99,12 +97,16 @@ class Message { * @param text * @param isLastMessage */ - static greeting (text, isLastMessage = false) { - text = Array.isArray(text) ? text : [text] - - message([ - ...text - ], Object.assign(isLastMessage ? {marginTop: 1} : {}, {borderColor: 'green', marginBottom: 1})) + static greeting(text, isLastMessage = false) { + text = Array.isArray(text) ? text : [text]; + + message( + [...text], + Object.assign(isLastMessage ? { marginTop: 1 } : {}, { + borderColor: 'green', + marginBottom: 1 + }) + ); } } @@ -117,8 +119,8 @@ class Abstract { * * Initialize fields */ - constructor (answers) { - this.answers = answers + constructor(answers) { + this.answers = answers; } } @@ -131,19 +133,25 @@ class Backend extends Abstract { * * @returns {Promise} */ - cloneRepository () { + cloneRepository() { return new Promise((resolve, reject) => { - const backendDir = path.normalize(this.answers.backend_dir) - const gitPath = path.normalize(this.answers.git_path) - - Message.info(`Cloning backend into '${backendDir}'...`) - - if (shell.exec(`${gitPath} clone ${STOREFRONT_BACKEND_GIT_URL} '${backendDir}' > ${Abstract.infoLogStream} 2>&1`).code !== 0) { - reject(new Error(`Can't clone backend into '${backendDir}'.`)) + const backendDir = path.normalize(this.answers.backend_dir); + const gitPath = path.normalize(this.answers.git_path); + + Message.info(`Cloning backend into '${backendDir}'...`); + + if ( + shell.exec( + `${gitPath} clone ${STOREFRONT_BACKEND_GIT_URL} '${backendDir}' > ${ + Abstract.infoLogStream + } 2>&1` + ).code !== 0 + ) { + reject(new Error(`Can't clone backend into '${backendDir}'.`)); } - resolve() - }) + resolve(); + }); } /** @@ -151,20 +159,20 @@ class Backend extends Abstract { * * @returns {Promise} */ - goToDirectory (backendDir = null) { + goToDirectory(backendDir = null) { return new Promise((resolve, reject) => { - const dir = this.answers ? this.answers.backend_dir : backendDir + const dir = this.answers ? this.answers.backend_dir : backendDir; - Message.info(`Trying change directory to '${dir}'...`) + Message.info(`Trying change directory to '${dir}'...`); if (shell.cd(path.normalize(dir)).code !== 0) { - reject(new Error(`Can't change directory to '${dir}'.`)) + reject(new Error(`Can't change directory to '${dir}'.`)); } - Message.info(`Working in directory '${shell.pwd()}'...`) + Message.info(`Working in directory '${shell.pwd()}'...`); - resolve() - }) + resolve(); + }); } /** @@ -172,16 +180,16 @@ class Backend extends Abstract { * * @returns {Promise} */ - npmInstall () { + npmInstall() { return new Promise((resolve, reject) => { - Message.info('Installing backend npm...') + Message.info('Installing backend npm...'); if (shell.exec(`npm i >> ${Abstract.infoLogStream} 2>&1`).code !== 0) { - reject(new Error('Can\'t install backend npm.')) + reject(new Error("Can't install backend npm.")); } - resolve() - }) + resolve(); + }); } /** @@ -189,17 +197,19 @@ class Backend extends Abstract { * * @returns {Promise} */ - dockerComposeUp () { + dockerComposeUp() { return new Promise((resolve, reject) => { - Message.info('Starting Docker in background...') + Message.info('Starting Docker in background...'); if (shell.exec(`docker-compose up -d > /dev/null 2>&1`).code !== 0) { - reject(new Error('Can\'t start Docker in background.')) + reject(new Error("Can't start Docker in background.")); } // Adding 20sec timer for ES to get up and running // before starting restoration and migration processes - setTimeout(() => { resolve() }, 20000) - }) + setTimeout(() => { + resolve(); + }, 20000); + }); } /** @@ -207,38 +217,44 @@ class Backend extends Abstract { * * @returns {Promise} */ - validateM2Integration () { + validateM2Integration() { return new Promise((resolve, reject) => { - const Magento2Client = require('magento2-rest-client').Magento2Client + const Magento2Client = require('magento2-rest-client').Magento2Client; - Message.info(`Validating Magento integration configuration...`) + Message.info(`Validating Magento integration configuration...`); - let m2Url = urlParser(this.answers.m2_url).href - let apiUrl = urlParser(this.answers.m2_api_url).href + let m2Url = urlParser(this.answers.m2_url).href; + let apiUrl = urlParser(this.answers.m2_api_url).href; if (!m2Url.length) { - reject(new Error('Invalid Magento URL supplied.')) + reject(new Error('Invalid Magento URL supplied.')); } if (!apiUrl.length) { - reject(new Error('Invalid Magento rest API URL supplied.')) + reject(new Error('Invalid Magento rest API URL supplied.')); } let options = { - 'url': apiUrl, - 'consumerKey': this.answers.m2_api_consumer_key, - 'consumerSecret': this.answers.m2_api_consumer_secret, - 'accessToken': this.answers.m2_api_access_token, - 'accessTokenSecret': this.answers.m2_api_access_token_secret - } - let client = Magento2Client(options) - - client.categories.list() - .then((categories) => { - resolve() - }).catch((e) => { - reject(new Error('Invalid Magento integration settings. Original error: ' + e)) + url: apiUrl, + consumerKey: this.answers.m2_api_consumer_key, + consumerSecret: this.answers.m2_api_consumer_secret, + accessToken: this.answers.m2_api_access_token, + accessTokenSecret: this.answers.m2_api_access_token_secret + }; + let client = Magento2Client(options); + + client.categories + .list() + .then(categories => { + resolve(); }) - }) + .catch(e => { + reject( + new Error( + 'Invalid Magento integration settings. Original error: ' + e + ) + ); + }); + }); } /** @@ -246,37 +262,50 @@ class Backend extends Abstract { * * @returns {Promise} */ - createConfig () { + createConfig() { return new Promise((resolve, reject) => { - let config + let config; - Message.info(`Creating backend config '${TARGET_BACKEND_CONFIG_FILE}'...`) + Message.info( + `Creating backend config '${TARGET_BACKEND_CONFIG_FILE}'...` + ); try { - config = jsonFile.readFileSync(SOURCE_BACKEND_CONFIG_FILE) - let host = urlParser(this.answers.images_endpoint).hostname + config = jsonFile.readFileSync(SOURCE_BACKEND_CONFIG_FILE); + let host = urlParser(this.answers.images_endpoint).hostname; if (!host.length) { - throw new Error() + throw new Error(); } - config.imageable.whitelist.allowedHosts.push(host) - - config.magento2.url = urlParser(this.answers.m2_url).href - config.magento2.imgUrl = this.answers.m2_url ? urlParser(this.answers.m2_url).href + '/pub/media/catalog/product' : config.magento2.imgUrl - config.magento2.api.url = urlParser(this.answers.m2_api_url).href || config.magento2.api.url - config.magento2.api.consumerKey = this.answers.m2_api_consumer_key || config.magento2.api.consumerKey - config.magento2.api.consumerSecret = this.answers.m2_api_consumer_secret || config.magento2.api.consumerSecret - config.magento2.api.accessToken = this.answers.m2_api_access_token || config.magento2.api.accessToken - config.magento2.api.accessTokenSecret = this.answers.m2_api_access_token_secret || config.magento2.api.accessTokenSecret - - jsonFile.writeFileSync(TARGET_BACKEND_CONFIG_FILE, config, {spaces: 2}) + config.imageable.whitelist.allowedHosts.push(host); + + config.magento2.url = urlParser(this.answers.m2_url).href; + config.magento2.imgUrl = this.answers.m2_url + ? urlParser(this.answers.m2_url).href + '/pub/media/catalog/product' + : config.magento2.imgUrl; + config.magento2.api.url = + urlParser(this.answers.m2_api_url).href || config.magento2.api.url; + config.magento2.api.consumerKey = + this.answers.m2_api_consumer_key || config.magento2.api.consumerKey; + config.magento2.api.consumerSecret = + this.answers.m2_api_consumer_secret || + config.magento2.api.consumerSecret; + config.magento2.api.accessToken = + this.answers.m2_api_access_token || config.magento2.api.accessToken; + config.magento2.api.accessTokenSecret = + this.answers.m2_api_access_token_secret || + config.magento2.api.accessTokenSecret; + + jsonFile.writeFileSync(TARGET_BACKEND_CONFIG_FILE, config, { + spaces: 2 + }); } catch (e) { - reject(new Error('Can\'t create backend config. Original error: ' + e)) + reject(new Error("Can't create backend config. Original error: " + e)); } - resolve() - }) + resolve(); + }); } /** @@ -284,16 +313,19 @@ class Backend extends Abstract { * * @returns {Promise} */ - restoreElasticSearch () { + restoreElasticSearch() { return new Promise((resolve, reject) => { - Message.info('Restoring data for ElasticSearch...') + Message.info('Restoring data for ElasticSearch...'); - if (shell.exec(`npm run restore >> ${Abstract.infoLogStream} 2>&1`).code !== 0) { - reject(new Error('Can\'t restore data for ElasticSearch.')) + if ( + shell.exec(`npm run restore >> ${Abstract.infoLogStream} 2>&1`).code !== + 0 + ) { + reject(new Error("Can't restore data for ElasticSearch.")); } - resolve() - }) + resolve(); + }); } /** @@ -301,16 +333,19 @@ class Backend extends Abstract { * * @returns {Promise} */ - migrateElasticSearch () { + migrateElasticSearch() { return new Promise((resolve, reject) => { - Message.info('Migrating data into ElasticSearch...') + Message.info('Migrating data into ElasticSearch...'); - if (shell.exec(`npm run migrate >> ${Abstract.infoLogStream} 2>&1`).code !== 0) { - reject(new Error('Can\'t migrate data into ElasticSearch.')) + if ( + shell.exec(`npm run migrate >> ${Abstract.infoLogStream} 2>&1`).code !== + 0 + ) { + reject(new Error("Can't migrate data into ElasticSearch.")); } - resolve() - }) + resolve(); + }); } /** @@ -318,16 +353,19 @@ class Backend extends Abstract { * * @returns {Promise} */ - importElasticSearch () { + importElasticSearch() { return new Promise((resolve, reject) => { - Message.info('Importing data from Magento into ElasticSearch...') + Message.info('Importing data from Magento into ElasticSearch...'); - if (shell.exec(`yarn mage2vs import >> ${Abstract.infoLogStream} 2>&1`).code !== 0) { - reject(new Error('Can\'t import data into ElasticSearch.')) + if ( + shell.exec(`yarn mage2vs import >> ${Abstract.infoLogStream} 2>&1`) + .code !== 0 + ) { + reject(new Error("Can't import data into ElasticSearch.")); } - resolve() - }) + resolve(); + }); } /** @@ -335,16 +373,30 @@ class Backend extends Abstract { * * @returns {Promise} */ - cloneMagentoSampleData () { + cloneMagentoSampleData() { return new Promise((resolve, reject) => { - Message.info(`Cloning Magento 2 Sample Data into '${SAMPLE_DATA_PATH}'...`) - - if (shell.exec(`${this.answers.git_path} clone ${MAGENTO_SAMPLE_DATA_GIT_URL} ${SAMPLE_DATA_PATH} >> ${Abstract.infoLogStream} 2>&1`).code !== 0) { - reject(new Error(`Can't clone Magento 2 Sample Data into '${SAMPLE_DATA_PATH}'...`)) + Message.info( + `Cloning Magento 2 Sample Data into '${SAMPLE_DATA_PATH}'...` + ); + + if ( + shell.exec( + `${ + this.answers.git_path + } clone ${MAGENTO_SAMPLE_DATA_GIT_URL} ${SAMPLE_DATA_PATH} >> ${ + Abstract.infoLogStream + } 2>&1` + ).code !== 0 + ) { + reject( + new Error( + `Can't clone Magento 2 Sample Data into '${SAMPLE_DATA_PATH}'...` + ) + ); } - resolve() - }) + resolve(); + }); } /** @@ -352,22 +404,39 @@ class Backend extends Abstract { * * @returns {Promise} */ - runDevEnvironment () { + runDevEnvironment() { return new Promise((resolve, reject) => { - Message.info('Starting backend server...') + Message.info('Starting backend server...'); if (isWindows()) { - if (shell.exec(`start /min npm run dev > ${Abstract.backendLogStream} 2>&1 &`).code !== 0) { - reject(new Error('Can\'t start dev server.', VUE_STOREFRONT_BACKEND_LOG_FILE)) + if ( + shell.exec( + `start /min npm run dev > ${Abstract.backendLogStream} 2>&1 &` + ).code !== 0 + ) { + reject( + new Error( + "Can't start dev server.", + VUE_STOREFRONT_BACKEND_LOG_FILE + ) + ); } } else { - if (shell.exec(`nohup npm run dev > ${Abstract.backendLogStream} 2>&1 &`).code !== 0) { - reject(new Error('Can\'t start dev server.', VUE_STOREFRONT_BACKEND_LOG_FILE)) + if ( + shell.exec(`nohup npm run dev > ${Abstract.backendLogStream} 2>&1 &`) + .code !== 0 + ) { + reject( + new Error( + "Can't start dev server.", + VUE_STOREFRONT_BACKEND_LOG_FILE + ) + ); } } - resolve() - }) + resolve(); + }); } } @@ -380,20 +449,22 @@ class Storefront extends Abstract { * * @returns {Promise} */ - goToDirectory () { + goToDirectory() { return new Promise((resolve, reject) => { if (Abstract.wasLocalBackendInstalled) { - Message.info(`Trying change directory to '${STOREFRONT_DIRECTORY}'...`) + Message.info(`Trying change directory to '${STOREFRONT_DIRECTORY}'...`); if (shell.cd(STOREFRONT_DIRECTORY).code !== 0) { - reject(new Error(`Can't change directory to '${STOREFRONT_DIRECTORY}'.`)) + reject( + new Error(`Can't change directory to '${STOREFRONT_DIRECTORY}'.`) + ); } - Message.info(`Working in directory '${STOREFRONT_DIRECTORY}'...`) + Message.info(`Working in directory '${STOREFRONT_DIRECTORY}'...`); } - resolve() - }) + resolve(); + }); } /** @@ -401,74 +472,80 @@ class Storefront extends Abstract { * * @returns {Promise} */ - createConfig () { + createConfig() { return new Promise((resolve, reject) => { - let config + let config; - Message.info(`Creating storefront config '${TARGET_FRONTEND_CONFIG_FILE}'...`) + Message.info( + `Creating storefront config '${TARGET_FRONTEND_CONFIG_FILE}'...` + ); try { - config = jsonFile.readFileSync(SOURCE_FRONTEND_CONFIG_FILE) + config = jsonFile.readFileSync(SOURCE_FRONTEND_CONFIG_FILE); - let backendPath - let graphQlHost - let graphQlPort = 8080 + let backendPath; + let graphQlHost; + let graphQlPort = 8080; if (Abstract.wasLocalBackendInstalled) { - graphQlHost = 'localhost' - backendPath = 'http://localhost:8080' + graphQlHost = 'localhost'; + backendPath = 'http://localhost:8080'; } else { - backendPath = STOREFRONT_REMOTE_BACKEND_URL - graphQlHost = backendPath.replace('https://', '').replace('http://', '') + backendPath = STOREFRONT_REMOTE_BACKEND_URL; + graphQlHost = backendPath + .replace('https://', '') + .replace('http://', ''); } - config.api.url = backendPath - config.graphql.host = graphQlHost - config.graphql.port = graphQlPort - config.elasticsearch.host = `${backendPath}/api/catalog` - config.orders.endpoint = `${backendPath}/api/order` - config.products.endpoint = `${backendPath}/api/product` - config.users.endpoint = `${backendPath}/api/user` - config.users.history_endpoint = `${backendPath}/api/user/order-history?token={{token}}` - config.users.resetPassword_endpoint = `${backendPath}/api/user/reset-password` - config.users.changePassword_endpoint = `${backendPath}/api/user/change-password?token={{token}}` - config.users.login_endpoint = `${backendPath}/api/user/login` - config.users.create_endpoint = `${backendPath}/api/user/create` - config.users.me_endpoint = `${backendPath}/api/user/me?token={{token}}` - config.users.refresh_endpoint = `${backendPath}/api/user/refresh` - config.stock.endpoint = `${backendPath}/api/stock` - config.cart.create_endpoint = `${backendPath}/api/cart/create?token={{token}}` - config.cart.updateitem_endpoint = `${backendPath}/api/cart/update?token={{token}}&cartId={{cartId}}` - config.cart.deleteitem_endpoint = `${backendPath}/api/cart/delete?token={{token}}&cartId={{cartId}}` - config.cart.pull_endpoint = `${backendPath}/api/cart/pull?token={{token}}&cartId={{cartId}}` - config.cart.totals_endpoint = `${backendPath}/api/cart/totals?token={{token}}&cartId={{cartId}}` - config.cart.paymentmethods_endpoint = `${backendPath}/api/cart/payment-methods?token={{token}}&cartId={{cartId}}` - config.cart.shippingmethods_endpoint = `${backendPath}/api/cart/shipping-methods?token={{token}}&cartId={{cartId}}` - config.cart.shippinginfo_endpoint = `${backendPath}/api/cart/shipping-information?token={{token}}&cartId={{cartId}}` - config.cart.collecttotals_endpoint = `${backendPath}/api/cart/collect-totals?token={{token}}&cartId={{cartId}}` - config.cart.deletecoupon_endpoint = `${backendPath}/api/cart/delete-coupon?token={{token}}&cartId={{cartId}}` - config.cart.applycoupon_endpoint = `${backendPath}/api/cart/apply-coupon?token={{token}}&cartId={{cartId}}&coupon={{coupon}}` - config.reviews.create_endpoint = `${backendPath}/api/review/create?token={{token}}` - - config.mailchimp.endpoint = `${backendPath}/api/ext/mailchimp-subscribe/subscribe` - config.mailer.endpoint.send = `${backendPath}/api/ext/mail-service/send-email` - config.mailer.endpoint.token = `${backendPath}/api/ext/mail-service/get-token` - config.images.baseUrl = this.answers.images_endpoint - config.cms.endpoint = `${backendPath}/api/ext/cms-data/cms{{type}}/{{cmsId}}` - config.cms.endpointIdentifier = `${backendPath}/api/ext/cms-data/cms{{type}}Identifier/{{cmsIdentifier}}/storeId/{{storeId}}` + config.api.url = backendPath; + config.graphql.host = graphQlHost; + config.graphql.port = graphQlPort; + config.elasticsearch.host = `${backendPath}/api/catalog`; + config.orders.endpoint = `${backendPath}/api/order`; + config.products.endpoint = `${backendPath}/api/product`; + config.users.endpoint = `${backendPath}/api/user`; + config.users.history_endpoint = `${backendPath}/api/user/order-history?token={{token}}`; + config.users.resetPassword_endpoint = `${backendPath}/api/user/reset-password`; + config.users.changePassword_endpoint = `${backendPath}/api/user/change-password?token={{token}}`; + config.users.login_endpoint = `${backendPath}/api/user/login`; + config.users.create_endpoint = `${backendPath}/api/user/create`; + config.users.me_endpoint = `${backendPath}/api/user/me?token={{token}}`; + config.users.refresh_endpoint = `${backendPath}/api/user/refresh`; + config.stock.endpoint = `${backendPath}/api/stock`; + config.cart.create_endpoint = `${backendPath}/api/cart/create?token={{token}}`; + config.cart.updateitem_endpoint = `${backendPath}/api/cart/update?token={{token}}&cartId={{cartId}}`; + config.cart.deleteitem_endpoint = `${backendPath}/api/cart/delete?token={{token}}&cartId={{cartId}}`; + config.cart.pull_endpoint = `${backendPath}/api/cart/pull?token={{token}}&cartId={{cartId}}`; + config.cart.totals_endpoint = `${backendPath}/api/cart/totals?token={{token}}&cartId={{cartId}}`; + config.cart.paymentmethods_endpoint = `${backendPath}/api/cart/payment-methods?token={{token}}&cartId={{cartId}}`; + config.cart.shippingmethods_endpoint = `${backendPath}/api/cart/shipping-methods?token={{token}}&cartId={{cartId}}`; + config.cart.shippinginfo_endpoint = `${backendPath}/api/cart/shipping-information?token={{token}}&cartId={{cartId}}`; + config.cart.collecttotals_endpoint = `${backendPath}/api/cart/collect-totals?token={{token}}&cartId={{cartId}}`; + config.cart.deletecoupon_endpoint = `${backendPath}/api/cart/delete-coupon?token={{token}}&cartId={{cartId}}`; + config.cart.applycoupon_endpoint = `${backendPath}/api/cart/apply-coupon?token={{token}}&cartId={{cartId}}&coupon={{coupon}}`; + config.reviews.create_endpoint = `${backendPath}/api/review/create?token={{token}}`; + + config.mailchimp.endpoint = `${backendPath}/api/ext/mailchimp-subscribe/subscribe`; + config.mailer.endpoint.send = `${backendPath}/api/ext/mail-service/send-email`; + config.mailer.endpoint.token = `${backendPath}/api/ext/mail-service/get-token`; + config.images.baseUrl = this.answers.images_endpoint; + config.cms.endpoint = `${backendPath}/api/ext/cms-data/cms{{type}}/{{cmsId}}`; + config.cms.endpointIdentifier = `${backendPath}/api/ext/cms-data/cms{{type}}Identifier/{{cmsIdentifier}}/storeId/{{storeId}}`; config.install = { is_local_backend: Abstract.wasLocalBackendInstalled, backend_dir: this.answers.backend_dir || false - } + }; - jsonFile.writeFileSync(TARGET_FRONTEND_CONFIG_FILE, config, {spaces: 2}) + jsonFile.writeFileSync(TARGET_FRONTEND_CONFIG_FILE, config, { + spaces: 2 + }); } catch (e) { - reject(new Error('Can\'t create storefront config.')) + reject(new Error("Can't create storefront config.")); } - resolve() - }) + resolve(); + }); } /** @@ -476,16 +553,21 @@ class Storefront extends Abstract { * * @returns {Promise} */ - npmBuild () { + npmBuild() { return new Promise((resolve, reject) => { - Message.info('Build storefront npm...') - - if (shell.exec(`npm run build > ${Abstract.storefrontLogStream} 2>&1`).code !== 0) { - reject(new Error('Can\'t build storefront npm.', VUE_STOREFRONT_LOG_FILE)) + Message.info('Build storefront npm...'); + + if ( + shell.exec(`npm run build > ${Abstract.storefrontLogStream} 2>&1`) + .code !== 0 + ) { + reject( + new Error("Can't build storefront npm.", VUE_STOREFRONT_LOG_FILE) + ); } - resolve() - }) + resolve(); + }); } /** @@ -493,22 +575,34 @@ class Storefront extends Abstract { * * @returns {Promise} */ - runDevEnvironment (answers) { + runDevEnvironment(answers) { return new Promise((resolve, reject) => { - Message.info('Starting storefront server...') + Message.info('Starting storefront server...'); if (isWindows()) { - if (shell.exec(`start /min npm run dev >> ${Abstract.storefrontLogStream} 2>&1 &`).code !== 0) { - reject(new Error('Can\'t start storefront server.', VUE_STOREFRONT_LOG_FILE)) + if ( + shell.exec( + `start /min npm run dev >> ${Abstract.storefrontLogStream} 2>&1 &` + ).code !== 0 + ) { + reject( + new Error("Can't start storefront server.", VUE_STOREFRONT_LOG_FILE) + ); } } else { - if (shell.exec(`nohup npm run dev >> ${Abstract.storefrontLogStream} 2>&1 &`).code !== 0) { - reject(new Error('Can\'t start storefront server.', VUE_STOREFRONT_LOG_FILE)) + if ( + shell.exec( + `nohup npm run dev >> ${Abstract.storefrontLogStream} 2>&1 &` + ).code !== 0 + ) { + reject( + new Error("Can't start storefront server.", VUE_STOREFRONT_LOG_FILE) + ); } } - resolve(answers) - }) + resolve(answers); + }); } } @@ -518,11 +612,11 @@ class Manager extends Abstract { * * Assign backend and storefront entities */ - constructor (answers) { - super(answers) + constructor(answers) { + super(answers); - this.backend = new Backend(answers) - this.storefront = new Storefront(answers) + this.backend = new Backend(answers); + this.storefront = new Storefront(answers); } /** @@ -531,35 +625,35 @@ class Manager extends Abstract { * * @returns {Promise} */ - tryToCreateLogFiles () { + tryToCreateLogFiles() { return new Promise((resolve, reject) => { - Message.info('Trying to create log files...') + Message.info('Trying to create log files...'); try { - mkdirp.sync(LOG_DIR, {mode: parseInt('0755', 8)}) + mkdirp.sync(LOG_DIR, { mode: parseInt('0755', 8) }); let logFiles = [ INSTALL_LOG_FILE, VUE_STOREFRONT_BACKEND_LOG_FILE, VUE_STOREFRONT_LOG_FILE - ] + ]; for (let logFile of logFiles) { if (shell.touch(logFile).code !== 0 || !exists(logFile)) { - throw new Error() + throw new Error(); } } - Abstract.logsWereCreated = true - Abstract.infoLogStream = INSTALL_LOG_FILE - Abstract.storefrontLogStream = VUE_STOREFRONT_LOG_FILE - Abstract.backendLogStream = VUE_STOREFRONT_BACKEND_LOG_FILE + Abstract.logsWereCreated = true; + Abstract.infoLogStream = INSTALL_LOG_FILE; + Abstract.storefrontLogStream = VUE_STOREFRONT_LOG_FILE; + Abstract.backendLogStream = VUE_STOREFRONT_BACKEND_LOG_FILE; } catch (e) { - Message.warning('Can\'t create log files.') + Message.warning("Can't create log files."); } - resolve() - }) + resolve(); + }); } /** @@ -567,20 +661,22 @@ class Manager extends Abstract { * * @returns {Promise} */ - initBackend () { + initBackend() { if (this.answers.is_remote_backend === false) { - Abstract.wasLocalBackendInstalled = true + Abstract.wasLocalBackendInstalled = true; if (this.answers.m2_api_oauth2 === true) { - return this.backend.validateM2Integration() + return this.backend + .validateM2Integration() .then(this.backend.cloneRepository.bind(this.backend)) .then(this.backend.goToDirectory.bind(this.backend)) .then(this.backend.npmInstall.bind(this.backend)) .then(this.backend.createConfig.bind(this.backend)) .then(this.backend.dockerComposeUp.bind(this.backend)) .then(this.backend.importElasticSearch.bind(this.backend)) - .then(this.backend.runDevEnvironment.bind(this.backend)) + .then(this.backend.runDevEnvironment.bind(this.backend)); } else { - return this.backend.cloneRepository() + return this.backend + .cloneRepository() .then(this.backend.goToDirectory.bind(this.backend)) .then(this.backend.npmInstall.bind(this.backend)) .then(this.backend.createConfig.bind(this.backend)) @@ -588,10 +684,10 @@ class Manager extends Abstract { .then(this.backend.restoreElasticSearch.bind(this.backend)) .then(this.backend.migrateElasticSearch.bind(this.backend)) .then(this.backend.cloneMagentoSampleData.bind(this.backend)) - .then(this.backend.runDevEnvironment.bind(this.backend)) + .then(this.backend.runDevEnvironment.bind(this.backend)); } } else { - return Promise.resolve() + return Promise.resolve(); } } @@ -600,21 +696,22 @@ class Manager extends Abstract { * * @returns {Promise} */ - initStorefront () { - return this.storefront.goToDirectory() + initStorefront() { + return this.storefront + .goToDirectory() .then(this.storefront.createConfig.bind(this.storefront)) .then(this.storefront.npmBuild.bind(this.storefront)) - .then(this.storefront.runDevEnvironment.bind(this.storefront)) + .then(this.storefront.runDevEnvironment.bind(this.storefront)); } /** * Shows message rendered on the very beginning */ - static showWelcomeMessage () { + static showWelcomeMessage() { Message.greeting([ 'Hi, welcome to the vue-storefront installation.', - 'Let\'s configure it together :)' - ]) + "Let's configure it together :)" + ]); } /** @@ -622,24 +719,32 @@ class Manager extends Abstract { * * @returns {Promise} */ - showGoodbyeMessage () { + showGoodbyeMessage() { return new Promise((resolve, reject) => { - Message.greeting([ - 'Congratulations!', - '', - 'You\'ve just successfully installed vue-storefront.', - 'All required servers are running in background', - '', - 'Storefront: http://localhost:3000', - 'Backend: ' + (Abstract.wasLocalBackendInstalled ? 'http://localhost:8080' : STOREFRONT_REMOTE_BACKEND_URL), - '', - Abstract.logsWereCreated ? `Logs: ${LOG_DIR}/` : 'You don\'t have log files created.', - '', - 'Good Luck!' - ], true) - - resolve() - }) + Message.greeting( + [ + 'Congratulations!', + '', + "You've just successfully installed vue-storefront.", + 'All required servers are running in background', + '', + 'Storefront: http://localhost:3000', + 'Backend: ' + + (Abstract.wasLocalBackendInstalled + ? 'http://localhost:8080' + : STOREFRONT_REMOTE_BACKEND_URL), + '', + Abstract.logsWereCreated + ? `Logs: ${LOG_DIR}/` + : "You don't have log files created.", + '', + 'Good Luck!' + ], + true + ); + + resolve(); + }); } } @@ -658,17 +763,17 @@ let questions = [ { type: 'input', name: 'git_path', - message: 'Please provide Git path (if it\'s not globally installed)', + message: "Please provide Git path (if it's not globally installed)", default: 'git', - when: function (answers) { - return answers.is_remote_backend === false + when: function(answers) { + return answers.is_remote_backend === false; }, - validate: function (value) { + validate: function(value) { if (!commandExists.sync(value)) { - return 'Invalid git path. Try again ;)' + return 'Invalid git path. Try again ;)'; } - return true + return true; } }, { @@ -676,21 +781,21 @@ let questions = [ name: 'backend_dir', message: 'Please provide path for installing backend locally', default: '../vue-storefront-api', - when: function (answers) { - return answers.is_remote_backend === false + when: function(answers) { + return answers.is_remote_backend === false; }, - validate: function (value) { + validate: function(value) { try { - mkdirp.sync(value, {mode: parseInt('0755', 8)}) + mkdirp.sync(value, { mode: parseInt('0755', 8) }); if (!isEmptyDir.sync(value)) { - return 'Please provide path to empty directory.' + return 'Please provide path to empty directory.'; } } catch (error) { - return 'Can\'t access to write in this directory. Try again ;)' + return "Can't access to write in this directory. Try again ;)"; } - return true + return true; } }, { @@ -702,8 +807,8 @@ let questions = [ 'http://localhost:8080/img/', 'Custom url' ], - when: function (answers) { - return answers.is_remote_backend === false + when: function(answers) { + return answers.is_remote_backend === false; } }, { @@ -711,24 +816,27 @@ let questions = [ name: 'images_endpoint', message: 'Please provide path for images endpoint', default: `${STOREFRONT_REMOTE_BACKEND_URL}/img/`, - when: function (answers) { - let isProvideByYourOwn = answers.images_endpoint === 'Custom url' + when: function(answers) { + let isProvideByYourOwn = answers.images_endpoint === 'Custom url'; - return isProvideByYourOwn || answers.is_remote_backend === true + return isProvideByYourOwn || answers.is_remote_backend === true; }, - filter: function (url) { - let prefix = 'http://' - let prefixSsl = 'https://' + filter: function(url) { + let prefix = 'http://'; + let prefixSsl = 'https://'; - url = url.trim() + url = url.trim(); // add http:// if no protocol set - if (url.substr(0, prefix.length) !== prefix && url.substr(0, prefixSsl.length) !== prefixSsl) { - url = prefix + url + if ( + url.substr(0, prefix.length) !== prefix && + url.substr(0, prefixSsl.length) !== prefixSsl + ) { + url = prefix + url; } // add extra slash as suffix if was not set - return url.slice(-1) === '/' ? url : `${url}/` + return url.slice(-1) === '/' ? url : `${url}/`; } }, { @@ -736,8 +844,8 @@ let questions = [ name: 'm2_url', message: 'Please provide your Magento url', default: 'http://demo-magento2.vuestorefront.io', - when: function (answers) { - return answers.is_remote_backend === false + when: function(answers) { + return answers.is_remote_backend === false; } }, { @@ -745,8 +853,8 @@ let questions = [ name: 'm2_api_oauth2', message: `Would You like to perform initial data import from Magento2 instance?`, default: false, - when: function (answers) { - return answers.is_remote_backend === false + when: function(answers) { + return answers.is_remote_backend === false; } }, { @@ -754,21 +862,24 @@ let questions = [ name: 'm2_api_url', message: 'Please provide the URL to your Magento rest API', default: 'http://demo-magento2.vuestorefront.io/rest', - when: function (answers) { - return answers.m2_api_oauth2 === true + when: function(answers) { + return answers.m2_api_oauth2 === true; }, - filter: function (url) { - let prefix = 'http://' - let prefixSsl = 'https://' + filter: function(url) { + let prefix = 'http://'; + let prefixSsl = 'https://'; - url = url.trim() + url = url.trim(); // add http:// if no protocol set - if (url.substr(0, prefix.length) !== prefix && url.substr(0, prefixSsl.length) !== prefixSsl) { - url = prefix + url + if ( + url.substr(0, prefix.length) !== prefix && + url.substr(0, prefixSsl.length) !== prefixSsl + ) { + url = prefix + url; } - return url + return url; } }, { @@ -776,8 +887,8 @@ let questions = [ name: 'm2_api_consumer_key', message: 'Please provide your consumer key', default: 'byv3730rhoulpopcq64don8ukb8lf2gq', - when: function (answers) { - return answers.m2_api_oauth2 === true + when: function(answers) { + return answers.m2_api_oauth2 === true; } }, { @@ -785,8 +896,8 @@ let questions = [ name: 'm2_api_consumer_secret', message: 'Please provide your consumer secret', default: 'u9q4fcobv7vfx9td80oupa6uhexc27rb', - when: function (answers) { - return answers.m2_api_oauth2 === true + when: function(answers) { + return answers.m2_api_oauth2 === true; } }, { @@ -794,8 +905,8 @@ let questions = [ name: 'm2_api_access_token', message: 'Please provide your access token', default: '040xx3qy7s0j28o3q0exrfop579cy20m', - when: function (answers) { - return answers.m2_api_oauth2 === true + when: function(answers) { + return answers.m2_api_oauth2 === true; } }, { @@ -803,32 +914,33 @@ let questions = [ name: 'm2_api_access_token_secret', message: 'Please provide your access token secret', default: '7qunl3p505rubmr7u1ijt7odyialnih9', - when: function (answers) { - return answers.m2_api_oauth2 === true + when: function(answers) { + return answers.m2_api_oauth2 === true; } } -] +]; -async function processAnswers (answers) { - let manager = new Manager(answers) +async function processAnswers(answers) { + let manager = new Manager(answers); - await manager.tryToCreateLogFiles() + await manager + .tryToCreateLogFiles() .then(manager.initBackend.bind(manager)) .then(manager.initStorefront.bind(manager)) .then(manager.showGoodbyeMessage.bind(manager)) - .catch(Message.error) + .catch(Message.error); - shell.exit(0) + shell.exit(0); } /** * Predefine class static variables */ -Abstract.wasLocalBackendInstalled = false -Abstract.logsWereCreated = false -Abstract.infoLogStream = '/dev/null' -Abstract.storefrontLogStream = '/dev/null' -Abstract.backendLogStream = '/dev/null' +Abstract.wasLocalBackendInstalled = false; +Abstract.logsWereCreated = false; +Abstract.infoLogStream = '/dev/null'; +Abstract.storefrontLogStream = '/dev/null'; +Abstract.backendLogStream = '/dev/null'; if (require.main.filename === __filename) { /** @@ -837,23 +949,23 @@ if (require.main.filename === __filename) { program .option('--default-config', 'Run with default configuration') - .parse(process.argv) + .parse(process.argv); if (program.defaultConfig) { - const defaultConfig = {} + const defaultConfig = {}; questions.forEach(question => { - defaultConfig[question.name] = question.default - }) - processAnswers(defaultConfig) + defaultConfig[question.name] = question.default; + }); + processAnswers(defaultConfig); } else { - Manager.showWelcomeMessage() - inquirer.prompt(questions).then(answers => processAnswers(answers)) + Manager.showWelcomeMessage(); + inquirer.prompt(questions).then(answers => processAnswers(answers)); } } else { - module.exports.Message = Message - module.exports.Manager = Manager - module.exports.Abstract = Abstract - module.exports.STOREFRONT_REMOTE_BACKEND_URL = STOREFRONT_REMOTE_BACKEND_URL - module.exports.TARGET_FRONTEND_CONFIG_FILE = TARGET_FRONTEND_CONFIG_FILE - module.exports.TARGET_BACKEND_CONFIG_FILE = TARGET_BACKEND_CONFIG_FILE + module.exports.Message = Message; + module.exports.Manager = Manager; + module.exports.Abstract = Abstract; + module.exports.STOREFRONT_REMOTE_BACKEND_URL = STOREFRONT_REMOTE_BACKEND_URL; + module.exports.TARGET_FRONTEND_CONFIG_FILE = TARGET_FRONTEND_CONFIG_FILE; + module.exports.TARGET_BACKEND_CONFIG_FILE = TARGET_BACKEND_CONFIG_FILE; } diff --git a/core/scripts/resolvers/resolveGraphQL.js b/core/scripts/resolvers/resolveGraphQL.js index a1b651c60e..b8858d9b31 100644 --- a/core/scripts/resolvers/resolveGraphQL.js +++ b/core/scripts/resolvers/resolveGraphQL.js @@ -1,36 +1,52 @@ -import { server, graphql } from 'config' -import Vue from 'vue' -import { Logger } from '@vue-storefront/core/lib/logger' -import { once } from '@vue-storefront/core/helpers' +import { server, graphql } from 'config'; +import Vue from 'vue'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { once } from '@vue-storefront/core/helpers'; export const getApolloProvider = async () => { if (server.api === 'graphql') { - const ApolloModule = await import(/* webpackChunkName: "vsf-graphql" */ 'vue-apollo') - const VueApollo = ApolloModule.default + const ApolloModule = await import( + /* webpackChunkName: "vsf-graphql" */ 'vue-apollo' + ); + const VueApollo = ApolloModule.default; once('__VUE_EXTEND_GQL__', () => { - Vue.use(VueApollo) - }) + Vue.use(VueApollo); + }); - const HttpLinkModule = await import(/* webpackChunkName: "vsf-graphql" */ 'apollo-link-http') - const HttpLink = HttpLinkModule.HttpLink + const HttpLinkModule = await import( + /* webpackChunkName: "vsf-graphql" */ 'apollo-link-http' + ); + const HttpLink = HttpLinkModule.HttpLink; const httpLink = new HttpLink({ - uri: graphql.host.indexOf('://') >= 0 ? graphql.host : (server.protocol + '://' + graphql.host + ':' + graphql.port + '/graphql') - }) + uri: + graphql.host.indexOf('://') >= 0 + ? graphql.host + : server.protocol + + '://' + + graphql.host + + ':' + + graphql.port + + '/graphql' + }); - const ApolloClientModule = await import(/* webpackChunkName: "vsf-graphql" */ 'apollo-client') - const ApolloClient = ApolloClientModule.default - const inMemoryCacheModule = await import(/* webpackChunkName: "vsf-graphql" */ 'apollo-cache-inmemory') - const InMemoryCache = inMemoryCacheModule.InMemoryCache + const ApolloClientModule = await import( + /* webpackChunkName: "vsf-graphql" */ 'apollo-client' + ); + const ApolloClient = ApolloClientModule.default; + const inMemoryCacheModule = await import( + /* webpackChunkName: "vsf-graphql" */ 'apollo-cache-inmemory' + ); + const InMemoryCache = inMemoryCacheModule.InMemoryCache; const apolloClient = new ApolloClient({ link: httpLink, cache: new InMemoryCache(), connectToDevTools: true - }) + }); - let loading = 0 + let loading = 0; const apolloProvider = new VueApollo({ clients: { @@ -40,20 +56,20 @@ export const getApolloProvider = async () => { defaultOptions: { // $loadingKey: 'loading', }, - watchLoading (state, mod) { - loading += mod - Logger.log('Global loading', loading, mod)() + watchLoading(state, mod) { + loading += mod; + Logger.log('Global loading', loading, mod)(); }, - errorHandler (error) { - Logger.log('Global error handler')() - Logger.error(error)() + errorHandler(error) { + Logger.log('Global error handler')(); + Logger.error(error)(); } - }) + }); - return apolloProvider + return apolloProvider; } -} +}; export default { getApolloProvider -} +}; diff --git a/core/scripts/server.js b/core/scripts/server.js index dac9d2fb6a..2abddda561 100755 --- a/core/scripts/server.js +++ b/core/scripts/server.js @@ -1,54 +1,54 @@ -const fs = require('fs') -const path = require('path') -const express = require('express') -const compile = require('lodash.template') -const rootPath = require('app-root-path').path -const resolve = file => path.resolve(rootPath, file) +const fs = require('fs'); +const path = require('path'); +const express = require('express'); +const compile = require('lodash.template'); +const rootPath = require('app-root-path').path; +const resolve = file => path.resolve(rootPath, file); -const cache = require('./utils/cache-instance') -const apiStatus = require('./utils/api-status') -const HTMLContent = require('../pages/Compilation') -let config = require('config') +const cache = require('./utils/cache-instance'); +const apiStatus = require('./utils/api-status'); +const HTMLContent = require('../pages/Compilation'); +let config = require('config'); const compileOptions = { escape: /{{([^{][\s\S]+?[^}])}}/g, interpolate: /{{{([\s\S]+?)}}}/g -} +}; -const isProd = process.env.NODE_ENV === 'production' -process.noDeprecation = true +const isProd = process.env.NODE_ENV === 'production'; +process.noDeprecation = true; -const app = express() +const app = express(); -const templatesCache = {} -let renderer +const templatesCache = {}; +let renderer; for (const tplName of Object.keys(config.ssr.templates)) { - const fileName = resolve(config.ssr.templates[tplName]) + const fileName = resolve(config.ssr.templates[tplName]); if (fs.existsSync(fileName)) { - const template = fs.readFileSync(fileName, 'utf-8') - templatesCache[tplName] = compile(template, compileOptions) + const template = fs.readFileSync(fileName, 'utf-8'); + templatesCache[tplName] = compile(template, compileOptions); } } if (isProd) { // In production: create server renderer using server bundle and index HTML // template from real fs. // The server bundle is generated by vue-ssr-webpack-plugin. - const clientManifest = require(resolve('dist/vue-ssr-client-manifest.json')) - const bundle = require(resolve('dist/vue-ssr-bundle.json')) + const clientManifest = require(resolve('dist/vue-ssr-client-manifest.json')); + const bundle = require(resolve('dist/vue-ssr-bundle.json')); // src/index.template.html is processed by html-webpack-plugin to inject // build assets and output as dist/index.html. // TODO: Add dynamic templates loading from (config based?) list - renderer = createRenderer(bundle, clientManifest) + renderer = createRenderer(bundle, clientManifest); } else { // In development: setup the dev server with watch and hot-reload, // and create a new renderer on bundle / index template update. require(resolve('core/build/dev-server'))(app, (bundle, template) => { - templatesCache['default'] = compile(template, compileOptions) // Important Notice: template switching doesn't work with dev server because of the HMR - renderer = createRenderer(bundle) - }) + templatesCache['default'] = compile(template, compileOptions); // Important Notice: template switching doesn't work with dev server because of the HMR + renderer = createRenderer(bundle); + }); } -function createRenderer (bundle, clientManifest, template) { +function createRenderer(bundle, clientManifest, template) { // https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/README.md#why-use-bundlerenderer return require('vue-server-renderer').createBundleRenderer(bundle, { clientManifest, @@ -57,98 +57,130 @@ function createRenderer (bundle, clientManifest, template) { max: 1000, maxAge: 1000 * 60 * 15 }) - }) + }); } -function invalidateCache (req, res) { +function invalidateCache(req, res) { if (config.server.useOutputCache) { - if (req.query.tag && req.query.key) { // clear cache pages for specific query tag + if (req.query.tag && req.query.key) { + // clear cache pages for specific query tag if (req.query.key !== config.server.invalidateCacheKey) { - console.error('Invalid cache invalidation key') - apiStatus(res, 'Invalid cache invalidation key', 500) - return + console.error('Invalid cache invalidation key'); + apiStatus(res, 'Invalid cache invalidation key', 500); + return; } - console.log(`Clear cache request for [${req.query.tag}]`) - let tags = [] + console.log(`Clear cache request for [${req.query.tag}]`); + let tags = []; if (req.query.tag === '*') { - tags = config.server.availableCacheTags + tags = config.server.availableCacheTags; } else { - tags = req.query.tag.split(',') + tags = req.query.tag.split(','); } - const subPromises = [] + const subPromises = []; tags.forEach(tag => { - if (config.server.availableCacheTags.indexOf(tag) >= 0 || config.server.availableCacheTags.find(t => { - return tag.indexOf(t) === 0 - })) { - subPromises.push(cache.invalidate(tag).then(() => { - console.log(`Tags invalidated successfully for [${tag}]`) - })) + if ( + config.server.availableCacheTags.indexOf(tag) >= 0 || + config.server.availableCacheTags.find(t => { + return tag.indexOf(t) === 0; + }) + ) { + subPromises.push( + cache.invalidate(tag).then(() => { + console.log(`Tags invalidated successfully for [${tag}]`); + }) + ); } else { - console.error(`Invalid tag name ${tag}`) + console.error(`Invalid tag name ${tag}`); } - }) - Promise.all(subPromises).then(r => { - apiStatus(res, `Tags invalidated successfully [${req.query.tag}]`, 200) - }).catch(error => { - apiStatus(res, error, 500) - console.error(error) - }) + }); + Promise.all(subPromises) + .then(r => { + apiStatus( + res, + `Tags invalidated successfully [${req.query.tag}]`, + 200 + ); + }) + .catch(error => { + apiStatus(res, error, 500); + console.error(error); + }); } else { - apiStatus(res, 'Invalid parameters for Clear cache request', 500) - console.error('Invalid parameters for Clear cache request') + apiStatus(res, 'Invalid parameters for Clear cache request', 500); + console.error('Invalid parameters for Clear cache request'); } } else { - apiStatus(res, 'Cache invalidation is not required, output cache is disabled', 200) + apiStatus( + res, + 'Cache invalidation is not required, output cache is disabled', + 200 + ); } } -const serve = (path, cache, options) => express.static(resolve(path), Object.assign({ - maxAge: cache && isProd ? 2592000000 : 0, // 1 month in milliseconds = 1000 * 60 * 60 * 24 * 30 = 2592000000 - fallthrough: false -}, options)) +const serve = (path, cache, options) => + express.static( + resolve(path), + Object.assign( + { + maxAge: cache && isProd ? 2592000000 : 0, // 1 month in milliseconds = 1000 * 60 * 60 * 24 * 30 = 2592000000 + fallthrough: false + }, + options + ) + ); -const themeRoot = require('../build/theme-path') +const themeRoot = require('../build/theme-path'); -app.use('/dist', serve('dist', true)) -app.use('/assets', serve(themeRoot + '/assets', true)) -app.use('/service-worker.js', serve('dist/service-worker.js', false, { - setHeaders: function (res, path, stat) { - res.set('Content-Type', 'text/javascript; charset=UTF-8') - } -})) +app.use('/dist', serve('dist', true)); +app.use('/assets', serve(themeRoot + '/assets', true)); +app.use( + '/service-worker.js', + serve('dist/service-worker.js', false, { + setHeaders: function(res, path, stat) { + res.set('Content-Type', 'text/javascript; charset=UTF-8'); + } + }) +); -const serverExtensions = require(resolve('src/server')) -serverExtensions.registerUserServerRoutes(app) +const serverExtensions = require(resolve('src/server')); +serverExtensions.registerUserServerRoutes(app); -app.post('/invalidate', invalidateCache) +app.post('/invalidate', invalidateCache); -app.get('/invalidate', invalidateCache) +app.get('/invalidate', invalidateCache); app.get('*', (req, res, next) => { - const s = Date.now() + const s = Date.now(); const errorHandler = err => { if (err && err.code === 404) { - res.redirect('/page-not-found') + res.redirect('/page-not-found'); } else { - res.redirect('/error') - console.error(`Error during render : ${req.url}`) - console.error(err) - next() + res.redirect('/error'); + console.error(`Error during render : ${req.url}`); + console.error(err); + next(); } - } + }; const dynamicRequestHandler = renderer => { if (!renderer) { - res.setHeader('Content-Type', 'text/html') - res.status(202).end(HTMLContent) - return next() + res.setHeader('Content-Type', 'text/html'); + res.status(202).end(HTMLContent); + return next(); } const context = { url: decodeURI(req.url), output: { - prepend: (context) => { return '' }, // these functions can be replaced in the Vue components to append or prepend some content AFTER all other things are rendered. So in this function You may call: output.prepend() { return context.renderStyles() } to attach styles - append: (context) => { return '' }, - appendHead: (context) => { return '' }, + prepend: context => { + return ''; + }, // these functions can be replaced in the Vue components to append or prepend some content AFTER all other things are rendered. So in this function You may call: output.prepend() { return context.renderStyles() } to attach styles + append: context => { + return ''; + }, + appendHead: context => { + return ''; + }, template: 'default', cacheTags: null }, @@ -160,118 +192,152 @@ app.get('*', (req, res, next) => { meta: null, vs: { config: config, - storeCode: req.header('x-vs-store-code') ? req.header('x-vs-store-code') : process.env.STORE_CODE - } - } - renderer.renderToString(context).then(output => { - if (!res.get('content-type')) { - res.setHeader('Content-Type', 'text/html') + storeCode: req.header('x-vs-store-code') + ? req.header('x-vs-store-code') + : process.env.STORE_CODE } - let tagsArray = [] - if (config.server.useOutputCacheTagging && context.output.cacheTags !== null) { - tagsArray = Array.from(context.output.cacheTags) - const cacheTags = tagsArray.join(' ') - res.setHeader('X-VS-Cache-Tags', cacheTags) - console.log(`cache tags for the request: ${cacheTags}`) - } - const contentPrepend = (typeof context.output.prepend === 'function') ? context.output.prepend(context) : '' - const contentAppend = (typeof context.output.append === 'function') ? context.output.append(context) : '' + }; + renderer + .renderToString(context) + .then(output => { + if (!res.get('content-type')) { + res.setHeader('Content-Type', 'text/html'); + } + let tagsArray = []; + if ( + config.server.useOutputCacheTagging && + context.output.cacheTags !== null + ) { + tagsArray = Array.from(context.output.cacheTags); + const cacheTags = tagsArray.join(' '); + res.setHeader('X-VS-Cache-Tags', cacheTags); + console.log(`cache tags for the request: ${cacheTags}`); + } + const contentPrepend = + typeof context.output.prepend === 'function' + ? context.output.prepend(context) + : ''; + const contentAppend = + typeof context.output.append === 'function' + ? context.output.append(context) + : ''; - output = contentPrepend + output + contentAppend - if (context.output.template) { // case when we've got the template name back from vue app - if (!isProd) context.output.template = 'default' // in dev mode we can not use pre-rendered HTML templates - if (templatesCache[context.output.template]) { // please look at: https://github.com/vuejs/vue/blob/79cabadeace0e01fb63aa9f220f41193c0ca93af/src/server/template-renderer/index.js#L87 for reference - output = templatesCache[context.output.template](context).replace('', output) - } else { - throw new Error(`The given template name ${context.output.template} does not exist`) + output = contentPrepend + output + contentAppend; + if (context.output.template) { + // case when we've got the template name back from vue app + if (!isProd) context.output.template = 'default'; // in dev mode we can not use pre-rendered HTML templates + if (templatesCache[context.output.template]) { + // please look at: https://github.com/vuejs/vue/blob/79cabadeace0e01fb63aa9f220f41193c0ca93af/src/server/template-renderer/index.js#L87 for reference + output = templatesCache[context.output.template](context).replace( + '', + output + ); + } else { + throw new Error( + `The given template name ${ + context.output.template + } does not exist` + ); + } } - } - if (config.server.useOutputCache && cache) { - cache.set( - 'page:' + req.url, - { headers: res.getHeaders(), body: output }, - tagsArray - ).catch(errorHandler) - } - res.end(output) - console.log(`whole request [${req.url}]: ${Date.now() - s}ms`) - next() - }).catch(errorHandler) - } + if (config.server.useOutputCache && cache) { + cache + .set( + 'page:' + req.url, + { headers: res.getHeaders(), body: output }, + tagsArray + ) + .catch(errorHandler); + } + res.end(output); + console.log(`whole request [${req.url}]: ${Date.now() - s}ms`); + next(); + }) + .catch(errorHandler); + }; const dynamicCacheHandler = () => { if (config.server.useOutputCache && cache) { - cache.get( - 'page:' + req.url - ).then(output => { - if (output !== null) { - if (output.headers) { - for (const header of Object.keys(output.headers)) { - res.setHeader(header, output.headers[header]) + cache + .get('page:' + req.url) + .then(output => { + if (output !== null) { + if (output.headers) { + for (const header of Object.keys(output.headers)) { + res.setHeader(header, output.headers[header]); + } } - } - res.setHeader('X-VS-Cache', 'Hit') - if (output.body) { - res.end(output.body) + res.setHeader('X-VS-Cache', 'Hit'); + if (output.body) { + res.end(output.body); + } else { + res.setHeader('Content-Type', 'text/html'); + res.end(output.body); + } + res.end(output); + console.log( + `cache hit [${req.url}], cached request: ${Date.now() - s}ms` + ); + next(); } else { - res.setHeader('Content-Type', 'text/html') - res.end(output.body) + res.setHeader('Content-Type', 'text/html'); + res.setHeader('X-VS-Cache', 'Miss'); + console.log( + `cache miss [${req.url}], request: ${Date.now() - s}ms` + ); + dynamicRequestHandler(renderer); // render response } - res.end(output) - console.log(`cache hit [${req.url}], cached request: ${Date.now() - s}ms`) - next() - } else { - res.setHeader('Content-Type', 'text/html') - res.setHeader('X-VS-Cache', 'Miss') - console.log(`cache miss [${req.url}], request: ${Date.now() - s}ms`) - dynamicRequestHandler(renderer) // render response - } - }).catch(errorHandler) + }) + .catch(errorHandler); } else { - dynamicRequestHandler(renderer) + dynamicRequestHandler(renderer); } - } + }; if (config.server.dynamicConfigReload) { - delete require.cache[require.resolve('config')] - config = require('config') // reload config + delete require.cache[require.resolve('config')]; + config = require('config'); // reload config if (typeof serverExtensions.configProvider === 'function') { - serverExtensions.configProvider(req).then(loadedConfig => { - config = Object.assign(config, loadedConfig) // merge loaded conf with build time conf - dynamicCacheHandler() - }).catch(error => { - if (config.server.dynamicConfigContinueOnError) { - dynamicCacheHandler() - } else { - console.log('config provider error:', error) - if (req.url !== '/error') { - res.redirect('/error') + serverExtensions + .configProvider(req) + .then(loadedConfig => { + config = Object.assign(config, loadedConfig); // merge loaded conf with build time conf + dynamicCacheHandler(); + }) + .catch(error => { + if (config.server.dynamicConfigContinueOnError) { + dynamicCacheHandler(); + } else { + console.log('config provider error:', error); + if (req.url !== '/error') { + res.redirect('/error'); + } + dynamicCacheHandler(); } - dynamicCacheHandler() - } - }) + }); } else { - config = require('config') // reload config - dynamicCacheHandler() + config = require('config'); // reload config + dynamicCacheHandler(); } } else { - dynamicCacheHandler() + dynamicCacheHandler(); } -}) +}); -let port = process.env.PORT || config.server.port -const host = process.env.HOST || config.server.host +let port = process.env.PORT || config.server.port; +const host = process.env.HOST || config.server.host; const start = () => { - app.listen(port, host) + app + .listen(port, host) .on('listening', () => { - console.log(`Vue Storefront Server started at http://${host}:${port}`) + console.log(`Vue Storefront Server started at http://${host}:${port}`); }) - .on('error', (e) => { + .on('error', e => { if (e.code === 'EADDRINUSE') { - port = parseInt(port) + 1 - console.log(`The port is already in use, trying ${port}`) - start() + port = parseInt(port) + 1; + console.log(`The port is already in use, trying ${port}`); + start(); } - }) -} -start() + }); +}; +start(); diff --git a/core/scripts/utils/api-status.js b/core/scripts/utils/api-status.js index 53a6305f6e..5ac27b7290 100644 --- a/core/scripts/utils/api-status.js +++ b/core/scripts/utils/api-status.js @@ -4,10 +4,10 @@ * @param {json} [result='OK'] Text message or result information object */ module.exports = (res, result = 'OK', code = 200, meta = null) => { - let apiResult = { code: code, result: result } + let apiResult = { code: code, result: result }; if (meta !== null) { - apiResult.meta = meta + apiResult.meta = meta; } - res.status(code).json(apiResult) - return result -} + res.status(code).json(apiResult); + return result; +}; diff --git a/core/scripts/utils/cache-instance.js b/core/scripts/utils/cache-instance.js index 2dd09e26d7..ecbbde561a 100644 --- a/core/scripts/utils/cache-instance.js +++ b/core/scripts/utils/cache-instance.js @@ -1,20 +1,22 @@ -const fs = require('fs') -const path = require('path') -const TagCache = require('redis-tag-cache').default -const config = require('config') -let cache = false +const fs = require('fs'); +const path = require('path'); +const TagCache = require('redis-tag-cache').default; +const config = require('config'); +let cache = false; if (config.server.useOutputCache) { - const cacheVersionPath = path.resolve(path.join('core', 'build', 'cache-version.json')) - const cacheKey = JSON.parse(fs.readFileSync(cacheVersionPath) || '') - const redisConfig = Object.assign(config.redis, { keyPrefix: cacheKey }) + const cacheVersionPath = path.resolve( + path.join('core', 'build', 'cache-version.json') + ); + const cacheKey = JSON.parse(fs.readFileSync(cacheVersionPath) || ''); + const redisConfig = Object.assign(config.redis, { keyPrefix: cacheKey }); - console.log('Redis cache set', redisConfig) + console.log('Redis cache set', redisConfig); cache = new TagCache({ redis: redisConfig, defaultTimeout: config.server.outputCacheDefaultTtl - }) + }); } -module.exports = cache +module.exports = cache; diff --git a/core/server-entry.ts b/core/server-entry.ts index 098f0cfc05..cd4390e99d 100755 --- a/core/server-entry.ts +++ b/core/server-entry.ts @@ -1,101 +1,172 @@ -import union from 'lodash-es/union' +import union from 'lodash-es/union'; -import { createApp } from '@vue-storefront/core/app' -import { HttpError } from '@vue-storefront/core/helpers/exceptions' -import { prepareStoreView, storeCodeFromRoute } from '@vue-storefront/core/lib/multistore' -import omit from 'lodash-es/omit' -import pick from 'lodash-es/pick' -import buildTimeConfig from 'config' -import { AsyncDataLoader } from './lib/async-data-loader' -import { Logger } from '@vue-storefront/core/lib/logger' +import { createApp } from '@vue-storefront/core/app'; +import { HttpError } from '@vue-storefront/core/helpers/exceptions'; +import { + prepareStoreView, + storeCodeFromRoute +} from '@vue-storefront/core/lib/multistore'; +import omit from 'lodash-es/omit'; +import pick from 'lodash-es/pick'; +import buildTimeConfig from 'config'; +import { AsyncDataLoader } from './lib/async-data-loader'; +import { Logger } from '@vue-storefront/core/lib/logger'; -function _commonErrorHandler (err, reject) { +function _commonErrorHandler(err, reject) { if (err.message.indexOf('query returned empty result') > 0) { - reject(new HttpError(err.message, 404)) + reject(new HttpError(err.message, 404)); } else { - reject(new Error(err.message)) + reject(new Error(err.message)); } } -function _ssrHydrateSubcomponents (components, store, router, resolve, reject, app, context) { - Promise.all(components.map(SubComponent => { - if (SubComponent.asyncData) { - return SubComponent.asyncData({ - store, - route: router.currentRoute, - context - }) - } else { - return Promise.resolve(null) - } - })).then(() => { - AsyncDataLoader.flush({ store, route: router.currentRoute, context: null } /*AsyncDataLoaderActionContext*/).then((r) => { - if (buildTimeConfig.ssr.useInitialStateFilter) { - context.state = omit(store.state, store.state.config.ssr.initialStateFilter) +function _ssrHydrateSubcomponents( + components, + store, + router, + resolve, + reject, + app, + context +) { + Promise.all( + components.map(SubComponent => { + if (SubComponent.asyncData) { + return SubComponent.asyncData({ + store, + route: router.currentRoute, + context + }); } else { - context.state = store.state + return Promise.resolve(null); } - if (!buildTimeConfig.server.dynamicConfigReload) { // if dynamic config reload then we're sending config along with the request - context.state = omit(store.state, buildTimeConfig.ssr.useInitialStateFilter ? [...store.state.config.ssr.initialStateFilter, 'config'] : ['config']) - } else { - const excludeFromConfig = buildTimeConfig.server.dynamicConfigExclude - const includeFromConfig = buildTimeConfig.server.dynamicConfigInclude - console.log(excludeFromConfig, includeFromConfig) - if (includeFromConfig && includeFromConfig.length > 0) { - context.state.config = pick(context.state.config, includeFromConfig) - } - if (excludeFromConfig && excludeFromConfig.length > 0) { - context.state.config = omit(context.state.config, excludeFromConfig) - } - } - resolve (app) - }).catch(err => { - _commonErrorHandler(err, reject) }) - }).catch(err => { - _commonErrorHandler(err, reject) - }) + ) + .then(() => { + AsyncDataLoader.flush( + { + store, + route: router.currentRoute, + context: null + } /*AsyncDataLoaderActionContext*/ + ) + .then(r => { + if (buildTimeConfig.ssr.useInitialStateFilter) { + context.state = omit( + store.state, + store.state.config.ssr.initialStateFilter + ); + } else { + context.state = store.state; + } + if (!buildTimeConfig.server.dynamicConfigReload) { + // if dynamic config reload then we're sending config along with the request + context.state = omit( + store.state, + buildTimeConfig.ssr.useInitialStateFilter + ? [...store.state.config.ssr.initialStateFilter, 'config'] + : ['config'] + ); + } else { + const excludeFromConfig = + buildTimeConfig.server.dynamicConfigExclude; + const includeFromConfig = + buildTimeConfig.server.dynamicConfigInclude; + console.log(excludeFromConfig, includeFromConfig); + if (includeFromConfig && includeFromConfig.length > 0) { + context.state.config = pick( + context.state.config, + includeFromConfig + ); + } + if (excludeFromConfig && excludeFromConfig.length > 0) { + context.state.config = omit( + context.state.config, + excludeFromConfig + ); + } + } + resolve(app); + }) + .catch(err => { + _commonErrorHandler(err, reject); + }); + }) + .catch(err => { + _commonErrorHandler(err, reject); + }); } export default async context => { - const { app, router, store } = await createApp(context, context.vs && context.vs.config ? context.vs.config : buildTimeConfig) + const { app, router, store } = await createApp( + context, + context.vs && context.vs.config ? context.vs.config : buildTimeConfig + ); return new Promise((resolve, reject) => { - context.output.cacheTags = new Set() - const meta = (app as any).$meta() - router.push(context.url) - context.meta = meta + context.output.cacheTags = new Set(); + const meta = (app as any).$meta(); + router.push(context.url); + context.meta = meta; router.onReady(() => { if (store.state.config.storeViews.multistore === true) { - let storeCode = context.vs.storeCode // this is from http header or env variable - if (router.currentRoute) { // this is from url - storeCode = storeCodeFromRoute(router.currentRoute) + let storeCode = context.vs.storeCode; // this is from http header or env variable + if (router.currentRoute) { + // this is from url + storeCode = storeCodeFromRoute(router.currentRoute); } if (storeCode !== '' && storeCode !== null) { - prepareStoreView(storeCode) + prepareStoreView(storeCode); } } - const matchedComponents = router.getMatchedComponents() + const matchedComponents = router.getMatchedComponents(); if (!matchedComponents.length) { - return reject(new HttpError('No components matched', 404)) + return reject(new HttpError('No components matched', 404)); } - Promise.all(matchedComponents.map((Component: any) => { - const components = Component.mixins ? Array.from(Component.mixins) : [] - union(components, [Component]).map(SubComponent => { - if (SubComponent.preAsyncData) { - SubComponent.preAsyncData({ store, route: router.currentRoute }) + Promise.all( + matchedComponents.map((Component: any) => { + const components = Component.mixins + ? Array.from(Component.mixins) + : []; + union(components, [Component]).map(SubComponent => { + if (SubComponent.preAsyncData) { + SubComponent.preAsyncData({ store, route: router.currentRoute }); + } + }); + if (Component.asyncData) { + Component.asyncData({ + store, + route: router.currentRoute, + context: context + }) + .then(result => { + // always execute the asyncData() from the top most component first + Logger.debug('Top-most asyncData executed')(); + _ssrHydrateSubcomponents( + components, + store, + router, + resolve, + reject, + app, + context + ); + }) + .catch(err => { + _commonErrorHandler(err, reject); + }); + } else { + _ssrHydrateSubcomponents( + components, + store, + router, + resolve, + reject, + app, + context + ); } }) - if (Component.asyncData) { - Component.asyncData({ store, route: router.currentRoute, context: context }).then((result) => { // always execute the asyncData() from the top most component first - Logger.debug('Top-most asyncData executed')() - _ssrHydrateSubcomponents(components, store, router, resolve, reject, app, context) - }).catch((err) => { - _commonErrorHandler(err, reject) - }) - } else { - _ssrHydrateSubcomponents(components, store, router, resolve, reject, app, context) - } - })) - }, reject) - }) -} + ); + }, reject); + }); +}; diff --git a/core/service-worker/index.js b/core/service-worker/index.js index af83f90dfe..300a83aa75 100644 --- a/core/service-worker/index.js +++ b/core/service-worker/index.js @@ -1,4 +1,4 @@ -import '../modules/offline-order/extends/service-worker.js' -import 'theme/service-worker/index.js' +import '../modules/offline-order/extends/service-worker.js'; +import 'theme/service-worker/index.js'; // core service worker, all service worker related features are placed here. diff --git a/core/service-worker/registration.js b/core/service-worker/registration.js index 0d74296127..ef074207f7 100644 --- a/core/service-worker/registration.js +++ b/core/service-worker/registration.js @@ -1,27 +1,25 @@ -import { register } from 'register-service-worker' -import { server } from 'config' -import { Logger } from '@vue-storefront/core/lib/logger' +import { register } from 'register-service-worker'; +import { server } from 'config'; +import { Logger } from '@vue-storefront/core/lib/logger'; if (process.env.NODE_ENV === 'production' || server.devServiceWorker) { register(`/service-worker.js`, { - ready () { - Logger.log( - 'App is being served from cache by a service worker.' - ) + ready() { + Logger.log('App is being served from cache by a service worker.'); }, - cached () { - Logger.log('Content has been cached for offline use.')() + cached() { + Logger.log('Content has been cached for offline use.')(); }, - updated (registration) { - Logger.log('New content is available, please refresh.')() + updated(registration) { + Logger.log('New content is available, please refresh.')(); }, - offline () { + offline() { Logger.log( 'No internet connection found. App is running in offline mode.' - ) + ); }, - error (error) { - Logger.error('Error during service worker registration:', error)() + error(error) { + Logger.error('Error during service worker registration:', error)(); } - }) + }); } diff --git a/core/store/index.ts b/core/store/index.ts index d85aba7935..4086788b76 100644 --- a/core/store/index.ts +++ b/core/store/index.ts @@ -1,11 +1,11 @@ -import Vue from 'vue' -import Vuex from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import { once } from '@vue-storefront/core/helpers' +import Vue from 'vue'; +import Vuex from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import { once } from '@vue-storefront/core/helpers'; once('__VUE_EXTEND_VUEX__', () => { - Vue.use(Vuex) -}) + Vue.use(Vuex); +}); const state = { version: '', @@ -40,11 +40,11 @@ const state = { userTokenInvalidated: null, userTokenInvalidateAttemptsCount: 0, userTokenInvalidateLock: 0 -} +}; let rootStore = new Vuex.Store({ // TODO: refactor it to return just the constructor to avoid event-bus and i18n shenanigans; challenge: the singleton management OR add i18n and eventBus here to rootStore instance? modules: { state -}) +}); -export default rootStore \ No newline at end of file +export default rootStore; diff --git a/core/store/lib/entities.ts b/core/store/lib/entities.ts index 76c6ebc881..fcea6c6692 100644 --- a/core/store/lib/entities.ts +++ b/core/store/lib/entities.ts @@ -1,28 +1,40 @@ /** * @returns {string} */ -export function guid () { - function s4 () { +export function guid() { + function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) - .substring(1) + .substring(1); } - return s4() + s4() + '-' + s4() + '-' + s4() + '-' + - s4() + '-' + s4() + s4() + s4() + return ( + s4() + + s4() + + '-' + + s4() + + '-' + + s4() + + '-' + + s4() + + '-' + + s4() + + s4() + + s4() + ); } /** - * Return unique entity.id - * @param {Object} entity - */ -export function uniqueEntityId (entity) { - return new Date().getTime() + '-' + guid() + * Return unique entity.id + * @param {Object} entity + */ +export function uniqueEntityId(entity) { + return new Date().getTime() + '-' + guid(); } /** - * Return unique entity key name for specified key value - * @param {String} key - * @param {String} value - */ -export function entityKeyName (...values) { - return values.join('$$') + * Return unique entity key name for specified key value + * @param {String} key + * @param {String} value + */ +export function entityKeyName(...values) { + return values.join('$$'); } diff --git a/core/store/lib/filters.ts b/core/store/lib/filters.ts index 886b52f52d..52040a13c1 100644 --- a/core/store/lib/filters.ts +++ b/core/store/lib/filters.ts @@ -1,9 +1,9 @@ -import decode from 'lean-he/decode' +import decode from 'lean-he/decode'; /** * Decodes any named and numerical character references in the text * @param {String} value */ -export function htmlDecode (value: any) { - return value ? decode(value) : '' +export function htmlDecode(value: any) { + return value ? decode(value) : ''; } diff --git a/core/store/lib/storage.ts b/core/store/lib/storage.ts index f9bd2cb93e..a934387586 100644 --- a/core/store/lib/storage.ts +++ b/core/store/lib/storage.ts @@ -1,38 +1,33 @@ -import Vue from 'vue' -import * as localForage from 'localforage' -import { Logger } from '@vue-storefront/core/lib/logger' -import { isServer } from '@vue-storefront/core/helpers' +import Vue from 'vue'; +import * as localForage from 'localforage'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { isServer } from '@vue-storefront/core/helpers'; -const CACHE_TIMEOUT = 800 -const CACHE_TIMEOUT_ITERATE = 2000 -const DISABLE_PERSISTANCE_AFTER = 1 -const DISABLE_PERSISTANCE_AFTER_SAVE = 30 +const CACHE_TIMEOUT = 800; +const CACHE_TIMEOUT_ITERATE = 2000; +const DISABLE_PERSISTANCE_AFTER = 1; +const DISABLE_PERSISTANCE_AFTER_SAVE = 30; -function roughSizeOfObject( object ) { - const objectList = [] - const stack = [ object ] - let bytes = 0 - while ( stack.length ) { - const value = stack.pop() - if ( typeof value === 'boolean' ) { - bytes += 4 - } - else if ( typeof value === 'string' ) { - bytes += value.length * 2 - } - else if ( typeof value === 'number' ) { - bytes += 8 - } else if ( - typeof value === 'object' - && objectList.indexOf( value ) === -1 - ) { - objectList.push( value ) - for( var i in value ) { - stack.push( value[ i ] ) +function roughSizeOfObject(object) { + const objectList = []; + const stack = [object]; + let bytes = 0; + while (stack.length) { + const value = stack.pop(); + if (typeof value === 'boolean') { + bytes += 4; + } else if (typeof value === 'string') { + bytes += value.length * 2; + } else if (typeof value === 'number') { + bytes += 8; + } else if (typeof value === 'object' && objectList.indexOf(value) === -1) { + objectList.push(value); + for (var i in value) { + stack.push(value[i]); } } } - return bytes + return bytes; } class LocalForageCacheDriver { @@ -47,85 +42,109 @@ class LocalForageCacheDriver { private localCache: any; private _storageQuota: number; - constructor (collection, useLocalCacheByDefault = true, storageQuota = 0) { - const collectionName = collection._config.storeName - const dbName = collection._config.name - this._storageQuota = storageQuota + constructor(collection, useLocalCacheByDefault = true, storageQuota = 0) { + const collectionName = collection._config.storeName; + const dbName = collection._config.name; + this._storageQuota = storageQuota; if (this._storageQuota && !isServer) { - const storageQuota = this._storageQuota - const iterateFnc = this.iterate.bind(this) - const removeItemFnc = this.removeItem.bind(this) + const storageQuota = this._storageQuota; + const iterateFnc = this.iterate.bind(this); + const removeItemFnc = this.removeItem.bind(this); setInterval(() => { - let storageSize = 0 - this.iterate((item, id, number) => { - storageSize += roughSizeOfObject(item) - }, (err, result) => { - if ((storageSize / 1024) > storageQuota) { - Logger.info('Clearing out the storage ', 'cache', { storageSizeKB: Math.round(storageSize / 1024), storageQuotaKB: storageQuota })() - const howManyItemsToRemove = 100 - const keysPurged = [] - iterateFnc((item, id, number) => { - if (number < howManyItemsToRemove) { - removeItemFnc(id) - keysPurged.push(id) - } - }, (err, result) => { - Logger.info('Cache purged', 'cache', { keysPurged })() - }) - } else { - Logger.info('Storage size', 'cache', { storageSizeKB: Math.round(storageSize / 1024) })() + let storageSize = 0; + this.iterate( + (item, id, number) => { + storageSize += roughSizeOfObject(item); + }, + (err, result) => { + if (storageSize / 1024 > storageQuota) { + Logger.info('Clearing out the storage ', 'cache', { + storageSizeKB: Math.round(storageSize / 1024), + storageQuotaKB: storageQuota + })(); + const howManyItemsToRemove = 100; + const keysPurged = []; + iterateFnc( + (item, id, number) => { + if (number < howManyItemsToRemove) { + removeItemFnc(id); + keysPurged.push(id); + } + }, + (err, result) => { + Logger.info('Cache purged', 'cache', { keysPurged })(); + } + ); + } else { + Logger.info('Storage size', 'cache', { + storageSizeKB: Math.round(storageSize / 1024) + })(); + } } - }) - }, 30000) + ); + }, 30000); } if (typeof this.cacheErrorsCount === 'undefined') { - this.cacheErrorsCount = {} + this.cacheErrorsCount = {}; } if (typeof this.cacheErrorsCount[collectionName] === 'undefined') { - this.cacheErrorsCount[collectionName] = 0 + this.cacheErrorsCount[collectionName] = 0; } if (isServer) { - this._localCache = {} + this._localCache = {}; } else { if (typeof Vue.prototype.$localCache === 'undefined') { - Vue.prototype.$localCache = {} + Vue.prototype.$localCache = {}; } if (typeof Vue.prototype.$localCache[dbName] === 'undefined') { - Vue.prototype.$localCache[dbName] = {} + Vue.prototype.$localCache[dbName] = {}; } - if (typeof Vue.prototype.$localCache[dbName][collectionName] === 'undefined') { - Vue.prototype.$localCache[dbName][collectionName] = {} + if ( + typeof Vue.prototype.$localCache[dbName][collectionName] === 'undefined' + ) { + Vue.prototype.$localCache[dbName][collectionName] = {}; } - this._localCache = Vue.prototype.$localCache[dbName][collectionName] + this._localCache = Vue.prototype.$localCache[dbName][collectionName]; } - this._collectionName = collectionName - this._dbName = dbName - this._useLocalCacheByDefault = useLocalCacheByDefault - this._localForageCollection = collection - this._lastError = null - this._persistenceErrorNotified = false + this._collectionName = collectionName; + this._dbName = dbName; + this._useLocalCacheByDefault = useLocalCacheByDefault; + this._localForageCollection = collection; + this._lastError = null; + this._persistenceErrorNotified = false; } // Remove all keys from the datastore, effectively destroying all data in // the app's key/value store! - clear (callback?) { - return this._localForageCollection.clear(callback) + clear(callback?) { + return this._localForageCollection.clear(callback); } // Increment the database version number and recreate the context - recreateDb () { + recreateDb() { if (this._localForageCollection._config) { - const existingConfig = Object.assign({}, this._localForageCollection._config) + const existingConfig = Object.assign( + {}, + this._localForageCollection._config + ); if (existingConfig.storeName) { // localForage.dropInstance(existingConfig) // drop the store and create the new one - const destVersionNumber = this._localForageCollection && this._localForageCollection._dbInfo ? this._localForageCollection._dbInfo.version + 1 : 0 + const destVersionNumber = + this._localForageCollection && this._localForageCollection._dbInfo + ? this._localForageCollection._dbInfo.version + 1 + : 0; if (destVersionNumber > 0) { - this._localForageCollection = localForage.createInstance({ ...existingConfig, version: destVersionNumber }) + this._localForageCollection = localForage.createInstance({ + ...existingConfig, + version: destVersionNumber + }); } else { - this._localForageCollection = localForage.createInstance(existingConfig) + this._localForageCollection = localForage.createInstance( + existingConfig + ); } - Logger.log('DB recreated with', existingConfig, destVersionNumber)() + Logger.log('DB recreated with', existingConfig, destVersionNumber)(); } } } @@ -133,207 +152,287 @@ class LocalForageCacheDriver { // Retrieve an item from the store. Unlike the original async_storage // library in Gaia, we don't modify return values at all. If a key's value // is `undefined`, we pass that value to the callback function. - getItem (key, callback?) { - const isCallbackCallable = (typeof callback !== 'undefined' && callback) - let isResolved = false + getItem(key, callback?) { + const isCallbackCallable = typeof callback !== 'undefined' && callback; + let isResolved = false; if (this._useLocalCacheByDefault && this._localCache[key]) { // Logger.debug('Local cache fallback for GET', key)() return new Promise((resolve, reject) => { - const value = typeof this._localCache[key] !== 'undefined' ? this._localCache[key] : null - if (isCallbackCallable) callback(null, value) - resolve(value) - }) + const value = + typeof this._localCache[key] !== 'undefined' + ? this._localCache[key] + : null; + if (isCallbackCallable) callback(null, value); + resolve(value); + }); } if (!isServer) { - if (this.cacheErrorsCount[this._collectionName] >= DISABLE_PERSISTANCE_AFTER && this._useLocalCacheByDefault) { + if ( + this.cacheErrorsCount[this._collectionName] >= + DISABLE_PERSISTANCE_AFTER && + this._useLocalCacheByDefault + ) { if (!this._persistenceErrorNotified) { - Logger.error('Persistent cache disabled becasue of previous errors [get]', key)() - this._persistenceErrorNotified = true + Logger.error( + 'Persistent cache disabled becasue of previous errors [get]', + key + )(); + this._persistenceErrorNotified = true; } return new Promise((resolve, reject) => { - if (isCallbackCallable) callback(null, null) - resolve(null) - }) + if (isCallbackCallable) callback(null, null); + resolve(null); + }); } else { - const startTime = new Date().getTime() + const startTime = new Date().getTime(); // Logger.debug('No local cache fallback for GET', key)() - const promise = this._localForageCollection.ready().then(() => this._localForageCollection.getItem(key).then(result => { - const endTime = new Date().getTime() - if ((endTime - startTime) >= CACHE_TIMEOUT) { - Logger.error('Cache promise resolved after [ms]' + key + (endTime - startTime))() - } - if (!this._localCache[key] && result) { - this._localCache[key] = result // populate the local cache for the next call - } - if (!isResolved) { - if (isCallbackCallable) { - callback(null, result) - } - isResolved = true - } else { - Logger.debug('Skipping return value as it was previously resolved')() - } - return result - }).catch(err => { - this._lastError = err - if (!isResolved) { - if (isCallbackCallable) callback(null, typeof this._localCache[key] !== 'undefined' ? this._localCache[key] : null) - } - Logger.error(err)() - isResolved = true - })) + const promise = this._localForageCollection.ready().then(() => + this._localForageCollection + .getItem(key) + .then(result => { + const endTime = new Date().getTime(); + if (endTime - startTime >= CACHE_TIMEOUT) { + Logger.error( + 'Cache promise resolved after [ms]' + + key + + (endTime - startTime) + )(); + } + if (!this._localCache[key] && result) { + this._localCache[key] = result; // populate the local cache for the next call + } + if (!isResolved) { + if (isCallbackCallable) { + callback(null, result); + } + isResolved = true; + } else { + Logger.debug( + 'Skipping return value as it was previously resolved' + )(); + } + return result; + }) + .catch(err => { + this._lastError = err; + if (!isResolved) { + if (isCallbackCallable) + callback( + null, + typeof this._localCache[key] !== 'undefined' + ? this._localCache[key] + : null + ); + } + Logger.error(err)(); + isResolved = true; + }) + ); setTimeout(() => { - if (!isResolved) { // this is cache time out check + if (!isResolved) { + // this is cache time out check if (!this._persistenceErrorNotified) { - Logger.error('Cache not responding for ' + key + '.', 'cache', { timeout: CACHE_TIMEOUT, errorsCount: this.cacheErrorsCount[this._collectionName] })() - this._persistenceErrorNotified = true - this.recreateDb() + Logger.error('Cache not responding for ' + key + '.', 'cache', { + timeout: CACHE_TIMEOUT, + errorsCount: this.cacheErrorsCount[this._collectionName] + })(); + this._persistenceErrorNotified = true; + this.recreateDb(); } - this.cacheErrorsCount[this._collectionName] = this.cacheErrorsCount[this._collectionName] ? this.cacheErrorsCount[this._collectionName] + 1 : 1 - if (isCallbackCallable) callback(null, typeof this._localCache[key] !== 'undefined' ? this._localCache[key] : null) + this.cacheErrorsCount[this._collectionName] = this.cacheErrorsCount[ + this._collectionName + ] + ? this.cacheErrorsCount[this._collectionName] + 1 + : 1; + if (isCallbackCallable) + callback( + null, + typeof this._localCache[key] !== 'undefined' + ? this._localCache[key] + : null + ); } - }, CACHE_TIMEOUT) - return promise + }, CACHE_TIMEOUT); + return promise; } } else { return new Promise((resolve, reject) => { - const value = typeof this._localCache[key] !== 'undefined' ? this._localCache[key] : null - if (isCallbackCallable) callback(null, value) - resolve(value) - }) + const value = + typeof this._localCache[key] !== 'undefined' + ? this._localCache[key] + : null; + if (isCallbackCallable) callback(null, value); + resolve(value); + }); } } // Iterate over all items in the store. - iterate (iterator, callback?) { - const isIteratorCallable = (typeof iterator !== 'undefined' && iterator) - const isCallbackCallable = (typeof callback !== 'undefined' && callback) - let globalIterationNumber = 1 + iterate(iterator, callback?) { + const isIteratorCallable = typeof iterator !== 'undefined' && iterator; + const isCallbackCallable = typeof callback !== 'undefined' && callback; + let globalIterationNumber = 1; if (this._useLocalCacheByDefault) { // Logger.debug('Local cache iteration')() for (const localKey in this._localCache) { if (isIteratorCallable) { - iterator(this._localCache[localKey], localKey, globalIterationNumber) - globalIterationNumber++ + iterator(this._localCache[localKey], localKey, globalIterationNumber); + globalIterationNumber++; } } } - let isResolved = false - const promise = this._localForageCollection.ready().then(() => this._localForageCollection.iterate((value, key, iterationNumber) => { - isResolved = true - if (isIteratorCallable) { - if (this._useLocalCacheByDefault) { - if (typeof this._localCache[key] === 'undefined') { - iterator(value, key, globalIterationNumber) - globalIterationNumber++ - } else { - // Logger.debug('Skipping iteration key because local cache executed', key)() + let isResolved = false; + const promise = this._localForageCollection + .ready() + .then(() => + this._localForageCollection.iterate( + (value, key, iterationNumber) => { + isResolved = true; + if (isIteratorCallable) { + if (this._useLocalCacheByDefault) { + if (typeof this._localCache[key] === 'undefined') { + iterator(value, key, globalIterationNumber); + globalIterationNumber++; + } else { + // Logger.debug('Skipping iteration key because local cache executed', key)() + } + } else { + iterator(value, key, iterationNumber); + } + } + }, + (err, result) => { + if (isCallbackCallable) callback(err, result); + isResolved = true; } - } else { - iterator(value, key, iterationNumber) + ) + ) + .catch(err => { + this._lastError = err; + Logger.error(err)(); + if (!isResolved) { + isResolved = true; + if (isCallbackCallable) callback(err, null); } - } - }, (err, result) => { - if (isCallbackCallable) callback(err, result) - isResolved = true - })).catch(err => { - this._lastError = err - Logger.error(err)() - if (!isResolved) { - isResolved = true - if (isCallbackCallable) callback(err, null) - } - }) + }); setTimeout(() => { - if (!isResolved) { // this is cache time out check + if (!isResolved) { + // this is cache time out check if (!this._persistenceErrorNotified) { - Logger.error('Cache not responding. (iterate)', 'cache', { timeout: CACHE_TIMEOUT, errorsCount: this.cacheErrorsCount[this._collectionName] })() - this._persistenceErrorNotified = true - this.recreateDb() + Logger.error('Cache not responding. (iterate)', 'cache', { + timeout: CACHE_TIMEOUT, + errorsCount: this.cacheErrorsCount[this._collectionName] + })(); + this._persistenceErrorNotified = true; + this.recreateDb(); } - this.cacheErrorsCount[this._collectionName] = this.cacheErrorsCount[this._collectionName] ? this.cacheErrorsCount[this._collectionName] + 1 : 1 - if (isCallbackCallable) callback(null, null) + this.cacheErrorsCount[this._collectionName] = this.cacheErrorsCount[ + this._collectionName + ] + ? this.cacheErrorsCount[this._collectionName] + 1 + : 1; + if (isCallbackCallable) callback(null, null); } - }, CACHE_TIMEOUT_ITERATE) - return promise + }, CACHE_TIMEOUT_ITERATE); + return promise; } // Same as localStorage's key() method, except takes a callback. - key (n, callback?) { - return this._localForageCollection.key(n, callback) + key(n, callback?) { + return this._localForageCollection.key(n, callback); } - keys (callback?) { - return this._localForageCollection.keys(callback) + keys(callback?) { + return this._localForageCollection.keys(callback); } // Supply the number of keys in the datastore to the callback function. - length (callback?) { - return this._localForageCollection.length(callback) + length(callback?) { + return this._localForageCollection.length(callback); } // Remove an item from the store, nice and simple. - removeItem (key, callback?) { + removeItem(key, callback?) { if (typeof this._localCache[key] !== 'undefined') { - delete this._localCache[key] + delete this._localCache[key]; } - return this._localForageCollection.removeItem(key, callback) + return this._localForageCollection.removeItem(key, callback); } // Set a key's value and run an optional callback once the value is set. // Unlike Gaia's implementation, the callback function is passed the value, // in case you want to operate on that value only after you're sure it // saved, or something like that. - setItem (key, value, callback?, memoryOnly = false) { - const isCallbackCallable = (typeof callback !== 'undefined' && callback) - this._localCache[key] = value + setItem(key, value, callback?, memoryOnly = false) { + const isCallbackCallable = typeof callback !== 'undefined' && callback; + this._localCache[key] = value; if (memoryOnly) { return new Promise((resolve, reject) => { - if (isCallbackCallable) callback(null, null) - resolve(null) - }) + if (isCallbackCallable) callback(null, null); + resolve(null); + }); } if (!isServer) { - if (this.cacheErrorsCount[this._collectionName] >= DISABLE_PERSISTANCE_AFTER_SAVE && this._useLocalCacheByDefault) { + if ( + this.cacheErrorsCount[this._collectionName] >= + DISABLE_PERSISTANCE_AFTER_SAVE && + this._useLocalCacheByDefault + ) { if (!this._persistenceErrorNotified) { - Logger.error('Persistent cache disabled becasue of previous errors [set]', key)() - this._persistenceErrorNotified = true + Logger.error( + 'Persistent cache disabled becasue of previous errors [set]', + key + )(); + this._persistenceErrorNotified = true; } return new Promise((resolve, reject) => { - if (isCallbackCallable) callback(null, null) - resolve(null) - }) + if (isCallbackCallable) callback(null, null); + resolve(null); + }); } else { - let isResolved = false - const promise = this._localForageCollection.ready().then(() => this._localForageCollection.setItem(key, value).then(result => { - if (isCallbackCallable) { - callback(null, result) - } - isResolved = true - }).catch(err => { - isResolved = true - this._lastError = err - })) + let isResolved = false; + const promise = this._localForageCollection.ready().then(() => + this._localForageCollection + .setItem(key, value) + .then(result => { + if (isCallbackCallable) { + callback(null, result); + } + isResolved = true; + }) + .catch(err => { + isResolved = true; + this._lastError = err; + }) + ); setTimeout(() => { - if (!isResolved) { // this is cache time out check + if (!isResolved) { + // this is cache time out check if (!this._persistenceErrorNotified) { - Logger.error('Cache not responding for ' + key + '.', 'cache', { timeout: CACHE_TIMEOUT, errorsCount: this.cacheErrorsCount[this._collectionName] })() - this._persistenceErrorNotified = true - this.recreateDb() + Logger.error('Cache not responding for ' + key + '.', 'cache', { + timeout: CACHE_TIMEOUT, + errorsCount: this.cacheErrorsCount[this._collectionName] + })(); + this._persistenceErrorNotified = true; + this.recreateDb(); } - this.cacheErrorsCount[this._collectionName] = this.cacheErrorsCount[this._collectionName] ? this.cacheErrorsCount[this._collectionName] + 1 : 1 - if (isCallbackCallable) callback(null, null) + this.cacheErrorsCount[this._collectionName] = this.cacheErrorsCount[ + this._collectionName + ] + ? this.cacheErrorsCount[this._collectionName] + 1 + : 1; + if (isCallbackCallable) callback(null, null); } - }, CACHE_TIMEOUT) - return promise + }, CACHE_TIMEOUT); + return promise; } } else { - return new Promise((resolve, reject) => resolve()) + return new Promise((resolve, reject) => resolve()); } } } // The actual localForage object that we expose as a module. It's extended by pulling in one of our other libraries. -export default LocalForageCacheDriver +export default LocalForageCacheDriver; diff --git a/core/types/RootState.ts b/core/types/RootState.ts index 515d3fc781..2bd9070d34 100644 --- a/core/types/RootState.ts +++ b/core/types/RootState.ts @@ -1,35 +1,35 @@ export default interface RootState { - version: string, - __DEMO_MODE__: boolean, - config: any, - cart: any, - checkout: any, - cms: any, - compare: any, - product: any, - shipping: any, - user: any, - wishlist: any, - attribute: string, - ui: any, + version: string; + __DEMO_MODE__: boolean; + config: any; + cart: any; + checkout: any; + cms: any; + compare: any; + product: any; + shipping: any; + user: any; + wishlist: any; + attribute: string; + ui: any; category: { - current_path: string, - current_product_query: any, + current_path: string; + current_product_query: any; current: { - slug: string, - name: string - }, - filters: any - }, + slug: string; + name: string; + }; + filters: any; + }; stock: { - cache: any - }, - storeView: any, - twoStageCachingDelta1: number, - twoStageCachingDelta2: number, - twoStageCachingDisabled: boolean, - userTokenInvalidated: string | null, - userTokenInvalidateAttemptsCount: number, - userTokenInvalidateLock: number, - route?: any + cache: any; + }; + storeView: any; + twoStageCachingDelta1: number; + twoStageCachingDelta2: number; + twoStageCachingDisabled: boolean; + userTokenInvalidated: string | null; + userTokenInvalidateAttemptsCount: number; + userTokenInvalidateLock: number; + route?: any; } diff --git a/core/types/isomorphic-fetch.d.ts b/core/types/isomorphic-fetch.d.ts index c6df7604f5..5a7458ed47 100644 --- a/core/types/isomorphic-fetch.d.ts +++ b/core/types/isomorphic-fetch.d.ts @@ -3,4 +3,4 @@ declare const fet: typeof fetch; declare module 'isomorphic-fetch' { export const fetch: typeof fet; export default fetch; -} \ No newline at end of file +} diff --git a/core/types/search/HttpQuery.ts b/core/types/search/HttpQuery.ts index 7b5b6c125a..e1f155893f 100644 --- a/core/types/search/HttpQuery.ts +++ b/core/types/search/HttpQuery.ts @@ -1,9 +1,9 @@ export default interface HttpQuery { - q?: string - size: number - from: number - sort: string - request?: string, - _source_exclude?: string - _source_include?: string + q?: string; + size: number; + from: number; + sort: string; + request?: string; + _source_exclude?: string; + _source_include?: string; } diff --git a/core/types/search/SearchRequest.ts b/core/types/search/SearchRequest.ts index 68c09ff5c7..f57d3b115d 100644 --- a/core/types/search/SearchRequest.ts +++ b/core/types/search/SearchRequest.ts @@ -1,16 +1,14 @@ interface SearchRequest { - store: any - type: string - searchQuery: any - size: number - groupId: any - groupToken: any - from: number - sort: string - _sourceExclude?: string - _sourceInclude?: string + store: any; + type: string; + searchQuery: any; + size: number; + groupId: any; + groupToken: any; + from: number; + sort: string; + _sourceExclude?: string; + _sourceInclude?: string; } -export { - SearchRequest -} \ No newline at end of file +export { SearchRequest }; diff --git a/core/types/search/SearchResponse.ts b/core/types/search/SearchResponse.ts index e4741970a1..035f3e4ef8 100644 --- a/core/types/search/SearchResponse.ts +++ b/core/types/search/SearchResponse.ts @@ -1,14 +1,12 @@ interface SearchResponse { - items: any[] - total: number - start: number - perPage: number - aggregations: any - offline?: boolean - cache?: boolean - noresults?: boolean + items: any[]; + total: number; + start: number; + perPage: number; + aggregations: any; + offline?: boolean; + cache?: boolean; + noresults?: boolean; } -export { - SearchResponse -} \ No newline at end of file +export { SearchResponse }; diff --git a/src/extensions/index.ts b/src/extensions/index.ts index 1d86667f29..097a4add57 100644 --- a/src/extensions/index.ts +++ b/src/extensions/index.ts @@ -1,5 +1,5 @@ -/** +/** * If you have some extensions that are not yet ported to modules you can register them here * Keep in mind that extensions will be depreciated in next versions of Vue Storefront and replaced by modules */ -export const registerExtensions = [] \ No newline at end of file +export const registerExtensions = []; diff --git a/src/modules/amp-renderer/index.ts b/src/modules/amp-renderer/index.ts index 62c73494e9..a9fb741292 100644 --- a/src/modules/amp-renderer/index.ts +++ b/src/modules/amp-renderer/index.ts @@ -1,15 +1,15 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import moduleRoutes from './router' +import { createModule } from '@vue-storefront/core/lib/module'; +import moduleRoutes from './router'; const store = { namespaced: true, state: { key: null } -} -const KEY = 'amp-renderer' +}; +const KEY = 'amp-renderer'; export const AmpRenderer = createModule({ key: KEY, router: { routes: moduleRoutes }, store: { modules: [{ key: KEY, module: store }] } -}) \ No newline at end of file +}); diff --git a/src/modules/amp-renderer/router.ts b/src/modules/amp-renderer/router.ts index 0ce737dbd9..b14dae3cf4 100644 --- a/src/modules/amp-renderer/router.ts +++ b/src/modules/amp-renderer/router.ts @@ -1,2 +1,2 @@ -import AmpThemeRouting from 'src/themes/default-amp/router' -export default AmpThemeRouting \ No newline at end of file +import AmpThemeRouting from 'src/themes/default-amp/router'; +export default AmpThemeRouting; diff --git a/src/modules/claims/hooks/beforeRegistration.ts b/src/modules/claims/hooks/beforeRegistration.ts index 1f78a3f085..13fa76eafd 100644 --- a/src/modules/claims/hooks/beforeRegistration.ts +++ b/src/modules/claims/hooks/beforeRegistration.ts @@ -1,14 +1,16 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import * as localForage from 'localforage'; +import UniversalStorage from '@vue-storefront/core/store/lib/storage'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function beforeRegistration({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + const storeView = currentStoreView(); + const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''; - Vue.prototype.$db.claimsCollection = new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'claims', - driver: localForage[config.localForage.defaultDrivers['claims']] - })) -} \ No newline at end of file + Vue.prototype.$db.claimsCollection = new UniversalStorage( + localForage.createInstance({ + name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', + storeName: 'claims', + driver: localForage[config.localForage.defaultDrivers['claims']] + }) + ); +} diff --git a/src/modules/claims/index.ts b/src/modules/claims/index.ts index 7bc7cef9bf..295b694aea 100644 --- a/src/modules/claims/index.ts +++ b/src/modules/claims/index.ts @@ -1,11 +1,11 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { module } from './store' +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { module } from './store'; -const KEY = 'claims' +const KEY = 'claims'; export const Claims = createModule({ key: KEY, - store: { modules: [{ key: KEY, module }]}, + store: { modules: [{ key: KEY, module }] }, beforeRegistration -}) \ No newline at end of file +}); diff --git a/src/modules/claims/store/actions.ts b/src/modules/claims/store/actions.ts index 54180bcfb2..3fef8542cf 100644 --- a/src/modules/claims/store/actions.ts +++ b/src/modules/claims/store/actions.ts @@ -1,35 +1,37 @@ -import Vue from 'vue' -import { ActionTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import ClaimsState from '../types/ClaimsState' -import { Logger } from '@vue-storefront/core/lib/logger' +import Vue from 'vue'; +import { ActionTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import ClaimsState from '../types/ClaimsState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { - set (context, { claimCode, value, description }) { - const claimCollection = Vue.prototype.$db.claimsCollection - claimCollection.setItem(claimCode, { - code: claimCode, - created_at: new Date(), - value: value, - description: description - }).catch((reason) => { - Logger.error(reason) // it doesn't work on SSR - }) + set(context, { claimCode, value, description }) { + const claimCollection = Vue.prototype.$db.claimsCollection; + claimCollection + .setItem(claimCode, { + code: claimCode, + created_at: new Date(), + value: value, + description: description + }) + .catch(reason => { + Logger.error(reason); // it doesn't work on SSR + }); }, - unset (context, { claimCode }) { - const claimCollection = Vue.prototype.$db.claimsCollection - claimCollection.removeItem(claimCode).catch((reason) => { - Logger.error(reason) // it doesn't work on SSR - }) + unset(context, { claimCode }) { + const claimCollection = Vue.prototype.$db.claimsCollection; + claimCollection.removeItem(claimCode).catch(reason => { + Logger.error(reason); // it doesn't work on SSR + }); }, - check (context, { claimCode }) { - const claimCollection = Vue.prototype.$db.claimsCollection - return claimCollection.getItem(claimCode).catch((reason) => { - Logger.error(reason) // it doesn't work on SSR - }) + check(context, { claimCode }) { + const claimCollection = Vue.prototype.$db.claimsCollection; + return claimCollection.getItem(claimCode).catch(reason => { + Logger.error(reason); // it doesn't work on SSR + }); } -} +}; -export default actions +export default actions; diff --git a/src/modules/claims/store/index.ts b/src/modules/claims/store/index.ts index d08aa63558..52b558c314 100644 --- a/src/modules/claims/store/index.ts +++ b/src/modules/claims/store/index.ts @@ -1,10 +1,9 @@ -import { Module } from 'vuex' -import actions from './actions' -import RootState from '@vue-storefront/core/types/RootState' -import ClaimsState from '../types/ClaimsState' +import { Module } from 'vuex'; +import actions from './actions'; +import RootState from '@vue-storefront/core/types/RootState'; +import ClaimsState from '../types/ClaimsState'; export const module: Module = { namespaced: true, actions -} - +}; diff --git a/src/modules/claims/types/ClaimsState.ts b/src/modules/claims/types/ClaimsState.ts index b64f0f2b4a..d92ed4a45b 100644 --- a/src/modules/claims/types/ClaimsState.ts +++ b/src/modules/claims/types/ClaimsState.ts @@ -1,2 +1 @@ -export default interface ClaimsState { -} \ No newline at end of file +export default interface ClaimsState {} diff --git a/src/modules/droppoint-shipping/components/DroppointMap.vue b/src/modules/droppoint-shipping/components/DroppointMap.vue index 3b4f8835dd..ea99889c49 100644 --- a/src/modules/droppoint-shipping/components/DroppointMap.vue +++ b/src/modules/droppoint-shipping/components/DroppointMap.vue @@ -1,25 +1,37 @@ diff --git a/src/modules/droppoint-shipping/index.ts b/src/modules/droppoint-shipping/index.ts index 0accfc0bcf..fc8d401870 100644 --- a/src/modules/droppoint-shipping/index.ts +++ b/src/modules/droppoint-shipping/index.ts @@ -1,8 +1,8 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { module } from './store' +import { createModule } from '@vue-storefront/core/lib/module'; +import { module } from './store'; -export const KEY = 'droppoint-shipping' +export const KEY = 'droppoint-shipping'; export const DroppointShipping = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] }, -}) + key: KEY, + store: { modules: [{ key: KEY, module }] } +}); diff --git a/src/modules/droppoint-shipping/store/actions.ts b/src/modules/droppoint-shipping/store/actions.ts index 2ae4a1fe6e..ad2c6a8758 100644 --- a/src/modules/droppoint-shipping/store/actions.ts +++ b/src/modules/droppoint-shipping/store/actions.ts @@ -1,14 +1,12 @@ import { ActionTree } from 'vuex'; -import { execute as taskExecute } from '@vue-storefront/core/lib/sync/task' -import * as entities from '@vue-storefront/core/store/lib/entities' +import { execute as taskExecute } from '@vue-storefront/core/lib/sync/task'; +import * as entities from '@vue-storefront/core/store/lib/entities'; // actions export const actions: ActionTree = { - fetch ({ commit }, request) { - const taskId = entities.uniqueEntityId(request) - request.task_id = taskId.toString() - return taskExecute(request) + fetch({ commit }, request) { + const taskId = entities.uniqueEntityId(request); + request.task_id = taskId.toString(); + return taskExecute(request); } -} - - +}; diff --git a/src/modules/droppoint-shipping/store/index.ts b/src/modules/droppoint-shipping/store/index.ts index 2db1f9fcff..34feb64a93 100644 --- a/src/modules/droppoint-shipping/store/index.ts +++ b/src/modules/droppoint-shipping/store/index.ts @@ -1,7 +1,7 @@ -import { Module } from 'vuex' -import { actions } from './actions' +import { Module } from 'vuex'; +import { actions } from './actions'; export const module: Module = { namespaced: true, - actions, -} + actions +}; diff --git a/src/modules/google-analytics/hooks/afterRegistration.ts b/src/modules/google-analytics/hooks/afterRegistration.ts index 7d0f29fef6..74db970ac3 100644 --- a/src/modules/google-analytics/hooks/afterRegistration.ts +++ b/src/modules/google-analytics/hooks/afterRegistration.ts @@ -1,8 +1,8 @@ -export function afterRegistration ({ Vue, config, store, isServer }) { +export function afterRegistration({ Vue, config, store, isServer }) { if (config.analytics.id && !isServer) { Vue.prototype.$bus.$on('order-after-placed', event => { - const order = event.order - const ecommerce = (Vue as any).$ga.ecommerce + const order = event.order; + const ecommerce = (Vue as any).$ga.ecommerce; order.products.forEach(product => { ecommerce.addItem({ @@ -12,9 +12,9 @@ export function afterRegistration ({ Vue, config, store, isServer }) { category: product.category ? product.category[0].name : '', price: product.price.toString(), quantity: product.qty.toString() - }) - }) - ecommerce.send() - }) + }); + }); + ecommerce.send(); + }); } } diff --git a/src/modules/google-analytics/hooks/beforeRegistration.ts b/src/modules/google-analytics/hooks/beforeRegistration.ts index 05e18778f3..b59f5089e0 100644 --- a/src/modules/google-analytics/hooks/beforeRegistration.ts +++ b/src/modules/google-analytics/hooks/beforeRegistration.ts @@ -1,7 +1,7 @@ -import VueAnalytics from 'vue-analytics' -import { router } from '@vue-storefront/core/app' -import { Logger } from '@vue-storefront/core/lib/logger' -import { once } from '@vue-storefront/core/helpers' +import VueAnalytics from 'vue-analytics'; +import { router } from '@vue-storefront/core/app'; +import { Logger } from '@vue-storefront/core/lib/logger'; +import { once } from '@vue-storefront/core/helpers'; export function beforeRegistration({ Vue, config, store, isServer }) { if (config.analytics.id && !isServer) { @@ -12,12 +12,12 @@ export function beforeRegistration({ Vue, config, store, isServer }) { ecommerce: { enabled: true } - }) - }) + }); + }); } else { Logger.warn( 'Google Analytics extension is not working. Ensure Google Analytics account ID is defined in config', 'GA' - )() + )(); } } diff --git a/src/modules/google-analytics/index.ts b/src/modules/google-analytics/index.ts index ed71c4e021..e4ff1eb042 100644 --- a/src/modules/google-analytics/index.ts +++ b/src/modules/google-analytics/index.ts @@ -1,18 +1,18 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; const store = { namespaced: true, state: { key: null } -} +}; -const KEY = 'google-analytics' +const KEY = 'google-analytics'; export const GoogleAnalytics = createModule({ key: KEY, store: { modules: [{ key: KEY, module: store }] }, beforeRegistration, afterRegistration -}) \ No newline at end of file +}); diff --git a/src/modules/google-tag-manager/hooks/afterRegistration.ts b/src/modules/google-tag-manager/hooks/afterRegistration.ts index 1f30a27ab9..65c932d76e 100644 --- a/src/modules/google-tag-manager/hooks/afterRegistration.ts +++ b/src/modules/google-tag-manager/hooks/afterRegistration.ts @@ -1,34 +1,38 @@ -import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; export function afterRegistration(Vue, config, store, isServer) { if (config.googleTagManager.id && !isServer) { - const storeView = currentStoreView(), - currencyCode = storeView.i18n.currencyCode + currencyCode = storeView.i18n.currencyCode; - const getProduct = (item) => { - const { name, id, sku, priceInclTax: price, category: category, qty: quantity } = item + const getProduct = item => { + const { + name, + id, + sku, + priceInclTax: price, + category: category, + qty: quantity + } = item; let product = { name, id, sku, price - } + }; if (quantity) { - product['quantity'] = quantity + product['quantity'] = quantity; } if (category && category.length > 0) { - product['category'] = category.slice(-1)[0].name + product['category'] = category.slice(-1)[0].name; } - return product - } + return product; + }; store.subscribe(({ type, payload }, state) => { - // Adding a Product to a Shopping Cart if (type === 'cart/cart/ADD') { - Vue.gtm.trackEvent({ event: 'addToCart', ecommerce: { @@ -54,12 +58,11 @@ export function afterRegistration(Vue, config, store, isServer) { // Measuring Views of Product Details if (type === 'product/product/SET_PRODUCT_CURRENT') { - Vue.gtm.trackEvent({ ecommerce: { detail: { - 'actionField': { 'list': '' },// 'detail' actions have an optional list property. - 'products': [getProduct(payload)] + actionField: { list: '' }, // 'detail' actions have an optional list property. + products: [getProduct(payload)] } } }); @@ -67,34 +70,36 @@ export function afterRegistration(Vue, config, store, isServer) { // Measuring Purchases if (type === 'order/order/LAST_ORDER_CONFIRMATION') { - const orderId = payload.confirmation.backendOrderId - const products = payload.order.products.map(product => getProduct(product)) - store.dispatch( - 'user/getOrdersHistory', - { refresh: true, useCache: false } - ).then(() => { - const orderHistory = state.user.orders_history - const order = orderHistory.items.find((order) => order['entity_id'].toString() === orderId) - if (order) { - Vue.gtm.trackEvent({ - 'ecommerce': { - 'purchase': { - 'actionField': { - 'id': orderId, - 'affiliation': order.store_name, - 'revenue': order.total_due, - 'tax': order.tax_amount, - 'shipping': order.shipping_amount, - 'coupon': '' - }, - 'products': products + const orderId = payload.confirmation.backendOrderId; + const products = payload.order.products.map(product => + getProduct(product) + ); + store + .dispatch('user/getOrdersHistory', { refresh: true, useCache: false }) + .then(() => { + const orderHistory = state.user.orders_history; + const order = orderHistory.items.find( + order => order['entity_id'].toString() === orderId + ); + if (order) { + Vue.gtm.trackEvent({ + ecommerce: { + purchase: { + actionField: { + id: orderId, + affiliation: order.store_name, + revenue: order.total_due, + tax: order.tax_amount, + shipping: order.shipping_amount, + coupon: '' + }, + products: products + } } - } - }) - } - }) + }); + } + }); } - - }) + }); } } diff --git a/src/modules/google-tag-manager/hooks/beforeRegistration.ts b/src/modules/google-tag-manager/hooks/beforeRegistration.ts index e55d221abb..325886e4c5 100644 --- a/src/modules/google-tag-manager/hooks/beforeRegistration.ts +++ b/src/modules/google-tag-manager/hooks/beforeRegistration.ts @@ -1,15 +1,18 @@ import VueGtm from 'vue-gtm'; -import { router } from '@vue-storefront/core/app' -import { Logger } from '@vue-storefront/core/lib/logger' +import { router } from '@vue-storefront/core/app'; +import { Logger } from '@vue-storefront/core/lib/logger'; export function beforeRegistration(Vue, config, store, isServer) { if (config.googleTagManager.id && !isServer) { - Vue.use(VueGtm, { - id: config.googleTagManager.id, - enabled: true, - debug: config.googleTagManager.debug, - vueRouter: router, - }); - } else { - Logger.warn('Google Tag Manager extensions is not working. Ensure Google Tag Manager container ID is defined in config', 'GTM')() - } + Vue.use(VueGtm, { + id: config.googleTagManager.id, + enabled: true, + debug: config.googleTagManager.debug, + vueRouter: router + }); + } else { + Logger.warn( + 'Google Tag Manager extensions is not working. Ensure Google Tag Manager container ID is defined in config', + 'GTM' + )(); + } } diff --git a/src/modules/google-tag-manager/index.ts b/src/modules/google-tag-manager/index.ts index c670f216c3..7f2787dc03 100644 --- a/src/modules/google-tag-manager/index.ts +++ b/src/modules/google-tag-manager/index.ts @@ -1,21 +1,24 @@ -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import { + VueStorefrontModule, + VueStorefrontModuleConfig +} from '@vue-storefront/core/lib/module'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; const store = { namespaced: true, state: { key: null } -} +}; -const KEY = 'google-tag-manager' +const KEY = 'google-tag-manager'; const moduleConfig: VueStorefrontModuleConfig = { key: KEY, store: { modules: [{ key: KEY, module: store }] }, beforeRegistration, afterRegistration -} +}; -export const googleTagManager = new VueStorefrontModule(moduleConfig) +export const googleTagManager = new VueStorefrontModule(moduleConfig); diff --git a/src/modules/homepage/index.ts b/src/modules/homepage/index.ts index 4b61597b55..9169d907cc 100644 --- a/src/modules/homepage/index.ts +++ b/src/modules/homepage/index.ts @@ -1,14 +1,14 @@ -import { createModule } from '@vue-storefront/core/lib/module' +import { createModule } from '@vue-storefront/core/lib/module'; // TODO: Move the logic to appropriate modules and depreciate this one -const KEY = 'homepage' +const KEY = 'homepage'; const store = { namespaced: true, state: { new_collection: [] } -} +}; export const Homepage = createModule({ key: KEY, store: { modules: [{ key: KEY, module: store }] } -}) \ No newline at end of file +}); diff --git a/src/modules/hotjar/hooks/afterRegistration.ts b/src/modules/hotjar/hooks/afterRegistration.ts index 2fde5fe043..f102ac4833 100644 --- a/src/modules/hotjar/hooks/afterRegistration.ts +++ b/src/modules/hotjar/hooks/afterRegistration.ts @@ -1,16 +1,17 @@ -const hotjarSnippet = (hjid) => (function (h, o, t, j, a, r) { - h.hj = - h.hj || - function () { - (h.hj.q = h.hj.q || []).push(arguments); - }; - h._hjSettings = {hjid, hjsv: 6}; - a = o.getElementsByTagName('head')[0]; - r = o.createElement('script'); - r.async = 1; - r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv; - a.appendChild(r); -})(window as any, document, '//static.hotjar.com/c/hotjar-', '.js?sv='); +const hotjarSnippet = hjid => + (function(h, o, t, j, a, r) { + h.hj = + h.hj || + function() { + (h.hj.q = h.hj.q || []).push(arguments); + }; + h._hjSettings = { hjid, hjsv: 6 }; + a = o.getElementsByTagName('head')[0]; + r = o.createElement('script'); + r.async = 1; + r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv; + a.appendChild(r); + })(window as any, document, '//static.hotjar.com/c/hotjar-', '.js?sv='); export function afterRegistration({ Vue, config, store, isServer }) { if (!isServer && config.hotjar && config.hotjar.id) { diff --git a/src/modules/hotjar/index.ts b/src/modules/hotjar/index.ts index 9492527b53..c36ad02485 100644 --- a/src/modules/hotjar/index.ts +++ b/src/modules/hotjar/index.ts @@ -1,5 +1,5 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' +import { createModule } from '@vue-storefront/core/lib/module'; +import { afterRegistration } from './hooks/afterRegistration'; const store = { namespaced: true, diff --git a/src/modules/index.ts b/src/modules/index.ts index 2746a6d0ed..823321fe52 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -1,29 +1,29 @@ // import { extendModule } from '@vue-storefront/core/lib/module' -import { VueStorefrontModule } from '@vue-storefront/core/lib/module' -import { Catalog } from "@vue-storefront/core/modules/catalog" -import { Cart } from '@vue-storefront/core/modules/cart' -import { Checkout } from '@vue-storefront/core/modules/checkout' -import { Compare } from '@vue-storefront/core/modules/compare' -import { Review } from '@vue-storefront/core/modules/review' -import { Mailer } from '@vue-storefront/core/modules/mailer' -import { Wishlist } from '@vue-storefront/core/modules/wishlist' -import { Mailchimp } from '../modules/mailchimp' -import { Notification } from '@vue-storefront/core/modules/notification' -import { RecentlyViewed } from '@vue-storefront/core/modules/recently-viewed' -import { Url } from '@vue-storefront/core/modules/url' -import { Homepage } from "./homepage" -import { Claims } from './claims' -import { PromotedOffers } from './promoted-offers' -import { Ui } from './ui-store' +import { VueStorefrontModule } from '@vue-storefront/core/lib/module'; +import { Catalog } from '@vue-storefront/core/modules/catalog'; +import { Cart } from '@vue-storefront/core/modules/cart'; +import { Checkout } from '@vue-storefront/core/modules/checkout'; +import { Compare } from '@vue-storefront/core/modules/compare'; +import { Review } from '@vue-storefront/core/modules/review'; +import { Mailer } from '@vue-storefront/core/modules/mailer'; +import { Wishlist } from '@vue-storefront/core/modules/wishlist'; +import { Mailchimp } from '../modules/mailchimp'; +import { Notification } from '@vue-storefront/core/modules/notification'; +import { RecentlyViewed } from '@vue-storefront/core/modules/recently-viewed'; +import { Url } from '@vue-storefront/core/modules/url'; +import { Homepage } from './homepage'; +import { Claims } from './claims'; +import { PromotedOffers } from './promoted-offers'; +import { Ui } from './ui-store'; // import { GoogleAnalytics } from './google-analytics'; // import { Hotjar } from './hotjar'; import { googleTagManager } from './google-tag-manager'; import { AmpRenderer } from './amp-renderer'; import { PaymentBackendMethods } from './payment-backend-methods'; import { PaymentCashOnDelivery } from './payment-cash-on-delivery'; -import { RawOutputExample } from './raw-output-example' -import { Magento2CMS } from './magento-2-cms' -import { InstantCheckout } from './instant-checkout' +import { RawOutputExample } from './raw-output-example'; +import { Magento2CMS } from './magento-2-cms'; +import { InstantCheckout } from './instant-checkout'; // import { Example } from './module-template' @@ -76,6 +76,6 @@ export const registerModules: VueStorefrontModule[] = [ RawOutputExample, AmpRenderer, InstantCheckout, - Url, + Url // Example -] +]; diff --git a/src/modules/instant-checkout/components/InstantCheckout.vue b/src/modules/instant-checkout/components/InstantCheckout.vue index eb575ef346..3eb542419b 100644 --- a/src/modules/instant-checkout/components/InstantCheckout.vue +++ b/src/modules/instant-checkout/components/InstantCheckout.vue @@ -1,24 +1,23 @@ diff --git a/src/modules/instant-checkout/index.ts b/src/modules/instant-checkout/index.ts index 7448408b84..0a0c717c26 100644 --- a/src/modules/instant-checkout/index.ts +++ b/src/modules/instant-checkout/index.ts @@ -1,9 +1,12 @@ -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' +import { + VueStorefrontModule, + VueStorefrontModuleConfig +} from '@vue-storefront/core/lib/module'; -const KEY = 'instant-checkout' +const KEY = 'instant-checkout'; const moduleConfig: VueStorefrontModuleConfig = { key: KEY -} +}; -export const InstantCheckout = new VueStorefrontModule(moduleConfig) \ No newline at end of file +export const InstantCheckout = new VueStorefrontModule(moduleConfig); diff --git a/src/modules/magento-2-cms/components/CmsData.vue b/src/modules/magento-2-cms/components/CmsData.vue index 6f916c22c1..e3274b3520 100644 --- a/src/modules/magento-2-cms/components/CmsData.vue +++ b/src/modules/magento-2-cms/components/CmsData.vue @@ -1,14 +1,14 @@ diff --git a/src/modules/magento-2-cms/hooks/afterRegistration.ts b/src/modules/magento-2-cms/hooks/afterRegistration.ts index b895bf1ca1..750cc2614e 100644 --- a/src/modules/magento-2-cms/hooks/afterRegistration.ts +++ b/src/modules/magento-2-cms/hooks/afterRegistration.ts @@ -1,14 +1,11 @@ export function afterRegistration({ Vue, config, store, isServer }) { store.subscribe((mutation, state) => { - const type = mutation.type + const type = mutation.type; - if ( - type.endsWith('setCmsBlock') || - type.endsWith('setCmsPage') - ) { - Vue.prototype.$db.cmsData.setItem('cms-data', state.cms).catch((reason) => { - console.error(reason) - }) + if (type.endsWith('setCmsBlock') || type.endsWith('setCmsPage')) { + Vue.prototype.$db.cmsData.setItem('cms-data', state.cms).catch(reason => { + console.error(reason); + }); } - }) -} \ No newline at end of file + }); +} diff --git a/src/modules/magento-2-cms/index.ts b/src/modules/magento-2-cms/index.ts index 61cf08bc49..7f1770190c 100644 --- a/src/modules/magento-2-cms/index.ts +++ b/src/modules/magento-2-cms/index.ts @@ -1,10 +1,10 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { store } from './store' -import { afterRegistration } from './hooks/afterRegistration' +import { createModule } from '@vue-storefront/core/lib/module'; +import { store } from './store'; +import { afterRegistration } from './hooks/afterRegistration'; -const KEY = 'cms' +const KEY = 'cms'; export const Magento2CMS = createModule({ key: KEY, store: { modules: [{ key: KEY, module: store }] }, afterRegistration -}) \ No newline at end of file +}); diff --git a/src/modules/magento-2-cms/store/index.js b/src/modules/magento-2-cms/store/index.js index 1c394da476..7b9b477bdd 100644 --- a/src/modules/magento-2-cms/store/index.js +++ b/src/modules/magento-2-cms/store/index.js @@ -1,29 +1,29 @@ -import fetch from 'isomorphic-fetch' -import { Logger } from '@vue-storefront/core/lib/logger' +import fetch from 'isomorphic-fetch'; +import { Logger } from '@vue-storefront/core/lib/logger'; const state = { cmsPages: [], cmsBlocks: [] -} +}; const getters = { - getBlock: (state) => (id) => { - return state.cmsBlocks.find(item => item.id === id) + getBlock: state => id => { + return state.cmsBlocks.find(item => item.id === id); }, - getBlockIdentifier: (state) => (identifier) => { - return state.cmsBlocks.find(item => item.identifier === identifier) + getBlockIdentifier: state => identifier => { + return state.cmsBlocks.find(item => item.identifier === identifier); }, - getPage: (state) => (id) => { - return state.cmsPages.find(item => item.id === id) + getPage: state => id => { + return state.cmsPages.find(item => item.id === id); }, - getPageIdentifier: (state) => (identifier) => { - return state.cmsPages.find(item => item.identifier === identifier) + getPageIdentifier: state => identifier => { + return state.cmsPages.find(item => item.identifier === identifier); } -} +}; // actions const actions = { - loadCms (context, {url, type}) { + loadCms(context, { url, type }) { fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json' }, @@ -32,29 +32,31 @@ const actions = { .then(response => response.json()) .then(data => { if (data.code === 200) { - context.commit(`setCms${type}`, data.result) + context.commit(`setCms${type}`, data.result); } }) - .catch((err) => { - Logger.log(err)() - Logger.error('You need to install a custom Magento module from Snow.dog to make the CMS magic happen. Please go to https://github.com/SnowdogApps/magento2-cms-api and follow the instructions')() - }) + .catch(err => { + Logger.log(err)(); + Logger.error( + 'You need to install a custom Magento module from Snow.dog to make the CMS magic happen. Please go to https://github.com/SnowdogApps/magento2-cms-api and follow the instructions' + )(); + }); } -} +}; // mutations const mutations = { - setCmsBlock (state, data) { + setCmsBlock(state, data) { if (!state.cmsBlocks.filter(e => e.id === data.id).length > 0) { - state.cmsBlocks.push(data) + state.cmsBlocks.push(data); } }, - setCmsPage (state, data) { + setCmsPage(state, data) { if (!state.cmsPages.filter(e => e.id === data.id).length > 0) { - state.cmsPages.push(data) + state.cmsPages.push(data); } } -} +}; export const store = { namespaced: true, @@ -62,4 +64,4 @@ export const store = { getters, actions, mutations -} +}; diff --git a/src/modules/mailchimp/components/Subscribe.ts b/src/modules/mailchimp/components/Subscribe.ts index e584b6f255..5e05ff7c5e 100644 --- a/src/modules/mailchimp/components/Subscribe.ts +++ b/src/modules/mailchimp/components/Subscribe.ts @@ -1,24 +1,24 @@ -import { required, email } from 'vuelidate/lib/validators' +import { required, email } from 'vuelidate/lib/validators'; /** * Newsletter subscription form component. * * #### Data * - `email: String` - email that will be used for subscription, validated with vuelidate (email, required) - * + * * ### Computed * - `isSubscribed: boolean` - returns true if user subscribed to the newsletter in this session - * + * * #### Methods * - `submit(success?: Function, failure?: Function)` dispatches `newsletter-mailchimp/subscribe` with `email` data property. `success(res)` and `failure(err)` are callback functions called depending on subscription result and contain response info or error. - * + * */ export const Subscribe = { name: 'MailchimpSubscribe', - data () { + data() { return { email: '' - } + }; }, validations: { email: { @@ -27,20 +27,23 @@ export const Subscribe = { } }, methods: { - submit (success?: Function, failure?: Function) { + submit(success?: Function, failure?: Function) { // argument omitted for validation purposes if (!this.$v.$invalid) { - this.$store.dispatch('mailchimp/subscribe', this.email).then(res => { - if (success) success(res) - }).catch(err => { - if (failure) failure(err) - } - )} + this.$store + .dispatch('mailchimp/subscribe', this.email) + .then(res => { + if (success) success(res); + }) + .catch(err => { + if (failure) failure(err); + }); + } } }, computed: { - isSubscribed (): boolean { - return this.$store.state.mailchimp.subscribed + isSubscribed(): boolean { + return this.$store.state.mailchimp.subscribed; } - }, -} + } +}; diff --git a/src/modules/mailchimp/components/Unsubscribe.ts b/src/modules/mailchimp/components/Unsubscribe.ts index 3b64c05896..2c67d8848f 100644 --- a/src/modules/mailchimp/components/Unsubscribe.ts +++ b/src/modules/mailchimp/components/Unsubscribe.ts @@ -1,17 +1,18 @@ export const Unsubscribe = { name: 'MailchimpUnsubscribe', methods: { - unsubscribe () { - this.$store.dispatch('mailchimp/unsubscribe', this.email).then(res => { - this.$emit('unsubscribed', res) - }).catch(err => - this.$emit('unsubscription-error', err) - ) - } + unsubscribe() { + this.$store + .dispatch('mailchimp/unsubscribe', this.email) + .then(res => { + this.$emit('unsubscribed', res); + }) + .catch(err => this.$emit('unsubscription-error', err)); + } }, computed: { - isSubscribed () { - return this.$store.state.mailchimp.isSubscribed + isSubscribed() { + return this.$store.state.mailchimp.isSubscribed; } } -} +}; diff --git a/src/modules/mailchimp/index.ts b/src/modules/mailchimp/index.ts index d507a71961..1bbdd0c751 100644 --- a/src/modules/mailchimp/index.ts +++ b/src/modules/mailchimp/index.ts @@ -1,13 +1,16 @@ -import { module } from './store' -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { module } from './store'; +import { + VueStorefrontModule, + VueStorefrontModuleConfig +} from '@vue-storefront/core/lib/module'; +import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; -export const KEY = 'mailchimp' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'mailchimp'; +export const cacheStorage = initCacheStorage(KEY); const moduleConfig: VueStorefrontModuleConfig = { key: KEY, - store: { modules: [{ key: KEY, module }] }, -} + store: { modules: [{ key: KEY, module }] } +}; -export const Mailchimp = new VueStorefrontModule(moduleConfig) \ No newline at end of file +export const Mailchimp = new VueStorefrontModule(moduleConfig); diff --git a/src/modules/mailchimp/store/index.ts b/src/modules/mailchimp/store/index.ts index 1c86b01881..b4d06719d2 100644 --- a/src/modules/mailchimp/store/index.ts +++ b/src/modules/mailchimp/store/index.ts @@ -1,28 +1,28 @@ -import * as types from './mutation-types' -import config from 'config' -import { Module } from 'vuex' -import { mailchimpState } from '../types/mailchimpState' -import { cacheStorage } from '../' +import * as types from './mutation-types'; +import config from 'config'; +import { Module } from 'vuex'; +import { mailchimpState } from '../types/mailchimpState'; +import { cacheStorage } from '../'; -export const module: Module ={ +export const module: Module = { namespaced: true, state: { isSubscribed: null, - email: null, + email: null }, mutations: { - [types.NEWSLETTER_SUBSCRIBE] (state) { - state.isSubscribed = true + [types.NEWSLETTER_SUBSCRIBE](state) { + state.isSubscribed = true; }, - [types.NEWSLETTER_UNSUBSCRIBE] (state) { - state.isSubscribed = false + [types.NEWSLETTER_UNSUBSCRIBE](state) { + state.isSubscribed = false; }, - [types.SET_EMAIL] (state, payload) { - state.email = payload + [types.SET_EMAIL](state, payload) { + state.email = payload; } }, actions: { - subscribe ({ commit, state }, email): Promise { + subscribe({ commit, state }, email): Promise { if (!state.isSubscribed) { return new Promise((resolve, reject) => { fetch(config.mailchimp.endpoint, { @@ -30,18 +30,20 @@ export const module: Module ={ headers: { 'Content-Type': 'application/json' }, mode: 'cors', body: JSON.stringify({ email }) - }).then(res => { - commit(types.NEWSLETTER_SUBSCRIBE) - commit(types.SET_EMAIL, email) - cacheStorage.setItem('email', email) - resolve(res) - }).catch(err => { - reject(err) }) - }) + .then(res => { + commit(types.NEWSLETTER_SUBSCRIBE); + commit(types.SET_EMAIL, email); + cacheStorage.setItem('email', email); + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); } }, - unsubscribe ({ commit, state }, email): Promise { + unsubscribe({ commit, state }, email): Promise { if (!state.isSubscribed) { return new Promise((resolve, reject) => { fetch(config.mailchimp.endpoint, { @@ -49,14 +51,16 @@ export const module: Module ={ headers: { 'Content-Type': 'application/json' }, mode: 'cors', body: JSON.stringify({ email }) - }).then(res => { - commit(types.NEWSLETTER_UNSUBSCRIBE) - resolve(res) - }).catch(err => { - reject(err) }) - }) + .then(res => { + commit(types.NEWSLETTER_UNSUBSCRIBE); + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); } } } -} +}; diff --git a/src/modules/mailchimp/store/mutation-types.ts b/src/modules/mailchimp/store/mutation-types.ts index 61a155ca2c..4b01885df0 100644 --- a/src/modules/mailchimp/store/mutation-types.ts +++ b/src/modules/mailchimp/store/mutation-types.ts @@ -1,3 +1,3 @@ -export const NEWSLETTER_SUBSCRIBE = 'NEWSLETTER_SUBSCRIBE' -export const NEWSLETTER_UNSUBSCRIBE = 'NEWSLETTER_UNSUBSCRIBE' -export const SET_EMAIL = 'SET_EMAIL' +export const NEWSLETTER_SUBSCRIBE = 'NEWSLETTER_SUBSCRIBE'; +export const NEWSLETTER_UNSUBSCRIBE = 'NEWSLETTER_UNSUBSCRIBE'; +export const SET_EMAIL = 'SET_EMAIL'; diff --git a/src/modules/mailchimp/types/mailchimpState.ts b/src/modules/mailchimp/types/mailchimpState.ts index cb846e20f2..c4f083d289 100644 --- a/src/modules/mailchimp/types/mailchimpState.ts +++ b/src/modules/mailchimp/types/mailchimpState.ts @@ -1,4 +1,4 @@ export interface mailchimpState { - isSubscribed: boolean | null, - email: string | null -} \ No newline at end of file + isSubscribed: boolean | null; + email: string | null; +} diff --git a/src/modules/module-template/components/ExtensionComponent.ts b/src/modules/module-template/components/ExtensionComponent.ts index 43e00c16dc..c31f316e54 100644 --- a/src/modules/module-template/components/ExtensionComponent.ts +++ b/src/modules/module-template/components/ExtensionComponent.ts @@ -1,26 +1,33 @@ - /** +/** * User list component example. Try to document components like this. You can also export .vue files if you want to provide baseline template. * * #### Data * - `users: String[]` - list of users - * + * * #### Methods * - `addUser(name: Function, success?: Function, failure?: Function)` adds new user to the list, calls failure if user with the same name is already on list */ export const ExtensionComponent = { name: 'ExtensionComponent', computed: { - users () { - return this.$store.state.example.user + users() { + return this.$store.state.example.user; } }, methods: { - addUser(user: Object, success: (res: Object) => void, failure: (err: Error) => void): void { - this.$store.dispatch('example/addUser', user).then(res => { - success(res) - }).catch(err => { - failure(err) - }) + addUser( + user: Object, + success: (res: Object) => void, + failure: (err: Error) => void + ): void { + this.$store + .dispatch('example/addUser', user) + .then(res => { + success(res); + }) + .catch(err => { + failure(err); + }); } } -} \ No newline at end of file +}; diff --git a/src/modules/module-template/hooks/afterRegistration.ts b/src/modules/module-template/hooks/afterRegistration.ts index 90c8961f95..84fa4bd396 100644 --- a/src/modules/module-template/hooks/afterRegistration.ts +++ b/src/modules/module-template/hooks/afterRegistration.ts @@ -1,6 +1,9 @@ -import { Logger } from '@vue-storefront/core/lib/logger' +import { Logger } from '@vue-storefront/core/lib/logger'; // This function will be fired both on server and client side context after registering other parts of the module -export function afterRegistration({ Vue, config, store, isServer }){ - if (isServer) Logger.info('This will be called after extension registration and only on client side')() +export function afterRegistration({ Vue, config, store, isServer }) { + if (isServer) + Logger.info( + 'This will be called after extension registration and only on client side' + )(); } diff --git a/src/modules/module-template/hooks/beforeRegistration.ts b/src/modules/module-template/hooks/beforeRegistration.ts index 6395dcd9cf..3c0b3d671e 100644 --- a/src/modules/module-template/hooks/beforeRegistration.ts +++ b/src/modules/module-template/hooks/beforeRegistration.ts @@ -1,18 +1,24 @@ -import { AsyncDataLoader } from '@vue-storefront/core/lib/async-data-loader' +import { AsyncDataLoader } from '@vue-storefront/core/lib/async-data-loader'; // This function will be fired both on server and client side context before registering other parts of the module export function beforeRegistration({ Vue, config, store, isServer }) { - if (!isServer) console.info('This will be called before extension registration and only on client side') - AsyncDataLoader.push({ // this is an example showing how to call data loader from another module + if (!isServer) + console.info( + 'This will be called before extension registration and only on client side' + ); + AsyncDataLoader.push({ + // this is an example showing how to call data loader from another module execute: ({ route, store, context }) => { - return new Promise ((resolve, reject) => { + return new Promise((resolve, reject) => { if (route.name === 'configurable-product') { - store.state.exampleDataFetchedByLoader = 'this is just example data fetched by loader on configurable product page' + store.state.exampleDataFetchedByLoader = + 'this is just example data fetched by loader on configurable product page'; } else { - store.state.exampleDataFetchedByLoader = 'this is just example data fetched by loader on any page' + store.state.exampleDataFetchedByLoader = + 'this is just example data fetched by loader on any page'; } - resolve(null) - }) + resolve(null); + }); } - }) + }); } diff --git a/src/modules/module-template/index.ts b/src/modules/module-template/index.ts index 3c3216bc8c..bba449f328 100644 --- a/src/modules/module-template/index.ts +++ b/src/modules/module-template/index.ts @@ -1,20 +1,19 @@ // Read more about modules: https://github.com/DivanteLtd/vue-storefront/blob/master/doc/api-modules/about-modules.md -import { module } from './store' -import { plugin } from './store/plugin' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeEach } from './router/beforeEach' -import { afterEach } from './router/afterEach' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { module } from './store'; +import { plugin } from './store/plugin'; +import { beforeRegistration } from './hooks/beforeRegistration'; +import { afterRegistration } from './hooks/afterRegistration'; +import { createModule } from '@vue-storefront/core/lib/module'; +import { beforeEach } from './router/beforeEach'; +import { afterEach } from './router/afterEach'; +import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; -export const KEY = 'example' -export const cacheStorage = initCacheStorage(KEY) +export const KEY = 'example'; +export const cacheStorage = initCacheStorage(KEY); export const Example = createModule({ key: KEY, store: { modules: [{ key: KEY, module }], plugin }, beforeRegistration, afterRegistration, router: { beforeEach, afterEach } -} -) +}); diff --git a/src/modules/module-template/pages/ExtensionPage.vue b/src/modules/module-template/pages/ExtensionPage.vue index 25f7f02998..c0db791ec9 100644 --- a/src/modules/module-template/pages/ExtensionPage.vue +++ b/src/modules/module-template/pages/ExtensionPage.vue @@ -7,12 +7,12 @@ diff --git a/src/modules/module-template/queries/exampleQuery.ts b/src/modules/module-template/queries/exampleQuery.ts index 7d9201451d..a698f05a62 100644 --- a/src/modules/module-template/queries/exampleQuery.ts +++ b/src/modules/module-template/queries/exampleQuery.ts @@ -1,12 +1,10 @@ // GraphQL and ES queries exposed by this module -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; export function exampleQuery(queryText, queryFilter) { - let exampleQuery = new SearchQuery() + let exampleQuery = new SearchQuery(); - exampleQuery = exampleQuery - .setSearchText(queryText) - .applyFilter(queryFilter) + exampleQuery = exampleQuery.setSearchText(queryText).applyFilter(queryFilter); -return exampleQuery + return exampleQuery; } diff --git a/src/modules/module-template/router/afterEach.ts b/src/modules/module-template/router/afterEach.ts index f03539a395..08d2cc397f 100644 --- a/src/modules/module-template/router/afterEach.ts +++ b/src/modules/module-template/router/afterEach.ts @@ -1,8 +1,8 @@ // This function will be executed after entering each route. // See https://router.vuejs.org/guide/advanced/navigation-guards.html#global-after-hooks -import { Route } from 'vue-router' -import { Logger } from '@vue-storefront/core/lib/logger' +import { Route } from 'vue-router'; +import { Logger } from '@vue-storefront/core/lib/logger'; export function afterEach(to: Route, from: Route) { - Logger.info(`We have just entered ${to.name} from ${from.name}.`)() + Logger.info(`We have just entered ${to.name} from ${from.name}.`)(); } diff --git a/src/modules/module-template/router/beforeEach.ts b/src/modules/module-template/router/beforeEach.ts index 3ebb631780..2746652fc3 100644 --- a/src/modules/module-template/router/beforeEach.ts +++ b/src/modules/module-template/router/beforeEach.ts @@ -1,10 +1,10 @@ // This function will be executed before entering each route. // It's important to have 'next()'. It enables navigation to new route. // See https://router.vuejs.org/guide/advanced/navigation-guards.html#global-guards -import { Route } from 'vue-router' -import { Logger } from '@vue-storefront/core/lib/logger' +import { Route } from 'vue-router'; +import { Logger } from '@vue-storefront/core/lib/logger'; export function beforeEach(to: Route, from: Route, next) { - Logger.info('We are going to visit' + to.name)() - next() + Logger.info('We are going to visit' + to.name)(); + next(); } diff --git a/src/modules/module-template/store/actions.ts b/src/modules/module-template/store/actions.ts index 0d8c3dffba..6b8baf9f5f 100644 --- a/src/modules/module-template/store/actions.ts +++ b/src/modules/module-template/store/actions.ts @@ -1,26 +1,29 @@ -import { ExampleState } from '../types/ExampleState' +import { ExampleState } from '../types/ExampleState'; import { ActionTree } from 'vuex'; -import * as types from './mutation-types' +import * as types from './mutation-types'; // you can use this storage if you want to enable offline capabilities -import { cacheStorage } from '../' +import { cacheStorage } from '../'; // it's a good practice for all actions to return Promises with effect of their execution export const actions: ActionTree = { // if you want to use cache in your module you can load cached data like this - loadUsers ({ commit }) { - return new Promise ((resolve, reject) => { - cacheStorage.getItem('user').then(userData => { - commit(types.SET_USERS, userData) - resolve(userData) - }).catch(() => reject()) - }) + loadUsers({ commit }) { + return new Promise((resolve, reject) => { + cacheStorage + .getItem('user') + .then(userData => { + commit(types.SET_USERS, userData); + resolve(userData); + }) + .catch(() => reject()); + }); }, // if you are using cache in your module it's a good practice to allow develoeprs to choose either to use it or not - addUser ({ commit }, { user, useCache = false }) { - return new Promise ((resolve, reject) => { - commit(types.ADD_USER, user) - if (useCache) cacheStorage.setItem('user', user) - resolve(user) - }) + addUser({ commit }, { user, useCache = false }) { + return new Promise((resolve, reject) => { + commit(types.ADD_USER, user); + if (useCache) cacheStorage.setItem('user', user); + resolve(user); + }); } -} \ No newline at end of file +}; diff --git a/src/modules/module-template/store/getters.ts b/src/modules/module-template/store/getters.ts index 1751ff39ec..a37d40c473 100644 --- a/src/modules/module-template/store/getters.ts +++ b/src/modules/module-template/store/getters.ts @@ -1,4 +1,4 @@ -import { ExampleState } from '../types/ExampleState' +import { ExampleState } from '../types/ExampleState'; import { GetterTree } from 'vuex'; -export const getters: GetterTree = {} \ No newline at end of file +export const getters: GetterTree = {}; diff --git a/src/modules/module-template/store/index.ts b/src/modules/module-template/store/index.ts index bf11145632..927ba3d70b 100644 --- a/src/modules/module-template/store/index.ts +++ b/src/modules/module-template/store/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import { ExampleState } from '../types/ExampleState' -import { mutations } from './mutations' -import { getters } from './getters' -import { actions } from './actions' -import { state } from './state' +import { Module } from 'vuex'; +import { ExampleState } from '../types/ExampleState'; +import { mutations } from './mutations'; +import { getters } from './getters'; +import { actions } from './actions'; +import { state } from './state'; export const module: Module = { namespaced: true, @@ -11,4 +11,4 @@ export const module: Module = { actions, getters, state -} \ No newline at end of file +}; diff --git a/src/modules/module-template/store/mutation-types.ts b/src/modules/module-template/store/mutation-types.ts index baea4a0178..e288e5ecf1 100644 --- a/src/modules/module-template/store/mutation-types.ts +++ b/src/modules/module-template/store/mutation-types.ts @@ -1,2 +1,2 @@ -export const SET_USERS = 'TEMPLATE/SET_USERS' -export const ADD_USER = 'TEMPLATE/SET_USER' \ No newline at end of file +export const SET_USERS = 'TEMPLATE/SET_USERS'; +export const ADD_USER = 'TEMPLATE/SET_USER'; diff --git a/src/modules/module-template/store/mutations.ts b/src/modules/module-template/store/mutations.ts index 735e1689a0..85a7a7d00b 100644 --- a/src/modules/module-template/store/mutations.ts +++ b/src/modules/module-template/store/mutations.ts @@ -1,11 +1,11 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' +import { MutationTree } from 'vuex'; +import * as types from './mutation-types'; export const mutations: MutationTree = { - [types.SET_USERS] (state, payload) { - state.users = payload + [types.SET_USERS](state, payload) { + state.users = payload; }, - [types.ADD_USER] (state, payload) { - state.users.push(payload) - } -} \ No newline at end of file + [types.ADD_USER](state, payload) { + state.users.push(payload); + } +}; diff --git a/src/modules/module-template/store/plugin.ts b/src/modules/module-template/store/plugin.ts index b3e3bd29ee..85ed5ca1e3 100644 --- a/src/modules/module-template/store/plugin.ts +++ b/src/modules/module-template/store/plugin.ts @@ -1,10 +1,14 @@ -import * as types from './mutation-types' -import { Logger } from '@vue-storefront/core/lib/logger' +import * as types from './mutation-types'; +import { Logger } from '@vue-storefront/core/lib/logger'; -export function plugin (mutation, state) { +export function plugin(mutation, state) { if (types[mutation.type]) { - Logger.info('performed mutation from this store with type' + mutation.type)() + Logger.info( + 'performed mutation from this store with type' + mutation.type + )(); } else { - Logger.info('performed mutation from other store with type' + mutation.type)() + Logger.info( + 'performed mutation from other store with type' + mutation.type + )(); } } diff --git a/src/modules/module-template/store/state.ts b/src/modules/module-template/store/state.ts index cecc3491c3..79190380e4 100644 --- a/src/modules/module-template/store/state.ts +++ b/src/modules/module-template/store/state.ts @@ -1,5 +1,5 @@ -import { ExampleState } from '../types/ExampleState' +import { ExampleState } from '../types/ExampleState'; export const state: ExampleState = { users: null -} \ No newline at end of file +}; diff --git a/src/modules/module-template/types/ExampleState.ts b/src/modules/module-template/types/ExampleState.ts index ec0368bfc8..093942ce61 100644 --- a/src/modules/module-template/types/ExampleState.ts +++ b/src/modules/module-template/types/ExampleState.ts @@ -1,5 +1,5 @@ // This object should represent structure of your modules Vuex state // It's a good practice is to name this interface accordingly to the KET (for example mailchimpState) export interface ExampleState { - users: string[] -} \ No newline at end of file + users: string[]; +} diff --git a/src/modules/payment-backend-methods/hooks/afterRegistration.ts b/src/modules/payment-backend-methods/hooks/afterRegistration.ts index 03438634fd..643727b498 100644 --- a/src/modules/payment-backend-methods/hooks/afterRegistration.ts +++ b/src/modules/payment-backend-methods/hooks/afterRegistration.ts @@ -1,35 +1,43 @@ -import * as types from './../store/mutation-types' +import * as types from './../store/mutation-types'; export function afterRegistration({ Vue, config, store, isServer }) { - - let correctPaymentMethod = false + let correctPaymentMethod = false; // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' const placeOrder = () => { if (correctPaymentMethod) { - Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}) + Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}); } - } + }; if (!isServer) { // Update the methods Vue.prototype.$bus.$on('set-unique-payment-methods', methods => { - store.commit('payment-backend-methods/' + types.SET_BACKEND_PAYMENT_METHODS, methods) - }) + store.commit( + 'payment-backend-methods/' + types.SET_BACKEND_PAYMENT_METHODS, + methods + ); + }); - Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder) + Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder); // Mount the info component when required - Vue.prototype.$bus.$on('checkout-payment-method-changed', (paymentMethodCode) => { - let methods = store.state['payment-backend-methods'].methods - if (methods !== null && methods.find(item => (item.code === paymentMethodCode && item.is_server_method === true))) { - correctPaymentMethod = true - } else { - correctPaymentMethod = false + Vue.prototype.$bus.$on( + 'checkout-payment-method-changed', + paymentMethodCode => { + let methods = store.state['payment-backend-methods'].methods; + if ( + methods !== null && + methods.find( + item => + item.code === paymentMethodCode && item.is_server_method === true + ) + ) { + correctPaymentMethod = true; + } else { + correctPaymentMethod = false; + } } - }) + ); } } - - - diff --git a/src/modules/payment-backend-methods/index.ts b/src/modules/payment-backend-methods/index.ts index eb47353348..4cc40ebbc1 100644 --- a/src/modules/payment-backend-methods/index.ts +++ b/src/modules/payment-backend-methods/index.ts @@ -1,6 +1,6 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' -import * as types from './store/mutation-types' +import { createModule } from '@vue-storefront/core/lib/module'; +import { afterRegistration } from './hooks/afterRegistration'; +import * as types from './store/mutation-types'; const store = { namespaced: true, @@ -8,15 +8,15 @@ const store = { methods: null }, mutations: { - [types.SET_BACKEND_PAYMENT_METHODS](state, paymentMethods) { - state.methods = paymentMethods + [types.SET_BACKEND_PAYMENT_METHODS](state, paymentMethods) { + state.methods = paymentMethods; } } -} +}; -const KEY = 'payment-backend-methods' +const KEY = 'payment-backend-methods'; export const PaymentBackendMethods = createModule({ key: KEY, store: { modules: [{ key: KEY, module: store }] }, afterRegistration -}) \ No newline at end of file +}); diff --git a/src/modules/payment-backend-methods/store/mutation-types.ts b/src/modules/payment-backend-methods/store/mutation-types.ts index 57a657327e..90041332e6 100644 --- a/src/modules/payment-backend-methods/store/mutation-types.ts +++ b/src/modules/payment-backend-methods/store/mutation-types.ts @@ -1 +1 @@ -export const SET_BACKEND_PAYMENT_METHODS = 'SET_BACKEND_PAYMENT_METHODS' \ No newline at end of file +export const SET_BACKEND_PAYMENT_METHODS = 'SET_BACKEND_PAYMENT_METHODS'; diff --git a/src/modules/payment-cash-on-delivery/components/Info.vue b/src/modules/payment-cash-on-delivery/components/Info.vue index 852de1f7d8..8cdff7aa99 100644 --- a/src/modules/payment-cash-on-delivery/components/Info.vue +++ b/src/modules/payment-cash-on-delivery/components/Info.vue @@ -1,5 +1,4 @@ diff --git a/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts b/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts index a80cc9e8b2..998d1d6c19 100644 --- a/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts +++ b/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts @@ -1,44 +1,52 @@ -import InfoComponent from '../components/Info.vue' -import rootStore from '@vue-storefront/core/store' +import InfoComponent from '../components/Info.vue'; +import rootStore from '@vue-storefront/core/store'; export function afterRegistration({ Vue, config, store, isServer }) { // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' - let correctPaymentMethod = false + let correctPaymentMethod = false; const placeOrder = () => { if (correctPaymentMethod) { - Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}) + Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}); } - } + }; if (!isServer) { // Update the methods let paymentMethodConfig = { - 'title': 'Cash on delivery', - 'code': 'cashondelivery', - 'cost': 0, - 'costInclTax': 0, - 'default': true, - 'offline': true, - 'is_server_method': false - } - rootStore.dispatch('payment/addMethod', paymentMethodConfig) + title: 'Cash on delivery', + code: 'cashondelivery', + cost: 0, + costInclTax: 0, + default: true, + offline: true, + is_server_method: false + }; + rootStore.dispatch('payment/addMethod', paymentMethodConfig); - Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder) + Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder); // Mount the info component when required. - Vue.prototype.$bus.$on('checkout-payment-method-changed', (paymentMethodCode) => { - let methods = store.state['payment-backend-methods'].methods - let method = methods.find(item => (item.code === paymentMethodCode)) - if (paymentMethodCode === 'cashondelivery' && ((typeof method !== 'undefined' && !method.is_server_method) || typeof method === 'undefined') /* otherwise it could be a `payment-backend-methods` module */) { - correctPaymentMethod = true + Vue.prototype.$bus.$on( + 'checkout-payment-method-changed', + paymentMethodCode => { + let methods = store.state['payment-backend-methods'].methods; + let method = methods.find(item => item.code === paymentMethodCode); + if ( + paymentMethodCode === 'cashondelivery' && + ((typeof method !== 'undefined' && !method.is_server_method) || + typeof method === + 'undefined') /* otherwise it could be a `payment-backend-methods` module */ + ) { + correctPaymentMethod = true; - // Dynamically inject a component into the order review section (optional) - const Component = Vue.extend(InfoComponent) - const componentInstance = (new Component()) - componentInstance.$mount('#checkout-order-review-additional') - } else { - correctPaymentMethod = false + // Dynamically inject a component into the order review section (optional) + const Component = Vue.extend(InfoComponent); + const componentInstance = new Component(); + componentInstance.$mount('#checkout-order-review-additional'); + } else { + correctPaymentMethod = false; + } } - }) + ); } } diff --git a/src/modules/payment-cash-on-delivery/index.ts b/src/modules/payment-cash-on-delivery/index.ts index ea4fc6d010..f2de4f33f0 100644 --- a/src/modules/payment-cash-on-delivery/index.ts +++ b/src/modules/payment-cash-on-delivery/index.ts @@ -1,8 +1,8 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' +import { createModule } from '@vue-storefront/core/lib/module'; +import { afterRegistration } from './hooks/afterRegistration'; -const KEY = 'payment-cash-on-delivery' +const KEY = 'payment-cash-on-delivery'; export const PaymentCashOnDelivery = createModule({ key: KEY, afterRegistration -}) \ No newline at end of file +}); diff --git a/src/modules/promoted-offers/index.ts b/src/modules/promoted-offers/index.ts index 4eccbae2e9..31beda5b60 100644 --- a/src/modules/promoted-offers/index.ts +++ b/src/modules/promoted-offers/index.ts @@ -1,8 +1,8 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { module } from './store' +import { createModule } from '@vue-storefront/core/lib/module'; +import { module } from './store'; -const KEY = 'promoted' +const KEY = 'promoted'; export const PromotedOffers = createModule({ key: KEY, store: { modules: [{ key: KEY, module }] } -}) \ No newline at end of file +}); diff --git a/src/modules/promoted-offers/store/actions.ts b/src/modules/promoted-offers/store/actions.ts index cd10471c32..924fc9e8b0 100644 --- a/src/modules/promoted-offers/store/actions.ts +++ b/src/modules/promoted-offers/store/actions.ts @@ -1,27 +1,37 @@ -import { ActionTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import PromotedOffersState from '../types/PromotedOffersState' -import { Logger } from '@vue-storefront/core/lib/logger' +import { ActionTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import PromotedOffersState from '../types/PromotedOffersState'; +import { Logger } from '@vue-storefront/core/lib/logger'; const actions: ActionTree = { - async updatePromotedOffers ({commit, rootState}, data) { - let promotedBannersResource = rootState.storeView && rootState.storeView.storeCode ? `banners/${rootState.storeView.storeCode}_promoted_offers` : `promoted_offers` + async updatePromotedOffers({ commit, rootState }, data) { + let promotedBannersResource = + rootState.storeView && rootState.storeView.storeCode + ? `banners/${rootState.storeView.storeCode}_promoted_offers` + : `promoted_offers`; try { - const promotedOffersModule = await import(/* webpackChunkName: "vsf-promoted-offers-[request]" */ `theme/resource/${promotedBannersResource}.json`) - commit('updatePromotedOffers', promotedOffersModule) + const promotedOffersModule = await import( + /* webpackChunkName: "vsf-promoted-offers-[request]" */ `theme/resource/${promotedBannersResource}.json` + ); + commit('updatePromotedOffers', promotedOffersModule); } catch (err) { - Logger.debug('Unable to load promotedOffers' + err)() + Logger.debug('Unable to load promotedOffers' + err)(); } }, - async updateHeadImage ({commit, rootState}, data) { - let mainImageResource = rootState.storeView && rootState.storeView.storeCode ? `banners/${rootState.storeView.storeCode}_main-image` : `main-image` + async updateHeadImage({ commit, rootState }, data) { + let mainImageResource = + rootState.storeView && rootState.storeView.storeCode + ? `banners/${rootState.storeView.storeCode}_main-image` + : `main-image`; try { - const imageModule = await import(/* webpackChunkName: "vsf-head-img-[request]" */ `theme/resource/${mainImageResource}.json`) - commit('SET_HEAD_IMAGE', imageModule.image) + const imageModule = await import( + /* webpackChunkName: "vsf-head-img-[request]" */ `theme/resource/${mainImageResource}.json` + ); + commit('SET_HEAD_IMAGE', imageModule.image); } catch (err) { - Logger.debug('Unable to load headImage' + err)() + Logger.debug('Unable to load headImage' + err)(); } } -} +}; -export default actions +export default actions; diff --git a/src/modules/promoted-offers/store/getters.ts b/src/modules/promoted-offers/store/getters.ts index 8e9f74ac19..b121c40b6e 100644 --- a/src/modules/promoted-offers/store/getters.ts +++ b/src/modules/promoted-offers/store/getters.ts @@ -1,12 +1,12 @@ -import { GetterTree } from 'vuex' -import RootState from '@vue-storefront/core/types/RootState' -import PromotedOffersState from '../types/PromotedOffersState' +import { GetterTree } from 'vuex'; +import RootState from '@vue-storefront/core/types/RootState'; +import PromotedOffersState from '../types/PromotedOffersState'; const getters: GetterTree = { getPromotedOffers: state => { - return state.banners + return state.banners; }, getHeadImage: state => state.headImage -} +}; -export default getters +export default getters; diff --git a/src/modules/promoted-offers/store/index.ts b/src/modules/promoted-offers/store/index.ts index 83bf36f518..aed9915532 100644 --- a/src/modules/promoted-offers/store/index.ts +++ b/src/modules/promoted-offers/store/index.ts @@ -1,9 +1,9 @@ -import { Module } from 'vuex' -import getters from './getters' -import actions from './actions' -import mutations from './mutations' -import RootState from '@vue-storefront/core/types/RootState' -import PromotedOffersState from '../types/PromotedOffersState' +import { Module } from 'vuex'; +import getters from './getters'; +import actions from './actions'; +import mutations from './mutations'; +import RootState from '@vue-storefront/core/types/RootState'; +import PromotedOffersState from '../types/PromotedOffersState'; export const module: Module = { namespaced: true, @@ -18,4 +18,4 @@ export const module: Module = { getters, actions, mutations -} +}; diff --git a/src/modules/promoted-offers/store/mutations.ts b/src/modules/promoted-offers/store/mutations.ts index acb3864d5a..c11d9ccebc 100644 --- a/src/modules/promoted-offers/store/mutations.ts +++ b/src/modules/promoted-offers/store/mutations.ts @@ -1,13 +1,13 @@ -import { MutationTree } from 'vuex' -import PromotedOffersState from '../types/PromotedOffersState' +import { MutationTree } from 'vuex'; +import PromotedOffersState from '../types/PromotedOffersState'; const mutations: MutationTree = { - updatePromotedOffers (state, data) { - state.banners = data + updatePromotedOffers(state, data) { + state.banners = data; }, - SET_HEAD_IMAGE (state, headImage) { - state.headImage = headImage + SET_HEAD_IMAGE(state, headImage) { + state.headImage = headImage; } -} +}; -export default mutations +export default mutations; diff --git a/src/modules/promoted-offers/types/PromotedOffersState.ts b/src/modules/promoted-offers/types/PromotedOffersState.ts index 9a8af884e3..28350f4bc4 100644 --- a/src/modules/promoted-offers/types/PromotedOffersState.ts +++ b/src/modules/promoted-offers/types/PromotedOffersState.ts @@ -1,8 +1,8 @@ export default interface PromotedOffersState { banners: { - mainBanners: any[], - smallBanners: any[], - productBanners: any[] - }, - headImage: Object + mainBanners: any[]; + smallBanners: any[]; + productBanners: any[]; + }; + headImage: Object; } diff --git a/src/modules/raw-output-example/index.ts b/src/modules/raw-output-example/index.ts index b519cef19e..641ff084e2 100644 --- a/src/modules/raw-output-example/index.ts +++ b/src/modules/raw-output-example/index.ts @@ -1,8 +1,8 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { routes } from './router/routes' +import { createModule } from '@vue-storefront/core/lib/module'; +import { routes } from './router/routes'; -const KEY = 'raw-output-example' +const KEY = 'raw-output-example'; export const RawOutputExample = createModule({ key: KEY, router: { routes } -}) \ No newline at end of file +}); diff --git a/src/modules/raw-output-example/pages/NoJSExample.vue b/src/modules/raw-output-example/pages/NoJSExample.vue index 1e09d70888..449c5bf374 100755 --- a/src/modules/raw-output-example/pages/NoJSExample.vue +++ b/src/modules/raw-output-example/pages/NoJSExample.vue @@ -1,33 +1,33 @@ - + diff --git a/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue b/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue index ec0ed77d9d..c11b8448d3 100755 --- a/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue +++ b/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue @@ -1,33 +1,32 @@ - + diff --git a/src/modules/raw-output-example/pages/RawOutputExample.vue b/src/modules/raw-output-example/pages/RawOutputExample.vue index 5033610f6e..1d7ad30244 100755 --- a/src/modules/raw-output-example/pages/RawOutputExample.vue +++ b/src/modules/raw-output-example/pages/RawOutputExample.vue @@ -7,24 +7,21 @@ - + diff --git a/src/modules/raw-output-example/router/routes.ts b/src/modules/raw-output-example/router/routes.ts index dc935d3cb4..82d7c8837a 100644 --- a/src/modules/raw-output-example/router/routes.ts +++ b/src/modules/raw-output-example/router/routes.ts @@ -1,9 +1,17 @@ -import NoJSExample from '../pages/NoJSExample.vue' -import RawOutputExample from '../pages/RawOutputExample.vue' -import NoLayoutAppendPrependExample from '../pages/NoLayoutAppendPrependExample.vue' +import NoJSExample from '../pages/NoJSExample.vue'; +import RawOutputExample from '../pages/RawOutputExample.vue'; +import NoLayoutAppendPrependExample from '../pages/NoLayoutAppendPrependExample.vue'; export const routes = [ - { path: '/raw-output-example.xml', component: RawOutputExample, meta: { layout: 'empty' } }, - { path: '/append-prepend.html', component: NoLayoutAppendPrependExample, meta: { layout: 'empty' } }, + { + path: '/raw-output-example.xml', + component: RawOutputExample, + meta: { layout: 'empty' } + }, + { + path: '/append-prepend.html', + component: NoLayoutAppendPrependExample, + meta: { layout: 'empty' } + }, { path: '/no-js.html', component: NoJSExample, meta: { layout: 'default' } } -] +]; diff --git a/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts b/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts index b66b63364f..f47429e99c 100644 --- a/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts +++ b/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts @@ -1,19 +1,18 @@ +import { getSearchAdapter } from '@vue-storefront/core/lib/search/adapter/searchAdapterFactory'; +import { processESResponseType } from '@vue-storefront/core/lib/search/adapter/graphql/processor/processType'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore'; +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery'; +import { Logger } from '@vue-storefront/core/lib/logger'; -import { getSearchAdapter } from '@vue-storefront/core/lib/search/adapter/searchAdapterFactory' -import { processESResponseType } from '@vue-storefront/core/lib/search/adapter/graphql/processor/processType' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { Logger } from '@vue-storefront/core/lib/logger' +const EXTENSION_KEY = 'sample-custom-entity-graphql-extension'; +const TEST_ENTITY_TYPE = 'testentity'; -const EXTENSION_KEY = 'sample-custom-entity-graphql-extension' -const TEST_ENTITY_TYPE = 'testentity' - -export function afterRegistration ({ Vue, config, store, isServer }) { +export function afterRegistration({ Vue, config, store, isServer }) { Vue.$on('application-after-init', async () => { - Logger.debug('Example of custom entity graphql extension')() + Logger.debug('Example of custom entity graphql extension')(); // create GraphQL searchAdapter - let searchAdapter = await getSearchAdapter('graphql') + let searchAdapter = await getSearchAdapter('graphql'); // register custom entity type using registerEntityTypeByQuery // different GraphQL servers could be used for different entity types @@ -21,30 +20,32 @@ export function afterRegistration ({ Vue, config, store, isServer }) { searchAdapter.registerEntityTypeByQuery(TEST_ENTITY_TYPE, { url: 'http://localhost:8080/graphql/', query: require('../queries/testentity.gql'), - queryProcessor: (query) => { + queryProcessor: query => { // function that can modify the query each time before it's being executed - return query + return query; }, resultPorcessor: (resp, start, size) => { if (resp === null) { - throw new Error('Invalid GraphQL result - null not expected') + throw new Error('Invalid GraphQL result - null not expected'); } if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.testentity, start, size) + return processESResponseType(resp.data.testentity, start, size); } else { if (resp.error) { - throw new Error(JSON.stringify(resp.error)) + throw new Error(JSON.stringify(resp.error)); } else { - throw new Error('Unknown error with GraphQL result in resultProcessor for entity type \'category\'') + throw new Error( + "Unknown error with GraphQL result in resultProcessor for entity type 'category'" + ); } } } - }) + }); - const storeView = currentStoreView() + const storeView = currentStoreView(); // create an empty SearchQuery to get all data for the new custom entity - const searchQuery = new SearchQuery() + const searchQuery = new SearchQuery(); // prepare a SearchRequest object const Request = { @@ -52,12 +53,17 @@ export function afterRegistration ({ Vue, config, store, isServer }) { type: TEST_ENTITY_TYPE, searchQuery: searchQuery, sort: '' - } + }; // apply test search - searchAdapter.search(Request).then((resp) => { // we're always trying to populate cache - when online - const res = searchAdapter.entities[Request.type].resultPorcessor(resp, 0, 200) - Logger.log('Testentity response: ', res)() - }) - }) + searchAdapter.search(Request).then(resp => { + // we're always trying to populate cache - when online + const res = searchAdapter.entities[Request.type].resultPorcessor( + resp, + 0, + 200 + ); + Logger.log('Testentity response: ', res)(); + }); + }); } diff --git a/src/modules/sample-custom-entity-graphql/index.ts b/src/modules/sample-custom-entity-graphql/index.ts index 5be90d9e63..294d420a01 100644 --- a/src/modules/sample-custom-entity-graphql/index.ts +++ b/src/modules/sample-custom-entity-graphql/index.ts @@ -1,8 +1,8 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' +import { createModule } from '@vue-storefront/core/lib/module'; +import { afterRegistration } from './hooks/afterRegistration'; -const KEY = 'sample-custom-entity-gql' +const KEY = 'sample-custom-entity-gql'; export const SampleCustomEntityGql = createModule({ key: KEY, - afterRegistration, -}) + afterRegistration +}); diff --git a/src/modules/ui-store/index.ts b/src/modules/ui-store/index.ts index ca9b4f4fab..4dd0425b49 100644 --- a/src/modules/ui-store/index.ts +++ b/src/modules/ui-store/index.ts @@ -1,7 +1,7 @@ -import { createModule } from '@vue-storefront/core/lib/module' +import { createModule } from '@vue-storefront/core/lib/module'; // TODO: Move the logic to appropriate modules and deprecate this one -const KEY = 'ui' +const KEY = 'ui'; const store = { namespaced: true, state: { @@ -21,56 +21,56 @@ const store = { } }, mutations: { - setCheckoutMode (state, action) { - state.checkoutMode = action === true + setCheckoutMode(state, action) { + state.checkoutMode = action === true; }, - setMicrocart (state, action) { - state.microcart = action === true - state.overlay = action === true + setMicrocart(state, action) { + state.microcart = action === true; + state.overlay = action === true; }, - setSidebar (state, action) { - state.sidebar = action === true - state.overlay = action === true + setSidebar(state, action) { + state.sidebar = action === true; + state.overlay = action === true; }, - setSubmenu (state, { id, depth }) { + setSubmenu(state, { id, depth }) { if (id) { - state.submenu.path.push(id) + state.submenu.path.push(id); } else if (state.submenu.path.length) { setTimeout(() => { - state.submenu.path.pop() - }, 300) + state.submenu.path.pop(); + }, 300); } - state.submenu.depth = state.submenu.depth > 0 && depth + state.submenu.depth = state.submenu.depth > 0 && depth; }, - setSearchpanel (state, action) { - state.searchpanel = action === true - state.overlay = action === true + setSearchpanel(state, action) { + state.searchpanel = action === true; + state.overlay = action === true; }, - setWishlist (state, action) { - state.wishlist = action === true - state.overlay = action === true + setWishlist(state, action) { + state.wishlist = action === true; + state.overlay = action === true; }, - setOverlay (state, action) { - state.overlay = action === true + setOverlay(state, action) { + state.overlay = action === true; }, - setLoader (state, action) { - state.loader = action === true + setLoader(state, action) { + state.loader = action === true; }, - setAuthElem (state, action) { - state.authElem = action + setAuthElem(state, action) { + state.authElem = action; } }, actions: { - toggleMicrocart ({ commit, state }) { - commit('setMicrocart', !state.microcart) + toggleMicrocart({ commit, state }) { + commit('setMicrocart', !state.microcart); }, - toggleWishlist ({ commit, state }) { - commit('setWishlist', !state.wishlist) + toggleWishlist({ commit, state }) { + commit('setWishlist', !state.wishlist); } } -} +}; export const Ui = createModule({ key: KEY, store: { modules: [{ key: KEY, module: store }] } -}) \ No newline at end of file +}); diff --git a/src/server/index.js b/src/server/index.js index 9168238662..dfc892b7d9 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -1,7 +1,7 @@ // You can extend Vue Storefront server routes by binding to the Express.js (expressApp) in here -module.exports.registerUserServerRoutes = (expressApp) => { - require('./robots')(expressApp) -} +module.exports.registerUserServerRoutes = expressApp => { + require('./robots')(expressApp); +}; // Use can use dynamic config by using this function below: // (Needs to return a Promise) diff --git a/src/server/robots.js b/src/server/robots.js index 6d030b3af7..1638388928 100644 --- a/src/server/robots.js +++ b/src/server/robots.js @@ -1,6 +1,5 @@ - -module.exports = (expressApp) => { +module.exports = expressApp => { expressApp.get('/robots.txt', (req, res) => { - res.end('User-agent: *\nDisallow: ') - }) -} + res.end('User-agent: *\nDisallow: '); + }); +}; diff --git a/src/themes/default-amp/components/core/Header.vue b/src/themes/default-amp/components/core/Header.vue index 06e84c82fe..278f790aa6 100755 --- a/src/themes/default-amp/components/core/Header.vue +++ b/src/themes/default-amp/components/core/Header.vue @@ -12,7 +12,7 @@
- +
@@ -29,11 +29,16 @@
- +
-
+
diff --git a/src/themes/default-amp/pages/Product.vue b/src/themes/default-amp/pages/Product.vue index c5d8cf5134..d9abcf146b 100755 --- a/src/themes/default-amp/pages/Product.vue +++ b/src/themes/default-amp/pages/Product.vue @@ -9,7 +9,8 @@ width="450" height="500" layout="responsive" - type="slides"> + type="slides" + > + :height="500" + />
@@ -26,67 +28,102 @@ :routes="breadcrumbs.routes" :active-route="breadcrumbs" /> -

+

{{ product.name | htmlDecode }}

sku: {{ product.sku }}
- - + +
- {{ product.priceInclTax * product.qty | price }} -   + {{ (product.priceInclTax * product.qty) | price }}   - {{ product.originalPriceInclTax * product.qty | price }} + {{ (product.originalPriceInclTax * product.qty) | price }}
- {{ product.priceInclTax * product.qty | price }} + {{ (product.priceInclTax * product.qty) | price }}
-
+
{{ product.errors | formatProductMessages }}
- Check available sizes + Check available sizes
@@ -98,7 +135,7 @@
@@ -126,20 +163,20 @@ diff --git a/src/themes/default-amp/router/index.ts b/src/themes/default-amp/router/index.ts index 450c465e46..fe2e71953f 100755 --- a/src/themes/default-amp/router/index.ts +++ b/src/themes/default-amp/router/index.ts @@ -1,30 +1,108 @@ // import router from '@vue-storefront/core/router' // uncomment if you want to modify the router e.g. add before/after hooks -import Category from '../pages/Category.vue' -import Product from '../pages/Product.vue' -import { RouteConfig } from 'vue-router' +import Category from '../pages/Category.vue'; +import Product from '../pages/Product.vue'; +import { RouteConfig } from 'vue-router'; -import config from 'config' +import config from 'config'; -let routes: RouteConfig[] = [ -] +let routes: RouteConfig[] = []; if (!config.products.useShortCatalogUrls) { - routes = routes.concat([{ name: 'virtual-product-amp', path: '/amp/p/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'bundle-product-amp', path: '/amp/p/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'simple-product-amp', path: '/amp/p/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'downloadable-product-amp', path: '/amp/p/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'grouped-product-amp', path: '/amp/p/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'configurable-product-amp', path: '/amp/p/:parentSku/:slug/:childSku', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'product-amp', path: '/amp/p/:parentSku/:slug/:childSku', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'category-amp', path: '/amp/c/:slug', component: Category }]) + routes = routes.concat([ + { + name: 'virtual-product-amp', + path: '/amp/p/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'bundle-product-amp', + path: '/amp/p/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'simple-product-amp', + path: '/amp/p/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'downloadable-product-amp', + path: '/amp/p/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'grouped-product-amp', + path: '/amp/p/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'configurable-product-amp', + path: '/amp/p/:parentSku/:slug/:childSku', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'product-amp', + path: '/amp/p/:parentSku/:slug/:childSku', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { name: 'category-amp', path: '/amp/c/:slug', component: Category } + ]); } else { - routes = routes.concat([{ name: 'virtual-product-amp', path: '/amp/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'bundle-product-amp', path: '/amp/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'simple-product-amp', path: '/amp/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'downloadable-product-amp', path: '/amp/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'grouped-product-amp', path: '/amp/:parentSku/:slug', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'configurable-product-amp', path: '/amp/:parentSku/:slug/:childSku', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'product-amp', path: '/amp/:parentSku/:slug/:childSku', component: Product, meta: { layout: 'minimal' } }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site - { name: 'category-amp', path: '/amp/:slug', component: Category, meta: { layout: 'minimal' } }]) + routes = routes.concat([ + { + name: 'virtual-product-amp', + path: '/amp/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'bundle-product-amp', + path: '/amp/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'simple-product-amp', + path: '/amp/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'downloadable-product-amp', + path: '/amp/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'grouped-product-amp', + path: '/amp/:parentSku/:slug', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'configurable-product-amp', + path: '/amp/:parentSku/:slug/:childSku', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'product-amp', + path: '/amp/:parentSku/:slug/:childSku', + component: Product, + meta: { layout: 'minimal' } + }, // :sku param can be marked as optional with ":sku?" (https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js#L16), but it requires a lot of work to adjust the rest of the site + { + name: 'category-amp', + path: '/amp/:slug', + component: Category, + meta: { layout: 'minimal' } + } + ]); } -export default routes +export default routes; diff --git a/src/themes/default-amp/webpack.config.js b/src/themes/default-amp/webpack.config.js index f31eabdac6..1dc333bca0 100755 --- a/src/themes/default-amp/webpack.config.js +++ b/src/themes/default-amp/webpack.config.js @@ -1,4 +1,4 @@ // You can extend default webpack build here. Read more on docs: https://github.com/DivanteLtd/vue-storefront/blob/master/doc/Working%20with%20webpack.md -module.exports = function (config, { isClient, isDev }) { - return config -} +module.exports = function(config, { isClient, isDev }) { + return config; +}; diff --git a/src/themes/default/App.vue b/src/themes/default/App.vue index cb8bcb73a8..2360f28466 100755 --- a/src/themes/default/App.vue +++ b/src/themes/default/App.vue @@ -7,23 +7,26 @@ diff --git a/src/themes/default/assets/manifest.json b/src/themes/default/assets/manifest.json index 3069a0bdc7..1594888528 100644 --- a/src/themes/default/assets/manifest.json +++ b/src/themes/default/assets/manifest.json @@ -1,45 +1,45 @@ { - "short_name": "VSF Demo", - "name": "Vue Storefront", - "background_color": "#ffffff", - "display": "standalone", - "theme_color": "#ffffff", - "start_url": "/pwa.html", - "icons": [ - { - "src": "/assets/android-icon-48x48.png", - "type": "image/png", - "sizes": "48x48" - }, - { - "src": "/assets/android-icon-72x72.png", - "type": "image/png", - "sizes": "72x72" - }, - { - "src": "/assets/android-icon-96x96.png", - "type": "image/png", - "sizes": "96x96" - }, - { - "src": "/assets/android-icon-144x144.png", - "type": "image/png", - "sizes": "144x144" - }, - { - "src": "/assets/android-icon-168x168.png", - "type": "image/png", - "sizes": "168x168" - }, - { - "src": "/assets/android-icon-192x192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "/assets/android-icon-512x512.png", - "type": "image/png", - "sizes": "512x512" - } - ] - } + "short_name": "VSF Demo", + "name": "Vue Storefront", + "background_color": "#ffffff", + "display": "standalone", + "theme_color": "#ffffff", + "start_url": "/pwa.html", + "icons": [ + { + "src": "/assets/android-icon-48x48.png", + "type": "image/png", + "sizes": "48x48" + }, + { + "src": "/assets/android-icon-72x72.png", + "type": "image/png", + "sizes": "72x72" + }, + { + "src": "/assets/android-icon-96x96.png", + "type": "image/png", + "sizes": "96x96" + }, + { + "src": "/assets/android-icon-144x144.png", + "type": "image/png", + "sizes": "144x144" + }, + { + "src": "/assets/android-icon-168x168.png", + "type": "image/png", + "sizes": "168x168" + }, + { + "src": "/assets/android-icon-192x192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "/assets/android-icon-512x512.png", + "type": "image/png", + "sizes": "512x512" + } + ] +} diff --git a/src/themes/default/components/core/AddToCart.vue b/src/themes/default/components/core/AddToCart.vue index e991ee8edb..4078cdbd8c 100644 --- a/src/themes/default/components/core/AddToCart.vue +++ b/src/themes/default/components/core/AddToCart.vue @@ -1,34 +1,38 @@ diff --git a/src/themes/default/components/core/Breadcrumbs.vue b/src/themes/default/components/core/Breadcrumbs.vue index 0fb73675b5..92e0010116 100644 --- a/src/themes/default/components/core/Breadcrumbs.vue +++ b/src/themes/default/components/core/Breadcrumbs.vue @@ -3,7 +3,8 @@ {{ link.name | htmlDecode }} - / + + / {{ activeRoute | htmlDecode }} @@ -12,9 +13,9 @@ diff --git a/src/themes/default/components/core/ColorSelector.vue b/src/themes/default/components/core/ColorSelector.vue index 4bd1a5a31d..33d2ab44a0 100644 --- a/src/themes/default/components/core/ColorSelector.vue +++ b/src/themes/default/components/core/ColorSelector.vue @@ -1,6 +1,9 @@ diff --git a/src/themes/default/components/core/CookieNotification.vue b/src/themes/default/components/core/CookieNotification.vue index 93686a9cfd..f3d06991ee 100644 --- a/src/themes/default/components/core/CookieNotification.vue +++ b/src/themes/default/components/core/CookieNotification.vue @@ -7,7 +7,11 @@ {{ message }} - + {{ detailsLinkText }}
@@ -30,7 +34,7 @@ diff --git a/src/themes/default/components/core/LanguageSwitcher.vue b/src/themes/default/components/core/LanguageSwitcher.vue index 7f3a467b09..fa72a043e5 100644 --- a/src/themes/default/components/core/LanguageSwitcher.vue +++ b/src/themes/default/components/core/LanguageSwitcher.vue @@ -3,36 +3,37 @@ {{ country }} / {{ lang }} / {{ currency }} - +
- + diff --git a/src/themes/default/components/core/Loader.vue b/src/themes/default/components/core/Loader.vue index 756b8b5ee8..f8fe2ea699 100644 --- a/src/themes/default/components/core/Loader.vue +++ b/src/themes/default/components/core/Loader.vue @@ -2,8 +2,12 @@
-
-
+
+
diff --git a/src/themes/default/components/core/ProductAttribute.vue b/src/themes/default/components/core/ProductAttribute.vue index a3a2b582fa..0da21b3617 100644 --- a/src/themes/default/components/core/ProductAttribute.vue +++ b/src/themes/default/components/core/ProductAttribute.vue @@ -1,14 +1,14 @@ diff --git a/src/themes/default/components/core/ProductBundleOption.vue b/src/themes/default/components/core/ProductBundleOption.vue index 51bd8f8472..b9219b1a5e 100644 --- a/src/themes/default/components/core/ProductBundleOption.vue +++ b/src/themes/default/components/core/ProductBundleOption.vue @@ -1,7 +1,11 @@ diff --git a/src/themes/default/components/core/ProductBundleOptions.vue b/src/themes/default/components/core/ProductBundleOptions.vue index a247bb37a4..646c644603 100644 --- a/src/themes/default/components/core/ProductBundleOptions.vue +++ b/src/themes/default/components/core/ProductBundleOptions.vue @@ -1,21 +1,27 @@ - + diff --git a/src/themes/default/components/core/ProductCustomOptions.vue b/src/themes/default/components/core/ProductCustomOptions.vue index edadd6703e..c3bfb76be5 100644 --- a/src/themes/default/components/core/ProductCustomOptions.vue +++ b/src/themes/default/components/core/ProductCustomOptions.vue @@ -1,6 +1,9 @@ diff --git a/src/themes/default/components/core/ProductGallery.vue b/src/themes/default/components/core/ProductGallery.vue index fef0aa01d1..b150d90b6b 100644 --- a/src/themes/default/components/core/ProductGallery.vue +++ b/src/themes/default/components/core/ProductGallery.vue @@ -1,5 +1,8 @@ diff --git a/src/themes/default/components/core/ValidationError.vue b/src/themes/default/components/core/ValidationError.vue index c83c8e3d55..2b9ab73c4e 100644 --- a/src/themes/default/components/core/ValidationError.vue +++ b/src/themes/default/components/core/ValidationError.vue @@ -5,9 +5,9 @@ diff --git a/src/themes/default/components/core/blocks/Auth/ForgotPass.vue b/src/themes/default/components/core/blocks/Auth/ForgotPass.vue index 045e0e88d0..3ed3c41019 100644 --- a/src/themes/default/components/core/blocks/Auth/ForgotPass.vue +++ b/src/themes/default/components/core/blocks/Auth/ForgotPass.vue @@ -16,7 +16,11 @@

- {{ $t('Enter your email to receive instructions on how to reset your password.') }} + {{ + $t( + 'Enter your email to receive instructions on how to reset your password.' + ) + }}

- {{ $t("We've sent password reset instructions to your email. Check your inbox and follow the link.") }} + {{ + $t( + "We've sent password reset instructions to your email. Check your inbox and follow the link." + ) + }}

{{ $t('Back to login') }} @@ -62,11 +70,10 @@ diff --git a/src/themes/default/components/core/blocks/Auth/Login.vue b/src/themes/default/components/core/blocks/Auth/Login.vue index 95b0e3e449..89230923a7 100644 --- a/src/themes/default/components/core/blocks/Auth/Login.vue +++ b/src/themes/default/components/core/blocks/Auth/Login.vue @@ -11,7 +11,9 @@ {{ $t('Log in') }}
-

{{ $t('You need to be logged in to see this page') }}

+

+ {{ $t('You need to be logged in to see this page') }} +

diff --git a/src/themes/default/components/core/blocks/Auth/SignUp.vue b/src/themes/default/components/core/blocks/Auth/SignUp.vue index ec36bcf83d..869d068faf 100644 --- a/src/themes/default/components/core/blocks/Auth/SignUp.vue +++ b/src/themes/default/components/core/blocks/Auth/SignUp.vue @@ -7,11 +7,11 @@ diff --git a/src/themes/default/components/core/blocks/Category/CategoryPanel.vue b/src/themes/default/components/core/blocks/Category/CategoryPanel.vue index 0f29b253e6..d978005ab8 100644 --- a/src/themes/default/components/core/blocks/Category/CategoryPanel.vue +++ b/src/themes/default/components/core/blocks/Category/CategoryPanel.vue @@ -1,8 +1,6 @@ diff --git a/src/themes/default/components/core/blocks/Checkout/Payment.vue b/src/themes/default/components/core/blocks/Checkout/Payment.vue index d7e053e84b..dbbd600005 100644 --- a/src/themes/default/components/core/blocks/Checkout/Payment.vue +++ b/src/themes/default/components/core/blocks/Checkout/Payment.vue @@ -4,14 +4,20 @@
- {{ (isVirtualCart ? 2 : 3) }} + {{ isVirtualCart ? 2 : 3 }}
-
+

{{ $t('Payment') }}

@@ -30,7 +36,7 @@
-