From b2954181b92b8a02f2d466ee8a446a6fa336e37c Mon Sep 17 00:00:00 2001 From: "a.kornienko" Date: Fri, 14 Jul 2023 16:41:39 +0500 Subject: [PATCH] feat(PAYMENTS-15245): add legal component --- package-lock.json | 264 ++++++++++++++++-- package.json | 3 +- src/assets/icons/logo.svg | 8 + src/assets/images.d.ts | 1 + src/core/event-name.enum.ts | 3 + .../legal-config-event-message.guard.ts | 16 ++ .../web-component-tag-name.enum.ts | 1 + src/core/web-components/web-components.map.ts | 2 + ...get-legal-component-config.handler.spec.ts | 22 ++ .../get-legal-component-config.handler.ts | 21 ++ .../legal/legal-component.config.interface.ts | 10 + .../legal/legal.component.spec.ts | 167 +++++++++++ .../legal/legal.component.tempate.ts | 78 ++++++ .../legal/legal.component.template.spec.ts | 34 +++ .../web-components/legal/legal.component.ts | 85 ++++++ ...cure-connection.component.template.spec.ts | 27 ++ .../secure-connection.component.template.ts | 36 +++ src/translations/ar.json | 16 +- src/translations/bg.json | 16 +- src/translations/cs.json | 16 +- src/translations/de.json | 16 +- src/translations/en.json | 9 +- src/translations/es.json | 16 +- src/translations/fr.json | 16 +- src/translations/he.json | 16 +- src/translations/it.json | 16 +- src/translations/ja.json | 16 +- src/translations/ko.json | 16 +- src/translations/pl.json | 16 +- src/translations/pt.json | 16 +- src/translations/ro.json | 16 +- src/translations/ru.json | 16 +- src/translations/th.json | 16 +- src/translations/tr.json | 16 +- src/translations/vi.json | 16 +- src/translations/zh_HANS.json | 16 +- src/translations/zh_HANT.json | 16 +- src/web-components.ts | 8 +- webpack.config.js | 5 + 39 files changed, 975 insertions(+), 129 deletions(-) create mode 100644 src/assets/icons/logo.svg create mode 100644 src/assets/images.d.ts create mode 100644 src/core/guards/legal-config-event-message.guard.ts create mode 100644 src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.spec.ts create mode 100644 src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.ts create mode 100644 src/features/headless-checkout/web-components/legal/legal-component.config.interface.ts create mode 100644 src/features/headless-checkout/web-components/legal/legal.component.spec.ts create mode 100644 src/features/headless-checkout/web-components/legal/legal.component.tempate.ts create mode 100644 src/features/headless-checkout/web-components/legal/legal.component.template.spec.ts create mode 100644 src/features/headless-checkout/web-components/legal/legal.component.ts create mode 100644 src/features/headless-checkout/web-components/legal/secure-connection.component.template.spec.ts create mode 100644 src/features/headless-checkout/web-components/legal/secure-connection.component.template.ts diff --git a/package-lock.json b/package-lock.json index e267842..7b4e922 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "stylelint-config-prettier-scss": "^1.0.0", "stylelint-config-standard-scss": "^9.0.0", "stylelint-order": "^6.0.3", + "svgo-loader": "^4.0.0", "ts-loader": "^9.4.2", "typescript": "^5.0.4", "webpack": "^5.82.1", @@ -78,9 +79,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", - "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -153,16 +154,16 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", - "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", + "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.5", + "@babel/compat-data": "^7.22.9", "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.3", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -181,9 +182,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -273,9 +274,9 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { "@babel/types": "^7.22.5" @@ -1135,6 +1136,15 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -2152,6 +2162,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2263,9 +2279,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, "funding": [ { @@ -2275,13 +2291,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" }, "bin": { "browserslist": "cli.js" @@ -2399,9 +2419,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001488", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz", - "integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==", + "version": "1.0.30001515", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz", + "integrity": "sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA==", "dev": true, "funding": [ { @@ -3015,6 +3035,22 @@ "webpack": "^5.0.0" } }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -3028,6 +3064,18 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3040,6 +3088,39 @@ "node": ">=4" } }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, "node_modules/custom-event": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", @@ -3246,6 +3327,20 @@ "void-elements": "^2.0.0" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, "node_modules/domain-browser": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", @@ -3258,6 +3353,47 @@ "url": "https://bevry.me/fund" } }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -3283,9 +3419,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.397", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.397.tgz", - "integrity": "sha512-jwnPxhh350Q/aMatQia31KAIQdhEsYS0fFZ0BQQlN9tfvOEwShu6ZNwI4kL/xBabjcB/nTy6lSt17kNIluJZ8Q==", + "version": "1.4.457", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.457.tgz", + "integrity": "sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA==", "dev": true }, "node_modules/elliptic": { @@ -3382,6 +3518,18 @@ "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "dev": true }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -6912,9 +7060,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, "node_modules/normalize-package-data": { @@ -6953,6 +7101,18 @@ "node": ">=8" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9011,6 +9171,48 @@ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, + "node_modules/svgo": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", + "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.2.1", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svgo-loader/-/svgo-loader-4.0.0.tgz", + "integrity": "sha512-bdk2H73AHP8Vo9zgMuA8piEzi5pjFzllK4EwfebDF3hDjmHQpmmqXMoDd6abDtVFrlKTJuveepmnc2kuTdt/WA==", + "dev": true, + "dependencies": { + "svgo": "^3.0.0" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", diff --git a/package.json b/package.json index b058c15..4060097 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "devDependencies": { "@commitlint/cli": "^17.6.5", "@commitlint/config-conventional": "^17.6.5", - "@types/jasmine": "^4.3.2", "@types/i18next": "^13.0.0", + "@types/jasmine": "^4.3.2", "@types/prettier": "^2.7.2", "@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/parser": "^5.59.6", @@ -56,6 +56,7 @@ "stylelint-config-prettier-scss": "^1.0.0", "stylelint-config-standard-scss": "^9.0.0", "stylelint-order": "^6.0.3", + "svgo-loader": "^4.0.0", "ts-loader": "^9.4.2", "typescript": "^5.0.4", "webpack": "^5.82.1", diff --git a/src/assets/icons/logo.svg b/src/assets/icons/logo.svg new file mode 100644 index 0000000..5cedc5c --- /dev/null +++ b/src/assets/icons/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/images.d.ts b/src/assets/images.d.ts new file mode 100644 index 0000000..bff9471 --- /dev/null +++ b/src/assets/images.d.ts @@ -0,0 +1 @@ +declare module '*.svg'; diff --git a/src/core/event-name.enum.ts b/src/core/event-name.enum.ts index b36ea09..e11322e 100644 --- a/src/core/event-name.enum.ts +++ b/src/core/event-name.enum.ts @@ -6,4 +6,7 @@ export const enum EventName { getSavedMethods = 'getSavedMethods', getUserBalance = 'getUserBalance', submitButton = 'submitButton', + getLegalComponentConfig = 'getLegalComponentConfig', + legalComponentPing = 'legalComponentPing', + legalComponentPong = 'legalComponentPong', } diff --git a/src/core/guards/legal-config-event-message.guard.ts b/src/core/guards/legal-config-event-message.guard.ts new file mode 100644 index 0000000..0cc81f9 --- /dev/null +++ b/src/core/guards/legal-config-event-message.guard.ts @@ -0,0 +1,16 @@ +import { Message } from '../../core/message.interface'; +import { isEventMessage } from './event-message.guard'; +import { EventName } from '../../core/event-name.enum'; +import { LegalComponentConfig } from '../../features/headless-checkout/web-components/legal/legal-component.config.interface'; + +export const isLegalConfigEventMessage = ( + messageData: unknown +): messageData is Message<{ config: LegalComponentConfig }> => { + if (isEventMessage(messageData)) { + return ( + messageData.name === EventName.getLegalComponentConfig && + (messageData.data as { [key: string]: unknown })?.config !== undefined + ); + } + return false; +}; diff --git a/src/core/web-components/web-component-tag-name.enum.ts b/src/core/web-components/web-component-tag-name.enum.ts index 82ceda5..7234557 100644 --- a/src/core/web-components/web-component-tag-name.enum.ts +++ b/src/core/web-components/web-component-tag-name.enum.ts @@ -2,4 +2,5 @@ export enum WebComponentTagName { CardNumberComponent = 'psdk-card-number', SubmitButtonComponent = 'psdk-submit-button', PaymentMethodsComponent = 'psdk-payment-methods', + LegalComponent = 'psdk-legal', } diff --git a/src/core/web-components/web-components.map.ts b/src/core/web-components/web-components.map.ts index 21bb4a0..62cc671 100644 --- a/src/core/web-components/web-components.map.ts +++ b/src/core/web-components/web-components.map.ts @@ -2,6 +2,7 @@ import { CardNumberComponent } from '../../features/headless-checkout/web-compon import { SubmitButtonComponent } from '../../features/headless-checkout/web-components/submit-button/submit-button.component'; import { WebComponentTagName } from './web-component-tag-name.enum'; import { PaymentMethodsComponent } from '../../features/headless-checkout/web-components/payment-methods/payment-methods.component'; +import { LegalComponent } from '../../features/headless-checkout/web-components/legal/legal.component'; export const webComponents: { [key in WebComponentTagName]: CustomElementConstructor; @@ -9,4 +10,5 @@ export const webComponents: { [WebComponentTagName.CardNumberComponent]: CardNumberComponent, [WebComponentTagName.SubmitButtonComponent]: SubmitButtonComponent, [WebComponentTagName.PaymentMethodsComponent]: PaymentMethodsComponent, + [WebComponentTagName.LegalComponent]: LegalComponent, }; diff --git a/src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.spec.ts b/src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.spec.ts new file mode 100644 index 0000000..b463256 --- /dev/null +++ b/src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.spec.ts @@ -0,0 +1,22 @@ +import { EventName } from '../../../core/event-name.enum'; +import { Message } from '../../../core/message.interface'; +import { getLegalComponentConfigHandler } from './get-legal-component-config.handler'; +import { LegalComponentConfig } from '../web-components/legal/legal-component.config.interface'; + +const mockMessage: Message<{ config: LegalComponentConfig }> = { + name: EventName.getLegalComponentConfig, + data: { config: {} as unknown as LegalComponentConfig }, +}; +describe('getLegalComponentConfigHandler', () => { + it('Should handle data', () => { + expect(getLegalComponentConfigHandler(mockMessage)).toEqual({ + isHandled: true, + value: {} as unknown as LegalComponentConfig, + }); + }); + it('Should return null', () => { + expect( + getLegalComponentConfigHandler({ name: EventName.initPayment }) + ).toBeNull(); + }); +}); diff --git a/src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.ts b/src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.ts new file mode 100644 index 0000000..6e92c96 --- /dev/null +++ b/src/features/headless-checkout/post-messages-handlers/get-legal-component-config.handler.ts @@ -0,0 +1,21 @@ +import { Handler } from '../../../core/post-messages-client/handler.type'; +import { Message } from '../../../core/message.interface'; +import { EventName } from '../../../core/event-name.enum'; +import { LegalComponentConfig } from '../web-components/legal/legal-component.config.interface'; +import { isLegalConfigEventMessage } from '../../../core/guards/legal-config-event-message.guard'; + +export const getLegalComponentConfigHandler: Handler = ( + message: Message +): { isHandled: boolean; value: LegalComponentConfig } | null => { + if ( + isLegalConfigEventMessage(message) && + message.name === EventName.getLegalComponentConfig + ) { + const config = message.data?.config; + return { + isHandled: true, + value: config!, + }; + } + return null; +}; diff --git a/src/features/headless-checkout/web-components/legal/legal-component.config.interface.ts b/src/features/headless-checkout/web-components/legal/legal-component.config.interface.ts new file mode 100644 index 0000000..730c295 --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/legal-component.config.interface.ts @@ -0,0 +1,10 @@ +export interface LegalComponentConfig { + isJapanUser: boolean; + refundPolicyUrl: string; + sctlPolicyUrl?: string; + secureConnection: { + secureConnectionUrl?: string; + isWhiteLabel?: boolean; + }; + disclaimer?: string; +} diff --git a/src/features/headless-checkout/web-components/legal/legal.component.spec.ts b/src/features/headless-checkout/web-components/legal/legal.component.spec.ts new file mode 100644 index 0000000..419914d --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/legal.component.spec.ts @@ -0,0 +1,167 @@ +import { container } from 'tsyringe'; +import { WebComponentTagName } from '../../../../core/web-components/web-component-tag-name.enum'; +import { HeadlessCheckoutSpy } from '../../../../core/headless-checkout-spy/headless-checkout-spy'; +import { noopStub } from '../../../../tests/stubs/noop.stub'; +import { HeadlessCheckout } from '../../headless-checkout'; +import { LegalComponent } from './legal.component'; +import { PostMessagesClient } from '../../../../core/post-messages-client/post-messages-client'; +import { EventName } from '../../../../core/event-name.enum'; +import { LegalComponentConfig } from './legal-component.config.interface'; + +function createComponent(): void { + const element = document.createElement(WebComponentTagName.LegalComponent); + element.setAttribute('id', 'test'); + (document.getElementById('container')! as HTMLElement).appendChild(element); +} + +const mockConfig: LegalComponentConfig = { + isJapanUser: false, + refundPolicyUrl: 'refundPolicyUrl', + secureConnection: { + secureConnectionUrl: 'secureConnectionUrl', + }, +}; + +const delay = async (): Promise => + new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }); + }); + +describe('LegalComponent', () => { + let headlessCheckout: HeadlessCheckout; + let headlessCheckoutSpy: HeadlessCheckoutSpy; + let postMessagesClient: PostMessagesClient; + let windowService: Window; + + window.customElements.define( + WebComponentTagName.LegalComponent, + LegalComponent + ); + + beforeEach(() => { + document.body.innerHTML = '
'; + + headlessCheckout = { + getRegularMethods: noopStub, + } as unknown as HeadlessCheckout; + + headlessCheckoutSpy = { + listenAppInit: noopStub, + get appWasInit() { + return; + }, + } as unknown as HeadlessCheckoutSpy; + + postMessagesClient = { + send: noopStub, + } as unknown as PostMessagesClient; + + windowService = window; + + container + .register(HeadlessCheckoutSpy, { + useValue: headlessCheckoutSpy, + }) + .register(HeadlessCheckout, { + useValue: headlessCheckout, + }) + .register(PostMessagesClient, { + useValue: postMessagesClient, + }) + .register(Window, { useValue: windowService }); + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('Should create component', () => { + createComponent(); + expect( + document.querySelector(WebComponentTagName.LegalComponent) + ).toBeDefined(); + }); + + it('Should load legal component config', () => { + const spy = spyOn(postMessagesClient, 'send').and.returnValue( + Promise.resolve({}) + ); + spyOnProperty(headlessCheckoutSpy, 'appWasInit', 'get').and.returnValue( + true + ); + createComponent(); + expect(spy).toHaveBeenCalled(); + }); + + it('Should load legal component config after init', () => { + const spy = spyOn(postMessagesClient, 'send').and.returnValue( + Promise.resolve({}) + ); + const appWasInitSpy = spyOnProperty( + headlessCheckoutSpy, + 'appWasInit', + 'get' + ); + const listenAppInitSpy = spyOn(headlessCheckoutSpy, 'listenAppInit'); + listenAppInitSpy.and.callFake((callback: () => void) => { + appWasInitSpy.and.returnValue(true); + callback(); + }); + appWasInitSpy.and.returnValue(false); + createComponent(); + expect(spy).toHaveBeenCalled(); + }); + + it('Should call addEventListener', async () => { + spyOn(postMessagesClient, 'send').and.returnValue( + Promise.resolve(mockConfig) + ); + spyOnProperty(headlessCheckoutSpy, 'appWasInit', 'get').and.returnValue( + true + ); + const spy = spyOn(windowService, 'addEventListener'); + createComponent(); + await delay(); + expect(spy).toHaveBeenCalled(); + }); + + it('Should not call addEventListener', async () => { + spyOn(postMessagesClient, 'send').and.returnValue(Promise.resolve(null)); + spyOnProperty(headlessCheckoutSpy, 'appWasInit', 'get').and.returnValue( + true + ); + const spy = spyOn(windowService, 'addEventListener'); + createComponent(); + await delay(); + expect(spy).not.toHaveBeenCalled(); + }); + + it('Should send pong message', async () => { + spyOn(postMessagesClient, 'send').and.returnValue( + Promise.resolve(mockConfig) + ); + spyOnProperty(headlessCheckoutSpy, 'appWasInit', 'get').and.returnValue( + true + ); + spyOn(windowService, 'addEventListener').and.callFake( + (name: string, callback: (event: unknown) => void) => { + const messageEvent = { + data: JSON.stringify({ + name: EventName.legalComponentPing, + }), + origin: '', + source: { + postMessage: noopStub, + }, + }; + const spy = spyOn(messageEvent.source, 'postMessage'); + callback(messageEvent); + expect(spy).toHaveBeenCalled(); + } + ); + createComponent(); + await delay(); + }); +}); diff --git a/src/features/headless-checkout/web-components/legal/legal.component.tempate.ts b/src/features/headless-checkout/web-components/legal/legal.component.tempate.ts new file mode 100644 index 0000000..68104c4 --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/legal.component.tempate.ts @@ -0,0 +1,78 @@ +import { LegalComponentConfig } from './legal-component.config.interface'; +import { getSecureConnectionTemplate } from './secure-connection.component.template'; +import i18next from 'i18next'; + +export const getLegalComponentTemplate = ( + config: LegalComponentConfig +): string => { + const { + isJapanUser, + refundPolicyUrl, + sctlPolicyUrl, + secureConnection, + disclaimer, + } = config; + return ` + ${ + disclaimer + ? ` +
+ ${i18next.t('disclaimer')} +
` + : '' + } + ${getSecureConnectionTemplate(secureConnection)} + `; +}; diff --git a/src/features/headless-checkout/web-components/legal/legal.component.template.spec.ts b/src/features/headless-checkout/web-components/legal/legal.component.template.spec.ts new file mode 100644 index 0000000..5772ba1 --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/legal.component.template.spec.ts @@ -0,0 +1,34 @@ +import { getLegalComponentTemplate } from './legal.component.tempate'; +import { LegalComponentConfig } from './legal-component.config.interface'; + +const mockConfig: LegalComponentConfig = { + isJapanUser: false, + refundPolicyUrl: 'refundPolicyUrl', + sctlPolicyUrl: 'sctlPolicyUrl', + secureConnection: { + isWhiteLabel: true, + secureConnectionUrl: 'secureConnectionUrl', + }, + disclaimer: 'disclaimer', +}; + +const mockConfigJapan: LegalComponentConfig = { + isJapanUser: true, + refundPolicyUrl: 'refundPolicyUrl', + sctlPolicyUrl: 'sctlPolicyUrl', + secureConnection: { + isWhiteLabel: true, + secureConnectionUrl: 'secureConnectionUrl', + }, + disclaimer: 'disclaimer', +}; + +describe('getLegalComponentTemplate', () => { + it('Should contains legal-links', () => { + expect(getLegalComponentTemplate(mockConfig)).toContain('legal-links'); + }); + + it('Should contains sctl-link', () => { + expect(getLegalComponentTemplate(mockConfigJapan)).toContain('sctl-link'); + }); +}); diff --git a/src/features/headless-checkout/web-components/legal/legal.component.ts b/src/features/headless-checkout/web-components/legal/legal.component.ts new file mode 100644 index 0000000..90d8338 --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/legal.component.ts @@ -0,0 +1,85 @@ +import { WebComponentAbstract } from '../../../../core/web-components/web-component.abstract'; +import { container } from 'tsyringe'; +import { PostMessagesClient } from '../../../../core/post-messages-client/post-messages-client'; +import { EventName } from '../../../../core/event-name.enum'; +import { HeadlessCheckout } from '../../headless-checkout'; +import { getLegalComponentTemplate } from './legal.component.tempate'; +import { Message } from '../../../../core/message.interface'; +import { HeadlessCheckoutSpy } from '../../../../core/headless-checkout-spy/headless-checkout-spy'; +import { getLegalComponentConfigHandler } from '../../post-messages-handlers/get-legal-component-config.handler'; +import { LegalComponentConfig } from './legal-component.config.interface'; +import { isEventMessage } from '../../../../core/guards/event-message.guard'; + +export class LegalComponent extends WebComponentAbstract { + private readonly postMessagesClient: PostMessagesClient; + private readonly headlessCheckout: HeadlessCheckout; + private readonly headlessCheckoutSpy: HeadlessCheckoutSpy; + private readonly window: Window; + private config?: LegalComponentConfig; + + public constructor() { + super(); + this.headlessCheckoutSpy = container.resolve(HeadlessCheckoutSpy); + this.headlessCheckout = container.resolve(HeadlessCheckout); + this.postMessagesClient = container.resolve(PostMessagesClient); + this.window = container.resolve(Window); + } + + protected connectedCallback(): void { + if (!this.headlessCheckoutSpy.appWasInit) { + this.headlessCheckoutSpy.listenAppInit(() => this.connectedCallback()); + return; + } + void this.getLegalComponentConfig().then(this.configLoadedHandler); + } + + protected readonly configLoadedHandler = ( + config: LegalComponentConfig + ): void => { + this.config = config; + super.render(); + if (this.config) { + this.listenPings(); + } + }; + + protected listenPings(): void { + this.window.addEventListener('message', this.pingCallback); + } + + protected disconnectedCallback(): void { + super.disconnectedCallback(); + this.window.removeEventListener('message', this.pingCallback); + } + + protected async getLegalComponentConfig(): Promise { + const msg: Message = { + name: EventName.getLegalComponentConfig, + }; + + return this.postMessagesClient.send( + msg, + getLegalComponentConfigHandler + ) as Promise; + } + + protected getHtml(): string { + if (this.config) { + return getLegalComponentTemplate(this.config); + } + return ''; + } + + private readonly pingCallback = (message: MessageEvent): void => { + const data = JSON.parse(message.data); + if (!isEventMessage(data) || data.name !== EventName.legalComponentPing) { + return; + } + message.source?.postMessage( + JSON.stringify({ + name: EventName.legalComponentPong, + }), + message.origin as WindowPostMessageOptions + ); + }; +} diff --git a/src/features/headless-checkout/web-components/legal/secure-connection.component.template.spec.ts b/src/features/headless-checkout/web-components/legal/secure-connection.component.template.spec.ts new file mode 100644 index 0000000..f20bf9a --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/secure-connection.component.template.spec.ts @@ -0,0 +1,27 @@ +import { LegalComponentConfig } from './legal-component.config.interface'; +import { getSecureConnectionTemplate } from './secure-connection.component.template'; + +const mockSecureConnection: LegalComponentConfig['secureConnection'] = { + isWhiteLabel: false, + secureConnectionUrl: 'secureConnectionUrl', +}; + +const mockSecureConnectionWhiteLabel: LegalComponentConfig['secureConnection'] = + { + isWhiteLabel: true, + secureConnectionUrl: 'secureConnectionUrl', + }; + +describe('getSecureConnectionTemplate', () => { + it('Should contains legal-links', () => { + expect(getSecureConnectionTemplate(mockSecureConnection)).toContain( + 'logo-link' + ); + }); + + it('Should not draw link if is white label', () => { + expect( + getSecureConnectionTemplate(mockSecureConnectionWhiteLabel) + ).not.toContain('logo-link'); + }); +}); diff --git a/src/features/headless-checkout/web-components/legal/secure-connection.component.template.ts b/src/features/headless-checkout/web-components/legal/secure-connection.component.template.ts new file mode 100644 index 0000000..fa21ed0 --- /dev/null +++ b/src/features/headless-checkout/web-components/legal/secure-connection.component.template.ts @@ -0,0 +1,36 @@ +import { LegalComponentConfig } from './legal-component.config.interface'; +import logo from '../../../../assets/icons/logo.svg'; +import i18next from 'i18next'; +export const getSecureConnectionTemplate = ( + secureConnection?: LegalComponentConfig['secureConnection'] +): string => { + const isWhiteLabel = secureConnection?.isWhiteLabel; + const secureConnectionUrl = secureConnection?.secureConnectionUrl; + return ` +
+
+ ${ + !isWhiteLabel && secureConnectionUrl + ? ` + + ` + : ` + + ` + } +
+ ${i18next.t('secure-connection')} +
+
+
+`; +}; diff --git a/src/translations/ar.json b/src/translations/ar.json index b481222..d2eca88 100644 --- a/src/translations/ar.json +++ b/src/translations/ar.json @@ -1,7 +1,13 @@ { - "ar" : { - "translation" : { - "hello" : "مرحبًا بالعالم!" - } - } + "ar": { + "translation": { + "cookie-policy": "سياسة ملفات تعريف الارتباط", + "hello": "مرحبًا بالعالم!", + "legal": "قانوني", + "privacy-policy": "سياسة الخصوصية", + "refund-policy": "سياسة الاسترداد", + "sctl-indications": "SCTL Indications", + "secure-connection": "اتصال آمن" + } + } } diff --git a/src/translations/bg.json b/src/translations/bg.json index 4d8136d..80fba55 100644 --- a/src/translations/bg.json +++ b/src/translations/bg.json @@ -1,7 +1,13 @@ { - "bg" : { - "translation" : { - "hello" : "Здравей, свят!" - } - } + "bg": { + "translation": { + "cookie-policy": "Политика за бисквитките", + "hello": "Здравей, свят!", + "legal": "Правни документи", + "privacy-policy": "Политика за поверителност", + "refund-policy": "Политика за връщане на средства", + "sctl-indications": "SCTL Indications", + "secure-connection": "Сигурна връзка" + } + } } diff --git a/src/translations/cs.json b/src/translations/cs.json index add47be..4f85a98 100644 --- a/src/translations/cs.json +++ b/src/translations/cs.json @@ -1,7 +1,13 @@ { - "cs" : { - "translation" : { - "hello" : "Ahoj světe!" - } - } + "cs": { + "translation": { + "cookie-policy": "Zásady používání cookies", + "hello": "Ahoj světe!", + "legal": "Právní informace", + "privacy-policy": "Zásady ochrany osobních údajů", + "refund-policy": "Podmínky vrácení peněz", + "sctl-indications": "SCTL Indications", + "secure-connection": "Zabezpečené připojení" + } + } } diff --git a/src/translations/de.json b/src/translations/de.json index 126de0a..af4ea06 100644 --- a/src/translations/de.json +++ b/src/translations/de.json @@ -1,7 +1,13 @@ { - "de" : { - "translation" : { - "hello" : "Hallo Welt!" - } - } + "de": { + "translation": { + "cookie-policy": "Cookie-Richtlinie", + "hello": "Hallo Welt!", + "legal": "Rechtliches", + "privacy-policy": "Datenschutzerklärung", + "refund-policy": "Erstattungsrichtlinie", + "sctl-indications": "SCTL Indications", + "secure-connection": "Sichere Verbindung" + } + } } diff --git a/src/translations/en.json b/src/translations/en.json index 4fa6b8b..5a3a115 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1,7 +1,14 @@ { "en": { "translation": { - "hello": "Hello world!" + "disclaimer": "disclaimer", + "hello": "Hello world!", + "legal": "Legal", + "cookie-policy": "Cookie policy", + "privacy-policy": "Privacy policy", + "refund-policy": "Refund policy", + "sctl-indications": "SCTL Indications", + "secure-connection": "Secure connection" } } } diff --git a/src/translations/es.json b/src/translations/es.json index b58134a..cefcd9c 100644 --- a/src/translations/es.json +++ b/src/translations/es.json @@ -1,7 +1,13 @@ { - "es" : { - "translation" : { - "hello" : "¡Hola mundo!" - } - } + "es": { + "translation": { + "cookie-policy": "Política de cookies", + "hello": "¡Hola mundo!", + "legal": "Legal", + "privacy-policy": "Política de privacidad", + "refund-policy": "Política de reembolso", + "sctl-indications": "SCTL Indications", + "secure-connection": "Conexión segura" + } + } } diff --git a/src/translations/fr.json b/src/translations/fr.json index 59205a4..9297f93 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -1,7 +1,13 @@ { - "fr" : { - "translation" : { - "hello" : "Bonjour monde!" - } - } + "fr": { + "translation": { + "cookie-policy": "Politique en matière de cookies", + "hello": "Bonjour monde!", + "legal": "Juridique", + "privacy-policy": "Politique de confidentialité", + "refund-policy": "Politique de remboursement", + "sctl-indications": "SCTL Indications", + "secure-connection": "Connexion sécurisée" + } + } } diff --git a/src/translations/he.json b/src/translations/he.json index ae00390..67d3d64 100644 --- a/src/translations/he.json +++ b/src/translations/he.json @@ -1,7 +1,13 @@ { - "he" : { - "translation" : { - "hello" : "שלום עולם!" - } - } + "he": { + "translation": { + "cookie-policy": "מדיניות בנושא קובצי Cookie", + "hello": "שלום עולם!", + "legal": "משפטי", + "privacy-policy": "מדיניות פרטיות", + "refund-policy": "מדיניות החזרים כספיים", + "sctl-indications": "SCTL Indications", + "secure-connection": "חיבור מאובטח" + } + } } diff --git a/src/translations/it.json b/src/translations/it.json index fb1d344..3e0cc24 100644 --- a/src/translations/it.json +++ b/src/translations/it.json @@ -1,7 +1,13 @@ { - "it" : { - "translation" : { - "hello" : "Ciao mondo!" - } - } + "it": { + "translation": { + "cookie-policy": "Informativa sui Cookie", + "hello": "Ciao mondo!", + "legal": "Note legali", + "privacy-policy": "Informativa sulla Privacy", + "refund-policy": "Politica di Rimborso", + "sctl-indications": "SCTL Indications", + "secure-connection": "Connessione sicura" + } + } } diff --git a/src/translations/ja.json b/src/translations/ja.json index 1341522..dfd6b57 100644 --- a/src/translations/ja.json +++ b/src/translations/ja.json @@ -1,7 +1,13 @@ { - "ja" : { - "translation" : { - "hello" : "こんにちは、世界!" - } - } + "ja": { + "translation": { + "cookie-policy": "クッキーポリシー", + "hello": "こんにちは、世界!", + "legal": "法的文書", + "privacy-policy": "プライバシーポリシー", + "refund-policy": "返金ポリシー", + "sctl-indications": "特商法取引に基づく表示", + "secure-connection": "安全な接続" + } + } } diff --git a/src/translations/ko.json b/src/translations/ko.json index 6a13dd4..a081c99 100644 --- a/src/translations/ko.json +++ b/src/translations/ko.json @@ -1,7 +1,13 @@ { - "ko" : { - "translation" : { - "hello" : "안녕하세요 세상!" - } - } + "ko": { + "translation": { + "cookie-policy": "쿠키 정책", + "hello": "안녕하세요 세상!", + "legal": "법률", + "privacy-policy": "개인정보 보호정책", + "refund-policy": "환불 정책", + "sctl-indications": "SCTL Indications", + "secure-connection": "보안 연결" + } + } } diff --git a/src/translations/pl.json b/src/translations/pl.json index 0e46c41..ec8eeeb 100644 --- a/src/translations/pl.json +++ b/src/translations/pl.json @@ -1,7 +1,13 @@ { - "pl" : { - "translation" : { - "hello" : "Witaj świecie!" - } - } + "pl": { + "translation": { + "cookie-policy": "Polityka plików cookie", + "hello": "Witaj świecie!", + "legal": "Informacje prawne", + "privacy-policy": "Polityka prywatności", + "refund-policy": "Polityka zwrotów", + "sctl-indications": "SCTL Indications", + "secure-connection": "Bezpieczne połączenie" + } + } } diff --git a/src/translations/pt.json b/src/translations/pt.json index 525b224..95e6eae 100644 --- a/src/translations/pt.json +++ b/src/translations/pt.json @@ -1,7 +1,13 @@ { - "pt" : { - "translation" : { - "hello" : "Olá mundo!" - } - } + "pt": { + "translation": { + "cookie-policy": "Política de Cookies", + "hello": "Olá mundo!", + "legal": "Legal", + "privacy-policy": "Política de Privacidade", + "refund-policy": "Política de Reembolso", + "sctl-indications": "SCTL Indications", + "secure-connection": "Conexão segura" + } + } } diff --git a/src/translations/ro.json b/src/translations/ro.json index 796ce64..3d0582f 100644 --- a/src/translations/ro.json +++ b/src/translations/ro.json @@ -1,7 +1,13 @@ { - "ro" : { - "translation" : { - "hello" : "Salutare, lume!" - } - } + "ro": { + "translation": { + "cookie-policy": "Politica privind modulele cookie", + "hello": "Salutare, lume!", + "legal": "Juridic", + "privacy-policy": "Politica de confidențialitate", + "refund-policy": "Politica de retur", + "sctl-indications": "Indicații SCTL", + "secure-connection": "Conexiune securizată" + } + } } diff --git a/src/translations/ru.json b/src/translations/ru.json index 292cce3..486775b 100644 --- a/src/translations/ru.json +++ b/src/translations/ru.json @@ -1,7 +1,13 @@ { - "ru" : { - "translation" : { - "hello" : "Привет, мир!" - } - } + "ru": { + "translation": { + "cookie-policy": "Политика использования cookie", + "hello": "Привет, мир!", + "legal": "Юридические документы", + "privacy-policy": "Политика конфиденциальности", + "refund-policy": "Политика возврата", + "sctl-indications": "SCTL Indications", + "secure-connection": "Безопасное соединение" + } + } } diff --git a/src/translations/th.json b/src/translations/th.json index 4ed34ce..4ab9d46 100644 --- a/src/translations/th.json +++ b/src/translations/th.json @@ -1,7 +1,13 @@ { - "th" : { - "translation" : { - "hello" : "สวัสดีชาวโลก!" - } - } + "th": { + "translation": { + "cookie-policy": "นโยบายคุกกี้", + "hello": "สวัสดีชาวโลก!", + "legal": "ข้อมูลด้านกฎหมาย", + "privacy-policy": "นโยบายความเป็นส่วนตัว", + "refund-policy": "นโยบายการคืนเงิน", + "sctl-indications": "SCTL Indications", + "secure-connection": "การเชื่อมต่อที่ปลอดภัย" + } + } } diff --git a/src/translations/tr.json b/src/translations/tr.json index d21c794..ba56653 100644 --- a/src/translations/tr.json +++ b/src/translations/tr.json @@ -1,7 +1,13 @@ { - "tr" : { - "translation" : { - "hello" : "Merhaba dünya!" - } - } + "tr": { + "translation": { + "cookie-policy": "Çerez Politikası", + "hello": "Merhaba dünya!", + "legal": "Yasal", + "privacy-policy": "Gizlilik Politikası", + "refund-policy": "İade Politikası", + "sctl-indications": "SCTL Indications", + "secure-connection": "Güvenli bağlantı" + } + } } diff --git a/src/translations/vi.json b/src/translations/vi.json index a398083..4f5d1ac 100644 --- a/src/translations/vi.json +++ b/src/translations/vi.json @@ -1,7 +1,13 @@ { - "vi" : { - "translation" : { - "hello" : "Xin chào thế giới!" - } - } + "vi": { + "translation": { + "cookie-policy": "Chính sách cookie", + "hello": "Xin chào thế giới!", + "legal": "Pháp lý", + "privacy-policy": "Chính sách Quyền riêng tư", + "refund-policy": "Chính sách hoàn tiền", + "sctl-indications": "SCTL Indications", + "secure-connection": "Kết nối bảo mật" + } + } } diff --git a/src/translations/zh_HANS.json b/src/translations/zh_HANS.json index 4973be7..cc040c5 100644 --- a/src/translations/zh_HANS.json +++ b/src/translations/zh_HANS.json @@ -1,7 +1,13 @@ { - "zh_HANS" : { - "translation" : { - "hello" : "你好,世界!" - } - } + "zh_HANS": { + "translation": { + "cookie-policy": "Cookie政策", + "hello": "你好,世界!", + "legal": "法律信息", + "privacy-policy": "隐私政策", + "refund-policy": "退款政策", + "sctl-indications": "SCTL Indications", + "secure-connection": "安全连接" + } + } } diff --git a/src/translations/zh_HANT.json b/src/translations/zh_HANT.json index d8e2120..c723101 100644 --- a/src/translations/zh_HANT.json +++ b/src/translations/zh_HANT.json @@ -1,7 +1,13 @@ { - "zh_HANT" : { - "translation" : { - "hello" : "你好,世界!" - } - } + "zh_HANT": { + "translation": { + "cookie-policy": "Cookie 政策", + "hello": "你好,世界!", + "legal": "法律文件", + "privacy-policy": "隱私權政策", + "refund-policy": "退款政策", + "sctl-indications": "特定商業交易法聲明", + "secure-connection": "安全連線" + } + } } diff --git a/src/web-components.ts b/src/web-components.ts index 283b291..f83dbd2 100644 --- a/src/web-components.ts +++ b/src/web-components.ts @@ -1,5 +1,11 @@ import { SubmitButtonComponent } from './features/headless-checkout/web-components/submit-button/submit-button.component'; import { CardNumberComponent } from './features/headless-checkout/web-components/card-number/card-number.component'; import { PaymentMethodsComponent } from './features/headless-checkout/web-components/payment-methods/payment-methods.component'; +import { LegalComponent } from './features/headless-checkout/web-components/legal/legal.component'; -export { SubmitButtonComponent, CardNumberComponent, PaymentMethodsComponent }; +export { + SubmitButtonComponent, + CardNumberComponent, + PaymentMethodsComponent, + LegalComponent, +}; diff --git a/webpack.config.js b/webpack.config.js index d0c631c..5ff190c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,6 +20,11 @@ const config = { 'sass-loader', ], }, + { + test: /\.svg$/, + type: 'asset', + use: 'svgo-loader', + }, ], }, resolve: {