diff --git a/.github/workflows/checkout-cd-inte.yml b/.github/workflows/checkout-cd-inte.yml deleted file mode 100644 index 95d6b4c2a..000000000 --- a/.github/workflows/checkout-cd-inte.yml +++ /dev/null @@ -1,87 +0,0 @@ -name: Module checkout CD - -on: - pull_request: - types: [opened,edited,reopened,synchronize] - - -env: - MODULE_NAME: ps_checkout - GCLOUD_TOKEN_PATH: ./token.json - -jobs: - checkout_cd: - name: Module Checkout continuous deployment - runs-on: ubuntu-latest - timeout-minutes: 5 - if: contains(github.event.pull_request.labels.*.name, 'quality insurance needed') - - steps: - - name: Checkout the repository - uses: actions/checkout@v2 - - - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v0 - with: - project_id: ${{ secrets.GCLOUD_PROJECT_INTEGRATION }} - service_account_key: ${{ secrets.G_CREDENTIAL_INTEGRATION }} - export_default_credentials: true - - - name: Copy env files - run: | - gcloud components install beta - gcloud beta secrets versions access latest --secret="checkout-module" > .env - env: - GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.G_CREDENTIAL_INTEGRATION }} - - - name: Build module - run: | - composer install - cd _dev - yarn - - - name: Delete old module - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_INTEGRATION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") rm -rf modules/${{ env.MODULE_NAME }}' - - - name: Copy module - uses: appleboy/scp-action@master - with: - host: ${{ secrets.SSH_HOST_INTEGRATION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - source: "." - target: ${{ env.MODULE_NAME }} - - - name: Move module - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_INTEGRATION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - sudo su -c 'mv ${{ env.MODULE_NAME }} ${{ secrets.MODULE_PATH }}' - sudo su -c 'chown -R www-data:www-data ${{ secrets.MODULE_PATH }}/${{ env.MODULE_NAME }}' - - - name: Install module - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_INTEGRATION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") bin/console prestashop:module install ${{ env.MODULE_NAME }}' - - - name: Clear cache - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_INTEGRATION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") bin/console cache:cl' - sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") chmod -R 777 var/cache var/logs' diff --git a/.github/workflows/checkout-cd-prod-beta.yml b/.github/workflows/checkout-cd-prod-beta.yml deleted file mode 100644 index 447d97b7e..000000000 --- a/.github/workflows/checkout-cd-prod-beta.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Module checkout CD Production Beta - -on: - push: - tags: - - '*' - -env: - MODULE_NAME: ps_checkout - GCLOUD_TOKEN_PATH: ./token.json - -jobs: - checkout_cd: - name: Module Checkout continuous deployment - runs-on: ubuntu-latest - timeout-minutes: 5 - - steps: - - name: Checkout the repository - uses: actions/checkout@v2 - - - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v0 - with: - project_id: ${{ secrets.GCLOUD_PROJECT_PRODUCTION }} - service_account_key: ${{ secrets.G_CREDENTIAL_PRODUCTION }} - export_default_credentials: true - - - name: Copy env files - run: | - gcloud components install beta - gcloud beta secrets versions access latest --secret="checkout-module" > .env - env: - GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.G_CREDENTIAL_PRODUCTION }} - - - name: Build module - run: | - composer install - cd _dev - yarn - - - name: Delete old module - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_PRODUCTION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") rm -rf modules/${{ env.MODULE_NAME }}' - - - name: Copy module - uses: appleboy/scp-action@master - with: - host: ${{ secrets.SSH_HOST_PRODUCTION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - source: "." - target: ${{ env.MODULE_NAME }} - - - name: Move module - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_PRODUCTION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - sudo su -c 'mv ${{ env.MODULE_NAME }} ${{ secrets.MODULE_PATH }}' - sudo su -c 'chown -R www-data:www-data ${{ secrets.MODULE_PATH }}/${{ env.MODULE_NAME }}' - - - name: Install module - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_PRODUCTION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") bin/console prestashop:module install ${{ env.MODULE_NAME }}' - - - name: Clear cache - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.SSH_HOST_PRODUCTION }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") bin/console cache:cl' - sudo su -c 'docker exec $(docker ps -qf "name=${{ secrets.CONTAINER_NAME }}") chmod -R 777 var/cache var/logs' diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml deleted file mode 100644 index a4361e382..000000000 --- a/.github/workflows/js.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: JS tests -on: [push, pull_request] -jobs: - js-linter: - name: JS linter - runs-on: ubuntu-latest - if: ${{ contains(github.event.pull_request.labels.*.name, 'ready to review') }} - steps: - - name: Checkout - uses: actions/checkout@v2.0.0 - - name: lint js dependencies - uses: PrestaShopCorp/github-action-lint-js/12@v1.0 - with: - cmd: npm - path: ./ diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 8d66a0925..17c044885 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -36,7 +36,7 @@ jobs: - run: composer install - name: Run Header Stamp in Dry Run mode - run: php vendor/bin/header-stamp --license=vendor/prestashop/header-stamp/assets/afl.txt --exclude=.github,node_modules,vendor,tests,_dev --dry-run + run: php vendor/bin/header-stamp --license=vendor/prestashop/header-stamp/assets/afl.txt --exclude=.github,node_modules,vendor,tests --dry-run php-linter: name: PHP Syntax check 5.6|7.1|7.2|7.3|7.4 runs-on: ubuntu-latest diff --git a/.github/workflows/push-to-bucket.yml b/.github/workflows/push-to-bucket.yml index 4258c21ce..a94e1d77b 100644 --- a/.github/workflows/push-to-bucket.yml +++ b/.github/workflows/push-to-bucket.yml @@ -79,7 +79,7 @@ jobs: - name: Prepare zip for push đŸ‘· run: | cd ${{ inputs.repository-name }} - zip -r ../${{ needs.bucket-zip-name.outputs[inputs.env-lower] }} . -x '*.DS_Store*' '*.git*' '*/.php_cs.*' '*__MACOSX*' '*/node_modules' '*/.npmrc' '*/composer.*' '*/package.*' '*/.editorconfig' '*_dev*' '*test*' '*/tests/*' '*/Test/*' '*/Tests/*' '*/gha-creds-*.json' + zip -r ../${{ needs.bucket-zip-name.outputs[inputs.env-lower] }} . -x '*.DS_Store*' '*.git*' '*/.php_cs.*' '*__MACOSX*' '*/node_modules' '*/.npmrc' '*/composer.*' '*/package.*' '*/.editorconfig' '*test*' '*/tests/*' '*/Test/*' '*/Tests/*' '*/gha-creds-*.json' - name: Push to GCP bucket storage đŸ›©ïž shell: bash diff --git a/.github/workflows/update-release-draft.yml b/.github/workflows/update-release-draft.yml index 7ba2710ca..c9223286c 100644 --- a/.github/workflows/update-release-draft.yml +++ b/.github/workflows/update-release-draft.yml @@ -44,7 +44,7 @@ jobs: - name: Prepare zip for release đŸ‘· run: | cd ${{ inputs.repository-name }} - zip -r ../${{ env.ZIP_NAME }} . -x '*.DS_Store*' '*.git*' '*/.php_cs.*' '*__MACOSX*' '*/node_modules' '*/.npmrc' '*/composer.*' '*/package.*' '*/.editorconfig' '*_dev*' '*test*' '*/tests/*' '*/Test/*' '*/Tests/*' '*/gha-creds-*.json' + zip -r ../${{ env.ZIP_NAME }} . -x '*.DS_Store*' '*.git*' '*/.php_cs.*' '*__MACOSX*' '*/node_modules' '*/.npmrc' '*/composer.*' '*/package.*' '*/.editorconfig' '*test*' '*/tests/*' '*/Test/*' '*/Tests/*' '*/gha-creds-*.json' - name: Clean existing assets ♻ shell: bash diff --git a/.php_cs.dist b/.php_cs.dist index 7a5dbceb5..9830d6d3d 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -6,7 +6,6 @@ $config ->setUsingCache(true) ->getFinder() ->in(__DIR__) - ->exclude('_dev') ->exclude('vendor'); return $config; diff --git a/.well-known/apple-LIVE-merchantid-domain-association b/.well-known/apple-LIVE-merchantid-domain-association new file mode 100644 index 000000000..7668e4310 --- /dev/null +++ b/.well-known/apple-LIVE-merchantid-domain-association @@ -0,0 +1 @@ +7B227073704964223A2246354246304143324336314131413238313043373531453439333444414433384346393037313041303935303844314133453241383436314141363232414145222C2276657273696F6E223A312C22637265617465644F6E223A313731353230343037313232362C227369676E6174757265223A223330383030363039326138363438383666373064303130373032613038303330383030323031303133313064333030623036303936303836343830313635303330343032303133303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038313636333463386230653330353731373330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433323334333033343332333933313337333433373332333735613137306433323339333033343332333833313337333433373332333635613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306336663032336362323631346262333033383838613136323938336531613933663130353666353066613738636462396261346361323431636331346532356530323231303062653363643064666431363234376636343934343735333830653964343463323238613130383930613361316463373234623862346362383838393831386263333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031383833303832303138343032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383136363334633862306533303537313733303062303630393630383634383031363530333034303230316130383139333330313830363039326138363438383666373064303130393033333130623036303932613836343838366637306430313037303133303163303630393261383634383836663730643031303930353331306631373064333233343330333533303338333233313333333433333331356133303238303630393261383634383836663730643031303933343331316233303139333030623036303936303836343830313635303330343032303161313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230353936643939343335373738303366313137346361653066633761343164383634653964366266336535363638646164356563393334303937313439633762623330306130363038326138363438636533643034303330323034343733303435303232313030383565623363643837343731346466343461333830373838643439626537656630303630643765313236633966653638663261333336386363623233373363643032323035366535336363363330376433393561643465663532376234333531323462616636653761383537363030616463376135343561333862613039376139643734303030303030303030303030227D \ No newline at end of file diff --git a/.well-known/apple-SANDBOX-merchantid-domain-association b/.well-known/apple-SANDBOX-merchantid-domain-association new file mode 100644 index 000000000..976bc9863 --- /dev/null +++ b/.well-known/apple-SANDBOX-merchantid-domain-association @@ -0,0 +1 @@ +7B227073704964223A2241443631324543383841333039314132314539434132433035304439454130353741414535444341304542413237424243333838463239344231353534434233222C2276657273696F6E223A312C22637265617465644F6E223A313731353237313630333931352C227369676E6174757265223A223330383030363039326138363438383666373064303130373032613038303330383030323031303133313064333030623036303936303836343830313635303330343032303133303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038313636333463386230653330353731373330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433323334333033343332333933313337333433373332333735613137306433323339333033343332333833313337333433373332333635613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306336663032336362323631346262333033383838613136323938336531613933663130353666353066613738636462396261346361323431636331346532356530323231303062653363643064666431363234376636343934343735333830653964343463323238613130383930613361316463373234623862346362383838393831386263333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031383833303832303138343032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383136363334633862306533303537313733303062303630393630383634383031363530333034303230316130383139333330313830363039326138363438383666373064303130393033333130623036303932613836343838366637306430313037303133303163303630393261383634383836663730643031303930353331306631373064333233343330333533303339333133363332333033303333356133303238303630393261383634383836663730643031303933343331316233303139333030623036303936303836343830313635303330343032303161313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230633364366466616634636131326539643331666630363161636563303536613232653131386261333262633934346664323166336231373838363634646634363330306130363038326138363438636533643034303330323034343733303435303232313030633961346263306665316537366332356636343136303264306238313462363666643264376534623263636537343138633132343532313866356230353963363032323036623632373361383536363830633738313064303131333538666463383563633764303730656531393736333234316537356336636237353732326164303930303030303030303030303030227D \ No newline at end of file diff --git a/src/Api/Payment/Client/index.php b/.well-known/index.php old mode 100755 new mode 100644 similarity index 100% rename from src/Api/Payment/Client/index.php rename to .well-known/index.php diff --git a/Makefile b/Makefile deleted file mode 100644 index 23e0ff4b5..000000000 --- a/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -help: - @egrep "^#" Makefile - -# target: docker-build|db - Setup/Build PHP & (node)JS dependencies -db: docker-build -docker-build: build-back build-front - -build-back: - docker-compose run --rm php sh -c "composer install" - -build-back-prod: - docker-compose run --rm php sh -c "composer install --no-dev -o" - -build-front: - docker-compose run --rm node sh -c "npm i --prefix ./_dev/js/front" - docker-compose run --rm node sh -c "npm run build --prefix ./_dev/js/front" - -# target: watch-front - Watcher for the vueJS files -watch-front: - docker-compose run --rm node sh -c "npm run watch --prefix ./_dev/js/front" - -# target: test-front - Launch the front test suite -test-front: - docker-compose run --rm node sh -c "npm test --prefix ./_dev/js/front" - -build-zip: - cp -Ra $(PWD) /tmp/ps_checkout - rm -rf /tmp/ps_checkout/.env.test - rm -rf /tmp/ps_checkout/.php_cs.* - rm -rf /tmp/ps_checkout/.travis.yml - rm -rf /tmp/ps_checkout/cloudbuild.yaml - rm -rf /tmp/ps_checkout/composer.* - rm -rf /tmp/ps_checkout/package.json - rm -rf /tmp/ps_checkout/.npmrc - rm -rf /tmp/ps_checkout/package-lock.json - rm -rf /tmp/ps_checkout/.gitignore - rm -rf /tmp/ps_checkout/deploy.sh - rm -rf /tmp/ps_checkout/.editorconfig - rm -rf /tmp/ps_checkout/.git - rm -rf /tmp/ps_checkout/.github - rm -rf /tmp/ps_checkout/_dev - rm -rf /tmp/ps_checkout/tests - rm -rf /tmp/ps_checkout/docker-compose.yml - rm -rf /tmp/ps_checkout/Makefile - mv -v /tmp/ps_checkout $(PWD)/ps_checkout - zip -r ps_checkout.zip ps_checkout - rm -rf $(PWD)/ps_checkout - -# target: build-zip-prod - Launch prod zip generation of the module (will not work on windows) -build-zip-prod: build-back-prod test-front build-front build-zip diff --git a/README.md b/README.md index 0aa0823cb..cfa79f91c 100755 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@ -

PrestaShop Checkout

- # PrestaShop Checkout ![PHP tests](https://github.com/PrestaShopCorp/ps_checkout/workflows/PHP%20tests/badge.svg) -![NodeJS tests](https://github.com/PrestaShopCorp/ps_checkout/workflows/NodeJS%20tests/badge.svg) ![JS tests](https://github.com/PrestaShopCorp/ps_checkout/workflows/JS%20tests/badge.svg) ![Build & Release draft](https://github.com/PrestaShopCorp/ps_checkout/workflows/Build%20&%20Release%20draft/badge.svg) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/prestashopcorp/ps_checkout) @@ -15,48 +12,27 @@ PrestaShop official payment module in partnership with PayPal. ## Reporting issues -In order to contact the team, please use the link available in the +In order to contact the team, please use the [link][contact-us] available in the back-office once logged to your PrestaShop account. -## Building the module - -### Direct download +## Direct download If you want to get a zip ready to install on your shop. You can directly download it by clicking [here][direct-download]. -### Production - -1. Clone this repo `git clone git@github.com:PrestaShop/ps_checkout.git` -2. `make build-prod-zip` - -The zip will be generated in the root directory of the module. - -### Development - -1. Clone this repo -2. `make docker-build` -3. `make watch-front` - -I also recommend you to install the [vuejs-devtools][vuejs-devtools]. - -#### Switch on sanbox (Advanced) - -PayPal offers a sandbox mode in which an order can be created without -involving actual money. - -To enable it, reach the module configuration page, then replace `#...` at the end of the URL with `#/experimental`. - -This route allow you to acces to some experimental features (like paypal sandbox). Don't use them in a production environment until these features are officially released. - ## Contributing PrestaShop modules are open source extensions to the PrestaShop e-commerce solution. Everyone is welcome and even encouraged to contribute with their own improvements. ### Requirements +There 3 main branches on the repository: +- `prestashop/8.x` is the branch for PrestaShop v8.x +- `prestashop/1.7.x` is the branch for PrestaShop v1.7.x +- `prestashop/1.6.1.x` is the branch for PrestaShop v1.6.1.x + Contributors **must** follow the following rules: -* **Make your Pull Request on the "dev" branch**, NOT the "master" branch. +* Use the main branch `prestashop/1.7.x` * Do not update the module's version number. * Follow [the coding standards][1]. @@ -66,11 +42,11 @@ Contributors wishing to edit a module's files should follow the following proces 1. Create your GitHub account, if you do not have one already. 2. Fork this project to your GitHub account. -3. Clone your fork to your local machine in the ```/modules``` directory of your PrestaShop installation. +3. Clone your fork to your local machine in the `/modules` directory of your PrestaShop installation. 4. Create a branch in your local clone of the module for your changes. 5. Change the files in your branch. Be sure to follow the [coding standards][1]! 6. Push your changed branch to your fork in your GitHub account. -7. Create a pull request for your changes **on the _'dev'_ branch** of the module's project. Be sure to follow the [contribution guidelines][2] in your pull request. If you need help to make a pull request, read the [GitHub help page about creating pull requests][3]. +7. Create a pull request for your changes on the `prestashop/1.7.x` branch of the module's project. Be sure to follow the [contribution guidelines][2] in your pull request. If you need help to make a pull request, read the [GitHub help page about creating pull requests][3]. 8. Wait for one of the core developers either to include your change in the codebase, or to comment on possible improvements you should make to your code. That's it: you have contributed to this open source project! Congratulations! @@ -79,9 +55,8 @@ That's it: you have contributed to this open source project! Congratulations! This module is released under the [Academic Free License 3.0][AFL-3.0] -[vuejs]: https://vuejs.org/ -[vuejs-devtools]: https://github.com/vuejs/vue-devtools -[direct-download]: https://github.com/PrestaShop/ps_checkout/releases/latest/download/ps_checkout.zip +[contact-us]: https://help-center.prestashop.com/contact?psx=ps_checkout +[direct-download]: https://github.com/PrestaShopCorp/ps_checkout/releases [1]: https://devdocs.prestashop.com/1.7/development/coding-standards/ [2]: https://devdocs.prestashop.com/1.7/contribute/contribution-guidelines/ [3]: https://help.github.com/articles/using-pull-requests diff --git a/_dev/js/front/.babelrc b/_dev/js/front/.babelrc deleted file mode 100644 index 644dde977..000000000 --- a/_dev/js/front/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@babel/preset-env"], - "plugins": ["@babel/plugin-proposal-class-properties"] -} diff --git a/_dev/js/front/.browserslistrc b/_dev/js/front/.browserslistrc deleted file mode 100644 index 3e240b5f4..000000000 --- a/_dev/js/front/.browserslistrc +++ /dev/null @@ -1,4 +0,0 @@ -> 1% -last 2 versions -not dead -IE 11 diff --git a/_dev/js/front/.eslintrc.js b/_dev/js/front/.eslintrc.js deleted file mode 100644 index ce2ec90fa..000000000 --- a/_dev/js/front/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - es6: true, - jest: true, - node: true - }, - extends: ['eslint:recommended'], - parser: 'babel-eslint', - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module' - }, - plugins: ['babel'], - rules: { - 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' - } -}; diff --git a/_dev/js/front/.gitignore b/_dev/js/front/.gitignore deleted file mode 100644 index 121cfd2e8..000000000 --- a/_dev/js/front/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -.DS_Store -node_modules -/dist - -/tests/e2e/videos/ -/tests/e2e/screenshots/ - -# Coverage metadata -/coverage/ - -# local env files -.env -.env.local -.env.*.local - -# Log files -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/_dev/js/front/.prettierrc.js b/_dev/js/front/.prettierrc.js deleted file mode 100644 index dd1819414..000000000 --- a/_dev/js/front/.prettierrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - htmlWhitespaceSensitivity: 'ignore', - semi: true, - singleQuote: true, - trailingComma: 'none' -}; diff --git a/_dev/js/front/jest.config.json b/_dev/js/front/jest.config.json deleted file mode 100644 index 535f5fefe..000000000 --- a/_dev/js/front/jest.config.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "clearMocks": true, - "collectCoverageFrom": [ - "src/*.js", - "src/**/*.js", - "!src/utils/extra/**", - "!src/utils/extra/**/*", - "!src/utils/polyfills/**", - "!src/utils/polyfills/**/*" - ], - "setupFiles": [ - "./test/setup.js" - ], - "testMatch": [ - "**/src/*.spec.js", - "**/src/**/*.spec.js" - ], - "transform": { - "\\.[jt]sx?$": "babel-jest" - } -} diff --git a/_dev/js/front/package-lock.json b/_dev/js/front/package-lock.json deleted file mode 100644 index 7c805387d..000000000 --- a/_dev/js/front/package-lock.json +++ /dev/null @@ -1,12924 +0,0 @@ -{ - "name": "ps_checkout-frontoffice", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "ps_checkout-frontoffice", - "license": "AFL-3.0", - "dependencies": { - "@paypal/paypal-js": "^8.0.0", - "@ungap/event-target": "^0.2.2", - "classlist-polyfill": "^1.2.0", - "promise-polyfill": "8.1.3", - "url-polyfill": "^1.1.9", - "whatwg-fetch": "^3.0.0" - }, - "devDependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.3", - "babel-loader": "^8.1.0", - "bottlejs": "^2.0.0", - "core-js": "^3.7.0", - "eslint": "^7.12.1", - "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-prettier": "^3.1.4", - "jest": "^26.6.3", - "prettier": "^2.1.2", - "regenerator-runtime": "^0.13.7", - "terser-webpack-plugin": "^4.2.3", - "webpack": "^4.44.2", - "webpack-cli": "^4.1.0", - "webpack-merge": "^5.3.0" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", - "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "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" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", - "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, - "node_modules/@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime/node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "dev": true, - "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "node_modules/@npmcli/fs/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/fs/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@paypal/paypal-js": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@paypal/paypal-js/-/paypal-js-8.0.2.tgz", - "integrity": "sha512-JbWXxMsTDUE4j+JXAu04qBacjkP6/38lgGC5YKW/FBfU1v3S5EgjfF1cMCGFehcpmsU5T88rkpKDsuftrCkyCA==", - "dependencies": { - "promise-polyfill": "^8.3.0" - } - }, - "node_modules/@paypal/paypal-js/node_modules/promise-polyfill": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", - "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==" - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.11.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", - "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "15.0.19", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", - "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@ungap/event-target": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ungap/event-target/-/event-target-0.2.4.tgz", - "integrity": "sha512-u9Fd3k2qfMtn+0dxbCn/y0pzQ9Ucw6lWR984CrHcbxc+WzcMkJE4VjWHWSb9At40MjwMyHCkJNXroS55Osshhw==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", - "dev": true, - "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "peerDependencies": { - "ajv": ">=5.0.0" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", - "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", - "dev": true, - "dependencies": { - "object.assign": "^4.1.4", - "util": "^0.10.4" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "optional": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "eslint": ">= 4.12.1" - } - }, - "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dev": true, - "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dev": true, - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.5.0", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/bottlejs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bottlejs/-/bottlejs-2.0.1.tgz", - "integrity": "sha512-50T0bzqeAqZ+//kgjdDxNu7UP8Je04isNPyHPwwOOPoeZmtVESkuF9nwkWEqSEd9Sw1yJ1oaoHBAMxe/wG4Zzg==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001580", - "electron-to-chromium": "^1.4.648", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", - "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "set-function-length": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "optional": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "dev": true - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/classlist-polyfill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/classlist-polyfill/-/classlist-polyfill-1.2.0.tgz", - "integrity": "sha512-GzIjNdcEtH4ieA2S8NmrSxv7DfEV5fmixQeyTmqmRmRJPGpRBaSnA2a0VrCjyT8iW8JjEdMbKzDotAJf+ajgaQ==" - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-concurrently/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/copy-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-js": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz", - "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.1.tgz", - "integrity": "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw==", - "dev": true, - "dependencies": { - "browserslist": "^4.22.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/cyclist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz", - "integrity": "sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==", - "dev": true - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", - "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.2", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true, - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "deprecated": "Use your platform's native DOMException instead", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.665", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.665.tgz", - "integrity": "sha512-UpyCWObBoD+nSZgOC2ToaIdZB0r9GhqT2WahPKiSki6ckkSuKhQNso8V2PrFcHBMleI/eqbKgVQgVC4Wni4ilw==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz", - "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==", - "dev": true, - "dependencies": { - "eslint-rule-composer": "^0.3.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": ">=4.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-rule-composer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/expect/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expect/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "deprecated": "This module is no longer supported.", - "dev": true - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", - "dev": true, - "optional": true - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", - "dev": true - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dev": true, - "dependencies": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dev": true, - "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", - "dev": true, - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/move-concurrently/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/move-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true, - "optional": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "dev": true, - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "node_modules/node-notifier/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-notifier/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-notifier/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "optional": true - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", - "dev": true - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true, - "optional": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true - }, - "node_modules/promise-polyfill": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz", - "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "optional": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dev": true, - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "engines": { - "node": "6.* || >= 7.*" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", - "dev": true, - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/sane/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sane/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sane/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/sane/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/sane/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/semver": { - "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" - } - }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.2", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, - "node_modules/side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz", - "integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", - "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", - "dev": true, - "dependencies": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/url-polyfill": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz", - "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==" - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" - } - }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "dev": true, - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "optional": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "optional": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "dev": true, - "optional": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "optional": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "optional": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "optional": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "optional": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "optional": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "4.47.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz", - "integrity": "sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - }, - "webpack-command": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "cross-spawn": "^7.0.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "@webpack-cli/migrate": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/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/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/webpack/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webpack/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/webpack/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/webpack/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/webpack/node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/webpack/node_modules/terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", - "dev": true, - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/webpack/node_modules/terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dev": true, - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "dependencies": { - "errno": "~0.1.7" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/_dev/js/front/package.json b/_dev/js/front/package.json deleted file mode 100644 index bcdb828e6..000000000 --- a/_dev/js/front/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "author": "PrestaShop", - "name": "ps_checkout-frontoffice", - "homepage": "https://github.com/PrestaShopCorp/ps_checkout", - "repository": { - "type": "git", - "url": "git+https://github.com/PrestaShopCorp/ps_checkout.git" - }, - "scripts": { - "build": "webpack --config ./webpack/profile/build.js", - "test": "jest", - "coverage": "jest --collectCoverage", - "watch": "webpack --config ./webpack/profile/watch.js --watch" - }, - "devDependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.3", - "babel-loader": "^8.1.0", - "bottlejs": "^2.0.0", - "core-js": "^3.7.0", - "eslint": "^7.12.1", - "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-prettier": "^3.1.4", - "jest": "^26.6.3", - "prettier": "^2.1.2", - "regenerator-runtime": "^0.13.7", - "terser-webpack-plugin": "^4.2.3", - "webpack": "^4.44.2", - "webpack-cli": "^4.1.0", - "webpack-merge": "^5.3.0" - }, - "dependencies": { - "@paypal/paypal-js": "^8.0.0", - "@ungap/event-target": "^0.2.2", - "classlist-polyfill": "^1.2.0", - "promise-polyfill": "8.1.3", - "url-polyfill": "^1.1.9", - "whatwg-fetch": "^3.0.0" - }, - "license": "AFL-3.0", - "private": true -} diff --git a/_dev/js/front/src/api/ps-checkout.api.js b/_dev/js/front/src/api/ps-checkout.api.js deleted file mode 100644 index 36dba4707..000000000 --- a/_dev/js/front/src/api/ps-checkout.api.js +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseClass } from '../core/dependency-injection/base.class'; - -export class PsCheckoutApi extends BaseClass { - static Inject = { - config: 'PsCheckoutConfig', - $: '$' - }; - - postCancelOrder(data) { - return fetch(this.config.cancelUrl, { - method: 'post', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json' - }, - body: JSON.stringify(data) - }).then((response) => { - const contentType = response.headers.get('content-type'); - const isJsonResponse = - contentType && contentType.indexOf('application/json') !== -1; - - if (false === response.ok) { - if (isJsonResponse) { - return response.json().then((response) => { - throw response.body && response.body.error - ? response.body.error - : { message: this.$('checkout.form.error.label') }; - }); - } - - throw new Error(this.$('checkout.form.error.label')); - } - }); - } - - postCheckCartOrder(data, actions) { - return this.config.orderId - ? fetch(this.config.checkCartUrl, { - method: 'post', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json' - }, - body: JSON.stringify(data) - }) - .then((response) => { - const contentType = response.headers.get('content-type'); - const isJsonResponse = - contentType && contentType.indexOf('application/json') !== -1; - - if (isJsonResponse) { - if (false === response.ok) { - return response.json().then((response) => { - throw response.body && response.body.error - ? response.body.error - : { message: this.$('checkout.form.error.label') }; - }); - } - - return response.json(); - } - - throw new Error(this.$('checkout.form.error.label')); - }) - .then((data) => { - if (!data) { - return actions.reject(); - } else { - return actions.resolve(); - } - }) - : Promise.resolve().then(() => actions.resolve()); - } - - /** - * @param {*} [data] - * @returns {Promise} - */ - postCreateOrder(data) { - return fetch(this.config.createUrl, { - method: 'post', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json' - }, - ...(data ? { body: JSON.stringify(data) } : {}) - }) - .then((response) => { - const contentType = response.headers.get('content-type'); - const isJsonResponse = - contentType && contentType.indexOf('application/json') !== -1; - - if (isJsonResponse) { - if (false === response.ok || response.status >= 400) { - return response.json().then((response) => { - throw response.body && response.body.error - ? response.body.error - : { message: this.$('checkout.form.error.label') }; - }); - } - - return response.json(); - } - - throw new Error(this.$('checkout.form.error.label')); - }) - .then(({ body: { orderID } }) => orderID); - } - - postValidateOrder(data, actions) { - return fetch(this.config.validateOrderUrl, { - method: 'post', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json' - }, - body: JSON.stringify(data) - }) - .then((response) => { - const contentType = response.headers.get('content-type'); - const isJsonResponse = - contentType && contentType.indexOf('application/json') !== -1; - - if (isJsonResponse) { - if (false === response.ok || response.status >= 400) { - return response.json().then((response) => { - if ( - actions?.restart && - response.body && - 85 === response.body.error.code - ) { - return actions.restart(); - } - - throw response.body && response.body.error - ? response.body.error - : { message: this.$('checkout.form.error.label') }; - }); - } - - return response.json(); - } - - throw new Error(this.$('checkout.form.error.label')); - }) - .then((response) => { - if (response.body && response.body.id_order) { - const { - id_cart, - id_module, - id_order, - secure_key, - paypal_order, - paypal_transaction - } = response.body; - - const confirmationUrl = new URL(this.config.confirmationUrl); - confirmationUrl.searchParams.append('id_cart', id_cart); - confirmationUrl.searchParams.append('id_module', id_module); - confirmationUrl.searchParams.append('id_order', id_order); - confirmationUrl.searchParams.append('key', secure_key); - confirmationUrl.searchParams.append('paypal_order', paypal_order); - confirmationUrl.searchParams.append( - 'paypal_transaction', - paypal_transaction - ); - - window.location.href = confirmationUrl.toString(); - } - }); - } - - postExpressCheckoutOrder(data, actions) { - return actions.order.get().then(({ payer, purchase_units }) => - fetch(this.config.expressCheckoutUrl, { - method: 'post', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json' - }, - body: JSON.stringify({ - ...data, - order: { - payer: payer, - shipping: purchase_units[0].shipping - } - }) - }).then((response) => { - const contentType = response.headers.get('content-type'); - const isJsonResponse = - contentType && contentType.indexOf('application/json') !== -1; - - if (isJsonResponse) { - if (false === response.ok || response.status >= 400) { - return response.json().then((response) => { - throw response.body && response.body.error - ? response.body.error - : { message: this.$('checkout.form.error.label') }; - }); - } - - window.location.href = new URL( - this.config.checkoutCheckoutUrl - ).toString(); - - return; - } - - throw new Error(this.$('checkout.form.error.label')); - }) - ); - } -} diff --git a/_dev/js/front/src/components/1_6/express-button-cart.component.js b/_dev/js/front/src/components/1_6/express-button-cart.component.js deleted file mode 100644 index f555e8459..000000000 --- a/_dev/js/front/src/components/1_6/express-button-cart.component.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class ExpressButtonCartComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCart(); - } - - renderComponent() { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps_checkout-express-button-cart'; - this.checkoutExpressButton.classList.add( - 'ps_checkout-express-button', - 'ps_checkout-express-button-cart' - ); - - const separatorText = document.createElement('div'); - separatorText.classList.add('ps_checkout-express-separator'); - separatorText.innerText = this.$('express-button.cart.separator'); - - this.buttonReferenceContainer.append(separatorText); - this.buttonReferenceContainer.append(this.checkoutExpressButton); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paypal', - querySelector: '#ps_checkout-express-button-cart' - } - ).render(); - } - - render() { - if (!this.buttonReferenceContainer) return; - - this.renderComponent(); - this.prestashopService.onUpdatedShoppingCartExtra(() => { - if (null === document.querySelector('#ps_checkout-express-button-cart')) { - this.renderComponent(); - } - }); - - return this; - } -} diff --git a/_dev/js/front/src/components/1_6/express-button-checkout.component.js b/_dev/js/front/src/components/1_6/express-button-checkout.component.js deleted file mode 100644 index 6296b816b..000000000 --- a/_dev/js/front/src/components/1_6/express-button-checkout.component.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class ExpressButtonCheckoutComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCheckout(); - } - - renderTitle() { - this.checkoutExpressTitle = document.createElement('h3'); - this.checkoutExpressTitle.classList.add('page-heading', 'bottom-indent'); - this.checkoutExpressTitle.innerText = this.$( - 'express-button.checkout.express-checkout' - ); - - this.buttonReferenceContainer.prepend(this.checkoutExpressTitle); - } - - render() { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps_checkout-express-button-checkout'; - this.checkoutExpressButton.classList.add( - 'ps_checkout-express-button', - 'ps_checkout-express-button-checkout' - ); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paypal', - querySelector: '#ps_checkout-express-button-checkout' - } - ).render(); - - if (this.prestashopService.isNativeOnePageCheckoutPage()) { - const separatorText = document.createElement('div'); - separatorText.classList.add('ps_checkout-express-separator'); - separatorText.innerText = this.$('express-button.cart.separator'); - - this.buttonReferenceContainer.append(separatorText); - this.buttonReferenceContainer.append(this.checkoutExpressButton); - - return this; - } - - this.buttonReferenceContainer.prepend(this.checkoutExpressButton); - - this.renderTitle(); - - return this; - } -} diff --git a/_dev/js/front/src/components/1_6/express-button-product.component.js b/_dev/js/front/src/components/1_6/express-button-product.component.js deleted file mode 100644 index b040e843a..000000000 --- a/_dev/js/front/src/components/1_6/express-button-product.component.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class ExpressButtonProductComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - prestashopService: 'PrestashopService' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerProduct(); - } - - render() { - this.checkoutExpressButton = document.createElement('p'); - this.checkoutExpressButton.id = 'ps-checkout-express-button'; - this.checkoutExpressButton.classList.add( - 'buttons_bottom_block', - 'no-print' - ); - - const buttonContainer = this.buttonReferenceContainer.parentNode; - - buttonContainer.append(this.checkoutExpressButton); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paypal', - querySelector: '#ps-checkout-express-button' - } - ).render(); - - return this; - } -} diff --git a/_dev/js/front/src/components/1_6/notification.component.js b/_dev/js/front/src/components/1_6/notification.component.js deleted file mode 100644 index f32858335..000000000 --- a/_dev/js/front/src/components/1_6/notification.component.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class NotificationComponent extends BaseComponent { - static Inject = { - htmlElementService: 'HTMLElementService', - prestashopService: 'PrestashopService', - }; - - constructor(app, props) { - super(app, props); - - this.notificationPaymentContainer = this.htmlElementService.getNotificationPaymentContainer(); - this.notificationPaymentContainerTarget = this.htmlElementService.getNotificationPaymentContainerTarget(); - - this.notificationPaymentCanceled = this.htmlElementService.getNotificationPaymentCanceled(); - - this.notificationPaymentError = this.htmlElementService.getNotificationPaymentError(); - this.notificationPaymentErrorText = this.htmlElementService.getNotificationPaymentErrorText(); - } - - render() { - if (!this.prestashopService.isNativeOnePageCheckoutPage()) { - this.notificationPaymentContainerTarget.prepend( - this.notificationPaymentContainer - ); - } - - return this; - } - - hideConditions() {} - - hideCancelled() { - this.notificationPaymentCanceled.style.display = 'none'; - } - - hideError() { - this.notificationPaymentError.style.display = 'none'; - } - - showCanceled() { - this.notificationPaymentCanceled.style.display = 'block'; - } - - showConditions() {} - - showError(message) { - this.notificationPaymentError.style.display = 'block'; - this.notificationPaymentErrorText.textContent = message; - } -} diff --git a/_dev/js/front/src/components/1_6/pay-later-button-cart.component.js b/_dev/js/front/src/components/1_6/pay-later-button-cart.component.js deleted file mode 100644 index bf3c724a5..000000000 --- a/_dev/js/front/src/components/1_6/pay-later-button-cart.component.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PayLaterButtonCartComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi', - payPalService: 'PayPalService', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCart(); - this.data.orderId = this.payPalService.getOrderId(); - } - - renderComponent() { - if (!document.getElementById('ps_checkout-express-button-cart')) { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps_checkout-express-button-cart'; - this.checkoutExpressButton.classList.add( - 'ps_checkout-express-button', - 'ps_checkout-express-button-cart' - ); - - const separatorText = document.createElement('div'); - separatorText.classList.add('ps_checkout-express-separator'); - separatorText.innerText = this.$('express-button.cart.separator'); - - this.buttonReferenceContainer.append(separatorText); - this.buttonReferenceContainer.append(this.checkoutExpressButton); - } - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paylater', - querySelector: '#ps_checkout-express-button-cart' - } - ).render(); - } - - render() { - if (!this.buttonReferenceContainer) return; - - this.renderComponent(); - this.prestashopService.onUpdatedShoppingCartExtra(() => { - if (null === document.querySelector('#ps_checkout-express-button-cart')) { - this.renderComponent(); - } - }); - - return this; - } -} diff --git a/_dev/js/front/src/components/1_6/pay-later-button-checkout.component.js b/_dev/js/front/src/components/1_6/pay-later-button-checkout.component.js deleted file mode 100644 index 0989d7a73..000000000 --- a/_dev/js/front/src/components/1_6/pay-later-button-checkout.component.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PayLaterButtonCheckoutComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi', - payPalService: 'PayPalService', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCheckout(); - this.data.orderId = this.payPalService.getOrderId(); - } - - renderTitle() { - this.checkoutExpressTitle = document.createElement('h3'); - this.checkoutExpressTitle.classList.add('page-heading', 'bottom-indent'); - this.checkoutExpressTitle.innerText = this.$( - 'express-button.checkout.express-checkout' - ); - - this.buttonReferenceContainer.prepend(this.checkoutExpressTitle); - } - - render() { - if (!document.getElementById('ps_checkout-express-button-checkout')) { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps_checkout-express-button-checkout'; - this.checkoutExpressButton.classList.add( - 'ps_checkout-express-button', - 'ps_checkout-express-button-checkout' - ); - } - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paylater', - querySelector: '#ps_checkout-express-button-checkout' - } - ).render(); - - if ( - this.prestashopService.isNativeOnePageCheckoutPage() && - !document.getElementById('ps_checkout-express-button-checkout') - ) { - const separatorText = document.createElement('div'); - separatorText.classList.add('ps_checkout-express-separator'); - separatorText.innerText = this.$('express-button.cart.separator'); - - this.buttonReferenceContainer.append(separatorText); - this.buttonReferenceContainer.append(this.checkoutExpressButton); - - return this; - } - - if (!document.getElementById('ps_checkout-express-button-checkout')) { - this.buttonReferenceContainer.prepend(this.checkoutExpressButton); - - this.renderTitle(); - } - - return this; - } -} diff --git a/_dev/js/front/src/components/1_6/pay-later-button-product.component.js b/_dev/js/front/src/components/1_6/pay-later-button-product.component.js deleted file mode 100644 index f88e51a8a..000000000 --- a/_dev/js/front/src/components/1_6/pay-later-button-product.component.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PayLaterButtonProductComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - prestashopService: 'PrestashopService', - payPalService: 'PayPalService' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerProduct(); - this.data.orderId = this.payPalService.getOrderId(); - } - - render() { - if (!document.getElementById('ps-checkout-express-button')) { - this.checkoutExpressButton = document.createElement('p'); - this.checkoutExpressButton.id = 'ps-checkout-express-button'; - this.checkoutExpressButton.classList.add( - 'buttons_bottom_block', - 'no-print' - ); - - const buttonContainer = this.buttonReferenceContainer.parentNode; - - buttonContainer.append(this.checkoutExpressButton); - } - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paylater', - querySelector: '#ps-checkout-express-button' - } - ).render(); - - return this; - } -} diff --git a/_dev/js/front/src/components/1_6/payment-options.component.js b/_dev/js/front/src/components/1_6/payment-options.component.js deleted file mode 100644 index 076078574..000000000 --- a/_dev/js/front/src/components/1_6/payment-options.component.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { PaymentOptionComponent } from '../common/payment-option.component'; - -export class PaymentOptionsComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi', - querySelectorService: 'QuerySelectorService' - }; - - created() { - this.data.HTMLElement = this.querySelectorService.getPaymentOptions(); - } - - renderPaymentOptionItems() { - this.children.paymentOptions = this.payPalService - .getEligibleFundingSources() - .map((fundingSource) => { - const HTMLElement = document.querySelector( - `[data-module-name^="ps_checkout-${fundingSource.name}"]` - ); - - return ( - HTMLElement && - new PaymentOptionComponent(this.app, { - fundingSource: fundingSource, - markPosition: this.props.markPosition, - HTMLElement - }).render() - ); - }) - .filter((paymentOption) => paymentOption); - } - - renderPaymentOptionListener() { - const HTMLListenerElements = this.children.paymentOptions.map( - (paymentOption) => { - const HTMLElement = paymentOption.data.HTMLElementContainer; - const [button, form] = Array.prototype.slice.call( - HTMLElement.querySelectorAll('.payment_module') - ); - - return { button, form }; - } - ); - - this.children.paymentOptions.forEach((paymentOption, index) => { - paymentOption.onLabelClick(() => { - HTMLListenerElements.forEach(({ button, form }) => { - button.classList.add('closed'); - form.classList.add('closed'); - button.classList.remove('open'); - form.classList.remove('open'); - - this.data.notification.hideCancelled(); - this.data.notification.hideError(); - }); - - if ( - this.config.expressCheckout.active && - 'ps_checkout-' + this.payPalService.getFundingSource() !== - HTMLListenerElements[index].button.dataset.moduleName - ) { - this.psCheckoutApi - .postCancelOrder({ - orderID: this.payPalService.getOrderId(), - fundingSource: this.payPalService.getFundingSource(), - isExpressCheckout: true, - reason: 'payment_option_changed' - }) - .then(() => { - this.config.expressCheckout.active = false; - - const expressCheckoutContainer = document.querySelector( - '#ps_checkout-express-checkout-banner' - ); - if (expressCheckoutContainer) { - expressCheckoutContainer.style.display = 'none'; - } - }); - } - - HTMLListenerElements[index].button.classList.add('open'); - HTMLListenerElements[index].button.classList.remove('closed'); - HTMLListenerElements[index].form.classList.add('open'); - HTMLListenerElements[index].form.classList.remove('closed'); - }); - }); - - if (this.config.expressCheckout.active) { - HTMLListenerElements.forEach(({ button, form }) => { - if ( - button.dataset.moduleName === - 'ps_checkout-' + this.payPalService.getFundingSource() - ) { - button.classList.add('open'); - button.classList.remove('closed'); - form.classList.add('open'); - form.classList.remove('closed'); - } - }); - } - } - - render() { - this.data.conditions = this.app.root.children.conditionsCheckbox; - this.data.notification = this.app.root.children.notification; - this.data.loader = this.app.root.children.loader; - - this.renderPaymentOptionItems(); - this.renderPaymentOptionListener(); - - return this; - } -} diff --git a/_dev/js/front/src/components/1_7/conditions-checkbox.component.js b/_dev/js/front/src/components/1_7/conditions-checkbox.component.js deleted file mode 100644 index 365054c08..000000000 --- a/_dev/js/front/src/components/1_7/conditions-checkbox.component.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class ConditionsCheckboxComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService' - }; - - created() { - this.conditionsCheckboxes = - this.querySelectorService.getConditionsCheckboxes(); - } - - isActive() { - return this.conditionsCheckboxes?.length > 0; - } - - isChecked() { - if (this.isActive()) { - return this.conditionsCheckboxes?.every(({ checked }) => checked); - } - - return true; - } - - onChange(listener) { - this.conditionsCheckboxes?.forEach((checkbox) => - checkbox.addEventListener('change', listener) - ); - } -} diff --git a/_dev/js/front/src/components/1_7/express-button-cart.component.js b/_dev/js/front/src/components/1_7/express-button-cart.component.js deleted file mode 100644 index 66dafe5d2..000000000 --- a/_dev/js/front/src/components/1_7/express-button-cart.component.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class ExpressButtonCartComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCart(); - } - - render() { - if (!this.buttonReferenceContainer) return; - - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps-checkout-express-button'; - - const separatorText = document.createElement('div'); - separatorText.classList.add('ps-checkout-express-separator'); - separatorText.innerText = this.$('express-button.cart.separator'); - - this.buttonReferenceContainer.append(separatorText); - this.buttonReferenceContainer.append(this.checkoutExpressButton); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paypal', - querySelector: '#ps-checkout-express-button' - } - ).render(); - return this; - } -} diff --git a/_dev/js/front/src/components/1_7/express-button-checkout.component.js b/_dev/js/front/src/components/1_7/express-button-checkout.component.js deleted file mode 100644 index 12ebd9384..000000000 --- a/_dev/js/front/src/components/1_7/express-button-checkout.component.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class ExpressButtonCheckoutComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCheckout(); - } - - renderTitle() { - this.checkoutExpressTitle = document.createElement('ul'); - this.checkoutExpressTitle.classList.add('nav', 'nav-inline', 'my-1'); - - this.checkoutExpressTitleItem = document.createElement('li'); - this.checkoutExpressTitleItem.classList.add('nav-item'); - - this.checkoutExpressTitleItemHeading = document.createElement('div'); - this.checkoutExpressTitleItemHeading.classList.add('nav-link', 'active'); - this.checkoutExpressTitleItemHeading.innerText = this.$( - 'express-button.checkout.express-checkout' - ); - - this.checkoutExpressTitleItem.append(this.checkoutExpressTitleItemHeading); - this.checkoutExpressTitle.append(this.checkoutExpressTitleItem); - } - - render() { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps-checkout-express-button'; - - this.renderTitle(); - - this.buttonReferenceContainer.prepend(this.checkoutExpressButton); - this.buttonReferenceContainer.prepend(this.checkoutExpressTitle); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paypal', - querySelector: '#ps-checkout-express-button' - } - ).render(); - return this; - } -} diff --git a/_dev/js/front/src/components/1_7/express-button-product.component.js b/_dev/js/front/src/components/1_7/express-button-product.component.js deleted file mode 100644 index 90ca88f5e..000000000 --- a/_dev/js/front/src/components/1_7/express-button-product.component.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -const BUTTON_CONTAINER_SELECTOR = 'ps-checkout-express-button'; - -export class ExpressButtonProductComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - prestashopService: 'PrestashopService' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerProduct(); - } - - render() { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = BUTTON_CONTAINER_SELECTOR; - - const productQuantityHTMLElement = - this.buttonReferenceContainer.nextElementSibling; - - this.buttonReferenceContainer.parentNode.insertBefore( - this.checkoutExpressButton, - productQuantityHTMLElement - ); - - this.updateButtonContainerVisibility(); - - this.prestashopService.onUpdatedProduct(() => { - this.updateButtonContainerVisibility(); - }); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paypal', - querySelector: `#${BUTTON_CONTAINER_SELECTOR}` - } - ).render(); - - return this; - } - - updateButtonContainerVisibility() { - if (this.prestashopService.isAddToCartButtonDisabled()) { - document - .getElementById(BUTTON_CONTAINER_SELECTOR) - .classList.add('disabled'); - } else { - document - .getElementById(BUTTON_CONTAINER_SELECTOR) - .classList.remove('disabled'); - } - } -} diff --git a/_dev/js/front/src/components/1_7/notification.component.js b/_dev/js/front/src/components/1_7/notification.component.js deleted file mode 100644 index f56d143ef..000000000 --- a/_dev/js/front/src/components/1_7/notification.component.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class NotificationComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService' - }; - - created() { - this.notificationConditions = this.querySelectorService.getNotificationConditions(); - - this.notificationPaymentCanceled = this.querySelectorService.getNotificationPaymentCanceled(); - this.notificationPaymentError = this.querySelectorService.getNotificationPaymentError(); - this.notificationPaymentErrorText = this.querySelectorService.getNotificationPaymentErrorText(); - } - - hideCancelled() { - this.notificationPaymentCanceled.style.display = 'none'; - } - - hideConditions() { - if (this.notificationConditions) { - this.notificationConditions.style.display = 'none'; - } - } - - hideError() { - this.notificationPaymentError.style.display = 'none'; - } - - showCanceled() { - this.notificationPaymentCanceled.style.display = 'block'; - } - - showConditions() { - if (this.notificationConditions) { - this.notificationConditions.style.display = 'block'; - } - } - - showError(message) { - this.notificationPaymentError.style.display = 'block'; - this.notificationPaymentErrorText.textContent = message; - } -} diff --git a/_dev/js/front/src/components/1_7/pay-later-button-cart.component.js b/_dev/js/front/src/components/1_7/pay-later-button-cart.component.js deleted file mode 100644 index b9ee83180..000000000 --- a/_dev/js/front/src/components/1_7/pay-later-button-cart.component.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PayLaterButtonCartComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - payPalService: 'PayPalService', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCart(); - this.data.orderId = this.payPalService.getOrderId(); - } - - render() { - if (!this.buttonReferenceContainer) return; - - if (!document.getElementById('ps-checkout-express-button')) { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps-checkout-express-button'; - - const separatorText = document.createElement('div'); - separatorText.classList.add('ps-checkout-express-separator'); - separatorText.innerText = this.$('express-button.cart.separator'); - - this.buttonReferenceContainer.append(separatorText); - this.buttonReferenceContainer.append(this.checkoutExpressButton); - } - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paylater', - querySelector: '#ps-checkout-express-button' - } - ).render(); - return this; - } -} diff --git a/_dev/js/front/src/components/1_7/pay-later-button-checkout.component.js b/_dev/js/front/src/components/1_7/pay-later-button-checkout.component.js deleted file mode 100644 index aaa245d3c..000000000 --- a/_dev/js/front/src/components/1_7/pay-later-button-checkout.component.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PayLaterButtonCheckoutComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - payPalService: 'PayPalService', - $: '$' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerCheckout(); - this.data.orderId = this.payPalService.getOrderId(); - } - - renderTitle() { - this.checkoutExpressTitle = document.createElement('ul'); - this.checkoutExpressTitle.classList.add('nav', 'nav-inline', 'my-1'); - - this.checkoutExpressTitleItem = document.createElement('li'); - this.checkoutExpressTitleItem.classList.add('nav-item'); - - this.checkoutExpressTitleItemHeading = document.createElement('div'); - this.checkoutExpressTitleItemHeading.classList.add('nav-link', 'active'); - this.checkoutExpressTitleItemHeading.innerText = this.$( - 'express-button.checkout.express-checkout' - ); - - this.checkoutExpressTitleItem.append(this.checkoutExpressTitleItemHeading); - this.checkoutExpressTitle.append(this.checkoutExpressTitleItem); - } - - render() { - if (!document.getElementById('ps-checkout-express-button')) { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = 'ps-checkout-express-button'; - - this.renderTitle(); - - this.buttonReferenceContainer.prepend(this.checkoutExpressButton); - this.buttonReferenceContainer.prepend(this.checkoutExpressTitle); - } - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paylater', - querySelector: '#ps-checkout-express-button' - } - ).render(); - return this; - } -} diff --git a/_dev/js/front/src/components/1_7/pay-later-button-product.component.js b/_dev/js/front/src/components/1_7/pay-later-button-product.component.js deleted file mode 100644 index fb2313471..000000000 --- a/_dev/js/front/src/components/1_7/pay-later-button-product.component.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -const BUTTON_CONTAINER_SELECTOR = 'ps-checkout-express-button'; - -export class PayLaterButtonProductComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - psCheckoutApi: 'PsCheckoutApi', - prestashopService: 'PrestashopService', - payPalService: 'PayPalService' - }; - - created() { - this.buttonReferenceContainer = - this.querySelectorService.getExpressCheckoutButtonContainerProduct(); - this.data.orderId = this.payPalService.getOrderId(); - } - - render() { - if (!document.getElementById(BUTTON_CONTAINER_SELECTOR)) { - this.checkoutExpressButton = document.createElement('div'); - this.checkoutExpressButton.id = BUTTON_CONTAINER_SELECTOR; - - const productQuantityHTMLElement = - this.buttonReferenceContainer.nextElementSibling; - - this.buttonReferenceContainer.parentNode.insertBefore( - this.checkoutExpressButton, - productQuantityHTMLElement - ); - } - - this.updateButtonContainerVisibility(); - - this.prestashopService.onUpdatedProduct(() => { - this.updateButtonContainerVisibility(); - }); - - this.children.expressCheckoutButton = new ExpressCheckoutButtonComponent( - this.app, - { - fundingSource: 'paylater', - querySelector: `#${BUTTON_CONTAINER_SELECTOR}` - } - ).render(); - - return this; - } - - updateButtonContainerVisibility() { - if (this.prestashopService.isAddToCartButtonDisabled()) { - document - .getElementById(BUTTON_CONTAINER_SELECTOR) - .classList.add('disabled'); - } else { - document - .getElementById(BUTTON_CONTAINER_SELECTOR) - .classList.remove('disabled'); - } - } -} diff --git a/_dev/js/front/src/components/1_7/payment-options.component.js b/_dev/js/front/src/components/1_7/payment-options.component.js deleted file mode 100644 index a4d47d0bd..000000000 --- a/_dev/js/front/src/components/1_7/payment-options.component.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { PaymentOptionComponent } from '../common/payment-option.component'; - -export class PaymentOptionsComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi', - querySelectorService: 'QuerySelectorService' - }; - - created() { - this.data.HTMLElementPaymentOptionsContainer = this.querySelectorService.getPaymentOptions(); - this.data.HTMLBasePaymentConfirmation = this.querySelectorService.getBasePaymentConfirmation(); - } - - renderPaymentOptionItems() { - this.children.paymentOptions = this.payPalService - .getEligibleFundingSources() - .map((fundingSource) => { - const HTMLElement = document.querySelector( - `[data-module-name^="ps_checkout-${fundingSource.name}"]` - ); - - if ( - this.config.expressCheckout.active && - this.payPalService.getFundingSource() === fundingSource.name - ) { - HTMLElement.click(); - } - - return ( - HTMLElement && - new PaymentOptionComponent(this.app, { - fundingSource: fundingSource, - markPosition: this.props.markPosition, - HTMLElement - }).render() - ); - }) - .filter((paymentOption) => paymentOption); - } - - renderPaymentOptionListener() { - const radios = this.querySelectorService.getPaymentOptionRadios(); - radios.forEach((radio) => { - radio.addEventListener('change', () => { - this.data.notification.hideCancelled(); - this.data.notification.hideError(); - - if ( - this.config.expressCheckout.active && - 'ps_checkout-' + this.payPalService.getFundingSource() !== - radio.dataset.moduleName - ) { - this.psCheckoutApi - .postCancelOrder({ - orderID: this.payPalService.getOrderId(), - fundingSource: this.payPalService.getFundingSource(), - isExpressCheckout: true, - reason: 'payment_option_changed' - }) - .then(() => { - this.config.expressCheckout.active = false; - - const expressCheckoutContainer = document.querySelector( - '#ps_checkout-express-checkout-banner' - ); - if (expressCheckoutContainer) { - expressCheckoutContainer.style.display = 'none'; - } - }); - } - }); - }); - } - - render() { - this.data.conditions = this.app.root.children.conditionsCheckbox; - this.data.notification = this.app.root.children.notification; - this.data.loader = this.app.root.children.loader; - - this.renderPaymentOptionItems(); - this.renderPaymentOptionListener(); - - return this; - } -} diff --git a/_dev/js/front/src/components/common/card-fields.component.js b/_dev/js/front/src/components/common/card-fields.component.js deleted file mode 100644 index db87a7d34..000000000 --- a/_dev/js/front/src/components/common/card-fields.component.js +++ /dev/null @@ -1,368 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * @typedef PaypalCardFieldCardField - * @type {*} - * - * @property {boolean} isEmpty - * @property {boolean} isValid - * @property {boolean} isPotentiallyValid - * @property {boolean} isFocused - */ - -/** - * @typedef PaypalCardFieldsEvent - * @type {*} - * - * @property {string} emittedBy - * @property {boolean} isFormValid - * @property {String[]} errors - * @property {*} fields - * @property {PaypalCardFieldCardField} fields.cardCvvField - * @property {PaypalCardFieldCardField} fields.cardExpiryField - * @property {PaypalCardFieldCardField} fields.cardNameField - * @property {PaypalCardFieldCardField} fields.cardNumberField - */ - -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class CardFieldsComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - configPayPal: 'PayPalSdkConfig', - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi', - querySelectorService: 'QuerySelectorService', - $: '$' - }; - - created() { - this.data.name = this.props.fundingSource.name; - this.data.validity = false; - this.data.orderId = null; - /** - * @property {PaypalCardFieldsEvent} data.cardFieldsState - */ - this.data.cardFieldsState = {}; - - this.data.cardFieldsFocused = { - name: false, - number: false, - expiry: false, - cvv: false - }; - this.data.HTMLElement = this.props.HTMLElement; - this.data.HTMLElementCardForm = - this.querySelectorService.getCardFieldsFormContainer(); - this.data.HTMLElementBaseButton = - this.querySelectorService.getBasePaymentConfirmation(); - this.data.HTMLElementButton = null; - this.data.HTMLElementButtonWrapper = this.getButtonWrapper(); - - this.data.HTMLElementCardHolderName = - this.querySelectorService.getCardFieldsNameInputContainer(); - this.data.HTMLElementCardNumber = - this.querySelectorService.getCardFieldsNumberInputContainer(); - this.data.HTMLElementCardExpiry = - this.querySelectorService.getCardFieldsExpiryInputContainer(); - this.data.HTMLElementCardCvv = - this.querySelectorService.getCardFieldsCvvInputContainer(); - - this.data.HTMLElementCardNameError = - this.querySelectorService.getCardFieldsNameError(); - this.data.HTMLElementCardNumberError = - this.querySelectorService.getCardFieldsNumberError(); - this.data.HTMLElementCardVendorError = - this.querySelectorService.getCardFieldsVendorError(); - this.data.HTMLElementCardExpiryError = - this.querySelectorService.getCardFieldsExpiryError(); - this.data.HTMLElementCardCvvError = - this.querySelectorService.getCardFieldsCvvError(); - } - - getButtonWrapper() { - const buttonWrapper = `.ps_checkout-button[data-funding-source=${this.data.name}]`; - return document.querySelector(buttonWrapper); - } - - isSubmittable() { - return this.data.conditions - ? this.data.conditions.isChecked() && this.data.validity - : this.data.validity; - } - - isFormValid() { - const { cardNameField, cardNumberField, cardExpiryField, cardCvvField } = - this.data.cardFieldsState.fields; - return ( - (cardNameField.isEmpty || cardNameField.isValid) && - cardNumberField.isValid && - cardExpiryField.isValid && - cardCvvField.isValid - ); - } - - setFocusedField(fieldName) { - this.data.cardFieldsFocused[fieldName] = true; - } - - toggleCardNameFieldError() { - const { isFocused, isEmpty, isValid, isPotentiallyValid } = - this.data.cardFieldsState.fields.cardNameField; - const hideError = isEmpty || isFocused || isValid; - - this.data.HTMLElementCardNameError.classList.toggle('hidden', hideError); - } - - toggleCardNumberFieldError() { - const { isFocused, isEmpty, isValid, isPotentiallyValid } = - this.data.cardFieldsState.fields.cardNumberField; - const hideError = - isFocused || !this.data.cardFieldsFocused.number || isValid; - - this.data.HTMLElementCardNumberError.classList.toggle( - 'hidden', - !isPotentiallyValid || hideError - ); - this.data.HTMLElementCardVendorError.classList.toggle( - 'hidden', - isPotentiallyValid - ); - } - - toggleCardExpiryFieldError() { - const { isFocused, isEmpty, isValid, isPotentiallyValid } = - this.data.cardFieldsState.fields.cardExpiryField; - const hideError = - isPotentiallyValid && - (isFocused || !this.data.cardFieldsFocused.expiry || isValid); - - this.data.HTMLElementCardExpiryError.classList.toggle('hidden', hideError); - } - toggleCardCvvFieldError() { - const { isFocused, isEmpty, isValid, isPotentiallyValid } = - this.data.cardFieldsState.fields.cardCvvField; - const hideError = isFocused || !this.data.cardFieldsFocused.cvv || isValid; - - this.data.HTMLElementCardCvvError.classList.toggle('hidden', hideError); - } - - toggleCardFieldsErrors() { - this.toggleCardNameFieldError(); - this.toggleCardNumberFieldError(); - this.toggleCardExpiryFieldError(); - this.toggleCardCvvFieldError(); - } - - /** - * @param {PaypalCardFieldsEvent} event - */ - updateCardFieldsState(event) { - this.setFocusedField(event.emittedBy); - this.data.cardFieldsState = event; - this.data.validity = this.isFormValid(); - - this.isSubmittable() - ? this.data.HTMLElementButton.removeAttribute('disabled') - : this.data.HTMLElementButton.setAttribute('disabled', ''); - - this.toggleCardFieldsErrors(); - } - - renderPayPalCardFields() { - this.data.HTMLElementCardForm.classList.toggle('loading', true); - - const style = { - ...{ - input: { - 'font-size': '17px', - 'font-family': 'helvetica, tahoma, calibri, sans-serif', - color: '#3a3a3a', - padding: '8px 12px' - }, - ':focus': { - color: 'black' - }, - body: { - padding: '0 0 5px 0' - } - }, - ...(this.configPayPal.hostedFieldsCustomization || {}), - ...(window.ps_checkout.hostedFieldsCustomization || {}) - }; - - this.payPalService - .getCardFields( - { - name: this.data.HTMLElementCardHolderName, - number: this.data.HTMLElementCardNumber, - cvv: this.data.HTMLElementCardCvv, - expiry: this.data.HTMLElementCardExpiry - }, - { - style, - createOrder: async (data) => { - this.data.HTMLElementButton.setAttribute('disabled', true); - - return this.psCheckoutApi - .postCreateOrder({ - ...data, - fundingSource: this.data.name, - isHostedFields: true - // vault: storeCardInVault - }) - .then((data) => { - this.data.orderId = data; - return data; - }) - .catch((error) => { - throw error; - }); - }, - onApprove: async (data) => { - return this.psCheckoutApi - .postValidateOrder({ - ...data, - fundingSource: this.data.name, - isHostedFields: true - }) - .catch((error) => { - let message = error.message || ''; - - if (!message) { - message = `Unknown error, code: ${ - error.code || 'none' - }, description: ${error.description || 'none'}`; - } - - this.data.loader.hide(); - this.data.notification.showError(message); - this.data.HTMLElementButton.removeAttribute('disabled'); - }); - }, - onError: async (error) => { - this.data.loader.hide(); - let message = error.message || this.$('checkout.form.error.label'); - this.data.notification.showError(message); - this.data.HTMLElementButton.removeAttribute('disabled'); - - return this.psCheckoutApi - .postCancelOrder({ - orderID: this.data.orderId, - fundingSource: this.data.name, - isExpressCheckout: this.config.expressCheckout.active, - reason: 'card_fields_error', - error: error instanceof Error ? error.message : error - }) - .catch((error) => console.error(error)); - }, - inputEvents: { - /** - * @param {PaypalCardFieldsEvent} event - */ - onChange: (event) => { - this.updateCardFieldsState(event); - this.data.cardFields = event; - }, - /** - * @param {PaypalCardFieldsEvent} event - */ - onFocus: (event) => { - this.updateCardFieldsState(event); - window.ps_checkout.events.dispatchEvent( - new CustomEvent('hostedFieldsFocus', { - detail: { ps_checkout: window.ps_checkout, event } - }) - ); - }, - /** - * @param {PaypalCardFieldsEvent} event - */ - onBlur: (event) => { - this.updateCardFieldsState(event); - window.ps_checkout.events.dispatchEvent( - new CustomEvent('hostedFieldsBlur', { - detail: { ps_checkout: window.ps_checkout, event } - }) - ); - }, - /** - * @param {PaypalCardFieldsEvent} event - */ - onInputSubmitRequest: (event) => { - this.updateCardFieldsState(event); - } - } - } - ) - .then((cardFields) => { - this.data.HTMLElementCardForm.classList.toggle('loading', false); - - if (this.data.HTMLElementCardForm.style.display === 'none') { - this.data.HTMLElementCardForm.style.display = 'block'; - } - - if (this.data.HTMLElement !== null) { - this.data.HTMLElementButton.addEventListener('click', (event) => { - event.preventDefault(); - - if (!this.data.validity) { - this.data.HTMLElementButton.setAttribute('disabled', ''); - return; - } - - this.data.loader.show(); - this.data.HTMLElementButton.setAttribute('disabled', ''); - - cardFields.submit(); - }); - } - }); - } - - renderButton() { - this.data.HTMLElementButton = - this.data.HTMLElementBaseButton.cloneNode(true); - - this.data.HTMLElementButtonWrapper.append(this.data.HTMLElementButton); - this.data.HTMLElementButton.classList.remove('disabled'); - this.data.HTMLElementButton.style.display = ''; - this.data.HTMLElementButton.disabled = !this.isSubmittable(); - - this.data.conditions && - this.data.conditions.onChange(() => { - // In some PS versions, the handler fails to disable the button because of the timing. - setTimeout(() => { - this.data.HTMLElementButton.disabled = !this.isSubmittable(); - }, 0); - }); - } - - render() { - this.data.conditions = this.app.root.children.conditionsCheckbox; - this.data.notification = this.app.root.children.notification; - this.data.loader = this.app.root.children.loader; - - this.renderButton(); - this.renderPayPalCardFields(); - - return this; - } -} diff --git a/_dev/js/front/src/components/common/express-checkout-button.component.js b/_dev/js/front/src/components/common/express-checkout-button.component.js deleted file mode 100644 index 4d06e0ae5..000000000 --- a/_dev/js/front/src/components/common/express-checkout-button.component.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class ExpressCheckoutButtonComponent extends BaseComponent { - static Inject = { - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi', - prestashopService: 'PrestashopService', - $: '$' - }; - - created() { - this.data.orderId = this.payPalService.getOrderId(); - } - - onInit(data, actions) { - return actions.enable(); - } - - onClick(data, actions) { - return this.psCheckoutApi - .postCheckCartOrder( - { - ...data, - fundingSource: this.props.fundingSource, - isExpressCheckout: true, - orderID: this.data.orderId - }, - actions - ) - .catch((error) => { - actions.reject(); - throw error; - }); - } - - onError(error) { - const errorText = error?.message ? error.message : error; - this.notifyError(errorText); - console.error(error); - - return this.psCheckoutApi - .postCancelOrder({ - orderID: this.data.orderId, - fundingSource: this.props.fundingSource, - isExpressCheckout: true, - reason: 'express_checkout_error', - error: errorText - }) - .catch((error) => console.error(error)); - } - - onApprove(data, actions) { - return this.psCheckoutApi.postExpressCheckoutOrder( - { - ...data, - fundingSource: this.props.fundingSource, - isExpressCheckout: true - }, - actions - ); - } - - onCancel(data) { - return this.psCheckoutApi.postCancelOrder({ - ...data, - orderID: this.data.orderId, - fundingSource: this.props.fundingSource, - isExpressCheckout: true, - reason: 'express_checkout_cancelled' - }); - } - - createOrder(data) { - let extraData = {}; - - if (this.prestashopService.isProductPage()) { - let { - id_product, - id_product_attribute, - id_customization, - quantity_wanted - } = this.prestashopService.getProductDetails(); - extraData = { - id_product, - id_product_attribute, - id_customization, - quantity_wanted - }; - } - - return this.psCheckoutApi - .postCreateOrder({ - ...data, - ...extraData - }) - .then((data) => { - this.data.orderId = data; - return data; - }) - .catch((error) => { - throw error; - }); - } - - notifyError(message) { - const expressCheckoutContainer = document.querySelector( - this.props.querySelector - ); - const notificationContainerIdentifier = - 'ps_checkout-product-notification-container'; - let notificationContainerElement = document.getElementById( - notificationContainerIdentifier - ); - - if (!notificationContainerElement) { - notificationContainerElement = document.createElement('div'); - notificationContainerElement.id = notificationContainerIdentifier; - expressCheckoutContainer.prepend(notificationContainerElement); - } - - const notificationIdentifier = 'ps_checkout-product-notification-container'; - const currentNotificationElement = document.querySelector( - '#' + notificationContainerIdentifier + ' .' + notificationIdentifier - ); - - if (currentNotificationElement) { - return (currentNotificationElement.textContent = message); - } - - const notificationElement = document.createElement('div'); - notificationElement.classList.add( - 'alert', - 'alert-danger', - notificationIdentifier - ); - notificationElement.textContent = message; - notificationContainerElement.appendChild(notificationElement); - } - - renderPayPalButton() { - if ( - !this.payPalService - .getEligibleFundingSources() - .filter(({ name }) => name === this.props.fundingSource).length > 0 - ) - return; - - return this.payPalService - .getButtonExpress(this.props.fundingSource, { - onInit: (data, actions) => this.onInit(data, actions), - onClick: (data, actions) => this.onClick(data, actions), - onError: (error) => this.onError(error), - onApprove: (data, actions) => this.onApprove(data, actions), - onCancel: (data) => this.onCancel(data), - createOrder: (data) => this.createOrder(data) - }) - .render(this.props.querySelector); - } - - render() { - this.renderPayPalButton(); - return this; - } -} diff --git a/_dev/js/front/src/components/common/loader.component.js b/_dev/js/front/src/components/common/loader.component.js deleted file mode 100644 index 89f6f891b..000000000 --- a/_dev/js/front/src/components/common/loader.component.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class LoaderComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService', - config: 'PsCheckoutConfig', - $: '$' - }; - - created() { - this.data.parent = this.querySelectorService.getLoaderParent(); - } - - render() { - this.overlay = document.createElement('div'); - this.overlay.classList.add('ps-checkout', 'overlay'); - - this.popup = document.createElement('div'); - this.popup.classList.add('ps-checkout', 'popup'); - - this.text = document.createElement('h1'); - this.text.classList.add('ps-checkout', 'text'); - this.text.innerHTML = this.$('loader-component.label.header'); - - this.loader = document.createElement('img'); - this.loader.classList.add('ps-checkout', 'loader'); - this.loader.setAttribute('src', this.config.loaderImage); - this.loader.setAttribute('alt', 'loader'); - - this.subtext = document.createElement('div'); - this.subtext.classList.add('ps-checkout', 'subtext'); - this.text.innerHTML = this.$('loader-component.label.body'); - - this.popup.append(this.text); - this.popup.append(this.loader); - this.popup.append(this.subtext); - - this.overlay.append(this.popup); - this.data.parent.append(this.overlay); - - return this; - } - - show() { - this.overlay.classList.add('visible'); - document.body.style.overflow = 'hidden'; - } - - hide() { - this.overlay.classList.remove('visible'); - document.body.style.overflow = ''; - } -} diff --git a/_dev/js/front/src/components/common/loader.component.spec.js b/_dev/js/front/src/components/common/loader.component.spec.js deleted file mode 100644 index a71dd036f..000000000 --- a/_dev/js/front/src/components/common/loader.component.spec.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { PsCheckoutConfig } from '../../config/ps-checkout.config'; -import { LoaderComponent } from './loader.component'; - -function buildDIContainerMock() { - return { - container: { - PsCheckoutConfig: { - ...PsCheckoutConfig - }, - QuerySelectorService: { - getLoaderParent: jest.fn() - }, - $: jest.fn().mockImplementation(key => { - return ( - { - 'funding-source.name.foo': 'Foo', - 'funding-source.name.default': 'Default' - }[key] || '' - ); - }) - } - }; -} - -describe('src/components/common/loader.component.spec.js', () => { - afterEach(() => (document.body.innerHTML = '')); - - test('::render()', () => { - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getLoaderParent.mockImplementationOnce( - () => document.body - ); - - const loaderComponent = new LoaderComponent(diContainer); - expect(loaderComponent.render()).toBe(loaderComponent); - - const overlayHTMLElement = document.querySelector('.ps-checkout.overlay'); - expect(overlayHTMLElement.parentElement).toBe(document.body); - - const popupHTMLElement = document.querySelector('.ps-checkout.popup'); - expect(popupHTMLElement.parentElement).toBe(overlayHTMLElement); - - const popupTextHTMLElement = document.querySelector('.ps-checkout.text'); - expect(popupTextHTMLElement.parentElement).toBe(popupHTMLElement); - - const popupLoaderHTMLElement = document.querySelector( - '.ps-checkout.loader' - ); - expect(popupLoaderHTMLElement.parentElement).toBe(popupHTMLElement); - - const popupSubtextHTMLElement = document.querySelector( - '.ps-checkout.subtext' - ); - expect(popupSubtextHTMLElement.parentElement).toBe(popupHTMLElement); - }); - - test('::show() ', () => { - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getLoaderParent.mockImplementationOnce( - () => document.body - ); - - const loaderComponent = new LoaderComponent(diContainer); - expect(loaderComponent.render()).toBe(loaderComponent); - - const overlayHTMLElement = document.querySelector('.ps-checkout.overlay'); - expect(overlayHTMLElement.parentElement).toBe(document.body); - expect(overlayHTMLElement.classList).not.toContain('visible'); - - loaderComponent.show(); - expect(overlayHTMLElement.classList).toContain('visible'); - }); - - test('::hide() ', () => { - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getLoaderParent.mockImplementationOnce( - () => document.body - ); - - const loaderComponent = new LoaderComponent(diContainer); - expect(loaderComponent.render()).toBe(loaderComponent); - - const overlayHTMLElement = document.querySelector('.ps-checkout.overlay'); - expect(overlayHTMLElement.parentElement).toBe(document.body); - expect(overlayHTMLElement.classList).not.toContain('visible'); - - loaderComponent.show(); - expect(overlayHTMLElement.classList).toContain('visible'); - - loaderComponent.hide(); - expect(overlayHTMLElement.classList).not.toContain('visible'); - }); -}); diff --git a/_dev/js/front/src/components/common/marker.component.js b/_dev/js/front/src/components/common/marker.component.js deleted file mode 100644 index 07bc38efc..000000000 --- a/_dev/js/front/src/components/common/marker.component.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -/** - * @typedef MarkComponentProps - * - * @param {string} fundingSource.name - * @param {*} fundingSource.mark - * - * @param {HTMLElement} HTMLElement - */ - -export class MarkComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig' - }; - - created() { - this.data.name = this.props.fundingSource.name; - this.data.mark = this.props.fundingSource.mark; - - this.data.HTMLElement = this.props.HTMLElement; - this.data.HTMLElementImage = this.props.HTMLElementImage || null; - } - - hasCustomMark() { - return this.config.customMark[this.data.name]; - } - - renderCustomMark() { - const src = this.config.customMark[this.data.name]; - let logoList = []; - - if (this.config.cardSupportedBrands && this.config.cardLogoBrands) { - this.config.cardSupportedBrands.forEach(brand => { - if (this.config.cardLogoBrands[brand]) { - let customMarkImg = document.createElement('img'); - customMarkImg.classList.add('cards-logo'); - customMarkImg.setAttribute('alt', brand); - customMarkImg.setAttribute('src', this.config.cardLogoBrands[brand]); - logoList.push(customMarkImg); - let space = document.createElement('span'); - space.classList.add('paypal-button-space'); - space.innerText = ' '; - logoList.push(space); - } - }); - } else { - let customMarkImg = document.createElement('img'); - customMarkImg.classList.add('cards-logo'); - customMarkImg.setAttribute('alt', this.data.name); - customMarkImg.setAttribute('src', src); - logoList.push(customMarkImg); - } - - this.data.HTMLElement.classList.add('paypal-mark'); - logoList.forEach(customMarkImg => this.data.HTMLElement.append(customMarkImg)); - } - - render() { - this.data.HTMLElement.classList.add('ps_checkout-mark'); - this.data.HTMLElement.setAttribute('data-funding-source', this.data.name); - - if (this.hasCustomMark()) { - this.renderCustomMark(); - } else { - const markSelector = `.ps_checkout-mark[data-funding-source=${this.data.name}]`; - this.data.mark.render(markSelector); - } - - return this; - } -} diff --git a/_dev/js/front/src/components/common/marker.component.spec.js b/_dev/js/front/src/components/common/marker.component.spec.js deleted file mode 100644 index c0bba8838..000000000 --- a/_dev/js/front/src/components/common/marker.component.spec.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { MarkComponent } from './marker.component'; - -function buildDIContainerMock() { - return { - container: { - PsCheckoutConfig: { - customMark: { - bar: 'baz' - } - } - } - }; -} - -describe('src/components/common/marker.component.spec.js', () => { - beforeEach(() => (document.body.innerHTML = `
`)); - - afterEach(() => (document.body.innerHTML = '')); - - test('::render() with custom mark', () => { - const HTMLElement = document.getElementById('foo'); - const fundingSource = { - name: 'bar', - mark: { render: jest.fn() } - }; - - const diContainer = buildDIContainerMock(); - const component = new MarkComponent(diContainer, { - fundingSource, - HTMLElement - }); - - expect(component.render()).toBe(component); - - const image = document.querySelector('img'); - expect(image.classList.contains('ps-checkout-funding-img')).toBeTruthy(); - expect(image.getAttribute('alt')).toBe(fundingSource.name); - expect(image.getAttribute('src')).toBe( - diContainer.container.PsCheckoutConfig.customMark.bar - ); - - expect(HTMLElement.classList.contains('ps_checkout-mark')).toBeTruthy(); - expect(HTMLElement.getAttribute('data-funding-source')).toBe( - fundingSource.name - ); - }); - - test('::render() with default mark', () => { - const HTMLElement = document.getElementById('foo'); - const fundingSource = { - name: 'foo', - mark: { render: jest.fn() } - }; - - const selector = `.ps_checkout-mark[data-funding-source=${fundingSource.name}]`; - - const diContainer = buildDIContainerMock(); - const component = new MarkComponent(diContainer, { - fundingSource, - HTMLElement - }); - - expect(component.render()).toBe(component); - - expect(fundingSource.mark.render).toHaveBeenCalledWith(selector); - - expect(HTMLElement.classList.contains('ps_checkout-mark')).toBeTruthy(); - expect(HTMLElement.getAttribute('data-funding-source')).toBe( - fundingSource.name - ); - }); -}); diff --git a/_dev/js/front/src/components/common/payment-fields.component.js b/_dev/js/front/src/components/common/payment-fields.component.js deleted file mode 100644 index e6de875ab..000000000 --- a/_dev/js/front/src/components/common/payment-fields.component.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -/** - * @typedef PaymentFieldsComponentProps - * - * @param {string} fundingSource.name - * @param {*} fundingSource.mark - * - * @param {HTMLElement} HTMLElement - */ - -export class PaymentFieldsComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - payPalService: 'PayPalService' - }; - - created() { - this.data.name = this.props.fundingSource.name; - - this.data.HTMLElement = this.props.HTMLElement; - } - - render() { - const containerSelector = `.ps_checkout-payment-fields[data-funding-source=${this.data.name}]`; - - this.data.HTMLElement.classList.add('ps_checkout-payment-fields'); - this.data.HTMLElement.setAttribute('data-funding-source', this.data.name); - - const paymentFields = this.payPalService - .getPaymentFields(this.data.name); - - if (paymentFields) { - paymentFields.render(containerSelector); - } - - return this; - } -} diff --git a/_dev/js/front/src/components/common/payment-fields.component.spec.js b/_dev/js/front/src/components/common/payment-fields.component.spec.js deleted file mode 100644 index ec7fe4b4f..000000000 --- a/_dev/js/front/src/components/common/payment-fields.component.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import {PaymentFieldsComponent} from "./payment-fields.component"; - -function buildDIContainerMock() { - return { - container: { - PsCheckoutConfig: { - customMark: { - bar: 'baz' - } - }, - PayPalService: { - getPaymentFields: jest.fn(), - sdk: { - paymentFields: { - isEligible: jest.fn() - } - }, - } - } - }; -} - -describe('src/components/common/payment-fields.component.spec.js', () => { - beforeEach(() => (document.body.innerHTML = `
`)); - afterEach(() => (document.body.innerHTML = '')); - - test('::render()', () => { - document.body.innerHTML = - '
' + - '
Foo
' + - '
' + - '
' + - '
' + - '
'; - - const HTMLElement = document.getElementById('pay-with-payment-option-foo-form'); - - const diContainer = buildDIContainerMock(); - const fundingSource = { - name: 'foo', - mark: { render: jest.fn() } - }; - - const component = new PaymentFieldsComponent(diContainer, { - fundingSource, - HTMLElement - }); - - expect(component.render()).toBe(component); - expect(HTMLElement.classList.contains('ps_checkout-payment-fields')).toBeTruthy(); - expect(HTMLElement.getAttribute('data-funding-source')).toBe('foo'); - }); -}); diff --git a/_dev/js/front/src/components/common/payment-method-logos.component.js b/_dev/js/front/src/components/common/payment-method-logos.component.js deleted file mode 100644 index 255477ed5..000000000 --- a/_dev/js/front/src/components/common/payment-method-logos.component.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -/** - * @typedef PaymentFieldsComponentProps - * - * @param {string} fundingSource.name - * @param {*} fundingSource.mark - * - * @param {HTMLElement} HTMLElement - */ - -export class PaymentMethodLogosComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - querySelectorService: 'QuerySelectorService', - prestashopService: 'PrestashopService', - $: '$' - }; - - created() { - this.data.HTMLElement = this.props.HTMLElement; - } - - render() { - this.renderMark(); - - this.prestashopService.onUpdatedCart(() => { - return this.renderMark(); - }); - - this.prestashopService.onUpdatedProduct(() => { - return this.renderMark(); - }); - - return this; - } - - renderMark() { - let containerLogoIdentifier = `#ps_checkout-payment-method-logos-container`; - const containerLogoQuerySelector = this.querySelectorService.getPaymentMethodLogoContainer(this.props.placement); - const fundingSources = this.payPalService.getEligibleFundingSources(); - - if (containerLogoQuerySelector) { - const containerLogo = document.querySelector(containerLogoIdentifier); - - if (null === containerLogo) { - let containerLogoElement = this.createContainer(containerLogoIdentifier, containerLogoQuerySelector); - - fundingSources.forEach(fundingSource => { - if (this.hasCustomMark(fundingSource.name)) { - this.renderCustomMark(fundingSource.name, containerLogoElement); - } else { - fundingSource.mark.render(containerLogoElement); - } - }); - } - } - } - - createContainer(containerIdentifier, querySelector) { - const container = document.querySelector(containerIdentifier); - - if (null === container) { - let containerParentElement = document.createElement('div'); - containerParentElement.id = 'ps_checkout-payment-method-logo-block-container'; - - let titleImg = document.createElement('img'); - titleImg.id = 'ps_checkout-payment-method-logo-block-img'; - titleImg.setAttribute('alt', this.$('payment-method-logos.title')); - titleImg.setAttribute('src', this.config.imgTitlePaymentMethodLogos); - - let title = document.createElement('div'); - title.id = 'ps_checkout-payment-method-logo-block-title'; - title.innerText = this.$('payment-method-logos.title'); - title.prepend(titleImg); - containerParentElement.append(title); - - let containerLogoElement = document.createElement('div'); - containerLogoElement.id = containerIdentifier.slice(1); - - containerParentElement.append(containerLogoElement); - - querySelector.append(containerParentElement); - - return containerLogoElement; - } - - return container; - } - - hasCustomMark(fundingSource) { - return this.config.customMark[fundingSource]; - } - - renderCustomMark(fundingSource, containerQuerySelector) { - const src = this.config.customMark[fundingSource]; - let logoList = []; - let containerElement = document.createElement('div'); - - if (this.config.cardSupportedBrands && this.config.cardLogoBrands) { - this.config.cardSupportedBrands.forEach(brand => { - if (this.config.cardLogoBrands[brand]) { - let customMarkImg = document.createElement('img'); - customMarkImg.classList.add('cards-logo'); - customMarkImg.setAttribute('alt', brand); - customMarkImg.setAttribute('src', this.config.cardLogoBrands[brand]); - logoList.push(customMarkImg); - let space = document.createElement('span'); - space.classList.add('paypal-button-space'); - space.innerText = ' '; - logoList.push(space); - } - }); - } else { - let customMarkImg = document.createElement('img'); - customMarkImg.classList.add('cards-logo'); - customMarkImg.setAttribute('alt', fundingSource); - customMarkImg.setAttribute('src', src); - logoList.push(customMarkImg); - } - - logoList.forEach(customMarkImg => containerElement.append(customMarkImg)); - containerElement.classList.add('paypal-mark'); - containerQuerySelector.append(containerElement); - } -} diff --git a/_dev/js/front/src/components/common/payment-option.component.js b/_dev/js/front/src/components/common/payment-option.component.js deleted file mode 100644 index ea41ae465..000000000 --- a/_dev/js/front/src/components/common/payment-option.component.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -import { MarkComponent } from './marker.component'; -import { SmartButtonComponent } from './smart-button.component'; -import { PaymentFieldsComponent } from "./payment-fields.component"; -import {CardFieldsComponent} from "./card-fields.component"; -import {PS_VERSION_1_6} from "../../constants/ps-version.constants"; - -/** - * @typedef PaymentOptionComponentProps - * - * @param {string} fundingSource.name - * @param {*} fundingSource.mark - * - * @param {HTMLElement} HTMLElement - */ - -export class PaymentOptionComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - querySelectorService: 'QuerySelectorService', - prestashopService: 'PrestashopService', - $: '$' - }; - - created() { - this.data.name = this.props.fundingSource.name; - - this.data.HTMLElement = this.props.HTMLElement; - this.data.HTMLElementContainer = this.getContainer(); - this.data.HTMLElementLabel = this.getLabel(); - this.data.HTMLElementMark = this.props.HTMLElementMark || null; - - this.data.HTMLElementCardFields =this.querySelectorService.getCardFieldsFormContainer(); - this.data.HTMLElementSmartButton = this.getSmartButton(); - this.data.HTMLElementPaymentFields = this.getPaymentFields(); - } - - getContainer() { - const wrapperId = `${this.data.HTMLElement.id}-container`; - return document.getElementById(wrapperId); - } - - getPaymentFields() { - const container = `pay-with-${this.data.HTMLElement.id}-form`; - const APM = ['bancontact', 'blik', 'eps', 'giropay', 'ideal', 'mybank', 'p24', 'sofort']; - - const APMEligible = typeof this.payPalService.sdk.PaymentFields?.isEligible === "function" ? - this.payPalService.sdk.PaymentFields.isEligible(this.data.name) - : APM.includes(this.data.name) - - return ( - APMEligible && - document.getElementById(container) - ); - } - - getLabel() { - const translationKey = `funding-source.name.${this.data.name}`; - const label = - this.$(translationKey) !== undefined - ? this.$(translationKey) - : this.$('funding-source.name.default'); - - let element = Array.prototype.slice - .call(this.data.HTMLElementContainer.querySelectorAll('*')) - .find( - item => (this.prestashopService.getVersion() === PS_VERSION_1_6 ? item.innerHTML.trim() : item.innerText.trim()) - === label.trim() - ); - - if (!element) { - console.error('HTMLElement label "' + label.trim() + '" not found.'); - } - - return element; - } - - getSmartButton() { - const smartButtonSelector = `.ps_checkout-button[data-funding-source=${this.data.name}]`; - return document.querySelector(smartButtonSelector); - } - - onLabelClick(listener) { - this.data.HTMLElementLabel.addEventListener('click', event => { - event.preventDefault(); - listener(this, event); - }); - } - - renderWrapper() { - this.data.HTMLElementContainer.classList.add('ps_checkout-payment-option'); - this.data.HTMLElementContainer.style.display = ''; - } - - renderMark() { - if (!this.data.HTMLElementLabel) { - return; - } - - if (!this.data.HTMLElementMarker) { - this.data.HTMLElementMarker = document.createElement('div'); - this.data.HTMLElementMarker.style.display = 'inline-block'; - - if (this.props.markPosition === 'before') { - this.data.HTMLElementLabel.prepend(this.data.HTMLElementMarker); - } else { - this.data.HTMLElementLabel.append(this.data.HTMLElementMarker); - } - } - - this.children.Marker = this.marker = new MarkComponent(this.app, { - fundingSource: this.props.fundingSource, - - HTMLElement: this.data.HTMLElementMarker - }).render(); - } - - renderPaymentFields() { - if (!this.data.HTMLElementPaymentFields) { - return; - } - - this.children.PaymentFields = this.PaymentFields = new PaymentFieldsComponent(this.app, { - fundingSource: this.props.fundingSource, - - HTMLElement: this.data.HTMLElementPaymentFields - }).render(); - } - - render() { - if (this.data.HTMLElementContainer.classList.contains('ps_checkout-payment-option')) { - // Render already done - return; - } - - this.renderWrapper(); - this.renderMark(); - this.renderPaymentFields(); - - const isCardFieldsEligible = this.payPalService.isCardFieldsEligible(); - // Check if all fields required for cardFields are present in DOM - const isCardFieldsAvailable = this.data.name === 'card' - && this.config.hostedFieldsEnabled - && this.querySelectorService.getCardFieldsNameInputContainer() - && this.querySelectorService.getCardFieldsNumberInputContainer() - && this.querySelectorService.getCardFieldsExpiryInputContainer() - && this.querySelectorService.getCardFieldsCvvInputContainer(); - - if (this.data.HTMLElementCardFields && (!isCardFieldsEligible || !isCardFieldsAvailable)) { - this.data.HTMLElementCardFields.style.display = 'none'; - } - - if (this.data.HTMLElementCardFields && isCardFieldsEligible && isCardFieldsAvailable) { - this.data.HTMLElementCardFields.style.display = ''; - this.children.cardFields = new CardFieldsComponent(this.app, { - fundingSource: this.props.fundingSource, - HTMLElement: this.data.HTMLElementCardFields - }).render(); - } else { - this.children.smartButton = new SmartButtonComponent(this.app, { - fundingSource: this.props.fundingSource, - - HTMLElement: this.data.HTMLElementSmartButton - }).render(); - } - - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payment-option-active', { - detail: { - fundingSource: this.data.name, - HTMLElement: this.data.HTMLElement, - HTMLElementContainer: this.data.HTMLElementContainer, - HTMLElementBinary: this.data.HTMLElementCardFields && isCardFieldsEligible && isCardFieldsAvailable - ? this.children.cardFields.data.HTMLElementButton.parentElement - : this.data.HTMLElementSmartButton - } - }) - ); - - return this; - } -} diff --git a/_dev/js/front/src/components/common/payment-option.component.spec.js b/_dev/js/front/src/components/common/payment-option.component.spec.js deleted file mode 100644 index 7beb4129e..000000000 --- a/_dev/js/front/src/components/common/payment-option.component.spec.js +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { PsCheckoutConfig } from '../../config/ps-checkout.config'; - -import { HostedFieldsComponentMock } from '../../../test/mocks/components/common/hosted-fields.component.mock'; -import { MarkComponentMock } from '../../../test/mocks/components/common/mark.component.mock'; -import { SmartButtonComponentMock } from '../../../test/mocks/components/common/smart-button.component.mock'; -import { PaymentFieldsComponentMock } from '../../../test/mocks/components/common/payment-fields.component.mock'; - -function buildDIContainerMock() { - return { - container: { - PsCheckoutConfig: { - ...PsCheckoutConfig - }, - PayPalService: { - getPaymentFields: jest.fn(), - sdk: { - paymentFields: { - isEligible: jest.fn() - } - }, - }, - $: jest.fn().mockImplementation(key => { - return ( - { - 'funding-source.name.foo': 'Foo', - 'funding-source.name.default': 'Default' - }[key] || '' - ); - }) - } - }; -} - -describe('src/components/common/payment-option.component.spec.js', () => { - const markComponentMock = MarkComponentMock; - const smartButtonComponentMock = SmartButtonComponentMock; - const hostedFieldsComponentMock = HostedFieldsComponentMock; - const paymentFieldsComponentMock = PaymentFieldsComponentMock; - - let PaymentOptionComponent; - - beforeEach(() => { - markComponentMock.mockClear(); - markComponentMock.render.mockClear(); - - smartButtonComponentMock.mockClear(); - smartButtonComponentMock.render.mockClear(); - - hostedFieldsComponentMock.mockClear(); - hostedFieldsComponentMock.render.mockClear(); - - paymentFieldsComponentMock.mockClear(); - paymentFieldsComponentMock.render.mockClear(); - - jest - .doMock('./marker.component', () => ({ - MarkComponent: markComponentMock - })) - .doMock('./smart-button.component', () => ({ - SmartButtonComponent: smartButtonComponentMock - })) - .doMock('./payment-fields.component', () => ({ - PaymentFieldsComponent: paymentFieldsComponentMock - })) - .doMock('./hosted-fields.component', () => ({ - HostedFieldsComponent: hostedFieldsComponentMock - })); - - PaymentOptionComponent = require('./payment-option.component') - .PaymentOptionComponent; - }); - - afterEach(() => { - jest.clearAllMocks(); - - return (document.body.innerHTML = ''); - }); - - test('::render() with SmartButton and translatable label', () => { - document.body.innerHTML = - '
' + - '
Foo
' + - '
' + - '
' + - '
'; - - const HTMLElement = document.getElementById('foo-payment-option'); - const fundingSource = { - name: 'foo' - }; - - const diContainer = buildDIContainerMock(); - const paymentOptionComponent = new PaymentOptionComponent(diContainer, { - HTMLElement, - fundingSource - }); - - const labelListener = jest.fn(); - paymentOptionComponent.onLabelClick(labelListener); - - expect(paymentOptionComponent.render()).toBe(paymentOptionComponent); - expect(markComponentMock.render).toHaveBeenCalledTimes(1); - expect(smartButtonComponentMock.render).toHaveBeenCalledTimes(1); - expect(hostedFieldsComponentMock.render).not.toHaveBeenCalled(); - expect(diContainer.container.$).toHaveBeenCalledTimes(2); - - expect(labelListener).not.toHaveBeenCalled(); - document.getElementById('foo-label').click(); - expect(labelListener).toHaveBeenCalledTimes(1); - }); -}); diff --git a/_dev/js/front/src/components/common/payment-options-loader.component.spec.js b/_dev/js/front/src/components/common/payment-options-loader.component.spec.js deleted file mode 100644 index 671aa8a01..000000000 --- a/_dev/js/front/src/components/common/payment-options-loader.component.spec.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { PaymentOptionsLoaderComponent } from './payment-options-loader.component'; - -function buildDIContainerMock() { - return { - container: { - QuerySelectorService: { - getPaymentOptionsLoader: jest.fn() - } - } - }; -} - -describe('src/components/common/payment-options-loader.component.spec.js', () => { - test('::render() without HTMLElement', () => { - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getPaymentOptionsLoader.mockReturnValueOnce( - undefined - ); - - const component = new PaymentOptionsLoaderComponent(diContainer); - expect(component.render()).toBe(component); - }); - - test('::render()', () => { - document.body.innerHTML = '
'; - - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getPaymentOptionsLoader.mockReturnValueOnce( - document.getElementById('foo') - ); - - const component = new PaymentOptionsLoaderComponent(diContainer); - expect(component.render()).toBe(component); - - document.body.innerHTML = ''; - }); - - test('::hide() without HTMLElement', () => { - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getPaymentOptionsLoader.mockReturnValueOnce( - undefined - ); - - const component = new PaymentOptionsLoaderComponent(diContainer); - expect(component.render()).toBe(component); - expect(() => component.hide()).not.toThrow(); - }); - - test('::hide()', () => { - document.body.innerHTML = '
'; - const loader = document.getElementById('foo'); - - const diContainer = buildDIContainerMock(); - diContainer.container.QuerySelectorService.getPaymentOptionsLoader.mockReturnValueOnce( - loader - ); - - const component = new PaymentOptionsLoaderComponent(diContainer); - expect(component.render()).toBe(component); - expect(() => component.hide()).not.toThrow(); - expect(loader.style.display).toBe('none'); - }); -}); diff --git a/_dev/js/front/src/components/common/smart-button.component.js b/_dev/js/front/src/components/common/smart-button.component.js deleted file mode 100644 index 146ea21de..000000000 --- a/_dev/js/front/src/components/common/smart-button.component.js +++ /dev/null @@ -1,211 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -/** - * @typedef SmartButtonComponentProps - * - * @param {string} fundingSource.name - * @param {*} fundingSource.mark - * - * @param {HTMLElement} [HTMLElement] - * @param {HTMLElement} HTMLElementWrapper - */ - -export class SmartButtonComponent extends BaseComponent { - static Inject = { - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi' - }; - - created() { - this.data.name = this.props.fundingSource.name; - this.data.orderId = null; - - this.data.HTMLElement = this.props.HTMLElement; - - this.data.conditions = this.app.root.children.conditionsCheckbox; - this.data.loader = this.app.root.children.loader; - this.data.notification = this.app.root.children.notification; - } - - renderPayPalButton() { - const buttonSelector = `.ps_checkout-button[data-funding-source=${this.data.name}]`; - - this.data.HTMLElement.classList.add('ps_checkout-button'); - this.data.HTMLElement.setAttribute('data-funding-source', this.data.name); - - return this.payPalService - .getButtonPayment(this.data.name, { - onInit: (data, actions) => { - if (!this.data.conditions) { - actions.enable(); - return; - } - - if (this.data.conditions.isChecked()) { - this.data.notification.hideConditions(); - actions.enable(); - } else { - this.data.notification.showConditions(); - actions.disable(); - } - - this.data.conditions.onChange(() => { - if (this.data.conditions.isChecked()) { - this.data.notification.hideConditions(); - actions.enable(); - } else { - this.data.notification.showConditions(); - actions.disable(); - } - }); - }, - onClick: (data, actions) => { - if (this.data.conditions && !this.data.conditions.isChecked()) { - this.data.notification.hideCancelled(); - this.data.notification.hideError(); - this.data.notification.showConditions(); - - return actions.reject(); - } - - if (this.data.name !== 'card') { - this.data.loader.show(); - } - - return this.psCheckoutApi - .postCheckCartOrder( - { - ...data, - fundingSource: this.data.name, - isExpressCheckout: this.config.expressCheckout.active, - orderID: this.payPalService.getOrderId() - }, - actions - ) - .catch((error) => { - this.data.loader.hide(); - this.data.notification.showError(error.message); - return actions.reject(); - }); - }, - onError: (error) => { - let errorMessage = this.handleError(error); - console.error(error); - this.data.loader.hide(); - this.data.notification.showError(errorMessage); - - return this.psCheckoutApi - .postCancelOrder({ - orderID: this.data.orderId, - fundingSource: this.data.name, - isExpressCheckout: this.config.expressCheckout.active, - reason: 'checkout_error', - error: errorMessage - }) - .catch((error) => console.error(error)); - }, - onApprove: (data, actions) => { - this.data.loader.show(); - return this.psCheckoutApi - .postValidateOrder( - { - ...data, - fundingSource: this.data.name, - isExpressCheckout: this.config.expressCheckout.active - }, - actions - ) - .catch((error) => { - this.data.loader.hide(); - this.data.notification.showError(error.message); - }); - }, - onCancel: (data) => { - this.data.loader.hide(); - this.data.notification.showCanceled(); - - return this.psCheckoutApi - .postCancelOrder({ - ...data, - fundingSource: this.data.name, - isExpressCheckout: this.config.expressCheckout.active, - reason: 'checkout_cancelled' - }) - .catch((error) => { - this.data.loader.hide(); - this.data.notification.showError(error.message); - }); - }, - createOrder: (data) => { - return this.psCheckoutApi - .postCreateOrder({ - ...data, - fundingSource: this.data.name, - isExpressCheckout: this.config.expressCheckout.active - }) - .then((data) => { - this.data.orderId = data; - return data; - }) - .catch((error) => { - this.data.loader.hide(); - this.data.notification.showError( - `${error.message} ${error.name}` - ); - }); - } - }) - .render(buttonSelector); - } - - handleError(error) { - let errorMessage = error; - - if (error instanceof Error) { - if (error.message) { - errorMessage = error.message; - - if ( - error.message.includes('CURRENCY_NOT_SUPPORTED_BY_PAYMENT_SOURCE') - ) { - errorMessage = - 'Provided currency is not supported by the selected payment method.'; - } else if ( - error.message.includes('COUNTRY_NOT_SUPPORTED_BY_PAYMENT_SOURCE') - ) { - errorMessage = - 'Provided country is not supported by the selected payment method.'; - } else if (error.message.includes('Detected popup close')) { - errorMessage = - 'The payment failed because the payment window has been closed before the end of the payment process.'; - } - } - } - - return errorMessage; - } - - render() { - this.renderPayPalButton(); - return this; - } -} diff --git a/_dev/js/front/src/components/common/smart-button.component.spec.js b/_dev/js/front/src/components/common/smart-button.component.spec.js deleted file mode 100644 index de6cb3fe1..000000000 --- a/_dev/js/front/src/components/common/smart-button.component.spec.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { PsCheckoutConfig } from '../../config/ps-checkout.config'; -import { PayPalServiceMock } from '../../../test/mocks/service/paypal.service'; -import { PsCheckoutApiMock } from '../../../test/mocks/api/ps-checkout.api'; -import { PaymentOptionsLoaderComponent } from './payment-options-loader.component'; -import { SmartButtonComponent } from './smart-button.component'; - -function buildDIContainerMock() { - return { - root: { - children: { - conditionsCheckbox: jest.fn() - } - }, - container: { - PsCheckoutConfig: { - ...PsCheckoutConfig - }, - PayPalService: PayPalServiceMock, - PsCheckoutApi: PsCheckoutApiMock - } - }; -} - -describe('src/components/common/smart-button.component.spec.js', () => { - afterEach(() => (document.body.innerHTML = '')); - - test('::render()', () => { - document.body.innerHTML = - '
'; - - const HTMLElement = document.querySelector('.ps_checkout-button'); - const fundingSource = { - name: 'foo' - }; - - const diContainer = buildDIContainerMock(); - diContainer.container.PayPalService.getButtonPayment.mockImplementationOnce( - () => { - return diContainer.container.PayPalService; - } - ); - - const smartButtonComponent = new SmartButtonComponent(diContainer, { - HTMLElement, - fundingSource - }); - expect(smartButtonComponent.render()).toBe(smartButtonComponent); - expect(diContainer.container.PayPalService.render).toHaveBeenCalledWith( - `.ps_checkout-button[data-funding-source=${fundingSource.name}]` - ); - }); - - // TODO: Test listeners -}); diff --git a/_dev/js/front/src/components/ps-checkout-express.component/index.js b/_dev/js/front/src/components/ps-checkout-express.component/index.js deleted file mode 100644 index 3f596bacc..000000000 --- a/_dev/js/front/src/components/ps-checkout-express.component/index.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; - -import { PsCheckoutExpressPs1_6Component } from './ps-checkout-express-ps1_6.component'; -import { PsCheckoutExpressPs1_7Component } from './ps-checkout-express-ps1_7.component'; - -export class PsCheckoutExpressComponent extends BaseComponent { - static Inject = { - prestashopService: 'PrestashopService' - }; - - constructor(app, props) { - super(app, props); - - this.instance = new { - [PS_VERSION_1_6]: PsCheckoutExpressPs1_6Component, - [PS_VERSION_1_7]: PsCheckoutExpressPs1_7Component - }[this.prestashopService.getVersion()](app, props); - } - - render() { - return this.instance.render(); - } -} diff --git a/_dev/js/front/src/components/ps-checkout-express.component/ps-checkout-express-ps1_6.component.js b/_dev/js/front/src/components/ps-checkout-express.component/ps-checkout-express-ps1_6.component.js deleted file mode 100644 index 9029ff053..000000000 --- a/_dev/js/front/src/components/ps-checkout-express.component/ps-checkout-express-ps1_6.component.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -import { ExpressButtonCartComponent } from '../1_6/express-button-cart.component'; -import { ExpressButtonCheckoutComponent } from '../1_6/express-button-checkout.component'; -import { ExpressButtonProductComponent } from '../1_6/express-button-product.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PsCheckoutExpressPs1_6Component extends BaseComponent { - static ID = 0; - - static Inject = { - config: 'PsCheckoutConfig', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi' - }; - - renderExpressCheckoutCustom() { - this.props.HTMLElement.classList.add('ps_checkout-express-button'); - this.props.HTMLElement.setAttribute( - 'express-button-id', - PsCheckoutExpressPs1_6Component.ID - ); - - this.children.expressButton = new ExpressCheckoutButtonComponent(this.app, { - querySelector: `.ps_checkout-express-button[express-button-id="${PsCheckoutExpressPs1_6Component.ID++}"]`, - createOrder: (data) => - this.psCheckoutApi.postCreateOrder({ - ...(this.props.productData || data), - fundingSource: 'paypal', - isExpressCheckout: true - }) - }).render(); - } - - renderExpressCheckout() { - if (this.props.HTMLElement) { - this.renderExpressCheckoutCustom(); - return; - } - - if (this.prestashopService.isCartPage()) { - if (!this.config.expressCheckout.enabled.cart) return this; - if (!window.ps_checkoutCartProductCount) return this; - - this.children.expressButton = new ExpressButtonCartComponent( - this.app - ).render(); - - return this; - } - - if (this.prestashopService.isOrderPersonalInformationStepPage()) { - if (!this.config.expressCheckout.enabled.order) return this; - if (!window.ps_checkoutCartProductCount) return this; - this.children.expressButton = new ExpressButtonCheckoutComponent( - this.app - ).render(); - - return this; - } - - if ( - this.prestashopService.isProductPage() && - !this.prestashopService.isIframeProductPage() - ) { - if (!this.config.expressCheckout.enabled.product) return; - if ( - this.children.expressButton && - this.children.expressButton.checkoutExpressButton && - this.children.expressButton.checkoutExpressButton.parentNode - ) - return; - - this.children.expressButton = new ExpressButtonProductComponent( - this.app - ).render(); - - return this; - } - } - - render() { - this.renderExpressCheckout(); - - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout-express.component/ps-checkout-express-ps1_7.component.js b/_dev/js/front/src/components/ps-checkout-express.component/ps-checkout-express-ps1_7.component.js deleted file mode 100644 index a3e87f9e7..000000000 --- a/_dev/js/front/src/components/ps-checkout-express.component/ps-checkout-express-ps1_7.component.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -import { ExpressButtonCartComponent } from '../1_7/express-button-cart.component'; -import { ExpressButtonCheckoutComponent } from '../1_7/express-button-checkout.component'; -import { ExpressButtonProductComponent } from '../1_7/express-button-product.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PsCheckoutExpressPs1_7Component extends BaseComponent { - static ID = 0; - - static Inject = { - config: 'PsCheckoutConfig', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi' - }; - - renderExpressCheckoutCustom() { - this.props.HTMLElement.classList.add('ps_checkout-express-button'); - this.props.HTMLElement.setAttribute( - 'express-button-id', - PsCheckoutExpressPs1_7Component.ID - ); - - this.children.expressButton = new ExpressCheckoutButtonComponent(this.app, { - querySelector: `.ps_checkout-express-button[express-button-id="${PsCheckoutExpressPs1_7Component.ID++}"]`, - createOrder: (data) => - this.psCheckoutApi.postCreateOrder({ - ...(this.props.productData || data), - fundingSource: 'paypal', - isExpressCheckout: true - }) - }).render(); - } - - renderExpressCheckout() { - if (this.props.HTMLElement) { - this.renderExpressCheckoutCustom(); - return; - } - - if (this.prestashopService.isCartPage()) { - if (!this.config.expressCheckout.enabled.cart) return this; - if (document.body.classList.contains('cart-empty')) return this; - - this.children.expressButton = new ExpressButtonCartComponent( - this.app - ).render(); - - return this; - } - - if (this.prestashopService.isOrderPersonalInformationStepPage()) { - if (!this.config.expressCheckout.enabled.order) return this; - this.children.expressButton = new ExpressButtonCheckoutComponent( - this.app - ).render(); - - return this; - } - - if (this.prestashopService.isProductPage()) { - if (!this.config.expressCheckout.enabled.product) return; - - if ( - this.children.expressButton && - this.children.expressButton.checkoutExpressButton && - this.children.expressButton.checkoutExpressButton.parentNode - ) - return; - - this.children.expressButton = new ExpressButtonProductComponent( - this.app - ).render(); - - return this; - } - } - - render() { - this.renderExpressCheckout(); - this.prestashopService.onUpdatedCart(() => { - return this.renderExpressCheckout(); - }); - - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/index.js b/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/index.js deleted file mode 100644 index 8e70a3b36..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/index.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; - -import { PayLaterBannerPs1_6Component } from './pay-later-banner-ps1_6.component'; -import { PayLaterBannerPs1_7Component } from './pay-later-banner-ps1_7.component'; - -export class PayLaterBannerComponent extends BaseComponent { - - static Inject = { - prestashopService: 'PrestashopService', - querySelectorService: 'QuerySelectorService', - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi', - $: '$' - }; - - constructor(app, props) { - super(app, props); - - this.instance = new { - [PS_VERSION_1_6]: PayLaterBannerPs1_6Component, - [PS_VERSION_1_7]: PayLaterBannerPs1_7Component - }[this.prestashopService.getVersion()](app, props); - } - - onRender(...args) { - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payLaterOfferBannerOnRender', args) - ); - } - - onClick(...args) { - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payLaterOfferBannerOnClick', args) - ); - } - - onApply(...args) { - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payLaterOfferBannerOnApply', args) - ); - } - - getContainerIdentifier(placement) { - return `#ps_checkout-paypal-pay-later-banner-${placement}`; - } - - renderPayLaterOfferBanner() { - let containerIdentifier = this.getContainerIdentifier(this.props.placement); - let amount = 'product' === this.props.placement ? this.prestashopService.getProductPrice() : this.prestashopService.getCartAmount(); - let containerQuerySelector = this.querySelectorService.getPayLaterOfferBannerContainerSelector(this.props.placement); - - if (null === containerQuerySelector) { - return; - } - - this.instance.createContainer(containerIdentifier, containerQuerySelector); - - return this.payPalService - .getPayLaterOfferBanner(this.props.placement, amount, { - onRender: (...args) => this.onRender(...args), - onClick: (...args) => this.onClick(...args), - onApply: (...args) => this.onApply(...args) - }) - .render(containerIdentifier); - } - - render() { - this.renderPayLaterOfferBanner(); - this.prestashopService.onUpdatedCart(() => { - return this.renderPayLaterOfferBanner(); - }); - this.prestashopService.onUpdatedProduct(() => { - return this.renderPayLaterOfferBanner(); - }); - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/pay-later-banner-ps1_6.component.js b/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/pay-later-banner-ps1_6.component.js deleted file mode 100644 index a0f9ce875..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/pay-later-banner-ps1_6.component.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class PayLaterBannerPs1_6Component extends BaseComponent { - createContainer(containerIdentifier, querySelector) { - if (null === document.querySelector(containerIdentifier)) { - let containerElement = document.createElement('div'); - containerElement.id = containerIdentifier.slice(1); - containerElement.classList.add('container', 'paypal-pay-later-banner'); - querySelector.append(containerElement); - } - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/pay-later-banner-ps1_7.component.js b/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/pay-later-banner-ps1_7.component.js deleted file mode 100644 index addc39d32..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later-banner.component/pay-later-banner-ps1_7.component.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class PayLaterBannerPs1_7Component extends BaseComponent { - createContainer(containerIdentifier, querySelector) { - if (null === document.querySelector(containerIdentifier)) { - let containerElement = document.createElement('div'); - containerElement.id = containerIdentifier.slice(1); - containerElement.classList.add('paypal-pay-later-banner'); - querySelector.append(containerElement); - } - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later-message.component/index.js b/_dev/js/front/src/components/ps-checkout-pay-later-message.component/index.js deleted file mode 100644 index 845956cba..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later-message.component/index.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; - -import { PayLaterMessagePs1_6Component } from './pay-later-message-ps1_6.component'; -import { PayLaterMessagePs1_7Component } from './pay-later-message-ps1_7.component'; - -export class PayLaterMessageComponent extends BaseComponent { - static Inject = { - prestashopService: 'PrestashopService', - querySelectorService: 'QuerySelectorService', - config: 'PsCheckoutConfig', - payPalService: 'PayPalService', - psCheckoutApi: 'PsCheckoutApi', - $: '$' - }; - - constructor(app, props) { - super(app, props); - - this.instance = new { - [PS_VERSION_1_6]: PayLaterMessagePs1_6Component, - [PS_VERSION_1_7]: PayLaterMessagePs1_7Component - }[this.prestashopService.getVersion()](app, props); - } - - onRender(...args) { - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payLaterOfferMessageOnRender', args) - ); - } - - onClick(...args) { - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payLaterOfferMessageOnClick', args) - ); - } - - onApply(...args) { - window.ps_checkout.events.dispatchEvent( - new CustomEvent('payLaterOfferMessageOnApply', args) - ); - } - - getContainerIdentifier(placement) { - return `#ps_checkout-paypal-pay-later-message-${placement}`; - } - - renderPayLaterOfferMessage() { - let containerIdentifier = this.getContainerIdentifier(this.props.placement); - let amount = 'product' === this.props.placement ? this.prestashopService.getProductPrice() : this.prestashopService.getCartAmount(); - let containerQuerySelector = this.querySelectorService.getPayLaterOfferMessageContainerSelector(this.props.placement); - - if (null === containerQuerySelector) { - return; - } - - this.instance.createContainer(containerIdentifier, containerQuerySelector); - - return this.payPalService - .getPayLaterOfferMessage(this.props.placement, amount, { - onRender: (...args) => this.onRender(...args), - onClick: (...args) => this.onClick(...args), - onApply: (...args) => this.onApply(...args) - }) - .render(containerIdentifier); - } - - render() { - this.renderPayLaterOfferMessage(); - this.prestashopService.onUpdatedCart(() => { - return this.renderPayLaterOfferMessage(); - }); - this.prestashopService.onUpdatedProduct(() => { - return this.renderPayLaterOfferMessage(); - }); - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later-message.component/pay-later-message-ps1_6.component.js b/_dev/js/front/src/components/ps-checkout-pay-later-message.component/pay-later-message-ps1_6.component.js deleted file mode 100644 index e4563d660..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later-message.component/pay-later-message-ps1_6.component.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class PayLaterMessagePs1_6Component extends BaseComponent { - createContainer(containerIdentifier, querySelector) { - if (null === document.querySelector(containerIdentifier)) { - let containerElement = document.createElement('div'); - containerElement.id = containerIdentifier.slice(1); - containerElement.classList.add('paypal-pay-later-message'); - querySelector.append(containerElement); - } - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later-message.component/pay-later-message-ps1_7.component.js b/_dev/js/front/src/components/ps-checkout-pay-later-message.component/pay-later-message-ps1_7.component.js deleted file mode 100644 index 983313bdc..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later-message.component/pay-later-message-ps1_7.component.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -export class PayLaterMessagePs1_7Component extends BaseComponent { - createContainer(containerIdentifier, querySelector) { - if (null === document.querySelector(containerIdentifier)) { - let containerElement = document.createElement('div'); - containerElement.id = containerIdentifier.slice(1); - containerElement.classList.add('paypal-pay-later-message'); - querySelector.append(containerElement); - } - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later.component/index.js b/_dev/js/front/src/components/ps-checkout-pay-later.component/index.js deleted file mode 100644 index ab6705f19..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later.component/index.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; - -import { PsCheckoutPayLaterButtonPs1_6Component } from './ps-checkout-pay-later-button-ps1_6.component'; -import { PsCheckoutPayLaterButtonPs1_7Component } from './ps-checkout-pay-later-button-ps1_7.component'; - -export class PsCheckoutExpressPayLaterComponent extends BaseComponent { - static Inject = { - prestashopService: 'PrestashopService' - }; - - constructor(app, props) { - super(app, props); - - this.instance = new { - [PS_VERSION_1_6]: PsCheckoutPayLaterButtonPs1_6Component, - [PS_VERSION_1_7]: PsCheckoutPayLaterButtonPs1_7Component - }[this.prestashopService.getVersion()](app, props); - } - - render() { - return this.instance.render(); - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later.component/ps-checkout-pay-later-button-ps1_6.component.js b/_dev/js/front/src/components/ps-checkout-pay-later.component/ps-checkout-pay-later-button-ps1_6.component.js deleted file mode 100644 index 0fc4dfd78..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later.component/ps-checkout-pay-later-button-ps1_6.component.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -import { PayLaterButtonCartComponent } from '../1_6/pay-later-button-cart.component'; -import { PayLaterButtonCheckoutComponent } from '../1_6/pay-later-button-checkout.component'; -import { PayLaterButtonProductComponent } from '../1_6/pay-later-button-product.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PsCheckoutPayLaterButtonPs1_6Component extends BaseComponent { - static ID = 0; - - static Inject = { - config: 'PsCheckoutConfig', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi' - }; - - renderExpressCheckoutCustom() { - this.props.HTMLElement.classList.add('ps_checkout-express-button'); - this.props.HTMLElement.setAttribute( - 'express-button-id', - PsCheckoutPayLaterButtonPs1_6Component.ID - ); - - this.children.expressButton = new ExpressCheckoutButtonComponent(this.app, { - fundingSource: 'paylater', - querySelector: `.ps_checkout-express-button[express-button-id="${PsCheckoutPayLaterButtonPs1_6Component.ID++}"]`, - createOrder: (data) => - this.psCheckoutApi.postCreateOrder({ - ...(this.props.productData || data), - fundingSource: 'paylater', - isExpressCheckout: true - }) - }).render(); - } - - renderExpressCheckout() { - if (this.props.HTMLElement) { - this.renderExpressCheckoutCustom(); - return; - } - - if (this.prestashopService.isCartPage()) { - if (!this.config.payLater.button.cart) return this; - if (!window.ps_checkoutCartProductCount) return this; - - this.children.expressButton = new PayLaterButtonCartComponent( - this.app - ).render(); - - return this; - } - - if (this.prestashopService.isOrderPersonalInformationStepPage()) { - if (!this.config.payLater.button.order) return this; - if (!window.ps_checkoutCartProductCount) return this; - this.children.expressButton = new PayLaterButtonCheckoutComponent( - this.app - ).render(); - - return this; - } - - if ( - this.prestashopService.isProductPage() && - !this.prestashopService.isIframeProductPage() - ) { - if (!this.config.payLater.button.product) return; - if ( - this.children.expressButton && - this.children.expressButton.checkoutExpressButton && - this.children.expressButton.checkoutExpressButton.parentNode - ) - return; - - this.children.expressButton = new PayLaterButtonProductComponent( - this.app - ).render(); - - return this; - } - } - - render() { - this.renderExpressCheckout(); - - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout-pay-later.component/ps-checkout-pay-later-button-ps1_7.component.js b/_dev/js/front/src/components/ps-checkout-pay-later.component/ps-checkout-pay-later-button-ps1_7.component.js deleted file mode 100644 index 8097223b4..000000000 --- a/_dev/js/front/src/components/ps-checkout-pay-later.component/ps-checkout-pay-later-button-ps1_7.component.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; - -import { PayLaterButtonCartComponent } from '../1_7/pay-later-button-cart.component'; -import { PayLaterButtonCheckoutComponent } from '../1_7/pay-later-button-checkout.component'; -import { PayLaterButtonProductComponent } from '../1_7/pay-later-button-product.component'; -import { ExpressCheckoutButtonComponent } from '../common/express-checkout-button.component'; - -export class PsCheckoutPayLaterButtonPs1_7Component extends BaseComponent { - static ID = 0; - - static Inject = { - config: 'PsCheckoutConfig', - prestashopService: 'PrestashopService', - psCheckoutApi: 'PsCheckoutApi' - }; - - renderExpressCheckoutCustom() { - this.props.HTMLElement.classList.add('ps_checkout-express-button'); - this.props.HTMLElement.setAttribute( - 'express-button-id', - PsCheckoutPayLaterButtonPs1_7Component.ID - ); - - this.children.expressButton = new ExpressCheckoutButtonComponent(this.app, { - fundingSource: 'paylater', - querySelector: `.ps_checkout-express-button[express-button-id="${PsCheckoutPayLaterButtonPs1_7Component.ID++}"]`, - createOrder: (data) => - this.psCheckoutApi.postCreateOrder({ - ...(this.props.productData || data), - fundingSource: 'paylater', - isExpressCheckout: true - }) - }).render(); - } - - renderExpressCheckout() { - if (this.props.HTMLElement) { - this.renderExpressCheckoutCustom(); - return; - } - - if (this.prestashopService.isCartPage()) { - if (!this.config.payLater.button.cart) return this; - if (document.body.classList.contains('cart-empty')) return this; - - this.children.expressButton = new PayLaterButtonCartComponent( - this.app - ).render(); - - return this; - } - - if (this.prestashopService.isOrderPersonalInformationStepPage()) { - if (!this.config.payLater.button.order) return this; - this.children.expressButton = new PayLaterButtonCheckoutComponent( - this.app - ).render(); - - return this; - } - - if (this.prestashopService.isProductPage()) { - if (!this.config.payLater.button.product) return; - if ( - this.children.expressButton && - this.children.expressButton.checkoutExpressButton && - this.children.expressButton.checkoutExpressButton.parentNode - ) - return; - - this.children.expressButton = new PayLaterButtonProductComponent( - this.app - ).render(); - - return this; - } - } - - render() { - this.renderExpressCheckout(); - this.prestashopService.onUpdatedCart(() => { - return this.renderExpressCheckout(); - }); - - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout.component/index.js b/_dev/js/front/src/components/ps-checkout.component/index.js deleted file mode 100644 index 895cbffff..000000000 --- a/_dev/js/front/src/components/ps-checkout.component/index.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; - -import { PsCheckoutPs1_6Component } from './ps-checkout-ps1_6.component'; -import { PsCheckoutPs1_7Component } from './ps-checkout-ps1_7.component'; - -export class PsCheckoutComponent extends BaseComponent { - static Inject = { - prestashopService: 'PrestashopService' - }; - - created() { - this.instance = new { - [PS_VERSION_1_6]: PsCheckoutPs1_6Component, - [PS_VERSION_1_7]: PsCheckoutPs1_7Component - }[this.prestashopService.getVersion()](this.app, this.props); - } - - render() { - return this.instance.render(); - } -} diff --git a/_dev/js/front/src/components/ps-checkout.component/ps-checkout-ps1_6.component.js b/_dev/js/front/src/components/ps-checkout.component/ps-checkout-ps1_6.component.js deleted file mode 100644 index 7c2b097fa..000000000 --- a/_dev/js/front/src/components/ps-checkout.component/ps-checkout-ps1_6.component.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { NotificationComponent } from '../1_6/notification.component'; -import { PaymentOptionsComponent } from '../1_6/payment-options.component'; -import { LoaderComponent } from '../common/loader.component'; -import { PaymentOptionsLoaderComponent } from '../common/payment-options-loader.component'; -import { ConditionsCheckboxComponent } from '../1_7/conditions-checkbox.component'; - -export class PsCheckoutPs1_6Component extends BaseComponent { - static Inject = { - prestashopService: 'PrestashopService' - }; - - created() { - this.app.root = this; - } - - renderCheckout() { - this.children.paymentOptionsLoader = new PaymentOptionsLoaderComponent( - this.app - ).render(); - - this.children.conditionsCheckbox = new ConditionsCheckboxComponent( - this.app - ).render(); - - // TODO: Move this to HTMLElementService - const cgv = document.getElementById('cgv'); - if ((cgv && cgv.checked) || !cgv) { - this.children.notification = new NotificationComponent( - this.app - ).render(); - this.children.loader = new LoaderComponent(this.app).render(); - this.children.paymentOptions = new PaymentOptionsComponent(this.app, { - markPosition: 'before' - }).render(); - } - - this.children.paymentOptionsLoader.hide(); - } - - render() { - this.renderCheckout(); - this.prestashopService.onUpdatePaymentMethods(() => { - this.renderCheckout(); - }); - - return this; - } -} diff --git a/_dev/js/front/src/components/ps-checkout.component/ps-checkout-ps1_7.component.js b/_dev/js/front/src/components/ps-checkout.component/ps-checkout-ps1_7.component.js deleted file mode 100644 index 44ddf0261..000000000 --- a/_dev/js/front/src/components/ps-checkout.component/ps-checkout-ps1_7.component.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -import { NotificationComponent } from '../1_7/notification.component'; -import { PaymentOptionsComponent } from '../1_7/payment-options.component'; -import { ConditionsCheckboxComponent } from '../1_7/conditions-checkbox.component'; -import { LoaderComponent } from '../common/loader.component'; -import { PaymentOptionsLoaderComponent } from '../common/payment-options-loader.component'; - -export class PsCheckoutPs1_7Component extends BaseComponent { - created() { - this.app.root = this; - } - - render() { - this.children.paymentOptionsLoader = new PaymentOptionsLoaderComponent( - this.app - ).render(); - - this.children.loader = new LoaderComponent(this.app).render(); - this.children.conditionsCheckbox = new ConditionsCheckboxComponent( - this.app - ).render(); - - this.children.notification = new NotificationComponent(this.app).render(); - this.children.paymentOptions = new PaymentOptionsComponent( - this.app - ).render(); - - this.children.paymentOptionsLoader.hide(); - - return this; - } -} diff --git a/_dev/js/front/src/config/paypal-sdk.config.js b/_dev/js/front/src/config/paypal-sdk.config.js deleted file mode 100644 index 418e4fa18..000000000 --- a/_dev/js/front/src/config/paypal-sdk.config.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const PayPalSdkConfig = { - sdkConfig: { - dataNamespace: 'ps_checkoutPayPalSdkInstance', - dataOrderId: window.ps_checkoutPayPalOrderId, - ...window.ps_checkoutPayPalSdkConfig - }, - buttonCustomization: window.ps_checkoutPayPalButtonConfiguration, - paymentFieldsCustomization: window.ps_checkout.paymentFieldsCustomization, - expressCheckoutButtonCustomization: - window.ps_checkoutExpressCheckoutButtonCustomization, - hostedFieldsCustomization: - window.ps_checkoutHostedFieldsCustomizationConfiguration, - payLaterOfferMessageCustomization: - window.ps_checkoutPayLaterOfferMessageCustomization, - payLaterOfferBannerCustomization: - window.ps_checkoutPayLaterOfferBannerCustomization, - partnerAttributionId: window.ps_checkoutPartnerAttributionId -}; - diff --git a/_dev/js/front/src/config/ps-checkout.config.js b/_dev/js/front/src/config/ps-checkout.config.js deleted file mode 100644 index d8c7de27e..000000000 --- a/_dev/js/front/src/config/ps-checkout.config.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -function getTranslations() { - return { - ...Object.keys(window.ps_checkoutPayWithTranslations || {}).reduce( - (result, name) => { - result[`funding-source.name.${name}`] = - window.ps_checkoutPayWithTranslations[name]; - return result; - }, - {} - ), - ...window.ps_checkoutCheckoutTranslations - }; -} - -export const PsCheckoutConfig = { - createUrl: window.ps_checkoutCreateUrl, - checkCartUrl: window.ps_checkoutCheckUrl, - validateOrderUrl: window.ps_checkoutValidateUrl, - confirmationUrl: window.ps_checkoutConfirmUrl, - cancelUrl: window.ps_checkoutCancelUrl, - getTokenUrl: window.ps_checkoutGetTokenURL, // TODO: remove this? - checkoutCheckoutUrl: window.ps_checkoutCheckoutUrl, - expressCheckoutUrl: window.ps_checkoutExpressCheckoutUrl, - - hostedFieldsEnabled: window.ps_checkoutHostedFieldsEnabled, - hostedFieldsContingencies: window.ps_checkoutHostedFieldsContingencies, - - translations: getTranslations(), - - loaderImage: window.ps_checkoutLoaderImage, - customMark: { - card: window.ps_checkoutCardFundingSourceImg - }, - - autoRenderDisabled: window.ps_checkoutAutoRenderDisabled, - expressCheckout: { - active: window.ps_checkoutExpressCheckoutSelected, - enabled: { - cart: window.ps_checkoutExpressCheckoutCartEnabled, - order: window.ps_checkoutExpressCheckoutOrderEnabled, - product: window.ps_checkoutExpressCheckoutProductEnabled - } - }, - - payLater: { - message: { - order: window.ps_checkoutPayLaterOrderPageMessageEnabled, - product: window.ps_checkoutPayLaterProductPageMessageEnabled - }, - banner: { - home: window.ps_checkoutPayLaterHomePageBannerEnabled, - category: window.ps_checkoutPayLaterCategoryPageBannerEnabled, - order: window.ps_checkoutPayLaterOrderPageBannerEnabled, - product: window.ps_checkoutPayLaterProductPageBannerEnabled - }, - button: { - cart: window.ps_checkoutPayLaterCartPageButtonEnabled, - order: window.ps_checkoutPayLaterOrderPageButtonEnabled, - product: window.ps_checkoutPayLaterProductPageButtonEnabled - } - }, - - fundingSourcesSorted: window.ps_checkoutFundingSourcesSorted, - - orderId: window.ps_checkoutPayPalOrderId, - imgTitlePaymentMethodLogos: window.ps_checkoutPaymentMethodLogosTitleImg, - renderPaymentMethodLogos: window.ps_checkoutRenderPaymentMethodLogos, - cardSupportedBrands: window.ps_checkoutCardBrands, - cardLogoBrands: window.ps_checkoutCardLogos, - fundingSource: window.ps_checkoutFundingSource, -}; diff --git a/_dev/js/front/src/constants/html-selectors-ps1_6.constants.js b/_dev/js/front/src/constants/html-selectors-ps1_6.constants.js deleted file mode 100644 index c3de3a016..000000000 --- a/_dev/js/front/src/constants/html-selectors-ps1_6.constants.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -/* istanbul ignore file */ -// TODO: Remove this -export const HtmlSelectorsPs1_6Constants = { - ANY_PAYMENT_OPTION: '#ps_checkout-displayPayment .payment-option.row', - - CHECKOUT_PAYMENT_OPTIONS_CONTAINER: - '#ps_checkout-displayPayment .payment-options', - - NOTIFICATION_TARGET_ID: 'HOOK_PAYMENT', - - NOTIFICATION_CONTAINER_ID: 'ps_checkout-notification-container', - NOTIFICATION_PAYMENT_CANCELED_ID: 'ps_checkout-canceled', - NOTIFICATION_PAYMENT_ERROR_ID: 'ps_checkout-error', - NOTIFICATION_PAYMENT_ERROR_TEXT_ID: 'ps_checkout-error-text', - - PAYMENT_OPTION: '.row', - PAYMENT_OPTION_CONTAINER: '.payment-option-container', - - PAYMENT_OPTIONS_CONTAINER: 'HOOK_PAYMENT' -}; diff --git a/_dev/js/front/src/constants/html-selectors-ps1_7.constants.js b/_dev/js/front/src/constants/html-selectors-ps1_7.constants.js deleted file mode 100644 index 94a6cb35e..000000000 --- a/_dev/js/front/src/constants/html-selectors-ps1_7.constants.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -/* istanbul ignore file */ -// TODO: Remove this -export const HtmlSelectorsPs1_7Constants = { - ANY_PAYMENT_OPTION: '[data-module-name="ps_checkout"]', - - BUTTONS_CONTAINER_ID: 'ps_checkout-buttons-container', - - CHECKOUT_EXPRESS_CART_BUTTON_CONTAINER_ID: - 'js-ps_checkout-express-button-container', - CHECKOUT_EXPRESS_CHECKOUT_BUTTON_CONTAINER: - '#checkout-personal-information-step .content', - CHECKOUT_EXPRESS_PRODUCT_BUTTON_CONTAINER: '.product-add-to-cart', - - CONDITIONS_CHECKBOX_CONTAINER_ID: 'conditions-to-approve', - CONDITION_CHECKBOX: 'input[type="checkbox"]', - - HOSTED_FIELDS_FORM_ID: 'ps_checkout-hosted-fields-form', - - NOTIFICATION_CONDITIONS: '.accept-cgv', - NOTIFICATION_PAYMENT_CANCELED_ID: 'ps_checkout-canceled', - NOTIFICATION_PAYMENT_ERROR_ID: 'ps_checkout-error', - NOTIFICATION_PAYMENT_ERROR_TEXT_ID: 'ps_checkout-error-text', - - PAYMENT_OPTION: '[name="payment-option"]', - PAYMENT_OPTION_LABEL: id => `label[for="${id}"]`, - PAYMENT_OPTION_SELECT: '[name="select_payment_option"]', - PAYMENT_OPTION_CONTAINER_ID: id => `${id}-container`, - PAYMENT_OPTION_ADDITIONAL_INFORMATION_ID: id => - `${id}-additional-information`, - PAYMENT_OPTION_FORM_CONTAINER_ID: id => `pay-with-${id}-form`, - PAYMENT_OPTION_FORM_BUTTON: id => `#pay-with-${id}`, - - PAYMENT_OPTIONS_CONTAINER: '.payment-options' -}; diff --git a/_dev/js/front/src/core/app.js b/_dev/js/front/src/core/app.js deleted file mode 100644 index 8655e4a1c..000000000 --- a/_dev/js/front/src/core/app.js +++ /dev/null @@ -1,240 +0,0 @@ -import Bottle from 'bottlejs'; - -import { PsCheckoutApi } from '../api/ps-checkout.api'; -import { PayPalSdkConfig } from '../config/paypal-sdk.config'; -import { PsCheckoutConfig } from '../config/ps-checkout.config'; -import { PsCheckoutComponent } from '../components/ps-checkout.component'; -import { PsCheckoutExpressComponent } from '../components/ps-checkout-express.component'; -import { PsCheckoutExpressPayLaterComponent } from '../components/ps-checkout-pay-later.component'; -import { HTMLElementService } from '../service/html-element.service'; -import { PayPalService } from '../service/paypal.service'; -import { PrestashopService } from '../service/prestashop.service'; -import { TranslationService } from '../service/translation.service'; -import { QuerySelectorService } from '../service/query-selector.service'; -import { PaymentOptionsLoaderComponent } from '../components/common/payment-options-loader.component'; -import { PayLaterMessageComponent } from '../components/ps-checkout-pay-later-message.component'; -import { PayLaterBannerComponent } from '../components/ps-checkout-pay-later-banner.component'; -import { loadScript } from '@paypal/paypal-js'; -import { PaymentMethodLogosComponent } from '../components/common/payment-method-logos.component'; - -function initService(app) { - return (service) => () => new service(app); -} - -/** - * @param {ContainerAwareClass} app - */ -function initContainer(app) { - const bottle = app.bottle; - const serviceFactory = initService(app); - - bottle.value('PayPalSdkConfig', PayPalSdkConfig); - bottle.value('PsCheckoutConfig', PsCheckoutConfig); - - bottle.service('PrestashopService', PrestashopService); - - bottle.factory('HTMLElementService', serviceFactory(HTMLElementService)); - bottle.factory('QuerySelectorService', serviceFactory(QuerySelectorService)); - bottle.factory('PsCheckoutApi', serviceFactory(PsCheckoutApi)); - bottle.factory('TranslationService', serviceFactory(TranslationService)); - bottle.factory( - 'PaymentOptionsLoaderComponent', - serviceFactory(PaymentOptionsLoaderComponent) - ); - - bottle.factory('$', (container) => { - return (id) => container.TranslationService.getTranslationString(id); - }); -} - -export class App { - constructor() { - this.bottle = new Bottle(); - this.container = this.bottle.container; - initContainer(this); - - this.psCheckoutConfig = this.container.PsCheckoutConfig; - this.prestashopService = this.container.PrestashopService; - this.paymentOptionsLoader = this.container.PaymentOptionsLoaderComponent; - - this.$ = this.container.$; - - this.root = null; - } - - exposeAPI() { - window.ps_checkout.renderCheckout = () => { - return this.renderCheckout(); - }; - - window.ps_checkout.renderExpressCheckout = (props) => { - return this.renderExpressCheckout(props); - }; - - window.ps_checkout.renderPayLaterOfferMessage = (props) => { - return this.renderPayLaterOfferMessage(props); - }; - } - - async initPayPalService() { - return new Promise((resolve, reject) => { - loadScript(PayPalSdkConfig.sdkConfig) - .then((paypal) => { - this.bottle.value('PayPalSDK', paypal); - if (!this.container.PayPalService) { - this.bottle.factory( - 'PayPalService', - initService(this)(PayPalService) - ); - } - resolve(paypal); - }) - .catch((error) => { - console.error(this.$('error.paypal-sdk'), error); - reject(); - }); - }); - } - - async renderCheckout() { - await this.initPayPalService(); - new PsCheckoutComponent(this).render(); - } - - async renderExpressCheckout(props) { - await this.initPayPalService(); - new PsCheckoutExpressComponent(this, props).render(); - } - - async renderExpressCheckoutPayLater(props) { - await this.initPayPalService(); - new PsCheckoutExpressPayLaterComponent(this, props).render(); - } - - async renderPayLaterOfferMessage(props) { - await this.initPayPalService(); - new PayLaterMessageComponent(this, props).render(); - } - - async renderPayLaterOfferBanner(props) { - await this.initPayPalService(); - new PayLaterBannerComponent(this, props).render(); - } - - async renderPaymentMethodLogos(props) { - await this.initPayPalService(); - new PaymentMethodLogosComponent(this, props).render(); - } - - async render() { - this.exposeAPI(); - - if (!this.psCheckoutConfig.autoRenderDisabled) { - // Pay Later Message on Product Page - if ( - this.psCheckoutConfig.payLater.message.product && - this.prestashopService.isProductPage() - ) { - await this.renderPayLaterOfferMessage({ - placement: 'product' - }); - } - - // Pay Later Message on Cart & Order Page - if ( - this.psCheckoutConfig.payLater.message.order && - (this.prestashopService.isOrderPage() || - this.prestashopService.isCartPage()) - ) { - await this.renderPayLaterOfferMessage({ - placement: 'cart' - }); - } - - // Pay Later Banner on Homepage - if ( - this.psCheckoutConfig.payLater.banner.home && - this.prestashopService.isHomePage() - ) { - await this.renderPayLaterOfferBanner({ - placement: 'home' - }); - } - - // Pay Later Banner on Category Page - if ( - this.psCheckoutConfig.payLater.banner.category && - this.prestashopService.isCategoryPage() - ) { - await this.renderPayLaterOfferBanner({ - placement: 'category' - }); - } - - // Pay Later Message on Cart & Order Page - if ( - this.psCheckoutConfig.payLater.banner.order && - (this.prestashopService.isOrderPage() || - this.prestashopService.isCartPage()) - ) { - await this.renderPayLaterOfferBanner({ - placement: 'cart' - }); - } - - // Pay Later Message on Product Page - if ( - this.psCheckoutConfig.payLater.banner.product && - this.prestashopService.isProductPage() - ) { - await this.renderPayLaterOfferBanner({ - placement: 'product' - }); - } - - // Funding source logo - if ( - this.psCheckoutConfig.renderPaymentMethodLogos && - this.prestashopService.isProductPage() - ) { - await this.renderPaymentMethodLogos({ - placement: 'product' - }); - } - - if ( - this.psCheckoutConfig.renderPaymentMethodLogos && - this.prestashopService.isCartPage() - ) { - await this.renderPaymentMethodLogos({ - placement: 'cart' - }); - } - - if ( - this.prestashopService.isCartPage() || - this.prestashopService.isOrderPersonalInformationStepPage() || - this.prestashopService.isProductPage() - ) { - await this.renderExpressCheckout(); - await this.renderExpressCheckoutPayLater(); - - if (this.prestashopService.isOrderPersonalInformationStepPage()) { - await this.renderCheckout(); - } - - return this; - } - - if (this.prestashopService.isOrderPaymentStepPage()) { - await this.renderCheckout(); - return this; - } else if (this.prestashopService.isOrderPage()) { - this.paymentOptionsLoader.hide(); - return this; - } - } - - return this; - } -} diff --git a/_dev/js/front/src/core/bootstrap.js b/_dev/js/front/src/core/bootstrap.js deleted file mode 100644 index a6d7ae774..000000000 --- a/_dev/js/front/src/core/bootstrap.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -/** - * @param {Function} onBootstrap - */ -export function bootstrap(onBootstrap) { - if ('loading' === document.readyState) { - document.addEventListener('DOMContentLoaded', onBootstrap); - } else { - onBootstrap(); - } -} diff --git a/_dev/js/front/src/core/dependency-injection/base.class.js b/_dev/js/front/src/core/dependency-injection/base.class.js deleted file mode 100644 index e541ead42..000000000 --- a/_dev/js/front/src/core/dependency-injection/base.class.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { inject } from '../../utils/dependency-injection/inject'; - -export class BaseClass { - constructor(app) { - this.app = app; - inject(BaseClass)(this, this.constructor); - } -} diff --git a/_dev/js/front/src/core/dependency-injection/base.class.spec.js b/_dev/js/front/src/core/dependency-injection/base.class.spec.js deleted file mode 100644 index 236a467dd..000000000 --- a/_dev/js/front/src/core/dependency-injection/base.class.spec.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { DI_CONTAINER } from '../../../test/mocks/di-container.mock'; - -describe('src/core/dependency-injection/base-class.spec.js', () => { - let BaseClass; - - let inject; - let injector; - - beforeAll(() => { - injector = jest.fn(); - inject = jest.fn().mockReturnValue(injector); - - jest.doMock('../../utils/dependency-injection/inject', () => { - return { - __esModule: true, - inject - }; - }); - - return import('./base.class').then(({ BaseClass: BaseClassModule }) => { - BaseClass = BaseClassModule; - }); - }); - - afterAll(() => { - jest.resetModules(); - }); - - test('Inject is being called', () => { - new BaseClass(DI_CONTAINER); - expect(inject).toHaveBeenCalled(); - }); -}); diff --git a/_dev/js/front/src/core/dependency-injection/base.component.spec.js b/_dev/js/front/src/core/dependency-injection/base.component.spec.js deleted file mode 100644 index 5757e0481..000000000 --- a/_dev/js/front/src/core/dependency-injection/base.component.spec.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseComponent } from './base.component'; - -import { DI_CONTAINER } from '../../../test/mocks/di-container.mock'; - -describe.only('src/core/dependency-injection/base-component.spec.js', () => { - test('Simple Initialization', () => { - let createdCalled = false; - const cls = class extends BaseComponent { - created() { - createdCalled = true; - } - }; - - const instance = new cls(DI_CONTAINER); - expect(createdCalled).toBeTruthy(); - - expect(instance.data).toMatchObject({}); - expect(instance.props).toMatchObject({}); - expect(instance.children).toMatchObject({}); - }); - - test('Props Initialization', () => { - const props = { foo: 'Foo', bar: 'Bar' }; - const cls = class extends BaseComponent {}; - - const instance = new cls(DI_CONTAINER, props); - expect(instance.props).toMatchObject(props); - }); - - test('Base Render', () => { - const cls = class extends BaseComponent {}; - - const instance = new cls(DI_CONTAINER); - expect(instance.render()).toBe(instance); - }); -}); diff --git a/_dev/js/front/src/index.js b/_dev/js/front/src/index.js deleted file mode 100644 index db7336f7e..000000000 --- a/_dev/js/front/src/index.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import './utils/polyfills'; -import './utils/globals'; - -import { App } from './core/app'; -import { bootstrap } from './core/bootstrap'; - -bootstrap(async () => { - window.ps_checkout = window.ps_checkout || {}; - if (window.ps_checkout.app) { - return console.error( - 'There is an existing instance of `ps_checkout` on this context.' - ); - } - - window.ps_checkout.app = new App(); - window.ps_checkout.events.dispatchEvent( - new CustomEvent('init', { detail: { ps_checkout: window.ps_checkout } }) - ); - await window.ps_checkout.app.render(); - window.ps_checkout.events.dispatchEvent( - new CustomEvent('loaded', { detail: { ps_checkout: window.ps_checkout } }) - ); -}); diff --git a/_dev/js/front/src/service/html-element.service/html-element-ps1_6.service.js b/_dev/js/front/src/service/html-element.service/html-element-ps1_6.service.js deleted file mode 100644 index 45c8fe8b5..000000000 --- a/_dev/js/front/src/service/html-element.service/html-element-ps1_6.service.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -/* istanbul ignore file */ -// TODO: Remove this service (replace this with QuerySelectorService or local methods) -import { HtmlSelectorsPs1_6Constants } from '../../constants/html-selectors-ps1_6.constants'; - -export class HtmlElementPs1_6Service { - constructor() { - this.selectors = HtmlSelectorsPs1_6Constants; - } - - getBasePaymentOption() { - return document.querySelector(this.selectors.ANY_PAYMENT_OPTION); - } - - getCheckoutPaymentOptionsContainer() { - return document.querySelector( - this.selectors.CHECKOUT_PAYMENT_OPTIONS_CONTAINER - ); - } - - getNotificationPaymentContainer(cache = false) { - if (!this.notificationPaymentContainer || cache) { - this.notificationPaymentContainer = document.getElementById( - this.selectors.NOTIFICATION_CONTAINER_ID - ); - } - - return this.notificationPaymentContainer; - } - - getNotificationPaymentContainerTarget(cache = false) { - if (!this.notificationPaymentContainerTarget || cache) { - this.notificationPaymentContainerTarget = document.getElementById( - this.selectors.NOTIFICATION_TARGET_ID - ); - } - - return this.notificationPaymentContainerTarget; - } - - getNotificationPaymentCanceled(cache = false) { - if (!this.notificationPaymentCanceled || cache) { - this.notificationPaymentCanceled = document.getElementById( - this.selectors.NOTIFICATION_PAYMENT_CANCELED_ID - ); - } - - return this.notificationPaymentCanceled; - } - - getNotificationPaymentError(cache = false) { - if (!this.notificationPaymentError || cache) { - this.notificationPaymentError = document.getElementById( - this.selectors.NOTIFICATION_PAYMENT_ERROR_ID - ); - } - - return this.notificationPaymentError; - } - - getNotificationPaymentErrorText(cache = false) { - if (!this.notificationPaymentErrorText || cache) { - this.notificationPaymentErrorText = document.getElementById( - this.selectors.NOTIFICATION_PAYMENT_ERROR_TEXT_ID - ); - } - - return this.notificationPaymentErrorText; - } - - getPaymentOptionsContainer() { - return document.getElementById(this.selectors.PAYMENT_OPTIONS_CONTAINER); - } - - getPaymentOptions() { - return Array.prototype.slice.call( - this.getPaymentOptionsContainer().querySelectorAll( - this.selectors.PAYMENT_OPTION - ) - ); - } - - getPaymentOptionContainer(container) { - return container.querySelector(this.selectors.PAYMENT_OPTION_CONTAINER); - } -} diff --git a/_dev/js/front/src/service/html-element.service/html-element-ps1_7.service.js b/_dev/js/front/src/service/html-element.service/html-element-ps1_7.service.js deleted file mode 100644 index 0eb476793..000000000 --- a/_dev/js/front/src/service/html-element.service/html-element-ps1_7.service.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -/* istanbul ignore file */ -// TODO: Remove this service (replace this with QuerySelectorService or local methods) -import { HtmlSelectorsPs1_7Constants } from '../../constants/html-selectors-ps1_7.constants'; - -export class HtmlElementPs1_7Service { - constructor() { - this.selectors = HtmlSelectorsPs1_7Constants; - } - - getBasePaymentOption(cache = false) { - if (!this.basePaymentOption || cache) { - this.basePaymentOption = document.querySelector( - this.selectors.ANY_PAYMENT_OPTION - ); - } - - return this.basePaymentOption; - } - - getButtonContainer(cache = false) { - if (!this.buttonContainer || cache) { - this.buttonContainer = document.getElementById( - this.selectors.BUTTONS_CONTAINER_ID - ); - } - - return this.buttonContainer; - } - - getCheckoutExpressCartButtonContainer() { - return document.getElementById( - this.selectors.CHECKOUT_EXPRESS_CART_BUTTON_CONTAINER_ID - ); - } - - getCheckoutExpressCheckoutButtonContainer() { - return document.querySelector( - this.selectors.CHECKOUT_EXPRESS_CHECKOUT_BUTTON_CONTAINER - ); - } - - getCheckoutExpressProductButtonContainer() { - return document.querySelector( - this.selectors.CHECKOUT_EXPRESS_PRODUCT_BUTTON_CONTAINER - ); - } - - getConditionsCheckboxContainer(cache = false) { - if (!this.conditionsCheckboxContainer || cache) { - this.conditionsCheckboxContainer = document.getElementById( - this.selectors.CONDITIONS_CHECKBOX_CONTAINER_ID - ); - } - - return this.conditionsCheckboxContainer; - } - - getConditionsCheckboxes(container) { - return container - ? Array.prototype.slice.call( - container.querySelectorAll(this.selectors.CONDITION_CHECKBOX) - ) - : null; - } - - getHostedFieldsForm(cache = false) { - if (!this.hostedFieldsForm || cache) { - this.hostedFieldsForm = document.getElementById( - this.selectors.HOSTED_FIELDS_FORM_ID - ); - } - - return this.hostedFieldsForm; - } - - getNotificationConditions(cache = false) { - if (!this.notificationConditions || cache) { - this.notificationConditions = document.querySelector( - this.selectors.NOTIFICATION_CONDITIONS - ); - } - - return this.notificationConditions; - } - - getNotificationPaymentCanceled(cache = false) { - if (!this.notificationPaymentCanceled || cache) { - this.notificationPaymentCanceled = document.getElementById( - this.selectors.NOTIFICATION_PAYMENT_CANCELED_ID - ); - } - - return this.notificationPaymentCanceled; - } - - getNotificationPaymentError(cache = false) { - if (!this.notificationPaymentError || cache) { - this.notificationPaymentError = document.getElementById( - this.selectors.NOTIFICATION_PAYMENT_ERROR_ID - ); - } - - return this.notificationPaymentError; - } - - getNotificationPaymentErrorText(cache = false) { - if (!this.notificationPaymentErrorText || cache) { - this.notificationPaymentErrorText = document.getElementById( - this.selectors.NOTIFICATION_PAYMENT_ERROR_TEXT_ID - ); - } - - return this.notificationPaymentErrorText; - } - - getPaymentOption(container) { - return container.querySelector(this.selectors.PAYMENT_OPTION); - } - - getPaymentOptionLabel(container, text) { - const items = Array.prototype.slice.call(container.querySelectorAll('*')); - return items.find(item => item.innerText === text); - } - - getPaymentOptionLabelLegacy(container, id) { - return container.querySelector(this.selectors.PAYMENT_OPTION_LABEL(id)); - } - - getPaymentOptionSelect(container) { - return container.querySelector(this.selectors.PAYMENT_OPTION_SELECT); - } - - getPaymentOptionContainer(id) { - return document.getElementById( - this.selectors.PAYMENT_OPTION_CONTAINER_ID(id) - ); - } - - getPaymentOptionAdditionalInformation(id) { - return document.getElementById( - this.selectors.PAYMENT_OPTION_ADDITIONAL_INFORMATION_ID(id) - ); - } - - getPaymentOptionFormContainer(id) { - return document.getElementById( - this.selectors.PAYMENT_OPTION_FORM_CONTAINER_ID(id) - ); - } - - getPaymentOptionFormButton(container, id) { - return container.querySelector( - this.selectors.PAYMENT_OPTION_FORM_BUTTON(id) - ); - } - - getPaymentOptionsContainer(cache = false) { - if (!this.paymentOptionsContainer || cache) { - this.paymentOptionsContainer = document.querySelector( - this.selectors.PAYMENT_OPTIONS_CONTAINER - ); - } - - return this.paymentOptionsContainer; - } - - getPaymentOptions(cache = false) { - if (!this.paymentOptions || cache) { - this.paymentOptions = this.getPaymentOptionsContainer( - cache - ).querySelectorAll(this.selectors.PAYMENT_OPTION); - - this.paymentOptions = Array.prototype.slice.call(this.paymentOptions); - } - - return this.paymentOptions; - } -} diff --git a/_dev/js/front/src/service/html-element.service/index.js b/_dev/js/front/src/service/html-element.service/index.js deleted file mode 100644 index 21a4b5de1..000000000 --- a/_dev/js/front/src/service/html-element.service/index.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; -import { BaseClass } from '../../core/dependency-injection/base.class'; - -import { HtmlElementPs1_6Service } from './html-element-ps1_6.service'; -import { HtmlElementPs1_7Service } from './html-element-ps1_7.service'; - -export class HTMLElementService extends BaseClass { - static Inject = { - prestashopService: 'PrestashopService' - }; - - constructor(app) { - super(app); - - this.instance = new { - [PS_VERSION_1_6]: HtmlElementPs1_6Service, - [PS_VERSION_1_7]: HtmlElementPs1_7Service - }[this.prestashopService.getVersion()](app); - } - - getBasePaymentOption() { - return this.instance.getBasePaymentOption(); - } - - getButtonContainer() { - return this.instance.getButtonContainer(); - } - - getBasePaymentConfirmation() { - return this.instance.getBasePaymentConfirmation(); - } - - getCheckoutExpressCartButtonContainer() { - return this.instance.getCheckoutExpressCartButtonContainer(); - } - - getCheckoutExpressCheckoutButtonContainer() { - return this.instance.getCheckoutExpressCheckoutButtonContainer(); - } - - getCheckoutExpressProductButtonContainer() { - return this.instance.getCheckoutExpressProductButtonContainer(); - } - - getConditionsCheckboxContainer() { - return this.instance.getConditionsCheckboxContainer(); - } - - getConditionsCheckboxes(container) { - return this.instance.getConditionsCheckboxes(container); - } - - getHostedFieldsForm() { - return this.instance.getHostedFieldsForm(); - } - - getNotificationConditions() { - return this.instance.getNotificationConditions(); - } - - getNotificationPaymentCanceled() { - return this.instance.getNotificationPaymentCanceled(); - } - - getNotificationPaymentContainer() { - return this.instance.getNotificationPaymentContainer(); - } - - getNotificationPaymentContainerTarget() { - return this.instance.getNotificationPaymentContainerTarget(); - } - - getNotificationPaymentError() { - return this.instance.getNotificationPaymentError(); - } - - getNotificationPaymentErrorText() { - return this.instance.getNotificationPaymentErrorText(); - } - - getPaymentOption(container) { - return this.instance.getPaymentOption(container); - } - - getPaymentOptionLabel(container, text) { - return this.instance.getPaymentOptionLabel(container, text); - } - - getPaymentOptionLabelLegacy(container, id) { - return this.instance.getPaymentOptionLabelLegacy(container, id); - } - - getPaymentOptionSelect(container) { - return this.instance.getPaymentOptionSelect(container); - } - - getPaymentOptionContainer(id) { - return this.instance.getPaymentOptionContainer(id); - } - - getPaymentOptionAdditionalInformation(id) { - return this.instance.getPaymentOptionAdditionalInformation(id); - } - - getPaymentOptionFormContainer(id) { - return this.instance.getPaymentOptionFormContainer(id); - } - - getPaymentOptionFormButton(container, id) { - return this.instance.getPaymentOptionFormButton(container, id); - } - - getPaymentOptionsContainer() { - return this.instance.getPaymentOptionsContainer(); - } - - getPaymentOptions() { - return this.instance.getPaymentOptions(); - } -} diff --git a/_dev/js/front/src/service/paypal.service.js b/_dev/js/front/src/service/paypal.service.js deleted file mode 100644 index 1133d892c..000000000 --- a/_dev/js/front/src/service/paypal.service.js +++ /dev/null @@ -1,319 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * @typedef PaypalButtonEvents - * @type {*} - * - * @property {function} onInit - * @property {function} onClick - * @property {function} onError - * @property {function} onApprove - * @property {function} onCancel - * @property {function} createOrder - */ - -/** - * @typedef PaypalPayLaterOfferStyle - * @type {*} - * - * @property {string} layout - * @property {string} color - * @property {string} ratio - * @property {object} logo - * @property {string} logo.type - * @property {string} logo.position - * @property {object} text - * @property {string} text.color - * @property {string} text.size - * @property {string} text.align - */ - -/** - * @typedef PayPayCardFieldsOptions - * @type {*} - * - * @property {function} createOrder - * @property {function} onApprove - * @property {function} onError - * @property {function} inputEvents - * @property {object} style - */ - -/** - * @typedef PaypalPayLaterOfferEvents - * @type {*} - * - * @property {function} onRender - * @property {function} onClick - * @property {function} onApply - */ - -/** - * @typedef PaypalMarks - * @type {*} - * - * @property {function} isEligible - * @property {function} render - */ - -import { BaseClass } from '../core/dependency-injection/base.class'; - -export class PayPalService extends BaseClass { - static Inject = { - configPayPal: 'PayPalSdkConfig', - configPrestaShop: 'PsCheckoutConfig', - sdk: 'PayPalSDK', - $: '$' - }; - - getOrderId() { - return this.configPrestaShop.orderId; - } - - getFundingSource() { - return this.configPrestaShop.fundingSource; - } - - /** - * @param {string} fundingSource - * @param {PaypalButtonEvents} events - */ - getButtonExpress(fundingSource, events) { - return this.sdk.Buttons({ - fundingSource: fundingSource, - style: this.getButtonCustomizationStyle(fundingSource), - commit: false, - ...events - }); - } - - /** - * @param {string} fundingSource - * @param {PaypalButtonEvents} events - */ - getButtonPayment(fundingSource, events) { - return this.sdk.Buttons({ - fundingSource: fundingSource, - style: this.getButtonCustomizationStyle(fundingSource), - ...events - }); - } - - /** - * @param {string} fundingSource - */ - getButtonCustomizationStyle(fundingSource) { - const style = { - ...{ label: 'pay', color: 'gold', shape: 'pill' }, - ...(this.configPayPal.buttonCustomization || {}), - ...(window.ps_checkout.PayPalButtonCustomization || {}) - }; - - if (fundingSource === 'paypal') { - return style; - } else if (fundingSource === 'paylater') { - return { shape: style.shape, color: style.color }; - } - - return {}; - } - - /** - * @param {*} fieldSelectors - * @param {string} fieldSelectors.name - * @param {string} fieldSelectors.number - * @param {string} fieldSelectors.cvv - * @param {string} fieldSelectors.expiry - * - * @param {PayPayCardFieldsOptions} options - * - * @returns {PayPalSdk.CardFields} - */ - async getCardFields(fieldSelectors, options) { - const cardFields = this.sdk.CardFields(options); - - const nameField = cardFields.NameField({ - placeholder: this.$('paypal.hosted-fields.placeholder.card-name') - }); - const numberField = cardFields.NumberField({ - placeholder: this.$('paypal.hosted-fields.placeholder.card-number') - }); - const expiryField = cardFields.ExpiryField({ - placeholder: this.$('paypal.hosted-fields.placeholder.expiration-date') - }); - const cvvField = cardFields.CVVField({ - placeholder: this.$('paypal.hosted-fields.placeholder.cvv') - }); - - try { - await numberField.render(fieldSelectors.number); - await expiryField.render(fieldSelectors.expiry); - await cvvField.render(fieldSelectors.cvv); - await nameField.render(fieldSelectors.name); - } catch (e) { - return console.error('Failed to render CardFields', e); - } - - const nameLabel = document.querySelector( - `label[for="${fieldSelectors.name.id}"]` - ); - const numberLabel = document.querySelector( - `label[for="${fieldSelectors.number.id}"]` - ); - const cvvLabel = document.querySelector( - `label[for="${fieldSelectors.cvv.id}"]` - ); - const expirationDateLabel = document.querySelector( - `label[for="${fieldSelectors.expiry.id}"]` - ); - - nameLabel.innerHTML = this.$('paypal.hosted-fields.label.card-name'); - numberLabel.innerHTML = this.$('paypal.hosted-fields.label.card-number'); - cvvLabel.innerHTML = this.$('paypal.hosted-fields.label.cvv'); - expirationDateLabel.innerHTML = this.$( - 'paypal.hosted-fields.label.expiration-date' - ); - - return cardFields; - } - - getEligibleFundingSources(cache = false) { - if (!this.eligibleFundingSources || cache) { - const paypalFundingSources = this.sdk.getFundingSources(); - this.eligibleFundingSources = ( - this.configPrestaShop.fundingSourcesSorted || paypalFundingSources - ) - .filter((fundingSource) => paypalFundingSources.includes(fundingSource)) - .map((fundingSource) => ({ - name: fundingSource, - mark: this.sdk.Marks({ fundingSource }) - })) - .filter((fundingSource) => { - if ( - fundingSource.name === 'card' && - this.isCardFieldsEnabled() && - !this.isCardFieldsEligible() - ) { - console.warn( - 'Card Fields (CCF) eligibility is declined. Switching to PayPal branded card fields (SCF)' - ); - } - console.log(fundingSource.name, fundingSource.mark.isEligible()); - - return fundingSource.mark.isEligible(); - }); - } - - return this.eligibleFundingSources; - } - - isFundingEligible(fundingSource) { - return this.getEligibleFundingSources().contains(fundingSource); - } - - isCardFieldsEnabled() { - return this.sdk.CardFields && this.configPrestaShop.hostedFieldsEnabled; - } - - isCardFieldsEligible() { - return this.sdk.CardFields && this.sdk.CardFields().isEligible(); - } - - /** - * @param {string} placement - * @param {string} amount - * @param {PaypalPayLaterOfferEvents} events - */ - getPayLaterOfferMessage(placement, amount, events) { - const style = { - ...{ - layout: 'text', - logo: { - type: 'inline' - } - }, - ...(this.configPayPal.payLaterOfferMessageCustomization || {}), - ...(window.ps_checkout.payLaterOfferMessageCustomization || {}) - }; - return ( - this.sdk.Messages && - this.sdk.Messages({ - placement: placement, - amount: amount, - style: style, - ...events - }) - ); - } - - /** - * @param {string} placement - * @param {string} amount - * @param {PaypalPayLaterOfferEvents} events - */ - getPayLaterOfferBanner(placement, amount, events) { - const style = { - ...{ - layout: 'flex', - ratio: '20x1' - }, - ...(this.configPayPal.payLaterOfferBannerCustomization || {}), - ...(window.ps_checkout.payLaterOfferBannerCustomization || {}) - }; - return ( - this.sdk.Messages && - this.sdk.Messages({ - placement: placement, - amount: amount, - style: style, - ...events - }) - ); - } - - /** - * @param {string} fundingSource - * @param {object} fields - */ - getPaymentFields(fundingSource, fields = {}) { - return this.sdk.PaymentFields && this.sdk.PaymentFields({ - fundingSource: fundingSource, - style: this.getPaymentFieldsCustomizationStyle(fundingSource), - fields: fields - }); - } - - /** - * @returns {object} - */ - getPaymentFieldsCustomizationStyle() { - return { - ...(this.configPayPal.paymentFieldsCustomization || {}), - ...(window.ps_checkout.paymentFieldsCustomization || {}) - }; - } - - /** - * @returns {PaypalMarks} - */ - getMarks() { - return this.sdk.Marks && this.sdk.Marks(); - } -} diff --git a/_dev/js/front/src/service/prestashop.service.spec.js b/_dev/js/front/src/service/prestashop.service.spec.js deleted file mode 100644 index d78d828fc..000000000 --- a/_dev/js/front/src/service/prestashop.service.spec.js +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { PrestashopService } from './prestashop.service'; -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../constants/ps-version.constants'; - -import * as PrestashopSite1_7 from '../../test/mocks/html-templates/prestashop-site-1_7'; -import PRODUCT_DATASET from '../../test/mocks/data/product-dataset.json'; - -// TODO: Refactor this class to use DIContainer -function buildDIContainerMock() { - return {}; -} - -describe('src/service/prestashop.service.spec.js', () => { - describe('PS_VERSION_1_6', () => { - beforeEach(() => (window.updatePaymentMethods = jest.fn())); - - afterEach(() => delete window.updatePaymentMethods); - - test('::getVersion() returns PS_VERSION_1_6', () => { - const psService = new PrestashopService(); - expect(psService.getVersion()).toBe(PS_VERSION_1_6); - }); - - // This method only works on 1.6 so listener will never be called - test("::onUpdatedCart() don't get called", () => { - const listener = jest.fn(); - const psService = new PrestashopService(); - - psService.onUpdatedCart(listener); - expect(listener).not.toHaveBeenCalled(); - }); - - test("::onUpdatePaymentMethods() don't get called if event is undefined", () => { - const listener = jest.fn(); - - delete window.updatePaymentMethods; - - const psService = new PrestashopService(); - - psService.onUpdatePaymentMethods(listener); - expect(listener).not.toHaveBeenCalled(); - }); - - test('::onUpdatePaymentMethods()', () => { - const listener = jest.fn(); - const psService = new PrestashopService(); - - psService.onUpdatePaymentMethods(listener); - window['updatePaymentMethods'](); - - expect(listener).toHaveBeenCalled(); - }); - }); - - describe('PS_VERSION_1_7', () => { - beforeEach( - () => - (window.prestashop = { - on: jest.fn() - }) - ); - - afterEach(() => delete window.prestashop); - - test('::getProductDetails()', () => { - PrestashopSite1_7.mockProductPage(); - - const psService = new PrestashopService(); - expect(psService.getProductDetails()).toEqual(PRODUCT_DATASET); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isCartPage()', () => { - PrestashopSite1_7.mockCartPage(); - - const psService = new PrestashopService(); - expect(psService.isCartPage()).toBeTruthy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isOrderPaymentStepPage() on wrong page', () => { - PrestashopSite1_7.mockProductPage(); - - const psService = new PrestashopService(); - expect(psService.isOrderPaymentStepPage()).toBeFalsy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isOrderPaymentStepPage() on wrong step', () => { - PrestashopSite1_7.mockCheckoutPage(); - - const psService = new PrestashopService(); - expect(psService.isOrderPaymentStepPage()).toBeFalsy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isOrderPaymentStepPage()', () => { - PrestashopSite1_7.mockCheckoutPaymentStepPage(); - - const psService = new PrestashopService(); - expect(psService.isOrderPaymentStepPage()).toBeTruthy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isOrderPersonalInformationStepPage() on wrong page', () => { - PrestashopSite1_7.mockProductPage(); - - const psService = new PrestashopService(); - expect(psService.isOrderPersonalInformationStepPage()).toBeFalsy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isOrderPersonalInformationStepPage() on wrong step', () => { - PrestashopSite1_7.mockCheckoutPage(); - - const psService = new PrestashopService(); - expect(psService.isOrderPersonalInformationStepPage()).toBeFalsy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isOrderPersonalInformationStepPage()', () => { - PrestashopSite1_7.mockCheckoutPersonalInformationStepPage(); - - const psService = new PrestashopService(); - expect(psService.isOrderPersonalInformationStepPage()).toBeTruthy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::isProductPage()', () => { - PrestashopSite1_7.mockProductPage(); - - const psService = new PrestashopService(); - expect(psService.isProductPage()).toBeTruthy(); - - PrestashopSite1_7.cleanSite(); - }); - - test('::getVersion() returns PS_VERSION_1_7', () => { - const psService = new PrestashopService(); - expect(psService.getVersion()).toBe(PS_VERSION_1_7); - }); - - test('::onUpdatedCart() errors if prestashop object is wrong', () => { - const listener = jest.fn(); - - const source = console.error; - console.error = jest.fn(); - - delete window.prestashop.on; - - const psService = new PrestashopService(); - - psService.onUpdatedCart(listener); - expect(console.error).toHaveBeenCalledTimes(1); - expect(listener).not.toHaveBeenCalled(); - - delete window.prestashop; - - psService.onUpdatedCart(listener); - expect(console.error).toHaveBeenCalledTimes(2); - expect(listener).not.toHaveBeenCalled(); - - console.error = source; - }); - - test('::onUpdatedCart()', () => { - const listener = jest.fn(); - const psService = new PrestashopService(); - - psService.onUpdatedCart(listener); - expect(window.prestashop.on).toHaveBeenCalledWith( - 'updatedCart', - listener - ); - }); - - // This method only works on 1.6 so listener will never be called - test("::onUpdatePaymentMethods() don't get called", () => { - const listener = jest.fn(); - const psService = new PrestashopService(); - - psService.onUpdatePaymentMethods(listener); - expect(listener).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/_dev/js/front/src/service/prestashop.service/index.js b/_dev/js/front/src/service/prestashop.service/index.js deleted file mode 100644 index 34484be21..000000000 --- a/_dev/js/front/src/service/prestashop.service/index.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; - -import { PrestashopPs1_6Service } from './prestashop-ps1_6.service'; -import { PrestashopPs1_7Service } from './prestashop-ps1_7.service'; - -export class PrestashopService { - constructor() { - this.instance = { - [PS_VERSION_1_6]: PrestashopPs1_6Service, - [PS_VERSION_1_7]: PrestashopPs1_7Service - }[this.getVersion()]; - } - - getProductDetails() { - return this.instance.getProductDetails(); - } - - isHomePage() { - return !!this.instance.isHomePage(); - } - - isCategoryPage() { - return !!this.instance.isCategoryPage(); - } - - isCartPage() { - return !!this.instance.isCartPage(); - } - - isOrderPersonalInformationStepPage() { - return !!this.instance.isOrderPersonalInformationStepPage(); - } - - isOrderPaymentStepPage() { - return !!this.instance.isOrderPaymentStepPage(); - } - - isOrderPage() { - return this.instance.isOrderPage(); - } - - isNativeOnePageCheckoutPage() { - return this.instance.isNativeOnePageCheckoutPage(); - } - - isIframeProductPage() { - return !!this.instance.isIframeProductPage(); - } - - isProductPage() { - return !!this.instance.isProductPage(); - } - - isLogged() { - return this.instance.isLogged(); - } - - isGuestCheckoutEnabled() { - return this.instance.isGuestCheckoutEnabled(); - } - - hasProductInCart() { - return this.instance.hasProductInCart(); - } - - getCartAmount() { - return this.instance.getCartAmount(); - } - - getProductPrice() { - return this.instance.getProductPrice(); - } - - isAddToCartButtonDisabled() { - return this.instance.isAddToCartButtonDisabled(); - } - - getVersion() { - if (!window.prestashop) { - return PS_VERSION_1_6; - } - - return PS_VERSION_1_7; - } - - onUpdatedCart(listener) { - this.instance.onUpdatedCart(listener); - } - - onUpdatedProduct(listener) { - this.instance.onUpdatedProduct(listener); - } - - onUpdatePaymentMethods(listener) { - this.instance.onUpdatePaymentMethods(listener); - } - - onUpdatedShoppingCartExtra(listener) { - this.instance.onUpdatedShoppingCartExtra(listener); - } -} diff --git a/_dev/js/front/src/service/prestashop.service/prestashop-ps1_6.service.js b/_dev/js/front/src/service/prestashop.service/prestashop-ps1_6.service.js deleted file mode 100644 index 2b8181eef..000000000 --- a/_dev/js/front/src/service/prestashop.service/prestashop-ps1_6.service.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export class PrestashopPs1_6Service { - static getProductDetails() { - const id_product = document.getElementById('product_page_product_id'); - const id_product_attribute = document.getElementById('idCombination'); - const id_customization = window?.customizationId; - const quantity_wanted = document.getElementById('quantity_wanted'); - - return { - id_product: id_product?.value || '', - id_product_attribute: id_product_attribute?.value || '', - id_customization: id_customization || '', - quantity_wanted: quantity_wanted?.value || '' - }; - } - - static isHomePage() { - return document.body.id === 'index'; - } - - static isCategoryPage() { - return document.body.id === 'category'; - } - - static isCartPage() { - if (document.body.id === 'order') { - return document.querySelector('.step_current.first'); - } - - return false; - } - - static isOrderPaymentStepPage() { - if (document.body.id === 'order') { - return document.getElementById('ps_checkout-displayPayment'); - } - - return document.body.id === 'order-opc'; - } - - static isOrderPage() { - return document.body.id === 'order' || document.body.id === 'order-opc'; - } - - static isNativeOnePageCheckoutPage() { - return document.body.id === 'order-opc'; - } - - static isOrderPersonalInformationStepPage() { - return ( - document.body.id === 'authentication' || - (document.body.id === 'order-opc' && !window.isLogged && !window.isGuest) - ); - } - - static isIframeProductPage() { - return new URL(window.location).searchParams.get('content_only') === '1'; - } - - static isProductPage() { - return document.body.id === 'product'; - } - - static isLogged() { - return !!window.isLogged || !!window.isGuest; - } - - static isGuestCheckoutEnabled() { - return !!window.guestCheckoutEnabled; - } - - static hasProductInCart() { - return !!window.ps_checkoutCartProductCount; - } - - static getCartAmount() { - let cartAmountContainer = document.querySelector('.cart_block_total'); - - if (!cartAmountContainer) { - return ''; - } - - return cartAmountContainer.textContent.replace(',', '.').replace(/[^.\d]/g, ''); - } - - static getProductPrice() { - if (!window.productPrice) { - return ''; - } - - return Number.parseFloat(window.productPrice).toFixed(2) || ''; - } - - static isAddToCartButtonDisabled() { - let productIsAvailableForOrder = window.productAvailableForOrder || false; - let productAllowBuyWhenOutOfStock = window.allowBuyWhenOutOfStock || false; - let productQuantityAvailable = window.quantityAvailable || 0; - let productMinimalQuantity = window.minimalQuantity || 0; - let productQuantityWantedElement = document.querySelector('#quantity_wanted'); - let productQuantityWanted = 0; - - if (productQuantityWantedElement) { - productQuantityWanted = parseInt(productQuantityWantedElement.value) || 0; - } - - return !productIsAvailableForOrder - || (!productAllowBuyWhenOutOfStock && (productQuantityAvailable <= 0 || productQuantityWanted > productQuantityAvailable)) - || productQuantityWanted < productMinimalQuantity; - } - - static onUpdatedCart() {} - - static onUpdatedProduct() {} - - static onUpdatePaymentMethods(listener) { - if (window['updatePaymentMethods']) { - const updatePaymentMethods = window['updatePaymentMethods']; - window['updatePaymentMethods'] = (...args) => { - updatePaymentMethods(...args); - listener(...args); - }; - } - } - - static onUpdatedShoppingCartExtra(listener) { - if (window['updateHookShoppingCartExtra']) { - const updateHookShoppingCartExtra = window['updateHookShoppingCartExtra']; - window['updateHookShoppingCartExtra'] = (...args) => { - updateHookShoppingCartExtra(...args); - listener(...args); - }; - } - } -} diff --git a/_dev/js/front/src/service/prestashop.service/prestashop-ps1_7.service.js b/_dev/js/front/src/service/prestashop.service/prestashop-ps1_7.service.js deleted file mode 100644 index 47ee04ec7..000000000 --- a/_dev/js/front/src/service/prestashop.service/prestashop-ps1_7.service.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export class PrestashopPs1_7Service { - static getProductDetails() { - const productDetails = document.getElementById('product-details'); - - if (!productDetails || !productDetails.dataset || !productDetails.dataset.product) { - throw new Error('Unable to retrieve product details from DOM: document.getElementById("product-details").dataset.product'); - } - - return JSON.parse( - productDetails.dataset.product - ); - } - - static isHomePage() { - return document.body.id === 'index'; - } - - static isCategoryPage() { - return document.body.id === 'category'; - } - - static isCartPage() { - return document.body.id === 'cart'; - } - - static isOrderPaymentStepPage() { - if (document.body.id !== 'checkout') return false; - return document.querySelector('[data-module-name^="ps_checkout"]'); - } - - static isOrderPage() { - return document.body.id === 'checkout'; - } - - static isNativeOnePageCheckoutPage() { - return false; // This doesn't exist in PrestaShop 1.7 - } - - static isOrderPersonalInformationStepPage() { - if (document.body.id !== 'checkout') return false; - const step = document.querySelector('#checkout-personal-information-step'); - - return step && (step.classList.contains('-current') || step.classList.contains('step--current')); - } - - static isIframeProductPage() { - return false; - } - - static isProductPage() { - return document.body.id === 'product'; - } - - static isLogged() { - return window.prestashop?.customer?.is_logged || false; - } - - static isGuestCheckoutEnabled() { - return !!document.querySelector('#checkout-guest-form'); - } - - static hasProductInCart() { - return !!window.ps_checkoutCartProductCount; - } - - static displayPricesTaxIncluded() { - return window.prestashop?.configuration?.display_prices_tax_incl || false; - } - - static displayTaxLabel() { - return window.prestashop?.configuration?.display_taxes_label || false; - } - - static getCartAmount() { - let cartAmount = window.prestashop?.cart?.totals?.total?.amount || ''; - - if (window.prestashop?.cart?.totals?.total_excluding_tax?.amount && !this.displayPricesTaxIncluded() && !this.displayTaxLabel()) { - cartAmount = window.prestashop?.cart?.totals?.total_excluding_tax?.amount; - } - - if (window.prestashop?.cart?.totals?.total_including_tax?.amount && (this.displayPricesTaxIncluded() || this.displayTaxLabel())) { - cartAmount = window.prestashop?.cart?.totals?.total_including_tax?.amount; - } - - return cartAmount; - } - - static getProductPrice() { - let productPrice = document.querySelector('.current-price .current-price-value'); - - if (!productPrice) { - productPrice = document.querySelector('.current-price [itemprop="price"]'); - } - - if (productPrice) { - return productPrice.getAttribute('content'); - } - - return ''; - } - - static isAddToCartButtonDisabled() { - let addToCartElement = document.querySelector('.page-product:not(.modal-open) .row .product-add-to-cart, .page-product:not(.modal-open) .product-container .product-add-to-cart, .page-product:not(.modal-open) .row .js-product-add-to-cart, .page-product:not(.modal-open) .product-container .js-product-add-to-cart'); - let addToCartButtonElement = addToCartElement.querySelector('button.add-to-cart'); - - return addToCartButtonElement ? addToCartButtonElement.disabled : true; - } - - static onUpdatedCart(listener) { - if (window['prestashop'] && window['prestashop'].on) { - window['prestashop'].on('updatedCart', listener); - window['prestashop'].on('updatedAddressForm', listener); - window['prestashop'].on('updatedDeliveryForm', listener); - } else { - console.error(''); - } - } - - static onUpdatedProduct(listener) { - if (window['prestashop'] && window['prestashop'].on) { - window['prestashop'].on('updatedProduct', listener); - } else { - console.error(''); - } - } - - static onUpdatePaymentMethods() {} - - static onUpdatedShoppingCartExtra() {} -} diff --git a/_dev/js/front/src/service/query-selector.service.spec.js b/_dev/js/front/src/service/query-selector.service.spec.js deleted file mode 100644 index 21280c9cb..000000000 --- a/_dev/js/front/src/service/query-selector.service.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { QuerySelectorService } from './query-selector.service'; -import { PrestashopService } from './prestashop.service'; - -function buildDIContainerMock() { - return { - container: { - PrestashopService: new PrestashopService() - } - }; -} - -describe('src/service/query-selector.service.spec.js', () => { - const testAllQSSMethods = (qss) => { - expect(() => qss.getBasePaymentConfirmation()).not.toThrow(); - expect(() => qss.getConditionsCheckboxes()).not.toThrow(); - expect(() => qss.getLoaderParent()).not.toThrow(); - expect(() => qss.getNotificationConditions()).not.toThrow(); - expect(() => qss.getNotificationPaymentCanceled()).not.toThrow(); - expect(() => qss.getNotificationPaymentError()).not.toThrow(); - expect(() => qss.getNotificationPaymentErrorText()).not.toThrow(); - expect(() => qss.getPaymentOptions()).not.toThrow(); - expect(() => qss.getPaymentOptionsLoader()).not.toThrow(); - expect(() => qss.getPaymentOptionRadios()).not.toThrow(); - }; - - test('All methods are defined for PS1.6', () => { - const qss = new QuerySelectorService(buildDIContainerMock()); - testAllQSSMethods(qss); - }); - - test('All methods are defined for PS1.7', () => { - window.prestashop = {}; - - const qss = new QuerySelectorService(buildDIContainerMock()); - testAllQSSMethods(qss); - - delete window.prestashop; - }); -}); diff --git a/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_6.js b/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_6.js deleted file mode 100644 index 6692bbdc1..000000000 --- a/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_6.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const DefaultSelectors1_6 = { - BASE_PAYMENT_CONFIRMATION: '#ps_checkout-express-checkout-submit-button', - - CONDITIONS_CHECKBOXES: 'input[name="cgv"]', - - LOADER_PARENT: 'body', - - NOTIFICATION_CONDITIONS: '.accept-cgv', - NOTIFICATION_PAYMENT_CANCELLED: '#ps_checkout-canceled', - NOTIFICATION_PAYMENT_ERROR: '#ps_checkout-error', - NOTIFICATION_PAYMENT_ERROR_TEXT: '#ps_checkout-error-text', - - PAYMENT_OPTIONS: '.payment-options', - PAYMENT_OPTIONS_LOADER: '#ps_checkout-loader', - PAYMENT_OPTION_RADIOS: - '.payment-options input[type="radio"][name="payment-option"]', - - EXPRESS_CHECKOUT_CONTAINER_PRODUCT_PAGE: - 'body.product .box-cart-bottom .buttons_bottom_block', - EXPRESS_CHECKOUT_CONTAINER_CART_PAGE: 'body.order .cart_navigation_extra', - EXPRESS_CHECKOUT_CONTAINER_CHECKOUT_PAGE: - 'body.authentication #create-account_form, body.order-opc #opc_account_choice:not([style*="display: none"]) .opc-button, body.order-opc #opc_account_form:not([style*="display: none"])', - - PAY_LATER_OFFER_MESSAGE_CONTAINER_PRODUCT: '.content_prices', - PAY_LATER_OFFER_MESSAGE_CONTAINER_CART_SUMMARY: '#total_price_container', - - PAY_LATER_BANNER_CONTAINER: '.header-container', - - CARD_FIELDS: { - FORM: '#ps_checkout-card-fields-form', - NAME: '#ps_checkout-card-fields-card-name', - NUMBER: '#ps_checkout-card-fields-card-number', - EXPIRY: '#ps_checkout-card-fields-card-expiry', - CVV: '#ps_checkout-card-fields-card-cvv', - NAME_ERROR: '#ps_checkout-card-fields-card-name-error', - NUMBER_ERROR: '#ps_checkout-card-fields-card-number-error', - VENDOR_ERROR: '#ps_checkout-card-fields-card-vendor-error', - EXPIRY_ERROR: '#ps_checkout-card-fields-card-expiry-error', - CVV_ERROR: '#ps_checkout-card-fields-card-cvv-error', - }, - - PAYMENT_METHOD_LOGO_PRODUCT_CONTAINER: 'body.product .box-cart-bottom .buttons_bottom_block', - PAYMENT_METHOD_LOGO_CART_CONTAINER: 'body.order .cart_navigation_extra' -}; diff --git a/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_7-hummingbird.js b/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_7-hummingbird.js deleted file mode 100644 index 7547c47aa..000000000 --- a/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_7-hummingbird.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const DefaultSelectors1_7Hummingbird = { - BASE_PAYMENT_CONFIRMATION: '#payment-confirmation [type="submit"]', - - CONDITIONS_CHECKBOXES: '#conditions-to-approve input[type="checkbox"]', - - LOADER_PARENT: 'body', - - NOTIFICATION_CONDITIONS: '.accept-cgv', - NOTIFICATION_PAYMENT_CANCELLED: '#ps_checkout-canceled', - NOTIFICATION_PAYMENT_ERROR: '#ps_checkout-error', - NOTIFICATION_PAYMENT_ERROR_TEXT: '#ps_checkout-error-text', - - PAYMENT_OPTIONS: '.payment__list', - PAYMENT_OPTIONS_LOADER: '#ps_checkout-loader', - PAYMENT_OPTION_RADIOS: - '.payment__list input[type="radio"][name="payment-option"]', - - EXPRESS_CHECKOUT_CONTAINER_PRODUCT_PAGE: - '#product .product__add-to-cart .product__minimal-quantity', - EXPRESS_CHECKOUT_CONTAINER_CART_PAGE: - '#cart .cart-summary .cart-detailed__actions', - EXPRESS_CHECKOUT_CONTAINER_CHECKOUT_PAGE: - '#checkout-personal-information-step .step__content', - - PAY_LATER_OFFER_MESSAGE_CONTAINER_PRODUCT: '.product__prices', - PAY_LATER_OFFER_MESSAGE_CONTAINER_CART_SUMMARY: '.cart-summary__totals', - - PAY_LATER_BANNER_CONTAINER: '#notifications .container', - - CARD_FIELDS: { - FORM: '#ps_checkout-card-fields-form', - NAME: '#ps_checkout-card-fields-name', - NUMBER: '#ps_checkout-card-fields-number', - EXPIRY: '#ps_checkout-card-fields-expiry', - CVV: '#ps_checkout-card-fields-cvv', - NAME_ERROR: '#ps_checkout-card-fields-name-error', - NUMBER_ERROR: '#ps_checkout-card-fields-number-error', - VENDOR_ERROR: '#ps_checkout-card-fields-vendor-error', - EXPIRY_ERROR: '#ps_checkout-card-fields-expiry-error', - CVV_ERROR: '#ps_checkout-card-fields-cvv-error', - }, - - PAYMENT_METHOD_LOGO_PRODUCT_CONTAINER: '#product .product__add-to-cart', - PAYMENT_METHOD_LOGO_CART_CONTAINER: '#cart .cart-summary .cart-detailed__actions' -}; diff --git a/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_7.js b/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_7.js deleted file mode 100644 index fe82e8186..000000000 --- a/_dev/js/front/src/service/query-selector.service/default-selectors/default-selectors-ps1_7.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const DefaultSelectors1_7 = { - BASE_PAYMENT_CONFIRMATION: '#payment-confirmation [type="submit"]', - - CONDITIONS_CHECKBOXES: '#conditions-to-approve input[type="checkbox"]', - - LOADER_PARENT: 'body', - - NOTIFICATION_CONDITIONS: '.accept-cgv', - NOTIFICATION_PAYMENT_CANCELLED: '#ps_checkout-canceled', - NOTIFICATION_PAYMENT_ERROR: '#ps_checkout-error', - NOTIFICATION_PAYMENT_ERROR_TEXT: '#ps_checkout-error-text', - - PAYMENT_OPTIONS: '.payment-options', - PAYMENT_OPTIONS_LOADER: '#ps_checkout-loader', - PAYMENT_OPTION_RADIOS: - '.payment-options input[type="radio"][name="payment-option"]', - - EXPRESS_CHECKOUT_CONTAINER_PRODUCT_PAGE: - '#product .product-add-to-cart .product-quantity', - EXPRESS_CHECKOUT_CONTAINER_CART_PAGE: - '#cart .cart-summary .cart-detailed-actions', - EXPRESS_CHECKOUT_CONTAINER_CHECKOUT_PAGE: - '#checkout-personal-information-step .content', - - PAY_LATER_OFFER_MESSAGE_CONTAINER_PRODUCT: '.product-prices', - PAY_LATER_OFFER_MESSAGE_CONTAINER_CART_SUMMARY: '.cart-summary-totals', - - PAY_LATER_BANNER_CONTAINER: '#notifications .container', - - CARD_FIELDS: { - FORM: '#ps_checkout-card-fields-form', - NAME: '#ps_checkout-card-fields-name', - NUMBER: '#ps_checkout-card-fields-number', - EXPIRY: '#ps_checkout-card-fields-expiry', - CVV: '#ps_checkout-card-fields-cvv', - NAME_ERROR: '#ps_checkout-card-fields-name-error', - NUMBER_ERROR: '#ps_checkout-card-fields-number-error', - VENDOR_ERROR: '#ps_checkout-card-fields-vendor-error', - EXPIRY_ERROR: '#ps_checkout-card-fields-expiry-error', - CVV_ERROR: '#ps_checkout-card-fields-cvv-error', - }, - - PAYMENT_METHOD_LOGO_PRODUCT_CONTAINER: '#product .product-add-to-cart', - PAYMENT_METHOD_LOGO_CART_CONTAINER: '#cart .cart-summary .cart-detailed-actions' -}; diff --git a/_dev/js/front/src/service/query-selector.service/index.js b/_dev/js/front/src/service/query-selector.service/index.js deleted file mode 100644 index a1ab9352a..000000000 --- a/_dev/js/front/src/service/query-selector.service/index.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { - PS_VERSION_1_6, - PS_VERSION_1_7 -} from '../../constants/ps-version.constants'; -import { BaseClass } from '../../core/dependency-injection/base.class'; - -import { QuerySelectorPs1_6Service } from './query-selector-ps1_6.service'; -import { QuerySelectorPs1_7Service } from './query-selector-ps1_7.service'; - -export class QuerySelectorService extends BaseClass { - static Inject = { - prestashopService: 'PrestashopService' - }; - - constructor(app) { - super(app); - - this.instance = { - [PS_VERSION_1_6]: QuerySelectorPs1_6Service, - [PS_VERSION_1_7]: QuerySelectorPs1_7Service - }[this.prestashopService.getVersion()]; - } - - getBasePaymentConfirmation() { - return this.instance.getBasePaymentConfirmation(); - } - - getConditionsCheckboxes() { - return this.instance.getConditionsCheckboxes(); - } - - getLoaderParent() { - return this.instance.getLoaderParent(); - } - - getNotificationConditions() { - return this.instance.getNotificationConditions(); - } - - getNotificationPaymentCanceled() { - return this.instance.getNotificationPaymentCanceled(); - } - - getNotificationPaymentError() { - return this.instance.getNotificationPaymentError(); - } - - getNotificationPaymentErrorText() { - return this.instance.getNotificationPaymentErrorText(); - } - - getPaymentOptions() { - return this.instance.getPaymentOptions(); - } - - getPaymentOptionsLoader() { - return this.instance.getPaymentOptionsLoader(); - } - - getPaymentOptionRadios() { - return this.instance.getPaymentOptionRadios(); - } - - getExpressCheckoutButtonContainerCart() { - return this.instance.getExpressCheckoutButtonContainerCart(); - } - - getExpressCheckoutButtonContainerCheckout() { - return this.instance.getExpressCheckoutButtonContainerCheckout(); - } - - getExpressCheckoutButtonContainerProduct() { - return this.instance.getExpressCheckoutButtonContainerProduct(); - } - - getPayLaterOfferMessageContainerSelector(placement) { - return this.instance.getPayLaterOfferMessageContainerSelector(placement); - } - - getPayLaterOfferBannerContainerSelector(placement) { - return this.instance.getPayLaterOfferBannerContainerSelector(placement); - } - - getCardFieldsFormContainer() { - return this.instance.getCardFieldsFormContainer(); - } - - getCardFieldsNameInputContainer() { - return this.instance.getCardFieldsNameInputContainer(); - } - - getCardFieldsNameError() { - return this.instance.getCardFieldsNameError(); - - } - - getCardFieldsNumberInputContainer() { - return this.instance.getCardFieldsNumberInputContainer(); - } - - getCardFieldsNumberError() { - return this.instance.getCardFieldsNumberError(); - } - - getCardFieldsVendorError() { - return this.instance.getCardFieldsVendorError(); - } - - getCardFieldsExpiryInputContainer() { - return this.instance.getCardFieldsExpiryInputContainer(); - } - - getCardFieldsExpiryError() { - return this.instance.getCardFieldsExpiryError(); - } - - getCardFieldsCvvInputContainer() { - return this.instance.getCardFieldsCvvInputContainer(); - } - - getCardFieldsCvvError() { - return this.instance.getCardFieldsCvvError(); - } - - getPaymentMethodLogoContainer(placement) { - return this.instance.getPaymentMethodLogoContainer(placement); - } -} diff --git a/_dev/js/front/src/service/query-selector.service/query-selector-ps1_6.service.js b/_dev/js/front/src/service/query-selector.service/query-selector-ps1_6.service.js deleted file mode 100644 index 1f302587b..000000000 --- a/_dev/js/front/src/service/query-selector.service/query-selector-ps1_6.service.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { DefaultSelectors1_6 } from './default-selectors/default-selectors-ps1_6'; - -const SELECTORS = { - ...DefaultSelectors1_6, - ...(window.ps_checkout.selectors || {}) -}; - -export class QuerySelectorPs1_6Service { - static getBasePaymentConfirmation() { - return this.querySelector(SELECTORS.BASE_PAYMENT_CONFIRMATION); - } - - static getConditionsCheckboxes() { - return this.querySelectorAll(SELECTORS.CONDITIONS_CHECKBOXES); - } - - static getLoaderParent() { - return this.querySelector(SELECTORS.LOADER_PARENT); - } - - static getNotificationConditions() { - return this.querySelector(SELECTORS.NOTIFICATION_CONDITIONS); - } - - static getNotificationPaymentCanceled() { - return this.querySelector(SELECTORS.NOTIFICATION_PAYMENT_CANCELLED); - } - - static getNotificationPaymentError() { - return this.querySelector(SELECTORS.NOTIFICATION_PAYMENT_ERROR); - } - - static getNotificationPaymentErrorText() { - return this.querySelector(SELECTORS.NOTIFICATION_PAYMENT_ERROR_TEXT); - } - - static getPaymentOptions() { - return this.querySelector(SELECTORS.PAYMENT_OPTIONS); - } - - static getPaymentOptionsLoader() { - return this.querySelector(SELECTORS.PAYMENT_OPTIONS_LOADER); - } - - static getPaymentOptionRadios() { - return this.querySelectorAll(SELECTORS.PAYMENT_OPTION_RADIOS); - } - - static getExpressCheckoutButtonContainerCart() { - return this.querySelector(SELECTORS.EXPRESS_CHECKOUT_CONTAINER_CART_PAGE); - } - - static getExpressCheckoutButtonContainerCheckout() { - return this.querySelector( - SELECTORS.EXPRESS_CHECKOUT_CONTAINER_CHECKOUT_PAGE - ); - } - - static getExpressCheckoutButtonContainerProduct() { - return this.querySelector( - SELECTORS.EXPRESS_CHECKOUT_CONTAINER_PRODUCT_PAGE - ); - } - - static getCardFieldsFormContainer() { - return this.querySelector(SELECTORS.CARD_FIELDS.FORM); - } - - static getCardFieldsNameInputContainer() { - return this.querySelector(SELECTORS.CARD_FIELDS.NAME); - } - - static getCardFieldsNameError() { - return this.querySelector(SELECTORS.CARD_FIELDS.NAME_ERROR); - } - - static getCardFieldsNumberInputContainer() { - return this.querySelector(SELECTORS.CARD_FIELDS.NUMBER); - } - - static getCardFieldsNumberError() { - return this.querySelector(SELECTORS.CARD_FIELDS.NUMBER_ERROR); - } - - static getCardFieldsVendorError() { - return this.querySelector(SELECTORS.CARD_FIELDS.VENDOR_ERROR); - } - - static getCardFieldsExpiryInputContainer() { - return this.querySelector(SELECTORS.CARD_FIELDS.EXPIRY); - } - - static getCardFieldsExpiryError() { - return this.querySelector(SELECTORS.CARD_FIELDS.EXPIRY_ERROR); - } - - static getCardFieldsCvvInputContainer() { - return this.querySelector(SELECTORS.CARD_FIELDS.CVV); - } - - static getCardFieldsCvvError() { - return this.querySelector(SELECTORS.CARD_FIELDS.CVV_ERROR); - } - - static getPayLaterOfferMessageContainerSelector(placement) { - switch (placement) { - case 'product': - return this.querySelector( - SELECTORS.PAY_LATER_OFFER_MESSAGE_CONTAINER_PRODUCT - ); - case 'cart': - case 'payment': - return this.querySelector( - SELECTORS.PAY_LATER_OFFER_MESSAGE_CONTAINER_CART_SUMMARY - ); - default: - return; - } - } - - static getPayLaterOfferBannerContainerSelector(placement) { - switch (placement) { - case 'product': - case 'cart': - case 'home': - case 'payment': - case 'category': - return this.querySelector(SELECTORS.PAY_LATER_BANNER_CONTAINER); - default: - return; - } - } - - static querySelector(selector) { - let element = document.querySelector(selector); - - if (!element) { - console.error('HTMLElement selector ' + selector + ' not found.'); - } - - return element; - } - - static querySelectorAll(selector) { - const elements = [...document.querySelectorAll(selector)]; - - if (elements.length === 0) { - console.error(`HTMLElement selector ${selector} not found.`); - } - - return elements; - } - - static getPaymentMethodLogoContainer(placement) { - switch (placement) { - case 'product': - return document.querySelector( - SELECTORS.PAYMENT_METHOD_LOGO_PRODUCT_CONTAINER - ); - case 'cart': - return document.querySelector( - SELECTORS.PAYMENT_METHOD_LOGO_CART_CONTAINER - ); - default: - return; - } - } -} diff --git a/_dev/js/front/src/service/query-selector.service/query-selector-ps1_7.service.js b/_dev/js/front/src/service/query-selector.service/query-selector-ps1_7.service.js deleted file mode 100644 index 5fb7a1bab..000000000 --- a/_dev/js/front/src/service/query-selector.service/query-selector-ps1_7.service.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { DefaultSelectors1_7 } from './default-selectors/default-selectors-ps1_7'; -import { DefaultSelectors1_7Hummingbird } from './default-selectors/default-selectors-ps1_7-hummingbird'; - -const isThemeHummingbird = document.querySelector('body>main#wrapper') !== null; - -const SELECTORS = { - ...(isThemeHummingbird ? DefaultSelectors1_7Hummingbird : DefaultSelectors1_7), - ...(window.ps_checkout.selectors || {}) -}; - -export class QuerySelectorPs1_7Service { - static getBasePaymentConfirmation() { - return this.querySelector(SELECTORS.BASE_PAYMENT_CONFIRMATION); - } - - static getConditionsCheckboxes() { - return this.querySelectorAll(SELECTORS.CONDITIONS_CHECKBOXES); - } - - static getLoaderParent() { - return this.querySelector(SELECTORS.LOADER_PARENT); - } - - static getNotificationConditions() { - return this.querySelector(SELECTORS.NOTIFICATION_CONDITIONS); - } - - static getNotificationPaymentCanceled() { - return this.querySelector(SELECTORS.NOTIFICATION_PAYMENT_CANCELLED); - } - - static getNotificationPaymentError() { - return this.querySelector(SELECTORS.NOTIFICATION_PAYMENT_ERROR); - } - - static getNotificationPaymentErrorText() { - return this.querySelector(SELECTORS.NOTIFICATION_PAYMENT_ERROR_TEXT); - } - - static getPaymentOptions() { - return this.querySelector(SELECTORS.PAYMENT_OPTIONS); - } - - static getPaymentOptionsLoader() { - return this.querySelector(SELECTORS.PAYMENT_OPTIONS_LOADER); - } - - static getPaymentOptionRadios() { - return this.querySelectorAll(SELECTORS.PAYMENT_OPTION_RADIOS); - } - - static getExpressCheckoutButtonContainerCart() { - return this.querySelector( - SELECTORS.EXPRESS_CHECKOUT_CONTAINER_CART_PAGE - ); - } - - static getExpressCheckoutButtonContainerCheckout() { - return this.querySelector( - SELECTORS.EXPRESS_CHECKOUT_CONTAINER_CHECKOUT_PAGE - ); - } - - static getExpressCheckoutButtonContainerProduct() { - return this.querySelector( - SELECTORS.EXPRESS_CHECKOUT_CONTAINER_PRODUCT_PAGE - ); - } - - static getCardFieldsFormContainer() { - return this.querySelector( - SELECTORS.CARD_FIELDS.FORM - ); - } - static getCardFieldsNameInputContainer() { - return this.querySelector( - SELECTORS.CARD_FIELDS.NAME - ); - } - - static getCardFieldsNameError() { - return this.querySelector( - SELECTORS.CARD_FIELDS.NAME_ERROR - ); - } - - static getCardFieldsNumberInputContainer() { - return this.querySelector( - SELECTORS.CARD_FIELDS.NUMBER - ); - } - - static getCardFieldsNumberError() { - return this.querySelector( - SELECTORS.CARD_FIELDS.NUMBER_ERROR - ); - } - - static getCardFieldsVendorError() { - return this.querySelector( - SELECTORS.CARD_FIELDS.VENDOR_ERROR - ); - } - - static getCardFieldsExpiryInputContainer() { - return this.querySelector( - SELECTORS.CARD_FIELDS.EXPIRY - ); - } - - static getCardFieldsExpiryError() { - return this.querySelector( - SELECTORS.CARD_FIELDS.EXPIRY_ERROR - ); - } - - static getCardFieldsCvvInputContainer() { - return this.querySelector( - SELECTORS.CARD_FIELDS.CVV - ); - } - - static getCardFieldsCvvError() { - return this.querySelector( - SELECTORS.CARD_FIELDS.CVV_ERROR - ); - } - - static getPayLaterOfferMessageContainerSelector(placement) { - switch (placement) { - case 'product': - return this.querySelector(SELECTORS.PAY_LATER_OFFER_MESSAGE_CONTAINER_PRODUCT); - case 'cart': - case 'order': - return this.querySelector(SELECTORS.PAY_LATER_OFFER_MESSAGE_CONTAINER_CART_SUMMARY); - default: - return; - } - } - - static getPayLaterOfferBannerContainerSelector(placement) { - switch (placement) { - case 'product': - case 'cart': - case 'home': - case 'order': - case 'category': - return this.querySelector(SELECTORS.PAY_LATER_BANNER_CONTAINER); - default: - return; - } - } - - static querySelector(selector) { - let element = document.querySelector(selector); - - if (!element) { - console.error('HTMLElement selector ' + selector + ' not found.'); - } - - return element; - } - - static querySelectorAll(selector) { - const elements = [...document.querySelectorAll(selector)]; - - if (elements.length === 0) { - console.error(`HTMLElement selector ${selector} not found.`); - } - - return elements; - } - - static getPaymentMethodLogoContainer(placement) { - switch (placement) { - case 'product': - return document.querySelector(SELECTORS.PAYMENT_METHOD_LOGO_PRODUCT_CONTAINER); - case 'cart': - return document.querySelector(SELECTORS.PAYMENT_METHOD_LOGO_CART_CONTAINER); - default: - return; - } - } -} diff --git a/_dev/js/front/src/service/translation.service.spec.js b/_dev/js/front/src/service/translation.service.spec.js deleted file mode 100644 index 4eee96eed..000000000 --- a/_dev/js/front/src/service/translation.service.spec.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { PsCheckoutConfig } from '../config/ps-checkout.config'; -import { TranslationService } from './translation.service'; - -function buildDIContainerMock() { - return { - container: { - PsCheckoutConfig: { - ...PsCheckoutConfig, - translations: { - foo: 'Foo', - bar: 'Bar' - } - } - } - }; -} - -describe('src/service/translation.service.spec.js', () => { - test('::getTranslationString() with existing id', async () => { - const diContainer = buildDIContainerMock(); - const service = new TranslationService(diContainer); - - expect(service.getTranslationString('foo')).toBe('Foo'); - expect(service.getTranslationString('bar')).toBe('Bar'); - }); - - test('::getTranslationString() with missing id', async () => { - const diContainer = buildDIContainerMock(); - const service = new TranslationService(diContainer); - - expect(service.getTranslationString('baz')).toBe('TRANSLATED_STRING(baz)'); - }); -}); diff --git a/_dev/js/front/src/utils/dependency-injection/inject.js b/_dev/js/front/src/utils/dependency-injection/inject.js deleted file mode 100644 index b9e9348fc..000000000 --- a/_dev/js/front/src/utils/dependency-injection/inject.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * @param cls - * @return {function(AppAwareClass, *=): (void)} - */ -export function inject(cls) { - /** - * @param {AppAwareClass} instance - * @param constructor - * - * @return void - */ - const injector = (instance, constructor) => { - if (constructor === cls) return; - injector(instance, Object.getPrototypeOf(constructor)); - - const container = instance.app.container; - const services = constructor.Inject || {}; - - for (const alias of Object.keys(services)) { - const name = services[alias]; - instance[alias] = container[name]; - } - }; - - return injector; -} diff --git a/_dev/js/front/src/utils/dependency-injection/inject.spec.js b/_dev/js/front/src/utils/dependency-injection/inject.spec.js deleted file mode 100644 index af180c513..000000000 --- a/_dev/js/front/src/utils/dependency-injection/inject.spec.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import { BaseClass } from '../../core/dependency-injection/base.class'; - -import { DI_CONTAINER } from '../../../test/mocks/di-container.mock'; - -describe('src/utils/dependency-injection/inject.spec.js', () => { - test('No injection', () => { - let cls = class extends BaseClass {}; - expect(() => new cls(DI_CONTAINER)).not.toThrow(); - }); - - test('Single service injection with one level of inheritance', () => { - let cls = class extends BaseClass { - static Inject = { - foo: 'ServiceFoo' - }; - }; - - let instance = new cls(DI_CONTAINER); - expect(instance.foo).toBe('Foo'); - }); - - test('Multiple service injection with one level of inheritance', () => { - let cls = class extends BaseClass { - static Inject = { - foo: 'ServiceFoo', - bar: 'ServiceBar', - baz: 'ServiceBaz' - }; - }; - - let instance = new cls(DI_CONTAINER); - expect(instance.foo).toBe('Foo'); - expect(instance.bar).toBe('Bar'); - expect(instance.baz).toBe('Baz'); - }); - - test('Multiple service injection with multiple level of inheritance', () => { - let cls1 = class extends BaseClass { - static Inject = { - foo: 'ServiceFoo' - }; - }; - - let cls2 = class extends cls1 { - static Inject = { - bar: 'ServiceBar', - baz: 'ServiceBaz' - }; - }; - - let instance = new cls2(DI_CONTAINER); - expect(instance.foo).toBe('Foo'); - expect(instance.bar).toBe('Bar'); - expect(instance.baz).toBe('Baz'); - }); -}); diff --git a/_dev/js/front/src/utils/extra/types/paypal-sdk-config.typedef.doc.js b/_dev/js/front/src/utils/extra/types/paypal-sdk-config.typedef.doc.js deleted file mode 100644 index 90faeee59..000000000 --- a/_dev/js/front/src/utils/extra/types/paypal-sdk-config.typedef.doc.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * This file exists only for documentative purposes - */ - -/** - * @typedef PayPalSdkConfig - * @type {object} - * - * @property {string} id - * @property {string} namespace - * @property {string} src - * @property {string} card3dsEnabled - * @property {string} cspNonce - * @property {string} orderId - * @property {string} clientToken - */ diff --git a/_dev/js/front/src/utils/extra/types/paypal-sdk.typedef.doc.js b/_dev/js/front/src/utils/extra/types/paypal-sdk.typedef.doc.js deleted file mode 100644 index 75dbdfaed..000000000 --- a/_dev/js/front/src/utils/extra/types/paypal-sdk.typedef.doc.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * This file exists only for documentative purposes - */ - -/** - * @typedef PayPalCardField - * - * @property {function} addClass - * @property {function} clear - * @property {function} focus - * @property {function} removeAttribute - * @property {function} removeClass - * @property {function} render - * @property {function} setAttribute - * @property {function} setMessage - */ - -/** - * @typedef PayPalSdk - * @type {object} - * - * @property {string} version - * @property {string[]} FUNDING - * @property {function} getCorrelationID - * @property {function} getFundingSources - * @property {function} isFundingEligible - * @property {function} rememberFunding - * @property {object} Buttons - * @property {function} Buttons.isEligible - * @property {function} Buttons.render - * @property {object} Marks - * @property {function} Marks.isEligible - * @property {function} Marks.render - * @property {object} HostedFields - * @property {object} CardFields - * @property {PayPalCardField} CardFields.CVVField - * @property {PayPalCardField} CardFields.ExpiryField - * @property {PayPalCardField} CardFields.NameField - * @property {PayPalCardField} CardFields.NumberField - * @property {function} CardFields.getState - * @property {function} CardFields.isEligible - * @property {function} CardFields.submit - * @property {function} HostedFields.isEligible - * @property {function} HostedFields.render - * @property {object} Messages - * @property {function} Messages.render - */ diff --git a/_dev/js/front/src/utils/globals/index.js b/_dev/js/front/src/utils/globals/index.js deleted file mode 100644 index eae76a819..000000000 --- a/_dev/js/front/src/utils/globals/index.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -window.ps_checkout = window.ps_checkout || {}; - -window.ps_checkout.app = window.ps_checkout.app || null; - -window.ps_checkout.config = window.ps_checkout.config || {}; -window.ps_checkout.selectors = window.ps_checkout.selectors || {}; - -window.ps_checkout.events = window.ps_checkout.events || new EventTarget(); - -window.ps_checkout.version = - window.ps_checkout.version || window.ps_checkoutVersion; diff --git a/_dev/js/front/src/utils/polyfills/index.js b/_dev/js/front/src/utils/polyfills/index.js deleted file mode 100644 index 94ff5245b..000000000 --- a/_dev/js/front/src/utils/polyfills/index.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import 'classlist-polyfill'; -import 'core-js/stable'; -import 'promise-polyfill/src/polyfill'; -import 'regenerator-runtime/runtime'; -import 'url-polyfill'; -import 'whatwg-fetch'; - -import './event-target'; -import './web-api.child-node.remove'; -import './web-api.child-node.replace-with'; -import './web-api.parent-node.append'; -import './web-api.parent-node.prepend'; diff --git a/_dev/js/front/src/utils/polyfills/web-api.child-node.remove.js b/_dev/js/front/src/utils/polyfills/web-api.child-node.remove.js deleted file mode 100644 index 68e037735..000000000 --- a/_dev/js/front/src/utils/polyfills/web-api.child-node.remove.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * Polyfill .remove() - * https://developer.mozilla.org/es/docs/Web/API/ChildNode/remove#Polyfill - */ -(function (arr) { - arr.forEach(function (item) { - // eslint-disable-next-line no-prototype-builtins - if (item.hasOwnProperty('remove')) { - return; - } - Object.defineProperty(item, 'remove', { - configurable: true, - enumerable: true, - writable: true, - value: function remove() { - if (this.parentNode !== null) this.parentNode.removeChild(this); - } - }); - }); -})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); diff --git a/_dev/js/front/src/utils/polyfills/web-api.child-node.replace-with.js b/_dev/js/front/src/utils/polyfills/web-api.child-node.replace-with.js deleted file mode 100644 index 30e64b8c6..000000000 --- a/_dev/js/front/src/utils/polyfills/web-api.child-node.replace-with.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * Polyfill .replaceWith() - * https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith - */ -function ReplaceWithPolyfill() { - 'use-strict'; // For safari, and IE > 10 - var parent = this.parentNode, - i = arguments.length, - currentNode; - if (!parent) return; - if (!i) - // if there are no arguments - parent.removeChild(this); - while (i--) { - // i-- decrements i and returns the value of i before the decrement - currentNode = arguments[i]; - if (typeof currentNode !== 'object') { - currentNode = this.ownerDocument.createTextNode(currentNode); - } else if (currentNode.parentNode) { - currentNode.parentNode.removeChild(currentNode); - } - // the value of "i" below is after the decrement - if (!i) - // if currentNode is the first argument (currentNode === arguments[0]) - parent.replaceChild(currentNode, this); - // if currentNode isn't the first - else parent.insertBefore(currentNode, this.nextSibling); - } -} -if (!Element.prototype.replaceWith) - Element.prototype.replaceWith = ReplaceWithPolyfill; -if (!CharacterData.prototype.replaceWith) - CharacterData.prototype.replaceWith = ReplaceWithPolyfill; -if (!DocumentType.prototype.replaceWith) - DocumentType.prototype.replaceWith = ReplaceWithPolyfill; diff --git a/_dev/js/front/src/utils/polyfills/web-api.parent-node.append.js b/_dev/js/front/src/utils/polyfills/web-api.parent-node.append.js deleted file mode 100644 index cca0f48fc..000000000 --- a/_dev/js/front/src/utils/polyfills/web-api.parent-node.append.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * Polyfill .append() - * https://developer.mozilla.org/es/docs/Web/API/ParentNode/append#Polyfill - */ -(function (arr) { - arr.forEach(function (item) { - // eslint-disable-next-line no-prototype-builtins - if (item.hasOwnProperty('append')) { - return; - } - Object.defineProperty(item, 'append', { - configurable: true, - enumerable: true, - writable: true, - value: function append() { - var argArr = Array.prototype.slice.call(arguments), - docFrag = document.createDocumentFragment(); - - argArr.forEach(function (argItem) { - var isNode = argItem instanceof Node; - docFrag.appendChild( - isNode ? argItem : document.createTextNode(String(argItem)) - ); - }); - - this.appendChild(docFrag); - } - }); - }); -})([Element.prototype, Document.prototype, DocumentFragment.prototype]); diff --git a/_dev/js/front/src/utils/polyfills/web-api.parent-node.prepend.js b/_dev/js/front/src/utils/polyfills/web-api.parent-node.prepend.js deleted file mode 100644 index 03855f1f0..000000000 --- a/_dev/js/front/src/utils/polyfills/web-api.parent-node.prepend.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ - -/** - * Polyfill .prepend() - * https://developer.mozilla.org/es/docs/Web/API/ParentNode/append#Polyfill - */ -(function (arr) { - arr.forEach(function (item) { - // eslint-disable-next-line no-prototype-builtins - if (item.hasOwnProperty('prepend')) { - return; - } - Object.defineProperty(item, 'prepend', { - configurable: true, - enumerable: true, - writable: true, - value: function prepend() { - var argArr = Array.prototype.slice.call(arguments), - docFrag = document.createDocumentFragment(); - - argArr.forEach(function (argItem) { - var isNode = argItem instanceof Node; - docFrag.appendChild( - isNode ? argItem : document.createTextNode(String(argItem)) - ); - }); - - this.insertBefore(docFrag, this.firstChild); - } - }); - }); -})([Element.prototype, Document.prototype, DocumentFragment.prototype]); diff --git a/_dev/js/front/test/mocks/api/ps-checkout.api.js b/_dev/js/front/test/mocks/api/ps-checkout.api.js deleted file mode 100644 index 6fd5fc82c..000000000 --- a/_dev/js/front/test/mocks/api/ps-checkout.api.js +++ /dev/null @@ -1 +0,0 @@ -export const PsCheckoutApiMock = {}; diff --git a/_dev/js/front/test/mocks/components/common/hosted-fields.component.mock.js b/_dev/js/front/test/mocks/components/common/hosted-fields.component.mock.js deleted file mode 100644 index 208b9edb7..000000000 --- a/_dev/js/front/test/mocks/components/common/hosted-fields.component.mock.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const HostedFieldsComponentMock = jest.fn(); - -HostedFieldsComponentMock.render = jest.fn(); - -HostedFieldsComponentMock.mockImplementation(() => ({ - render: HostedFieldsComponentMock.render -})); diff --git a/_dev/js/front/test/mocks/components/common/payment-fields.component.mock.js b/_dev/js/front/test/mocks/components/common/payment-fields.component.mock.js deleted file mode 100644 index f849675ce..000000000 --- a/_dev/js/front/test/mocks/components/common/payment-fields.component.mock.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const PaymentFieldsComponentMock = jest.fn(); - -PaymentFieldsComponentMock.render = jest.fn(); - -PaymentFieldsComponentMock.mockImplementation(() => ({ - render: PaymentFieldsComponentMock.render -})); diff --git a/_dev/js/front/test/mocks/components/common/smart-button.component.mock.js b/_dev/js/front/test/mocks/components/common/smart-button.component.mock.js deleted file mode 100644 index fe5f1aa1d..000000000 --- a/_dev/js/front/test/mocks/components/common/smart-button.component.mock.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const SmartButtonComponentMock = jest.fn(); - -SmartButtonComponentMock.render = jest.fn(); - -SmartButtonComponentMock.mockImplementation(() => ({ - render: SmartButtonComponentMock.render -})); diff --git a/_dev/js/front/test/mocks/data/product-dataset.json b/_dev/js/front/test/mocks/data/product-dataset.json deleted file mode 100644 index 3061dbccf..000000000 --- a/_dev/js/front/test/mocks/data/product-dataset.json +++ /dev/null @@ -1,262 +0,0 @@ -{ - "id_shop_default": "1", - "id_manufacturer": "1", - "id_supplier": "0", - "reference": "demo_1", - "is_virtual": "0", - "delivery_in_stock": "", - "delivery_out_stock": "", - "id_category_default": "4", - "on_sale": "0", - "online_only": "0", - "ecotax": 0, - "minimal_quantity": "1", - "low_stock_threshold": null, - "low_stock_alert": "0", - "price": "0,10\u00a0\u20ac", - "unity": "", - "unit_price_ratio": "0.000000", - "additional_shipping_cost": "0.00", - "customizable": "0", - "text_fields": "0", - "uploadable_files": "0", - "redirect_type": "301-category", - "id_type_redirected": "0", - "available_for_order": "1", - "available_date": null, - "show_condition": "0", - "condition": "new", - "show_price": "1", - "indexed": "1", - "visibility": "both", - "cache_default_attribute": "1", - "advanced_stock_management": "0", - "date_add": "2019-07-12 15:09:17", - "date_upd": "2019-11-27 15:30:41", - "pack_stock_type": "3", - "meta_description": "", - "meta_keywords": "", - "meta_title": "", - "link_rewrite": "hummingbird-printed-t-shirt", - "name": "T-shirt imprim\u00e9 colibri", - "description": "

Symbole de l\u00e9g\u00e8ret\u00e9 et de d\u00e9licatesse, le colibri \u00e9voque la gaiet\u00e9 et la curiosit\u00e9.<\/span> La collection PolyFaune de la marque Studio Design propose des pi\u00e8ces aux coupes basiques et aux visuels color\u00e9s inspir\u00e9s des origamis japonais traditionnels. \u00c0 porter avec un chino ou un jean. Le proc\u00e9d\u00e9 d'impression par sublimation garantit la qualit\u00e9 et la long\u00e9vit\u00e9 des couleurs.<\/span><\/span><\/p>", - "description_short": "

Coupe classique, col rond, manches courtes. T-shirt en coton pima extra-fin \u00e0 fibres longues. <\/span><\/p>", - "available_now": "", - "available_later": "", - "id": 1, - "id_product": 1, - "out_of_stock": 2, - "new": 0, - "id_product_attribute": "1", - "quantity_wanted": 1, - "extraContent": [], - "allow_oosp": 0, - "category": "hommes", - "category_name": "Hommes", - "link": "http:\/\/shop13.webmodule.prestashop.net\/index.php?id_product=1&rewrite=hummingbird-printed-t-shirt&controller=product&id_lang=3", - "attribute_price": 0, - "price_tax_exc": 0.080000000000000002, - "price_without_reduction": 0.12, - "reduction": 0.024, - "specific_prices": { - "id_specific_price": "1", - "id_specific_price_rule": "0", - "id_cart": "0", - "id_product": "1", - "id_shop": "0", - "id_shop_group": "0", - "id_currency": "0", - "id_country": "0", - "id_group": "0", - "id_customer": "0", - "id_product_attribute": "0", - "price": "-1.000000", - "from_quantity": "1", - "reduction": "0.200000", - "reduction_tax": "1", - "reduction_type": "percentage", - "from": "0000-00-00 00:00:00", - "to": "0000-00-00 00:00:00", - "score": "32" - }, - "quantity": 272, - "quantity_all_versions": 2372, - "id_image": "it-default", - "features": [ - { - "name": "Composizioni", - "value": "Cotone", - "id_feature": "1", - "position": "0" - }, - { - "name": "Propri\u00e9t\u00e9", - "value": "Manica corta", - "id_feature": "2", - "position": "1" - } - ], - "attachments": [], - "virtual": 0, - "pack": 0, - "packItems": [], - "nopackprice": 0, - "customization_required": false, - "attributes": { - "1": { - "id_attribute": "1", - "id_attribute_group": "1", - "name": "S", - "group": "Dimensione", - "reference": "demo_1", - "ean13": "", - "isbn": "", - "upc": "" - }, - "2": { - "id_attribute": "8", - "id_attribute_group": "2", - "name": "Bianco", - "group": "Colore", - "reference": "demo_1", - "ean13": "", - "isbn": "", - "upc": "" - } - }, - "rate": 20, - "tax_name": "TVA FR 20%", - "ecotax_rate": 0, - "unit_price": "", - "customizations": { - "fields": [] - }, - "id_customization": 0, - "is_customizable": false, - "show_quantities": true, - "quantity_label": "Articoli", - "quantity_discounts": [], - "customer_group_discount": 0, - "images": [ - { - "bySize": { - "small_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-small_default.jpg", - "width": 98, - "height": 98 - }, - "cart_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-cart_default.jpg", - "width": 125, - "height": 125 - }, - "home_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-home_default.jpg", - "width": 250, - "height": 250 - }, - "medium_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-medium_default.jpg", - "width": 452, - "height": 452 - }, - "large_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-large_default.jpg", - "width": 800, - "height": 800 - } - }, - "small": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-small_default.jpg", - "width": 98, - "height": 98 - }, - "medium": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-home_default.jpg", - "width": 250, - "height": 250 - }, - "large": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-large_default.jpg", - "width": 800, - "height": 800 - }, - "legend": "T-shirt imprim\u00e9 colibri", - "cover": null, - "id_image": "2", - "position": "2", - "associatedVariants": [ - "7", - "1", - "5", - "3" - ] - } - ], - "cover": { - "bySize": { - "small_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-small_default.jpg", - "width": 98, - "height": 98 - }, - "cart_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-cart_default.jpg", - "width": 125, - "height": 125 - }, - "home_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-home_default.jpg", - "width": 250, - "height": 250 - }, - "medium_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-medium_default.jpg", - "width": 452, - "height": 452 - }, - "large_default": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-large_default.jpg", - "width": 800, - "height": 800 - } - }, - "small": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-small_default.jpg", - "width": 98, - "height": 98 - }, - "medium": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-home_default.jpg", - "width": 250, - "height": 250 - }, - "large": { - "url": "http:\/\/shop13.webmodule.prestashop.net\/img\/p\/2\/2-large_default.jpg", - "width": 800, - "height": 800 - }, - "legend": "T-shirt imprim\u00e9 colibri", - "cover": null, - "id_image": "2", - "position": "2", - "associatedVariants": [ - "7", - "1", - "5", - "3" - ] - }, - "has_discount": true, - "discount_type": "percentage", - "discount_percentage": "-20%", - "discount_percentage_absolute": "20%", - "discount_amount": "0,02\u00a0\u20ac", - "discount_amount_to_display": "-0,02\u00a0\u20ac", - "price_amount": 0.096000000000000002, - "unit_price_full": "", - "show_availability": true, - "availability_date": null, - "availability_message": "", - "availability": "available" -} diff --git a/_dev/js/front/test/mocks/di-container.mock.js b/_dev/js/front/test/mocks/di-container.mock.js deleted file mode 100644 index a1f1e30e8..000000000 --- a/_dev/js/front/test/mocks/di-container.mock.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const DI_CONTAINER = { - container: { - ServiceFoo: 'Foo', - ServiceBar: 'Bar', - ServiceBaz: 'Baz' - } -}; diff --git a/_dev/js/front/test/mocks/html-templates/prestashop-site-1_7.js b/_dev/js/front/test/mocks/html-templates/prestashop-site-1_7.js deleted file mode 100644 index c1a3735c8..000000000 --- a/_dev/js/front/test/mocks/html-templates/prestashop-site-1_7.js +++ /dev/null @@ -1,47 +0,0 @@ -import PRODUCT_DATASET from '../data/product-dataset.json'; - -export function cleanSite() { - document.body.removeAttribute('id'); - document.body.innerHTML = ''; -} - -export function mockCartPage() { - document.body.id = 'cart'; -} - -export function mockCheckoutPage() { - document.body.id = 'checkout'; -} - -export function mockCheckoutPaymentStepPage() { - document.body.id = 'checkout'; - document.body.innerHTML = `

`; -} - -export function mockCheckoutPersonalInformationStepPage() { - document.body.id = 'checkout'; - document.body.innerHTML = `
`; -} - -export function mockProductPage() { - document.body.id = 'product'; - document.body.innerHTML = ` -
- `; - - document - .getElementById('product-details') - .setAttribute('data-product', JSON.stringify(PRODUCT_DATASET)); -} - -export function mockCheckoutVars() { - window.ps_checkoutPayPalOrderId = ''; - window.ps_checkoutPayPalClientToken = ''; - window.ps_checkoutPayPalSdkConfig = { - clientId: 'test', - currency: 'EUR', - intent: 'capture', - integrationDate: '2022-14-06', - components: 'marks,funding-eligibility,buttons' - }; -} diff --git a/_dev/js/front/test/mocks/service/paypal.service.js b/_dev/js/front/test/mocks/service/paypal.service.js deleted file mode 100644 index 055875aa5..000000000 --- a/_dev/js/front/test/mocks/service/paypal.service.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -export const PayPalServiceMock = { - getButtonPayment: jest.fn(), - render: jest.fn() -}; diff --git a/_dev/js/front/test/setup.js b/_dev/js/front/test/setup.js deleted file mode 100644 index 71a0ec05d..000000000 --- a/_dev/js/front/test/setup.js +++ /dev/null @@ -1,4 +0,0 @@ -import 'core-js/stable'; -import 'regenerator-runtime/runtime'; - -import '../src/utils/globals'; diff --git a/_dev/js/front/webpack/profile/build.js b/_dev/js/front/webpack/profile/build.js deleted file mode 100644 index 5948fc653..000000000 --- a/_dev/js/front/webpack/profile/build.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -const TerserPlugin = require('terser-webpack-plugin'); -const { merge } = require('webpack-merge'); - -const common = require('../webpack.config'); -module.exports = merge(common, { - mode: 'production', - optimization: { - minimize: true, - minimizer: [ - new TerserPlugin({ - terserOptions: { - format: { - comments: false - }, - parse: { - // We want terser to parse ecma 8 code. However, we don't want it - // to apply any minification steps that turns valid ecma 5 code - // into invalid ecma 5 code. This is why the 'compress' and 'output' - // sections only apply transformations that are ecma 5 safe - // https://github.com/facebook/create-react-app/pull/4234 - ecma: 8 - }, - compress: { - ecma: 5, - warnings: false, - // Disabled because of an issue with Uglify breaking seemingly valid code: - // https://github.com/facebook/create-react-app/issues/2376 - // Pending further investigation: - // https://github.com/mishoo/UglifyJS2/issues/2011 - comparisons: false, - // Disabled because of an issue with Terser breaking valid code: - // https://github.com/facebook/create-react-app/issues/5250 - // Pending further investigation: - // https://github.com/terser-js/terser/issues/120 - inline: 2 - }, - mangle: { - safari10: true - }, - // Added for profiling in devtools - keep_classnames: false, - keep_fnames: false, - output: { - ecma: 5, - comments: false, - // Turned on because emoji and regex is not minified properly using default - // https://github.com/facebook/create-react-app/issues/2488 - ascii_only: true - } - }, - extractComments: false - }) - ] - } -}); diff --git a/_dev/js/front/webpack/profile/watch.js b/_dev/js/front/webpack/profile/watch.js deleted file mode 100644 index 6234891ad..000000000 --- a/_dev/js/front/webpack/profile/watch.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -const { merge } = require('webpack-merge'); - -const common = require('../webpack.config'); -module.exports = merge(common, { - mode: 'development', - devtool: 'inline-source-map' -}); diff --git a/_dev/js/front/webpack/utils/paths.js b/_dev/js/front/webpack/utils/paths.js deleted file mode 100644 index 18d47309b..000000000 --- a/_dev/js/front/webpack/utils/paths.js +++ /dev/null @@ -1,16 +0,0 @@ -const { join } = require('path'); - -const MODULE_DIR = join(__dirname, '../../../../../'); -const PROJECT_DIR = join(__dirname, '../../'); - -const INPUT_FILE = join(PROJECT_DIR, 'src/index.js'); -const OUTPUT_FOLDER = join(MODULE_DIR, 'views/js'); -const OUTPUT_LICENSES = join(MODULE_DIR, 'views/js/front.licenses.json'); - -module.exports = { - MODULE_DIR, - PROJECT_DIR, - INPUT_FILE, - OUTPUT_FOLDER, - OUTPUT_LICENSES -}; diff --git a/_dev/js/front/webpack/webpack.config.js b/_dev/js/front/webpack/webpack.config.js deleted file mode 100644 index 28af5902c..000000000 --- a/_dev/js/front/webpack/webpack.config.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * @author PrestaShop SA - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -const { INPUT_FILE, OUTPUT_FOLDER } = require('./utils/paths'); - -module.exports = { - entry: { - front: INPUT_FILE - }, - output: { - filename: '[name].js', - path: OUTPUT_FOLDER - }, - - stats: { - children: false, - modules: false - }, - - module: { - rules: [ - { - test: /\.js$/, - exclude: /(node_modules|bower_components)/, - use: 'babel-loader' - } - ] - } -}; diff --git a/classes/PsCheckoutCart.php b/classes/PsCheckoutCart.php index 8aa101127..376c355b6 100755 --- a/classes/PsCheckoutCart.php +++ b/classes/PsCheckoutCart.php @@ -124,7 +124,7 @@ class PsCheckoutCart extends ObjectModel 'paypal_status' => [ 'type' => self::TYPE_STRING, 'validate' => 'isGenericName', - 'size' => 20, + 'size' => 30, 'allow_null' => true, 'required' => false, ], diff --git a/composer.json b/composer.json index 493d1a6cd..e74f979ec 100755 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "@php -d date.timezone=UTC ./vendor/bin/phpunit -c tests/Unit/phpunit.xml" ], "set-license-header": [ - "@php ./vendor/bin/header-stamp --license=vendor/prestashop/header-stamp/assets/afl.txt --exclude=.github,node_modules,vendor,tests,_dev" + "@php ./vendor/bin/header-stamp --license=vendor/prestashop/header-stamp/assets/afl.txt --exclude=.github,node_modules,vendor,tests" ] }, "author": "PrestaShop" diff --git a/config.xml b/config.xml index 04c4a7e81..a648c2b93 100644 --- a/config.xml +++ b/config.xml @@ -2,7 +2,7 @@ ps_checkout - + diff --git a/config/accounts.yml b/config/accounts.yml new file mode 100644 index 000000000..dc3837922 --- /dev/null +++ b/config/accounts.yml @@ -0,0 +1,12 @@ +services: + ps_accounts.installer: + class: 'PrestaShop\PsAccountsInstaller\Installer\Installer' + public: true + arguments: + - "4.0.0" + + ps_accounts.facade: + class: 'PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts' + public: true + arguments: + - "@ps_accounts.installer" diff --git a/src/Api/Payment/index.php b/config/admin/index.php old mode 100755 new mode 100644 similarity index 100% rename from src/Api/Payment/index.php rename to config/admin/index.php diff --git a/config/admin/services.yml b/config/admin/services.yml index 21003a8d8..5e9cf5345 100644 --- a/config/admin/services.yml +++ b/config/admin/services.yml @@ -2,13 +2,13 @@ imports: - { resource: ../common.yml } services: - ps_checkout.logger.file.finder: + PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileFinder: class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileFinder' public: true arguments: - - '@ps_checkout.logger.directory' - - '@ps_checkout.logger.filename' + - '@PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory' + - '@PrestaShop\Module\PrestashopCheckout\Logger\LoggerFilename' - ps_checkout.logger.file.reader: + PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileReader: class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileReader' public: true diff --git a/config/cache.yml b/config/cache.yml new file mode 100644 index 000000000..4da6b6d55 --- /dev/null +++ b/config/cache.yml @@ -0,0 +1,52 @@ +services: + PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider: + class: 'PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider' + public: true + arguments: + - !php/const _PS_VERSION_ + - !php/const _PS_ROOT_DIR_ + - !php/const _PS_MODE_DEV_ + + ps_checkout.cache.array.paypal.order: + class: 'Symfony\Component\Cache\Simple\ArrayCache' + + ps_checkout.cache.filesystem.paypal.order: + class: 'Symfony\Component\Cache\Simple\FilesystemCache' + arguments: + - "paypal-orders" + - 3600 + - '@=service("PrestaShop\\ModuleLibCacheDirectoryProvider\\Cache\\CacheDirectoryProvider").getPath()' + + ps_checkout.cache.paypal.order: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\Cache\PayPalOrderCache' + public: true + arguments: + - [ + "@ps_checkout.cache.array.paypal.order", + "@ps_checkout.cache.filesystem.paypal.order"] + + ps_checkout.cache.array.paypal.capture: + class: 'Symfony\Component\Cache\Simple\ArrayCache' + + ps_checkout.cache.filesystem.paypal.capture: + class: 'Symfony\Component\Cache\Simple\FilesystemCache' + arguments: + - "paypal-capture" + - 3600 + - '@=service("PrestaShop\\ModuleLibCacheDirectoryProvider\\Cache\\CacheDirectoryProvider").getPath()' + + ps_checkout.cache.paypal.capture: + class: 'Symfony\Component\Cache\Simple\ChainCache' + public: true + arguments: + - [ + "@ps_checkout.cache.array.paypal.capture", + "@ps_checkout.cache.filesystem.paypal.capture"] + + ps_checkout.cache.pscheckoutcart: + class: 'Symfony\Component\Cache\Simple\ArrayCache' + public: true + + ps_checkout.cache.order: + class: 'Symfony\Component\Cache\Simple\ArrayCache' + public: true diff --git a/config/command-handlers.yml b/config/command-handlers.yml new file mode 100644 index 000000000..e1c3d4c8c --- /dev/null +++ b/config/command-handlers.yml @@ -0,0 +1,123 @@ +services: + PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\AddOrderPaymentCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\AddOrderPaymentCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + + PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\CreateOrderCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\CreateOrderCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Context\ContextStateManager' + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + - '@PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper' + - "@ps_checkout.module" + - '@PrestaShop\Module\PrestashopCheckout\Order\Service\CheckOrderAmount' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider' + + PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\UpdateOrderStatusCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\UpdateOrderStatusCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + + PrestaShop\Module\PrestashopCheckout\Order\Matrice\CommandHandler\UpdateOrderMatriceCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\Matrice\CommandHandler\UpdateOrderMatriceCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CreatePayPalOrderCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CreatePayPalOrderCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\UpdatePayPalOrderCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\UpdatePayPalOrderCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient' + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider' + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CapturePayPalOrderCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CapturePayPalOrderCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient' + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + - "@ps_checkout.cache.paypal.order" + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' + + PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SaveCheckoutCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SaveCheckoutCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\CancelCheckoutCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\CancelCheckoutCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SavePayPalOrderStatusCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SavePayPalOrderStatusCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' + + PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\UpdatePaymentMethodSelectedCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\UpdatePaymentMethodSelectedCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\CommandHandler\RefundPayPalCaptureCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\CommandHandler\RefundPayPalCaptureCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' + + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler\DeletePaymentTokenCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler\DeletePaymentTokenCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\PaymentMethodTokenService' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler\SavePaymentTokenCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler\SavePaymentTokenCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\Customer\CommandHandler\SavePayPalCustomerCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Customer\CommandHandler\SavePayPalCustomerCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\SavePayPalOrderCommandHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\SavePayPalOrderCommandHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' diff --git a/config/common.yml b/config/common.yml index f94a67ac5..bfec74776 100644 --- a/config/common.yml +++ b/config/common.yml @@ -1,3 +1,11 @@ +imports: + - { resource: ./accounts.yml } + - { resource: ./cache.yml } + - { resource: ./command-handlers.yml } + - { resource: ./http-clients.yml } + - { resource: ./logger.yml } + - { resource: ./query-handlers.yml } + - { resource: ./repository.yml } services: # From PS 1.7.0 to PS 1.7.3, the bundled version of Symfony is 2.x on which the _defaults # key is invalid. To prevent error on these versions, each service has to be specifically @@ -12,6 +20,11 @@ services: arguments: - "ps_checkout" + ps_checkout.db: + class: Db + factory: [ 'Db', 'getInstance' ] + public: true + ps_checkout.module.version: class: 'PrestaShop\Module\PrestashopCheckout\Version\Version' factory: ["PrestaShop\\Module\\PrestashopCheckout\\Version\\Version", "buildFromString"] @@ -19,719 +32,455 @@ services: arguments: - '@=service("ps_checkout.module").version' - ps_checkout.context.prestashop: - class: 'PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + PrestaShop\Module\PrestashopCheckout\Environment\EnvLoader: + class: 'PrestaShop\Module\PrestashopCheckout\Environment\EnvLoader' public: true - ps_checkout.context.state.manager: - class: 'PrestaShop\Module\PrestashopCheckout\Context\ContextStateManager' + PrestaShop\Module\PrestashopCheckout\Environment\Env: + class: 'PrestaShop\Module\PrestashopCheckout\Environment\Env' public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' - ps_checkout.context.shop: - class: 'PrestaShop\Module\PrestashopCheckout\ShopContext' + ps_checkout.tactician.bus: + class: 'League\Tactician\CommandBus' + factory: [ '@PrestaShop\Module\PrestashopCheckout\CommandBus\TacticianCommandBusFactory', "create" ] + + ps_checkout.bus.command: + class: 'PrestaShop\Module\PrestashopCheckout\CommandBus\TacticianCommandBusAdapter' public: true + arguments: + - "@ps_checkout.tactician.bus" - ps_checkout.shop.provider: - class: 'PrestaShop\Module\PrestashopCheckout\Shop\ShopProvider' + PrestaShop\Module\PrestashopCheckout\CommandBus\TacticianCommandBusFactory: + class: 'PrestaShop\Module\PrestashopCheckout\CommandBus\TacticianCommandBusFactory' public: true + arguments: + - "@ps_checkout.module" + - "@ps_checkout.logger" + - PrestaShop\Module\PrestashopCheckout\Order\Command\AddOrderPaymentCommand: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\AddOrderPaymentCommandHandler' + PrestaShop\Module\PrestashopCheckout\Order\Command\CreateOrderCommand: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\CreateOrderCommandHandler' + PrestaShop\Module\PrestashopCheckout\Order\Command\UpdateOrderStatusCommand: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\UpdateOrderStatusCommandHandler' + PrestaShop\Module\PrestashopCheckout\Order\Matrice\Command\UpdateOrderMatriceCommand: 'PrestaShop\Module\PrestashopCheckout\Order\Matrice\CommandHandler\UpdateOrderMatriceCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CreatePayPalOrderCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CreatePayPalOrderCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\UpdatePayPalOrderCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\UpdatePayPalOrderCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CapturePayPalOrderCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CapturePayPalOrderCommandHandler' + PrestaShop\Module\PrestashopCheckout\Checkout\Command\CancelCheckoutCommand: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\CancelCheckoutCommandHandler' + PrestaShop\Module\PrestashopCheckout\Checkout\Command\SaveCheckoutCommand: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SaveCheckoutCommandHandler' + PrestaShop\Module\PrestashopCheckout\Checkout\Command\SavePayPalOrderStatusCommand: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SavePayPalOrderStatusCommandHandler' + PrestaShop\Module\PrestashopCheckout\Checkout\Command\UpdatePaymentMethodSelectedCommand: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\UpdatePaymentMethodSelectedCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Command\RefundPayPalCaptureCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\CommandHandler\RefundPayPalCaptureCommandHandler' + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentCompletedQuery: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentCompletedQueryHandler' + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentDeniedQuery: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentDeniedQueryHandler' + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentPendingQuery: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentPendingQueryHandler' + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQuery: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentRefundedQueryHandler' + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentReversedQuery: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentReversedQueryHandler' + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQuery: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForApprovalReversedQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCartIdQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCartIdQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetCurrentPayPalOrderStatusQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetCurrentPayPalOrderStatusQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCheckoutCompletedQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCheckoutCompletedQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForOrderConfirmationQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForOrderConfirmationQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command\SavePaymentTokenCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler\SavePaymentTokenCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command\DeletePaymentTokenCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler\DeletePaymentTokenCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query\GetCustomerPaymentTokensQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query\GetCustomerPaymentTokensQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Customer\Command\SavePayPalCustomerCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Customer\CommandHandler\SavePayPalCustomerCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\SavePayPalOrderCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\SavePayPalOrderCommandHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query\GetGooglePayTransactionInfoQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query\GetGooglePayTransactionInfoQueryHandler' + PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query\GetApplePayPaymentRequestQuery: 'PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query\GetApplePayPaymentRequestQueryHandler' + + PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherFactory: + class: 'PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherFactory' + public: true + arguments: + - "@ps_checkout.logger" + - '@PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration' - ps_checkout.configuration.options.resolver: - class: 'PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfigurationOptionsResolver' + PrestaShop\Module\PrestashopCheckout\Checkout\EventSubscriber\CheckoutEventSubscriber: + class: 'PrestaShop\Module\PrestashopCheckout\Checkout\EventSubscriber\CheckoutEventSubscriber' public: true arguments: - - '@=service("ps_checkout.shop.provider").getIdentifier()' + - '@PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker' + - '@ps_checkout.bus.command' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' - ps_checkout.configuration: - class: 'PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' + PrestaShop\Module\PrestashopCheckout\Order\EventSubscriber\OrderEventSubscriber: + class: 'PrestaShop\Module\PrestashopCheckout\Order\EventSubscriber\OrderEventSubscriber' public: true arguments: - - "@ps_checkout.configuration.options.resolver" + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + - '@ps_checkout.module' - ps_checkout.logger.directory: - class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory' + PrestaShop\Module\PrestashopCheckout\PayPal\Order\EventSubscriber\PayPalOrderEventSubscriber: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\EventSubscriber\PayPalOrderEventSubscriber' public: true arguments: - - !php/const _PS_VERSION_ - - !php/const _PS_ROOT_DIR_ + - "@ps_checkout.module" + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + - "@ps_checkout.cache.paypal.order" + - '@PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\Order\CheckTransitionPayPalOrderStatusService' + - '@PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' - ps_checkout.logger.filename: - class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerFilename' + PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\EventSubscriber\PayPalCaptureEventSubscriber: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\EventSubscriber\PayPalCaptureEventSubscriber' public: true arguments: - - '@=service("ps_checkout.module").name' - - '@=service("ps_checkout.shop.provider").getIdentifier()' + - '@ps_checkout.module' + - '@PrestaShop\Module\PrestashopCheckout\Order\Service\CheckOrderAmount' + - "@ps_checkout.cache.paypal.capture" + - "@ps_checkout.cache.paypal.order" + - '@PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper' + + PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\EventSubscriber\PayPalRefundEventSubscriber: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\EventSubscriber\PayPalRefundEventSubscriber' + arguments: + - '@ps_checkout.module' + - '@ps_checkout.cache.paypal.order' + - '@PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider' + + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\EventSubscriber\PaymentMethodTokenEventSubscriber: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\EventSubscriber\PaymentMethodTokenEventSubscriber' + arguments: + - '@ps_checkout.module' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' - ps_checkout.logger.configuration: - class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration' + ps_checkout.event.dispatcher.symfony: + class: 'Symfony\Component\EventDispatcher\EventDispatcherInterface' + factory: [ '@PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherFactory', "create" ] + arguments: + - [ + '@PrestaShop\Module\PrestashopCheckout\Checkout\EventSubscriber\CheckoutEventSubscriber', + '@PrestaShop\Module\PrestashopCheckout\Order\EventSubscriber\OrderEventSubscriber', + '@PrestaShop\Module\PrestashopCheckout\PayPal\Order\EventSubscriber\PayPalOrderEventSubscriber', + '@PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\EventSubscriber\PayPalCaptureEventSubscriber', + '@PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\EventSubscriber\PayPalRefundEventSubscriber', + '@PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\EventSubscriber\PaymentMethodTokenEventSubscriber'] + + PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter: + class: 'PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' public: true arguments: - - "@ps_checkout.configuration" + - "@ps_checkout.event.dispatcher.symfony" - ps_checkout.logger.handler.factory: - class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerHandlerFactory' + PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext: + class: 'PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + public: true + + PrestaShop\Module\PrestashopCheckout\Context\ContextStateManager: + class: 'PrestaShop\Module\PrestashopCheckout\Context\ContextStateManager' + public: true + + PrestaShop\Module\PrestashopCheckout\ShopContext: + class: 'PrestaShop\Module\PrestashopCheckout\ShopContext' public: true arguments: - - '@=service("ps_checkout.logger.directory").getPath()' - - '@=service("ps_checkout.logger.filename").get()' - - '@=service("ps_checkout.logger.configuration").getMaxFiles()' - - '@=service("ps_checkout.logger.configuration").getLevel()' + - '@PrestaShop\Module\PrestashopCheckout\Environment\Env' - ps_checkout.logger.handler: - class: 'Monolog\Handler\HandlerInterface' + PrestaShop\Module\PrestashopCheckout\Shop\ShopProvider: + class: 'PrestaShop\Module\PrestashopCheckout\Shop\ShopProvider' public: true - factory: ["@ps_checkout.logger.handler.factory", "build"] - ps_checkout.logger.factory: - class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerFactory' + PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfigurationOptionsResolver: + class: 'PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfigurationOptionsResolver' public: true arguments: - - '@=service("ps_checkout.module").name' - - "@ps_checkout.logger.handler" + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\Shop\\ShopProvider").getIdentifier()' - ps_checkout.logger: - class: 'Psr\Log\LoggerInterface' + PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration: + class: 'PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' public: true - factory: ["@ps_checkout.logger.factory", "build"] arguments: - - "@ps_checkout.logger.directory" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfigurationOptionsResolver' - ps_checkout.paypal.configuration: + PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' public: true arguments: - - "@ps_checkout.configuration" - - "@ps_checkout.repository.paypal.code" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository' - ps_checkout.express_checkout.configuration: + PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration: class: 'PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.pay_later.configuration: + PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.sdk.paypal.configurationbuilder: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Sdk\PayPalSdkConfigurationBuilder' + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfiguration: + class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfiguration' public: true arguments: - - "@ps_checkout.paypal.configuration" - - "@ps_checkout.pay_later.configuration" - - "@ps_checkout.funding_source.configuration.repository" - - "@ps_checkout.express_checkout.configuration" - - '@ps_checkout.context.shop' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository' - ps_checkout.repository.prestashop.account: - class: 'PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository' + PrestaShop\Module\PrestashopCheckout\PayPal\Sdk\PayPalSdkConfigurationBuilder: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Sdk\PayPalSdkConfigurationBuilder' public: true arguments: - - "@ps_checkout.configuration" - - "@ps_accounts.facade" - - ps_checkout.store.module.paypal: + - '@ps_checkout.module' + - '@PrestaShop\Module\PrestashopCheckout\Environment\Env' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository' + - '@PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@ps_checkout.logger' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceEligibilityConstraint' + + PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\PaypalModule: class: 'PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\PaypalModule' public: true arguments: - - "@ps_checkout.paypal.configuration" + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' - ps_checkout.store.module.configuration: + PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ConfigurationModule: class: 'PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ConfigurationModule' public: true arguments: - - "@ps_checkout.pay_later.configuration" - - "@ps_checkout.express_checkout.configuration" - - "@ps_checkout.paypal.configuration" - - "@ps_checkout.funding_source.provider" + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider' - "@ps_checkout.module" - ps_checkout.builder.module_link: + PrestaShop\Module\PrestashopCheckout\Builder\ModuleLink\ModuleLinkBuilder: class: 'PrestaShop\Module\PrestashopCheckout\Builder\ModuleLink\ModuleLinkBuilder' public: true - ps_checkout.step.live: + PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\LiveStep: class: 'PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\LiveStep' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.step.value: + PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\ValueBanner: class: 'PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\ValueBanner' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.translations.translations: + PrestaShop\Module\PrestashopCheckout\Translations\Translations: class: 'PrestaShop\Module\PrestashopCheckout\Translations\Translations' public: true arguments: - "@ps_checkout.module" - ps_checkout.store.module.context: + PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ContextModule: class: 'PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ContextModule' public: true arguments: - '@=service("ps_checkout.module").name' - '@=service("ps_checkout.module").module_key' - - "@ps_checkout.context.prestashop" - - "@ps_checkout.paypal.configuration" - - "@ps_checkout.step.live" - - "@ps_checkout.step.value" - - "@ps_checkout.translations.translations" - - "@ps_checkout.context.shop" - - "@ps_checkout.shop.provider" - - "@ps_checkout.builder.module_link" - - "@ps_checkout.repository.prestashop.account" - - ps_checkout.adapter.language: + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\LiveStep' + - '@PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\ValueBanner' + - '@PrestaShop\Module\PrestashopCheckout\Translations\Translations' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Shop\ShopProvider' + - '@PrestaShop\Module\PrestashopCheckout\Builder\ModuleLink\ModuleLinkBuilder' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository' + + PrestaShop\Module\PrestashopCheckout\Adapter\LanguageAdapter: class: 'PrestaShop\Module\PrestashopCheckout\Adapter\LanguageAdapter' public: true arguments: - - "@ps_checkout.context.shop" + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' - ps_checkout.store.store: + PrestaShop\Module\PrestashopCheckout\Presenter\Store\StorePresenter: class: 'PrestaShop\Module\PrestashopCheckout\Presenter\Store\StorePresenter' public: true arguments: - [ - "@ps_checkout.store.module.context", - "@ps_checkout.store.module.paypal", - "@ps_checkout.store.module.configuration", + '@PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ContextModule', + '@PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\PaypalModule', + '@PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ConfigurationModule', ] - ps_checkout.repository.pscheckoutcart: - class: 'PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' - public: true - arguments: - - "@ps_checkout.cache.pscheckoutcart" - - ps_checkout.funding_source.configuration.repository: - class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository' - public: true - arguments: - - "@ps_checkout.context.prestashop" - - ps_checkout.funding_source.configuration: - class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfiguration' - public: true - arguments: - - "@ps_checkout.funding_source.configuration.repository" - - ps_checkout.funding_source.eligibility_constraint: + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceEligibilityConstraint: class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceEligibilityConstraint' public: true - ps_checkout.funding_source.collection.builder: + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceCollectionBuilder: class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceCollectionBuilder' public: true arguments: - - "@ps_checkout.funding_source.configuration" - - "@ps_checkout.funding_source.eligibility_constraint" + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceEligibilityConstraint' - ps_checkout.funding_source.translation: + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider: class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider' public: true arguments: - "@ps_checkout.module" - ps_checkout.repository.country: - class: 'PrestaShop\Module\PrestashopCheckout\Repository\CountryRepository' - public: true - - ps_checkout.funding_source.presenter: + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourcePresenter: class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourcePresenter' public: true arguments: - - "@ps_checkout.funding_source.translation" - - "@ps_checkout.repository.country" + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider' + - '@PrestaShop\Module\PrestashopCheckout\Repository\CountryRepository' + - '@PrestaShop\Module\PrestashopCheckout\Provider\PaymentMethodLogoProvider' - ps_checkout.funding_source.collection: + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceCollection: class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceCollection' public: true arguments: - - '@=service("ps_checkout.funding_source.collection.builder").create()' + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\FundingSource\\FundingSourceCollectionBuilder").create()' - ps_checkout.funding_source.provider: + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider: class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider' public: true arguments: - - "@ps_checkout.funding_source.collection.builder" - - "@ps_checkout.funding_source.presenter" + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceCollectionBuilder' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourcePresenter' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' ps_checkout.repository.paypal.code: class: 'PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository' public: true - ps_checkout.env_loader: - class: 'PrestaShop\Module\PrestashopCheckout\Environment\EnvLoader' - public: true - - ps_checkout.validator.merchant: + PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator: class: 'PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator' public: true arguments: - - "@ps_checkout.paypal.configuration" - - "@ps_checkout.repository.prestashop.account" - - "@ps_checkout.context.prestashop" + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' - ps_checkout.validator.front_controller: + PrestaShop\Module\PrestashopCheckout\Validator\FrontControllerValidator: class: 'PrestaShop\Module\PrestashopCheckout\Validator\FrontControllerValidator' public: true arguments: - - "@ps_checkout.validator.merchant" - - "@ps_checkout.express_checkout.configuration" - - "@ps_checkout.pay_later.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator' + - '@PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration' - ps_checkout.validator.batch_configuration: + PrestaShop\Module\PrestashopCheckout\Validator\BatchConfigurationValidator: class: 'PrestaShop\Module\PrestashopCheckout\Validator\BatchConfigurationValidator' public: true - ps_checkout.cache.directory: - class: 'PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider' - public: true - arguments: - - !php/const _PS_VERSION_ - - !php/const _PS_ROOT_DIR_ - - !php/const _PS_MODE_DEV_ - - ps_checkout.cache.array.paypal.order: - class: 'Symfony\Component\Cache\Simple\ArrayCache' - - ps_checkout.cache.filesystem.paypal.order: - class: 'Symfony\Component\Cache\Simple\FilesystemCache' - arguments: - - "paypal-orders" - - 3600 - - '@=service("ps_checkout.cache.directory").getPath()' - - ps_checkout.cache.paypal.order: - class: 'Symfony\Component\Cache\Simple\ChainCache' - public: true - arguments: - - [ - "@ps_checkout.cache.array.paypal.order", - "@ps_checkout.cache.filesystem.paypal.order", - ] - - ps_checkout.cache.array.paypal.capture: - class: 'Symfony\Component\Cache\Simple\ArrayCache' - - ps_checkout.cache.filesystem.paypal.capture: - class: 'Symfony\Component\Cache\Simple\FilesystemCache' - arguments: - - "paypal-capture" - - 3600 - - '@=service("ps_checkout.cache.directory").getPath()' - - ps_checkout.cache.paypal.capture: - class: 'Symfony\Component\Cache\Simple\ChainCache' - public: true - arguments: - - [ - "@ps_checkout.cache.array.paypal.capture", - "@ps_checkout.cache.filesystem.paypal.capture", - ] - - ps_checkout.cache.pscheckoutcart: - class: 'Symfony\Component\Cache\Simple\ArrayCache' - public: true - - ps_checkout.cache.order: - class: 'Symfony\Component\Cache\Simple\ArrayCache' - public: true - - ps_checkout.paypal.provider.order: + PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider' public: true arguments: - "@ps_checkout.cache.paypal.order" - ps_checkout.prestashop.router: + PrestaShop\Module\PrestashopCheckout\Routing\Router: class: 'PrestaShop\Module\PrestashopCheckout\Routing\Router' public: true - ps_checkout.paypal.order.translations: + PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderTranslationProvider: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderTranslationProvider' public: true arguments: - - '@ps_checkout.translations.translations' - - '@ps_checkout.funding_source.translation' - - ps_checkout.paypal.order.presenter: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder' - public: true - arguments: - - '@ps_checkout.repository.pscheckoutcart' - - '@ps_checkout.paypal.provider.order' - - '@ps_checkout.prestashop.router' - - '@ps_checkout.paypal.order.translations' - - '@ps_checkout.context.shop' + - '@PrestaShop\Module\PrestashopCheckout\Translations\Translations' + - '@PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider' - ps_checkout.paypal.builder.view_order_summary: + PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder' public: true arguments: - - '@ps_checkout.repository.pscheckoutcart' - - '@ps_checkout.paypal.provider.order' - - '@ps_checkout.prestashop.router' - - '@ps_checkout.paypal.order.translations' - - '@ps_checkout.context.shop' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider' + - '@PrestaShop\Module\PrestashopCheckout\Routing\Router' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderTranslationProvider' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' - ps_checkout.webhook.service.secret_token: + PrestaShop\Module\PrestashopCheckout\Webhook\WebhookSecretTokenService: class: 'PrestaShop\Module\PrestashopCheckout\Webhook\WebhookSecretTokenService' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.webhook.handler.event.configuration_updated: + PrestaShop\Module\PrestashopCheckout\Webhook\WebhookEventConfigurationUpdatedHandler: class: 'PrestaShop\Module\PrestashopCheckout\Webhook\WebhookEventConfigurationUpdatedHandler' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.order.service.check_order_amount: + PrestaShop\Module\PrestashopCheckout\Order\Service\CheckOrderAmount: class: 'PrestaShop\Module\PrestashopCheckout\Order\Service\CheckOrderAmount' public: true - ps_checkout.order.state.service.order_state_mapper: + PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper: class: 'PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper' public: true arguments: - - "@ps_checkout.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.paypal.order.service.paypal_order_status: + PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderStatus: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderStatus' public: true - ps_checkout.paypal.order.service.check_transition_paypal_order_status: + PrestaShop\Module\PrestashopCheckout\PayPal\Order\CheckTransitionPayPalOrderStatusService: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CheckTransitionPayPalOrderStatusService' public: true - ps_checkout.webhook.handler: + PrestaShop\Module\PrestashopCheckout\Webhook\WebhookHandler: class: 'PrestaShop\Module\PrestashopCheckout\Webhook\WebhookHandler' public: true arguments: - - "@ps_checkout.webhook.service.secret_token" - - ["@ps_checkout.webhook.handler.event.configuration_updated"] + - '@PrestaShop\Module\PrestashopCheckout\Webhook\WebhookSecretTokenService' + - ['@PrestaShop\Module\PrestashopCheckout\Webhook\WebhookEventConfigurationUpdatedHandler'] - ps_checkout.configuration.batch_processor: + PrestaShop\Module\PrestashopCheckout\Configuration\BatchConfigurationProcessor: class: 'PrestaShop\Module\PrestashopCheckout\Configuration\BatchConfigurationProcessor' public: true arguments: - - '@ps_checkout.configuration' - - ps_accounts.installer: - class: 'PrestaShop\PsAccountsInstaller\Installer\Installer' - public: true - arguments: - - "4.0.0" - - ps_accounts.facade: - class: 'PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts' - public: true - arguments: - - "@ps_accounts.installer" - - ps_checkout.tactician.bus: - class: 'League\Tactician\CommandBus' - factory: ["@ps_checkout.tactician.bus.factory", "create"] - - ps_checkout.bus.command: - class: 'PrestaShop\Module\PrestashopCheckout\CommandBus\TacticianCommandBusAdapter' - public: true - arguments: - - "@ps_checkout.tactician.bus" + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' - ps_checkout.tactician.bus.factory: - class: 'PrestaShop\Module\PrestashopCheckout\CommandBus\TacticianCommandBusFactory' + PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\CheckTransitionPayPalCaptureStatusService: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\CheckTransitionPayPalCaptureStatusService' public: true - arguments: - - "@ps_checkout.module" - - "@ps_checkout.logger" - - - PrestaShop\Module\PrestashopCheckout\Order\Command\AddOrderPaymentCommand: "ps_checkout.command.handler.order.add_order_payment" - PrestaShop\Module\PrestashopCheckout\Order\Command\CreateOrderCommand: "ps_checkout.command.handler.order.create_order" - PrestaShop\Module\PrestashopCheckout\Order\Command\UpdateOrderStatusCommand: "ps_checkout.command.handler.order.update_order_status" - PrestaShop\Module\PrestashopCheckout\Order\Matrice\Command\UpdateOrderMatriceCommand: "ps_checkout.command.handler.order.matrice.update_order_matrice" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CreatePayPalOrderCommand: "ps_checkout.command.handler.paypal.order.create_paypal_order" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\UpdatePayPalOrderCommand: "ps_checkout.command.handler.paypal.order.update_paypal_order" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CapturePayPalOrderCommand: "ps_checkout.command.handler.paypal.order.capture_paypal_order" - PrestaShop\Module\PrestashopCheckout\Checkout\Command\CancelCheckoutCommand: "ps_checkout.command.handler.checkout.cancel_checkout" - PrestaShop\Module\PrestashopCheckout\Checkout\Command\SaveCheckoutCommand: "ps_checkout.command.handler.checkout.save_checkout" - PrestaShop\Module\PrestashopCheckout\Checkout\Command\SavePayPalOrderStatusCommand: "ps_checkout.command.handler.checkout.save_paypal_order_status" - PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentCompletedQuery: "ps_checkout.query.handler.order.get_order_for_payment_completed" - PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentDeniedQuery: "ps_checkout.query.handler.order.get_order_for_payment_denied" - PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentPendingQuery: "ps_checkout.query.handler.order.get_order_for_payment_pending" - PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQuery: "ps_checkout.query.handler.order.get_order_for_payment_refunded" - PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentReversedQuery: "ps_checkout.query.handler.order.get_order_for_payment_reversed" - PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQuery: "ps_checkout.query.handler.order.get_order_for_approval_reversed" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCartIdQuery: "ps_checkout.query.handler.paypal.order.get_paypal_order_for_cart_id" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetCurrentPayPalOrderStatusQuery: "ps_checkout.query.handler.paypal.order.get_current_paypal_order_status" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCheckoutCompletedQuery: "ps_checkout.query.handler.paypal.order.get_paypal_order_for_checkout_completed" - PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForOrderConfirmationQuery: "ps_checkout.query.handler.paypal.order.get_paypal_order_for_order_confirmation" - PrestaShop\Module\PrestashopCheckout\Checkout\Command\UpdatePaymentMethodSelectedCommand: "ps_checkout.query.handler.checkout.update_payment_method_selected" - PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Command\RefundPayPalCaptureCommand: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\CommandHandler\RefundPayPalCaptureCommandHandler' - ps_checkout.event.dispatcher.factory: - class: 'PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherFactory' + PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker: + class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker' public: true arguments: - "@ps_checkout.logger" - - "@ps_checkout.logger.configuration" - ps_checkout.event.subscriber.checkout: - class: 'PrestaShop\Module\PrestashopCheckout\Checkout\EventSubscriber\CheckoutEventSubscriber' - public: true - arguments: - - "@ps_checkout.module" - - ps_checkout.event.subscriber.order: - class: 'PrestaShop\Module\PrestashopCheckout\Order\EventSubscriber\OrderEventSubscriber' + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\PaymentMethodTokenService: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\PaymentMethodTokenService' public: true arguments: - - "@ps_checkout.module" - - "@ps_checkout.repository.pscheckoutcart" + - '@?' + - '@PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' - ps_checkout.event.subscriber.paypal.order: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\EventSubscriber\PayPalOrderEventSubscriber' + PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\OAuthService: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\OAuthService' public: true arguments: - - "@ps_checkout.module" - - "@ps_checkout.repository.pscheckoutcart" - - "@ps_checkout.cache.paypal.order" - - "@ps_checkout.checkout.checker" - - "@ps_checkout.paypal.order.service.check_transition_paypal_order_status" - - "@ps_checkout.order.state.service.order_state_mapper" + - '@PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient' - ps_checkout.event.subscriber.paypal.capture: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\EventSubscriber\PayPalCaptureEventSubscriber' + PrestaShop\Module\PrestashopCheckout\Provider\PaymentMethodLogoProvider: + class: 'PrestaShop\Module\PrestashopCheckout\Provider\PaymentMethodLogoProvider' public: true - arguments: - - "@ps_checkout.module" - - "@ps_checkout.order.service.check_order_amount" - - "@ps_checkout.cache.paypal.capture" - - "@ps_checkout.cache.paypal.order" - - "@ps_checkout.order.state.service.order_state_mapper" - - PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\EventSubscriber\PayPalRefundEventSubscriber: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\EventSubscriber\PayPalRefundEventSubscriber' arguments: - '@ps_checkout.module' - - '@ps_checkout.order.service.check_order_amount' - - '@ps_checkout.cache.paypal.capture' - - '@ps_checkout.cache.paypal.order' - - '@ps_checkout.order.state.service.order_state_mapper' - - '@ps_checkout.paypal.provider.order' - - ps_checkout.event.dispatcher.symfony: - class: 'Symfony\Component\EventDispatcher\EventDispatcherInterface' - factory: ["@ps_checkout.event.dispatcher.factory", "create"] - arguments: - - [ - "@ps_checkout.event.subscriber.checkout", - "@ps_checkout.event.subscriber.order", - "@ps_checkout.event.subscriber.paypal.order", - "@ps_checkout.event.subscriber.paypal.capture", - '@PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\EventSubscriber\PayPalRefundEventSubscriber' - ] - - ps_checkout.event.dispatcher: - class: 'PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter' - public: true - arguments: - - "@ps_checkout.event.dispatcher.symfony" - - ps_checkout.command.handler.order.add_order_payment: - class: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\AddOrderPaymentCommandHandler' - public: true - arguments: - - "@ps_checkout.event.dispatcher" - - "@ps_checkout.funding_source.translation" - - "@ps_checkout.paypal.configuration" - - ps_checkout.command.handler.order.create_order: - class: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\CreateOrderCommandHandler' - public: true - arguments: - - "@ps_checkout.context.state.manager" - - "@ps_checkout.event.dispatcher" - - "@ps_checkout.repository.pscheckoutcart" - - "@ps_checkout.order.state.service.order_state_mapper" - - "@ps_checkout.module" - - "@ps_checkout.order.service.check_order_amount" - - ps_checkout.command.handler.order.update_order_status: - class: 'PrestaShop\Module\PrestashopCheckout\Order\CommandHandler\UpdateOrderStatusCommandHandler' - public: true - arguments: - - "@ps_checkout.event.dispatcher" - - ps_checkout.command.handler.order.matrice.update_order_matrice: - class: 'PrestaShop\Module\PrestashopCheckout\Order\Matrice\CommandHandler\UpdateOrderMatriceCommandHandler' - public: true - arguments: - - "@ps_checkout.event.dispatcher" - - ps_checkout.command.handler.paypal.order.create_paypal_order: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CreatePayPalOrderCommandHandler' - public: true - arguments: - - "@ps_checkout.http.client.checkout" - - "@ps_checkout.event.dispatcher" - - "@ps_checkout.context.shop" - - ps_checkout.command.handler.paypal.order.update_paypal_order: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\UpdatePayPalOrderCommandHandler' - public: true - arguments: - - "@ps_checkout.http.client.checkout" - - "@ps_checkout.event.dispatcher" - - "@ps_checkout.context.shop" - - ps_checkout.command.handler.paypal.order.capture_paypal_order: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler\CapturePayPalOrderCommandHandler' - public: true - arguments: - - "@ps_checkout.http.client.checkout" - - "@ps_checkout.event.dispatcher" - - "@ps_checkout.cache.paypal.order" - - ps_checkout.query.handler.paypal.order.get_current_paypal_order_status: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetCurrentPayPalOrderStatusQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.order.get_order_for_payment_completed: - class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentCompletedQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.order.get_order_for_payment_denied: - class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentDeniedQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.order.get_order_for_payment_pending: - class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentPendingQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.order.get_order_for_payment_refunded: - class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentRefundedQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.order.get_order_for_payment_reversed: - class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentReversedQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.order.get_order_for_approval_reversed: - class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForApprovalReversedQueryHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.paypal.order.get_paypal_order_for_cart_id: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCartIdQueryHandler' - public: true - arguments: - - '@ps_checkout.cache.paypal.order' - - '@ps_checkout.repository.pscheckoutcart' - - ps_checkout.query.handler.paypal.order.get_paypal_order_for_checkout_completed: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCheckoutCompletedQueryHandler' - public: true - arguments: - - "@ps_checkout.cache.paypal.order" - - ps_checkout.query.handler.paypal.order.get_paypal_order_for_order_confirmation: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForOrderConfirmationQueryHandler' - public: true - arguments: - - "@ps_checkout.cache.paypal.order" - - ps_checkout.command.handler.checkout.save_checkout: - class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SaveCheckoutCommandHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.command.handler.checkout.cancel_checkout: - class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\CancelCheckoutCommandHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.command.handler.checkout.save_paypal_order_status: - class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\SavePayPalOrderStatusCommandHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - ps_checkout.query.handler.checkout.update_payment_method_selected: - class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CommandHandler\UpdatePaymentMethodSelectedCommandHandler' - public: true - arguments: - - "@ps_checkout.repository.pscheckoutcart" - - PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\CommandHandler\RefundPayPalCaptureCommandHandler: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\CommandHandler\RefundPayPalCaptureCommandHandler' - public: true - arguments: - - '@ps_checkout.http.client.checkout' - - '@ps_checkout.paypal.configuration' - - '@ps_checkout.configuration' - - '@ps_checkout.context.prestashop' - - '@ps_checkout.event.dispatcher' - - ps_checkout.paypal.capture.service.check_transition_paypal_capture_status: - class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\CheckTransitionPayPalCaptureStatusService' - public: true - - ps_checkout.checkout.checker: - class: 'PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker' - public: true - arguments: - - "@ps_checkout.logger" - - ps_checkout.environment.payment: - class: 'PrestaShop\Module\PrestashopCheckout\Environment\PaymentEnv' - public: true - - ps_checkout.http.client.configuration: - class: 'PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClientConfigurationBuilder' - public: true - arguments: - - "@ps_checkout.environment.payment" - - "@ps_checkout.prestashop.router" - - "@ps_checkout.context.shop" - - "@ps_checkout.repository.prestashop.account" - - "@ps_checkout.context.prestashop" - - "@ps_checkout.logger.configuration" - - "@ps_checkout.logger" - - ps_checkout.http.client.factory: - class: 'PrestaShop\Module\PrestashopCheckout\Http\HttpClientFactory' - public: true - ps_checkout.http.client: - class: 'PrestaShop\Module\PrestashopCheckout\Http\HttpClientInterface' + PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Builder\GooglePayTransactionInfoBuilder: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Builder\GooglePayTransactionInfoBuilder' public: true - factory: ["@ps_checkout.http.client.factory", "create"] arguments: - - "@ps_checkout.http.client.configuration" + - '@PrestaShop\Module\PrestashopCheckout\Translations\Translations' - ps_checkout.http.client.checkout: - class: 'PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient' + PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Builder\ApplePayPaymentRequestBuilder: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Builder\ApplePayPaymentRequestBuilder' public: true arguments: - - "@ps_checkout.http.client" + - '@PrestaShop\Module\PrestashopCheckout\Translations\Translations' diff --git a/src/Api/index.php b/config/front/index.php old mode 100755 new mode 100644 similarity index 100% rename from src/Api/index.php rename to config/front/index.php diff --git a/config/http-clients.yml b/config/http-clients.yml new file mode 100644 index 000000000..2ff7954f2 --- /dev/null +++ b/config/http-clients.yml @@ -0,0 +1,47 @@ +services: + PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient: + class: 'PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient' + public: true + arguments: + - "@ps_checkout.http.client" + + PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient: + class: 'PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Builder\Configuration\CheckoutClientConfigurationBuilder' + + PrestaShop\Module\PrestashopCheckout\Builder\Configuration\MaaslandHttpClientConfigurationBuilder: + class: 'PrestaShop\Module\PrestashopCheckout\Builder\Configuration\MaaslandHttpClientConfigurationBuilder' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Environment\Env' + - '@PrestaShop\Module\PrestashopCheckout\Routing\Router' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration' + - "@ps_checkout.logger" + + PrestaShop\Module\PrestashopCheckout\Http\HttpClientFactory: + class: 'PrestaShop\Module\PrestashopCheckout\Http\HttpClientFactory' + public: true + + ps_checkout.http.client: + class: 'PrestaShop\Module\PrestashopCheckout\Http\HttpClientInterface' + public: true + factory: ['@PrestaShop\Module\PrestashopCheckout\Http\HttpClientFactory', "create"] + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Builder\Configuration\MaaslandHttpClientConfigurationBuilder' + + PrestaShop\Module\PrestashopCheckout\Builder\Configuration\CheckoutClientConfigurationBuilder: + class: 'PrestaShop\Module\PrestashopCheckout\Builder\Configuration\CheckoutClientConfigurationBuilder' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Environment\Env' + - '@PrestaShop\Module\PrestashopCheckout\Routing\Router' + - '@PrestaShop\Module\PrestashopCheckout\ShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository' + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + - '@PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration' + - "@ps_checkout.logger" diff --git a/_dev/js/front/src/utils/extra/types/container-aware.typedef.doc.js b/config/index.php similarity index 58% rename from _dev/js/front/src/utils/extra/types/container-aware.typedef.doc.js rename to config/index.php index 3312c209c..296d682e8 100644 --- a/_dev/js/front/src/utils/extra/types/container-aware.typedef.doc.js +++ b/config/index.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); -/** - * This file exists only for documentative purposes - */ - -/* eslint-disable no-unused-vars */ -import Bottle from 'bottlejs'; +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); -/** - * @typedef ContainerAwareClass - * - * @property {Bottle} bottle - * @property {Bottle.container} container - */ +header('Location: ../'); +exit; diff --git a/config/logger.yml b/config/logger.yml new file mode 100644 index 000000000..839d5a3f8 --- /dev/null +++ b/config/logger.yml @@ -0,0 +1,48 @@ +services: + PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory: + class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory' + public: true + arguments: + - !php/const _PS_VERSION_ + - !php/const _PS_ROOT_DIR_ + + PrestaShop\Module\PrestashopCheckout\Logger\LoggerFilename: + class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerFilename' + public: true + arguments: + - '@=service("ps_checkout.module").name' + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\Shop\\ShopProvider").getIdentifier()' + + PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration: + class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' + + PrestaShop\Module\PrestashopCheckout\Logger\LoggerHandlerFactory: + class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerHandlerFactory' + public: true + arguments: + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\Logger\\LoggerDirectory").getPath()' + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\Logger\\LoggerFilename").get()' + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\Logger\\LoggerConfiguration").getMaxFiles()' + - '@=service("PrestaShop\\Module\\PrestashopCheckout\\Logger\\LoggerConfiguration").getLevel()' + + ps_checkout.logger.handler: + class: 'Monolog\Handler\HandlerInterface' + public: true + factory: ['@PrestaShop\Module\PrestashopCheckout\Logger\LoggerHandlerFactory', "build"] + + PrestaShop\Module\PrestashopCheckout\Logger\LoggerFactory: + class: 'PrestaShop\Module\PrestashopCheckout\Logger\LoggerFactory' + public: true + arguments: + - '@=service("ps_checkout.module").name' + - "@ps_checkout.logger.handler" + + ps_checkout.logger: + class: 'Psr\Log\LoggerInterface' + public: true + factory: ['@PrestaShop\Module\PrestashopCheckout\Logger\LoggerFactory', "build"] + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory' diff --git a/config/query-handlers.yml b/config/query-handlers.yml new file mode 100644 index 000000000..1e3e05bf4 --- /dev/null +++ b/config/query-handlers.yml @@ -0,0 +1,87 @@ +services: + PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetCurrentPayPalOrderStatusQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetCurrentPayPalOrderStatusQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentCompletedQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentCompletedQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentDeniedQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentDeniedQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentPendingQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentPendingQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentRefundedQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentRefundedQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentReversedQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentReversedQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForApprovalReversedQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForApprovalReversedQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCartIdQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCartIdQueryHandler' + public: true + arguments: + - '@ps_checkout.cache.paypal.order' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCheckoutCompletedQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForCheckoutCompletedQueryHandler' + public: true + arguments: + - "@ps_checkout.cache.paypal.order" + + PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForOrderConfirmationQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Order\QueryHandler\GetPayPalOrderForOrderConfirmationQueryHandler' + public: true + arguments: + - "@ps_checkout.cache.paypal.order" + + PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query\GetCustomerPaymentTokensQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query\GetCustomerPaymentTokensQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' + + PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\OAuthService' + - '@PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository' + - '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration' + + PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query\GetGooglePayTransactionInfoQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query\GetGooglePayTransactionInfoQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Builder\GooglePayTransactionInfoBuilder' + + PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query\GetApplePayPaymentRequestQueryHandler: + class: 'PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query\GetApplePayPaymentRequestQueryHandler' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Builder\ApplePayPaymentRequestBuilder' diff --git a/config/repository.yml b/config/repository.yml new file mode 100644 index 000000000..771e5ac60 --- /dev/null +++ b/config/repository.yml @@ -0,0 +1,45 @@ +services: + PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository' + public: true + arguments: + - "@ps_checkout.cache.pscheckoutcart" + + PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository: + class: 'PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext' + + PrestaShop\Module\PrestashopCheckout\Repository\CountryRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\CountryRepository' + public: true + + PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository' + public: true + + PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository' + public: true + arguments: + - '@PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration' + - "@ps_accounts.facade" + + PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository' + public: true + arguments: + - '@ps_checkout.db' + + PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository' + public: true + arguments: + - '@ps_checkout.db' + + PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository: + class: 'PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository' + public: true + arguments: + - '@ps_checkout.db' diff --git a/controllers/admin/AdminAjaxPrestashopCheckoutController.php b/controllers/admin/AdminAjaxPrestashopCheckoutController.php index 79c0a487a..b107e13aa 100755 --- a/controllers/admin/AdminAjaxPrestashopCheckoutController.php +++ b/controllers/admin/AdminAjaxPrestashopCheckoutController.php @@ -21,9 +21,12 @@ use Monolog\Logger; use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; use PrestaShop\Module\PrestashopCheckout\Configuration\BatchConfigurationProcessor; +use PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration; +use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; use PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration; use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository; use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory; use PrestaShop\Module\PrestashopCheckout\Logger\LoggerFactory; use PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileFinder; @@ -42,6 +45,7 @@ use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration; use PrestaShop\Module\PrestashopCheckout\Presenter\Order\OrderPresenter; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository; use PrestaShop\Module\PrestashopCheckout\Settings\RoundingSettings; use PrestaShop\Module\PrestashopCheckout\Validator\BatchConfigurationValidator; @@ -90,7 +94,7 @@ public function ajaxProcessUpdatePaymentMethodsOrder() { $paymentOptions = json_decode(Tools::getValue('paymentMethods'), true); /** @var FundingSourceConfigurationRepository $fundingSourceConfigurationRepository */ - $fundingSourceConfigurationRepository = $this->module->getService('ps_checkout.funding_source.configuration.repository'); + $fundingSourceConfigurationRepository = $this->module->getService(FundingSourceConfigurationRepository::class); foreach ($paymentOptions as $key => $paymentOption) { $paymentOption['position'] = $key + 1; @@ -106,7 +110,7 @@ public function ajaxProcessUpdatePaymentMethodsOrder() public function ajaxProcessUpdatePaymentMode() { /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->module->getService('ps_checkout.paypal.configuration'); + $paypalConfiguration = $this->module->getService(PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); $paypalConfiguration->setPaymentMode(Tools::getValue('paymentMode')); $this->ajaxDie(json_encode(true)); @@ -118,7 +122,7 @@ public function ajaxProcessUpdatePaymentMode() public function ajaxProcessLiveStepConfirmed() { /** @var LiveStep $stepLive */ - $stepLive = $this->module->getService('ps_checkout.step.live'); + $stepLive = $this->module->getService(LiveStep::class); $stepLive->confirmed(true); $this->ajaxDie(json_encode(true)); @@ -130,7 +134,7 @@ public function ajaxProcessLiveStepConfirmed() public function ajaxProcessLiveStepViewed() { /** @var LiveStep $stepLive */ - $stepLive = $this->module->getService('ps_checkout.step.live'); + $stepLive = $this->module->getService(LiveStep::class); $stepLive->viewed(true); $this->ajaxDie(json_encode(true)); @@ -142,7 +146,7 @@ public function ajaxProcessLiveStepViewed() public function ajaxProcessValueBannerClosed() { /** @var ValueBanner $valueBanner */ - $valueBanner = $this->module->getService('ps_checkout.step.value'); + $valueBanner = $this->module->getService(ValueBanner::class); $valueBanner->closed(true); $this->ajaxDie(json_encode(true)); @@ -157,7 +161,7 @@ public function ajaxProcessValueBannerClosed() public function ajaxProcessEditRoundingSettings() { /** @var PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->module->getService('ps_checkout.paypal.configuration'); + $paypalConfiguration = $this->module->getService(PayPalConfiguration::class); $paypalConfiguration->setRoundType(RoundingSettings::ROUND_ON_EACH_ITEM); $paypalConfiguration->setPriceRoundMode(RoundingSettings::ROUND_UP_AWAY_FROM_ZERO); @@ -185,7 +189,7 @@ public function ajaxProcessTogglePaymentOptionAvailability() $paymentOption = json_decode(Tools::getValue('paymentOption'), true); /** @var FundingSourceConfigurationRepository $fundingSourceConfigurationRepository */ - $fundingSourceConfigurationRepository = $this->module->getService('ps_checkout.funding_source.configuration.repository'); + $fundingSourceConfigurationRepository = $this->module->getService(FundingSourceConfigurationRepository::class); $fundingSourceConfigurationRepository->save($paymentOption); @@ -198,7 +202,7 @@ public function ajaxProcessTogglePaymentOptionAvailability() public function ajaxProcessUpdateCreditCardFields() { /** @var PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->module->getService('ps_checkout.paypal.configuration'); + $paypalConfiguration = $this->module->getService(PayPalConfiguration::class); $paypalConfiguration->setCardPaymentEnabled((bool) Tools::getValue('hostedFieldsEnabled')); @@ -211,10 +215,10 @@ public function ajaxProcessUpdateCreditCardFields() public function ajaxProcessToggleECOrderPage() { /** @var ExpressCheckoutConfiguration $ecConfiguration */ - $ecConfiguration = $this->module->getService('ps_checkout.express_checkout.configuration'); + $ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class); $ecConfiguration->setOrderPage((bool) Tools::getValue('status')); - (new PrestaShop\Module\PrestashopCheckout\Api\Payment\Shop(Context::getContext()->link))->updateSettings(); + $this->updateExpressCheckoutSettings(); $this->ajaxDie(json_encode(true)); } @@ -225,10 +229,10 @@ public function ajaxProcessToggleECOrderPage() public function ajaxProcessToggleECCheckoutPage() { /** @var ExpressCheckoutConfiguration $ecConfiguration */ - $ecConfiguration = $this->module->getService('ps_checkout.express_checkout.configuration'); + $ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class); $ecConfiguration->setCheckoutPage(Tools::getValue('status') ? true : false); - (new PrestaShop\Module\PrestashopCheckout\Api\Payment\Shop(Context::getContext()->link))->updateSettings(); + $this->updateExpressCheckoutSettings(); $this->ajaxDie(json_encode(true)); } @@ -239,14 +243,38 @@ public function ajaxProcessToggleECCheckoutPage() public function ajaxProcessToggleECProductPage() { /** @var ExpressCheckoutConfiguration $ecConfiguration */ - $ecConfiguration = $this->module->getService('ps_checkout.express_checkout.configuration'); + $ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class); $ecConfiguration->setProductPage(Tools::getValue('status') ? true : false); - (new PrestaShop\Module\PrestashopCheckout\Api\Payment\Shop(Context::getContext()->link))->updateSettings(); + $this->updateExpressCheckoutSettings(); $this->ajaxDie(json_encode(true)); } + /** + * @return void + * + * @throws PayPalException + */ + private function updateExpressCheckoutSettings() + { + /** @var PrestaShopConfiguration $configuration */ + $configuration = $this->module->getService(PrestaShopConfiguration::class); + /** @var ExpressCheckoutConfiguration $ecConfiguration */ + $ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class); + /** @var MaaslandHttpClient $maaslandHttpClient */ + $maaslandHttpClient = $this->module->getService(MaaslandHttpClient::class); + + $maaslandHttpClient->updateSettings([ + 'settings' => [ + 'cb' => (bool) $configuration->get('PS_CHECKOUT_CARD_PAYMENT_ENABLED'), + 'express_in_product' => (bool) $ecConfiguration->isProductPageEnabled(), + 'express_in_cart' => (bool) $ecConfiguration->isOrderPageEnabled(), + 'express_in_checkout' => (bool) $ecConfiguration->isCheckoutPageEnabled(), + ], + ]); + } + /** * AJAX: Toggle pay later message on order page */ @@ -383,7 +411,7 @@ public function ajaxProcessFetchOrder() } /** @var PayPalConfiguration $configurationPayPal */ - $configurationPayPal = $this->module->getService('ps_checkout.paypal.configuration'); + $configurationPayPal = $this->module->getService(PayPalConfiguration::class); if ($configurationPayPal->getPaymentMode() !== $psCheckoutCart->getEnvironment()) { http_response_code(422); @@ -401,7 +429,7 @@ public function ajaxProcessFetchOrder() } /** @var PayPalOrderProvider $paypalOrderProvider */ - $paypalOrderProvider = $this->module->getService('ps_checkout.paypal.provider.order'); + $paypalOrderProvider = $this->module->getService(PayPalOrderProvider::class); try { $paypalOrder = $paypalOrderProvider->getById($psCheckoutCart->paypal_order); @@ -414,7 +442,7 @@ public function ajaxProcessFetchOrder() } /** @var FundingSourceTranslationProvider $fundingSourceTranslationProvider */ - $fundingSourceTranslationProvider = $this->module->getService('ps_checkout.funding_source.translation'); + $fundingSourceTranslationProvider = $this->module->getService(FundingSourceTranslationProvider::class); $presenter = new OrderPresenter($this->module, $paypalOrder); $this->context->smarty->assign([ @@ -667,7 +695,7 @@ public function ajaxProcessUpdateLoggerMaxFiles() public function ajaxProcessGetLogFiles() { /** @var LoggerFileFinder $loggerFileFinder */ - $loggerFileFinder = $this->module->getService('ps_checkout.logger.file.finder'); + $loggerFileFinder = $this->module->getService(LoggerFileFinder::class); header('Content-type: application/json'); $this->ajaxDie(json_encode($loggerFileFinder->getLogFileNames())); @@ -695,9 +723,9 @@ public function ajaxProcessGetLogs() } /** @var LoggerDirectory $loggerDirectory */ - $loggerDirectory = $this->module->getService('ps_checkout.logger.directory'); + $loggerDirectory = $this->module->getService(LoggerDirectory::class); /** @var LoggerFileReader $loggerFileReader */ - $loggerFileReader = $this->module->getService('ps_checkout.logger.file.reader'); + $loggerFileReader = $this->module->getService(LoggerFileReader::class); $fileData = []; try { @@ -733,7 +761,7 @@ public function ajaxProcessGetLogs() public function ajaxProcessSavePaypalButtonConfiguration() { /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->module->getService('ps_checkout.paypal.configuration'); + $paypalConfiguration = $this->module->getService(PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); $paypalConfiguration->setButtonConfiguration(json_decode(Tools::getValue('configuration'))); $this->ajaxDie(json_encode(true)); @@ -745,7 +773,7 @@ public function ajaxProcessSavePaypalButtonConfiguration() public function ajaxProcessGetOrRefreshToken() { /** @var PsAccountRepository $psAccountRepository */ - $psAccountRepository = $this->module->getService('ps_checkout.repository.prestashop.account'); + $psAccountRepository = $this->module->getService(PsAccountRepository::class); try { $this->exitWithResponse([ @@ -818,7 +846,7 @@ public function display() private function togglePayLaterConfiguration($method) { /** @var PayPalPayLaterConfiguration $payLaterConfiguration */ - $payLaterConfiguration = $this->module->getService('ps_checkout.pay_later.configuration'); + $payLaterConfiguration = $this->module->getService(PayPalPayLaterConfiguration::class); $payLaterConfiguration->$method(Tools::getValue('status') ? true : false); $this->ajaxDie(json_encode(true)); @@ -827,7 +855,7 @@ private function togglePayLaterConfiguration($method) public function ajaxProcessUpsertSecretToken() { /** @var WebhookSecretTokenService $webhookSecretTokenService */ - $webhookSecretTokenService = $this->module->getService('ps_checkout.webhook.service.secret_token'); + $webhookSecretTokenService = $this->module->getService(WebhookSecretTokenService::class); $secret = (string) Tools::getValue('body'); @@ -910,7 +938,7 @@ public function ajaxProcessFetchConfiguration() public function ajaxProcessGetMappedOrderStates() { /** @var OrderStateMapper $orderStateMapper */ - $orderStateMapper = $this->module->getService('ps_checkout.order.state.service.order_state_mapper'); + $orderStateMapper = $this->module->getService(OrderStateMapper::class); $mappedOrderStates = []; try { @@ -936,9 +964,9 @@ public function ajaxProcessGetMappedOrderStates() public function ajaxProcessBatchSaveConfiguration() { /** @var BatchConfigurationValidator $configurationValidator */ - $configurationValidator = $this->module->getService('ps_checkout.validator.batch_configuration'); + $configurationValidator = $this->module->getService(BatchConfigurationValidator::class); /** @var BatchConfigurationProcessor $batchConfigurationProcessor */ - $batchConfigurationProcessor = $this->module->getService('ps_checkout.configuration.batch_processor'); + $batchConfigurationProcessor = $this->module->getService(BatchConfigurationProcessor::class); $configuration = json_decode(Tools::getValue('configuration'), true); try { @@ -967,6 +995,20 @@ public function ajaxProcessGetOrderStates() ]); } + public function ajaxProcessGetPaymentTokenCount() + { + /** @var PaymentTokenRepository $paymentTokenRepository */ + $paymentTokenRepository = $this->module->getService(PaymentTokenRepository::class); + + /** @var PayPalConfiguration $payPalConfiguration */ + $payPalConfiguration = $this->module->getService(PayPalConfiguration::class); + + $this->exitWithResponse([ + 'status' => true, + 'count' => $paymentTokenRepository->getCount(null, $payPalConfiguration->getMerchantId()), + ]); + } + /** * @param array $response * @@ -989,4 +1031,40 @@ private function exitWithResponse(array $response) exit; } + + public function ajaxProcessDownloadLogs() + { + $filename = Tools::getValue('file'); + + if (empty($filename) || false === Validate::isFileName($filename)) { + $this->exitWithResponse([ + 'status' => false, + 'httpCode' => 400, + 'errors' => [ + 'Filename is invalid.', + ], + ]); + } + + /** @var LoggerDirectory $loggerDirectory */ + $loggerDirectory = $this->module->getService(LoggerDirectory::class); + + $file = new SplFileObject($loggerDirectory->getPath() . $filename); + + if (false === $file->isReadable()) { + $this->exitWithResponse([ + 'status' => false, + 'httpCode' => 500, + 'errors' => [ + 'File is not readable.', + ], + ]); + } + + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="' . $filename . '.log"'); + header('Content-Length: ' . $file->getSize()); + readfile($file->getRealPath()); + exit; + } } diff --git a/controllers/front/DispatchWebHook.php b/controllers/front/DispatchWebHook.php index d998583a9..bab6c6d81 100755 --- a/controllers/front/DispatchWebHook.php +++ b/controllers/front/DispatchWebHook.php @@ -24,6 +24,7 @@ use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; use PrestaShop\Module\PrestashopCheckout\Dispatcher\OrderDispatcher; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository; use PrestaShop\Module\PrestashopCheckout\WebHookValidation; @@ -128,11 +129,12 @@ public function display() */ private function checkPSLSignature(array $bodyValues) { - $context = Context::getContext(); - $response = (new Webhook($context->link))->getShopSignature($bodyValues); + /** @var MaaslandHttpClient $maaslandHttpClient */ + $maaslandHttpClient = $this->module->getService(MaaslandHttpClient::class); + $response = $maaslandHttpClient->getShopSignature($bodyValues); // data return false if no error - if (200 === $response['httpCode'] && 'VERIFIED' === $response['body']['message']) { + if (isset($response['statusCode'], $response['message']) && 200 === $response['statusCode'] && 'VERIFIED' === $response['message']) { return true; } @@ -209,7 +211,7 @@ private function setAtributesBodyValues(array $bodyValues) private function checkExecutionPermissions() { /** @var PsAccountRepository $psAccountRepository */ - $psAccountRepository = $this->module->getService('ps_checkout.repository.prestashop.account'); + $psAccountRepository = $this->module->getService(PsAccountRepository::class); if ($this->shopId !== $psAccountRepository->getShopUuid()) { throw new PsCheckoutException('shopId wrong', PsCheckoutException::PSCHECKOUT_WEBHOOK_SHOP_ID_INVALID); diff --git a/controllers/front/ExpressCheckout.php b/controllers/front/ExpressCheckout.php index 8d8615732..ef42067a7 100644 --- a/controllers/front/ExpressCheckout.php +++ b/controllers/front/ExpressCheckout.php @@ -75,7 +75,7 @@ public function postProcess() } /** @var PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->module->getService(PsCheckoutCartRepository::class); /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartRepository->findOneByPayPalOrderId($this->payload['orderID']); @@ -271,7 +271,7 @@ private function createAddress( if ($country->contains_states) { /** @var CountryRepository $countryRepository */ - $countryRepository = $this->module->getService('ps_checkout.repository.country'); + $countryRepository = $this->module->getService(CountryRepository::class); $idState = $countryRepository->getStateId((int) $idCountry, $state); } diff --git a/controllers/front/applepay.php b/controllers/front/applepay.php new file mode 100644 index 000000000..f74fea18c --- /dev/null +++ b/controllers/front/applepay.php @@ -0,0 +1,115 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartException; +use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; +use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; +use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query\GetApplePayPaymentRequestQuery; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; + +/** + * This controller receive ajax call on customer click on a payment button + */ +class Ps_CheckoutApplepayModuleFrontController extends AbstractFrontController +{ + /** + * @var Ps_checkout + */ + public $module; + + /** + * @var CommandBusInterface + */ + private $commandBus; + + /** + * @see FrontController::postProcess() + */ + public function postProcess() + { + try { + $action = ''; + $bodyContent = file_get_contents('php://input'); + + if (!empty($bodyContent)) { + $bodyValues = json_decode($bodyContent, true); + $action = $bodyValues['action']; + } + + if (empty($action)) { + $getParam = Tools::getValue('action'); + if ($getParam === 'getDomainAssociation') { + $action = $getParam; + } + } + + $this->commandBus = $this->module->getService('ps_checkout.bus.command'); + + switch ($action) { + case 'getPaymentRequest': + $this->getPaymentRequest(); + break; + case 'getDomainAssociation': + /** + * @var PayPalConfiguration $payPalConfiguration + */ + $payPalConfiguration = $this->module->getService(PayPalConfiguration::class); + $environment = $payPalConfiguration->getPaymentMode(); + $associationFile = _PS_MODULE_DIR_ . "ps_checkout/.well-known/apple-$environment-merchantid-domain-association"; + if (file_exists($associationFile)) { + if (!headers_sent()) { + ob_end_clean(); + header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); + header('X-Robots-Tag: noindex, nofollow'); + header_remove('Last-Modified'); + header('Content-Type: text/plain', true, 200); + } + echo file_get_contents($associationFile); + exit; + } else { + $this->exitWithExceptionMessage(new Exception('File not found', 404)); + } + break; + default: + $this->exitWithExceptionMessage(new Exception('Invalid request', 400)); + } + } catch (Exception $exception) { + $this->exitWithExceptionMessage($exception); + } + } + + /** + * @return void + * + * @throws CartException + */ + private function getPaymentRequest() + { + $cartId = new CartId($this->context->cart->id); + $query = new GetApplePayPaymentRequestQuery($cartId); + $paymentRequest = $this->commandBus->handle($query); + + $this->exitWithResponse([ + 'httpCode' => 200, + 'body' => $paymentRequest->getPayload()->toArray(), + ]); + } +} diff --git a/controllers/front/cancel.php b/controllers/front/cancel.php index d0ced054e..6581a3a0b 100644 --- a/controllers/front/cancel.php +++ b/controllers/front/cancel.php @@ -70,7 +70,9 @@ public function postProcess() $isExpressCheckout = isset($bodyValues['isExpressCheckout']) && $bodyValues['isExpressCheckout']; $isHostedFields = isset($bodyValues['isHostedFields']) && $bodyValues['isHostedFields']; $reason = isset($bodyValues['reason']) ? Tools::safeOutput($bodyValues['reason']) : null; - $error = isset($bodyValues['error']) ? Tools::safeOutput($bodyValues['error']) : null; + $error = isset($bodyValues['error']) + ? Tools::safeOutput(is_string($bodyValues['error']) ? $bodyValues['error'] : json_encode($bodyValues['error'])) + : null; if ($orderId) { /** @var CommandBusInterface $commandBus */ diff --git a/controllers/front/create.php b/controllers/front/create.php index b5fadb430..be79195fd 100755 --- a/controllers/front/create.php +++ b/controllers/front/create.php @@ -19,6 +19,7 @@ * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ +use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CreatePayPalOrderCommand; @@ -47,7 +48,7 @@ public function postProcess() $bodyValues = []; $bodyContent = file_get_contents('php://input'); - if (false === empty($bodyContent)) { + if (!empty($bodyContent)) { $bodyValues = json_decode($bodyContent, true); } @@ -95,13 +96,39 @@ public function postProcess() $cartId = (int) $this->context->cart->id; + $vaultId = isset($bodyValues['vaultId']) ? $bodyValues['vaultId'] : null; + $vault = isset($bodyValues['vault']) && $bodyValues['vault']; + $favorite = isset($bodyValues['favorite']) && $bodyValues['favorite']; + $fundingSource = isset($bodyValues['fundingSource']) ? $bodyValues['fundingSource'] : 'paypal'; - $isHostedFields = isset($bodyValues['isHostedFields']) && $bodyValues['isHostedFields']; + $isCardFields = isset($bodyValues['isCardFields']) && $bodyValues['isCardFields']; $isExpressCheckout = (isset($bodyValues['isExpressCheckout']) && $bodyValues['isExpressCheckout']) || empty($this->context->cart->id_address_delivery); + if ($isExpressCheckout) { + $psCheckoutCartCollection = new PrestaShopCollection(PsCheckoutCart::class); + $psCheckoutCartCollection->where('id_cart', '=', (int) $cartId); + $psCheckoutCartCollection->where('isExpressCheckout', '=', '1'); + $psCheckoutCartCollection->where('paypal_status', 'IN', [PsCheckoutCart::STATUS_CREATED, PsCheckoutCart::STATUS_APPROVED, PsCheckoutCart::STATUS_PAYER_ACTION_REQUIRED]); + $psCheckoutCartCollection->where('date_upd', '>', date('Y-m-d H:i:s', strtotime('-1 hour'))); + $psCheckoutCartCollection->orderBy('date_upd', 'desc'); + /** @var PsCheckoutCart|false $psCheckoutCart */ + $psCheckoutCart = $psCheckoutCartCollection->getFirst(); + if ($psCheckoutCart) { + $this->exitWithResponse([ + 'status' => true, + 'httpCode' => 200, + 'body' => [ + 'orderID' => $psCheckoutCart->paypal_order, + ], + 'exceptionCode' => null, + 'exceptionMessage' => null, + ]); + } + } + /** @var CommandBusInterface $commandBus */ $commandBus = $this->module->getService('ps_checkout.bus.command'); - $commandBus->handle(new CreatePayPalOrderCommand($cartId, $fundingSource, $isHostedFields, $isExpressCheckout)); + $commandBus->handle(new CreatePayPalOrderCommand($cartId, $fundingSource, $isCardFields, $isExpressCheckout, $vaultId, $favorite, $vault)); /** @var GetPayPalOrderForCartIdQueryResult $getPayPalOrderForCartIdQueryResult */ $getPayPalOrderForCartIdQueryResult = $commandBus->handle(new GetPayPalOrderForCartIdQuery($cartId)); @@ -116,6 +143,11 @@ public function postProcess() 'exceptionCode' => null, 'exceptionMessage' => null, ]); + } catch (CartNotFoundException $exception) { + $this->exitWithResponse([ + 'httpCode' => 400, + 'body' => 'No cart found.', + ]); } catch (Exception $exception) { $this->module->getLogger()->error( 'CreateController - Exception ' . $exception->getCode(), diff --git a/controllers/front/googlepay.php b/controllers/front/googlepay.php new file mode 100644 index 000000000..7734798cc --- /dev/null +++ b/controllers/front/googlepay.php @@ -0,0 +1,77 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; +use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; +use PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query\GetGooglePayTransactionInfoQuery; + +/** + * This controller receive ajax call on customer click on a payment button + */ +class Ps_CheckoutGooglepayModuleFrontController extends AbstractFrontController +{ + /** + * @var Ps_checkout + */ + public $module; + + /** + * @var CommandBusInterface + */ + private $commandBus; + + /** + * @see FrontController::postProcess() + */ + public function postProcess() + { + try { + $bodyValues = []; + $bodyContent = file_get_contents('php://input'); + + if (!empty($bodyContent)) { + $bodyValues = json_decode($bodyContent, true); + } + + $action = $bodyValues['action']; + + $this->commandBus = $this->module->getService('ps_checkout.bus.command'); + + if ($action === 'getTransactionInfo') { + $this->getTransactionInfo($bodyValues); + } else { + $this->exitWithExceptionMessage(new Exception('Invalid request', 400)); + } + } catch (Exception $exception) { + $this->exitWithExceptionMessage($exception); + } + } + + private function getTransactionInfo(array $bodyValues) + { + $transactionInfo = $this->commandBus->handle(new GetGooglePayTransactionInfoQuery(new CartId($this->context->cart->id))); + + $this->exitWithResponse([ + 'httpCode' => 200, + 'body' => $transactionInfo->getPayload()->toArray(), + ]); + } +} diff --git a/controllers/front/payment.php b/controllers/front/payment.php new file mode 100644 index 000000000..4138907a3 --- /dev/null +++ b/controllers/front/payment.php @@ -0,0 +1,255 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; +use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\Order\Command\CreateOrderCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\Card3DSecure; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CapturePayPalOrderCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCheckoutCompletedQuery; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCheckoutCompletedQueryResult; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; + +class Ps_CheckoutPaymentModuleFrontController extends AbstractFrontController +{ + public $ssl = true; + + public $controller_type = 'front'; + + public $display_footer = false; + + public $display_header = true; + + private $orderPageUrl; + + /** + * @var PayPalOrderId + */ + private $paypalOrderId; + + /** + * @var CommandBusInterface + */ + private $commandBus; + + public function checkAccess() + { + return $this->context->customer; + } + + public function initContent() + { + $this->orderPageUrl = $this->context->link->getPageLink('order'); + parent::initContent(); + $this->setTemplate('module:ps_checkout/views/templates/front/payment.tpl'); + $this->context->smarty->assign('css_url', $this->module->getPathUri() . 'views/css/payment.css'); + $this->context->smarty->assign('order_url', $this->orderPageUrl); + } + + public function setMedia() + { + $this->registerStylesheet('ps_checkout_payment', '/modules/ps_checkout/views/css/payment.css'); + parent::setMedia(); + } + + public function postProcess() + { + $orderId = Tools::getValue('orderID'); + + if (!$orderId) { + $this->redirectToOrderPage(); + } + + try { + $this->paypalOrderId = new PayPalOrderId($orderId); + + $this->commandBus = $this->module->getService('ps_checkout.bus.command'); + + /** @var PayPalOrderRepository $payPalOrderRepository */ + $payPalOrderRepository = $this->module->getService(PayPalOrderRepository::class); + /** @var Psr\SimpleCache\CacheInterface $payPalOrderCache */ + $payPalOrderCache = $this->module->getService('ps_checkout.cache.paypal.order'); + + $payPalOrder = $payPalOrderRepository->getPayPalOrderById($this->paypalOrderId); + + $orders = new PrestaShopCollection(Order::class); + $orders->where('id_cart', '=', $payPalOrder->getIdCart()); + + if ($orders->count()) { + if ($this->context->customer->isLogged()) { + $this->redirectToOrderHistoryPage(); + } else { + $payPalOrderQueryResult = $this->getPayPalOrder($orderId); + $payPalOrderFromCache = $payPalOrderQueryResult->getPayPalOrder(); + + $this->redirectToOrderConfirmationPage($payPalOrder->getIdCart(), $payPalOrderFromCache['purchase_units'][0]['payments']['captures'][0]['id'], $payPalOrderFromCache['status']); + } + } + + if ($payPalOrder->getIdCart() !== $this->context->cart->id) { + $this->redirectToOrderPage(); + } + + $payPalOrderQueryResult = $this->getPayPalOrder($orderId); + $payPalOrderFromCache = $payPalOrderQueryResult->getPayPalOrder(); + + if ($payPalOrderFromCache['status'] === 'COMPLETED') { + $this->createOrder($payPalOrderFromCache, $payPalOrder); + } + + if ($payPalOrderFromCache['status'] === 'PAYER_ACTION_REQUIRED') { + $this->redirectTo3DSVerification($payPalOrderFromCache); + } + + // WHEN 3DS fails + if ($payPalOrderFromCache['status'] === 'CREATED') { + $card3DSecure = new Card3DSecure(); + switch ($card3DSecure->continueWithAuthorization($payPalOrderFromCache)) { + case Card3DSecure::RETRY: + $this->redirectTo3DSVerification($payPalOrderFromCache); + break; + case Card3DSecure::PROCEED: + $this->commandBus->handle(new CapturePayPalOrderCommand($orderId, array_keys($payPalOrderFromCache['payment_source'])[0])); + $payPalOrderFromCache = $payPalOrderCache->get($orderId); + $this->createOrder($payPalOrderFromCache, $payPalOrder); + break; + case Card3DSecure::NO_DECISION: + default: + break; + } + } + + if ($payPalOrderFromCache['status'] === 'APPROVED') { + $this->commandBus->handle(new CapturePayPalOrderCommand($orderId, array_keys($payPalOrderFromCache['payment_source'])[0])); + $payPalOrderFromCache = $payPalOrderCache->get($orderId); + $this->createOrder($payPalOrderFromCache, $payPalOrder); + } + } catch (Exception $exception) { + $this->context->smarty->assign('error', $exception->getMessage()); + } + } + + /** + * @param array $payPalOrderFromCache + * @param PayPalOrder$payPalOrder + * + * @return void + * + * @throws PrestaShopException + * @throws PsCheckoutException + * @throws PayPalOrderException + */ + private function createOrder($payPalOrderFromCache, $payPalOrder) + { + $capture = isset($payPalOrderFromCache['purchase_units'][0]['payments']['captures'][0]) ? $payPalOrderFromCache['purchase_units'][0]['payments']['captures'][0] : null; + $this->commandBus->handle(new CreateOrderCommand($payPalOrder->getId()->getValue(), $capture)); + if ($payPalOrder->getPaymentTokenId() && $payPalOrder->checkCustomerIntent(PayPalOrder::CUSTOMER_INTENT_FAVORITE)) { + /** @var PaymentTokenRepository $paymentTokenRepository */ + $paymentTokenRepository = $this->module->getService(PaymentTokenRepository::class); + $paymentTokenRepository->setTokenFavorite($payPalOrder->getPaymentTokenId()); + } + $this->redirectToOrderConfirmationPage($payPalOrder->getIdCart(), $capture ? $capture['id'] : null, $payPalOrderFromCache['status']); + } + + /** + * @param array $order + * + * @return void + */ + private function redirectTo3DSVerification($order) + { + $payerActionLinks = array_filter($order['links'], function ($link) { + return $link['rel'] === 'payer-action'; + }); + if (!empty($payerActionLinks)) { + Tools::redirect(reset($payerActionLinks)['href'] . '&redirect_uri=' . urlencode($this->context->link->getModuleLink('ps_checkout', 'payment', ['orderID' => $this->paypalOrderId->getValue()]))); + } + } + + private function redirectToOrderPage() + { + Tools::redirect($this->orderPageUrl); + } + + /** + * @param int $cartId + * @param string $captureId + * @param string $payPalOrderStatus + * + * @return void + * + * @throws PrestaShopException + */ + private function redirectToOrderConfirmationPage($cartId, $captureId, $payPalOrderStatus) + { + $orders = new PrestaShopCollection(Order::class); + $orders->where('id_cart', '=', $cartId); + + if (!$orders->count()) { + return; + } + + /** @var Order $order */ + $order = $orders->getFirst(); + + $cart = new Cart($cartId); + + if ($_SERVER['REQUEST_METHOD'] === 'GET') { + Tools::redirect($this->context->link->getPageLink( + 'order-confirmation', + true, + (int) $order->id_lang, + [ + 'paypal_status' => $payPalOrderStatus, + 'paypal_order' => $this->paypalOrderId->getValue(), + 'paypal_transaction' => $captureId, + 'id_cart' => $cartId, + 'id_module' => (int) $this->module->id, + 'id_order' => (int) $order->id, + 'key' => $cart->secure_key, + ] + )); + } + } + + /** + * @param string $orderId + * + * @return GetPayPalOrderForCheckoutCompletedQueryResult + * + * @throws PayPalOrderException + */ + private function getPayPalOrder($orderId) + { + $payPalOrderQuery = new GetPayPalOrderForCheckoutCompletedQuery($orderId); + + return $this->commandBus->handle($payPalOrderQuery); + } + + private function redirectToOrderHistoryPage() + { + Tools::redirect($this->context->link->getPageLink('history')); + } +} diff --git a/controllers/front/validate.php b/controllers/front/validate.php index 1ef8999c7..5f3f095ad 100644 --- a/controllers/front/validate.php +++ b/controllers/front/validate.php @@ -23,6 +23,7 @@ use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; use PrestaShop\Module\PrestashopCheckout\Event\EventDispatcherInterface; +use PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter; use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForOrderConfirmationQuery; @@ -85,7 +86,7 @@ public function postProcess() $this->paypalOrderId = $bodyValues['orderID']; /** @var PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->module->getService(PsCheckoutCartRepository::class); $psCheckoutCart = $psCheckoutCartRepository->findOneByPayPalOrderId($this->paypalOrderId); if (!Validate::isLoadedObject($psCheckoutCart)) { @@ -96,7 +97,7 @@ public function postProcess() } /** @var EventDispatcherInterface $eventDispatcher */ - $eventDispatcher = $this->module->getService('ps_checkout.event.dispatcher'); + $eventDispatcher = $this->module->getService(SymfonyEventDispatcherAdapter::class); $eventDispatcher->dispatch(new CheckoutCompletedEvent( $psCheckoutCart->getIdCart(), @@ -129,7 +130,7 @@ private function generateResponse() $commandBus = $this->module->getService('ps_checkout.bus.command'); /** @var PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->module->getService(PsCheckoutCartRepository::class); $psCheckoutCart = $psCheckoutCartRepository->findOneByPayPalOrderId($this->paypalOrderId); if (!Validate::isLoadedObject($psCheckoutCart)) { @@ -188,7 +189,7 @@ private function sendOkResponse($response) } /** @var PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->module->getService(PsCheckoutCartRepository::class); $psCheckoutCart = $psCheckoutCartRepository->findOneByPayPalOrderId($this->paypalOrderId); if (!Validate::isLoadedObject($psCheckoutCart)) { @@ -437,6 +438,9 @@ private function handleException(Exception $exception) 'body' => [ 'error' => [ 'message' => $exceptionMessageForCustomer, + 'code' => (int) $exception->getCode() < 400 && $exception->getPrevious() !== null + ? (int) $exception->getPrevious()->getCode() + : (int) $exception->getCode(), ], ], 'exceptionCode' => $exception->getCode(), @@ -447,7 +451,7 @@ private function handleException(Exception $exception) private function notifyCustomerService(Exception $exception) { /** @var PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->module->getService(PsCheckoutCartRepository::class); $psCheckoutCart = $psCheckoutCartRepository->findOneByPayPalOrderId($this->paypalOrderId); if (!Validate::isLoadedObject($psCheckoutCart)) { diff --git a/controllers/front/vault.php b/controllers/front/vault.php new file mode 100644 index 000000000..f45a24c67 --- /dev/null +++ b/controllers/front/vault.php @@ -0,0 +1,103 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; +use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command\DeletePaymentTokenCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query\GetCustomerPaymentTokensQuery; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query\GetCustomerPaymentTokensQueryResult; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; +use Psr\Log\LoggerInterface; + +/** + * This controller receive ajax call to manage the Customer PayPal Payment Method tokens + */ +class Ps_CheckoutVaultModuleFrontController extends AbstractFrontController +{ + /** + * @see FrontController::postProcess() + */ + public function postProcess() + { + try { + /** @var CommandBusInterface $commandBus */ + $commandBus = $this->module->getService('ps_checkout.bus.command'); + + $bodyValues = []; + $bodyContent = file_get_contents('php://input'); + + if (!empty($bodyContent)) { + $bodyValues = json_decode($bodyContent, true); + } + + $customerId = $this->getCustomerId(); + + if (isset($bodyValues['action'])) { + $action = $bodyValues['action']; + + switch ($action) { + case 'deleteToken': + $vaultId = $bodyValues['vaultId']; + $commandBus->handle(new DeletePaymentTokenCommand(new PaymentTokenId($vaultId), $customerId)); + $this->exitWithResponse([ + 'status' => true, + 'httpCode' => 200, + ]); + break; + default: + $this->exitWithResponse([ + 'status' => false, + 'httpCode' => 400, + ]); + } + } + + /** @var GetCustomerPaymentTokensQueryResult $getCustomerPaymentMethodTokensQueryResult */ + $getCustomerPaymentMethodTokensQueryResult = $commandBus->handle(new GetCustomerPaymentTokensQuery( + $customerId, + $this->getPageSize(), + $this->getPageNumber() + )); + + $this->exitWithResponse([ + 'status' => true, + 'httpCode' => 200, + 'body' => [ + 'customerId' => $getCustomerPaymentMethodTokensQueryResult->getCustomerId(), + 'paymentTokens' => $getCustomerPaymentMethodTokensQueryResult->getPaymentTokens(), + 'totalItems' => $getCustomerPaymentMethodTokensQueryResult->getTotalItems(), + 'totalPages' => $getCustomerPaymentMethodTokensQueryResult->getTotalPages(), + ], + ]); + } catch (Exception $exception) { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService('ps_checkout.logger'); + $logger->error( + sprintf( + 'VaultController exception %s : %s', + $exception->getCode(), + $exception->getMessage() + ) + ); + + $this->exitWithExceptionMessage($exception); + } + } +} diff --git a/controllers/front/webhook.php b/controllers/front/webhook.php index 0680157f3..109a2ba1b 100644 --- a/controllers/front/webhook.php +++ b/controllers/front/webhook.php @@ -49,7 +49,7 @@ public function postProcess() try { /** @var WebhookHandler $webhookHandler */ - $webhookHandler = $this->module->getService('ps_checkout.webhook.handler'); + $webhookHandler = $this->module->getService(WebhookHandler::class); if (empty($_SERVER['HTTP_WEBHOOK_SECRET']) || !$webhookHandler->authenticate($_SERVER['HTTP_WEBHOOK_SECRET'])) { throw new WebhookException('Webhook secret mismatch', WebhookException::WEBHOOK_SECRET_MISMATCH); diff --git a/deploy.sh b/deploy.sh deleted file mode 100644 index f022a82e4..000000000 --- a/deploy.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -FILEPATH=$1 -ENV=$2 -SHOP=$3 - -gcloud container clusters get-credentials --project="prestashop-ready-$ENV" --zone="europe-west1-d" "prestashop-ready-cluster" - -function deploy() { - echo "** Deploy on : " $1 " ***" - kubectl cp /workspace/$FILEPATH $ENV-shops/$1:/ - kubectl exec -t --namespace=$ENV-shops $1 -- bash -c \ - " - sudo -u presthost -H bash -c \"mkdir -p /presthost/core/img/tmp &>/dev/null;\"; - sudo -u presthost -H bash -c \"unzip -o /$FILEPATH -d /presthost/userland/modules > /dev/null 2>&1;\"; - rm -f /${FILEPATH}; - sudo -u presthost --preserve-env -H bash -c '/presthost/core/bin/console prestashop:module install ps_checkout'; - " -} - -deploy $(kubectl get pods --namespace=$ENV-shops -l shop=dep-$SHOP -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 1533f54df..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -version: '3.7' - -services: - php: - image: phpdockerio/php72-cli - volumes: - - ./:/var/www/html/modules/ps_checkout - working_dir: /var/www/html/modules/ps_checkout - environment: - _PS_ROOT_DIR_: /var/www/html - node: - image: node:13.1 - volumes: - - ./:/var/www/html/modules/ps_checkout - working_dir: /var/www/html/modules/ps_checkout - environment: - PATH: /var/www/html/_dev/node_modules/.bin/:$PATH diff --git a/_dev/js/front/README.md b/docs/front/README.md similarity index 100% rename from _dev/js/front/README.md rename to docs/front/README.md diff --git a/_dev/js/front/docs/front-end-initialization.jpg b/docs/front/front-end-initialization.jpg similarity index 100% rename from _dev/js/front/docs/front-end-initialization.jpg rename to docs/front/front-end-initialization.jpg diff --git a/_dev/js/front/docs/html-generation.jpg b/docs/front/html-generation.jpg similarity index 100% rename from _dev/js/front/docs/html-generation.jpg rename to docs/front/html-generation.jpg diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 06824f98b..000000000 --- a/package-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "ps_checkout", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "hasInstallScript": true, - "license": "AFL-3.0" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index a56ead3f9..000000000 --- a/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": "PrestaShop", - "name": "ps_checkout", - "homepage": "https://github.com/PrestaShopCorp/ps_checkout", - "repository": { - "type": "git", - "url": "git+https://github.com/PrestaShopCorp/ps_checkout.git" - }, - "scripts": { - "build": "npm run front:build", - "front:build": "npm run build --prefix ./_dev/js/front", - "front:coverage": "npm run coverage --prefix ./_dev/js/front", - "front:install": "npm i --prefix ./_dev/js/front", - "front:test": "npm test --prefix ./_dev/js/front", - "front:watch": "npm run watch --prefix ./_dev/js/front", - "lint": "", - "postback:build": "rm ./_dev/js/back/.env", - "postfront:build": "rm ./_dev/js/front/.env", - "prefront:build": "cp ./.env ./_dev/js/front/.", - "postfront:watch": "rm ./_dev/js/front/.env", - "prefront:watch": "cp ./.env ./_dev/js/front/.", - "preinstall": "npm run front:install", - "test": "npm run front:test" - }, - "license": "AFL-3.0", - "private": true -} diff --git a/ps_checkout.php b/ps_checkout.php index 64b240d68..608c8ef5f 100755 --- a/ps_checkout.php +++ b/ps_checkout.php @@ -46,6 +46,7 @@ class Ps_checkout extends PaymentModule 'actionObjectOrderPaymentUpdateAfter', 'displayPaymentReturn', 'displayOrderDetail', + 'moduleRoutes', ]; /** @@ -105,6 +106,9 @@ class Ps_checkout extends PaymentModule 'PS_CHECKOUT_LIABILITY_SHIFT_REQ' => '1', 'PS_CHECKOUT_DISPLAY_LOGO_PRODUCT' => '1', 'PS_CHECKOUT_DISPLAY_LOGO_CART' => '1', + 'PS_CHECKOUT_HOSTED_FIELDS_CONTINGENCIES' => 'SCA_WHEN_REQUIRED', + 'PS_CHECKOUT_DOMAIN_REGISTERED_SANDBOX' => false, + 'PS_CHECKOUT_DOMAIN_REGISTERED_LIVE' => false, ]; public $confirmUninstall; @@ -112,9 +116,9 @@ class Ps_checkout extends PaymentModule // Needed in order to retrieve the module version easier (in api call headers) than instanciate // the module each time to get the version - const VERSION = '7.3.6.3'; + const VERSION = '7.4.2.2'; - const INTEGRATION_DATE = '2022-14-06'; + const INTEGRATION_DATE = '2024-04-01'; /** @var \Psr\Log\LoggerInterface */ private $logger; @@ -133,7 +137,7 @@ public function __construct() // We cannot use the const VERSION because the const is not computed by addons marketplace // when the zip is uploaded - $this->version = '7.3.6.3'; + $this->version = '7.4.2.2'; $this->author = 'PrestaShop'; $this->currencies = true; $this->currencies_mode = 'checkbox'; @@ -171,7 +175,7 @@ public function install() $this->installConfiguration() && $this->installHooks() && (new PrestaShop\Module\PrestashopCheckout\Database\TableManager())->createTable() && - (new PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceInstaller())->createFundingSources() && + (new PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceInstaller())->createFundingSourcesOnAllShops() && $this->installTabs() && $this->disableIncompatibleCountries() && $this->disableIncompatibleCurrencies(); @@ -194,7 +198,7 @@ public function installHooks() { $result = (bool) $this->registerHook(self::HOOK_LIST); /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); // Install specific to prestashop 1.6 if (!$shopContext->isShop17()) { @@ -275,8 +279,8 @@ public function installTabs() */ public function disableIncompatibleCountries() { - /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->getService('ps_checkout.paypal.configuration'); + /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ + $paypalConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); $incompatibleCodes = $paypalConfiguration->getIncompatibleCountryCodes(false); $result = true; @@ -301,8 +305,8 @@ public function disableIncompatibleCountries() */ public function disableIncompatibleCurrencies() { - /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->getService('ps_checkout.paypal.configuration'); + /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ + $paypalConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); $incompatibleCodes = $paypalConfiguration->getIncompatibleCurrencyCodes(false); $result = true; @@ -395,14 +399,15 @@ public function getContent() } /** @var \PrestaShop\Module\PrestashopCheckout\Presenter\Store\StorePresenter $storePresenter */ - $storePresenter = $this->getService('ps_checkout.store.store'); + $storePresenter = $this->getService(\PrestaShop\Module\PrestashopCheckout\Presenter\Store\StorePresenter::class); Media::addJsDef([ 'store' => $storePresenter->present(), 'contextPsAccounts' => $contextPsAccounts, ]); - $env = new \PrestaShop\Module\PrestashopCheckout\Environment\Env(); + /** @var \PrestaShop\Module\PrestashopCheckout\Environment\Env $env */ + $env = $this->getService(\PrestaShop\Module\PrestashopCheckout\Environment\Env::class); $boSdkUrl = $env->getEnv('CHECKOUT_BO_SDK_URL'); if (substr($boSdkUrl, -3) !== '.js') { $boSdkVersion = $env->getEnv('CHECKOUT_BO_SDK_VERSION'); @@ -465,7 +470,7 @@ public function hookActionAfterDeleteProductInCart() } /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); if ($shopContext->isShop17()) { return; @@ -488,7 +493,7 @@ public function hookActionCartUpdateQuantityBefore() } /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository::class); /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartRepository->findOneByCartId((int) $this->context->cart->id); @@ -513,7 +518,7 @@ public function hookActionBeforeCartUpdateQty() } /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); if ($shopContext->isShop17()) { return; @@ -535,7 +540,7 @@ public function hookDisplayPayment() } /** @var \PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider $fundingSourceProvider */ - $fundingSourceProvider = $this->getService('ps_checkout.funding_source.provider'); + $fundingSourceProvider = $this->getService(\PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider::class); $paymentOptions = []; foreach ($fundingSourceProvider->getAll() as $fundingSource) { @@ -543,16 +548,16 @@ public function hookDisplayPayment() } /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository::class); /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartRepository->findOneByCartId((int) $this->context->cart->id); - /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $configurationPayPal */ - $configurationPayPal = $this->getService('ps_checkout.paypal.configuration'); + /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $configurationPayPal */ + $configurationPayPal = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); $isExpressCheckout = false !== $psCheckoutCart && $psCheckoutCart->isExpressCheckout && $psCheckoutCart->isOrderAvailable(); @@ -600,22 +605,67 @@ public function hookPaymentOptions(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider $fundingSourceProvider */ - $fundingSourceProvider = $this->getService('ps_checkout.funding_source.provider'); + $fundingSourceProvider = $this->getService(\PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider::class); - /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $configurationPayPal */ - $configurationPayPal = $this->getService('ps_checkout.paypal.configuration'); + /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $configurationPayPal */ + $configurationPayPal = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); $paymentOptions = []; + $vaultingEnabled = $configurationPayPal->isVaultingEnabled() + && $this->context->customer->isLogged(); + + $this->context->smarty->assign('lockIcon', Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/views/img/icons/lock_fill.svg')); + $vaultedPayPal = []; + + if ($vaultingEnabled) { + foreach ($fundingSourceProvider->getSavedTokens($cart->id_customer) as $fundingSource) { + if ($fundingSource->paymentSource === 'paypal') { + $vaultedPayPal = [ + 'paymentIdentifier' => $fundingSource->name, + 'fundingSource' => $fundingSource->paymentSource, + 'isFavorite' => $fundingSource->isFavorite, + 'label' => $fundingSource->label, + 'vaultId' => explode('-', $fundingSource->name)[1], + ]; + continue; + } + $paymentOption = new PrestaShop\PrestaShop\Core\Payment\PaymentOption(); + $paymentOption->setModuleName($this->name . '-' . $fundingSource->name); + $paymentOption->setCallToActionText($fundingSource->label); + $paymentOption->setBinary(true); + + $this->context->smarty->assign([ + 'paymentIdentifier' => $fundingSource->name, + 'fundingSource' => $fundingSource->paymentSource, + 'isFavorite' => $fundingSource->isFavorite, + 'label' => $fundingSource->label, + 'vaultId' => explode('-', $fundingSource->name)[1], + ]); + $paymentOption->setForm($this->context->smarty->fetch('module:ps_checkout/views/templates/hook/partials/vaultTokenForm.tpl')); + + $paymentOptions[] = $paymentOption; + } + } + foreach ($fundingSourceProvider->getAll() as $fundingSource) { $paymentOption = new PrestaShop\PrestaShop\Core\Payment\PaymentOption(); $paymentOption->setModuleName($this->name . '-' . $fundingSource->name); $paymentOption->setCallToActionText($fundingSource->label); $paymentOption->setBinary(true); + $this->context->smarty->assign([ + 'vaultingEnabled' => $vaultingEnabled, + 'paymentIdentifier' => $fundingSource->name, + ]); if ('card' === $fundingSource->name && $configurationPayPal->isHostedFieldsEnabled() && in_array($configurationPayPal->getCardHostedFieldsStatus(), ['SUBSCRIBED', 'LIMITED'], true)) { $this->context->smarty->assign('modulePath', $this->getPathUri()); $paymentOption->setForm($this->context->smarty->fetch('module:ps_checkout/views/templates/hook/partials/cardFields.tpl')); + } elseif ($fundingSource->name === 'paypal' && empty($vaultedPayPal)) { + $paymentOption->setForm($this->context->smarty->fetch('module:ps_checkout/views/templates/hook/partials/vaultPaymentForm.tpl')); + } elseif ($fundingSource->name === 'paypal' && $vaultedPayPal) { + $this->context->smarty->assign($vaultedPayPal); + $paymentOption->setForm($this->context->smarty->fetch('module:ps_checkout/views/templates/hook/partials/vaultTokenForm.tpl')); } $paymentOptions[] = $paymentOption; @@ -645,7 +695,7 @@ public function hookDisplayOrderConfirmation(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder $orderSummaryViewBuilder */ - $orderSummaryViewBuilder = $this->getService('ps_checkout.paypal.builder.view_order_summary'); + $orderSummaryViewBuilder = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder::class); try { $orderSummaryView = $orderSummaryViewBuilder->build($order); @@ -673,7 +723,7 @@ public function checkCurrency($cart) } /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository $codeRepository */ - $codeRepository = $this->getService('ps_checkout.repository.paypal.code'); + $codeRepository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository::class); $currency_order = Currency::getCurrencyInstance($cart->id_currency); $isCurrencySupported = false; @@ -716,14 +766,14 @@ public function checkCurrency($cart) */ public function hookDisplayAdminAfterHeader() { - /** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $this->getService('ps_checkout.paypal.configuration'); - /** @var PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository $psAccount */ - $psAccount = $this->getService('ps_checkout.repository.prestashop.account'); + /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */ + $paypalConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); + /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository $psAccount */ + $psAccount = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository::class); /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); /** @var \PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ContextModule $moduleContext */ - $moduleContext = $this->getService('ps_checkout.store.module.context'); + $moduleContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\Presenter\Store\Modules\ContextModule::class); $isShop17 = $shopContext->isShop17(); $isFullyOnboarded = $psAccount->onBoardingIsCompleted() && $paypalConfiguration->getMerchantId(); @@ -782,6 +832,15 @@ public function hookActionAdminControllerSetMedia() /** @var \PrestaShop\Module\PrestashopCheckout\Version\Version $version */ $version = $this->getService('ps_checkout.module.version'); + if ('AdminModules' === Tools::getValue('controller') && 'ps_checkout' === Tools::getValue('configure')) { + $this->context->controller->addCss( + $this->_path . 'views/css/adminModules.css?version=' . $version->getSemVersion(), + 'all', + null, + false + ); + } + if ('AdminPayment' === Tools::getValue('controller')) { $this->context->controller->addCss( $this->_path . 'views/css/adminAfterHeader.css?version=' . $version->getSemVersion(), @@ -832,7 +891,7 @@ public function merchantIsValid() { if (static::$merchantIsValid === null) { /** @var \PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator $merchantValidator */ - $merchantValidator = $this->getService('ps_checkout.validator.merchant'); + $merchantValidator = $this->getService(\PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator::class); static::$merchantIsValid = $merchantValidator->merchantIsValid(); } @@ -851,7 +910,7 @@ public function hookActionFrontControllerSetMedia() } /** @var \PrestaShop\Module\PrestashopCheckout\Validator\FrontControllerValidator $frontControllerValidator */ - $frontControllerValidator = $this->getService('ps_checkout.validator.front_controller'); + $frontControllerValidator = $this->getService(\PrestaShop\Module\PrestashopCheckout\Validator\FrontControllerValidator::class); /** @var \PrestaShop\Module\PrestashopCheckout\Version\Version $version */ $version = $this->getService('ps_checkout.module.version'); @@ -880,22 +939,22 @@ public function hookActionFrontControllerSetMedia() } /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\Sdk\PayPalSdkConfigurationBuilder $payPalSdkConfigurationBuilder */ - $payPalSdkConfigurationBuilder = $this->getService('ps_checkout.sdk.paypal.configurationbuilder'); + $payPalSdkConfigurationBuilder = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\Sdk\PayPalSdkConfigurationBuilder::class); /** @var \PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration $expressCheckoutConfiguration */ - $expressCheckoutConfiguration = $this->getService('ps_checkout.express_checkout.configuration'); + $expressCheckoutConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration::class); /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $payPalConfiguration */ - $payPalConfiguration = $this->getService('ps_checkout.paypal.configuration'); + $payPalConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class); /** @var \PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider $fundingSourceProvider */ - $fundingSourceProvider = $this->getService('ps_checkout.funding_source.provider'); + $fundingSourceProvider = $this->getService(\PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider::class); /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration $payLaterConfiguration */ - $payLaterConfiguration = $this->getService('ps_checkout.pay_later.configuration'); + $payLaterConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration::class); /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); /** @var \PrestaShop\Module\PrestashopCheckout\Version\Version $version */ $version = $this->getService('ps_checkout.module.version'); @@ -914,11 +973,22 @@ public function hookActionFrontControllerSetMedia() $fundingSourcesSorted = []; $payWithTranslations = []; $isCardAvailable = false; + $customMarks = []; + + foreach ($fundingSourceProvider->getSavedTokens($this->context->customer->id) as $fundingSource) { + $fundingSourcesSorted[] = $fundingSource->name; + $payWithTranslations[$fundingSource->name] = $fundingSource->label; + $customMarks[$fundingSource->name] = $fundingSource->customMark; + } foreach ($fundingSourceProvider->getAll() as $fundingSource) { $fundingSourcesSorted[] = $fundingSource->name; $payWithTranslations[$fundingSource->name] = $fundingSource->label; + if ($fundingSource->customMark !== null) { + $customMarks[$fundingSource->name] = $fundingSource->customMark; + } + if ('card' === $fundingSource->name) { $isCardAvailable = $fundingSource->isEnabled; } @@ -934,7 +1004,7 @@ public function hookActionFrontControllerSetMedia() if (Validate::isLoadedObject($this->context->cart)) { $cartProductCount = (int) $this->context->cart->nbProducts(); /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository::class); /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartRepository->findOneByCartId((int) $this->context->cart->id); @@ -952,6 +1022,7 @@ public function hookActionFrontControllerSetMedia() $this->name . 'LoaderImage' => $this->getPathUri() . 'views/img/loader.svg', $this->name . 'PayPalButtonConfiguration' => $payPalConfiguration->getButtonConfiguration(), $this->name . 'CardFundingSourceImg' => Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/views/img/payment-cards.png'), + $this->name . 'CustomMarks' => $customMarks, $this->name . 'CardLogos' => [ 'AMEX' => Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/views/img/amex.svg'), 'CB_NATIONALE' => Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/views/img/cb.svg'), @@ -965,11 +1036,16 @@ public function hookActionFrontControllerSetMedia() ], $this->name . 'CardBrands' => $supportedCardBrands, $this->name . 'PaymentMethodLogosTitleImg' => Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/views/img/lock_checkout.svg'), + $this->name . 'IconsPath' => Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/views/img/icons/'), $this->name . 'CreateUrl' => $this->context->link->getModuleLink($this->name, 'create', [], true), $this->name . 'CheckUrl' => $this->context->link->getModuleLink($this->name, 'check', [], true), $this->name . 'ValidateUrl' => $this->context->link->getModuleLink($this->name, 'validate', [], true), $this->name . 'CancelUrl' => $this->context->link->getModuleLink($this->name, 'cancel', [], true), $this->name . 'ExpressCheckoutUrl' => $this->context->link->getModuleLink($this->name, 'ExpressCheckout', [], true), + $this->name . 'VaultUrl' => $this->context->link->getModuleLink($this->name, 'vault', [], true), + $this->name . 'PaymentUrl' => $this->context->link->getModuleLink($this->name, 'payment', [], true), + $this->name . 'GooglePayUrl' => $this->context->link->getModuleLink($this->name, 'googlepay', [], true), + $this->name . 'ApplePayUrl' => $this->context->link->getModuleLink($this->name, 'applepay', [], true), $this->name . 'CheckoutUrl' => $this->getCheckoutPageUrl(), $this->name . 'ConfirmUrl' => $this->context->link->getPageLink('order-confirmation', true, (int) $this->context->language->id), $this->name . 'PayPalSdkConfig' => $payPalSdkConfigurationBuilder->buildConfiguration(), @@ -978,6 +1054,7 @@ public function hookActionFrontControllerSetMedia() $this->name . 'HostedFieldsEnabled' => $isCardAvailable && $payPalConfiguration->isHostedFieldsEnabled() && in_array($payPalConfiguration->getCardHostedFieldsStatus(), ['SUBSCRIBED', 'LIMITED'], true), $this->name . 'HostedFieldsSelected' => false !== $psCheckoutCart && $psCheckoutCart->isHostedFields(), $this->name . 'HostedFieldsContingencies' => $payPalConfiguration->getHostedFieldsContingencies(), + $this->name . 'PayPalEnvironment' => $payPalConfiguration->getPaymentMode(), $this->name . 'ExpressCheckoutSelected' => false !== $psCheckoutCart && $psCheckoutCart->isExpressCheckout(), $this->name . 'ExpressCheckoutProductEnabled' => $expressCheckoutConfiguration->isProductPageEnabled() && $payPalConfiguration->isPayPalPaymentsReceivable(), $this->name . 'ExpressCheckoutCartEnabled' => $expressCheckoutConfiguration->isOrderPageEnabled() && $payPalConfiguration->isPayPalPaymentsReceivable(), @@ -1024,22 +1101,49 @@ public function hookActionFrontControllerSetMedia() 'express-button.cart.separator' => $this->l('or'), 'express-button.checkout.express-checkout' => $this->l('Express Checkout'), 'error.paypal-sdk' => $this->l('No PayPal Javascript SDK Instance'), + 'error.google-pay-sdk' => $this->l('No Google Pay Javascript SDK Instance'), + 'error.google-pay.transaction-info' => $this->l('An error occurred fetching Google Pay transaction info'), + 'error.apple-pay-sdk' => $this->l('No Apple Pay Javascript SDK Instance'), + 'error.apple-pay.payment-request' => $this->l('An error occurred fetching Apple Pay payment request'), 'checkout.payment.others.link.label' => $this->l('Other payment methods'), 'checkout.payment.others.confirm.button.label' => $this->l('I confirm my order'), 'checkout.form.error.label' => $this->l('There was an error during the payment. Please try again or contact the support.'), 'loader-component.label.header' => $this->l('Thanks for your purchase!'), 'loader-component.label.body' => $this->l('Please wait, we are processing your payment'), + 'loader-component.label.body.longer' => $this->l('This is taking longer than expected. Please wait...'), 'error.paypal-sdk.contingency.cancel' => $this->l('Card holder authentication canceled, please choose another payment method or try again.'), 'error.paypal-sdk.contingency.error' => $this->l('An error occurred on card holder authentication, please choose another payment method or try again.'), 'error.paypal-sdk.contingency.failure' => $this->l('Card holder authentication failed, please choose another payment method or try again.'), 'error.paypal-sdk.contingency.unknown' => $this->l('Card holder authentication cannot be checked, please choose another payment method or try again.'), + 'ok' => $this->l('Ok'), + 'cancel' => $this->l('Cancel'), + 'checkout.payment.token.delete.modal.header' => $this->l('Delete this payment method?'), + 'checkout.payment.token.delete.modal.content' => $this->l('The following payment method will be deleted from your account:'), + 'checkout.payment.token.delete.modal.confirm-button' => $this->l('Delete payment method'), + 'checkout.payment.loader.processing-request' => $this->l('Please wait, we are processing your request'), ], ]); + /** @var \PrestaShop\Module\PrestashopCheckout\Environment\Env $env */ + $env = $this->getService(\PrestaShop\Module\PrestashopCheckout\Environment\Env::class); + + $foSdkUrl = $env->getEnv('CHECKOUT_FO_SDK_URL'); + if (substr($foSdkUrl, -3) !== '.js') { + $foSdkVersion = $env->getEnv('CHECKOUT_FO_SDK_VERSION'); + if (empty($foSdkVersion)) { + /** @var \PrestaShop\Module\PrestashopCheckout\Version\Version $version */ + $version = $this->getService('ps_checkout.module.version'); + $majorModuleVersion = explode('.', $version->getSemVersion())[0]; + $foSdkVersion = "$majorModuleVersion.X.X"; + } + + $foSdkUrl = $foSdkUrl . $foSdkVersion . '/sdk/ps_checkout-fo-sdk.js'; + } + if (method_exists($this->context->controller, 'registerJavascript')) { $this->context->controller->registerJavascript( $this->name . 'Front', - $this->getPathUri() . 'views/js/front.js?version=' . $version->getSemVersion(), + $foSdkUrl, [ 'position' => 'bottom', 'priority' => 201, @@ -1047,10 +1151,7 @@ public function hookActionFrontControllerSetMedia() ] ); } else { - $this->context->controller->addJS( - $this->getPathUri() . 'views/js/front.js?version=' . $version->getSemVersion(), - false - ); + $this->context->controller->addJS($foSdkUrl, false); } } @@ -1067,7 +1168,7 @@ public function hookActionFrontControllerSetMedia() public function addCheckboxCarrierRestrictionsForModule(array $shopsList = []) { /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); if (false === $shopContext->isShop17()) { return true; } @@ -1189,13 +1290,13 @@ public function hookDisplayInvoiceLegalFreeText(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository::class); /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartRepository->findOneByCartId((int) $order->id_cart); /** @var \PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration $psConfiguration */ - $psConfiguration = $this->getService('ps_checkout.configuration'); + $psConfiguration = $this->getService(\PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration::class); // No PayPal Order found for this Order if (false === $psCheckoutCart) { @@ -1217,7 +1318,7 @@ public function hookDisplayInvoiceLegalFreeText(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderTranslationProvider $translationService */ - $translationService = $this->getService('ps_checkout.paypal.order.translations'); + $translationService = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderTranslationProvider::class); $translations = $translationService->getSummaryTranslations(); $legalFreeText .= $translations['blockTitle'] . PHP_EOL; @@ -1291,6 +1392,7 @@ public function hookActionObjectShopAddAfter(array $params) Configuration::set($name, $value, (int) $shop->id_shop_group, (int) $shop->id); } + (new PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceInstaller())->createFundingSources((int) $shop->id); $this->addCheckboxCarrierRestrictionsForModule([(int) $shop->id]); $this->addCheckboxCountryRestrictionsForModule([(int) $shop->id]); @@ -1366,10 +1468,10 @@ public function hookDisplayPaymentTop() } /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->getService('ps_checkout.repository.pscheckoutcart'); + $psCheckoutCartRepository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository::class); /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartRepository->findOneByCartId((int) $this->context->cart->id); @@ -1434,9 +1536,13 @@ public function hookDisplayPaymentByBinaries(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider $fundingSourceProvider */ - $fundingSourceProvider = $this->getService('ps_checkout.funding_source.provider'); + $fundingSourceProvider = $this->getService(\PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceProvider::class); $paymentOptions = []; + foreach ($fundingSourceProvider->getSavedTokens($cart->id_customer) as $fundingSource) { + $paymentOptions[] = $fundingSource->name; + } + foreach ($fundingSourceProvider->getAll() as $fundingSource) { $paymentOptions[] = $fundingSource->name; } @@ -1456,7 +1562,7 @@ public function hookDisplayPaymentByBinaries(array $params) private function getCheckoutPageUrl() { /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ - $shopContext = $this->getService('ps_checkout.context.shop'); + $shopContext = $this->getService(\PrestaShop\Module\PrestashopCheckout\ShopContext::class); if ($shopContext->isShop17()) { return $this->context->link->getPageLink( @@ -1546,7 +1652,7 @@ private function processHookActionObjectOrderPayment($params) } /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $repository */ - $repository = $this->getService('ps_checkout.repository.pscheckoutcart'); + $repository = $this->getService(\PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository::class); $psCheckoutCart = $repository->findOneByCartId($id_cart); @@ -1555,7 +1661,7 @@ private function processHookActionObjectOrderPayment($params) } /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider $paypalOrderProvider */ - $paypalOrderProvider = $this->getService('ps_checkout.paypal.provider.order'); + $paypalOrderProvider = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider::class); $paypalOrder = $paypalOrderProvider->getById($psCheckoutCart->paypal_order); @@ -1576,7 +1682,7 @@ private function processHookActionObjectOrderPayment($params) } /** @var \PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider $fundingSourceTranslationProvider */ - $fundingSourceTranslationProvider = $this->getService('ps_checkout.funding_source.translation'); + $fundingSourceTranslationProvider = $this->getService(\PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider::class); \Db::getInstance()->update( 'order_payment', @@ -1641,7 +1747,7 @@ public function hookDisplayPaymentReturn(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder $orderSummaryViewBuilder */ - $orderSummaryViewBuilder = $this->getService('ps_checkout.paypal.builder.view_order_summary'); + $orderSummaryViewBuilder = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder::class); try { $orderSummaryView = $orderSummaryViewBuilder->build($order); @@ -1675,7 +1781,7 @@ public function hookDisplayOrderDetail(array $params) } /** @var \PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder $orderSummaryViewBuilder */ - $orderSummaryViewBuilder = $this->getService('ps_checkout.paypal.builder.view_order_summary'); + $orderSummaryViewBuilder = $this->getService(\PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderSummaryViewBuilder::class); try { $orderSummaryView = $orderSummaryViewBuilder->build($order); @@ -1687,4 +1793,20 @@ public function hookDisplayOrderDetail(array $params) return $this->display(__FILE__, 'views/templates/hook/displayOrderDetail.tpl'); } + + public function hookModuleRoutes() + { + return [ + 'ps_checkout_applepay' => [ + 'rule' => '.well-known/apple-developer-merchantid-domain-association', + 'keywords' => [], + 'controller' => 'applepay', + 'params' => [ + 'fc' => 'module', + 'module' => 'ps_checkout', + 'action' => 'getDomainAssociation', + ], + ], + ]; + } } diff --git a/src/Adapter/LinkAdapter.php b/src/Adapter/LinkAdapter.php index 7eaefcdda..f95b435d2 100644 --- a/src/Adapter/LinkAdapter.php +++ b/src/Adapter/LinkAdapter.php @@ -58,8 +58,12 @@ public function __construct(\Link $link = null) public function getAdminLink($controller, $withToken = true, $sfRouteParams = [], $params = []) { $shop = \Context::getContext()->shop; + /** @var \Ps_checkout $module */ + $module = \Module::getInstanceByName('ps_checkout'); + /** @var ShopContext $shopContext */ + $shopContext = $module->getService(ShopContext::class); - if ((new ShopContext())->isShop17()) { + if ($shopContext->isShop17()) { $adminLink = $this->link->getAdminLink($controller, $withToken, $sfRouteParams, $params); if ($shop->virtual_uri !== '') { diff --git a/src/Api/GenericClient.php b/src/Api/GenericClient.php deleted file mode 100755 index f0ef52135..000000000 --- a/src/Api/GenericClient.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 - */ - -namespace PrestaShop\Module\PrestashopCheckout\Api; - -use Exception; -use GuzzleHttp\Psr7\Request; -use Http\Client\Exception\NetworkException; -use Http\Client\Exception\TransferException; -use Link; -use Module; -use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; -use PrestaShop\Module\PrestashopCheckout\Handler\Response\ResponseApiHandler; -use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository; -use Ps_checkout; - -/** - * Construct the client used to make call to maasland - */ -class GenericClient -{ - /** - * Guzzle Client - */ - protected $client; - - /** - * Class Link in order to generate module link - * - * @var Link - */ - protected $link; - - /** - * Enable or disable the catch of Maasland 400 error - * If set to false, you will not be able to catch the error of maasland - * guzzle will show a different error message. - * - * @var bool - */ - protected $catchExceptions = false; - - /** - * Set how long guzzle will wait a response before end it up - * - * @var int - */ - protected $timeout = 10; - - /** - * Api route - * - * @var string - */ - protected $route; - - /** - * @var string - */ - protected $shopUid; - - /** - * @var string - */ - protected $token; - - public function __construct() - { - /** @var Ps_checkout $module */ - $module = Module::getInstanceByName('ps_checkout'); - /** @var PsAccountRepository $psAccountRepository */ - $psAccountRepository = $module->getService('ps_checkout.repository.prestashop.account'); - - $this->shopUid = $psAccountRepository->getShopUuid(); - $this->token = $psAccountRepository->getIdToken(); - } - - /** - * Wrapper of method post from guzzle client - * - * @param array $options payload - * - * @return array return response or false if no response - */ - protected function post(array $options = []) - { - $request = new Request('POST', $this->getRoute(), [], json_encode($options)); - - try { - $response = $this->client->sendRequest($request); - } catch (\GuzzleHttp\Ring\Exception\ConnectException $exception) { - return $this->handleException(new NetworkException($exception->getMessage(), $request, $exception)); - } catch (\GuzzleHttp\Ring\Exception\RingException $exception) { - return $this->handleException(new TransferException($exception->getMessage(), 0, $exception)); - } catch (Exception $exception) { - return $this->handleException($exception); - } - - return (new ResponseApiHandler())->handleResponse($response); - } - - /** - * Setter for route - * - * @param string $route - */ - protected function setRoute($route) - { - $this->route = $route; - } - - /** - * Setter for client - * - * @param object $client Guzzle client - */ - protected function setClient($client) - { - $this->client = $client; - } - - /** - * Setter for link - * - * @param Link $link - */ - protected function setLink(Link $link) - { - $this->link = $link; - } - - /** - * Setter for timeout - * - * @param int $timeout - */ - protected function setTimeout($timeout) - { - $this->timeout = $timeout; - } - - /** - * Setter for exceptions mode - * - * @param bool $bool - */ - protected function setExceptionsMode($bool) - { - $this->catchExceptions = $bool; - } - - /** - * Getter for route - * - * @return string - */ - protected function getRoute() - { - return $this->route; - } - - /** - * Getter for client - * - * @return object Guzzle client - */ - protected function getClient() - { - return $this->client; - } - - /** - * Getter for Link - * - * @return Link - */ - protected function getLink() - { - return $this->link; - } - - /** - * Getter for timeout - * - * @return int - */ - protected function getTimeout() - { - return $this->timeout; - } - - /** - * Getter for exceptions mode - * - * @return bool - */ - protected function getExceptionsMode() - { - return $this->catchExceptions; - } - - private function handleException(Exception $exception) - { - $body = ''; - $httpCode = 500; - $exceptionCode = $exception->getCode(); - $exceptionMessage = $exception->getMessage(); - - if ($exception instanceof NetworkException || $exception instanceof TransferException) { - $exceptionCode = PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION; - } - - if (method_exists($exception, 'getResponse')) { - $response = $exception->getResponse(); - $body = $response ? $response->getBody() : $body; - $httpCode = $response ? $response->getStatusCode() : $httpCode; - } - - return [ - 'status' => false, - 'httpCode' => $httpCode, - 'body' => $body, - 'exceptionCode' => $exceptionCode, - 'exceptionMessage' => $exceptionMessage, - ]; - } - - /** - * @see https://docs.guzzlephp.org/en/5.3/clients.html#verify - * - * @return true|string - */ - protected function getVerify() - { - if (defined('_PS_CACHE_CA_CERT_FILE_') && file_exists(constant('_PS_CACHE_CA_CERT_FILE_'))) { - return constant('_PS_CACHE_CA_CERT_FILE_'); - } - - return true; - } -} diff --git a/src/Api/Payment/Client/PaymentClient.php b/src/Api/Payment/Client/PaymentClient.php deleted file mode 100755 index 820448360..000000000 --- a/src/Api/Payment/Client/PaymentClient.php +++ /dev/null @@ -1,207 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 - */ - -namespace PrestaShop\Module\PrestashopCheckout\Api\Payment\Client; - -use Context; -use GuzzleHttp\Event\Emitter; -use GuzzleHttp\HandlerStack; -use GuzzleHttp\Subscriber\Log\Formatter; -use GuzzleHttp\Subscriber\Log\LogSubscriber; -use GuzzleLogMiddleware\LogMiddleware; -use Link; -use Module; -use PrestaShop\Module\PrestashopCheckout\Api\GenericClient; -use PrestaShop\Module\PrestashopCheckout\Environment\PaymentEnv; -use PrestaShop\Module\PrestashopCheckout\Exception\HttpTimeoutException; -use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; -use PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration; -use PrestaShop\Module\PrestashopCheckout\Routing\Router; -use PrestaShop\Module\PrestashopCheckout\ShopContext; -use PrestaShop\Module\PrestashopCheckout\Version\Version; -use Prestashop\ModuleLibGuzzleAdapter\ClientFactory; -use Ps_checkout; -use Psr\Log\LoggerInterface; - -/** - * Construct the client used to make call to maasland - */ -class PaymentClient extends GenericClient -{ - /** - * @param Link $link - * @param object|null $client - */ - public function __construct(Link $link, $client = null) - { - parent::__construct(); - - $this->setLink($link); - - // Client can be provided for tests - if (null === $client) { - /** @var Ps_checkout $module */ - $module = Module::getInstanceByName('ps_checkout'); - - /** @var Version $version */ - $version = $module->getService('ps_checkout.module.version'); - - /** @var LoggerConfiguration $loggerConfiguration */ - $loggerConfiguration = $module->getService('ps_checkout.logger.configuration'); - - /** @var LoggerInterface $logger */ - $logger = $module->getService('ps_checkout.logger'); - - /** @var Router $router */ - $router = $module->getService('ps_checkout.prestashop.router'); - - $clientConfiguration = [ - 'base_url' => (new PaymentEnv())->getPaymentApiUrl(), - 'verify' => $this->getVerify(), - 'timeout' => $this->timeout, - 'exceptions' => $this->catchExceptions, - 'headers' => [ - 'Content-Type' => 'application/vnd.checkout.v1+json', // api version to use (psl side) - 'Accept' => 'application/json', - 'Authorization' => 'Bearer ' . $this->token, // Token we get from PsAccounts - 'Shop-Id' => $this->shopUid, // Shop UUID we get from PsAccounts - 'Hook-Url' => $router->getDispatchWebhookLink((int) Context::getContext()->shop->id), - 'Bn-Code' => (new ShopContext())->getBnCode(), - 'Module-Version' => $version->getSemVersion(), // version of the module - 'Prestashop-Version' => _PS_VERSION_, // prestashop version - ], - ]; - - if ( - $loggerConfiguration->isHttpEnabled() - && defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION') - && class_exists(HandlerStack::class) - && class_exists(LogMiddleware::class) - ) { - $handlerStack = HandlerStack::create(); - $handlerStack->push(new LogMiddleware($logger)); - $clientConfiguration['handler'] = $handlerStack; - } elseif ( - $loggerConfiguration->isHttpEnabled() - && defined('\GuzzleHttp\ClientInterface::VERSION') - && class_exists(Emitter::class) - && class_exists(LogSubscriber::class) - && class_exists(Formatter::class) - ) { - $emitter = new Emitter(); - $emitter->attach(new LogSubscriber( - $logger, - Formatter::DEBUG - )); - - $clientConfiguration['emitter'] = $emitter; - } - - $client = (new ClientFactory())->getClient($clientConfiguration); - } - - $this->setClient($client); - } - - /** - * @param array $options - * - * @return array - * - * @throws HttpTimeoutException - */ - protected function post(array $options = []) - { - $delay = isset($options['delay']) ? (int) $options['delay'] : 2; - $retries = isset($options['retries']) ? (int) $options['retries'] : 2; - unset($options['delay'], $options['retries']); - - return $this->postWithRetry($options, $delay, $retries); - } - - /** - * @param array $options - * @param int $delay - * @param int $retries - * - * @return array - * - * @throws HttpTimeoutException - * @throws PsCheckoutException - */ - private function postWithRetry(array $options, $delay = 2, $retries = 2) - { - try { - $response = parent::post($options); - - if ($response['httpCode'] === 401 || false !== strpos($response['exceptionMessage'], 'Unauthorized')) { - throw new PsCheckoutException('Unauthorized', PsCheckoutException::PSCHECKOUT_HTTP_UNAUTHORIZED); - } - - if (false !== $response['status']) { - return $response; - } - - if ( - isset($response['exceptionCode']) - && $response['exceptionCode'] === PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION - && false !== strpos($response['exceptionMessage'], 'cURL error 28') - ) { - throw new HttpTimeoutException($response['exceptionMessage'], PsCheckoutException::PSL_TIMEOUT); - } elseif ( - isset($response['exceptionCode']) - && $response['exceptionCode'] === PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION - ) { - throw new PsCheckoutException($response['exceptionMessage'], PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION); - } - - if ( - isset($response['body']['message']) - && ($response['body']['message'] === 'Error: ETIMEDOUT' || $response['body']['message'] === 'Error: ESOCKETTIMEDOUT') - ) { - throw new HttpTimeoutException($response['body']['message'], PsCheckoutException::PSL_TIMEOUT); - } - } catch (HttpTimeoutException $exception) { - if ($this->isRouteRetryable() && $retries > 0) { - sleep($delay); - - return $this->postWithRetry($options, $delay, $retries - 1); - } - - throw $exception; - } - - return $response; - } - - /** - * @return bool - */ - private function isRouteRetryable() - { - switch ($this->getRoute()) { - case '/payments/order/capture': - case '/payments/order/refund': - return false; - } - - return true; - } -} diff --git a/src/Api/Payment/Order.php b/src/Api/Payment/Order.php deleted file mode 100644 index 18f97a0d5..000000000 --- a/src/Api/Payment/Order.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 - */ - -namespace PrestaShop\Module\PrestashopCheckout\Api\Payment; - -use PrestaShop\Module\PrestashopCheckout\Api\Payment\Client\PaymentClient; - -/** - * Handle order requests - * - * @deprecated - */ -class Order extends PaymentClient -{ - /** - * @deprecated - * Create order to paypal api - * - * @param array $payload Cart details (json) - * - * @return array data with paypal order id or false if error - */ - public function create($payload) - { - $this->setRoute('/payments/order/create'); - - return $this->post($payload); - } - - /** - * @deprecated - * Capture order funds - * - * @param string $orderId paypal - * @param string $merchantId - * @param string $fundingSource - * - * @return array response from paypal if the payment is accepted or false if error occured - */ - public function capture($orderId, $merchantId, $fundingSource) - { - $this->setRoute('/payments/order/capture'); - - return $this->post([ - 'mode' => $fundingSource, - 'orderId' => (string) $orderId, - 'payee' => [ - 'merchant_id' => $merchantId, - ], - ]); - } - - /** - * @deprecated - * Get paypal order details - * - * @param string $orderId paypal - * - * @return array paypal order - */ - public function fetch($orderId) - { - $this->setRoute('/payments/order/fetch'); - - return $this->post([ - 'orderId' => $orderId, - ]); - } - - /** - * Authorize an order - * - * @param string $orderId paypal - * @param string $merchantId - * - * @return array paypal order - */ - public function authorize($orderId, $merchantId) - { - // TODO : waiting maasland integration - return []; - } - - /** - * @deprecated - * Refund an order - * - * @param array $payload - * - * @return array paypal order - */ - public function refund($payload) - { - $this->setRoute('/payments/order/refund'); - - return $this->post($payload); - } - - /** - * @deprecated - * Patch paypal order - * - * @param array $payload - * - * @return array response from paypal if the payment is accepted or false if error occured - */ - public function patch($payload) - { - $this->setRoute('/payments/order/update'); - - return $this->post($payload); - } -} diff --git a/src/Api/Payment/Shop.php b/src/Api/Payment/Shop.php deleted file mode 100644 index 0d13aa4be..000000000 --- a/src/Api/Payment/Shop.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 - */ - -namespace PrestaShop\Module\PrestashopCheckout\Api\Payment; - -use PrestaShop\Module\PrestashopCheckout\Api\Payment\Client\PaymentClient; -use PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration; -use PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration; - -/** - * Handle request to maasland regarding the shop/merchant status - */ -class Shop extends PaymentClient -{ - /** - * Used to notify PSL on settings update - * - * @return array - */ - public function updateSettings() - { - $this->setRoute('/payments/shop/update_settings'); - - /** @var \Ps_checkout $module */ - $module = \Module::getInstanceByName('ps_checkout'); - /** @var PrestaShopConfiguration $configuration */ - $configuration = $module->getService('ps_checkout.configuration'); - /** @var ExpressCheckoutConfiguration $ecConfiguration */ - $ecConfiguration = $module->getService('ps_checkout.express_checkout.configuration'); - - return $this->post([ - 'settings' => [ - 'cb' => (bool) $configuration->get('PS_CHECKOUT_CARD_PAYMENT_ENABLED'), - 'express_in_product' => (bool) $ecConfiguration->isProductPageEnabled(), - 'express_in_cart' => (bool) $ecConfiguration->isOrderPageEnabled(), - 'express_in_checkout' => (bool) $ecConfiguration->isCheckoutPageEnabled(), - ], - ]); - } -} diff --git a/src/Builder/Configuration/CheckoutClientConfigurationBuilder.php b/src/Builder/Configuration/CheckoutClientConfigurationBuilder.php new file mode 100755 index 000000000..84bd3d29e --- /dev/null +++ b/src/Builder/Configuration/CheckoutClientConfigurationBuilder.php @@ -0,0 +1,147 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Builder\Configuration; + +use GuzzleHttp\Event\Emitter; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Subscriber\Log\Formatter; +use GuzzleHttp\Subscriber\Log\LogSubscriber; +use GuzzleLogMiddleware\LogMiddleware; +use PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext; +use PrestaShop\Module\PrestashopCheckout\Environment\Env; +use PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration; +use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository; +use PrestaShop\Module\PrestashopCheckout\Routing\Router; +use PrestaShop\Module\PrestashopCheckout\ShopContext; +use Ps_checkout; +use Psr\Log\LoggerInterface; + +class CheckoutClientConfigurationBuilder implements HttpClientConfigurationBuilderInterface +{ + const TIMEOUT = 10; + + /** @var Env */ + private $env; + + /** @var Router */ + private $router; + + /** @var ShopContext */ + private $shopContext; + + /** @var PsAccountRepository */ + private $psAccountRepository; + + /** + * @var PrestaShopContext + */ + private $prestaShopContext; + /** + * @var LoggerConfiguration + */ + private $loggerConfiguration; + /** + * @var LoggerInterface + */ + private $logger; + + public function __construct( + Env $env, + Router $router, + ShopContext $shopContext, + PsAccountRepository $psAccountRepository, + PrestaShopContext $prestaShopContext, + LoggerConfiguration $loggerConfiguration, + LoggerInterface $logger + ) { + $this->env = $env; + $this->router = $router; + $this->shopContext = $shopContext; + $this->psAccountRepository = $psAccountRepository; + $this->prestaShopContext = $prestaShopContext; + $this->loggerConfiguration = $loggerConfiguration; + $this->logger = $logger; + } + + /** + * @return array + */ + public function build() + { + $configuration = [ + 'base_url' => $this->env->getCheckoutApiUrl(), + 'verify' => $this->getVerify(), + 'timeout' => static::TIMEOUT, + 'headers' => [ +// 'Content-Type' => 'application/vnd.checkout.v1+json', // api version to use (psl side) + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Bearer ' . $this->psAccountRepository->getIdToken(), // Token we get from PsAccounts + 'Checkout-Shop-Id' => $this->psAccountRepository->getShopUuid(), // Shop UUID we get from PsAccounts + 'Checkout-Hook-Url' => $this->router->getDispatchWebhookLink($this->prestaShopContext->getShopId()), + 'Checkout-Bn-Code' => $this->shopContext->getBnCode(), + 'Checkout-Module-Version' => Ps_checkout::VERSION, // version of the module + 'Checkout-Prestashop-Version' => _PS_VERSION_, // prestashop version + ], + ]; + + if ($this->loggerConfiguration->isHttpEnabled()) { + if ( + defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION') + && class_exists(HandlerStack::class) + && class_exists(LogMiddleware::class) + ) { + $handlerStack = HandlerStack::create(); + $handlerStack->push(new LogMiddleware($this->logger)); + $configuration['handler'] = $handlerStack; + } elseif ( + defined('\GuzzleHttp\ClientInterface::VERSION') + && class_exists(Emitter::class) + && class_exists(LogSubscriber::class) + && class_exists(Formatter::class) + ) { + $emitter = new Emitter(); + $emitter->attach(new LogSubscriber( + $this->logger, + Formatter::DEBUG + )); + + $configuration['emitter'] = $emitter; + } + } + + return $configuration; + } + + /** + * @see https://docs.guzzlephp.org/en/5.3/clients.html#verify + * + * @return true|string + */ + protected function getVerify() + { + if (defined('_PS_CACHE_CA_CERT_FILE_') && file_exists(constant('_PS_CACHE_CA_CERT_FILE_'))) { + return constant('_PS_CACHE_CA_CERT_FILE_'); + } + + return true; + } +} diff --git a/src/Http/HttpClientConfigurationBuilderInterface.php b/src/Builder/Configuration/HttpClientConfigurationBuilderInterface.php similarity index 93% rename from src/Http/HttpClientConfigurationBuilderInterface.php rename to src/Builder/Configuration/HttpClientConfigurationBuilderInterface.php index 232ab832d..999be1a68 100644 --- a/src/Http/HttpClientConfigurationBuilderInterface.php +++ b/src/Builder/Configuration/HttpClientConfigurationBuilderInterface.php @@ -18,7 +18,7 @@ * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -namespace PrestaShop\Module\PrestashopCheckout\Http; +namespace PrestaShop\Module\PrestashopCheckout\Builder\Configuration; interface HttpClientConfigurationBuilderInterface { diff --git a/src/Http/CheckoutHttpClientConfigurationBuilder.php b/src/Builder/Configuration/MaaslandHttpClientConfigurationBuilder.php similarity index 95% rename from src/Http/CheckoutHttpClientConfigurationBuilder.php rename to src/Builder/Configuration/MaaslandHttpClientConfigurationBuilder.php index e5bd032fc..2787768ba 100644 --- a/src/Http/CheckoutHttpClientConfigurationBuilder.php +++ b/src/Builder/Configuration/MaaslandHttpClientConfigurationBuilder.php @@ -18,7 +18,7 @@ * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -namespace PrestaShop\Module\PrestashopCheckout\Http; +namespace PrestaShop\Module\PrestashopCheckout\Builder\Configuration; use GuzzleHttp\Event\Emitter; use GuzzleHttp\HandlerStack; @@ -26,7 +26,7 @@ use GuzzleHttp\Subscriber\Log\LogSubscriber; use GuzzleLogMiddleware\LogMiddleware; use PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext; -use PrestaShop\Module\PrestashopCheckout\Environment\PaymentEnv; +use PrestaShop\Module\PrestashopCheckout\Environment\Env; use PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration; use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository; use PrestaShop\Module\PrestashopCheckout\Routing\Router; @@ -34,12 +34,12 @@ use Ps_checkout; use Psr\Log\LoggerInterface; -class CheckoutHttpClientConfigurationBuilder implements HttpClientConfigurationBuilderInterface +class MaaslandHttpClientConfigurationBuilder implements HttpClientConfigurationBuilderInterface { const TIMEOUT = 10; /** - * @var PaymentEnv + * @var Env */ private $paymentEnv; @@ -74,7 +74,7 @@ class CheckoutHttpClientConfigurationBuilder implements HttpClientConfigurationB private $logger; public function __construct( - PaymentEnv $paymentEnv, + Env $paymentEnv, Router $router, ShopContext $shopContext, PsAccountRepository $psAccountRepository, diff --git a/_dev/js/front/test/mocks/components/common/mark.component.mock.js b/src/Builder/Configuration/index.php similarity index 58% rename from _dev/js/front/test/mocks/components/common/mark.component.mock.js rename to src/Builder/Configuration/index.php index 3d52484df..296d682e8 100644 --- a/_dev/js/front/test/mocks/components/common/mark.component.mock.js +++ b/src/Builder/Configuration/index.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -export const MarkComponentMock = jest.fn(); +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); -MarkComponentMock.render = jest.fn(); +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); -MarkComponentMock.mockImplementation(() => ({ - render: MarkComponentMock.render -})); +header('Location: ../'); +exit; diff --git a/src/Builder/ModuleLink/index.php b/src/Builder/ModuleLink/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Builder/ModuleLink/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Builder/Payload/OrderPayloadBuilder.php b/src/Builder/Payload/OrderPayloadBuilder.php index d886b8cb8..7dfb6f8b5 100644 --- a/src/Builder/Payload/OrderPayloadBuilder.php +++ b/src/Builder/Payload/OrderPayloadBuilder.php @@ -70,6 +70,71 @@ class OrderPayloadBuilder extends Builder implements PayloadBuilderInterface */ private $isCard = false; + /** + * @var string + */ + private $fundingSource; + + /** + * @var string + */ + private $paypalCustomerId; + + /** + * @var string + */ + private $paypalVaultId; + + /** + * @var bool + */ + private $savePaymentMethod; + + /** + * @var bool + */ + private $vault = false; + + /** + * @param bool $savePaymentMethod + */ + public function setSavePaymentMethod($savePaymentMethod) + { + $this->savePaymentMethod = $savePaymentMethod; + } + + /** + * @param string $fundingSource + */ + public function setFundingSource($fundingSource) + { + $this->fundingSource = $fundingSource; + } + + /** + * @param string $paypalCustomerId + */ + public function setPaypalCustomerId($paypalCustomerId) + { + $this->paypalCustomerId = $paypalCustomerId; + } + + /** + * @param string $paypalVaultId + */ + public function setPaypalVaultId($paypalVaultId) + { + $this->paypalVaultId = $paypalVaultId; + } + + /** + * @param bool $vault + */ + public function setVault($vault) + { + $this->vault = $vault; + } + /** * @param array $cart * @param bool $isPatch @@ -109,9 +174,20 @@ public function buildFullPayload() } if ($this->isCard) { - $this->buildPaymentSourceNode(); + $this->buildCardPaymentSourceNode(); $this->buildSupplementaryDataNode(); } + + switch ($this->fundingSource) { + case 'paypal': + $this->buildPayPalPaymentSourceNode(); + break; + case 'google_pay': + $this->buildGooglePayPaymentSourceNode(); + break; + default: + break; + } } /** @@ -140,7 +216,7 @@ public function buildMinimalPayload() } if ($this->isCard) { - $this->buildPaymentSourceNode(); + $this->buildCardPaymentSourceNode(); $this->buildSupplementaryDataNode(); } } @@ -153,9 +229,9 @@ public function buildBaseNode() /** @var \Ps_checkout $module */ $module = \Module::getInstanceByName('ps_checkout'); /** @var PrestaShopConfiguration $configuration */ - $configuration = $module->getService('ps_checkout.configuration'); + $configuration = $module->getService(PrestaShopConfiguration::class); /** @var PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $module->getService('ps_checkout.paypal.configuration'); + $paypalConfiguration = $module->getService(PayPalConfiguration::class); $shopName = $configuration->get('PS_SHOP_NAME'); $merchantId = $paypalConfiguration->getMerchantId(); @@ -175,6 +251,7 @@ public function buildBaseNode() 'payee' => [ 'merchant_id' => $merchantId, ], + 'vault' => $this->vault, ]; if (true === $this->isUpdate) { @@ -285,7 +362,7 @@ public function buildApplicationContextNode() /** @var \Ps_checkout $module */ $module = \Module::getInstanceByName('ps_checkout'); /** @var Router $router */ - $router = $module->getService('ps_checkout.prestashop.router'); + $router = $module->getService(Router::class); $node['application_context'] = [ 'brand_name' => \Configuration::get( 'PS_SHOP_NAME', @@ -295,6 +372,7 @@ public function buildApplicationContextNode() ), 'shipping_preference' => $this->expressCheckout ? 'GET_FROM_FILE' : 'SET_PROVIDED_ADDRESS', 'return_url' => $router->getCheckoutValidateLink(), + 'cancel_url' => $router->getCheckoutCancelLink(), ]; $this->getPayload()->addAndMergeItems($node); @@ -396,12 +474,12 @@ public function buildAmountBreakdownNode() $this->getPayload()->addAndMergeItems($node); } - private function buildPaymentSourceNode() + private function buildCardPaymentSourceNode() { /** @var \Ps_checkout $module */ $module = \Module::getInstanceByName('ps_checkout'); /** @var PayPalConfiguration $paypalConfiguration */ - $paypalConfiguration = $module->getService('ps_checkout.paypal.configuration'); + $paypalConfiguration = $module->getService(PayPalConfiguration::class); $node = [ 'payment_source' => [ @@ -416,6 +494,23 @@ private function buildPaymentSourceNode() $node['payment_source']['card']['attributes']['verification']['method'] = $paypalConfiguration->getHostedFieldsContingencies(); } + if ($this->paypalVaultId) { + unset($node['payment_source']['card']['billing_address']); + $node['payment_source']['card']['vault_id'] = $this->paypalVaultId; + } + + if ($this->paypalCustomerId) { + $node['payment_source']['card']['attributes']['customer'] = [ + 'id' => $this->paypalCustomerId, + ]; + } + + if ($this->savePaymentMethod) { + $node['payment_source']['card']['attributes']['vault'] = [ + 'store_in_vault' => 'ON_SUCCESS', + ]; + } + $this->getPayload()->addAndMergeItems($node); } @@ -426,7 +521,6 @@ private function buildSupplementaryDataNode() 'supplementary_data' => [ 'card' => [ 'level_2' => [ -// 'invoice_id' => '', 'tax_total' => $payload['amount']['breakdown']['tax_total'], ], 'level_3' => [ @@ -606,4 +700,68 @@ public function getExpressCheckout() { return $this->expressCheckout; } + + private function buildPayPalPaymentSourceNode() + { + $data = []; + + if ($this->paypalVaultId) { + return; + // $data['vault_id'] = $this->paypalVaultId; + } + + if ($this->paypalCustomerId) { + $data['attributes']['customer'] = [ + 'id' => $this->paypalCustomerId, + ]; + } + + if ($this->savePaymentMethod) { + $data['attributes']['vault'] = [ + 'store_in_vault' => 'ON_SUCCESS', + 'usage_pattern' => 'IMMEDIATE', + 'usage_type' => 'MERCHANT', + 'customer_type' => 'CONSUMER', + 'permit_multiple_payment_tokens' => false, + ]; + } + + if (empty($data)) { + return; + } + + $node = [ + 'payment_source' => [ + 'paypal' => $data, + ], + ]; + + $this->getPayload()->addAndMergeItems($node); + } + + private function buildGooglePayPaymentSourceNode() + { + /** @var \Ps_checkout $module */ + $module = \Module::getInstanceByName('ps_checkout'); + /** @var PayPalConfiguration $paypalConfiguration */ + $paypalConfiguration = $module->getService(PayPalConfiguration::class); + + if (!$paypalConfiguration->is3dSecureEnabled()) { + return; + } + + $node = [ + 'payment_source' => [ + 'google_pay' => [ + 'attributes' => [ + 'verification' => [ + 'method' => $paypalConfiguration->getHostedFieldsContingencies(), + ], + ], + ], + ], + ]; + + $this->getPayload()->addAndMergeItems($node); + } } diff --git a/src/Cart/Cache/index.php b/src/Cart/Cache/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Cart/Cache/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Cart/Exception/index.php b/src/Cart/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Cart/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Cart/ValueObject/index.php b/src/Cart/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Cart/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Cart/index.php b/src/Cart/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Cart/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Checkout/CheckoutChecker.php b/src/Checkout/CheckoutChecker.php index e52f6190e..a4c25a45b 100644 --- a/src/Checkout/CheckoutChecker.php +++ b/src/Checkout/CheckoutChecker.php @@ -55,16 +55,18 @@ public function __construct(LoggerInterface $logger) public function continueWithAuthorization($cartId, $orderPayPal) { if ($orderPayPal['status'] === 'COMPLETED') { - throw new PsCheckoutException(sprintf('PayPal Order %s is already captured', $orderPayPal['id'])); + throw new PsCheckoutException(sprintf('PayPal Order %s is already captured', $orderPayPal['id']), PsCheckoutException::PAYPAL_ORDER_ALREADY_CAPTURED); } - if (isset($orderPayPal['payment_source']['card'])) { + $paymentSource = isset($orderPayPal['payment_source']) ? key($orderPayPal['payment_source']) : ''; + + if (in_array($paymentSource, ['google_pay', 'card'], true)) { $card3DSecure = (new Card3DSecure())->continueWithAuthorization($orderPayPal); $this->logger->info( '3D Secure authentication result', [ - 'authentication_result' => isset($orderPayPal['payment_source']['card']['authentication_result']) ? $orderPayPal['payment_source']['card']['authentication_result'] : null, + 'authentication_result' => isset($orderPayPal['payment_source'][$paymentSource]['authentication_result']) ? $orderPayPal['payment_source'][$paymentSource]['authentication_result'] : null, 'decision' => str_replace( [ (string) Card3DSecure::NO_DECISION, diff --git a/src/Checkout/Command/index.php b/src/Checkout/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Checkout/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Checkout/CommandHandler/SavePayPalOrderStatusCommandHandler.php b/src/Checkout/CommandHandler/SavePayPalOrderStatusCommandHandler.php index 00483385b..fff4db8e4 100644 --- a/src/Checkout/CommandHandler/SavePayPalOrderStatusCommandHandler.php +++ b/src/Checkout/CommandHandler/SavePayPalOrderStatusCommandHandler.php @@ -24,6 +24,7 @@ use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; use PrestaShop\Module\PrestashopCheckout\Checkout\Command\SavePayPalOrderStatusCommand; use PrestaShop\Module\PrestashopCheckout\Checkout\Exception\PsCheckoutSessionException; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use PsCheckoutCart; @@ -33,10 +34,15 @@ class SavePayPalOrderStatusCommandHandler * @var PsCheckoutCartRepository */ private $psCheckoutCartRepository; + /** + * @var PayPalOrderRepository + */ + private $payPalOrderRepository; - public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository) + public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository, PayPalOrderRepository $payPalOrderRepository) { $this->psCheckoutCartRepository = $psCheckoutCartRepository; + $this->payPalOrderRepository = $payPalOrderRepository; } /** @@ -46,6 +52,14 @@ public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository) */ public function handle(SavePayPalOrderStatusCommand $command) { + // TODO: To be repurposed + try { + $payPalOrder = $this->payPalOrderRepository->getPayPalOrderById($command->getOrderPayPalId()); + $payPalOrder->setStatus($command->getOrderPayPalStatus()); + $this->payPalOrderRepository->savePayPalOrder($payPalOrder); + } catch (Exception $exception) { + } + try { /** @var PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $this->psCheckoutCartRepository->findOneByPayPalOrderId($command->getOrderPayPalId()->getValue()); diff --git a/src/Checkout/CommandHandler/index.php b/src/Checkout/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Checkout/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Checkout/Event/index.php b/src/Checkout/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Checkout/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Checkout/EventSubscriber/CheckoutEventSubscriber.php b/src/Checkout/EventSubscriber/CheckoutEventSubscriber.php index 1849b37a9..e30561c4a 100644 --- a/src/Checkout/EventSubscriber/CheckoutEventSubscriber.php +++ b/src/Checkout/EventSubscriber/CheckoutEventSubscriber.php @@ -57,15 +57,16 @@ class CheckoutEventSubscriber implements EventSubscriberInterface * @var CheckoutChecker */ private $checkoutChecker; - /** - * @param Ps_checkout $module + * @var PsCheckoutCartRepository */ - public function __construct(Ps_checkout $module) + private $psCheckoutCartRepository; + + public function __construct(CheckoutChecker $checkoutChecker, CommandBusInterface $commandBus, PsCheckoutCartRepository $psCheckoutCartRepository) { - $this->module = $module; - $this->checkoutChecker = $this->module->getService('ps_checkout.checkout.checker'); - $this->commandBus = $this->module->getService('ps_checkout.bus.command'); + $this->checkoutChecker = $checkoutChecker; + $this->commandBus = $commandBus; + $this->psCheckoutCartRepository = $psCheckoutCartRepository; } /** @@ -117,54 +118,70 @@ public function updatePaymentMethodSelected(CheckoutCompletedEvent $event) * @throws PrestaShopDatabaseException * @throws PrestaShopException * @throws PsCheckoutException + * @throws HttpTimeoutException */ public function proceedToPayment(CheckoutCompletedEvent $event) { + $payPalOrderId = $event->getPayPalOrderId()->getValue(); + + /** @var GetPayPalOrderForCheckoutCompletedQueryResult $getPayPalOrderForCheckoutCompletedQueryResult */ + $getPayPalOrderForCheckoutCompletedQueryResult = $this->commandBus->handle(new GetPayPalOrderForCheckoutCompletedQuery( + $payPalOrderId + )); + + $payPalOrder = $getPayPalOrderForCheckoutCompletedQueryResult->getPayPalOrder(); + try { - /** @var GetPayPalOrderForCheckoutCompletedQueryResult $getPayPalOrderForCheckoutCompletedQueryResult */ - $getPayPalOrderForCheckoutCompletedQueryResult = $this->module->getService('ps_checkout.bus.command')->handle(new GetPayPalOrderForCheckoutCompletedQuery( - $event->getPayPalOrderId()->getValue() - )); - } catch (HttpTimeoutException $exception) { - $this->commandBus->handle(new CreateOrderCommand($event->getPayPalOrderId()->getValue())); - - return; - } + $this->checkoutChecker->continueWithAuthorization($event->getCartId()->getValue(), $payPalOrder); + } catch (PsCheckoutException $exception) { + if ($exception->getCode() === PsCheckoutException::PAYPAL_ORDER_ALREADY_CAPTURED) { + $capture = isset($payPalOrder['purchase_units'][0]['payments']['captures'][0]) ? $payPalOrder['purchase_units'][0]['payments']['captures'][0] : null; + $this->commandBus->handle(new CreateOrderCommand($payPalOrderId, $capture)); - $this->checkoutChecker->continueWithAuthorization($event->getCartId()->getValue(), $getPayPalOrderForCheckoutCompletedQueryResult->getPayPalOrder()); + return; + } else { + throw $exception; + } + } try { $this->commandBus->handle( new CapturePayPalOrderCommand( - $event->getPayPalOrderId()->getValue(), + $payPalOrderId, $event->getFundingSource() ) ); } catch (PayPalException $exception) { if ($exception->getCode() === PayPalException::ORDER_NOT_APPROVED) { - $this->commandBus->handle(new CreateOrderCommand($event->getPayPalOrderId()->getValue())); + $this->commandBus->handle(new CreateOrderCommand($payPalOrderId)); return; } elseif ($exception->getCode() === PayPalException::RESOURCE_NOT_FOUND) { - /** @var PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); - $psCheckoutCart = $psCheckoutCartRepository->findOneByPayPalOrderId($event->getPayPalOrderId()->getValue()); + $psCheckoutCart = $this->psCheckoutCartRepository->findOneByPayPalOrderId($payPalOrderId); if (Validate::isLoadedObject($psCheckoutCart)) { $psCheckoutCart->paypal_status = PsCheckoutCart::STATUS_CANCELED; - $psCheckoutCartRepository->save($psCheckoutCart); + $this->psCheckoutCartRepository->save($psCheckoutCart); } throw $exception; } elseif ($exception->getCode() === PayPalException::ORDER_ALREADY_CAPTURED) { + if (isset($payPalOrder['purchase_units'][0]['payments']['captures'][0])) { + $capture = $payPalOrder['purchase_units'][0]['payments']['captures'][0]; + } else { + $payPalOrderQuery = new GetPayPalOrderForCheckoutCompletedQuery($payPalOrderId); + + /** @var GetPayPalOrderForCheckoutCompletedQueryResult $getPayPalOrderForCheckoutCompletedQueryResult */ + $getPayPalOrderForCheckoutCompletedQueryResult = $this->commandBus->handle($payPalOrderQuery); + $payPalOrder = $getPayPalOrderForCheckoutCompletedQueryResult->getPayPalOrder(); + $capture = isset($payPalOrder['purchase_units'][0]['payments']['captures'][0]) ? $payPalOrder['purchase_units'][0]['payments']['captures'][0] : null; + } + $this->commandBus->handle(new CreateOrderCommand($payPalOrderId, $capture)); + return; } else { throw $exception; } - } catch (HttpTimeoutException $exception) { - $this->commandBus->handle(new CreateOrderCommand($event->getPayPalOrderId()->getValue())); - - return; } } } diff --git a/src/Checkout/EventSubscriber/index.php b/src/Checkout/EventSubscriber/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Checkout/EventSubscriber/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Checkout/Exception/index.php b/src/Checkout/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Checkout/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Checkout/index.php b/src/Checkout/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Checkout/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/CommandBus/index.php b/src/CommandBus/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/CommandBus/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Configuration/index.php b/src/Configuration/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Configuration/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Context/PrestaShopContext.php b/src/Context/PrestaShopContext.php index 889e4b8a0..065169d9d 100644 --- a/src/Context/PrestaShopContext.php +++ b/src/Context/PrestaShopContext.php @@ -74,4 +74,14 @@ public function getCurrentThemeName() { return $this->context->shop->theme_name; } + + public function customerIsLogged() + { + return $this->context->customer->isLogged(); + } + + public function getCustomerId() + { + return (int) $this->context->customer->id; + } } diff --git a/src/Context/index.php b/src/Context/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Context/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Controller/AbstractFrontController.php b/src/Controller/AbstractFrontController.php index 6de73b31c..f823f56d3 100644 --- a/src/Controller/AbstractFrontController.php +++ b/src/Controller/AbstractFrontController.php @@ -22,11 +22,15 @@ use Exception; use ModuleFrontController; +use PrestaShop\Module\PrestashopCheckout\Customer\Exception\CustomerException; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use Ps_checkout; +use Tools; class AbstractFrontController extends ModuleFrontController { /** - * @var \Ps_checkout + * @var Ps_checkout */ public $module; @@ -73,4 +77,30 @@ protected function exitWithResponse(array $response = []) exit; } + + /** + * @return CustomerId|null + * + * @throws CustomerException + */ + protected function getCustomerId() + { + return $this->context->customer->isLogged() ? new CustomerId($this->context->customer->id) : null; + } + + /** + * @return int + */ + protected function getPageSize() + { + return (int) Tools::getValue('pageSize', 10); + } + + /** + * @return int + */ + protected function getPageNumber() + { + return (int) Tools::getValue('pageNumber', 1); + } } diff --git a/src/Controller/index.php b/src/Controller/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Controller/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Customer/Exception/index.php b/src/Customer/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Customer/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Customer/ValueObject/index.php b/src/Customer/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Customer/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Customer/index.php b/src/Customer/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Customer/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Database/TableManager.php b/src/Database/TableManager.php index 501385036..e721240e3 100644 --- a/src/Database/TableManager.php +++ b/src/Database/TableManager.php @@ -59,7 +59,7 @@ public function createTable() `id_cart` int unsigned NOT NULL, `paypal_intent` varchar(20) DEFAULT "CAPTURE", `paypal_order` varchar(20) NULL, - `paypal_status` varchar(20) NULL, + `paypal_status` varchar(30) NULL, `paypal_funding` varchar(20) NULL, `paypal_token` text DEFAULT NULL, `paypal_token_expire` datetime NULL, @@ -80,6 +80,81 @@ public function createTable() PRIMARY KEY (`name`, `id_shop`), INDEX (`id_shop`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_order` ( + `id` varchar(50) NOT NULL, + `id_cart` int unsigned NOT NULL, + `status` varchar(30) NOT NULL, + `intent` varchar(50) DEFAULT "CAPTURE", + `funding_source` varchar(50) NOT NULL, + `payment_source` text, + `environment` varchar(50) NOT NULL, + `is_card_fields` tinyint(1) NOT NULL, + `is_express_checkout` tinyint(1) NOT NULL, + `customer_intent` varchar(50), + `payment_token_id` varchar(50), + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_capture` ( + `id` varchar(50) NOT NULL, + `id_order` varchar(50) NOT NULL, + `status` varchar(30) NOT NULL, + `final_capture` tinyint(1) NOT NULL, + `created_at` varchar(50) NOT NULL, + `updated_at` varchar(50) NOT NULL, + `seller_protection` text, + `seller_receivable_breakdown` text, + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_refund` ( + `id` varchar(50) NOT NULL, + `id_order` varchar(50) NOT NULL, + `status` varchar(30) NOT NULL, + `invoice_id` varchar(50) NOT NULL, + `custom_id` varchar(50) NOT NULL, + `acquirer_reference_number` varchar(50) NOT NULL, + `seller_payable_breakdown` text, + `id_order_slip` INT UNSIGNED, + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_authorization` ( + `id` varchar(50) NOT NULL, + `id_order` varchar(50) NOT NULL, + `status` varchar(30) NOT NULL, + `expiration_time` varchar(50) NOT NULL, + `seller_protection` text, + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_purchase_unit` ( + `id_order` varchar(50) NOT NULL, + `checksum` varchar(50) NOT NULL, + `reference_id` varchar(50) NOT NULL, + `items` text, + PRIMARY KEY (`reference_id`, `id_order`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_customer` ( + `id_customer` int unsigned NOT NULL, + `paypal_customer_id` varchar(50) NOT NULL, + PRIMARY KEY (`id_customer`, `paypal_customer_id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_payment_token` ( + `id` INT UNSIGNED AUTO_INCREMENT, + `token_id` varchar(50) NOT NULL, + `paypal_customer_id` varchar(50) NOT NULL, + `payment_source` varchar(50) NOT NULL, + `data` text NOT NULL, + `merchant_id` varchar(50) NOT NULL, + `status` varchar(50) NOT NULL, + `is_favorite` tinyint(1) unsigned DEFAULT 0 NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `token_id_merchant_id_paypal_customer_id` (`token_id`, `merchant_id`, `paypal_customer_id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; '); $this->checkTable(); @@ -131,6 +206,10 @@ public function checkTable() if ($field['Field'] === 'paypal_token' && $field['Type'] !== 'text') { $this->db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` CHANGE `paypal_token` `paypal_token` text DEFAULT NULL;'); } + + if ($field['Field'] === 'paypal_status' && $field['Type'] !== 'varchar(30)') { + $this->db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` CHANGE `paypal_status` `paypal_status` varchar(30) NULL;'); + } } } diff --git a/src/Dispatcher/OrderDispatcher.php b/src/Dispatcher/OrderDispatcher.php index d3a91a8ba..35f2eeba6 100644 --- a/src/Dispatcher/OrderDispatcher.php +++ b/src/Dispatcher/OrderDispatcher.php @@ -22,6 +22,7 @@ use Module; use PrestaShop\Module\PrestashopCheckout\Event\EventDispatcherInterface; +use PrestaShop\Module\PrestashopCheckout\Event\SymfonyEventDispatcherAdapter; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderApprovalReversedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderApprovedEvent; @@ -33,6 +34,10 @@ use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\Event\PayPalCaptureReversedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\Exception\PayPalCaptureException; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Event\PayPalCaptureRefundedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenCreatedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenDeletedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenDeletionInitiatedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; use Ps_checkout; use Psr\Log\LoggerInterface; @@ -47,6 +52,9 @@ class OrderDispatcher implements Dispatcher const PS_CHECKOUT_ORDER_APPROVED = 'CheckoutOrderApproved'; const PS_CHECKOUT_ORDER_COMPLETED = 'CheckoutOrderCompleted'; const PS_CHECKOUT_ORDER_APPROVAL_REVERSED = 'CheckoutPaymentApprovalReversed'; + const PS_CHECKOUT_VAULT_PAYMENT_TOKEN_CREATED = 'VaultPaymentTokenCreated'; + const PS_CHECKOUT_VAULT_PAYMENT_TOKEN_DELETED = 'VaultPaymentTokenDeleted'; + const PS_CHECKOUT_VAULT_PAYMENT_TOKEN_DELETION_INITIATED = 'VaultPaymentTokenDeletionInitiated'; /** * Dispatch the Event Type to manage the merchant status @@ -67,11 +75,14 @@ public function dispatchEventType($payload) $module = Module::getInstanceByName('ps_checkout'); /** @var EventDispatcherInterface $eventDispatcher */ - $eventDispatcher = $module->getService('ps_checkout.event.dispatcher'); + $eventDispatcher = $module->getService(SymfonyEventDispatcherAdapter::class); /** @var LoggerInterface $logger */ $logger = $module->getService('ps_checkout.logger'); + /** @var PayPalConfiguration $payPalConfiguration */ + $payPalConfiguration = $module->getService(PayPalConfiguration::class); + switch ($payload['eventType']) { case static::PS_CHECKOUT_PAYMENT_COMPLETED: $eventDispatcher->dispatch(new PayPalCaptureCompletedEvent($payload['resource']['id'], $payload['orderId'], $payload['resource'])); @@ -97,6 +108,15 @@ public function dispatchEventType($payload) case static::PS_CHECKOUT_ORDER_APPROVAL_REVERSED: $eventDispatcher->dispatch(new PayPalOrderApprovalReversedEvent($payload['orderId'], $payload['resource'])); break; + case static::PS_CHECKOUT_VAULT_PAYMENT_TOKEN_CREATED: + $eventDispatcher->dispatch(new PaymentTokenCreatedEvent($payload['resource'], $payPalConfiguration->getMerchantId())); + break; + case static::PS_CHECKOUT_VAULT_PAYMENT_TOKEN_DELETED: + $eventDispatcher->dispatch(new PaymentTokenDeletedEvent($payload['resource'])); + break; + case static::PS_CHECKOUT_VAULT_PAYMENT_TOKEN_DELETION_INITIATED: + $eventDispatcher->dispatch(new PaymentTokenDeletionInitiatedEvent($payload['resource'])); + break; default: $logger->warning( 'Unknown webhook, cannot be processed.', diff --git a/src/Environment/Env.php b/src/Environment/Env.php index d3a8aefb3..f5d4fa6af 100644 --- a/src/Environment/Env.php +++ b/src/Environment/Env.php @@ -20,6 +20,9 @@ namespace PrestaShop\Module\PrestashopCheckout\Environment; +use PrestaShop\Module\PrestashopCheckout\PayPal\Mode; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; + /** * Get the current environment used: prod or test // sandbox or live */ @@ -52,7 +55,7 @@ class Env */ protected $mode; - public function __construct() + public function __construct(PayPalConfiguration $payPalConfiguration) { foreach (self::FILE_ENV_LIST as $env => $fileName) { if (!file_exists(_PS_MODULE_DIR_ . 'ps_checkout/' . $fileName)) { @@ -67,10 +70,7 @@ public function __construct() break; } - /** @var \Ps_checkout $module */ - $module = \Module::getInstanceByName('ps_checkout'); - - $this->setMode($module->getService('ps_checkout.paypal.configuration')->getPaymentMode()); + $this->setMode($payPalConfiguration->getPaymentMode()); } /** @@ -126,4 +126,45 @@ public function getEnv($name) return getenv($name); } + + /** + * getter for paymentApiUrl + */ + public function getPaymentApiUrl() + { + if (Mode::SANDBOX === $this->mode) { + return $this->getEnv('PAYMENT_API_URL_SANDBOX'); + } + + return $this->getEnv('PAYMENT_API_URL_LIVE'); + } + + /** + * @return string + */ + public function getCheckoutApiUrl() + { + if (Mode::SANDBOX === $this->mode) { + return $this->getEnv('CHECKOUT_API_URL_SANDBOX'); + } + + return $this->getEnv('CHECKOUT_API_URL_LIVE'); + } + + /** + * @return string + */ + public function getPaypalClientId() + { + if (Mode::SANDBOX === $this->mode) { + return $this->getEnv('PAYPAL_CLIENT_ID_SANDBOX'); + } + + return $this->getEnv('PAYPAL_CLIENT_ID_LIVE'); + } + + public function getBnCode() + { + return $this->getEnv('PAYPAL_BN_CODE'); + } } diff --git a/src/Environment/PaymentEnv.php b/src/Environment/PaymentEnv.php deleted file mode 100644 index 7faa4ba7a..000000000 --- a/src/Environment/PaymentEnv.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 - */ - -namespace PrestaShop\Module\PrestashopCheckout\Environment; - -use PrestaShop\Module\PrestashopCheckout\PayPal\Mode; - -/** - * Allow to set the differents api key / api link depending on - */ -class PaymentEnv extends Env -{ - /** - * Url api maasland (production live by default) - * - * @var string - */ - private $paymentApiUrl; - - public function __construct() - { - parent::__construct(); - - $this->setEnvDependingOnMode(); - } - - private function setEnvDependingOnMode() - { - $this->setPaymentApiUrl($this->getEnv('PAYMENT_API_URL_LIVE')); - - if (Mode::SANDBOX === $this->mode) { - $this->setPaymentApiUrl($this->getEnv('PAYMENT_API_URL_SANDBOX')); - } - } - - /** - * getter for paymentApiUrl - */ - public function getPaymentApiUrl() - { - return $this->paymentApiUrl; - } - - /** - * setter for paymentApiUrl - * - * @param string $url - */ - private function setPaymentApiUrl($url) - { - $this->paymentApiUrl = $url; - } -} diff --git a/src/Environment/PaypalEnv.php b/src/Environment/PaypalEnv.php deleted file mode 100644 index abce416a6..000000000 --- a/src/Environment/PaypalEnv.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 - */ - -namespace PrestaShop\Module\PrestashopCheckout\Environment; - -use PrestaShop\Module\PrestashopCheckout\PayPal\Mode; - -/** - * Allow to set the differents api key / api link depending on - */ -class PaypalEnv extends Env -{ - /** - * PayPal client ID (production live by default) - * - * @var string - */ - private $paypalClientId; - - public function __construct() - { - parent::__construct(); - - $this->setEnvDependingOnMode(); - } - - private function setEnvDependingOnMode() - { - $this->setPaypalClientId($this->getEnv('PAYPAL_CLIENT_ID_LIVE')); - - if (Mode::SANDBOX === $this->mode) { - $this->setPaypalClientId($this->getEnv('PAYPAL_CLIENT_ID_SANDBOX')); - } - } - - /** - * getter for paypalClientId - */ - public function getPaypalClientId() - { - return $this->paypalClientId; - } - - /** - * setter for paypalClientId - * - * @param string $clientId - */ - private function setPaypalClientId($clientId) - { - $this->paypalClientId = $clientId; - } -} diff --git a/src/Event/EventDispatcherInterface.php b/src/Event/EventDispatcherInterface.php index d30df28af..815f6495f 100644 --- a/src/Event/EventDispatcherInterface.php +++ b/src/Event/EventDispatcherInterface.php @@ -20,25 +20,17 @@ namespace PrestaShop\Module\PrestashopCheckout\Event; -use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface; - -if (interface_exists(PsrEventDispatcherInterface::class)) { - interface EventDispatcherInterface extends PsrEventDispatcherInterface - { - } -} else { +/** + * Defines a dispatcher for events. + */ +interface EventDispatcherInterface +{ /** - * Defines a dispatcher for events. + * Provide all relevant listeners with an event to process. + * + * @param object $event the object to process + * + * @return object the Event that was passed, now modified by listeners */ - interface EventDispatcherInterface - { - /** - * Provide all relevant listeners with an event to process. - * - * @param object $event the object to process - * - * @return object the Event that was passed, now modified by listeners - */ - public function dispatch($event); - } + public function dispatch($event); } diff --git a/src/Event/index.php b/src/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Exception/InvalidRequestException.php b/src/Exception/InvalidRequestException.php new file mode 100644 index 000000000..16f9fed76 --- /dev/null +++ b/src/Exception/InvalidRequestException.php @@ -0,0 +1,39 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Exception; + +class InvalidRequestException extends PsCheckoutException +{ + const UNKNOWN = 0; + const INVALID_ARRAY_MAX_ITEMS = 1; + const INVALID_ARRAY_MIN_ITEMS = 2; + const INVALID_COUNTRY_CODE = 3; + const INVALID_PARAMETER_SYNTAX = 4; + const INVALID_STRING_LENGTH = 5; + const INVALID_PARAMETER_VALUE = 6; + const MISSING_REQUIRED_PARAMETER = 7; + const NOT_SUPPORTED = 8; + const PAYPAL_REQUEST_ID_REQUIRED = 9; + const MALFORMED_REQUEST_JSON = 10; + const FIELD_NOT_PATCHABLE = 11; + const AMOUNT_NOT_PATCHABLE = 12; + const INVALID_PATCH_OPERATION = 13; +} diff --git a/_dev/js/front/src/components/common/payment-options-loader.component.js b/src/Exception/NotAuthorizedException.php similarity index 52% rename from _dev/js/front/src/components/common/payment-options-loader.component.js rename to src/Exception/NotAuthorizedException.php index 773dbf962..0e1c3bc82 100644 --- a/_dev/js/front/src/components/common/payment-options-loader.component.js +++ b/src/Exception/NotAuthorizedException.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -import { BaseComponent } from '../../core/dependency-injection/base.component'; -export class PaymentOptionsLoaderComponent extends BaseComponent { - static Inject = { - querySelectorService: 'QuerySelectorService' - }; +namespace PrestaShop\Module\PrestashopCheckout\Exception; - created() { - this.data.loader = this.querySelectorService.getPaymentOptionsLoader(); - } - - hide() { - this.data.loader && (this.data.loader.style.display = 'none'); - } +class NotAuthorizedException extends PsCheckoutException +{ + const UNKNOWN = 0; + const PERMISSION_DENIED = 1; + const PERMISSION_DENIED_FOR_DONATION_ITEMS = 2; + const MALFORMED_REQUEST = 3; + const PAYEE_ACCOUNT_NOT_SUPPORTED = 4; + const PAYEE_ACCOUNT_NOT_VERIFIED = 5; + const PAYEE_NOT_CONSENTED = 6; + const INVALID_TOKEN = 7; + const CONSENT_NEEDED = 8; } diff --git a/src/Exception/PayPalException.php b/src/Exception/PayPalException.php index 710268a8b..e5acf56d8 100644 --- a/src/Exception/PayPalException.php +++ b/src/Exception/PayPalException.php @@ -173,4 +173,15 @@ class PayPalException extends PsCheckoutException const PERMISSION_DENIED_FOR_DONATION_ITEMS = 148; const MALFORMED_REQUEST_JSON = 149; const PAYPAL_REQUEST_ID_REQUIRED = 150; + const NOT_ENABLED_TO_VAULT_PAYMENT_SOURCE = 151; + const SETUP_TOKEN_ALREADY_TOKENIZED = 152; + const TOKEN_NOT_FOUND = 153; + const PAYPAL_REQUEST_ID_PREVIOUSLY_USED = 154; + const OPERATION_NOT_SUPPORTED = 155; + const INVALID_SECURITY_CODE = 156; + const INVALID_INTEGER_MIN_VALUE = 157; + const INVALID_EXPIRY_DATE = 158; + const EXACTLY_ONE_FIELD_REQUIRED = 159; + const CREDIT_CARD_NUMBER_IS_INVALID = 160; + const CARD_EXPIRATION_YEAR_IS_INVALID = 161; } diff --git a/src/Exception/PsCheckoutException.php b/src/Exception/PsCheckoutException.php index 627675825..1b5256976 100644 --- a/src/Exception/PsCheckoutException.php +++ b/src/Exception/PsCheckoutException.php @@ -89,4 +89,6 @@ class PsCheckoutException extends \Exception const CART_ADDRESS_DELIVERY_INVALID = 57; const CART_DELIVERY_OPTION_INVALID = 58; const PSCHECKOUT_HTTP_UNAUTHORIZED = 59; + + const PAYPAL_ORDER_ALREADY_CAPTURED = 60; } diff --git a/src/Exception/UnprocessableEntityException.php b/src/Exception/UnprocessableEntityException.php new file mode 100644 index 000000000..f3b117bdd --- /dev/null +++ b/src/Exception/UnprocessableEntityException.php @@ -0,0 +1,100 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Exception; + +class UnprocessableEntityException extends PsCheckoutException +{ + const UNKNOWN = 0; + const AMOUNT_MISMATCH = 1; + const BILLING_ADDRESS_INVALID = 2; + const CANNOT_BE_NEGATIVE = 3; + const CANNOT_BE_ZERO_OR_NEGATIVE = 4; + const CARD_EXPIRED = 5; + const CITY_REQUIRED = 6; + const DECIMAL_PRECISION = 7; + const DONATION_ITEMS_NOT_SUPPORTED = 8; + const DUPLICATE_REFERENCE_ID = 9; + const INVALID_CURRENCY_CODE = 10; + const INVALID_PAYER_ID = 11; + const ITEM_TOTAL_MISMATCH = 12; + const ITEM_TOTAL_REQUIRED = 13; + const MAX_VALUE_EXCEEDED = 14; + const MISSING_PICKUP_ADDRESS = 15; + const MULTI_CURRENCY_ORDER = 16; + const MULTIPLE_ITEM_CATEGORIES = 17; + const MULTIPLE_SHIPPING_ADDRESS_NOT_SUPPORTED = 18; + const MULTIPLE_SHIPPING_TYPE_NOT_SUPPORTED = 19; + const PAYEE_ACCOUNT_INVALID = 20; + const PAYEE_ACCOUNT_LOCKED_OR_CLOSED = 21; + const PAYEE_ACCOUNT_RESTRICTED = 22; + const REFERENCE_ID_REQUIRED = 23; + const PAYMENT_SOURCE_CANNOT_BE_USED = 24; + const PAYMENT_SOURCE_DECLINED_BY_PROCESSOR = 25; + const PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED = 26; + const POSTAL_CODE_REQUIRED = 27; + const SHIPPING_ADDRESS_INVALID = 28; + const TAX_TOTAL_MISMATCH = 29; + const TAX_TOTAL_REQUIRED = 30; + const UNSUPPORTED_INTENT = 31; + const UNSUPPORTED_PAYMENT_INSTRUCTION = 32; + const SHIPPING_TYPE_NOT_SUPPORTED_FOR_CLIENT = 33; + const UNSUPPORTED_SHIPPING_TYPE = 34; + const SHIPPING_OPTION_NOT_SELECTED = 35; + const SHIPPING_OPTIONS_NOT_SUPPORTED = 36; + const MULTIPLE_SHIPPING_OPTION_SELECTED = 37; + const PREFERRED_SHIPPING_OPTION_AMOUNT_MISMATCH = 38; + const CARD_CLOSED = 39; + const ORDER_CANNOT_BE_SAVED = 40; + const SAVE_ORDER_NOT_SUPPORTED = 41; + const PUI_DUPLICATE_ORDER = 42; + const INVALID_JSON_POINTER_FORMAT = 43; + const INVALID_PARAMETER = 44; + const NOT_PATCHABLE = 45; + const UNSUPPORTED_PATCH_PARAMETER_VALUE = 46; + const PATCH_VALUE_REQUIRED = 47; + const PATCH_PATH_REQUIRED = 48; + const REFERENCE_ID_NOT_FOUND = 49; + const ORDER_ALREADY_COMPLETED = 50; + const AGREEMENT_ALREADY_CANCELLED = 51; + const BILLING_AGREEMENT_NOT_FOUND = 52; + const COMPLIANCE_VIOLATION = 53; + const DOMESTIC_TRANSACTION_REQUIRED = 54; + const DUPLICATE_INVOICE_ID = 55; + const INSTRUMENT_DECLINED = 56; + const ORDER_NOT_APPROVED = 57; + const MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED = 58; + const PAYEE_BLOCKED_TRANSACTION = 59; + const PAYER_ACCOUNT_LOCKED_OR_CLOSED = 60; + const PAYER_ACCOUNT_RESTRICTED = 61; + const PAYER_CANNOT_PAY = 62; + const TRANSACTION_LIMIT_EXCEEDED = 63; + const TRANSACTION_RECEIVING_LIMIT_EXCEEDED = 64; + const TRANSACTION_REFUSED = 65; + const REDIRECT_PAYER_FOR_ALTERNATE_FUNDING = 66; + const ORDER_ALREADY_CAPTURED = 67; + const TRANSACTION_BLOCKED_BY_PAYEE = 68; + const AUTH_CAPTURE_NOT_ENABLED = 69; + const NOT_ENABLED_FOR_CARD_PROCESSING = 70; + const PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING = 71; + const INVALID_PICKUP_ADDRESS = 72; + const CANNOT_PROCESS_REFUNDS = 73; + const INVALID_REFUND_AMOUNT = 74; +} diff --git a/src/ExpressCheckout/index.php b/src/ExpressCheckout/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/ExpressCheckout/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/FundingSource/FundingSource.php b/src/FundingSource/FundingSource.php index 547722237..9f636926c 100644 --- a/src/FundingSource/FundingSource.php +++ b/src/FundingSource/FundingSource.php @@ -52,6 +52,19 @@ class FundingSource */ public $isToggleable; + /** + * @var string|null + */ + public $paymentSource; + /** + * @var bool + */ + public $isFavorite; + /** + * @var string|null + */ + public $customMark; + /** * @param string $name * @param string $label @@ -59,8 +72,9 @@ class FundingSource * @param array $countries * @param bool $isEnabled * @param bool $isToggleable + * @param string|null $paymentSource */ - public function __construct($name, $label, $position, $countries, $isEnabled, $isToggleable) + public function __construct($name, $label, $position, $countries, $isEnabled, $isToggleable, $paymentSource = null, $isFavorite = false, $customMark = null) { $this->name = $name; $this->label = $label; @@ -68,5 +82,8 @@ public function __construct($name, $label, $position, $countries, $isEnabled, $i $this->countries = $countries; $this->isEnabled = $isEnabled; $this->isToggleable = $isToggleable; + $this->paymentSource = $paymentSource; + $this->isFavorite = $isFavorite; + $this->customMark = $customMark; } } diff --git a/src/FundingSource/FundingSourceCollectionBuilder.php b/src/FundingSource/FundingSourceCollectionBuilder.php index 762d7afda..a97fb3344 100644 --- a/src/FundingSource/FundingSourceCollectionBuilder.php +++ b/src/FundingSource/FundingSourceCollectionBuilder.php @@ -107,6 +107,18 @@ public function create() $blik->setIsEnabled($this->configuration->isEnabled('blik')); $blik->setCountries($this->eligibilityConstraint->getCountries('blik')); - return [$paypal, $paylater, $card, $bancontact, $eps, $giropay, $ideal, $mybank, $p24, $blik]; + // Google pay + $googlePay = new FundingSourceEntity('google_pay'); + $googlePay->setPosition($this->configuration->getPosition('google_pay', 11)); + $googlePay->setIsEnabled($this->configuration->isEnabled('google_pay')); + $googlePay->setCountries($this->eligibilityConstraint->getCountries('google_pay')); + + // Apple pay + $applePay = new FundingSourceEntity('apple_pay'); + $applePay->setPosition($this->configuration->getPosition('apple_pay', 12)); + $applePay->setIsEnabled($this->configuration->isEnabled('apple_pay')); + $applePay->setCountries($this->eligibilityConstraint->getCountries('apple_pay')); + + return [$paypal, $paylater, $card, $bancontact, $eps, $giropay, $ideal, $mybank, $p24, $blik, $googlePay, $applePay]; } } diff --git a/src/FundingSource/FundingSourceConfiguration.php b/src/FundingSource/FundingSourceConfiguration.php index 01a25b409..e16033be2 100644 --- a/src/FundingSource/FundingSourceConfiguration.php +++ b/src/FundingSource/FundingSourceConfiguration.php @@ -67,6 +67,6 @@ public function isEnabled($fundingSourceName) return (bool) $fundingSource['active']; } - return true; + return false; } } diff --git a/src/FundingSource/FundingSourceConfigurationRepository.php b/src/FundingSource/FundingSourceConfigurationRepository.php index c4936eaa3..6e0ce9863 100644 --- a/src/FundingSource/FundingSourceConfigurationRepository.php +++ b/src/FundingSource/FundingSourceConfigurationRepository.php @@ -50,12 +50,13 @@ public function __construct(PrestaShopContext $context) /** * @param string $name + * @param int|null $shopId * * @return array|null */ - public function get($name) + public function get($name, $shopId = null) { - $fundingSources = $this->getAll(); + $fundingSources = $this->getAll($shopId); if (null === $fundingSources) { return null; @@ -71,42 +72,53 @@ public function get($name) } /** + * @param int|null $shopId + * * @return array|null */ - public function getAll() + public function getAll($shopId = null) { - if (null !== $this->fundingSources) { - return $this->fundingSources; + $shopId = (int) ($shopId === null ? $this->context->getShopId() : $shopId); + + if (isset($this->fundingSources[$shopId]) && null !== $this->fundingSources[$shopId]) { + return $this->fundingSources[$shopId]; } $data = $this->db->executeS(' SELECT `name`, `active`, `position` FROM `' . _DB_PREFIX_ . 'pscheckout_funding_source` - WHERE `id_shop` = ' . (int) $this->context->getShopId() + WHERE `id_shop` = ' . $shopId ); if (!empty($data)) { - $this->fundingSources = $data; + $this->fundingSources[$shopId] = $data; } - return $this->fundingSources; + return isset($this->fundingSources[$shopId]) ? $this->fundingSources[$shopId] : null; } /** * @param array $data + * @param int|null $shopId * * @return bool + * + * @throws \PrestaShopDatabaseException */ - public function save($data) + public function save($data, $shopId = null) { - if ($this->get($data['name'])) { + $shopId = (int) ($shopId === null ? $this->context->getShopId() : $shopId); + + $this->fundingSources[$shopId] = null; + + if ($this->get($data['name'], $shopId)) { return (bool) $this->db->update( 'pscheckout_funding_source', [ 'position' => (int) $data['position'], 'active' => (int) $data['isEnabled'], ], - '`name` = "' . pSQL($data['name']) . '" AND `id_shop` = ' . (int) $this->context->getShopId() + '`name` = "' . pSQL($data['name']) . '" AND `id_shop` = ' . $shopId ); } @@ -116,7 +128,7 @@ public function save($data) 'name' => pSQL($data['name']), 'position' => (int) $data['position'], 'active' => (int) $data['isEnabled'], - 'id_shop' => (int) $this->context->getShopId(), + 'id_shop' => $shopId, ] ); } diff --git a/src/FundingSource/FundingSourceEligibilityConstraint.php b/src/FundingSource/FundingSourceEligibilityConstraint.php index f6284123e..de29a6d48 100644 --- a/src/FundingSource/FundingSourceEligibilityConstraint.php +++ b/src/FundingSource/FundingSourceEligibilityConstraint.php @@ -41,8 +41,27 @@ public function getCountries($fundingSourceName) 'mybank' => ['IT'], 'p24' => ['PL'], 'paylater' => ['FR', 'GB', 'US', 'ES', 'IT'], + 'google_pay' => ['AU', 'AT', 'BE', 'BG', 'CA', 'CN', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LI', 'LT', 'LU', 'MK', 'MT', 'NL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'US'], + 'apple_pay' => ['AU', 'AT', 'BE', 'BG', 'CA', 'CN', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LI', 'LT', 'LU', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'US'], ]; return $countries[$fundingSourceName]; } + + /** + * Get eligible currencies for PayPal funding sources + * + * @param string $fundingSourceName + * + * @return array + */ + public function getCurrencies($fundingSourceName) + { + $currencies = [ + 'google_pay' => ['AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'THB', 'TWD', 'USD'], + 'apple_pay' => ['AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'THB', 'TWD', 'USD'], + ]; + + return $currencies[$fundingSourceName]; + } } diff --git a/src/FundingSource/FundingSourceInstaller.php b/src/FundingSource/FundingSourceInstaller.php index e764707c1..150e6d870 100644 --- a/src/FundingSource/FundingSourceInstaller.php +++ b/src/FundingSource/FundingSourceInstaller.php @@ -27,9 +27,11 @@ class FundingSourceInstaller /** * Saves Funding Sources for the first time into the database * + * @param int|null $shopId + * * @return bool */ - public function createFundingSources() + public function createFundingSources($shopId = null) { $fundingSourceConfigurationRepository = new FundingSourceConfigurationRepository(new PrestaShopContext()); $fundingSourceCollectionBuilder = new FundingSourceCollectionBuilder( @@ -42,10 +44,21 @@ public function createFundingSources() $fundingSourceConfigurationRepository->save([ 'name' => $fundingSourceEntity->getName(), 'position' => $fundingSourceEntity->getPosition(), - 'isEnabled' => $fundingSourceEntity->getIsEnabled() ? 1 : 0, - ]); + 'isEnabled' => !in_array($fundingSourceEntity->getName(), ['google_pay', 'apple_pay']) ? 1 : 0, + ], $shopId); } return true; } + + public function createFundingSourcesOnAllShops() + { + $result = true; + + foreach (\Shop::getShops(false, null, true) as $shopId) { + $result &= $this->createFundingSources((int) $shopId); + } + + return $result; + } } diff --git a/src/FundingSource/FundingSourcePresenter.php b/src/FundingSource/FundingSourcePresenter.php index db30b33a9..4e91198b1 100644 --- a/src/FundingSource/FundingSourcePresenter.php +++ b/src/FundingSource/FundingSourcePresenter.php @@ -20,6 +20,8 @@ namespace PrestaShop\Module\PrestashopCheckout\FundingSource; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Entity\PaymentToken; +use PrestaShop\Module\PrestashopCheckout\Provider\PaymentMethodLogoProvider; use PrestaShop\Module\PrestashopCheckout\Repository\CountryRepository; class FundingSourcePresenter @@ -33,15 +35,23 @@ class FundingSourcePresenter * @var CountryRepository */ private $country; + /** + * @var PaymentMethodLogoProvider + */ + private $paymentMethodLogoProvider; /** * @param FundingSourceTranslationProvider $translation * @param CountryRepository $country */ - public function __construct(FundingSourceTranslationProvider $translation, CountryRepository $country) - { + public function __construct( + FundingSourceTranslationProvider $translation, + CountryRepository $country, + PaymentMethodLogoProvider $paymentMethodLogoProvider + ) { $this->translation = $translation; $this->country = $country; + $this->paymentMethodLogoProvider = $paymentMethodLogoProvider; } /** @@ -60,7 +70,42 @@ public function present($entity, $isAdmin) $entity->getPosition(), $isAdmin ? $this->country->getCountryNames($entity->getCountries()) : $entity->getCountries(), $entity->getIsEnabled(), - $entity->getIsToggleable() + $entity->getIsToggleable(), + null, + null, + in_array($name, ['google_pay', 'apple_pay']) ? $this->paymentMethodLogoProvider->getLogoByPaymentSource([$name => []]) : null + ); + } + + /** + * @param PaymentToken $paymentToken + * + * @return FundingSource + */ + public function presentPaymentToken(PaymentToken $paymentToken) + { + $paymentSource = $paymentToken->getData()['payment_source'][$paymentToken->getPaymentSource()]; + + if ($paymentToken->getPaymentSource() === 'card') { + $fundingSourceName = $this->translation->getVaultedPaymentMethodName( + (isset($paymentSource['brand']) ? $paymentSource['brand'] : '') . (isset($paymentSource['last_digits']) ? ' *' . $paymentSource['last_digits'] : '') + ); + } else { + $fundingSourceName = $this->translation->getVaultedPaymentMethodName( + isset($paymentSource['email_address']) ? $paymentSource['email_address'] : '' + ); + } + + return new FundingSource( + 'token-' . $paymentToken->getId()->getValue(), + $fundingSourceName, + 0, + [], + true, + false, + $paymentToken->getPaymentSource(), + $paymentToken->isFavorite(), + $this->paymentMethodLogoProvider->getLogoByPaymentSource($paymentToken->getData()['payment_source']) ); } } diff --git a/src/FundingSource/FundingSourceProvider.php b/src/FundingSource/FundingSourceProvider.php index 62a594c0d..596f32340 100644 --- a/src/FundingSource/FundingSourceProvider.php +++ b/src/FundingSource/FundingSourceProvider.php @@ -20,6 +20,9 @@ namespace PrestaShop\Module\PrestashopCheckout\FundingSource; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; + class FundingSourceProvider { /** @@ -31,17 +34,31 @@ class FundingSourceProvider * @var FundingSourcePresenter */ private $presenter; + /** + * @var PaymentTokenRepository + */ + private $paymentTokenRepository; + /** + * @var PayPalConfiguration + */ + private $payPalConfiguration; /** * @param FundingSourceCollectionBuilder $fundingSourceCollectionBuilder * @param FundingSourcePresenter $presenter + * @param PaymentTokenRepository $paymentTokenRepository + * @param PayPalConfiguration $payPalConfiguration */ public function __construct( FundingSourceCollectionBuilder $fundingSourceCollectionBuilder, - FundingSourcePresenter $presenter + FundingSourcePresenter $presenter, + PaymentTokenRepository $paymentTokenRepository, + PayPalConfiguration $payPalConfiguration ) { $this->collection = new FundingSourceCollection($fundingSourceCollectionBuilder->create()); $this->presenter = $presenter; + $this->paymentTokenRepository = $paymentTokenRepository; + $this->payPalConfiguration = $payPalConfiguration; } /** @@ -66,4 +83,22 @@ public function getAll($isAdmin = false) return $fundingSources; } + + /** + * @param int $customerId + * + * @return FundingSource[] + * + * @throws \PrestaShopDatabaseException + */ + public function getSavedTokens($customerId) + { + if ((int) $customerId && $this->payPalConfiguration->isVaultingEnabled()) { + return array_map(function ($paymentToken) { + return $this->presenter->presentPaymentToken($paymentToken); + }, $this->paymentTokenRepository->findByPrestaShopCustomerId((int) $customerId, true, $this->payPalConfiguration->getMerchantId())); + } + + return []; + } } diff --git a/src/FundingSource/FundingSourceTranslationProvider.php b/src/FundingSource/FundingSourceTranslationProvider.php index 8e83281c1..9b1a8f08e 100644 --- a/src/FundingSource/FundingSourceTranslationProvider.php +++ b/src/FundingSource/FundingSourceTranslationProvider.php @@ -64,6 +64,9 @@ public function __construct(Module $module) 'maxima' => 'Maxima', 'mercadopago' => 'Mercado Pago', 'sepa' => 'SEPA', + 'google_pay' => 'Google Pay', + 'apple_pay' => 'Apple Pay', + 'token' => $module->l('Pay with %s', 'fundingsourcetranslationprovider'), ]; $payByTranslation = $module->l('Pay by %s', 'fundingsourcetranslationprovider'); @@ -98,6 +101,16 @@ public function getPaymentMethodName($fundingSource) return isset($this->fundingSourceNames[$fundingSource]) ? $this->fundingSourceNames[$fundingSource] : ''; } + /** + * @param string $identifier + * + * @return string + */ + public function getVaultedPaymentMethodName($identifier) + { + return str_replace('%s', $identifier, $this->fundingSourceNames['token']); + } + /** * @return array */ diff --git a/src/Handler/CreatePaypalOrderHandler.php b/src/Handler/CreatePaypalOrderHandler.php index cb34dc75d..beb2d808f 100644 --- a/src/Handler/CreatePaypalOrderHandler.php +++ b/src/Handler/CreatePaypalOrderHandler.php @@ -27,7 +27,7 @@ use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Handler\Response\ResponseApiHandler; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use PrestaShop\Module\PrestashopCheckout\Presenter\Cart\CartPresenter; use PrestaShop\Module\PrestashopCheckout\ShopContext; use Ps_checkout; @@ -41,12 +41,8 @@ class CreatePaypalOrderHandler */ private $context; - public function __construct(Context $context = null) + public function __construct(Context $context) { - if (null === $context) { - $context = Context::getContext(); - } - $this->context = $context; } @@ -70,7 +66,7 @@ public function handle($expressCheckout = false, $isCardPayment = false, $update $module = Module::getInstanceByName('ps_checkout'); /** @var ShopContext $shopContext */ - $shopContext = $module->getService('ps_checkout.context.shop'); + $shopContext = $module->getService(ShopContext::class); $builder->setIsCard($isCardPayment); @@ -93,8 +89,8 @@ public function handle($expressCheckout = false, $isCardPayment = false, $update $payload = $builder->presentPayload()->getArray(); - /** @var CheckoutHttpClient $checkoutHttpClient */ - $checkoutHttpClient = $module->getService('ps_checkout.http.client.checkout'); + /** @var MaaslandHttpClient $checkoutHttpClient */ + $checkoutHttpClient = $module->getService(MaaslandHttpClient::class); // Create the paypal order or update it try { diff --git a/src/Http/CheckoutHttpClient.php b/src/Http/CheckoutHttpClient.php old mode 100644 new mode 100755 index 0d03828cf..392484fad --- a/src/Http/CheckoutHttpClient.php +++ b/src/Http/CheckoutHttpClient.php @@ -25,160 +25,159 @@ use Http\Client\Exception\NetworkException; use Http\Client\Exception\RequestException; use Http\Client\Exception\TransferException; -use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; -use PrestaShop\Module\PrestashopCheckout\PayPalError; +use PrestaShop\Module\PrestashopCheckout\Builder\Configuration\CheckoutClientConfigurationBuilder; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -class CheckoutHttpClient implements HttpClientInterface +class CheckoutHttpClient extends PsrHttpClientAdapter implements CheckoutHttpClientInterface { - /** - * @var HttpClientInterface - */ - private $httpClient; + const SUFFIX_IDENTITY = '/v1/identity'; + const SUFFIX_ORDER = '/v1/order'; + const SUFFIX_VAULT = '/v1/vault-merchant'; - public function __construct(HttpClientInterface $httpClient) + public function __construct(CheckoutClientConfigurationBuilder $configurationBuilder) { - $this->httpClient = $httpClient; + parent::__construct($configurationBuilder->build()); } /** - * @param array $payload - * @param array $options + * @param RequestInterface $request * * @return ResponseInterface * - * @throws NetworkException - * @throws HttpException - * @throws RequestException - * @throws TransferException - * @throws PayPalException + * @throws HttpException|RequestException|TransferException|NetworkException */ - public function createOrder(array $payload, array $options = []) + public function sendRequest(RequestInterface $request) { - return $this->sendRequest(new Request('POST', '/payments/order/create', $options, json_encode($payload))); + try { + return parent::sendRequest($request); + } catch (NetworkException $exception) { + throw $exception; + // Thrown when the request cannot be completed because of network issues. + // No response here + } catch (HttpException $exception) { + // Thrown when a response was received but the request itself failed. + // There a response here + // So this one contains why response failed with Maasland error response + if ($exception->getResponse()->getStatusCode() === 500) { + // Internal Server Error: retry then stop using Maasland for XXX times after X failed retries, requires a circuit breaker + } + if ($exception->getResponse()->getStatusCode() === 503) { + // Service Unavailable: we should stop using Maasland, requires a circuit breaker + } + // response status code 4XX throw exception to be catched on specific method + throw $exception; // Avoid this to be catched next + } catch (RequestException $exception) { + throw $exception; + // No response here + } catch (TransferException $exception) { + throw $exception; + // others without response + } } /** - * @param array $payload + * @param string $payload //Payload JSON * @param array $options * * @return ResponseInterface - * - * @throws NetworkException - * @throws HttpException - * @throws RequestException - * @throws TransferException - * @throws PayPalException */ - public function updateOrder(array $payload, array $options = []) + public function createOrder($payload, array $options = []) { - return $this->sendRequest(new Request('POST', '/payments/order/update', $options, json_encode($payload))); + return $this->sendRequest(new Request('POST', '/payments/order/create', $options, $payload)); } /** - * @param array $payload + * @param string $payload * @param array $options * * @return ResponseInterface - * - * @throws NetworkException - * @throws HttpException - * @throws RequestException - * @throws TransferException - * @throws PayPalException */ - public function fetchOrder(array $payload, array $options = []) + public function updateOrder($payload, array $options = []) { - return $this->sendRequest(new Request('POST', '/payments/order/fetch', $options, json_encode($payload))); + return $this->sendRequest(new Request('POST', '/payments/order/update', $options, $payload)); } /** - * @param array $payload + * @param string $payload * @param array $options * * @return ResponseInterface - * - * @throws NetworkException - * @throws HttpException - * @throws RequestException - * @throws TransferException - * @throws PayPalException */ - public function captureOrder(array $payload, array $options = []) + public function fetchOrder($payload, array $options = []) { - return $this->sendRequest(new Request('POST', '/payments/order/capture', $options, json_encode($payload))); + return $this->sendRequest(new Request('POST', '/payments/order/fetch', $options, $payload)); } /** - * @param array $payload + * @param string $payload * @param array $options * * @return ResponseInterface - * - * @throws NetworkException - * @throws HttpException - * @throws RequestException - * @throws TransferException - * @throws PayPalException */ - public function refundOrder(array $payload, array $options = []) + public function captureOrder($payload, array $options = []) { - return $this->sendRequest(new Request('POST', '/payments/order/refund', $options, json_encode($payload))); + return $this->sendRequest(new Request('POST', '/payments/order/capture', $options, $payload)); } /** - * @param RequestInterface $request + * @param string $payload + * @param array $options * * @return ResponseInterface - * - * @throws NetworkException - * @throws HttpException - * @throws RequestException - * @throws TransferException - * @throws PayPalException */ - public function sendRequest(RequestInterface $request) + public function refundOrder($payload, array $options = []) { - try { - $response = $this->httpClient->sendRequest($request); - } catch (HttpException $exception) { - $response = $exception->getResponse(); - $message = $this->extractMessage(json_decode($response->getBody(), true)); - - if ($message) { - (new PayPalError($message))->throwException($exception); - } + return $this->sendRequest(new Request('POST', '/payments/order/refund', $options, $payload)); + } - throw $exception; - } + /** + * @param string $merchantId + * @param PaymentTokenId $paymentTokenId + * @param array $options + * + * @return ResponseInterface + */ + public function getPaymentTokenStatus($merchantId, PaymentTokenId $paymentTokenId, array $options = []) + { + $tokenId = $paymentTokenId->getValue(); - return $response; + return $this->sendRequest(new Request('GET', self::SUFFIX_VAULT . "/payment-token/$merchantId/$tokenId/status", $options)); } /** - * @param array $body + * @param string $merchantId + * @param PaymentTokenId $paymentTokenId + * @param array $options * - * @return string + * @return ResponseInterface */ - private function extractMessage(array $body) + public function deletePaymentToken($merchantId, PaymentTokenId $paymentTokenId, array $options = []) { - if (isset($body['details'][0]['issue']) && preg_match('/^[0-9A-Z_]+$/', $body['details'][0]['issue']) === 1) { - return $body['details'][0]['issue']; - } + $tokenId = $paymentTokenId->getValue(); - if (isset($body['error']) && preg_match('/^[0-9A-Z_]+$/', $body['error']) === 1) { - return $body['error']; - } + return $this->sendRequest(new Request('DELETE', self::SUFFIX_VAULT . "/payment-token/$merchantId/$tokenId", $options)); + } - if (isset($body['message']) && preg_match('/^[0-9A-Z_]+$/', $body['message']) === 1) { - return $body['message']; - } + public function getUserIdToken($merchantId, PayPalCustomerId $payPalCustomerId = null, $options = []) + { + $payload = [ + 'payer_id' => $merchantId, + ]; - if (isset($body['name']) && preg_match('/^[0-9A-Z_]+$/', $body['name']) === 1) { - return $body['name']; + if ($payPalCustomerId) { + $payload['customer_id'] = $payPalCustomerId->getValue(); } - return ''; + return $this->sendRequest( + new Request( + 'POST', + self::SUFFIX_IDENTITY . '/oauth2/token', + $options, + json_encode($payload) + ) + ); } } diff --git a/_dev/js/front/src/core/dependency-injection/base.component.js b/src/Http/CheckoutHttpClientInterface.php similarity index 54% rename from _dev/js/front/src/core/dependency-injection/base.component.js rename to src/Http/CheckoutHttpClientInterface.php index 930f985a4..053855809 100644 --- a/_dev/js/front/src/core/dependency-injection/base.component.js +++ b/src/Http/CheckoutHttpClientInterface.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -import { BaseClass } from './base.class'; -export class BaseComponent extends BaseClass { - constructor(app, props = {}) { - super(app); +namespace PrestaShop\Module\PrestashopCheckout\Http; - this.data = {}; - this.props = props; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; +use Psr\Http\Message\ResponseInterface; - this.children = {}; - - this.created(); - } - - created() {} - - /** - * @return {this} - */ - render() { - return this; - } +interface CheckoutHttpClientInterface +{ + /** + * @param string $payload + * + * @return ResponseInterface + * + * @throws PayPalOrderException + */ + public function createOrder($payload); } diff --git a/src/Http/HttpClientFactory.php b/src/Http/HttpClientFactory.php index 6c1ca840c..be7c52daa 100644 --- a/src/Http/HttpClientFactory.php +++ b/src/Http/HttpClientFactory.php @@ -20,6 +20,8 @@ namespace PrestaShop\Module\PrestashopCheckout\Http; +use PrestaShop\Module\PrestashopCheckout\Builder\Configuration\HttpClientConfigurationBuilderInterface; + class HttpClientFactory { /** diff --git a/src/Http/MaaslandHttpClient.php b/src/Http/MaaslandHttpClient.php new file mode 100644 index 000000000..e68bbc29e --- /dev/null +++ b/src/Http/MaaslandHttpClient.php @@ -0,0 +1,219 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Http; + +use GuzzleHttp\Psr7\Request; +use Http\Client\Exception\HttpException; +use Http\Client\Exception\NetworkException; +use Http\Client\Exception\RequestException; +use Http\Client\Exception\TransferException; +use PrestaShop\Module\PrestashopCheckout\Exception\HttpTimeoutException; +use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; +use PrestaShop\Module\PrestashopCheckout\PayPalError; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +class MaaslandHttpClient implements HttpClientInterface +{ + /** + * @var HttpClientInterface + */ + private $httpClient; + + public function __construct(HttpClientInterface $httpClient) + { + $this->httpClient = $httpClient; + } + + /** + * @param array $payload + * @param array $options + * + * @return ResponseInterface + * + * @throws NetworkException + * @throws HttpException + * @throws RequestException + * @throws TransferException + * @throws PayPalException + * @throws HttpTimeoutException + */ + public function createOrder(array $payload, array $options = []) + { + return $this->sendRequest(new Request('POST', '/payments/order/create', $options, json_encode($payload))); + } + + /** + * @param array $payload + * @param array $options + * + * @return ResponseInterface + * + * @throws NetworkException + * @throws HttpException + * @throws RequestException + * @throws TransferException + * @throws PayPalException + * @throws HttpTimeoutException + */ + public function updateOrder(array $payload, array $options = []) + { + return $this->sendRequest(new Request('POST', '/payments/order/update', $options, json_encode($payload))); + } + + /** + * @param array $payload + * @param array $options + * + * @return ResponseInterface + * + * @throws NetworkException + * @throws HttpException + * @throws RequestException + * @throws TransferException + * @throws PayPalException + * @throws HttpTimeoutException + */ + public function fetchOrder(array $payload, array $options = []) + { + return $this->sendRequest(new Request('POST', '/payments/order/fetch', $options, json_encode($payload))); + } + + /** + * @param array $payload + * @param array $options + * + * @return ResponseInterface + * + * @throws NetworkException + * @throws HttpException + * @throws RequestException + * @throws TransferException + * @throws PayPalException + * @throws HttpTimeoutException + */ + public function captureOrder(array $payload, array $options = []) + { + return $this->sendRequest(new Request('POST', '/payments/order/capture', $options, json_encode($payload))); + } + + /** + * @param array $payload + * @param array $options + * + * @return ResponseInterface + * + * @throws NetworkException + * @throws HttpException + * @throws RequestException + * @throws TransferException + * @throws PayPalException + * @throws HttpTimeoutException + */ + public function refundOrder(array $payload, array $options = []) + { + return $this->sendRequest(new Request('POST', '/payments/order/refund', $options, json_encode($payload))); + } + + /** + * @param RequestInterface $request + * + * @return ResponseInterface + * + * @throws NetworkException + * @throws HttpException + * @throws RequestException + * @throws TransferException + * @throws PayPalException + */ + public function sendRequest(RequestInterface $request) + { + try { + $response = $this->httpClient->sendRequest($request); + } catch (HttpException $exception) { + $response = $exception->getResponse(); + $body = json_decode($response->getBody(), true); + $message = $this->extractMessage($body); + + if ($message) { + (new PayPalError($message))->throwException($exception); + } + + throw $exception; + } + + return $response; + } + + /** + * @param array $body + * + * @return string + */ + private function extractMessage(array $body) + { + if (isset($body['details'][0]['issue']) && preg_match('/^[0-9A-Z_]+$/', $body['details'][0]['issue']) === 1) { + return $body['details'][0]['issue']; + } + + if (isset($body['error']) && preg_match('/^[0-9A-Z_]+$/', $body['error']) === 1) { + return $body['error']; + } + + if (isset($body['message']) && preg_match('/^[0-9A-Z_]+$/', $body['message']) === 1) { + return $body['message']; + } + + if (isset($body['name']) && preg_match('/^[0-9A-Z_]+$/', $body['name']) === 1) { + return $body['name']; + } + + return ''; + } + + /** + * Tells if the webhook came from the PSL + * + * @param array $payload + * + * @return array + */ + public function getShopSignature(array $payload, array $options = []) + { + $response = $this->sendRequest(new Request('POST', '/payments/shop/verify_webhook_signature', $options, json_encode($payload))); + + return json_decode($response->getBody(), true); + } + + /** + * Used to notify PSL on settings update + * + * @return array + * + * @throws PayPalException + */ + public function updateSettings(array $payload) + { + $response = $this->sendRequest(new Request('POST', '/payments/shop/update_settings', [], json_encode($payload))); + + return json_decode($response->getBody(), true); + } +} diff --git a/src/Http/index.php b/src/Http/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Http/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/OnBoarding/index.php b/src/OnBoarding/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/OnBoarding/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Command/index.php b/src/Order/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/CommandHandler/CreateOrderCommandHandler.php b/src/Order/CommandHandler/CreateOrderCommandHandler.php index 4a7e7921d..2a6d0ee4c 100644 --- a/src/Order/CommandHandler/CreateOrderCommandHandler.php +++ b/src/Order/CommandHandler/CreateOrderCommandHandler.php @@ -77,6 +77,10 @@ class CreateOrderCommandHandler extends AbstractOrderCommandHandler * @var CheckOrderAmount */ private $checkOrderAmount; + /** + * @var FundingSourceTranslationProvider + */ + private $fundingSourceTranslationProvider; public function __construct( ContextStateManager $contextStateManager, @@ -84,7 +88,8 @@ public function __construct( PsCheckoutCartRepository $psCheckoutCartRepository, OrderStateMapper $psOrderStateMapper, Ps_checkout $module, - CheckOrderAmount $checkOrderAmount + CheckOrderAmount $checkOrderAmount, + FundingSourceTranslationProvider $fundingSourceTranslationProvider ) { $this->contextStateManager = $contextStateManager; $this->eventDispatcher = $eventDispatcher; @@ -92,6 +97,7 @@ public function __construct( $this->psOrderStateMapper = $psOrderStateMapper; $this->module = $module; $this->checkOrderAmount = $checkOrderAmount; + $this->fundingSourceTranslationProvider = $fundingSourceTranslationProvider; } /** @@ -167,9 +173,6 @@ public function handle(CreateOrderCommand $command) $orderStateId = $this->psOrderStateMapper->getIdByKey(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PENDING); } - /** @var FundingSourceTranslationProvider $fundingSourceTranslationProvider */ - $fundingSourceTranslationProvider = $this->module->getService('ps_checkout.funding_source.translation'); - if ($this->shouldSetCartContext($this->contextStateManager->getContext(), $cart)) { $this->setCartContext($this->contextStateManager, $cart); } @@ -187,7 +190,7 @@ public function handle(CreateOrderCommand $command) (int) $cart->id, $orderStateId, $paidAmount, - $fundingSourceTranslationProvider->getPaymentMethodName($fundingSource), + $this->fundingSourceTranslationProvider->getPaymentMethodName($fundingSource), null, $extraVars, $currencyId, diff --git a/src/Order/CommandHandler/index.php b/src/Order/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Event/index.php b/src/Order/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/EventSubscriber/OrderEventSubscriber.php b/src/Order/EventSubscriber/OrderEventSubscriber.php index 2d4f2f4e3..59dff925a 100644 --- a/src/Order/EventSubscriber/OrderEventSubscriber.php +++ b/src/Order/EventSubscriber/OrderEventSubscriber.php @@ -21,10 +21,10 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\EventSubscriber; +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; use PrestaShop\Module\PrestashopCheckout\Order\Event\OrderCreatedEvent; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; use PrestaShop\Module\PrestashopCheckout\Order\Matrice\Command\UpdateOrderMatriceCommand; -use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use PrestaShopException; @@ -33,26 +33,19 @@ class OrderEventSubscriber implements EventSubscriberInterface { - /** - * @var Ps_checkout - */ - private $module; - /** * @var PsCheckoutCartRepository */ private $psCheckoutCartRepository; - /** - * @param Ps_checkout $module - * @param PsCheckoutCartRepository $psCheckoutCartRepository + * @var CommandBusInterface */ - public function __construct( - Ps_checkout $module, - PsCheckoutCartRepository $psCheckoutCartRepository - ) { - $this->module = $module; + private $commandBus; + + public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository, Ps_checkout $module) + { $this->psCheckoutCartRepository = $psCheckoutCartRepository; + $this->commandBus = $module->getService('ps_checkout.bus.command'); } /** @@ -70,17 +63,16 @@ public static function getSubscribedEvents() * * @return void * - * @throws PrestaShopException * @throws OrderException * @throws PayPalOrderException - * @throws OrderStateException + * @throws PrestaShopException */ public function updateOrderMatrice(OrderCreatedEvent $event) { $cartId = $event->getCartId()->getValue(); $psCheckoutCart = $this->psCheckoutCartRepository->findOneByCartId($cartId); - $this->module->getService('ps_checkout.bus.command')->handle(new UpdateOrderMatriceCommand( + $this->commandBus->handle(new UpdateOrderMatriceCommand( $event->getOrderId()->getValue(), $psCheckoutCart->getPaypalOrderId() )); diff --git a/src/Order/EventSubscriber/index.php b/src/Order/EventSubscriber/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/EventSubscriber/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Exception/index.php b/src/Order/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Matrice/Command/index.php b/src/Order/Matrice/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Matrice/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Matrice/CommandHandler/index.php b/src/Order/Matrice/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Matrice/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Matrice/Event/index.php b/src/Order/Matrice/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Matrice/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Matrice/index.php b/src/Order/Matrice/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Matrice/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Payment/Exception/index.php b/src/Order/Payment/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Payment/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Payment/ValueObject/index.php b/src/Order/Payment/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Payment/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Payment/index.php b/src/Order/Payment/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Payment/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Query/GetOrderForApprovalReversedQueryResult.php b/src/Order/Query/GetOrderForApprovalReversedQueryResult.php index 96cc0b578..668e862bb 100644 --- a/src/Order/Query/GetOrderForApprovalReversedQueryResult.php +++ b/src/Order/Query/GetOrderForApprovalReversedQueryResult.php @@ -22,7 +22,6 @@ use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; -use PrestaShop\Module\PrestashopCheckout\Order\State\ValueObject\OrderStateId; use PrestaShop\Module\PrestashopCheckout\Order\ValueObject\OrderId; class GetOrderForApprovalReversedQueryResult @@ -32,11 +31,6 @@ class GetOrderForApprovalReversedQueryResult */ private $orderId; - /** - * @var OrderStateId - */ - private $currentStateId; - /** * @var bool */ @@ -49,7 +43,6 @@ class GetOrderForApprovalReversedQueryResult /** * @param int $orderId - * @param int $currentStateId * @param bool $hasBeenPaid * @param bool $hasBeenCanceled * @@ -58,12 +51,10 @@ class GetOrderForApprovalReversedQueryResult */ public function __construct( $orderId, - $currentStateId, $hasBeenPaid, $hasBeenCanceled ) { $this->orderId = new OrderId($orderId); - $this->currentStateId = new OrderStateId($currentStateId); $this->hasBeenPaid = $hasBeenPaid; $this->hasBeenCanceled = $hasBeenCanceled; } @@ -76,14 +67,6 @@ public function getOrderId() return $this->orderId; } - /** - * @return OrderStateId - */ - public function getCurrentStateId() - { - return $this->currentStateId; - } - /** * @return bool */ diff --git a/src/Order/Query/GetOrderForPaymentCompletedQueryResult.php b/src/Order/Query/GetOrderForPaymentCompletedQueryResult.php index 166a7889a..ff49f9bef 100644 --- a/src/Order/Query/GetOrderForPaymentCompletedQueryResult.php +++ b/src/Order/Query/GetOrderForPaymentCompletedQueryResult.php @@ -23,8 +23,6 @@ use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartException; use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; -use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; -use PrestaShop\Module\PrestashopCheckout\Order\State\ValueObject\OrderStateId; use PrestaShop\Module\PrestashopCheckout\Order\ValueObject\OrderId; class GetOrderForPaymentCompletedQueryResult @@ -39,11 +37,6 @@ class GetOrderForPaymentCompletedQueryResult */ private $cartId; - /** - * @var OrderStateId - */ - private $currentStateId; - /** * @var bool */ @@ -54,11 +47,6 @@ class GetOrderForPaymentCompletedQueryResult */ private $totalAmount; - /** - * @var string - */ - private $totalAmountPaid; - /** * @var int */ @@ -77,35 +65,28 @@ class GetOrderForPaymentCompletedQueryResult /** * @param int $orderId * @param int $cartId - * @param int $currentStateId * @param bool $hasBeenPaid * @param string $totalAmount - * @param string $totalAmountPaid * @param int $currencyId * @param string $paymentMethod * @param int|null $orderPaymentId * * @throws OrderException * @throws CartException - * @throws OrderStateException */ public function __construct( $orderId, $cartId, - $currentStateId, $hasBeenPaid, $totalAmount, - $totalAmountPaid, $currencyId, $paymentMethod, $orderPaymentId = null ) { $this->orderId = new OrderId($orderId); $this->cartId = new CartId($cartId); - $this->currentStateId = new OrderStateId($currentStateId); $this->hasBeenPaid = $hasBeenPaid; $this->totalAmount = $totalAmount; - $this->totalAmountPaid = $totalAmountPaid; $this->currencyId = $currencyId; $this->paymentMethod = $paymentMethod; $this->orderPaymentId = $orderPaymentId; @@ -127,14 +108,6 @@ public function getCartId() return $this->cartId; } - /** - * @return OrderStateId - */ - public function getCurrentStateId() - { - return $this->currentStateId; - } - /** * @return bool */ @@ -151,14 +124,6 @@ public function getTotalAmount() return $this->totalAmount; } - /** - * @return string - */ - public function getTotalAmountPaid() - { - return $this->totalAmountPaid; - } - /** * @return int */ diff --git a/src/Order/Query/GetOrderForPaymentDeniedQueryResult.php b/src/Order/Query/GetOrderForPaymentDeniedQueryResult.php index 76a343cc3..4f9e2b3ee 100644 --- a/src/Order/Query/GetOrderForPaymentDeniedQueryResult.php +++ b/src/Order/Query/GetOrderForPaymentDeniedQueryResult.php @@ -21,8 +21,6 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\Query; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; -use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; -use PrestaShop\Module\PrestashopCheckout\Order\State\ValueObject\OrderStateId; use PrestaShop\Module\PrestashopCheckout\Order\ValueObject\OrderId; class GetOrderForPaymentDeniedQueryResult @@ -32,11 +30,6 @@ class GetOrderForPaymentDeniedQueryResult */ private $orderId; - /** - * @var OrderStateId - */ - private $currentStateId; - /** * @var bool */ @@ -44,19 +37,15 @@ class GetOrderForPaymentDeniedQueryResult /** * @param int $orderId - * @param int $currentState * @param bool $hasBeenError * * @throws OrderException - * @throws OrderStateException */ public function __construct( $orderId, - $currentState, $hasBeenError ) { $this->orderId = new OrderId($orderId); - $this->currentStateId = new OrderStateId($currentState); $this->hasBeenError = $hasBeenError; } @@ -68,14 +57,6 @@ public function getOrderId() return $this->orderId; } - /** - * @return OrderStateId - */ - public function getCurrentStateId() - { - return $this->currentStateId; - } - /** * @return bool */ diff --git a/src/Order/Query/GetOrderForPaymentPendingQueryResult.php b/src/Order/Query/GetOrderForPaymentPendingQueryResult.php index f50c016a9..174e40856 100644 --- a/src/Order/Query/GetOrderForPaymentPendingQueryResult.php +++ b/src/Order/Query/GetOrderForPaymentPendingQueryResult.php @@ -22,8 +22,6 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\Query; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; -use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; -use PrestaShop\Module\PrestashopCheckout\Order\State\ValueObject\OrderStateId; use PrestaShop\Module\PrestashopCheckout\Order\ValueObject\OrderId; class GetOrderForPaymentPendingQueryResult @@ -33,40 +31,23 @@ class GetOrderForPaymentPendingQueryResult */ private $orderId; - /** - * @var OrderStateId - */ - private $currentStateId; - /** * @var bool */ private $isInPending; - /** - * @var string - */ - private $paymentMethod; - /** * @param int $orderId - * @param int $currentStateId * @param bool $isInPending - * @param string $paymentMethod * * @throws OrderException - * @throws OrderStateException */ public function __construct( $orderId, - $currentStateId, - $isInPending, - $paymentMethod + $isInPending ) { $this->orderId = new OrderId($orderId); - $this->currentStateId = new OrderStateId($currentStateId); $this->isInPending = $isInPending; - $this->paymentMethod = $paymentMethod; } /** @@ -77,14 +58,6 @@ public function getOrderId() return $this->orderId; } - /** - * @return OrderStateId - */ - public function getCurrentStateId() - { - return $this->currentStateId; - } - /** * @return bool */ @@ -92,12 +65,4 @@ public function isInPending() { return $this->isInPending; } - - /** - * @return string - */ - public function getPaymentMethod() - { - return $this->paymentMethod; - } } diff --git a/src/Order/Query/GetOrderForPaymentRefundedQueryResult.php b/src/Order/Query/GetOrderForPaymentRefundedQueryResult.php index b3cff68f1..faac91cda 100644 --- a/src/Order/Query/GetOrderForPaymentRefundedQueryResult.php +++ b/src/Order/Query/GetOrderForPaymentRefundedQueryResult.php @@ -45,17 +45,17 @@ class GetOrderForPaymentRefundedQueryResult /** * @var bool */ - private $hasBeenTotallyRefund; + private $hasBeenPartiallyRefund; /** - * @var string + * @var bool */ - private $totalAmount; + private $hasBeenTotallyRefund; /** * @var string */ - private $totalRefund; + private $totalAmount; /** * @var int @@ -66,9 +66,9 @@ class GetOrderForPaymentRefundedQueryResult * @param int $orderId * @param int $currentStateId * @param bool $hasBeenPaid + * @param bool $hasBeenPartiallyRefund * @param bool $hasBeenTotallyRefund * @param string $totalAmount - * @param string $totalRefund * @param int $currencyId * * @throws OrderException @@ -78,17 +78,17 @@ public function __construct( $orderId, $currentStateId, $hasBeenPaid, + $hasBeenPartiallyRefund, $hasBeenTotallyRefund, $totalAmount, - $totalRefund, $currencyId ) { $this->orderId = new OrderId($orderId); $this->currentStateId = new OrderStateId($currentStateId); $this->hasBeenPaid = $hasBeenPaid; + $this->hasBeenPartiallyRefund = $hasBeenPartiallyRefund; $this->hasBeenTotallyRefund = $hasBeenTotallyRefund; $this->totalAmount = $totalAmount; - $this->totalRefund = $totalRefund; $this->currencyId = $currencyId; } @@ -116,6 +116,11 @@ public function hasBeenPaid() return $this->hasBeenPaid; } + public function hasBeenPartiallyRefund() + { + return $this->hasBeenPartiallyRefund; + } + /** * @return bool */ @@ -132,14 +137,6 @@ public function getTotalAmount() return $this->totalAmount; } - /** - * @return string - */ - public function getTotalRefund() - { - return $this->totalRefund; - } - /** * @return int */ diff --git a/src/Order/Query/GetOrderForPaymentReversedQuery.php b/src/Order/Query/GetOrderForPaymentReversedQuery.php index 2e52e4374..bdb6d4488 100644 --- a/src/Order/Query/GetOrderForPaymentReversedQuery.php +++ b/src/Order/Query/GetOrderForPaymentReversedQuery.php @@ -22,8 +22,6 @@ use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; -use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\Exception\PayPalCaptureException; -use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\ValueObject\PayPalCaptureId; class GetOrderForPaymentReversedQuery { @@ -32,22 +30,14 @@ class GetOrderForPaymentReversedQuery */ private $orderPayPalId; - /** - * @var PayPalCaptureId - */ - private $capturePayPalId; - /** * @param string $orderPayPalId - * @param string $capturePayPalId * * @throws PayPalOrderException - * @throws PayPalCaptureException */ - public function __construct($orderPayPalId, $capturePayPalId) + public function __construct($orderPayPalId) { $this->orderPayPalId = new PayPalOrderId($orderPayPalId); - $this->capturePayPalId = new PayPalCaptureId($capturePayPalId); } /** @@ -57,9 +47,4 @@ public function getOrderPayPalId() { return $this->orderPayPalId; } - - public function getCapturePayPalId() - { - return $this->capturePayPalId; - } } diff --git a/src/Order/Query/GetOrderForPaymentReversedQueryResult.php b/src/Order/Query/GetOrderForPaymentReversedQueryResult.php index 874edfdf1..ffdba476d 100644 --- a/src/Order/Query/GetOrderForPaymentReversedQueryResult.php +++ b/src/Order/Query/GetOrderForPaymentReversedQueryResult.php @@ -21,8 +21,6 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\Query; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; -use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; -use PrestaShop\Module\PrestashopCheckout\Order\State\ValueObject\OrderStateId; use PrestaShop\Module\PrestashopCheckout\Order\ValueObject\OrderId; class GetOrderForPaymentReversedQueryResult @@ -32,11 +30,6 @@ class GetOrderForPaymentReversedQueryResult */ private $orderId; - /** - * @var OrderStateId - */ - private $currentStateId; - /** * @var bool */ @@ -49,21 +42,17 @@ class GetOrderForPaymentReversedQueryResult /** * @param int $orderId - * @param int $currentStateId * @param bool $hasBeenPaid * @param bool $hasBeenTotallyRefund * * @throws OrderException - * @throws OrderStateException */ public function __construct( $orderId, - $currentStateId, $hasBeenPaid, $hasBeenTotallyRefund ) { $this->orderId = new OrderId($orderId); - $this->currentStateId = new OrderStateId($currentStateId); $this->hasBeenPaid = $hasBeenPaid; $this->hasBeenTotallyRefund = $hasBeenTotallyRefund; } @@ -76,14 +65,6 @@ public function getOrderId() return $this->orderId; } - /** - * @return OrderStateId - */ - public function getCurrentStateId() - { - return $this->currentStateId; - } - /** * @return bool */ diff --git a/src/Order/Query/index.php b/src/Order/Query/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Query/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php b/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php index 461fdd10c..b188f5673 100644 --- a/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php +++ b/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php @@ -81,11 +81,13 @@ public function handle(GetOrderForApprovalReversedQuery $query) } $hasBeenCanceled = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_CANCELED))); + $hasBeenPaid = $order->hasBeenPaid(); + $hasBeenCompleted = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_COMPLETED))); + $hasBeenPartiallyPaid = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_PAID))); return new GetOrderForApprovalReversedQueryResult( (int) $order->id, - (int) $order->getCurrentState(), - (bool) $order->hasBeenPaid(), + $hasBeenPaid || $hasBeenCompleted || $hasBeenPartiallyPaid, (bool) $hasBeenCanceled ); } diff --git a/src/Order/QueryHandler/GetOrderForPaymentCompletedQueryHandler.php b/src/Order/QueryHandler/GetOrderForPaymentCompletedQueryHandler.php index 5cb2def84..b94423127 100644 --- a/src/Order/QueryHandler/GetOrderForPaymentCompletedQueryHandler.php +++ b/src/Order/QueryHandler/GetOrderForPaymentCompletedQueryHandler.php @@ -21,6 +21,7 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\QueryHandler; +use Configuration; use Order; use OrderPayment; use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; @@ -28,6 +29,7 @@ use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentCompletedQuery; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentCompletedQueryResult; +use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use PrestaShopCollection; use PrestaShopDatabaseException; @@ -89,13 +91,15 @@ public function handle(GetOrderForPaymentCompletedQuery $query) } } + $hasBeenPaid = $order->hasBeenPaid(); + $hasBeenCompleted = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_COMPLETED))); + $hasBeenPartiallyPaid = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_PAID))); + return new GetOrderForPaymentCompletedQueryResult( (int) $order->id, (int) $order->id_cart, - (int) $order->getCurrentState(), - (bool) $order->hasBeenPaid(), + $hasBeenPaid || $hasBeenCompleted || $hasBeenPartiallyPaid, (string) $order->total_paid, - (string) $order->total_paid_real, (int) $order->id_currency, $psCheckoutCart->getPaypalFundingSource(), $orderPaymentId diff --git a/src/Order/QueryHandler/GetOrderForPaymentDeniedQueryHandler.php b/src/Order/QueryHandler/GetOrderForPaymentDeniedQueryHandler.php index 8e8046718..8b8347e07 100644 --- a/src/Order/QueryHandler/GetOrderForPaymentDeniedQueryHandler.php +++ b/src/Order/QueryHandler/GetOrderForPaymentDeniedQueryHandler.php @@ -82,7 +82,6 @@ public function handle(GetOrderForPaymentDeniedQuery $query) return new GetOrderForPaymentDeniedQueryResult( (int) $order->id, - (int) $order->getCurrentState(), $this->hasBeenError($order) ); } diff --git a/src/Order/QueryHandler/GetOrderForPaymentPendingQueryHandler.php b/src/Order/QueryHandler/GetOrderForPaymentPendingQueryHandler.php index 5f87d43ef..a978cebe2 100644 --- a/src/Order/QueryHandler/GetOrderForPaymentPendingQueryHandler.php +++ b/src/Order/QueryHandler/GetOrderForPaymentPendingQueryHandler.php @@ -82,9 +82,7 @@ public function handle(GetOrderForPaymentPendingQuery $query) return new GetOrderForPaymentPendingQueryResult( (int) $order->id, - (int) $order->getCurrentState(), - $this->isInPending($order), - $psCheckoutCart->getPaypalFundingSource() + $this->isInPending($order) ); } diff --git a/src/Order/QueryHandler/GetOrderForPaymentRefundedQueryHandler.php b/src/Order/QueryHandler/GetOrderForPaymentRefundedQueryHandler.php index 3ba5b28b5..7a967eae3 100644 --- a/src/Order/QueryHandler/GetOrderForPaymentRefundedQueryHandler.php +++ b/src/Order/QueryHandler/GetOrderForPaymentRefundedQueryHandler.php @@ -21,13 +21,14 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\QueryHandler; +use Configuration; use Order; -use OrderSlip; use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQuery; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQueryResult; +use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use PrestaShopCollection; use PrestaShopDatabaseException; @@ -79,34 +80,18 @@ public function handle(GetOrderForPaymentRefundedQuery $query) throw new OrderNotFoundException('No PrestaShop Order associated to this PayPal Order at this time.'); } - $totalRefund = $this->getTotalRefund($order); + $hasBeenPaid = $order->hasBeenPaid(); + $hasBeenCompleted = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_COMPLETED))); + $hasBeenPartiallyPaid = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_PAID))); return new GetOrderForPaymentRefundedQueryResult( (int) $order->id, (int) $order->getCurrentState(), - (bool) $order->hasBeenPaid(), - $this->hasBeenTotallyRefunded($totalRefund, $order), + $hasBeenPaid || $hasBeenCompleted || $hasBeenPartiallyPaid, + (bool) count($order->getHistory((int) $order->id_lang, (int) Configuration::get('PS_CHECKOUT_STATE_PARTIALLY_REFUNDED'))), + (bool) count($order->getHistory((int) $order->id_lang, (int) Configuration::get('PS_CHECKOUT_STATE_REFUNDED'))), (string) $order->getTotalPaid(), - (string) $totalRefund, (int) $order->id_currency ); } - - private function hasBeenTotallyRefunded($refundAmount, $order) - { - return $refundAmount >= $order->total_paid; - } - - private function getTotalRefund(Order $order) - { - /** @var OrderSlip[] $orderSlips */ - $orderSlips = $order->getOrderSlipsCollection()->getResults(); - $refundAmount = 0; - - foreach ($orderSlips as $orderSlip) { - $refundAmount += $orderSlip->amount + $orderSlip->shipping_cost_amount; - } - - return $refundAmount; - } } diff --git a/src/Order/QueryHandler/GetOrderForPaymentReversedQueryHandler.php b/src/Order/QueryHandler/GetOrderForPaymentReversedQueryHandler.php index 9c6dc432d..06676d5b7 100644 --- a/src/Order/QueryHandler/GetOrderForPaymentReversedQueryHandler.php +++ b/src/Order/QueryHandler/GetOrderForPaymentReversedQueryHandler.php @@ -21,13 +21,14 @@ namespace PrestaShop\Module\PrestashopCheckout\Order\QueryHandler; +use Configuration; use Order; -use OrderSlip; use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentReversedQuery; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentReversedQueryResult; +use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use PrestaShopCollection; use PrestaShopDatabaseException; @@ -79,26 +80,15 @@ public function handle(GetOrderForPaymentReversedQuery $query) throw new OrderNotFoundException('No PrestaShop Order associated to this PayPal Order at this time.'); } + $hasBeenPaid = $order->hasBeenPaid(); + $hasBeenCompleted = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_COMPLETED))); + $hasBeenPartiallyPaid = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_PAID))); + $hasBeenTotallyRefunded = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_REFUNDED))); + return new GetOrderForPaymentReversedQueryResult( (int) $order->id, - (int) $order->getCurrentState(), - (bool) $order->hasBeenPaid(), - $this->hasBeenTotallyRefunded($order) + $hasBeenPaid || $hasBeenCompleted || $hasBeenPartiallyPaid, + (bool) $hasBeenTotallyRefunded ); } - - private function hasBeenTotallyRefunded(Order $order) - { - /** @var OrderSlip[] $orderSlips */ - $orderSlips = $order->getOrderSlipsCollection()->getResults(); - $refundAmount = 0; - - if (!empty($orderSlips)) { - foreach ($orderSlips as $orderSlip) { - $refundAmount += $orderSlip->amount + $orderSlip->shipping_cost_amount; - } - } - - return $refundAmount >= $order->total_paid; - } } diff --git a/src/Order/QueryHandler/index.php b/src/Order/QueryHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/QueryHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/Service/index.php b/src/Order/Service/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/Service/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/State/Exception/index.php b/src/Order/State/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/State/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/State/Service/index.php b/src/Order/State/Service/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/State/Service/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/State/ValueObject/index.php b/src/Order/State/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/State/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/State/index.php b/src/Order/State/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/State/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/ValueObject/index.php b/src/Order/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Order/index.php b/src/Order/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Order/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/ApplePay/Builder/ApplePayPaymentRequestBuilder.php b/src/PayPal/ApplePay/Builder/ApplePayPaymentRequestBuilder.php new file mode 100644 index 000000000..8a92eb432 --- /dev/null +++ b/src/PayPal/ApplePay/Builder/ApplePayPaymentRequestBuilder.php @@ -0,0 +1,81 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Builder; + +use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\DTO\ApplePayLineItem; +use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\DTO\ApplePayPaymentRequest; +use PrestaShop\Module\PrestashopCheckout\Translations\Translations; + +class ApplePayPaymentRequestBuilder +{ + /** + * @var Translations + */ + private $translations; + + public function __construct(Translations $translations) + { + $this->translations = current($translations->getTranslations())['apple_pay']; + } + + /** + * @return ApplePayPaymentRequest + */ + public function buildMinimalPaymentRequestFromPayPalPayload($payload) + { + $paymentRequest = new ApplePayPaymentRequest(); + + $total = new ApplePayLineItem(); + $total->setAmount($payload['amount']['value']) + ->setLabel($this->translations['total']); + + $paymentRequest->setCurrencyCode($payload['amount']['currency_code']) + ->setTotal($total); + + return $paymentRequest; + } + + /** + * Get decimal to round correspondent to the payment currency used + * Advise from PayPal: Always round to 2 decimals except for HUF, JPY and TWD + * currencies which require a round with 0 decimal + * + * @return int + */ + private function getNbDecimalToRound($currencyIsoCode) + { + if (in_array($currencyIsoCode, ['HUF', 'JPY', 'TWD'], true)) { + return 0; + } + + return 2; + } + + /** + * @param float|int|string $amount + * + * @return string + */ + private function formatAmount($amount, $currencyIsoCode) + { + return sprintf("%01.{$this->getNbDecimalToRound($currencyIsoCode)}F", $amount); + } +} diff --git a/src/PayPal/ApplePay/Builder/index.php b/src/PayPal/ApplePay/Builder/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/ApplePay/Builder/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/ApplePay/DTO/ApplePayLineItem.php b/src/PayPal/ApplePay/DTO/ApplePayLineItem.php new file mode 100644 index 000000000..e8a4408c6 --- /dev/null +++ b/src/PayPal/ApplePay/DTO/ApplePayLineItem.php @@ -0,0 +1,297 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\DTO; + +use DateTime; + +class ApplePayLineItem +{ + const TYPE_PENDING = 'pending'; + const TYPE_FINAL = 'final'; + const PAYMENT_TIMING_IMMEDIATE = 'immediate'; + const PAYMENT_TIMING_RECURRING = 'recurring'; + const PAYMENT_TIMING_DEFERRED = 'deferred'; + const PAYMENT_TIMING_AUTOMATIC_RELOAD = 'automaticReload'; + const RECURRING_PAYMENT_INTERVAL_UNIT_DAY = 'day'; + const RECURRING_PAYMENT_INTERVAL_UNIT_WEEK = 'week'; + const RECURRING_PAYMENT_INTERVAL_UNIT_MONTH = 'month'; + const RECURRING_PAYMENT_INTERVAL_UNIT_YEAR = 'year'; + + /** + * @var self::TYPE_PENDING|self::TYPE_FINAL + */ + private $type = self::TYPE_FINAL; + /** + * @var string + */ + private $label; + /** + * @var string + */ + private $amount; + /** + * @var self::PAYMENT_TIMING_IMMEDIATE|self::PAYMENT_TIMING_RECURRING|self::PAYMENT_TIMING_DEFERRED|self::PAYMENT_TIMING_AUTOMATIC_RELOAD + */ + private $paymentTiming; + /** + * @var DateTime|null + */ + private $recurringPaymentStartDate = null; + /** + * @var self::RECURRING_PAYMENT_INTERVAL_UNIT_DAY|self::RECURRING_PAYMENT_INTERVAL_UNIT_WEEK|self::RECURRING_PAYMENT_INTERVAL_UNIT_MONTH|self::RECURRING_PAYMENT_INTERVAL_UNIT_YEAR + */ + private $recurringPaymentIntervalUnit; + /** + * @var int + */ + private $recurringPaymentIntervalCount; + /** + * @var DateTime|null + */ + private $recurringPaymentEndDate = null; + /** + * @var DateTime|null + */ + private $deferredPaymentDate = null; + /** + * @var string + */ + private $automaticReloadPaymentThresholdAmount; + + /** + * @param self::TYPE_PENDING|self::TYPE_FINAL $type + * + * @return ApplePayLineItem + */ + public function setType($type) + { + $this->type = $type; + + return $this; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $label + * + * @return ApplePayLineItem + */ + public function setLabel($label) + { + $this->label = $label; + + return $this; + } + + /** + * @return string + */ + public function getLabel() + { + return $this->label; + } + + /** + * @param string $amount + * + * @return ApplePayLineItem + */ + public function setAmount($amount) + { + $this->amount = $amount; + + return $this; + } + + /** + * @return string + */ + public function getAmount() + { + return $this->amount; + } + + /** + * @param self::PAYMENT_TIMING_IMMEDIATE|self::PAYMENT_TIMING_RECURRING|self::PAYMENT_TIMING_DEFERRED|self::PAYMENT_TIMING_AUTOMATIC_RELOAD $paymentTiming + * + * @return ApplePayLineItem + */ + public function setPaymentTiming($paymentTiming) + { + $this->paymentTiming = $paymentTiming; + + return $this; + } + + /** + * @return string + */ + public function getPaymentTiming() + { + return $this->paymentTiming; + } + + /** + * @param DateTime $recurringPaymentStartDate + * + * @return ApplePayLineItem + */ + public function setRecurringPaymentStartDate($recurringPaymentStartDate) + { + $this->recurringPaymentStartDate = $recurringPaymentStartDate; + + return $this; + } + + /** + * @return DateTime + */ + public function getRecurringPaymentStartDate() + { + return $this->recurringPaymentStartDate; + } + + /** + * @param self::RECURRING_PAYMENT_INTERVAL_UNIT_DAY|self::RECURRING_PAYMENT_INTERVAL_UNIT_WEEK|self::RECURRING_PAYMENT_INTERVAL_UNIT_MONTH|self::RECURRING_PAYMENT_INTERVAL_UNIT_YEAR $recurringPaymentIntervalUnit + * + * @return ApplePayLineItem + */ + public function setRecurringPaymentIntervalUnit($recurringPaymentIntervalUnit) + { + $this->recurringPaymentIntervalUnit = $recurringPaymentIntervalUnit; + + return $this; + } + + /** + * @return string + */ + public function getRecurringPaymentIntervalUnit() + { + return $this->recurringPaymentIntervalUnit; + } + + /** + * @param int $recurringPaymentIntervalCount + * + * @return ApplePayLineItem + */ + public function setRecurringPaymentIntervalCount($recurringPaymentIntervalCount) + { + $this->recurringPaymentIntervalCount = $recurringPaymentIntervalCount; + + return $this; + } + + /** + * @return int + */ + public function getRecurringPaymentIntervalCount() + { + return $this->recurringPaymentIntervalCount; + } + + /** + * @param DateTime $recurringPaymentEndDate + * + * @return ApplePayLineItem + */ + public function setRecurringPaymentEndDate($recurringPaymentEndDate) + { + $this->recurringPaymentEndDate = $recurringPaymentEndDate; + + return $this; + } + + /** + * @return DateTime + */ + public function getRecurringPaymentEndDate() + { + return $this->recurringPaymentEndDate; + } + + /** + * @param DateTime $deferredPaymentDate + * + * @return ApplePayLineItem + */ + public function setDeferredPaymentDate($deferredPaymentDate) + { + $this->deferredPaymentDate = $deferredPaymentDate; + + return $this; + } + + /** + * @return DateTime + */ + public function getDeferredPaymentDate() + { + return $this->deferredPaymentDate; + } + + /** + * @param string $automaticReloadPaymentThresholdAmount + * + * @return ApplePayLineItem + */ + public function setAutomaticReloadPaymentThresholdAmount($automaticReloadPaymentThresholdAmount) + { + $this->automaticReloadPaymentThresholdAmount = $automaticReloadPaymentThresholdAmount; + + return $this; + } + + /** + * @return string + */ + public function getAutomaticReloadPaymentThresholdAmount() + { + return $this->automaticReloadPaymentThresholdAmount; + } + + /** + * @return array + */ + public function toArray() + { + return array_filter([ + 'type' => $this->type, + 'label' => $this->label, + 'amount' => $this->amount, + 'paymentTiming' => $this->paymentTiming, + 'recurringPaymentStartDate' => $this->recurringPaymentStartDate ? $this->recurringPaymentStartDate->format(DateTime::ATOM) : null, + 'recurringPaymentIntervalUnit' => $this->recurringPaymentIntervalUnit, + 'recurringPaymentIntervalCount' => $this->recurringPaymentIntervalCount, + 'recurringPaymentEndDate' => $this->recurringPaymentEndDate ? $this->recurringPaymentEndDate->format(DateTime::ATOM) : null, + 'deferredPaymentDate' => $this->deferredPaymentDate ? $this->deferredPaymentDate->format(DateTime::ATOM) : null, + 'automaticReloadPaymentThresholdAmount' => $this->automaticReloadPaymentThresholdAmount, + ]); + } +} diff --git a/src/PayPal/ApplePay/DTO/ApplePayPaymentContact.php b/src/PayPal/ApplePay/DTO/ApplePayPaymentContact.php new file mode 100644 index 000000000..66346cb3c --- /dev/null +++ b/src/PayPal/ApplePay/DTO/ApplePayPaymentContact.php @@ -0,0 +1,384 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\DTO; + +class ApplePayPaymentContact +{ + /** + * @var string + */ + private $phoneNumber; + /** + * @var string + */ + private $emailAddress; + /** + * @var string + */ + private $givenName; + /** + * @var string + */ + private $familyName; + /** + * @var string + */ + private $phoneticGivenName; + /** + * @var string + */ + private $phoneticFamilyName; + /** + * @var array + */ + private $addressLines = []; + /** + * @var string + */ + private $subLocality; + /** + * @var string + */ + private $locality; + /** + * @var string + */ + private $postalCode; + /** + * @var string + */ + private $subAdministrativeArea; + /** + * @var string + */ + private $administrativeArea; + /** + * @var string + */ + private $country; + /** + * @var string + */ + private $countryCode; + + /** + * @return string + */ + public function getPhoneNumber() + { + return $this->phoneNumber; + } + + /** + * @param string $phoneNumber + * + * @return $this + */ + public function setPhoneNumber($phoneNumber) + { + $this->phoneNumber = $phoneNumber; + + return $this; + } + + /** + * @return string + */ + public function getEmailAddress() + { + return $this->emailAddress; + } + + /** + * @param string $emailAddress + * + * @return $this + */ + public function setEmailAddress($emailAddress) + { + $this->emailAddress = $emailAddress; + + return $this; + } + + /** + * @return string + */ + public function getGivenName() + { + return $this->givenName; + } + + /** + * @param string $givenName + * + * @return $this + */ + public function setGivenName($givenName) + { + $this->givenName = $givenName; + + return $this; + } + + /** + * @return string + */ + public function getFamilyName() + { + return $this->familyName; + } + + /** + * @param string $familyName + * + * @return $this + */ + public function setFamilyName($familyName) + { + $this->familyName = $familyName; + + return $this; + } + + /** + * @return string + */ + public function getPhoneticGivenName() + { + return $this->phoneticGivenName; + } + + /** + * @param string $phoneticGivenName + * + * @return $this + */ + public function setPhoneticGivenName($phoneticGivenName) + { + $this->phoneticGivenName = $phoneticGivenName; + + return $this; + } + + /** + * @return string + */ + public function getPhoneticFamilyName() + { + return $this->phoneticFamilyName; + } + + /** + * @param string $phoneticFamilyName + * + * @return $this + */ + public function setPhoneticFamilyName($phoneticFamilyName) + { + $this->phoneticFamilyName = $phoneticFamilyName; + + return $this; + } + + /** + * @return array + */ + public function getAddressLines() + { + return $this->addressLines; + } + + /** + * @param array $addressLines + * + * @return $this + */ + public function setAddressLines(array $addressLines) + { + $this->addressLines = $addressLines; + + return $this; + } + + /** + * @return string + */ + public function getSubLocality() + { + return $this->subLocality; + } + + /** + * @param string $subLocality + * + * @return $this + */ + public function setSubLocality($subLocality) + { + $this->subLocality = $subLocality; + + return $this; + } + + /** + * @return string + */ + public function getLocality() + { + return $this->locality; + } + + /** + * @param string $locality + * + * @return $this + */ + public function setLocality($locality) + { + $this->locality = $locality; + + return $this; + } + + /** + * @return string + */ + public function getPostalCode() + { + return $this->postalCode; + } + + /** + * @param string $postalCode + * + * @return $this + */ + public function setPostalCode($postalCode) + { + $this->postalCode = $postalCode; + + return $this; + } + + /** + * @return string + */ + public function getSubAdministrativeArea() + { + return $this->subAdministrativeArea; + } + + /** + * @param string $subAdministrativeArea + * + * @return $this + */ + public function setSubAdministrativeArea($subAdministrativeArea) + { + $this->subAdministrativeArea = $subAdministrativeArea; + + return $this; + } + + /** + * @return string + */ + public function getAdministrativeArea() + { + return $this->administrativeArea; + } + + /** + * @param string $administrativeArea + * + * @return $this + */ + public function setAdministrativeArea($administrativeArea) + { + $this->administrativeArea = $administrativeArea; + + return $this; + } + + /** + * @return string + */ + public function getCountry() + { + return $this->country; + } + + /** + * @param string $country + * + * @return $this + */ + public function setCountry($country) + { + $this->country = $country; + + return $this; + } + + /** + * @return string + */ + public function getCountryCode() + { + return $this->countryCode; + } + + /** + * @param string $countryCode + * + * @return $this + */ + public function setCountryCode($countryCode) + { + $this->countryCode = $countryCode; + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + return array_filter([ + 'phoneNumber' => $this->phoneNumber, + 'emailAddress' => $this->emailAddress, + 'givenName' => $this->givenName, + 'familyName' => $this->familyName, + 'phoneticGivenName' => $this->phoneticGivenName, + 'phoneticFamilyName' => $this->phoneticFamilyName, + 'addressLines' => $this->addressLines, + 'subLocality' => $this->subLocality, + 'locality' => $this->locality, + 'postalCode' => $this->postalCode, + 'subAdministrativeArea' => $this->subAdministrativeArea, + 'administrativeArea' => $this->administrativeArea, + 'country' => $this->country, + 'countryCode' => $this->countryCode, + ]); + } +} diff --git a/src/PayPal/ApplePay/DTO/ApplePayPaymentRequest.php b/src/PayPal/ApplePay/DTO/ApplePayPaymentRequest.php new file mode 100644 index 000000000..952a38318 --- /dev/null +++ b/src/PayPal/ApplePay/DTO/ApplePayPaymentRequest.php @@ -0,0 +1,187 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\DTO; + +class ApplePayPaymentRequest +{ + /** + * @var string + */ + private $countryCode; + /** + * @var string + */ + private $currencyCode; + /** + * @var ApplePayLineItem|null + */ + private $total = null; + /** + * @var ApplePayLineItem[] + */ + private $lineItems = []; + + /** + * @var ApplePayPaymentContact|null + */ + private $shippingContact = null; + /** + * @var ApplePayPaymentContact|null + */ + private $billingContact = null; + + /** + * @return string + */ + public function getCurrencyCode() + { + return $this->currencyCode; + } + + /** + * @param string $currencyCode + * + * @return ApplePayPaymentRequest + */ + public function setCurrencyCode($currencyCode) + { + $this->currencyCode = $currencyCode; + + return $this; + } + + /** + * @return string + */ + public function getCountryCode() + { + return $this->countryCode; + } + + /** + * @param string $countryCode + * + * @return ApplePayPaymentRequest + */ + public function setCountryCode($countryCode) + { + $this->countryCode = $countryCode; + + return $this; + } + + /** + * @return ApplePayLineItem + */ + public function getTotal() + { + return $this->total; + } + + /** + * @param ApplePayLineItem $total + * + * @return ApplePayPaymentRequest + */ + public function setTotal($total) + { + $this->total = $total; + + return $this; + } + + /** + * @return ApplePayLineItem[] + */ + public function getLineItems() + { + return $this->lineItems; + } + + /** + * @param ApplePayLineItem[] $lineItems + * + * @return ApplePayPaymentRequest + */ + public function setLineItems($lineItems) + { + $this->lineItems = $lineItems; + + return $this; + } + + /** + * @return ApplePayPaymentContact + */ + public function getShippingContact() + { + return $this->shippingContact; + } + + /** + * @param ApplePayPaymentContact $shippingContact + * + * @return ApplePayPaymentRequest + */ + public function setShippingContact($shippingContact) + { + $this->shippingContact = $shippingContact; + + return $this; + } + + /** + * @return ApplePayPaymentContact + */ + public function getBillingContact() + { + return $this->billingContact; + } + + /** + * @param ApplePayPaymentContact $billingContact + * + * @return ApplePayPaymentRequest + */ + public function setBillingContact($billingContact) + { + $this->billingContact = $billingContact; + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + return array_filter([ + 'countryCode' => $this->countryCode, + 'currencyCode' => $this->currencyCode, + 'total' => $this->total ? $this->total->toArray() : null, + 'lineItems' => array_map(function (ApplePayLineItem $lineItem) { + return $lineItem->toArray(); + }, $this->lineItems), + 'shippingContact' => $this->shippingContact ? $this->shippingContact->toArray() : null, + 'billingContact' => $this->billingContact ? $this->billingContact->toArray() : null, + ]); + } +} diff --git a/src/PayPal/ApplePay/DTO/index.php b/src/PayPal/ApplePay/DTO/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/ApplePay/DTO/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/_dev/js/front/src/service/translation.service.js b/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQuery.php similarity index 52% rename from _dev/js/front/src/service/translation.service.js rename to src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQuery.php index e553db521..c28ec9536 100644 --- a/_dev/js/front/src/service/translation.service.js +++ b/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQuery.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -import { BaseClass } from '../core/dependency-injection/base.class'; -export class TranslationService extends BaseClass { - static Inject = { - config: 'PsCheckoutConfig' - }; +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query; - constructor(app) { - super(app); - this.translationMap = this.config.translations; - } +use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; - getTranslationString(id) { - return this.translationMap[id] || `TRANSLATED_STRING(${id})`; - } +class GetApplePayPaymentRequestQuery +{ + /** + * @var CartId + */ + private $cartId; + + public function __construct(CartId $cartId) + { + $this->cartId = $cartId; + } + + /** + * @return CartId + */ + public function getCartId() + { + return $this->cartId; + } } diff --git a/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQueryHandler.php b/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQueryHandler.php new file mode 100644 index 000000000..9e6207f59 --- /dev/null +++ b/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQueryHandler.php @@ -0,0 +1,60 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query; + +use PrestaShop\Module\PrestashopCheckout\Builder\Payload\OrderPayloadBuilder; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Builder\ApplePayPaymentRequestBuilder; +use PrestaShop\Module\PrestashopCheckout\Presenter\Cart\CartPresenter; + +class GetApplePayPaymentRequestQueryHandler +{ + /** + * @var ApplePayPaymentRequestBuilder + */ + private $builder; + + public function __construct(ApplePayPaymentRequestBuilder $builder) + { + $this->builder = $builder; + } + + /** + * @param GetApplePayPaymentRequestQuery $query + * + * @return GetApplePayPaymentRequestQueryResult + * + * @throws PsCheckoutException + */ + public function handle(GetApplePayPaymentRequestQuery $query) + { + $cartPresenter = new CartPresenter(); + $cart = $cartPresenter->present(); + $orderPayloadBuilder = new OrderPayloadBuilder($cart); + + $orderPayloadBuilder->buildFullPayload(); + $payload = $orderPayloadBuilder->presentPayload()->getArray(); + + $paymentRequest = $this->builder->buildMinimalPaymentRequestFromPayPalPayload($payload); + + return new GetApplePayPaymentRequestQueryResult($paymentRequest); + } +} diff --git a/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQueryResult.php b/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQueryResult.php new file mode 100644 index 000000000..11dc197d4 --- /dev/null +++ b/src/PayPal/ApplePay/Query/GetApplePayPaymentRequestQueryResult.php @@ -0,0 +1,44 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Query; + +use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\DTO\ApplePayPaymentRequest; + +class GetApplePayPaymentRequestQueryResult +{ + /** + * @var ApplePayPaymentRequest + */ + private $payload; + + public function __construct(ApplePayPaymentRequest $payload) + { + $this->payload = $payload; + } + + /** + * @return ApplePayPaymentRequest + */ + public function getPayload() + { + return $this->payload; + } +} diff --git a/src/PayPal/ApplePay/Query/index.php b/src/PayPal/ApplePay/Query/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/ApplePay/Query/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Card3DSecure.php b/src/PayPal/Card3DSecure.php index 091eec299..c997ca986 100644 --- a/src/PayPal/Card3DSecure.php +++ b/src/PayPal/Card3DSecure.php @@ -130,9 +130,9 @@ public function is3DSecureAvailable(array $order) */ public function isLiabilityShifted(array $order) { - $cardAuthenticationResult = $this->getAuthenticationResult($order); - $liabilityShift = $this->getLiabilityShift($cardAuthenticationResult); - $threeDSecure = $this->get3DSecure($cardAuthenticationResult); + $authenticationResult = $this->getAuthenticationResult($order); + $liabilityShift = $this->getLiabilityShift($authenticationResult); + $threeDSecure = $this->get3DSecure($authenticationResult); $authenticationStatus = $this->getAuthenticationStatus($threeDSecure); return ($liabilityShift === self::LIABILITY_SHIFT_POSSIBLE || $liabilityShift === self::LIABILITY_SHIFT_YES) @@ -188,27 +188,29 @@ private function noLiabilityShift(array $cardAuthenticationResult) */ private function getAuthenticationResult(array $order) { - return isset($order['payment_source']['card']['authentication_result']) ? $order['payment_source']['card']['authentication_result'] : null; + $fundingSource = isset($order['payment_source']) ? key($order['payment_source']) : ''; + + return isset($order['payment_source'][$fundingSource]['authentication_result']) ? $order['payment_source'][$fundingSource]['authentication_result'] : null; } /** - * @param array|null $cardAuthenticationResult + * @param array|null $authenticationResult * * @return string|null */ - private function getLiabilityShift($cardAuthenticationResult) + private function getLiabilityShift($authenticationResult) { - return isset($cardAuthenticationResult['liability_shift']) ? $cardAuthenticationResult['liability_shift'] : null; + return isset($authenticationResult['liability_shift']) ? $authenticationResult['liability_shift'] : null; } /** - * @param array|null $cardAuthenticationResult + * @param array|null $authenticationResult * * @return array|null */ - private function get3DSecure($cardAuthenticationResult) + private function get3DSecure($authenticationResult) { - return isset($cardAuthenticationResult['three_d_secure']) ? $cardAuthenticationResult['three_d_secure'] : null; + return isset($authenticationResult['three_d_secure']) ? $authenticationResult['three_d_secure'] : null; } /** diff --git a/src/PayPal/Customer/Command/SavePayPalCustomerCommand.php b/src/PayPal/Customer/Command/SavePayPalCustomerCommand.php new file mode 100644 index 000000000..05a4d392f --- /dev/null +++ b/src/PayPal/Customer/Command/SavePayPalCustomerCommand.php @@ -0,0 +1,58 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Customer\Command; + +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; + +class SavePayPalCustomerCommand +{ + /** + * @var CustomerId + */ + private $customerId; + /** + * @var PayPalCustomerId + */ + private $payPalCustomerId; + + public function __construct(CustomerId $customerId, PayPalCustomerId $payPalCustomerId) + { + $this->customerId = $customerId; + $this->payPalCustomerId = $payPalCustomerId; + } + + /** + * @return CustomerId + */ + public function getCustomerId() + { + return $this->customerId; + } + + /** + * @return PayPalCustomerId + */ + public function getPayPalCustomerId() + { + return $this->payPalCustomerId; + } +} diff --git a/src/PayPal/Customer/Command/index.php b/src/PayPal/Customer/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Customer/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Customer/CommandHandler/SavePayPalCustomerCommandHandler.php b/src/PayPal/Customer/CommandHandler/SavePayPalCustomerCommandHandler.php new file mode 100644 index 000000000..7e381e7e1 --- /dev/null +++ b/src/PayPal/Customer/CommandHandler/SavePayPalCustomerCommandHandler.php @@ -0,0 +1,46 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Customer\CommandHandler; + +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\Command\SavePayPalCustomerCommand; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository; + +class SavePayPalCustomerCommandHandler +{ + /** + * @var PayPalCustomerRepository + */ + private $payPalCustomerRepository; + + public function __construct(PayPalCustomerRepository $payPalCustomerRepository) + { + $this->payPalCustomerRepository = $payPalCustomerRepository; + } + + public function handle(SavePayPalCustomerCommand $command) + { + try { + $this->payPalCustomerRepository->findPayPalCustomerIdByCustomerId($command->getCustomerId()); + } catch (\Exception $exception) { + $this->payPalCustomerRepository->save($command->getCustomerId(), $command->getPayPalCustomerId()); + } + } +} diff --git a/src/PayPal/Customer/CommandHandler/index.php b/src/PayPal/Customer/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Customer/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Customer/ValueObject/PayPalCustomerId.php b/src/PayPal/Customer/ValueObject/PayPalCustomerId.php new file mode 100644 index 000000000..279d22f4f --- /dev/null +++ b/src/PayPal/Customer/ValueObject/PayPalCustomerId.php @@ -0,0 +1,74 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject; + +use InvalidArgumentException; + +class PayPalCustomerId +{ + /** + * @var string + */ + private $customerId; + + /** + * @param string $customerId + * + * @throws InvalidArgumentException + */ + public function __construct($customerId) + { + $this->assertIsValid($customerId); + $this->customerId = $customerId; + } + + /** + * @return string + */ + public function getValue() + { + return $this->customerId; + } + + /** + * @param string $customerId + * + * @return void + * + * @throws InvalidArgumentException + */ + private function assertIsValid($customerId) + { + if (!is_string($customerId)) { + throw new InvalidArgumentException('PayPal Customer ID must be a string.'); + } + + $length = strlen($customerId); + + if ($length < 1 || $length > 22) { + throw new InvalidArgumentException('PayPal Customer ID must be between 1 and 22 characters long.'); + } + + if (preg_match('/^[0-9a-zA-Z_-]+$/', $customerId) !== 1) { + throw new InvalidArgumentException('PayPal Customer ID must be alphanumeric.'); + } + } +} diff --git a/src/PayPal/Customer/ValueObject/index.php b/src/PayPal/Customer/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Customer/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Customer/index.php b/src/PayPal/Customer/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Customer/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/GooglePay/Builder/GooglePayTransactionInfoBuilder.php b/src/PayPal/GooglePay/Builder/GooglePayTransactionInfoBuilder.php new file mode 100644 index 000000000..f9569fd4d --- /dev/null +++ b/src/PayPal/GooglePay/Builder/GooglePayTransactionInfoBuilder.php @@ -0,0 +1,159 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Builder; + +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO\GooglePayDisplayItem; +use PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO\GooglePayTransactionInfo; +use PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO\MerchantInfo; +use PrestaShop\Module\PrestashopCheckout\Translations\Translations; + +class GooglePayTransactionInfoBuilder +{ + /** + * @var Translations + */ + private $translations; + + public function __construct(Translations $translations) + { + $this->translations = current($translations->getTranslations())['google_pay']; + } + + /** + * @return GooglePayTransactionInfo + * + * @throws PsCheckoutException + */ + public function buildFromPayPalPayload($payload) + { + $transactionInfo = new GooglePayTransactionInfo(); + + $breakdown = $payload['amount']['breakdown']; + + $displayItems = []; + + if ($breakdown['shipping']['value'] > 0) { + $shipping = new GooglePayDisplayItem(); + $shipping->setPrice($breakdown['shipping']['value']) + ->setType(GooglePayDisplayItem::TYPE_LINE_ITEM) + ->setLabel($this->translations['shipping']); + $displayItems[] = $shipping; + } + + if ($breakdown['handling']['value'] > 0) { + $handling = new GooglePayDisplayItem(); + $handling->setPrice($breakdown['handling']['value']) + ->setType(GooglePayDisplayItem::TYPE_LINE_ITEM) + ->setLabel($this->translations['handling']); + $displayItems[] = $handling; + } + + if ($breakdown['discount']['value'] > 0) { + $discount = new GooglePayDisplayItem(); + $discount->setPrice('-' . $breakdown['discount']['value']) + ->setType(GooglePayDisplayItem::TYPE_LINE_ITEM) + ->setLabel($this->translations['discount']); + $displayItems[] = $discount; + } + + $subtotal = new GooglePayDisplayItem(); + $subtotal->setPrice($this->formatAmount($payload['amount']['value'] - $breakdown['tax_total']['value'], $payload['amount']['currency_code'])) + ->setType(GooglePayDisplayItem::TYPE_SUBTOTAL) + ->setLabel($this->translations['subtotal']); + $displayItems[] = $subtotal; + + $tax = new GooglePayDisplayItem(); + $tax->setPrice($breakdown['tax_total']['value']) + ->setType(GooglePayDisplayItem::TYPE_TAX) + ->setLabel($this->translations['tax']); + + $displayItems[] = $tax; + + $productItems = array_map(function ($item) { + $productItem = new GooglePayDisplayItem(); + $productItem->setPrice($this->formatAmount($item['unit_amount']['value'] * $item['quantity'], $item['unit_amount']['currency_code'])) + ->setType(GooglePayDisplayItem::TYPE_LINE_ITEM) + ->setLabel($item['name'] . ' ' . $item['description'] . ' x' . $item['quantity']); + + return $productItem; + }, $payload['items']); + + $displayItems = array_merge($productItems, $displayItems); + + $merchantInfo = new MerchantInfo(); + $merchantInfo->setMerchantName($payload['application_context']['brand_name']); + + $transactionInfo->setCurrencyCode($payload['amount']['currency_code']) + ->setTotalPrice($payload['amount']['value']) + ->setTotalPriceLabel($this->translations['total']) + ->setDisplayItems($displayItems) + ->setMerchantInfo($merchantInfo); + + return $transactionInfo; + } + + /** + * @return GooglePayTransactionInfo + * + * @throws PsCheckoutException + */ + public function buildMinimalTransactionInfoFromPayPalPayload($payload) + { + $transactionInfo = new GooglePayTransactionInfo(); + + $merchantInfo = new MerchantInfo(); + $merchantInfo->setMerchantName($payload['application_context']['brand_name']); + + $transactionInfo->setCurrencyCode($payload['amount']['currency_code']) + ->setTotalPrice($payload['amount']['value']) + ->setTotalPriceLabel($this->translations['total']) + ->setMerchantInfo($merchantInfo); + + return $transactionInfo; + } + + /** + * Get decimal to round correspondent to the payment currency used + * Advise from PayPal: Always round to 2 decimals except for HUF, JPY and TWD + * currencies which require a round with 0 decimal + * + * @return int + */ + private function getNbDecimalToRound($currencyIsoCode) + { + if (in_array($currencyIsoCode, ['HUF', 'JPY', 'TWD'], true)) { + return 0; + } + + return 2; + } + + /** + * @param float|int|string $amount + * + * @return string + */ + private function formatAmount($amount, $currencyIsoCode) + { + return sprintf("%01.{$this->getNbDecimalToRound($currencyIsoCode)}F", $amount); + } +} diff --git a/src/PayPal/GooglePay/Builder/index.php b/src/PayPal/GooglePay/Builder/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/GooglePay/Builder/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/GooglePay/DTO/GooglePayDisplayItem.php b/src/PayPal/GooglePay/DTO/GooglePayDisplayItem.php new file mode 100644 index 000000000..b542d41c5 --- /dev/null +++ b/src/PayPal/GooglePay/DTO/GooglePayDisplayItem.php @@ -0,0 +1,137 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO; + +class GooglePayDisplayItem +{ + const TYPE_LINE_ITEM = 'LINE_ITEM'; + const TYPE_SUBTOTAL = 'SUBTOTAL'; + const TYPE_TAX = 'TAX'; + const STATUS_FINAL = 'FINAL'; + const STATUS_PENDING = 'PENDING'; + + /** + * @var string + */ + private $label; + /** + * @var 'LINE_ITEM'|'SUBTOTAL'|'TAX' + */ + private $type; + /** + * @var string + */ + private $price; + /** + * @var 'FINAL'|'PENDING' + */ + private $status = self::STATUS_FINAL; + + /** + * @param string $label + * + * @return GooglePayDisplayItem + */ + public function setLabel($label) + { + $this->label = $label; + + return $this; + } + + /** + * @return string + */ + public function getLabel() + { + return $this->label; + } + + /** + * @param 'LINE_ITEM'|'SUBTOTAL'|'TAX' $type + * + * @return GooglePayDisplayItem + */ + public function setType($type) + { + $this->type = $type; + + return $this; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $price + * + * @return GooglePayDisplayItem + */ + public function setPrice($price) + { + $this->price = $price; + + return $this; + } + + /** + * @return string + */ + public function getPrice() + { + return $this->price; + } + + /** + * @param 'FINAL'|'PENDING' $status + * + * @return GooglePayDisplayItem + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } + + public function toArray() + { + return array_filter([ + 'label' => $this->label, + 'type' => $this->type, + 'price' => $this->price, + 'status' => $this->status, + ]); + } +} diff --git a/src/PayPal/GooglePay/DTO/GooglePayTransactionInfo.php b/src/PayPal/GooglePay/DTO/GooglePayTransactionInfo.php new file mode 100644 index 000000000..3eb915eea --- /dev/null +++ b/src/PayPal/GooglePay/DTO/GooglePayTransactionInfo.php @@ -0,0 +1,263 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO; + +class GooglePayTransactionInfo +{ + const TOTAL_PRICE_STATUS_ESTIMATED = 'ESTIMATED'; + const TOTAL_PRICE_STATUS_FINAL = 'FINAL'; + const CHECKOUT_OPTION_DEFAULT = 'DEFAULT'; + const CHECKOUT_OPTION_COMPLETE_IMMEDIATE_PURCHASE = 'COMPLETE_IMMEDIATE_PURCHASE'; + + /** + * @var string + */ + private $currencyCode; + /** + * @var string + */ + private $countryCode = null; + /** + * @var string + */ + private $transactionId = null; + /** + * @var 'ESTIMATED'|'FINAL' + */ + private $totalPriceStatus = self::TOTAL_PRICE_STATUS_FINAL; + /** + * @var string + */ + private $totalPrice; + /** + * @var GooglePayDisplayItem[] + */ + private $displayItems = []; + /** + * @var string + */ + private $totalPriceLabel; + /** + * @var 'DEFAULT'|'COMPLETE_IMMEDIATE_PURCHASE' + */ + private $checkoutOption = self::CHECKOUT_OPTION_DEFAULT; + /** + * @var MerchantInfo + */ + private $merchantInfo; + + /** + * @return string + */ + public function getCurrencyCode() + { + return $this->currencyCode; + } + + /** + * @param string $currencyCode + * + * @return GooglePayTransactionInfo + */ + public function setCurrencyCode($currencyCode) + { + $this->currencyCode = $currencyCode; + + return $this; + } + + /** + * @return string + */ + public function getCountryCode() + { + return $this->countryCode; + } + + /** + * @param string $countryCode + * + * @return GooglePayTransactionInfo + */ + public function setCountryCode($countryCode) + { + $this->countryCode = $countryCode; + + return $this; + } + + /** + * @return string + */ + public function getTransactionId() + { + return $this->transactionId; + } + + /** + * @param string $transactionId + * + * @return GooglePayTransactionInfo + */ + public function setTransactionId($transactionId) + { + $this->transactionId = $transactionId; + + return $this; + } + + /** + * @return string + */ + public function getTotalPriceStatus() + { + return $this->totalPriceStatus; + } + + /** + * @param 'ESTIMATED'|'FINAL' $totalPriceStatus + * + * @return GooglePayTransactionInfo + */ + public function setTotalPriceStatus($totalPriceStatus) + { + $this->totalPriceStatus = $totalPriceStatus; + + return $this; + } + + /** + * @return string + */ + public function getTotalPrice() + { + return $this->totalPrice; + } + + /** + * @param string $totalPrice + * + * @return GooglePayTransactionInfo + */ + public function setTotalPrice($totalPrice) + { + $this->totalPrice = $totalPrice; + + return $this; + } + + /** + * @return GooglePayDisplayItem[] + */ + public function getDisplayItems() + { + return $this->displayItems; + } + + /** + * @param GooglePayDisplayItem[] $displayItems + * + * @return GooglePayTransactionInfo + */ + public function setDisplayItems($displayItems) + { + $this->displayItems = $displayItems; + + return $this; + } + + /** + * @return string + */ + public function getTotalPriceLabel() + { + return $this->totalPriceLabel; + } + + /** + * @param string $totalPriceLabel + * + * @return GooglePayTransactionInfo + */ + public function setTotalPriceLabel($totalPriceLabel) + { + $this->totalPriceLabel = $totalPriceLabel; + + return $this; + } + + /** + * @return string + */ + public function getCheckoutOption() + { + return $this->checkoutOption; + } + + /** + * @param 'DEFAULT'|'COMPLETE_IMMEDIATE_PURCHASE' $checkoutOption + * + * @return GooglePayTransactionInfo + */ + public function setCheckoutOption($checkoutOption) + { + $this->checkoutOption = $checkoutOption; + + return $this; + } + + /** + * @param MerchantInfo $merchantInfo + * + * @return GooglePayTransactionInfo + */ + public function setMerchantInfo($merchantInfo) + { + $this->merchantInfo = $merchantInfo; + + return $this; + } + + /** + * @return MerchantInfo + */ + public function getMerchantInfo() + { + return $this->merchantInfo; + } + + public function toArray() + { + return array_filter([ + 'currencyCode' => $this->currencyCode, + 'countryCode' => $this->countryCode, + 'transactionId' => $this->transactionId, + 'totalPriceStatus' => $this->totalPriceStatus, + 'totalPrice' => $this->totalPrice, + 'totalPriceLabel' => $this->totalPriceLabel, + 'checkoutOption' => $this->checkoutOption, + 'displayItems' => array_map(function (GooglePayDisplayItem $item) { + return $item->toArray(); + }, $this->displayItems), + 'merchantInfo' => $this->merchantInfo->toArray(), + ]); + } +} diff --git a/src/PayPal/GooglePay/DTO/MerchantInfo.php b/src/PayPal/GooglePay/DTO/MerchantInfo.php new file mode 100644 index 000000000..739b1a322 --- /dev/null +++ b/src/PayPal/GooglePay/DTO/MerchantInfo.php @@ -0,0 +1,111 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO; + +class MerchantInfo +{ + /** + * @var string + */ + private $merchantName; + + /** + * @var string + */ + private $merchantId; + + /** + * @var string + */ + private $merchantOrigin; + + /** + * @return string + */ + public function getMerchantName() + { + return $this->merchantName; + } + + /** + * @param string $merchantName + * + * @return MerchantInfo + */ + public function setMerchantName($merchantName) + { + $this->merchantName = $merchantName; + + return $this; + } + + /** + * @return string + */ + public function getMerchantId() + { + return $this->merchantId; + } + + /** + * @param string $merchantId + * + * @return MerchantInfo + */ + public function setMerchantId($merchantId) + { + $this->merchantId = $merchantId; + + return $this; + } + + /** + * @return string + */ + public function getMerchantOrigin() + { + return $this->merchantOrigin; + } + + /** + * @param string $merchantOrigin + * + * @return MerchantInfo + */ + public function setMerchantOrigin($merchantOrigin) + { + $this->merchantOrigin = $merchantOrigin; + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + return array_filter([ + 'merchantName' => $this->merchantName, + 'merchantId' => $this->merchantId, + 'merchantOrigin' => $this->merchantOrigin, + ]); + } +} diff --git a/src/PayPal/GooglePay/DTO/index.php b/src/PayPal/GooglePay/DTO/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/GooglePay/DTO/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQuery.php b/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQuery.php new file mode 100644 index 000000000..e231252f9 --- /dev/null +++ b/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQuery.php @@ -0,0 +1,44 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query; + +use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; + +class GetGooglePayTransactionInfoQuery +{ + /** + * @var CartId + */ + private $cartId; + + public function __construct(CartId $cartId) + { + $this->cartId = $cartId; + } + + /** + * @return CartId + */ + public function getCartId() + { + return $this->cartId; + } +} diff --git a/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQueryHandler.php b/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQueryHandler.php new file mode 100644 index 000000000..4e0f5fe93 --- /dev/null +++ b/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQueryHandler.php @@ -0,0 +1,57 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query; + +use PrestaShop\Module\PrestashopCheckout\Builder\Payload\OrderPayloadBuilder; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Builder\GooglePayTransactionInfoBuilder; +use PrestaShop\Module\PrestashopCheckout\Presenter\Cart\CartPresenter; + +class GetGooglePayTransactionInfoQueryHandler +{ + /** + * @var GooglePayTransactionInfoBuilder + */ + private $builder; + + public function __construct(GooglePayTransactionInfoBuilder $builder) + { + $this->builder = $builder; + } + + /** + * @param GetGooglePayTransactionInfoQuery $query + * + * @return GetGooglePayTransactionInfoQueryResult + * + * @throws PsCheckoutException + */ + public function handle(GetGooglePayTransactionInfoQuery $query) + { + $cartPresenter = (new CartPresenter())->present(); + $orderPayloadBuilder = new OrderPayloadBuilder($cartPresenter); + + $orderPayloadBuilder->buildFullPayload(); + $payload = $orderPayloadBuilder->presentPayload(); + + return new GetGooglePayTransactionInfoQueryResult($this->builder->buildMinimalTransactionInfoFromPayPalPayload($payload->getArray())); + } +} diff --git a/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQueryResult.php b/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQueryResult.php new file mode 100644 index 000000000..fa799c18a --- /dev/null +++ b/src/PayPal/GooglePay/Query/GetGooglePayTransactionInfoQueryResult.php @@ -0,0 +1,44 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\Query; + +use PrestaShop\Module\PrestashopCheckout\PayPal\GooglePay\DTO\GooglePayTransactionInfo; + +class GetGooglePayTransactionInfoQueryResult +{ + /** + * @var GooglePayTransactionInfo + */ + private $payload; + + public function __construct(GooglePayTransactionInfo $payload) + { + $this->payload = $payload; + } + + /** + * @return GooglePayTransactionInfo + */ + public function getPayload() + { + return $this->payload; + } +} diff --git a/src/PayPal/GooglePay/Query/index.php b/src/PayPal/GooglePay/Query/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/GooglePay/Query/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Merchant/Exception/index.php b/src/PayPal/Merchant/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Merchant/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Merchant/ValueObject/index.php b/src/PayPal/Merchant/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Merchant/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Merchant/index.php b/src/PayPal/Merchant/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Merchant/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/OAuth/OAuthService.php b/src/PayPal/OAuth/OAuthService.php new file mode 100644 index 000000000..789188985 --- /dev/null +++ b/src/PayPal/OAuth/OAuthService.php @@ -0,0 +1,59 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; + +class OAuthService +{ + private $httpClient; + + public function __construct(CheckoutHttpClient $httpClient) + { + $this->httpClient = $httpClient; + } + + /** + * @param PayPalCustomerId|null $customerId + * + * @return string + * + * @throws Exception + */ + public function getUserIdToken($merchantId, PayPalCustomerId $customerId = null) + { + try { + $response = $this->httpClient->getUserIdToken($merchantId, $customerId); + + $data = json_decode($response->getBody(), true); + + if (empty($data['id_token'])) { + throw new Exception('Failed to get PayPal User ID token from response.'); + } + + return $data['id_token']; + } catch (Exception $exception) { + throw new Exception('Failed to get PayPal User ID token.', 0, $exception); + } + } +} diff --git a/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQuery.php b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQuery.php new file mode 100644 index 000000000..5d94ff131 --- /dev/null +++ b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQuery.php @@ -0,0 +1,47 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query; + +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; + +class GetPayPalGetUserIdTokenQuery +{ + /** + * @var CustomerId|null + */ + private $customerId; + + /** + * @param CustomerId|null $customerId + */ + public function __construct(CustomerId $customerId = null) + { + $this->customerId = $customerId; + } + + /** + * @return CustomerId|null + */ + public function getCustomerId() + { + return $this->customerId; + } +} diff --git a/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryHandler.php b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryHandler.php new file mode 100644 index 000000000..821616b34 --- /dev/null +++ b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryHandler.php @@ -0,0 +1,69 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\OAuthService; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository; + +class GetPayPalGetUserIdTokenQueryHandler +{ + /** + * @var OAuthService + */ + private $OAuthService; + + /** + * @var PayPalCustomerRepository + */ + private $customerRepository; + /** + * @var PayPalConfiguration + */ + private $payPalConfiguration; + + /** + * @param OAuthService $OAuthService + * @param PayPalCustomerRepository $customerRepository + */ + public function __construct(OAuthService $OAuthService, PayPalCustomerRepository $customerRepository, PayPalConfiguration $payPalConfiguration) + { + $this->OAuthService = $OAuthService; + $this->customerRepository = $customerRepository; + $this->payPalConfiguration = $payPalConfiguration; + } + + /** + * @param GetPayPalGetUserIdTokenQuery $query + * + * @return GetPayPalGetUserIdTokenQueryResult + * + * @throws Exception + */ + public function handle(GetPayPalGetUserIdTokenQuery $query) + { + $customerIdPayPal = $query->getCustomerId() ? $this->customerRepository->findPayPalCustomerIdByCustomerId($query->getCustomerId()) : null; + $merchantId = $this->payPalConfiguration->getMerchantId(); + + return new GetPayPalGetUserIdTokenQueryResult($this->OAuthService->getUserIdToken($merchantId, $customerIdPayPal)); + } +} diff --git a/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryResult.php b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryResult.php new file mode 100644 index 000000000..e3a3f4a9b --- /dev/null +++ b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryResult.php @@ -0,0 +1,45 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query; + +class GetPayPalGetUserIdTokenQueryResult +{ + /** + * @var string + */ + private $userIdToken; + + /** + * @param string $userIdToken + */ + public function __construct($userIdToken) + { + $this->userIdToken = $userIdToken; + } + + /** + * @return string + */ + public function getUserIdToken() + { + return $this->userIdToken; + } +} diff --git a/src/PayPal/OAuth/Query/index.php b/src/PayPal/OAuth/Query/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/OAuth/Query/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/OAuth/index.php b/src/PayPal/OAuth/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/OAuth/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/Cache/PayPalOrderCache.php b/src/PayPal/Order/Cache/PayPalOrderCache.php new file mode 100644 index 000000000..c326955e3 --- /dev/null +++ b/src/PayPal/Order/Cache/PayPalOrderCache.php @@ -0,0 +1,55 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Cache; + +use PsCheckoutCart; +use Symfony\Component\Cache\Simple\ChainCache; + +class PayPalOrderCache extends ChainCache +{ + const CACHE_TTL = [ + PsCheckoutCart::STATUS_CREATED => 600, + PsCheckoutCart::STATUS_PAYER_ACTION_REQUIRED => 600, + PsCheckoutCart::STATUS_APPROVED => 600, + PsCheckoutCart::STATUS_VOIDED => 3600, + PsCheckoutCart::STATUS_SAVED => 3600, + PsCheckoutCart::STATUS_CANCELED => 3600, + PsCheckoutCart::STATUS_COMPLETED => 3600, + ]; + + /** + * {@inheritdoc} + * + * @return bool + */ + public function set($key, $value, $ttl = null) + { + if (!$ttl && isset($value['status'])) { + $status = $value['status']; + if (self::CACHE_TTL[$status] !== null) { + $ttl = self::CACHE_TTL[$status]; + } + } + + return parent::set($key, $value, $ttl); + } +} diff --git a/src/PayPal/Order/Cache/index.php b/src/PayPal/Order/Cache/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/Cache/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/Command/CreatePayPalOrderCommand.php b/src/PayPal/Order/Command/CreatePayPalOrderCommand.php index b3b8998ef..84d242807 100644 --- a/src/PayPal/Order/Command/CreatePayPalOrderCommand.php +++ b/src/PayPal/Order/Command/CreatePayPalOrderCommand.php @@ -22,6 +22,7 @@ use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartException; use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; class CreatePayPalOrderCommand { @@ -44,6 +45,18 @@ class CreatePayPalOrderCommand * @var bool */ private $isExpressCheckout; + /** + * @var PaymentTokenId|null + */ + private $paymentTokenId; + /** + * @var bool + */ + private $favorite; + /** + * @var bool + */ + private $vault; /** * @param int $cartId @@ -53,12 +66,17 @@ class CreatePayPalOrderCommand * * @throws CartException */ - public function __construct($cartId, $fundingSource, $isHostedFields, $isExpressCheckout) + public function __construct($cartId, $fundingSource, $isHostedFields, $isExpressCheckout, $paymentTokenId = null, $favorite = false, $vault = false) { $this->cartId = new CartId($cartId); $this->fundingSource = $fundingSource; $this->isHostedFields = $isHostedFields; $this->isExpressCheckout = $isExpressCheckout; + if ($paymentTokenId) { + $this->paymentTokenId = new PaymentTokenId($paymentTokenId); + } + $this->favorite = $favorite; + $this->vault = $vault; } /** @@ -92,4 +110,52 @@ public function isExpressCheckout() { return $this->isExpressCheckout; } + + /** + * @return PaymentTokenId|null + */ + public function getPaymentTokenId() + { + return $this->paymentTokenId; + } + + /** + * @param PaymentTokenId|null $paymentTokenId + */ + public function setPaymentTokenId($paymentTokenId) + { + $this->paymentTokenId = $paymentTokenId; + } + + /** + * @return bool + */ + public function favorite() + { + return $this->favorite; + } + + /** + * @param bool $favorite + */ + public function setFavorite($favorite) + { + $this->favorite = $favorite; + } + + /** + * @return bool + */ + public function vault() + { + return $this->vault; + } + + /** + * @param bool $vault + */ + public function setVault($vault) + { + $this->vault = $vault; + } } diff --git a/src/PayPal/Order/Command/SavePayPalOrderCommand.php b/src/PayPal/Order/Command/SavePayPalOrderCommand.php new file mode 100644 index 000000000..497921103 --- /dev/null +++ b/src/PayPal/Order/Command/SavePayPalOrderCommand.php @@ -0,0 +1,139 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command; + +use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class SavePayPalOrderCommand +{ + /** + * @var array + */ + private $order; + /** + * @var CartId|null + */ + private $cartId; + /** + * @var string|null + */ + private $paymentMode; + /** + * @var array + */ + private $customerIntent; + /** + * @var bool|null + */ + private $isExpressCheckout; + /** + * @var bool|null + */ + private $isCardFields; + /** + * @var null + */ + private $fundingSource; + /** + * @var PaymentTokenId|null + */ + private $paymentTokenId; + + /** + * @param array $order + */ + public function __construct($order, CartId $cartId = null, $fundingSource = null, $paymentMode = null, $customerIntent = [], $isExpressCheckout = null, $isCardFields = null, $paymentTokenId = null) + { + $this->order = $order; + $this->cartId = $cartId; + $this->paymentMode = $paymentMode; + $this->customerIntent = $customerIntent; + $this->isExpressCheckout = $isExpressCheckout; + $this->isCardFields = $isCardFields; + $this->fundingSource = $fundingSource; + $this->paymentTokenId = $paymentTokenId; + } + + /** + * @return array + */ + public function getOrder() + { + return $this->order; + } + + /** + * @return CartId|null + */ + public function getCartId() + { + return $this->cartId; + } + + /** + * @return string|null + */ + public function getPaymentMode() + { + return $this->paymentMode; + } + + /** + * @return array + */ + public function getCustomerIntent() + { + return $this->customerIntent; + } + + /** + * @return bool|null + */ + public function isExpressCheckout() + { + return $this->isExpressCheckout; + } + + /** + * @return bool|null + */ + public function isCardFields() + { + return $this->isCardFields; + } + + /** + * @return string|null + */ + public function getFundingSource() + { + return $this->fundingSource; + } + + /** + * @return PaymentTokenId|null + */ + public function getPaymentTokenId() + { + return $this->paymentTokenId; + } +} diff --git a/src/PayPal/Order/Command/index.php b/src/PayPal/Order/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/CommandHandler/CapturePayPalOrderCommandHandler.php b/src/PayPal/Order/CommandHandler/CapturePayPalOrderCommandHandler.php index 7731c10d2..b3fade10a 100644 --- a/src/PayPal/Order/CommandHandler/CapturePayPalOrderCommandHandler.php +++ b/src/PayPal/Order/CommandHandler/CapturePayPalOrderCommandHandler.php @@ -22,18 +22,24 @@ namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler; use Configuration; -use Context; +use PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; use PrestaShop\Module\PrestashopCheckout\Event\EventDispatcherInterface; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CapturePayPalOrderCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderCompletedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderStatus; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\Event\PayPalCaptureCompletedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\Event\PayPalCaptureDeclinedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\Event\PayPalCapturePendingEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\PayPalCaptureStatus; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenCreatedEvent; use PrestaShop\Module\PrestashopCheckout\PayPalProcessorResponse; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; use Psr\SimpleCache\CacheInterface; class CapturePayPalOrderCommandHandler @@ -49,29 +55,55 @@ class CapturePayPalOrderCommandHandler private $orderPayPalCache; /** - * @var CheckoutHttpClient + * @var MaaslandHttpClient */ - private $httpClient; - - public function __construct(CheckoutHttpClient $httpClient, EventDispatcherInterface $eventDispatcher, CacheInterface $orderPayPalCache) - { - $this->httpClient = $httpClient; + private $maaslandHttpClient; + /** + * @var PrestaShopContext + */ + private $prestaShopContext; + /** + * @var PayPalCustomerRepository + */ + private $payPalCustomerRepository; + /** + * @var PayPalOrderRepository + */ + private $payPalOrderRepository; + + public function __construct( + MaaslandHttpClient $maaslandHttpClient, + EventDispatcherInterface $eventDispatcher, + CacheInterface $orderPayPalCache, + PrestaShopContext $prestaShopContext, + PayPalCustomerRepository $payPalCustomerRepository, + PayPalOrderRepository $payPalOrderRepository + ) { + $this->maaslandHttpClient = $maaslandHttpClient; $this->eventDispatcher = $eventDispatcher; $this->orderPayPalCache = $orderPayPalCache; + $this->prestaShopContext = $prestaShopContext; + $this->payPalCustomerRepository = $payPalCustomerRepository; + $this->payPalOrderRepository = $payPalOrderRepository; } public function handle(CapturePayPalOrderCommand $capturePayPalOrderCommand) { - $context = Context::getContext(); - $merchantId = Configuration::get('PS_CHECKOUT_PAYPAL_ID_MERCHANT', null, null, $context->shop->id); + $merchantId = Configuration::get('PS_CHECKOUT_PAYPAL_ID_MERCHANT', null, null, $this->prestaShopContext->getShopId()); - $response = $this->httpClient->captureOrder([ + $payload = [ 'mode' => $capturePayPalOrderCommand->getFundingSource(), 'orderId' => $capturePayPalOrderCommand->getOrderId()->getValue(), - 'payee' => [ - 'merchant_id' => $merchantId, - ], - ]); + 'payee' => ['merchant_id' => $merchantId], + ]; + + $order = $this->payPalOrderRepository->getPayPalOrderById($capturePayPalOrderCommand->getOrderId()); + + if ($order->checkCustomerIntent(PayPalOrder::CUSTOMER_INTENT_USES_VAULTING)) { + $payload['vault'] = true; + } + + $response = $this->maaslandHttpClient->captureOrder($payload); $orderPayPal = json_decode($response->getBody(), true); @@ -81,6 +113,34 @@ public function handle(CapturePayPalOrderCommand $capturePayPalOrderCommand) $capturePayPal = $orderPayPal['purchase_units'][0]['payments']['captures'][0]; + if (isset($orderPayPal['payment_source'][$capturePayPalOrderCommand->getFundingSource()]['attributes']['vault'])) { + $vault = $orderPayPal['payment_source'][$capturePayPalOrderCommand->getFundingSource()]['attributes']['vault']; + if (isset($vault['customer']['id'])) { + try { + $payPalCustomerId = new PayPalCustomerId($vault['customer']['id']); + $customerId = new CustomerId($this->prestaShopContext->getCustomerId()); + $this->payPalCustomerRepository->save($customerId, $payPalCustomerId); + } catch (\Exception $exception) { + } + } + + if (isset($vault['id'])) { + $resource = $vault; + $resource['metadata'] = [ + 'order_id' => $orderPayPal['id'], + ]; + $paymentSource = $orderPayPal['payment_source']; + unset($paymentSource[$capturePayPalOrderCommand->getFundingSource()]['attributes']['vault']); + $resource['payment_source'] = $paymentSource; + $resource['payment_source'][$capturePayPalOrderCommand->getFundingSource()]['verification_status'] = $resource['status']; + + $this->eventDispatcher->dispatch(new PaymentTokenCreatedEvent( + $resource, + $merchantId + )); + } + } + if ($orderPayPal['status'] === PayPalOrderStatus::COMPLETED) { $this->eventDispatcher->dispatch(new PayPalOrderCompletedEvent($orderPayPal['id'], $orderPayPal)); } diff --git a/src/PayPal/Order/CommandHandler/CreatePayPalOrderCommandHandler.php b/src/PayPal/Order/CommandHandler/CreatePayPalOrderCommandHandler.php index 4cf0cddfb..3dd9fa832 100644 --- a/src/PayPal/Order/CommandHandler/CreatePayPalOrderCommandHandler.php +++ b/src/PayPal/Order/CommandHandler/CreatePayPalOrderCommandHandler.php @@ -20,41 +20,67 @@ namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler; +use Exception; use PrestaShop\Module\PrestashopCheckout\Builder\Payload\OrderPayloadBuilder; +use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; +use PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; use PrestaShop\Module\PrestashopCheckout\Event\EventDispatcherInterface; -use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; +use PrestaShop\Module\PrestashopCheckout\Exception\InvalidRequestException; +use PrestaShop\Module\PrestashopCheckout\Exception\NotAuthorizedException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\Exception\UnprocessableEntityException; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CreatePayPalOrderCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderCreatedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; use PrestaShop\Module\PrestashopCheckout\Presenter\Cart\CartPresenter; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalCustomerRepository; use PrestaShop\Module\PrestashopCheckout\ShopContext; class CreatePayPalOrderCommandHandler { + /** + * @var MaaslandHttpClient + */ + private $maaslandHttpClient; /** * @var EventDispatcherInterface */ private $eventDispatcher; - /** - * @var CheckoutHttpClient + * @var PayPalCustomerRepository */ - private $httpClient; + private $payPalCustomerRepository; + /** + * @var PaymentTokenRepository + */ + private $paymentTokenRepository; /** * @var ShopContext */ private $shopContext; + /** + * @var PrestaShopContext + */ + private $prestaShopContext; public function __construct( - CheckoutHttpClient $httpClient, + MaaslandHttpClient $maaslandHttpClient, + ShopContext $shopContext, + PrestaShopContext $prestaShopContext, EventDispatcherInterface $eventDispatcher, - ShopContext $shopContext + PayPalCustomerRepository $payPalCustomerRepository, + PaymentTokenRepository $paymentTokenRepository ) { - $this->httpClient = $httpClient; - $this->eventDispatcher = $eventDispatcher; + $this->maaslandHttpClient = $maaslandHttpClient; $this->shopContext = $shopContext; + $this->eventDispatcher = $eventDispatcher; + $this->payPalCustomerRepository = $payPalCustomerRepository; + $this->paymentTokenRepository = $paymentTokenRepository; + $this->prestaShopContext = $prestaShopContext; } /** @@ -62,16 +88,47 @@ public function __construct( * * @return void * - * @throws PayPalException + * @throws CartNotFoundException * @throws PayPalOrderException + * @throws InvalidRequestException + * @throws NotAuthorizedException + * @throws UnprocessableEntityException + * @throws Exception * @throws PsCheckoutException */ public function handle(CreatePayPalOrderCommand $command) { $cartPresenter = (new CartPresenter())->present(); $builder = new OrderPayloadBuilder($cartPresenter); - $builder->setIsCard($command->getFundingSource() === 'card' && $command->isHostedFields()); + + try { + $customerId = $this->prestaShopContext->getCustomerId(); + $payPalCustomerId = $this->payPalCustomerRepository->findPayPalCustomerIdByCustomerId(new CustomerId($customerId)); + } catch (PsCheckoutException $exception) { + $payPalCustomerId = null; + } + + $customerIntent = []; + + if ($payPalCustomerId) { + $builder->setPaypalCustomerId($payPalCustomerId->getValue()); + } + + if ($command->getPaymentTokenId()) { + $customerIntent[] = PayPalOrder::CUSTOMER_INTENT_USES_VAULTING; + $paymentToken = $this->paymentTokenRepository->findById($command->getPaymentTokenId()); + + if (!$paymentToken || !$payPalCustomerId || $paymentToken->getPayPalCustomerId()->getValue() !== $payPalCustomerId->getValue()) { + throw new PsCheckoutException('Payment token does not belong to the customer'); + } + $builder->setPaypalVaultId($command->getPaymentTokenId()->getValue()); + } + + $builder->setIsCard($command->getFundingSource() === 'card' && ($command->isHostedFields() || $command->getPaymentTokenId())); $builder->setExpressCheckout($command->isExpressCheckout()); + $builder->setFundingSource($command->getFundingSource()); + $builder->setSavePaymentMethod($command->vault()); + $builder->setVault($command->getPaymentTokenId() || $command->vault()); if ($this->shopContext->isShop17()) { // Build full payload in 1.7 @@ -81,15 +138,27 @@ public function handle(CreatePayPalOrderCommand $command) $builder->buildMinimalPayload(); } - $response = $this->httpClient->createOrder($builder->presentPayload()->getArray()); + $response = $this->maaslandHttpClient->createOrder($builder->presentPayload()->getArray()); $order = json_decode($response->getBody(), true); + + if ($command->vault()) { + $customerIntent[] = PayPalOrder::CUSTOMER_INTENT_VAULT; + $customerIntent[] = PayPalOrder::CUSTOMER_INTENT_USES_VAULTING; + } + + if ($command->favorite()) { + $customerIntent[] = PayPalOrder::CUSTOMER_INTENT_FAVORITE; + } + $this->eventDispatcher->dispatch(new PayPalOrderCreatedEvent( $order['id'], $order, $command->getCartId()->getValue(), + $command->getFundingSource(), $command->isHostedFields(), $command->isExpressCheckout(), - $command->getFundingSource() + $customerIntent, + $command->getPaymentTokenId() )); } } diff --git a/src/PayPal/Order/CommandHandler/SavePayPalOrderCommandHandler.php b/src/PayPal/Order/CommandHandler/SavePayPalOrderCommandHandler.php new file mode 100644 index 000000000..11d5b10e4 --- /dev/null +++ b/src/PayPal/Order/CommandHandler/SavePayPalOrderCommandHandler.php @@ -0,0 +1,133 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\CommandHandler; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\SavePayPalOrderCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderAuthorization; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderCapture; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderPurchaseUnit; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderRefund; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; + +class SavePayPalOrderCommandHandler +{ + /** + * @var PayPalOrderRepository + */ + private $payPalOrderRepository; + + public function __construct(PayPalOrderRepository $payPalOrderRepository) + { + $this->payPalOrderRepository = $payPalOrderRepository; + } + + public function handle(SavePayPalOrderCommand $command) + { + $order = $command->getOrder(); + + $intent = isset($order['intent']) ? $order['intent'] : 'CAPTURE'; + try { + $payPalOrder = $this->payPalOrderRepository->getPayPalOrderById(new PayPalOrderId($order['id'])); + $payPalOrder->setStatus($order['status']); + $payPalOrder->setIntent($intent); + $payPalOrder->setFundingSource(isset($order['payment_source']) ? key($order['payment_source']) : $command->getFundingSource()); + if (isset($order['payment_source'])) { + $payPalOrder->setPaymentSource($order['payment_source']); + } + $this->payPalOrderRepository->savePayPalOrder($payPalOrder); + } catch (Exception $exception) { + $payPalOrder = new PayPalOrder( + $order['id'], + $command->getCartId()->getValue(), + $intent, + $command->getFundingSource(), + $order['status'], + isset($order['payment_source']) ? $order['payment_source'] : [], + $command->getPaymentMode(), + $command->isCardFields(), + $command->isExpressCheckout(), + $command->getCustomerIntent(), + $command->getPaymentTokenId() + ); + $this->payPalOrderRepository->savePayPalOrder($payPalOrder); + } + + if (!empty($order['purchase_units'])) { + foreach ($order['purchase_units'] as $purchaseUnit) { + $payPalPurchaseUnit = new PayPalOrderPurchaseUnit( + $order['id'], + crc32(json_encode($purchaseUnit)), + $purchaseUnit['reference_id'], + isset($purchaseUnit['items']) ? $purchaseUnit['items'] : [] + ); + + $this->payPalOrderRepository->savePayPalOrderPurchaseUnit($payPalPurchaseUnit); + + if (!empty($purchaseUnit['payments']['captures'])) { + foreach ($purchaseUnit['payments']['captures'] as $capture) { + $payPalCapture = new PayPalOrderCapture( + $capture['id'], + $order['id'], + $capture['status'], + $capture['create_time'], + $capture['update_time'], + $capture['seller_protection'], + $capture['seller_receivable_breakdown'], + (bool) $capture['final_capture'] + ); + $this->payPalOrderRepository->savePayPalOrderCapture($payPalCapture); + } + } + + if (!empty($purchaseUnit['payments']['authorizations'])) { + foreach ($purchaseUnit['payments']['authorizations'] as $authorization) { + $payPalAuthorization = new PayPalOrderAuthorization( + $authorization['id'], + $order['id'], + $authorization['status'], + $authorization['expiration_time'], + $authorization['seller_protection'] + ); + $this->payPalOrderRepository->savePayPalOrderAuthorization($payPalAuthorization); + } + } + + if (!empty($purchaseUnit['payments']['refunds'])) { + foreach ($purchaseUnit['payments']['refunds'] as $refund) { + $payPalRefund = new PayPalOrderRefund( + $refund['id'], + $order['id'], + $refund['status'], + $refund['invoice_id'], + $refund['custom_id'], + $refund['acquirer_reference_number'], + $refund['seller_payable_breakdown'] + ); + $this->payPalOrderRepository->savePayPalOrderRefund($payPalRefund); + } + } + } + } + } +} diff --git a/src/PayPal/Order/CommandHandler/UpdatePayPalOrderCommandHandler.php b/src/PayPal/Order/CommandHandler/UpdatePayPalOrderCommandHandler.php index e59ad0d5c..5e65221f4 100644 --- a/src/PayPal/Order/CommandHandler/UpdatePayPalOrderCommandHandler.php +++ b/src/PayPal/Order/CommandHandler/UpdatePayPalOrderCommandHandler.php @@ -26,10 +26,11 @@ use PrestaShop\Module\PrestashopCheckout\Event\EventDispatcherInterface; use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\UpdatePayPalOrderCommand; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderUpdatedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider; use PrestaShop\Module\PrestashopCheckout\Presenter\Cart\CartPresenter; use PrestaShop\Module\PrestashopCheckout\ShopContext; @@ -41,7 +42,7 @@ class UpdatePayPalOrderCommandHandler private $eventDispatcher; /** - * @var CheckoutHttpClient + * @var MaaslandHttpClient */ private $httpClient; @@ -51,18 +52,26 @@ class UpdatePayPalOrderCommandHandler private $shopContext; /** - * @param CheckoutHttpClient $httpClient + * @var PayPalOrderProvider + */ + private $paypalOrderProvider; + + /** + * @param MaaslandHttpClient $httpClient * @param EventDispatcherInterface $eventDispatcher * @param ShopContext $shopContext + * @param PayPalOrderProvider $paypalOrderProvider */ public function __construct( - CheckoutHttpClient $httpClient, + MaaslandHttpClient $httpClient, EventDispatcherInterface $eventDispatcher, - ShopContext $shopContext + ShopContext $shopContext, + PayPalOrderProvider $paypalOrderProvider ) { $this->httpClient = $httpClient; $this->eventDispatcher = $eventDispatcher; $this->shopContext = $shopContext; + $this->paypalOrderProvider = $paypalOrderProvider; } /** @@ -74,6 +83,16 @@ public function __construct( */ public function handle(UpdatePayPalOrderCommand $command) { + try { + $paypalOrder = $this->paypalOrderProvider->getById($command->getPayPalOrderId()->getValue()); + } catch (Exception $exception) { + return; + } + + if (empty($paypalOrder) || empty($paypalOrder['purchase_units'])) { + return; + } + $cartPresenter = (new CartPresenter())->present(); $builder = new OrderPayloadBuilder($cartPresenter, true); $builder->setIsUpdate(true); @@ -89,16 +108,87 @@ public function handle(UpdatePayPalOrderCommand $command) $builder->buildMinimalPayload(); } - $response = $this->httpClient->updateOrder($builder->presentPayload()->getArray()); - $order = json_decode($response->getBody(), true); + $payload = $builder->presentPayload()->getArray(); + $needToUpdate = false; + $updatedPayPalOrder = $paypalOrder; + + if (isset($paypalOrder['purchase_units'][0]['amount']) && isset($payload['amount'])) { + $amountDiff = $this->arrayRecursiveDiff($paypalOrder['purchase_units'][0]['amount'], $payload['amount']); + if (!empty($amountDiff)) { + $needToUpdate = true; + $updatedPayPalOrder['purchase_units'][0]['amount'] = $payload['amount']; + } + } + + if (isset($paypalOrder['purchase_units'][0]['items']) && isset($payload['items'])) { + $itemsDiff = $this->arrayRecursiveDiff($paypalOrder['purchase_units'][0]['items'], $payload['items']); + if (!empty($itemsDiff)) { + $needToUpdate = true; + $updatedPayPalOrder['purchase_units'][0]['items'] = $payload['items']; + } + } + + if (isset($paypalOrder['purchase_units'][0]['shipping']) && isset($payload['shipping'])) { + $shippingDiff = $this->arrayRecursiveDiff($paypalOrder['purchase_units'][0]['shipping'], $payload['shipping']); + if (!empty($shippingDiff)) { + $needToUpdate = true; + $updatedPayPalOrder['purchase_units'][0]['shipping'] = $payload['shipping']; + } + } + + if (!$needToUpdate) { + return; + } + + $response = $this->httpClient->updateOrder($payload); + + if ($response->getStatusCode() !== 204) { + throw new PayPalOrderException('Failed to update PayPal Order', PayPalOrderException::PAYPAL_ORDER_UPDATE_FAILED); + } $this->eventDispatcher->dispatch(new PayPalOrderUpdatedEvent( - $order['id'], - $order, + $command->getPayPalOrderId()->getValue(), + $updatedPayPalOrder, $command->getCartId()->getValue(), $command->isHostedFields(), $command->isExpressCheckout(), $command->getFundingSource() )); } + + /** + * Recursively compares two arrays and returns the differences. + * + * @param array $array1 + * @param array $array2 + * @param int $maxDepth + * @param int $currentDepth + * + * @return array + */ + private function arrayRecursiveDiff(array $array1, array $array2, $maxDepth = 5, $currentDepth = 0) + { + $result = []; + + if ($currentDepth >= $maxDepth) { + return $result; + } + + foreach ($array1 as $key => $value) { + if (array_key_exists($key, $array2)) { + if (is_array($value)) { + $recursiveDiff = $this->arrayRecursiveDiff($value, $array2[$key], $maxDepth, $currentDepth + 1); + if (!empty($recursiveDiff)) { + $result[$key] = $recursiveDiff; + } + } elseif ($value !== $array2[$key]) { + $result[$key] = $value; + } + } else { + $result[$key] = $value; + } + } + + return $result; + } } diff --git a/src/PayPal/Order/CommandHandler/index.php b/src/PayPal/Order/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/Entity/PayPalOrder.php b/src/PayPal/Order/Entity/PayPalOrder.php new file mode 100644 index 000000000..3e367a65a --- /dev/null +++ b/src/PayPal/Order/Entity/PayPalOrder.php @@ -0,0 +1,320 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity; + +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class PayPalOrder +{ + const TABLE = 'pscheckout_order'; + const CUSTOMER_INTENT_VAULT = 'VAULT'; + const CUSTOMER_INTENT_FAVORITE = 'FAVORITE'; + const CUSTOMER_INTENT_USES_VAULTING = 'USES_VAULTING'; + + /** + * @var PayPalOrderId + */ + private $id; + /** + * @var int + */ + private $idCart; + /** + * @var string + */ + private $intent; + /** + * @var string + */ + private $fundingSource; + /** + * @var string + */ + private $status; + /** + * @var array + */ + private $paymentSource; + /** + * @var string + */ + private $environment; + /** + * @var bool + */ + private $isCardFields; + /** + * @var bool + */ + private $isExpressCheckout; + /** + * @var array + */ + private $customerIntent; + /** + * @var PaymentTokenId|null + */ + private $paymentTokenId; + + public function __construct($id, $idCart, $intent, $fundingSource, $status, $paymentSource = [], $environment = 'LIVE', $isCardFields = false, $isExpressCheckout = false, $customerIntent = [], $paymentTokenId = null) + { + $this->id = new PayPalOrderId($id); + $this->idCart = $idCart; + $this->intent = $intent; + $this->fundingSource = $fundingSource; + $this->status = $status; + $this->paymentSource = $paymentSource; + $this->environment = $environment; + $this->isCardFields = (bool) $isCardFields; + $this->isExpressCheckout = (bool) $isExpressCheckout; + $this->customerIntent = $customerIntent; + $this->paymentTokenId = $paymentTokenId; + } + + /** + * @return PayPalOrderId + */ + public function getId() + { + return $this->id; + } + + /** + * @param PayPalOrderId $id + * + * @return PayPalOrder + */ + public function setId(PayPalOrderId $id) + { + $this->id = $id; + + return $this; + } + + /** + * @return int + */ + public function getIdCart() + { + return $this->idCart; + } + + /** + * @param int $idCart + * + * @return PayPalOrder + */ + public function setIdCart($idCart) + { + $this->idCart = $idCart; + + return $this; + } + + /** + * @return string + */ + public function getIntent() + { + return $this->intent; + } + + /** + * @param string $intent + * + * @return PayPalOrder + */ + public function setIntent($intent) + { + $this->intent = $intent; + + return $this; + } + + /** + * @return string + */ + public function getFundingSource() + { + return $this->fundingSource; + } + + /** + * @param string $fundingSource + * + * @return PayPalOrder + */ + public function setFundingSource($fundingSource) + { + $this->fundingSource = $fundingSource; + + return $this; + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string $status + * + * @return PayPalOrder + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } + + /** + * @return array + */ + public function getPaymentSource() + { + return $this->paymentSource; + } + + /** + * @param array $paymentSource + * + * @return PayPalOrder + */ + public function setPaymentSource($paymentSource) + { + $this->paymentSource = $paymentSource; + + return $this; + } + + /** + * @return string + */ + public function getEnvironment() + { + return $this->environment; + } + + /** + * @param string $environment + * + * @return PayPalOrder + */ + public function setEnvironment($environment) + { + $this->environment = $environment; + + return $this; + } + + /** + * @return bool + */ + public function isCardFields() + { + return $this->isCardFields; + } + + /** + * @param bool $isCardFields + * + * @return PayPalOrder + */ + public function setIsCardFields($isCardFields) + { + $this->isCardFields = (bool) $isCardFields; + + return $this; + } + + /** + * @return bool + */ + public function isExpressCheckout() + { + return $this->isExpressCheckout; + } + + /** + * @param bool $isExpressCheckout + * + * @return PayPalOrder + */ + public function setIsExpressCheckout($isExpressCheckout) + { + $this->isExpressCheckout = (bool) $isExpressCheckout; + + return $this; + } + + /** + * @return array + */ + public function getCustomerIntent() + { + return $this->customerIntent; + } + + /** + * @param array $customerIntent + * + * @return PayPalOrder + */ + public function setCustomerIntent($customerIntent) + { + $this->customerIntent = $customerIntent; + + return $this; + } + + /** + * Checks if customer intent contains an intent property and returns boolean value + * + * @param self::CUSTOMER_INTENT_VAULT|self::CUSTOMER_INTENT_FAVORITE|self::CUSTOMER_INTENT_USES_VAULTING $intent + * + * @return bool + */ + public function checkCustomerIntent($intent) + { + return in_array($intent, $this->customerIntent); + } + + /** + * @return PaymentTokenId|null + */ + public function getPaymentTokenId() + { + return $this->paymentTokenId; + } + + /** + * @param PaymentTokenId|null $paymentTokenId + */ + public function setPaymentTokenId($paymentTokenId) + { + $this->paymentTokenId = $paymentTokenId; + } +} diff --git a/src/PayPal/Order/Entity/PayPalOrderAuthorization.php b/src/PayPal/Order/Entity/PayPalOrderAuthorization.php new file mode 100644 index 000000000..12195a54c --- /dev/null +++ b/src/PayPal/Order/Entity/PayPalOrderAuthorization.php @@ -0,0 +1,156 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity; + +class PayPalOrderAuthorization +{ + const TABLE = 'pscheckout_authorization'; + + /** + * @var string|null + */ + private $id; + /** + * @var string|null + */ + private $idOrder; + /** + * @var string|null + */ + private $status; + /** + * @var string|null + */ + private $expirationTime; + /** + * @var array + */ + private $sellerProtection; + + public function __construct($id = null, $idOrder = null, $status = null, $expirationTime = null, $sellerProtection = []) + { + $this->id = $id; + $this->idOrder = $idOrder; + $this->status = $status; + $this->expirationTime = $expirationTime; + $this->sellerProtection = $sellerProtection; + } + + /** + * @return string|null + */ + public function getId() + { + return $this->id; + } + + /** + * @param string|null $id + * + * @return PayPalOrderAuthorization + */ + public function setId($id) + { + $this->id = $id; + + return $this; + } + + /** + * @return string|null + */ + public function getIdOrder() + { + return $this->idOrder; + } + + /** + * @param string|null $idOrder + * + * @return PayPalOrderAuthorization + */ + public function setIdOrder($idOrder) + { + $this->idOrder = $idOrder; + + return $this; + } + + /** + * @return string|null + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string|null $status + * + * @return PayPalOrderAuthorization + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } + + /** + * @return string|null + */ + public function getExpirationTime() + { + return $this->expirationTime; + } + + /** + * @param string|null $expirationTime + * + * @return PayPalOrderAuthorization + */ + public function setExpirationTime($expirationTime) + { + $this->expirationTime = $expirationTime; + + return $this; + } + + /** + * @return array + */ + public function getSellerProtection() + { + return $this->sellerProtection; + } + + /** + * @param array $sellerProtection + * + * @return PayPalOrderAuthorization + */ + public function setSellerProtection($sellerProtection) + { + $this->sellerProtection = $sellerProtection; + + return $this; + } +} diff --git a/src/PayPal/Order/Entity/PayPalOrderCapture.php b/src/PayPal/Order/Entity/PayPalOrderCapture.php new file mode 100644 index 000000000..0bb647325 --- /dev/null +++ b/src/PayPal/Order/Entity/PayPalOrderCapture.php @@ -0,0 +1,231 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity; + +class PayPalOrderCapture +{ + const TABLE = 'pscheckout_capture'; + + /** + * @var string + */ + private $id; + /** + * @var string + */ + private $idOrder; + /** + * @var string + */ + private $status; + /** + * @var bool + */ + private $finalCapture; + /** + * @var string + */ + private $createdAt; + /** + * @var string + */ + private $updatedAt; + /** + * @var array + */ + private $sellerProtection; + /** + * @var array + */ + private $sellerReceivableBreakdown; + + public function __construct($id, $idOrder, $status, $createdAt, $updatedAt, $sellerProtection, $sellerReceivableBreakdown, $finalCapture = false) + { + $this->id = $id; + $this->idOrder = $idOrder; + $this->status = $status; + $this->finalCapture = (bool) $finalCapture; + $this->createdAt = $createdAt; + $this->updatedAt = $updatedAt; + $this->sellerProtection = $sellerProtection; + $this->sellerReceivableBreakdown = $sellerReceivableBreakdown; + } + + /** + * @return string|null + */ + public function getId() + { + return $this->id; + } + + /** + * @param string|null $id + * + * @return PayPalOrderCapture + */ + public function setId($id) + { + $this->id = $id; + + return $this; + } + + /** + * @return string|null + */ + public function getIdOrder() + { + return $this->idOrder; + } + + /** + * @param string|null $idOrder + * + * @return PayPalOrderCapture + */ + public function setIdOrder($idOrder) + { + $this->idOrder = $idOrder; + + return $this; + } + + /** + * @return string|null + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string|null $status + * + * @return PayPalOrderCapture + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } + + /** + * @return bool|mixed + */ + public function getFinalCapture() + { + return $this->finalCapture; + } + + /** + * @param bool $finalCapture + * + * @return PayPalOrderCapture + */ + public function setFinalCapture($finalCapture) + { + $this->finalCapture = (bool) $finalCapture; + + return $this; + } + + /** + * @return string|null + */ + public function getCreatedAt() + { + return $this->createdAt; + } + + /** + * @param string|null $createdAt + * + * @return PayPalOrderCapture + */ + public function setCreatedAt($createdAt) + { + $this->createdAt = $createdAt; + + return $this; + } + + /** + * @return string|null + */ + public function getUpdatedAt() + { + return $this->updatedAt; + } + + /** + * @param string|null $updatedAt + * + * @return PayPalOrderCapture + */ + public function setUpdatedAt($updatedAt) + { + $this->updatedAt = $updatedAt; + + return $this; + } + + /** + * @return array|null + */ + public function getSellerProtection() + { + return $this->sellerProtection; + } + + /** + * @param array $sellerProtection + * + * @return PayPalOrderCapture + */ + public function setSellerProtection($sellerProtection) + { + $this->sellerProtection = $sellerProtection; + + return $this; + } + + /** + * @return array + */ + public function getSellerReceivableBreakdown() + { + return $this->sellerReceivableBreakdown; + } + + /** + * @param array $sellerReceivableBreakdown + * + * @return PayPalOrderCapture + */ + public function setSellerReceivableBreakdown($sellerReceivableBreakdown) + { + $this->sellerReceivableBreakdown = $sellerReceivableBreakdown; + + return $this; + } +} diff --git a/src/PayPal/Order/Entity/PayPalOrderPurchaseUnit.php b/src/PayPal/Order/Entity/PayPalOrderPurchaseUnit.php new file mode 100644 index 000000000..3f551ebf7 --- /dev/null +++ b/src/PayPal/Order/Entity/PayPalOrderPurchaseUnit.php @@ -0,0 +1,131 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity; + +class PayPalOrderPurchaseUnit +{ + const TABLE = 'pscheckout_purchase_unit'; + + /** + * @var string|null + */ + private $idOrder; + /** + * @var string|null + */ + private $checksum; + /** + * @var string|null + */ + private $referenceId; + /** + * @var array + */ + private $items; + + public function __construct($idOrder = null, $checksum = null, $referenceId = null, $items = []) + { + $this->idOrder = $idOrder; + $this->checksum = $checksum; + $this->referenceId = $referenceId; + $this->items = $items; + } + + /** + * @return string|null + */ + public function getIdOrder() + { + return $this->idOrder; + } + + /** + * @param string|null $idOrder + * + * @return PayPalOrderPurchaseUnit + */ + public function setIdOrder($idOrder) + { + $this->idOrder = $idOrder; + + return $this; + } + + /** + * @return string|null + */ + public function getChecksum() + { + return $this->checksum; + } + + /** + * @param string|null $checksum + * + * @return PayPalOrderPurchaseUnit + */ + public function setChecksum($checksum) + { + $this->checksum = $checksum; + + return $this; + } + + /** + * @return string|null + */ + public function getReferenceId() + { + return $this->referenceId; + } + + /** + * @param string|null $referenceId + * + * @return PayPalOrderPurchaseUnit + */ + public function setReferenceId($referenceId) + { + $this->referenceId = $referenceId; + + return $this; + } + + /** + * @return array + */ + public function getItems() + { + return $this->items; + } + + /** + * @param array $items + * + * @return PayPalOrderPurchaseUnit + */ + public function setItems($items) + { + $this->items = $items; + + return $this; + } +} diff --git a/src/PayPal/Order/Entity/PayPalOrderRefund.php b/src/PayPal/Order/Entity/PayPalOrderRefund.php new file mode 100644 index 000000000..e1d6dba87 --- /dev/null +++ b/src/PayPal/Order/Entity/PayPalOrderRefund.php @@ -0,0 +1,231 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity; + +class PayPalOrderRefund +{ + const TABLE = 'pscheckout_refund'; + + /** + * @var string|null + */ + private $id; + /** + * @var string|null + */ + private $idOrder; + /** + * @var string|null + */ + private $status; + /** + * @var string|null + */ + private $invoiceId; + /** + * @var string|null + */ + private $customId; + /** + * @var string|null + */ + private $acquirerReferenceNumber; + /** + * @var array + */ + private $sellerPayableBreakdown; + /** + * @var int + */ + private $idOrderSlip; + + public function __construct($id = null, $idOrder = null, $status = null, $invoiceId = null, $customId = null, $acquirerReferenceNumber = null, $sellerPayableBreakdown = [], $idOrderSlip = null) + { + $this->id = $id; + $this->idOrder = $idOrder; + $this->status = $status; + $this->invoiceId = $invoiceId; + $this->customId = $customId; + $this->acquirerReferenceNumber = $acquirerReferenceNumber; + $this->sellerPayableBreakdown = $sellerPayableBreakdown; + $this->idOrderSlip = $idOrderSlip; + } + + /** + * @return string|null + */ + public function getId() + { + return $this->id; + } + + /** + * @param string|null $id + * + * @return PayPalOrderRefund + */ + public function setId($id) + { + $this->id = $id; + + return $this; + } + + /** + * @return string|null + */ + public function getIdOrder() + { + return $this->idOrder; + } + + /** + * @param string|null $idOrder + * + * @return PayPalOrderRefund + */ + public function setIdOrder($idOrder) + { + $this->idOrder = $idOrder; + + return $this; + } + + /** + * @return string|null + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string|null $status + * + * @return PayPalOrderRefund + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } + + /** + * @return string|null + */ + public function getInvoiceId() + { + return $this->invoiceId; + } + + /** + * @param string|null $invoiceId + * + * @return PayPalOrderRefund + */ + public function setInvoiceId($invoiceId) + { + $this->invoiceId = $invoiceId; + + return $this; + } + + /** + * @return string|null + */ + public function getCustomId() + { + return $this->customId; + } + + /** + * @param string|null $customId + * + * @return PayPalOrderRefund + */ + public function setCustomId($customId) + { + $this->customId = $customId; + + return $this; + } + + /** + * @return string|null + */ + public function getAcquirerReferenceNumber() + { + return $this->acquirerReferenceNumber; + } + + /** + * @param string|null $acquirerReferenceNumber + * + * @return PayPalOrderRefund + */ + public function setAcquirerReferenceNumber($acquirerReferenceNumber) + { + $this->acquirerReferenceNumber = $acquirerReferenceNumber; + + return $this; + } + + /** + * @return array + */ + public function getSellerPayableBreakdown() + { + return $this->sellerPayableBreakdown; + } + + /** + * @param array $sellerPayableBreakdown + * + * @return PayPalOrderRefund + */ + public function setSellerPayableBreakdown($sellerPayableBreakdown) + { + $this->sellerPayableBreakdown = $sellerPayableBreakdown; + + return $this; + } + + /** + * @return int|null + */ + public function getIdOrderSlip() + { + return $this->idOrderSlip; + } + + /** + * @param int $idOrderSlip + * + * @return PayPalOrderRefund + */ + public function setIdOrderSlip($idOrderSlip) + { + $this->idOrderSlip = (int) $idOrderSlip; + + return $this; + } +} diff --git a/src/PayPal/Order/Entity/index.php b/src/PayPal/Order/Entity/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/Entity/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/Event/PayPalOrderCreatedEvent.php b/src/PayPal/Order/Event/PayPalOrderCreatedEvent.php index 53c1e46ee..7b7822741 100644 --- a/src/PayPal/Order/Event/PayPalOrderCreatedEvent.php +++ b/src/PayPal/Order/Event/PayPalOrderCreatedEvent.php @@ -23,6 +23,7 @@ use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartException; use PrestaShop\Module\PrestashopCheckout\Cart\ValueObject\CartId; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; class PayPalOrderCreatedEvent extends PayPalOrderEvent { @@ -34,36 +35,44 @@ class PayPalOrderCreatedEvent extends PayPalOrderEvent /** * @var bool */ - private $isHostedFields; - + private $isCardFields; /** * @var bool */ private $isExpressCheckout; - /** * @var string */ private $fundingSource; + /** + * @var array + */ + private $customerIntent; + /** + * @var PaymentTokenId|null + */ + private $paymentTokenId; /** * @param string $orderPayPalId * @param array $orderPayPal * @param int $cartId - * @param bool $isHostedFields + * @param bool $isCardFields * @param bool $isExpressCheckout * @param string $fundingSource * * @throws CartException * @throws PayPalOrderException */ - public function __construct($orderPayPalId, $orderPayPal, $cartId, $isHostedFields, $isExpressCheckout, $fundingSource) + public function __construct($orderPayPalId, $orderPayPal, $cartId, $fundingSource, $isCardFields, $isExpressCheckout, $customerIntent = [], $paymentTokenId = null) { parent::__construct($orderPayPalId, $orderPayPal); $this->cartId = new CartId($cartId); - $this->isHostedFields = $isHostedFields; + $this->isCardFields = $isCardFields; $this->isExpressCheckout = $isExpressCheckout; $this->fundingSource = $fundingSource; + $this->customerIntent = $customerIntent; + $this->paymentTokenId = $paymentTokenId; } /** @@ -77,9 +86,9 @@ public function getCartId() /** * @return bool */ - public function isHostedFields() + public function isCardFields() { - return $this->isHostedFields; + return $this->isCardFields; } /** @@ -97,4 +106,20 @@ public function getFundingSource() { return $this->fundingSource; } + + /** + * @return array + */ + public function getCustomerIntent() + { + return $this->customerIntent; + } + + /** + * @return PaymentTokenId|null + */ + public function getPaymentTokenId() + { + return $this->paymentTokenId; + } } diff --git a/src/PayPal/Order/Event/index.php b/src/PayPal/Order/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php b/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php index a4d5328c7..4d5954955 100644 --- a/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php +++ b/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php @@ -21,6 +21,7 @@ namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\EventSubscriber; +use Exception; use PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker; use PrestaShop\Module\PrestashopCheckout\Checkout\Command\SaveCheckoutCommand; use PrestaShop\Module\PrestashopCheckout\Checkout\Command\SavePayPalOrderStatusCommand; @@ -34,6 +35,7 @@ use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\CheckTransitionPayPalOrderStatusService; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CapturePayPalOrderCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\SavePayPalOrderCommand; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderApprovalReversedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderApprovedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderCompletedEvent; @@ -42,6 +44,7 @@ use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Event\PayPalOrderUpdatedEvent; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\PayPalOrderStatus; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use Ps_checkout; use Psr\SimpleCache\CacheInterface; @@ -83,6 +86,14 @@ class PayPalOrderEventSubscriber implements EventSubscriberInterface * @var CommandBusInterface */ private $commandBus; + /** + * @var PayPalConfiguration + */ + private $payPalConfiguration; + /** + * @var PayPalOrderRepository + */ + private $payPalOrderRepository; public function __construct( Ps_checkout $module, @@ -90,7 +101,9 @@ public function __construct( CacheInterface $orderPayPalCache, CheckoutChecker $checkoutChecker, CheckTransitionPayPalOrderStatusService $checkTransitionPayPalOrderStatusService, - OrderStateMapper $orderStateMapper + OrderStateMapper $orderStateMapper, + PayPalConfiguration $payPalConfiguration, + PayPalOrderRepository $payPalOrderRepository ) { $this->module = $module; $this->psCheckoutCartRepository = $psCheckoutCartRepository; @@ -99,6 +112,8 @@ public function __construct( $this->checkTransitionPayPalOrderStatusService = $checkTransitionPayPalOrderStatusService; $this->orderStateMapper = $orderStateMapper; $this->commandBus = $this->module->getService('ps_checkout.bus.command'); + $this->payPalConfiguration = $payPalConfiguration; + $this->payPalOrderRepository = $payPalOrderRepository; } /** @@ -126,6 +141,7 @@ public static function getSubscribedEvents() ['clearCache'], ], PayPalOrderUpdatedEvent::class => [ + ['updatePayPalOrder'], ['clearCache'], ], ]; @@ -133,19 +149,34 @@ public static function getSubscribedEvents() public function saveCreatedPayPalOrder(PayPalOrderCreatedEvent $event) { - /** @var PayPalConfiguration $configuration */ - $configuration = $this->module->getService('ps_checkout.paypal.configuration'); $order = $event->getOrderPayPal(); + try { // NOT SURE WHAT SHOULD HAPPEN IF ORDER WITH THAT ID ALREADY EXISTS + $payPalOrder = $this->payPalOrderRepository->getPayPalOrderByCartId($event->getCartId()->getValue()); + $this->payPalOrderRepository->deletePayPalOrder($payPalOrder->getId()); + } catch (Exception $e) { + } + + $this->commandBus->handle(new SavePayPalOrderCommand( + $order, + $event->getCartId(), + $event->getFundingSource(), + $this->payPalConfiguration->getPaymentMode(), + $event->getCustomerIntent(), + $event->isExpressCheckout(), + $event->isCardFields(), + $event->getPaymentTokenId() + )); + $this->commandBus->handle(new SaveCheckoutCommand( $event->getCartId()->getValue(), $event->getOrderPayPalId()->getValue(), $order['status'], - $order['intent'], + isset($order['intent']) ? $order['intent'] : $this->payPalConfiguration->getIntent(), $event->getFundingSource(), $event->isExpressCheckout(), - $event->isHostedFields(), - $configuration->getPaymentMode() + $event->isCardFields(), + $this->payPalConfiguration->getPaymentMode() )); } @@ -161,6 +192,11 @@ public function saveApprovedPayPalOrder(PayPalOrderApprovedEvent $event) return; } + try { + $this->commandBus->handle(new SavePayPalOrderCommand($event->getOrderPayPal())); + } catch (Exception $exception) { + } + $this->commandBus->handle(new SavePayPalOrderStatusCommand( $event->getOrderPayPalId()->getValue(), PayPalOrderStatus::APPROVED @@ -179,6 +215,11 @@ public function saveCompletedPayPalOrder(PayPalOrderCompletedEvent $event) return; } + try { + $this->commandBus->handle(new SavePayPalOrderCommand($event->getOrderPayPal())); + } catch (Exception $exception) { + } + $this->commandBus->handle(new SavePayPalOrderStatusCommand( $event->getOrderPayPalId()->getValue(), PayPalOrderStatus::COMPLETED @@ -267,6 +308,14 @@ public function updateCache(PayPalOrderEvent $event) $this->orderPayPalCache->set($event->getOrderPayPalId()->getValue(), $newOrderPayPal); } + public function updatePayPalOrder(PayPalOrderUpdatedEvent $event) + { + $this->commandBus->handle(new SavePayPalOrderCommand( + $event->getOrderPayPal(), + $event->getCartId() + )); + } + public function clearCache(PayPalOrderEvent $event) { $this->orderPayPalCache->delete($event->getOrderPayPalId()->getValue()); diff --git a/src/PayPal/Order/EventSubscriber/index.php b/src/PayPal/Order/EventSubscriber/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/EventSubscriber/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/Exception/PayPalOrderException.php b/src/PayPal/Order/Exception/PayPalOrderException.php index b4de3faf4..949e62cb1 100644 --- a/src/PayPal/Order/Exception/PayPalOrderException.php +++ b/src/PayPal/Order/Exception/PayPalOrderException.php @@ -27,7 +27,5 @@ class PayPalOrderException extends PsCheckoutException const INVALID_ID = 1; const CANNOT_RETRIEVE_ORDER = 2; const EMPTY_ORDER_DATA = 3; - const CANNOT_CAPTURE_ORDER = 4; - const SESSION_EXCEPTION = 5; - const CACHE_EXCEPTION = 6; + const PAYPAL_ORDER_UPDATE_FAILED = 4; } diff --git a/src/PayPal/Order/Exception/index.php b/src/PayPal/Order/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/PayPalOrderSummaryView.php b/src/PayPal/Order/PayPalOrderSummaryView.php index d62178c94..02bf762ce 100644 --- a/src/PayPal/Order/PayPalOrderSummaryView.php +++ b/src/PayPal/Order/PayPalOrderSummaryView.php @@ -108,6 +108,9 @@ public function getTemplateVars() 'contactUsLink' => $this->router->getContactLink($this->orderDataProvider->getOrderId()), 'isShop17' => $this->shopContext->isShop17(), 'translations' => $this->orderPayPalPresenter->getSummaryTranslations(), + 'vault' => $this->orderPayPalDataProvider->isIntentToVault(), + 'tokenIdentifier' => $this->orderPayPalDataProvider->getPaymentTokenIdentifier(), + 'isTokenSaved' => $this->orderPayPalDataProvider->isTokenSaved(), ]; } } diff --git a/src/PayPal/Order/PayPalOrderSummaryViewBuilder.php b/src/PayPal/Order/PayPalOrderSummaryViewBuilder.php index a78527f61..96fe7229b 100644 --- a/src/PayPal/Order/PayPalOrderSummaryViewBuilder.php +++ b/src/PayPal/Order/PayPalOrderSummaryViewBuilder.php @@ -24,8 +24,10 @@ use Order; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Order\OrderDataProvider; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider; use PrestaShop\Module\PrestashopCheckout\PsCheckoutDataProvider; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; use PrestaShop\Module\PrestashopCheckout\Routing\Router; use PrestaShop\Module\PrestashopCheckout\ShopContext; @@ -56,6 +58,10 @@ class PayPalOrderSummaryViewBuilder * @var ShopContext */ private $shopContext; + /** + * @var PayPalOrderRepository + */ + private $payPalOrderRepository; /** * @param PsCheckoutCartRepository $psCheckoutCartRepository @@ -69,13 +75,15 @@ public function __construct( PayPalOrderProvider $orderPayPalProvider, Router $router, PayPalOrderTranslationProvider $orderPayPalTranslationProvider, - ShopContext $shopContext + ShopContext $shopContext, + PayPalOrderRepository $payPalOrderRepository ) { $this->psCheckoutCartRepository = $psCheckoutCartRepository; $this->orderPayPalProvider = $orderPayPalProvider; $this->router = $router; $this->orderPayPalTranslationProvider = $orderPayPalTranslationProvider; $this->shopContext = $shopContext; + $this->payPalOrderRepository = $payPalOrderRepository; } /** @@ -97,6 +105,12 @@ public function build(Order $order) throw new PsCheckoutException('Unable to retrieve cart data'); } + try { + $payPalOrder = $this->payPalOrderRepository->getPayPalOrderById(new PayPalOrderId($psCheckoutCart->paypal_order)); + } catch (PsCheckoutException $exception) { + $payPalOrder = null; + } + try { $orderPayPal = $this->orderPayPalProvider->getById($psCheckoutCart->paypal_order); } catch (Exception $exception) { @@ -107,7 +121,7 @@ public function build(Order $order) throw new PsCheckoutException('Unable to retrieve PayPal order data'); } - $orderPayPalDataProvider = new PaypalOrderDataProvider($orderPayPal); + $orderPayPalDataProvider = new PaypalOrderDataProvider($orderPayPal, $payPalOrder); $checkoutDataProvider = new PsCheckoutDataProvider($psCheckoutCart); return new PayPalOrderSummaryView( diff --git a/src/PayPal/Order/PaypalOrderDataProvider.php b/src/PayPal/Order/PaypalOrderDataProvider.php index 786598468..b2c0fc1aa 100644 --- a/src/PayPal/Order/PaypalOrderDataProvider.php +++ b/src/PayPal/Order/PaypalOrderDataProvider.php @@ -20,19 +20,26 @@ namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; + class PaypalOrderDataProvider { /** * @var array */ private $orderData; + /** + * @var PayPalOrder|null + */ + private $payPalOrder; /** * @param array $order */ - public function __construct(array $order) + public function __construct(array $order, PayPalOrder $payPalOrder = null) { $this->orderData = $order; + $this->payPalOrder = $payPalOrder; } /** @@ -130,4 +137,40 @@ public function getCurrencyCode() ? $this->orderData['purchase_units'][0]['payments']['captures'][0]['amount']['currency_code'] : ''; } + + public function isIntentToVault() + { + return $this->payPalOrder && $this->payPalOrder->checkCustomerIntent(PayPalOrder::CUSTOMER_INTENT_VAULT); + } + + public function isTokenSaved() + { + if ($this->payPalOrder && isset($this->payPalOrder->getPaymentSource()[$this->payPalOrder->getFundingSource()])) { + $paymentSource = $this->payPalOrder->getPaymentSource()[$this->payPalOrder->getFundingSource()]; + + return isset($paymentSource['attributes']['vault']['id']) && + isset($paymentSource['attributes']['vault']['status']) && + $paymentSource['attributes']['vault']['status'] === 'VAULTED'; + } + + return false; + } + + public function getPaymentTokenIdentifier() + { + if ($this->payPalOrder) { + $fundingSource = $this->payPalOrder->getFundingSource(); + if (isset($this->payPalOrder->getPaymentSource()[$fundingSource])) { + $paymentSource = $this->payPalOrder->getPaymentSource()[$fundingSource]; + + if ($fundingSource === 'card') { + return (isset($paymentSource['brand']) ? $paymentSource['brand'] : '') . (isset($paymentSource['last_digits']) ? ' *' . $paymentSource['last_digits'] : ''); + } else { + return isset($paymentSource['email_address']) ? $paymentSource['email_address'] : ''; + } + } + } + + return ''; + } } diff --git a/src/PayPal/Order/Query/index.php b/src/PayPal/Order/Query/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/Query/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/QueryHandler/GetPayPalOrderForCheckoutCompletedQueryHandler.php b/src/PayPal/Order/QueryHandler/GetPayPalOrderForCheckoutCompletedQueryHandler.php index 6c4a439cc..53d96d1ca 100644 --- a/src/PayPal/Order/QueryHandler/GetPayPalOrderForCheckoutCompletedQueryHandler.php +++ b/src/PayPal/Order/QueryHandler/GetPayPalOrderForCheckoutCompletedQueryHandler.php @@ -46,24 +46,27 @@ public function __construct(CacheInterface $orderPayPalCache) public function handle(GetPayPalOrderForCheckoutCompletedQuery $getPayPalOrderQuery) { + $payPalOrderId = $getPayPalOrderQuery->getOrderPayPalId()->getValue(); + /** @var array{id: string, status: string} $order */ - $order = $this->orderPayPalCache->get($getPayPalOrderQuery->getOrderPayPalId()->getValue()); + $order = $this->orderPayPalCache->get($payPalOrderId); - if (!empty($order) && $order['status'] === 'APPROVED') { + if (!empty($order) && in_array($order['status'], ['COMPLETED', 'CANCELED'])) { return new GetPayPalOrderForCheckoutCompletedQueryResult($order); } try { - $orderPayPal = new PaypalOrder($getPayPalOrderQuery->getOrderPayPalId()->getValue()); - $this->orderPayPalCache->set($getPayPalOrderQuery->getOrderPayPalId()->getValue(), $orderPayPal->getOrder()); + $orderPayPal = new PaypalOrder($payPalOrderId); + $orderToStoreInCache = !empty($order) ? array_replace_recursive($order, $orderPayPal->getOrder()) : $orderPayPal->getOrder(); + $this->orderPayPalCache->set($payPalOrderId, $orderToStoreInCache); } catch (HttpTimeoutException $exception) { throw $exception; } catch (Exception $exception) { - throw new PayPalOrderException(sprintf('Unable to retrieve PayPal Order %s', $getPayPalOrderQuery->getOrderPayPalId()->getValue()), PayPalOrderException::CANNOT_RETRIEVE_ORDER, $exception); + throw new PayPalOrderException(sprintf('Unable to retrieve PayPal Order %s', $payPalOrderId), PayPalOrderException::CANNOT_RETRIEVE_ORDER, $exception); } if (!$orderPayPal->isLoaded()) { - throw new PayPalOrderException(sprintf('No data for PayPal Order %s', $getPayPalOrderQuery->getOrderPayPalId()->getValue()), PayPalOrderException::EMPTY_ORDER_DATA); + throw new PayPalOrderException(sprintf('No data for PayPal Order %s', $payPalOrderId), PayPalOrderException::EMPTY_ORDER_DATA); } return new GetPayPalOrderForCheckoutCompletedQueryResult($orderPayPal->getOrder()); diff --git a/src/PayPal/Order/QueryHandler/index.php b/src/PayPal/Order/QueryHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/QueryHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/ValueObject/index.php b/src/PayPal/Order/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Order/index.php b/src/PayPal/Order/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Order/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PayPalConfiguration.php b/src/PayPal/PayPalConfiguration.php index 3f6af00c3..efd1c6511 100644 --- a/src/PayPal/PayPalConfiguration.php +++ b/src/PayPal/PayPalConfiguration.php @@ -48,6 +48,12 @@ class PayPalConfiguration const PS_CHECKOUT_DISPLAY_LOGO_PRODUCT = 'PS_CHECKOUT_DISPLAY_LOGO_PRODUCT'; const PS_CHECKOUT_DISPLAY_LOGO_CART = 'PS_CHECKOUT_DISPLAY_LOGO_CART'; + const PS_CHECKOUT_VAULTING = 'PS_CHECKOUT_VAULTING'; + + const PS_CHECKOUT_GOOGLE_PAY = 'PS_CHECKOUT_GOOGLE_PAY'; + const PS_CHECKOUT_APPLE_PAY = 'PS_CHECKOUT_APPLE_PAY'; + const PS_CHECKOUT_DOMAIN_REGISTERED_SANDBOX = 'PS_CHECKOUT_DOMAIN_REGISTERED_SANDBOX'; + const PS_CHECKOUT_DOMAIN_REGISTERED_LIVE = 'PS_CHECKOUT_DOMAIN_REGISTERED_LIVE'; /** * @var PrestaShopConfiguration @@ -430,4 +436,29 @@ public function getTimeZone() 'default' => date_default_timezone_get(), ]); } + + /** + * Merchant can disable vaulting in module configuration + * + * @return bool + */ + public function isVaultingEnabled() + { + return (bool) $this->configuration->get(static::PS_CHECKOUT_VAULTING); + } + + public function isGooglePayEligible() + { + return (bool) $this->configuration->get(static::PS_CHECKOUT_GOOGLE_PAY); + } + + public function isApplePayEligible() + { + return (bool) $this->configuration->get(static::PS_CHECKOUT_APPLE_PAY); + } + + public function isApplePayDomainRegistered() + { + return (bool) $this->configuration->get($this->getPaymentMode() === Mode::SANDBOX ? static::PS_CHECKOUT_DOMAIN_REGISTERED_SANDBOX : static::PS_CHECKOUT_DOMAIN_REGISTERED_LIVE); + } } diff --git a/src/PayPal/Payment/Authorization/index.php b/src/PayPal/Payment/Authorization/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Authorization/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Capture/Event/index.php b/src/PayPal/Payment/Capture/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Capture/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Capture/EventSubscriber/PayPalCaptureEventSubscriber.php b/src/PayPal/Payment/Capture/EventSubscriber/PayPalCaptureEventSubscriber.php index eefa235de..99ce495cf 100644 --- a/src/PayPal/Payment/Capture/EventSubscriber/PayPalCaptureEventSubscriber.php +++ b/src/PayPal/Payment/Capture/EventSubscriber/PayPalCaptureEventSubscriber.php @@ -47,11 +47,6 @@ class PayPalCaptureEventSubscriber implements EventSubscriberInterface { - /** - * @var Ps_checkout - */ - private $module; - /** * @var CheckOrderAmount */ @@ -84,12 +79,11 @@ public function __construct( CacheInterface $orderPayPalCache, OrderStateMapper $orderStateMapper ) { - $this->module = $module; $this->checkOrderAmount = $checkOrderAmount; - $this->commandBus = $this->module->getService('ps_checkout.bus.command'); $this->capturePayPalCache = $capturePayPalCache; $this->orderPayPalCache = $orderPayPalCache; $this->orderStateMapper = $orderStateMapper; + $this->commandBus = $module->getService('ps_checkout.bus.command'); } /** @@ -213,7 +207,7 @@ public function setPaymentReversedOrderStatus(PayPalCaptureReversedEvent $event) { try { /** @var GetOrderForPaymentReversedQueryResult $order */ - $order = $this->commandBus->handle(new GetOrderForPaymentReversedQuery($event->getPayPalOrderId()->getValue(), $event->getPayPalCaptureId()->getValue())); + $order = $this->commandBus->handle(new GetOrderForPaymentReversedQuery($event->getPayPalOrderId()->getValue())); } catch (OrderNotFoundException $exception) { return; } diff --git a/src/PayPal/Payment/Capture/EventSubscriber/index.php b/src/PayPal/Payment/Capture/EventSubscriber/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Capture/EventSubscriber/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Capture/Exception/index.php b/src/PayPal/Payment/Capture/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Capture/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Capture/ValueObject/index.php b/src/PayPal/Payment/Capture/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Capture/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Capture/index.php b/src/PayPal/Payment/Capture/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Capture/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Refund/Command/index.php b/src/PayPal/Payment/Refund/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Refund/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Refund/CommandHandler/RefundPayPalCaptureCommandHandler.php b/src/PayPal/Payment/Refund/CommandHandler/RefundPayPalCaptureCommandHandler.php index 82a7c9ee6..7705bcf80 100644 --- a/src/PayPal/Payment/Refund/CommandHandler/RefundPayPalCaptureCommandHandler.php +++ b/src/PayPal/Payment/Refund/CommandHandler/RefundPayPalCaptureCommandHandler.php @@ -24,7 +24,7 @@ use PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext; use PrestaShop\Module\PrestashopCheckout\Event\EventDispatcherInterface; use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Command\RefundPayPalCaptureCommand; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Event\PayPalCaptureRefundedEvent; @@ -34,7 +34,7 @@ class RefundPayPalCaptureCommandHandler { /** - * @var CheckoutHttpClient + * @var MaaslandHttpClient */ private $checkoutHttpClient; /** @@ -55,7 +55,7 @@ class RefundPayPalCaptureCommandHandler private $eventDispatcher; public function __construct( - CheckoutHttpClient $checkoutHttpClient, + MaaslandHttpClient $checkoutHttpClient, PayPalConfiguration $payPalConfiguration, PrestaShopConfiguration $prestaShopConfiguration, PrestaShopContext $prestaShopContext, @@ -94,7 +94,7 @@ public function handle(RefundPayPalCaptureCommand $command) ), ]); - $refund = json_decode($response->getBody()->getContents(), true); + $refund = json_decode($response->getBody(), true); $this->eventDispatcher->dispatch( new PayPalCaptureRefundedEvent( $refund['id'], diff --git a/src/PayPal/Payment/Refund/CommandHandler/index.php b/src/PayPal/Payment/Refund/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Refund/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Refund/Event/index.php b/src/PayPal/Payment/Refund/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Refund/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Refund/EventSubscriber/PayPalRefundEventSubscriber.php b/src/PayPal/Payment/Refund/EventSubscriber/PayPalRefundEventSubscriber.php index 19699c7d7..cfe2df3f2 100644 --- a/src/PayPal/Payment/Refund/EventSubscriber/PayPalRefundEventSubscriber.php +++ b/src/PayPal/Payment/Refund/EventSubscriber/PayPalRefundEventSubscriber.php @@ -25,7 +25,6 @@ use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQuery; use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQueryResult; -use PrestaShop\Module\PrestashopCheckout\Order\Service\CheckOrderAmount; use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys; use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper; use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Event\PayPalCaptureRefundedEvent; @@ -42,21 +41,11 @@ class PayPalRefundEventSubscriber implements EventSubscriberInterface */ private $module; - /** - * @var CheckOrderAmount - */ - private $checkOrderAmount; - /** * @var CommandBusInterface */ private $commandBus; - /** - * @var CacheInterface - */ - private $capturePayPalCache; - /** * @var CacheInterface */ @@ -73,16 +62,12 @@ class PayPalRefundEventSubscriber implements EventSubscriberInterface public function __construct( Ps_checkout $module, - CheckOrderAmount $checkOrderAmount, - CacheInterface $capturePayPalCache, CacheInterface $orderPayPalCache, OrderStateMapper $orderStateMapper, PayPalOrderProvider $orderProvider ) { $this->module = $module; - $this->checkOrderAmount = $checkOrderAmount; $this->commandBus = $this->module->getService('ps_checkout.bus.command'); - $this->capturePayPalCache = $capturePayPalCache; $this->orderPayPalCache = $orderPayPalCache; $this->orderStateMapper = $orderStateMapper; $this->orderProvider = $orderProvider; @@ -129,11 +114,22 @@ public function setPaymentRefundedOrderStatus(PayPalCaptureRefundedEvent $event) }); $orderFullyRefunded = (float) $order->getTotalAmount() <= (float) $totalRefunded; + $orderStateRefunded = $this->orderStateMapper->getIdByKey(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_REFUNDED); + $orderStatePartiallyRefunded = $this->orderStateMapper->getIdByKey(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_REFUNDED); + $newOrderState = $orderFullyRefunded ? $orderStateRefunded : $orderStatePartiallyRefunded; + + if ($order->hasBeenPartiallyRefund() && $newOrderState === $orderStatePartiallyRefunded) { + return; + } + + if ($order->getCurrentStateId()->getValue() === $newOrderState) { + return; + } $this->commandBus->handle( new UpdateOrderStatusCommand( $order->getOrderId()->getValue(), - $this->orderStateMapper->getIdByKey($orderFullyRefunded ? OrderStateConfigurationKeys::PS_CHECKOUT_STATE_REFUNDED : OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_REFUNDED) + $newOrderState ) ); } diff --git a/src/PayPal/Payment/Refund/EventSubscriber/index.php b/src/PayPal/Payment/Refund/EventSubscriber/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Refund/EventSubscriber/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Refund/Exception/index.php b/src/PayPal/Payment/Refund/Exception/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Refund/Exception/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/Refund/index.php b/src/PayPal/Payment/Refund/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/Refund/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Payment/index.php b/src/PayPal/Payment/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Payment/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/Command/DeletePaymentTokenCommand.php b/src/PayPal/PaymentToken/Command/DeletePaymentTokenCommand.php new file mode 100644 index 000000000..8ae1ad560 --- /dev/null +++ b/src/PayPal/PaymentToken/Command/DeletePaymentTokenCommand.php @@ -0,0 +1,58 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command; + +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class DeletePaymentTokenCommand +{ + /** @var PaymentTokenId */ + private $paymentTokenId; + /** @var CustomerId */ + private $customerId; + + /** + * @param PaymentTokenId $paymentTokenId + * @param CustomerId $customerId + */ + public function __construct(PaymentTokenId $paymentTokenId, CustomerId $customerId) + { + $this->paymentTokenId = $paymentTokenId; + $this->customerId = $customerId; + } + + /** + * @return PaymentTokenId + */ + public function getPaymentTokenId() + { + return $this->paymentTokenId; + } + + /** + * @return CustomerId + */ + public function getCustomerId() + { + return $this->customerId; + } +} diff --git a/src/PayPal/PaymentToken/Command/SavePaymentTokenCommand.php b/src/PayPal/PaymentToken/Command/SavePaymentTokenCommand.php new file mode 100644 index 000000000..c459f04f3 --- /dev/null +++ b/src/PayPal/PaymentToken/Command/SavePaymentTokenCommand.php @@ -0,0 +1,118 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command; + +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class SavePaymentTokenCommand +{ + /** @var PaymentTokenId */ + private $paymentTokenId; + + /** @var PayPalCustomerId */ + private $paypalCustomerId; + + /** @var string */ + private $paymentSource; + + /** @var array */ + private $paymentTokenData; + /** @var bool */ + private $setFavorite; + /** @var string */ + private $merchantId; + /** @var string */ + private $status; + + /** + * @param PaymentTokenId $paymentTokenId + * @param PayPalCustomerId $paypalCustomerId + * @param string $paymentSource + * @param array $paymentTokenData + */ + public function __construct($paymentTokenId, $paypalCustomerId, $status, $paymentSource, $paymentTokenData, $merchantId, $setFavorite = false) + { + $this->paymentTokenId = $paymentTokenId; + $this->paypalCustomerId = $paypalCustomerId; + $this->paymentSource = $paymentSource; + $this->paymentTokenData = $paymentTokenData; + $this->setFavorite = $setFavorite; + $this->merchantId = $merchantId; + $this->status = $status; + } + + /** + * @return PaymentTokenId + */ + public function getPaymentTokenId() + { + return $this->paymentTokenId; + } + + /** + * @return PayPalCustomerId + */ + public function getPaypalCustomerId() + { + return $this->paypalCustomerId; + } + + /** + * @return string + */ + public function getPaymentSource() + { + return $this->paymentSource; + } + + /** + * @return array + */ + public function getPaymentTokenData() + { + return $this->paymentTokenData; + } + + /** + * @return bool + */ + public function isFavorite() + { + return $this->setFavorite; + } + + /** + * @return string + */ + public function getMerchantId() + { + return $this->merchantId; + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } +} diff --git a/src/PayPal/PaymentToken/Command/index.php b/src/PayPal/PaymentToken/Command/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/Command/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/CommandHandler/DeletePaymentTokenCommandHandler.php b/src/PayPal/PaymentToken/CommandHandler/DeletePaymentTokenCommandHandler.php new file mode 100644 index 000000000..4635b7c35 --- /dev/null +++ b/src/PayPal/PaymentToken/CommandHandler/DeletePaymentTokenCommandHandler.php @@ -0,0 +1,62 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command\DeletePaymentTokenCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\PaymentMethodTokenService; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; + +class DeletePaymentTokenCommandHandler +{ + /** @var PaymentTokenRepository */ + private $paymentTokenRepository; + /** + * @var PaymentMethodTokenService + */ + private $paymentMethodTokenService; + + public function __construct(PaymentMethodTokenService $paymentMethodTokenService, PaymentTokenRepository $paymentTokenRepository) + { + $this->paymentTokenRepository = $paymentTokenRepository; + $this->paymentMethodTokenService = $paymentMethodTokenService; + } + + /** + * @throws Exception + */ + public function handle(DeletePaymentTokenCommand $command) + { + $tokenBelongsToCustomer = false; + $tokens = $this->paymentTokenRepository->findByPrestaShopCustomerId($command->getCustomerId()->getValue()); + + foreach ($tokens as $token) { + $tokenBelongsToCustomer |= $token->getId()->getValue() === $command->getPaymentTokenId()->getValue(); + } + + if ($tokenBelongsToCustomer) { + $this->paymentMethodTokenService->deletePaymentToken($command->getPaymentTokenId()); + $this->paymentTokenRepository->deleteById($command->getPaymentTokenId()); + } else { + throw new Exception('Failed to remove saved payment token'); + } + } +} diff --git a/src/PayPal/PaymentToken/CommandHandler/SavePaymentTokenCommandHandler.php b/src/PayPal/PaymentToken/CommandHandler/SavePaymentTokenCommandHandler.php new file mode 100644 index 000000000..89724dcf4 --- /dev/null +++ b/src/PayPal/PaymentToken/CommandHandler/SavePaymentTokenCommandHandler.php @@ -0,0 +1,58 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\CommandHandler; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command\SavePaymentTokenCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Entity\PaymentToken; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; + +class SavePaymentTokenCommandHandler +{ + /** @var PaymentTokenRepository */ + private $paymentTokenRepository; + + public function __construct(PaymentTokenRepository $paymentTokenRepository) + { + $this->paymentTokenRepository = $paymentTokenRepository; + } + + /** + * @throws Exception + */ + public function handle(SavePaymentTokenCommand $command) + { + $token = new PaymentToken( + $command->getPaymentTokenId()->getValue(), + $command->getPaypalCustomerId()->getValue(), + $command->getPaymentSource(), + $command->getPaymentTokenData(), + $command->getMerchantId(), + $command->getStatus(), + $command->isFavorite() + ); + $this->paymentTokenRepository->save($token); + + if ($command->isFavorite()) { + $this->paymentTokenRepository->setTokenFavorite($command->getPaymentTokenId()); + } + } +} diff --git a/src/PayPal/PaymentToken/CommandHandler/index.php b/src/PayPal/PaymentToken/CommandHandler/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/CommandHandler/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/Entity/PaymentToken.php b/src/PayPal/PaymentToken/Entity/PaymentToken.php new file mode 100644 index 000000000..5abbc5ab3 --- /dev/null +++ b/src/PayPal/PaymentToken/Entity/PaymentToken.php @@ -0,0 +1,217 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Entity; + +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class PaymentToken +{ + const TABLE = 'pscheckout_payment_token'; + + /** + * @var PaymentTokenId + */ + private $id; + /** + * @var PayPalCustomerId + */ + private $payPalCustomerId; + /** + * @var string + */ + private $paymentSource; + /** + * @var array + */ + private $data; + /** + * @var bool + */ + private $isFavorite; + /** + * @var string + */ + private $merchantId; + /** + * @var string + */ + private $status; + + /** + * @param string $id + * @param string $payPalCustomerId + * @param string $paymentSource + * @param array $data + * @param string $merchantId + * @param bool $isFavorite + */ + public function __construct($id, $payPalCustomerId, $paymentSource, $data, $merchantId, $status, $isFavorite = false) + { + $this->id = new PaymentTokenId($id); + $this->payPalCustomerId = new PayPalCustomerId($payPalCustomerId); + $this->paymentSource = $paymentSource; + $this->data = $data; + $this->isFavorite = $isFavorite; + $this->merchantId = $merchantId; + $this->status = $status; + } + + /** + * @return PaymentTokenId + */ + public function getId() + { + return $this->id; + } + + /** + * @param string $id + * + * @return PaymentToken + */ + public function setId($id) + { + $this->id = new PaymentTokenId($id); + + return $this; + } + + /** + * @return PayPalCustomerId + */ + public function getPayPalCustomerId() + { + return $this->payPalCustomerId; + } + + /** + * @param string $payPalCustomerId + * + * @return PaymentToken + */ + public function setPayPalCustomerId($payPalCustomerId) + { + $this->payPalCustomerId = new PayPalCustomerId($payPalCustomerId); + + return $this; + } + + /** + * @return string + */ + public function getPaymentSource() + { + return $this->paymentSource; + } + + /** + * @param string $paymentSource + * + * @return PaymentToken + */ + public function setPaymentSource($paymentSource) + { + $this->paymentSource = $paymentSource; + + return $this; + } + + /** + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * @param array $data + * + * @return PaymentToken + */ + public function setData($data) + { + $this->data = $data; + + return $this; + } + + /** + * @return bool + */ + public function isFavorite() + { + return $this->isFavorite; + } + + /** + * @param bool $isFavorite + * + * @return PaymentToken + */ + public function setIsFavorite($isFavorite) + { + $this->isFavorite = $isFavorite; + + return $this; + } + + /** + * @return string + */ + public function getMerchantId() + { + return $this->merchantId; + } + + /** + * @param string $merchantId + * + * @return PaymentToken + */ + public function setMerchantId($merchantId) + { + $this->merchantId = $merchantId; + + return $this; + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string $status + * + * @return PaymentToken + */ + public function setStatus($status) + { + $this->status = $status; + + return $this; + } +} diff --git a/src/PayPal/PaymentToken/Entity/index.php b/src/PayPal/PaymentToken/Entity/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/Entity/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/Event/PaymentTokenCreatedEvent.php b/src/PayPal/PaymentToken/Event/PaymentTokenCreatedEvent.php new file mode 100644 index 000000000..23e401643 --- /dev/null +++ b/src/PayPal/PaymentToken/Event/PaymentTokenCreatedEvent.php @@ -0,0 +1,43 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event; + +class PaymentTokenCreatedEvent extends PaymentTokenEvent +{ + /** + * @var string + */ + private $merchantId; + + public function __construct($resource, $merchantId) + { + parent::__construct($resource); + $this->merchantId = $merchantId; + } + + /** + * @return string + */ + public function getMerchantId() + { + return $this->merchantId; + } +} diff --git a/_dev/js/front/src/utils/extra/types/app-aware.typedef.doc.js b/src/PayPal/PaymentToken/Event/PaymentTokenDeletedEvent.php similarity index 68% rename from _dev/js/front/src/utils/extra/types/app-aware.typedef.doc.js rename to src/PayPal/PaymentToken/Event/PaymentTokenDeletedEvent.php index b7e7455c9..28ef190ce 100644 --- a/_dev/js/front/src/utils/extra/types/app-aware.typedef.doc.js +++ b/src/PayPal/PaymentToken/Event/PaymentTokenDeletedEvent.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -/** - * This file exists only for documentative purposes - */ +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event; -/** - * @typedef AppAwareClass - * - * @property {ContainerAwareClass} app - */ +class PaymentTokenDeletedEvent extends PaymentTokenEvent +{ +} diff --git a/_dev/js/front/src/utils/polyfills/event-target.js b/src/PayPal/PaymentToken/Event/PaymentTokenDeletionInitiatedEvent.php similarity index 67% rename from _dev/js/front/src/utils/polyfills/event-target.js rename to src/PayPal/PaymentToken/Event/PaymentTokenDeletionInitiatedEvent.php index 569ab094c..efd1aaa9a 100644 --- a/_dev/js/front/src/utils/polyfills/event-target.js +++ b/src/PayPal/PaymentToken/Event/PaymentTokenDeletionInitiatedEvent.php @@ -1,10 +1,11 @@ + + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -import EventTarget from '@ungap/event-target'; -window.EventTarget = EventTarget; +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event; + +class PaymentTokenDeletionInitiatedEvent extends PaymentTokenEvent +{ +} diff --git a/src/Api/Payment/Webhook.php b/src/PayPal/PaymentToken/Event/PaymentTokenEvent.php similarity index 66% rename from src/Api/Payment/Webhook.php rename to src/PayPal/PaymentToken/Event/PaymentTokenEvent.php index 5fd511005..a865176a7 100644 --- a/src/Api/Payment/Webhook.php +++ b/src/PayPal/PaymentToken/Event/PaymentTokenEvent.php @@ -18,26 +18,28 @@ * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -namespace PrestaShop\Module\PrestashopCheckout\Api\Payment; +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event; -use PrestaShop\Module\PrestashopCheckout\Api\Payment\Client\PaymentClient; +use PrestaShop\Module\PrestashopCheckout\Event\Event; -/** - * Handle Webhook requests - */ -class Webhook extends PaymentClient +class PaymentTokenEvent extends Event { + /** @var array */ + private $resource; + /** - * Tells if the webhook came from the PSL - * - * @param array $payload - * - * @return array + * @param array $resource */ - public function getShopSignature(array $payload) + public function __construct($resource) { - $this->setRoute('/payments/shop/verify_webhook_signature'); + $this->resource = $resource; + } - return $this->post($payload); + /** + * @return array + */ + public function getResource() + { + return $this->resource; } } diff --git a/src/PayPal/PaymentToken/Event/index.php b/src/PayPal/PaymentToken/Event/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/Event/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/EventSubscriber/PaymentMethodTokenEventSubscriber.php b/src/PayPal/PaymentToken/EventSubscriber/PaymentMethodTokenEventSubscriber.php new file mode 100644 index 000000000..6c165e039 --- /dev/null +++ b/src/PayPal/PaymentToken/EventSubscriber/PaymentMethodTokenEventSubscriber.php @@ -0,0 +1,108 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\EventSubscriber; + +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Command\SavePaymentTokenCommand; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenCreatedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenDeletedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Event\PaymentTokenDeletionInitiatedEvent; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; +use Ps_checkout; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class PaymentMethodTokenEventSubscriber implements EventSubscriberInterface +{ + /** @var Ps_checkout */ + private $module; + + /** @var CommandBusInterface */ + private $commandBus; + /** + * @var PayPalOrderRepository + */ + private $payPalOrderRepository; + /** + * @var PaymentTokenRepository + */ + private $paymentTokenRepository; + + public function __construct(Ps_checkout $module, PayPalOrderRepository $payPalOrderRepository, PaymentTokenRepository $paymentTokenRepository) + { + $this->module = $module; + $this->commandBus = $this->module->getService('ps_checkout.bus.command'); + $this->payPalOrderRepository = $payPalOrderRepository; + $this->paymentTokenRepository = $paymentTokenRepository; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ + PaymentTokenCreatedEvent::class => [ + ['saveCreatedPaymentMethodToken'], + ], + PaymentTokenDeletedEvent::class => [ + ['deletePaymentMethodToken'], + ], + PaymentTokenDeletionInitiatedEvent::class => [ + [''], // No sĂ© + ], + ]; + } + + public function saveCreatedPaymentMethodToken(PaymentTokenCreatedEvent $event) + { + $resource = $event->getResource(); + $orderId = isset($resource['metadata']['order_id']) ? $resource['metadata']['order_id'] : null; + $setFavorite = false; + + if ($orderId) { + try { + $order = $this->payPalOrderRepository->getPayPalOrderById(new PayPalOrderId($orderId)); + $setFavorite = $order->checkCustomerIntent(PayPalOrder::CUSTOMER_INTENT_FAVORITE); + } catch (\Exception $exception) { + } + } + + $this->commandBus->handle(new SavePaymentTokenCommand( + new PaymentTokenId($resource['id']), + new PayPalCustomerId($resource['customer']['id']), + $resource['payment_source'][array_keys($resource['payment_source'])[0]]['verification_status'], + array_keys($resource['payment_source'])[0], + $resource, + $event->getMerchantId(), + $setFavorite + )); + } + + public function deletePaymentMethodToken(PaymentTokenDeletedEvent $event) + { + $this->paymentTokenRepository->deleteById($event->getResource()['id']); + } +} diff --git a/src/PayPal/PaymentToken/EventSubscriber/index.php b/src/PayPal/PaymentToken/EventSubscriber/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/EventSubscriber/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/PaymentMethodTokenService.php b/src/PayPal/PaymentToken/PaymentMethodTokenService.php new file mode 100644 index 000000000..e52f56d64 --- /dev/null +++ b/src/PayPal/PaymentToken/PaymentMethodTokenService.php @@ -0,0 +1,86 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken; + +use Exception; +use GuzzleHttp\Psr7\Request; +use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; + +class PaymentMethodTokenService +{ + private $httpClient; + /** + * @var CheckoutHttpClient + */ + private $checkoutHttpClient; + /** + * @var PayPalConfiguration + */ + private $payPalConfiguration; + + public function __construct($httpClient, CheckoutHttpClient $checkoutHttpClient, PayPalConfiguration $payPalConfiguration) + { + $this->httpClient = $httpClient; + $this->checkoutHttpClient = $checkoutHttpClient; + $this->payPalConfiguration = $payPalConfiguration; + } + + /** + * @param PayPalCustomerId $customerId + * + * @return array + * + * @throws Exception + */ + public function fetchPaymentMethodTokens(PayPalCustomerId $customerId) + { + try { + $request = new Request('GET', 'https://api.paypal.com/v3/vault/payment-tokens&customer_id=' . $customerId->getValue(), []); + $response = $this->httpClient->sendRequest($request); + + $data = json_decode($response->getBody(), true); + + if (empty($data['payment_tokens'])) { + throw new Exception('Failed to fetch PayPal Payment Method tokens from response.'); + } + + return $data['payment_tokens']; + } catch (Exception $exception) { + throw new Exception('Failed to fetch PayPal Payment Method tokens.', 0, $exception); + } + } + + public function deletePaymentToken(PaymentTokenId $paymentTokenId) + { + try { + $response = $this->checkoutHttpClient->deletePaymentToken($this->payPalConfiguration->getMerchantId(), $paymentTokenId); + + if ($response->getStatusCode() !== 204) { + throw new Exception('Failed to delete payment token', $response->getStatusCode()); + } + } catch (Exception $exception) { + throw new Exception('Failed to delete payment token', 0, $exception); + } + } +} diff --git a/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQuery.php b/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQuery.php new file mode 100644 index 000000000..44a8cdd44 --- /dev/null +++ b/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQuery.php @@ -0,0 +1,92 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query; + +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; + +class GetCustomerPaymentTokensQuery +{ + /** + * @var CustomerId + */ + private $customerId; + + /** + * @var int + */ + private $pageSize; + + /** + * @var int + */ + private $pageNumber; + + /** + * @var bool + */ + private $isTotalCountRequired; + + /** + * @param CustomerId $customerId + * @param int $pageSize + * @param int $pageNumber + * @param bool $isTotalCountRequired + */ + public function __construct(CustomerId $customerId, $pageSize, $pageNumber, $isTotalCountRequired = false) + { + $this->customerId = $customerId; + $this->pageSize = $pageSize; + $this->pageNumber = $pageNumber; + $this->isTotalCountRequired = $isTotalCountRequired; + } + + /** + * @return CustomerId + */ + public function getCustomerId() + { + return $this->customerId; + } + + /** + * @return int + */ + public function getPageSize() + { + return $this->pageSize; + } + + /** + * @return int + */ + public function getPageNumber() + { + return $this->pageNumber; + } + + /** + * @return bool + */ + public function isTotalCountRequired() + { + return $this->isTotalCountRequired; + } +} diff --git a/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQueryHandler.php b/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQueryHandler.php new file mode 100644 index 000000000..4d5077d38 --- /dev/null +++ b/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQueryHandler.php @@ -0,0 +1,68 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository; + +class GetCustomerPaymentTokensQueryHandler +{ + /** + * @var PaymentTokenRepository + */ + private $paymentTokenRepository; + + /** + * @param PaymentTokenRepository $paymentTokenRepository + */ + public function __construct(PaymentTokenRepository $paymentTokenRepository) + { + $this->paymentTokenRepository = $paymentTokenRepository; + } + + /** + * @param GetCustomerPaymentTokensQuery $query + * + * @return GetCustomerPaymentTokensQueryResult + * + * @throws Exception + */ + public function handle(GetCustomerPaymentTokensQuery $query) + { +// $paymentTokens = $this->paymentTokenRepository->findByPrestaShopCustomerId($query->getCustomerId()->getValue(), $query->getPageSize(), $query->getPageNumber()); + $paymentTokens = $this->paymentTokenRepository->findByPrestaShopCustomerId($query->getCustomerId()->getValue()); + + if ($query->isTotalCountRequired()) { + $totalItems = $this->paymentTokenRepository->getCount($query->getCustomerId()->getValue()); + $totalPages = ceil($totalItems / $query->getPageSize()); + } else { + $totalItems = null; + $totalPages = null; + } + + return new GetCustomerPaymentTokensQueryResult( + $paymentTokens, + $query->getCustomerId(), + $totalItems, + (int) $totalPages + ); + } +} diff --git a/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQueryResult.php b/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQueryResult.php new file mode 100644 index 000000000..520c5f4b0 --- /dev/null +++ b/src/PayPal/PaymentToken/Query/GetCustomerPaymentTokensQueryResult.php @@ -0,0 +1,93 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Query; + +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Entity\PaymentToken; + +class GetCustomerPaymentTokensQueryResult +{ + /** + * @var array + */ + private $paymentTokens; + + /** + * @var CustomerId + */ + private $customerId; + + /** + * @var int + */ + private $totalItems; + + /** + * @var int + */ + private $totalPages; + + /** + * @param PaymentToken[] $paymentTokens + * @param CustomerId $customerId + * @param int $totalItems + * @param int $totalPages + */ + public function __construct(array $paymentTokens, CustomerId $customerId, $totalItems, $totalPages) + { + $this->paymentTokens = $paymentTokens; + $this->customerId = $customerId; + $this->totalItems = $totalItems; + $this->totalPages = $totalPages; + } + + /** + * @return PaymentToken[] + */ + public function getPaymentTokens() + { + return $this->paymentTokens; + } + + /** + * @return CustomerId + */ + public function getCustomerId() + { + return $this->customerId; + } + + /** + * @return int + */ + public function getTotalItems() + { + return $this->totalItems; + } + + /** + * @return int + */ + public function getTotalPages() + { + return $this->totalPages; + } +} diff --git a/src/PayPal/PaymentToken/Query/index.php b/src/PayPal/PaymentToken/Query/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/Query/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/ValueObject/PaymentTokenId.php b/src/PayPal/PaymentToken/ValueObject/PaymentTokenId.php new file mode 100644 index 000000000..3e64fc6c3 --- /dev/null +++ b/src/PayPal/PaymentToken/ValueObject/PaymentTokenId.php @@ -0,0 +1,74 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject; + +use InvalidArgumentException; + +class PaymentTokenId +{ + /** + * @var string + */ + private $id; + + /** + * @param string $id + * + * @throws InvalidArgumentException + */ + public function __construct($id) + { + $this->assertIsValid($id); + $this->id = $id; + } + + /** + * @return string + */ + public function getValue() + { + return $this->id; + } + + /** + * @param string $id + * + * @return void + * + * @throws InvalidArgumentException + */ + private function assertIsValid($id) + { + if (!is_string($id)) { + throw new InvalidArgumentException('PayPal Vault ID must be a string.'); + } + + $length = strlen($id); + + if ($length < 1 || $length > 36) { + throw new InvalidArgumentException('PayPal Vault ID must be between 1 and 36 characters long.'); + } + + if (preg_match('/^[0-9a-zA-Z_-]+$/', $id) !== 1) { + throw new InvalidArgumentException('PayPal Vault ID must be alphanumeric.'); + } + } +} diff --git a/src/PayPal/PaymentToken/ValueObject/index.php b/src/PayPal/PaymentToken/ValueObject/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/ValueObject/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/PaymentToken/index.php b/src/PayPal/PaymentToken/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/PaymentToken/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPal/Sdk/PayPalSdkConfigurationBuilder.php b/src/PayPal/Sdk/PayPalSdkConfigurationBuilder.php index 6ab5624b2..703d87c3f 100644 --- a/src/PayPal/Sdk/PayPalSdkConfigurationBuilder.php +++ b/src/PayPal/Sdk/PayPalSdkConfigurationBuilder.php @@ -20,18 +20,32 @@ namespace PrestaShop\Module\PrestashopCheckout\PayPal\Sdk; -use PrestaShop\Module\PrestashopCheckout\Environment\PaypalEnv; +use Exception; +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; +use PrestaShop\Module\PrestashopCheckout\Context\PrestaShopContext; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use PrestaShop\Module\PrestashopCheckout\Environment\Env; use PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration; use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository; +use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceEligibilityConstraint; +use PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQuery; +use PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQueryResult; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration; use PrestaShop\Module\PrestashopCheckout\ShopContext; +use Psr\Log\LoggerInterface; /** * Build sdk link */ class PayPalSdkConfigurationBuilder { + /** + * google_pay and apple_pay are not considered funding sources + * and passing these values to disableFunding with crash PayPal SDK + */ + const NOT_FUNDING_SOURCES = ['google_pay', 'apple_pay']; + /** * @var PayPalConfiguration */ @@ -55,26 +69,61 @@ class PayPalSdkConfigurationBuilder /** @var array */ private static $cache = []; + /** + * @var CommandBusInterface + */ + private $commandBus; + /** + * @var PrestaShopContext + */ + private $prestaShopContext; + /** + * @var LoggerInterface + */ + private $logger; + /** + * @var Env + */ + private $env; + /** + * @var FundingSourceEligibilityConstraint + */ + private $fundingSourceEligibilityConstraint; /** + * @param \Ps_checkout $module + * @param Env $env * @param PayPalConfiguration $configuration * @param PayPalPayLaterConfiguration $payLaterConfiguration * @param FundingSourceConfigurationRepository $fundingSourceConfigurationRepository * @param ExpressCheckoutConfiguration $expressCheckoutConfiguration * @param ShopContext $shopContext + * @param PrestaShopContext $prestaShopContext + * @param LoggerInterface $logger + * @param FundingSourceEligibilityConstraint $fundingSourceEligibilityConstraint */ public function __construct( + \Ps_checkout $module, + Env $env, PayPalConfiguration $configuration, PayPalPayLaterConfiguration $payLaterConfiguration, FundingSourceConfigurationRepository $fundingSourceConfigurationRepository, ExpressCheckoutConfiguration $expressCheckoutConfiguration, - ShopContext $shopContext + ShopContext $shopContext, + PrestaShopContext $prestaShopContext, + LoggerInterface $logger, + FundingSourceEligibilityConstraint $fundingSourceEligibilityConstraint ) { $this->configuration = $configuration; $this->payLaterConfiguration = $payLaterConfiguration; $this->fundingSourceConfigurationRepository = $fundingSourceConfigurationRepository; $this->expressCheckoutConfiguration = $expressCheckoutConfiguration; $this->shopContext = $shopContext; + $this->commandBus = $module->getService('ps_checkout.bus.command'); + $this->prestaShopContext = $prestaShopContext; + $this->logger = $logger; + $this->env = $env; + $this->fundingSourceEligibilityConstraint = $fundingSourceEligibilityConstraint; } /** @@ -99,10 +148,18 @@ public function buildConfiguration() $components[] = 'messages'; } + if ($this->shouldIncludeGooglePayComponent()) { + $components[] = 'googlepay'; + } + + if ($this->shouldIncludeApplePayComponent()) { + $components[] = 'applepay'; + } + $params = [ - 'clientId' => (new PaypalEnv())->getPaypalClientId(), + 'clientId' => $this->env->getPaypalClientId(), 'merchantId' => $this->configuration->getMerchantId(), - 'currency' => \Context::getContext()->currency->iso_code, + 'currency' => $this->prestaShopContext->getCurrencyIsoCode(), 'intent' => strtolower($this->configuration->getIntent()), 'commit' => 'order' === $this->getPageName() ? 'true' : 'false', 'vault' => 'false', @@ -111,6 +168,16 @@ public function buildConfiguration() 'dataCspNonce' => $this->configuration->getCSPNonce(), ]; + if ($this->configuration->isVaultingEnabled() && $this->prestaShopContext->customerIsLogged() && $this->prestaShopContext->getCustomerId() && 'order' === $this->getPageName()) { + try { + /** @var GetPayPalGetUserIdTokenQueryResult $queryResult */ + $queryResult = $this->commandBus->handle(new GetPayPalGetUserIdTokenQuery(new CustomerId($this->prestaShopContext->getCustomerId()))); + $params['dataUserIdToken'] = $queryResult->getUserIdToken(); + } catch (Exception $exception) { + $this->logger->error('Failed to get PayPal User ID token.', ['exception' => $exception]); + } + } + if ($this->configuration->is3dSecureEnabled()) { $params['dataEnable3ds'] = 'true'; } @@ -166,7 +233,7 @@ private function getFundingSourcesDisabled() } foreach ($fundingSources as $fundingSource) { - if (!$fundingSource['active']) { + if (!$fundingSource['active'] && !in_array($fundingSource['name'], self::NOT_FUNDING_SOURCES, true)) { $fundingSourcesDisabled[] = $fundingSource['name']; } } @@ -428,4 +495,29 @@ private function getEligibleAlternativePaymentMethods() return $fundingSourcesEnabled; } + + private function shouldIncludeGooglePayComponent() + { + $context = \Context::getContext(); + $country = $this->getCountry(); + $fundingSource = $this->fundingSourceConfigurationRepository->get('google_pay'); + + return $fundingSource && $fundingSource['active'] + && $this->configuration->isGooglePayEligible() + && in_array($country, $this->fundingSourceEligibilityConstraint->getCountries('google_pay'), true) + && in_array($context->currency->iso_code, $this->fundingSourceEligibilityConstraint->getCurrencies('google_pay'), true); + } + + private function shouldIncludeApplePayComponent() + { + $context = \Context::getContext(); + $country = $this->getCountry(); + $fundingSource = $this->fundingSourceConfigurationRepository->get('apple_pay'); + + return $fundingSource && $fundingSource['active'] + && $this->configuration->isApplePayEligible() + && $this->configuration->isApplePayDomainRegistered() + && in_array($country, $this->fundingSourceEligibilityConstraint->getCountries('apple_pay'), true) + && in_array($context->currency->iso_code, $this->fundingSourceEligibilityConstraint->getCurrencies('apple_pay'), true); + } } diff --git a/src/PayPal/Sdk/index.php b/src/PayPal/Sdk/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/PayPal/Sdk/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/PayPalError.php b/src/PayPalError.php index 643346fa2..b49341e95 100644 --- a/src/PayPalError.php +++ b/src/PayPalError.php @@ -346,6 +346,28 @@ public function throwException(HttpException $previous = null) throw new PayPalException('We can\'t process any refund at this moment due to technical reasons. Please try again later.', PayPalException::CANNOT_PROCESS_REFUNDS, $previous); case 'INVALID_REFUND_AMOUNT': throw new PayPalException('The refund amount is invalid. Please check the refund amount and try again.', PayPalException::INVALID_REFUND_AMOUNT, $previous); + case 'NOT_ENABLED_TO_VAULT_PAYMENT_SOURCE': + throw new PayPalException('The API caller or the merchant on whose behalf the API call is initiated is not allowed to vault the given source. Please contact PayPal customer support for assistance.', PayPalException::NOT_ENABLED_TO_VAULT_PAYMENT_SOURCE, $previous); + case 'SETUP_TOKEN_ALREADY_TOKENIZED': + throw new PayPalException('The setup token has been used previously to generate a payment token.', PayPalException::SETUP_TOKEN_ALREADY_TOKENIZED, $previous); + case 'TOKEN_NOT_FOUND': + throw new PayPalException('The specified token id does not exist.', PayPalException::TOKEN_NOT_FOUND, $previous); + case 'PAYPAL_REQUEST_ID_PREVIOUSLY_USED': + throw new PayPalException('The PayPal-Request-ID has already been used for another request.', PayPalException::PAYPAL_REQUEST_ID_PREVIOUSLY_USED, $previous); + case 'OPERATION_NOT_SUPPORTED': + throw new PayPalException('Specified operation not supported on any fields.', PayPalException::OPERATION_NOT_SUPPORTED, $previous); + case 'INVALID_SECURITY_CODE': + throw new PayPalException('The security code provided does not conform to the card number provided.', PayPalException::INVALID_SECURITY_CODE, $previous); + case 'INVALID_INTEGER_MIN_VALUE': + throw new PayPalException('The integer value of a field is too small.', PayPalException::INVALID_INTEGER_MIN_VALUE, $previous); + case 'INVALID_EXPIRY_DATE': + throw new PayPalException('Expiry date is invalid. Expiry date should be a date in future and within the threshold for the payment source.', PayPalException::INVALID_EXPIRY_DATE, $previous); + case 'EXACTLY_ONE_FIELD_REQUIRED': + throw new PayPalException('Exactly one payment source is required.', PayPalException::EXACTLY_ONE_FIELD_REQUIRED, $previous); + case 'CREDIT_CARD_NUMBER_IS_INVALID': + throw new PayPalException('Credit card number is invalid.', PayPalException::CREDIT_CARD_NUMBER_IS_INVALID, $previous); + case 'CARD_EXPIRATION_YEAR_IS_INVALID': + throw new PayPalException('Expiration year outside of acceptable range.', PayPalException::CARD_EXPIRATION_YEAR_IS_INVALID, $previous); default: throw new PayPalException($this->message, PayPalException::UNKNOWN, $previous); } diff --git a/src/PaypalOrder.php b/src/PaypalOrder.php index 4cc0e6462..a2f502dc5 100644 --- a/src/PaypalOrder.php +++ b/src/PaypalOrder.php @@ -20,10 +20,15 @@ namespace PrestaShop\Module\PrestashopCheckout; +use Exception; use Module; use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; use PrestaShop\Module\PrestashopCheckout\Handler\Response\ResponseApiHandler; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder as PayPalOrderEntity; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; +use PrestaShop\Module\PrestashopCheckout\Repository\PayPalOrderRepository; use Ps_checkout; /** @@ -54,13 +59,35 @@ private function loadOrder($id) /** @var Ps_checkout $module */ $module = Module::getInstanceByName('ps_checkout'); - /** @var CheckoutHttpClient $checkoutHttpClient */ - $checkoutHttpClient = $module->getService('ps_checkout.http.client.checkout'); + /** @var MaaslandHttpClient $maaslandHttpClient */ + $maaslandHttpClient = $module->getService(MaaslandHttpClient::class); + + /** @var PayPalOrderRepository $payPalOrderRepository */ + $payPalOrderRepository = $module->getService(PayPalOrderRepository::class); + + /** @var PayPalConfiguration $payPalConfiguration */ + $payPalConfiguration = $module->getService(PayPalConfiguration::class); + + try { + $order = $payPalOrderRepository->getPayPalOrderById(new PayPalOrderId($id)); + } catch (Exception $exception) { + $order = null; + } try { - $response = $checkoutHttpClient->fetchOrder([ + $payload = [ 'orderId' => $id, - ]); + ]; + + if ($order && $order->checkCustomerIntent(PayPalOrderEntity::CUSTOMER_INTENT_USES_VAULTING)) { + $payload = array_merge($payload, [ + 'vault' => true, + 'payee' => [ + 'merchant_id' => $payPalConfiguration->getMerchantId(), + ], + ]); + } + $response = $maaslandHttpClient->fetchOrder($payload); $responseHandler = new ResponseApiHandler(); $response = $responseHandler->handleResponse($response); @@ -76,6 +103,13 @@ private function loadOrder($id) ], 'paypal_order = "' . pSQL($id) . '"' ); + \Db::getInstance()->update( + \PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder::TABLE, + [ + 'status' => \PsCheckoutCart::STATUS_CANCELED, + ], + 'id = "' . pSQL($id) . '"' + ); } } } diff --git a/src/Presenter/Cart/CartPresenter.php b/src/Presenter/Cart/CartPresenter.php index 818991d90..74f1cf3b0 100644 --- a/src/Presenter/Cart/CartPresenter.php +++ b/src/Presenter/Cart/CartPresenter.php @@ -38,29 +38,25 @@ public function present() { $context = \Context::getContext(); $productList = $context->cart->getProducts(); - - $cart = (array) $context->cart; - - if (class_exists('\PrestaShop\PrestaShop\Adapter\Cart\CartPresenter')) { - $cart = new \PrestaShop\PrestaShop\Adapter\Cart\CartPresenter(); - $cart = $cart->present($context->cart); - } - - if (false === isset($cart['totals']['total_including_tax']['amount'])) { - // Handle native CartPresenter before 1.7.2 - $cart['totals']['total_including_tax']['amount'] = $context->cart->getOrderTotal(true); - } - - $shippingAddress = \Address::initialize((int) $cart['id_address_delivery']); - $invoiceAddress = \Address::initialize((int) $cart['id_address_invoice']); + $shippingAddress = \Address::initialize((int) $context->cart->id_address_delivery); + $invoiceAddress = \Address::initialize((int) $context->cart->id_address_invoice); $currency = \Currency::getCurrencyInstance((int) $context->cart->id_currency); return [ - 'cart' => array_merge( - $cart, - ['id' => $context->cart->id], - ['shipping_cost' => $context->cart->getTotalShippingCost(null, true)] - ), + 'cart' => [ + 'id' => $context->cart->id, + 'shipping_cost' => $context->cart->getTotalShippingCost(null, true), + 'totals' => [ + 'total_including_tax' => [ + 'amount' => $context->cart->getOrderTotal(true), + ], + ], + 'subtotals' => [ + 'gift_wrapping' => [ + 'amount' => $context->cart->getGiftWrappingPrice(true), + ], + ], + ], 'customer' => \Validate::isLoadedObject($context->customer) ? $context->customer : new \Customer((int) $context->cart->id_customer), 'language' => $context->language, 'products' => $productList, diff --git a/src/Presenter/Date/index.php b/src/Presenter/Date/index.php new file mode 100755 index 000000000..296d682e8 --- /dev/null +++ b/src/Presenter/Date/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Presenter/Order/OrderPresenter.php b/src/Presenter/Order/OrderPresenter.php index 8592e634d..9e1a9a076 100644 --- a/src/Presenter/Order/OrderPresenter.php +++ b/src/Presenter/Order/OrderPresenter.php @@ -23,6 +23,7 @@ use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider; use PrestaShop\Module\PrestashopCheckout\PayPal\Card3DSecure; use PrestaShop\Module\PrestashopCheckout\Presenter\Date\DatePresenter; +use PrestaShop\Module\PrestashopCheckout\Provider\PaymentMethodLogoProvider; use Ps_checkout; use PsCheckoutCart; @@ -51,7 +52,7 @@ public function __construct(Ps_checkout $module, array $orderPayPal) $this->module = $module; $this->orderPayPal = $orderPayPal; /** @var FundingSourceTranslationProvider $fundingSourceTranslationProvider */ - $fundingSourceTranslationProvider = $this->module->getService('ps_checkout.funding_source.translation'); + $fundingSourceTranslationProvider = $this->module->getService(FundingSourceTranslationProvider::class); $this->fundingSourceTranslationProvider = $fundingSourceTranslationProvider; } @@ -381,32 +382,7 @@ private function getPaymentSourceName(array $orderPayPal) private function getPaymentSourceLogo(array $orderPayPal) { if (isset($orderPayPal['payment_source'])) { - $paymentSourceName = key($orderPayPal['payment_source']); - - if ($paymentSourceName === 'card' && isset($orderPayPal['payment_source']['card']['brand'])) { - switch ($orderPayPal['payment_source']['card']['brand']) { - case 'CB_NATIONALE': - return $this->module->getPathUri() . 'views/img/cb.svg'; - case 'VISA': - return $this->module->getPathUri() . 'views/img/visa.svg'; - case 'MASTERCARD': - return $this->module->getPathUri() . 'views/img/mastercard.svg'; - case 'AMEX': - return $this->module->getPathUri() . 'views/img/amex.svg'; - case 'DISCOVER': - return $this->module->getPathUri() . 'views/img/discover.svg'; - case 'JCB': - return $this->module->getPathUri() . 'views/img/jcb.svg'; - case 'DINERS': - return $this->module->getPathUri() . 'views/img/diners.svg'; - case 'UNIONPAY': - return $this->module->getPathUri() . 'views/img/unionpay.svg'; - case 'MAESTRO': - return $this->module->getPathUri() . 'views/img/maestro.svg'; - } - } - - return $this->module->getPathUri() . 'views/img/' . $paymentSourceName . '.svg'; + return (new PaymentMethodLogoProvider($this->module))->getLogoByPaymentSource($orderPayPal['payment_source']); } return ''; diff --git a/src/Provider/PaymentMethodLogoProvider.php b/src/Provider/PaymentMethodLogoProvider.php new file mode 100644 index 000000000..2c1879dd7 --- /dev/null +++ b/src/Provider/PaymentMethodLogoProvider.php @@ -0,0 +1,71 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Provider; + +use Ps_checkout; + +class PaymentMethodLogoProvider +{ + /** + * @var Ps_checkout + */ + private $module; + + public function __construct(Ps_checkout $module) + { + $this->module = $module; + } + + /** + * @param array $paymentSource + * + * @return string + */ + public function getLogoByPaymentSource($paymentSource) + { + $paymentSourceName = key($paymentSource); + + if ($paymentSourceName === 'card' && isset($paymentSource['card']['brand'])) { + switch ($paymentSource['card']['brand']) { + case 'CB_NATIONALE': + return $this->module->getPathUri() . 'views/img/cb.svg'; + case 'VISA': + return $this->module->getPathUri() . 'views/img/visa.svg'; + case 'MASTERCARD': + return $this->module->getPathUri() . 'views/img/mastercard.svg'; + case 'AMEX': + return $this->module->getPathUri() . 'views/img/amex.svg'; + case 'DISCOVER': + return $this->module->getPathUri() . 'views/img/discover.svg'; + case 'JCB': + return $this->module->getPathUri() . 'views/img/jcb.svg'; + case 'DINERS': + return $this->module->getPathUri() . 'views/img/diners.svg'; + case 'UNIONPAY': + return $this->module->getPathUri() . 'views/img/unionpay.svg'; + case 'MAESTRO': + return $this->module->getPathUri() . 'views/img/maestro.svg'; + } + } + + return $this->module->getPathUri() . 'views/img/' . $paymentSourceName . '.svg'; + } +} diff --git a/src/Provider/index.php b/src/Provider/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Provider/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Repository/PayPalCustomerRepository.php b/src/Repository/PayPalCustomerRepository.php new file mode 100644 index 000000000..02eb75d8e --- /dev/null +++ b/src/Repository/PayPalCustomerRepository.php @@ -0,0 +1,89 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Repository; + +use Db; +use DbQuery; +use Exception; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; + +class PayPalCustomerRepository +{ + /** + * @var Db + */ + private $db; + + /** + * @param Db $db + */ + public function __construct(Db $db) + { + $this->db = $db; + } + + /** + * @param CustomerId $customerId + * + * @return PayPalCustomerId|null + * + * @throws PsCheckoutException + */ + public function findPayPalCustomerIdByCustomerId(CustomerId $customerId) + { + try { + $query = new DbQuery(); + $query->select('`paypal_customer_id`'); + $query->from('pscheckout_customer'); + $query->where(sprintf('`id_customer` = %d', (int) $customerId->getValue())); + $customerIdPayPal = $this->db->getValue($query); + + return $customerIdPayPal ? new PayPalCustomerId($customerIdPayPal) : null; + } catch (Exception $exception) { + throw new PsCheckoutException('Failed to find PayPal Customer ID', 0, $exception); + } + } + + /** + * @param CustomerId $customerId + * @param PayPalCustomerId $paypalCustomerId + * + * @return void + * + * @throws PsCheckoutException + */ + public function save(CustomerId $customerId, PayPalCustomerId $paypalCustomerId) + { + try { + $this->db->insert( + 'pscheckout_customer', + [ + 'id_customer' => (int) $customerId->getValue(), + 'paypal_customer_id' => pSQL($paypalCustomerId->getValue()), + ] + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Failed to save PayPal Customer ID', 0, $exception); + } + } +} diff --git a/src/Repository/PayPalOrderRepository.php b/src/Repository/PayPalOrderRepository.php new file mode 100644 index 000000000..405d43e64 --- /dev/null +++ b/src/Repository/PayPalOrderRepository.php @@ -0,0 +1,436 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Repository; + +use Db; +use DbQuery; +use Exception; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderAuthorization; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderCapture; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderPurchaseUnit; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrderRefund; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class PayPalOrderRepository +{ + /** + * @var Db + */ + private $db; + + public function __construct(Db $db) + { + $this->db = $db; + } + + /** + * @param PayPalOrder $payPalOrder + * + * @return bool + * + * @throws PsCheckoutException + */ + public function savePayPalOrder(PayPalOrder $payPalOrder) + { + try { + return $this->db->insert( + PayPalOrder::TABLE, + [ + 'id' => pSQL($payPalOrder->getId()->getValue()), + 'id_cart' => (int) $payPalOrder->getIdCart(), + 'status' => pSQL($payPalOrder->getStatus()), + 'intent' => pSQL($payPalOrder->getIntent()), + 'funding_source' => pSQL($payPalOrder->getFundingSource()), + 'payment_source' => pSQL(json_encode($payPalOrder->getPaymentSource())), + 'environment' => pSQL($payPalOrder->getEnvironment()), + 'is_card_fields' => (int) $payPalOrder->isCardFields(), + 'is_express_checkout' => (int) $payPalOrder->isExpressCheckout(), + 'customer_intent' => pSQL(implode(',', $payPalOrder->getCustomerIntent())), + 'payment_token_id' => $payPalOrder->getPaymentTokenId() ? pSQL($payPalOrder->getPaymentTokenId()->getValue()) : null, + ], + false, + true, + Db::REPLACE + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while saving PayPal Order', 0, $exception); + } + } + + /** + * @param PayPalOrderId $payPalOrderId + * + * @return PayPalOrder + * + * @throws PsCheckoutException + */ + public function getPayPalOrderById(PayPalOrderId $payPalOrderId) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PayPalOrder::TABLE, 'o'); + $query->where(sprintf('o.`id` = "%s"', pSQL($payPalOrderId->getValue()))); + $queryResult = $this->db->getRow($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while retrieve PayPal Order', 0, $exception); + } + + if (empty($queryResult)) { + throw new PsCheckoutException('PayPal Order not found'); + } + + return new PayPalOrder( + $queryResult['id'], + (int) $queryResult['id_cart'], + $queryResult['intent'], + $queryResult['funding_source'], + $queryResult['status'], + json_decode($queryResult['payment_source'], true), + $queryResult['environment'], + $queryResult['is_card_fields'], + $queryResult['is_express_checkout'], + explode(',', $queryResult['customer_intent']), + $queryResult['payment_token_id'] ? new PaymentTokenId($queryResult['payment_token_id']) : null + ); + } + + /** + * @param int $cartId + * + * @return PayPalOrder + * + * @throws PsCheckoutException + */ + public function getPayPalOrderByCartId($cartId) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PayPalOrder::TABLE, 'o'); + $query->where(sprintf('o.`id_cart` = %d', (int) $cartId)); + $queryResult = $this->db->getRow($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while retrieve PayPal Order', 0, $exception); + } + + if (empty($queryResult)) { + throw new PsCheckoutException('PayPal Order not found'); + } + + return new PayPalOrder( + $queryResult['id'], + (int) $queryResult['id_cart'], + $queryResult['intent'], + $queryResult['funding_source'], + $queryResult['status'], + json_decode($queryResult['payment_source'], true), + $queryResult['environment'], + $queryResult['is_card_fields'], + $queryResult['is_express_checkout'], + explode(',', $queryResult['customer_intent']), + $queryResult['payment_token_id'] ? new PaymentTokenId($queryResult['payment_token_id']) : null + ); + } + + /** + * @param PayPalOrderId $payPalOrderId + * + * @return bool + * + * @throws PsCheckoutException + */ + public function deletePayPalOrder(PayPalOrderId $payPalOrderId) + { + try { + $this->db->delete(PayPalOrder::TABLE, sprintf('`id` = "%s"', pSQL($payPalOrderId->getValue()))); + $this->db->delete(PayPalOrderAuthorization::TABLE, sprintf('`id_order` = "%s"', pSQL($payPalOrderId->getValue()))); + $this->db->delete(PayPalOrderRefund::TABLE, sprintf('`id_order` = "%s"', pSQL($payPalOrderId->getValue()))); + $this->db->delete(PayPalOrderCapture::TABLE, sprintf('`id_order` = "%s"', pSQL($payPalOrderId->getValue()))); + $this->db->delete(PayPalOrderPurchaseUnit::TABLE, sprintf('`id_order` = "%s"', pSQL($payPalOrderId->getValue()))); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while deleting PayPal Order', 0, $exception); + } + + return true; + } + + /** + * @param PayPalOrderAuthorization $payPalOrderAuthorization + * + * @return bool + * + * @throws PsCheckoutException + */ + public function savePayPalOrderAuthorization(PayPalOrderAuthorization $payPalOrderAuthorization) + { + try { + return $this->db->insert( + PayPalOrderAuthorization::TABLE, + [ + 'id' => pSQL($payPalOrderAuthorization->getId()), + 'id_order' => pSQL($payPalOrderAuthorization->getIdOrder()), + 'status' => pSQL($payPalOrderAuthorization->getStatus()), + 'expiration_time' => pSQL($payPalOrderAuthorization->getExpirationTime()), + 'seller_protection' => pSQL(json_encode($payPalOrderAuthorization->getSellerProtection())), + ], + false, + true, + Db::REPLACE + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while saving PayPal Order Authorization', 0, $exception); + } + } + + /** + * @param string $payPalOrderId + * + * @return PayPalOrderAuthorization[] + * + * @throws PsCheckoutException + */ + public function getPayPalOrderAuthorizations($payPalOrderId) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PayPalOrderAuthorization::TABLE, 'a'); + $query->where(sprintf('a.`id_order` = "%s"', pSQL($payPalOrderId))); + $queryResult = $this->db->executeS($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while retrieve PayPal Order Authorization', 0, $exception); + } + + if (empty($queryResult)) { + throw new PsCheckoutException('PayPal Order not found'); + } + + return array_map(function ($authorization) { + return new PayPalOrderAuthorization( + $authorization['id'], + $authorization['id_order'], + $authorization['status'], + $authorization['expiration_time'], + json_decode($authorization['seller_protection'], true) + ); + }, $queryResult); + } + + /** + * @param PayPalOrderCapture $payPalOrderCapture + * + * @return bool + * + * @throws PsCheckoutException + */ + public function savePayPalOrderCapture(PayPalOrderCapture $payPalOrderCapture) + { + try { + return $this->db->insert( + PayPalOrderCapture::TABLE, + [ + 'id' => pSQL($payPalOrderCapture->getId()), + 'id_order' => pSQL($payPalOrderCapture->getIdOrder()), + 'status' => pSQL($payPalOrderCapture->getStatus()), + 'final_capture' => (int) $payPalOrderCapture->getFinalCapture(), + 'created_at' => pSQL($payPalOrderCapture->getCreatedAt()), + 'updated_at' => pSQL($payPalOrderCapture->getUpdatedAt()), + 'seller_protection' => pSQL(json_encode($payPalOrderCapture->getSellerProtection())), + 'seller_receivable_breakdown' => pSQL(json_encode($payPalOrderCapture->getSellerReceivableBreakdown())), + ], + false, + true, + Db::REPLACE + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while saving PayPal Order Capture', 0, $exception); + } + } + + /** + * @param string $payPalOrderId + * + * @return PayPalOrderCapture[] + * + * @throws PsCheckoutException + */ + public function getPayPalOrderCaptures($payPalOrderId) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PayPalOrderCapture::TABLE, 'c'); + $query->where(sprintf('c.`id_order` = "%s"', pSQL($payPalOrderId))); + $queryResult = $this->db->executeS($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while retrieve PayPal Order Capture', 0, $exception); + } + + if (empty($queryResult)) { + throw new PsCheckoutException('PayPal Order not found'); + } + + return array_map(function ($capture) { + return new PayPalOrderCapture( + $capture['id'], + $capture['id_order'], + $capture['status'], + $capture['final_capture'], + $capture['created_at'], + $capture['updated_at'], + json_decode($capture['seller_protection'], true), + json_decode($capture['seller_receivable_breakdown'], true) + ); + }, $queryResult); + } + + /** + * @param PayPalOrderRefund $payPalOrderRefund + * + * @return bool + * + * @throws PsCheckoutException + */ + public function savePayPalOrderRefund(PayPalOrderRefund $payPalOrderRefund) + { + try { + return $this->db->insert( + PayPalOrderRefund::TABLE, + [ + 'id' => pSQL($payPalOrderRefund->getId()), + 'id_order' => pSQL($payPalOrderRefund->getIdOrder()), + 'status' => pSQL($payPalOrderRefund->getStatus()), + 'invoice_id' => pSQL($payPalOrderRefund->getStatus()), + 'custom_id' => pSQL($payPalOrderRefund->getCustomId()), + 'acquirer_reference_number' => pSQL($payPalOrderRefund->getAcquirerReferenceNumber()), + 'seller_payable_breakdown' => pSQL(json_encode($payPalOrderRefund->getSellerPayableBreakdown())), + 'id_order_slip' => (int) $payPalOrderRefund->getIdOrderSlip(), + ], + false, + true, + Db::REPLACE + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while saving PayPal Order Refund', 0, $exception); + } + } + + /** + * @param string $payPalOrderId + * + * @return PayPalOrderRefund[] + * + * @throws PsCheckoutException + */ + public function getPayPalOrderRefunds($payPalOrderId) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PayPalOrderRefund::TABLE, 'r'); + $query->where(sprintf('r.`id_order` = "%s"', pSQL($payPalOrderId))); + $queryResult = $this->db->executeS($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while retrieve PayPal Order Refund', 0, $exception); + } + + if (empty($queryResult)) { + throw new PsCheckoutException('PayPal Order not found'); + } + + return array_map(function ($refund) { + return new PayPalOrderRefund( + $refund['id'], + $refund['id_order'], + $refund['status'], + $refund['invoice_id'], + $refund['custom_id'], + $refund['acquirer_reference_number'], + json_decode($refund['seller_payable_breakdown'], true), + $refund['id_order_slip'] + ); + }, $queryResult); + } + + /** + * @param PayPalOrderPurchaseUnit $payPalOrderPurchaseUnit + * + * @return bool + * + * @throws PsCheckoutException + */ + public function savePayPalOrderPurchaseUnit(PayPalOrderPurchaseUnit $payPalOrderPurchaseUnit) + { + try { + return $this->db->insert( + PayPalOrderPurchaseUnit::TABLE, + [ + 'id_order' => pSQL($payPalOrderPurchaseUnit->getIdOrder()), + 'checksum' => pSQL($payPalOrderPurchaseUnit->getChecksum()), + 'reference_id' => pSQL($payPalOrderPurchaseUnit->getReferenceId()), + 'items' => pSQL(json_encode($payPalOrderPurchaseUnit->getItems())), + ], + false, + true, + Db::REPLACE + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while saving PayPal Order Purchase Unit', 0, $exception); + } + } + + /** + * @param string $payPalOrderId + * + * @return PayPalOrderPurchaseUnit[] + * + * @throws PsCheckoutException + */ + public function getPayPalOrderPurchaseUnits($payPalOrderId) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PayPalOrderPurchaseUnit::TABLE, 'p'); + $query->where(sprintf('p.`id_order` = "%s"', pSQL($payPalOrderId))); + $queryResult = $this->db->executeS($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while retrieve PayPal Order Purchase Unit', 0, $exception); + } + + if (empty($queryResult)) { + throw new PsCheckoutException('PayPal Order not found'); + } + + return array_map(function ($purchaseUnit) { + return new PayPalOrderPurchaseUnit( + $purchaseUnit['id_order'], + $purchaseUnit['checksum'], + $purchaseUnit['reference_id'], + json_decode($purchaseUnit['items'], true) + ); + }, $queryResult); + } +} diff --git a/src/Repository/PaymentTokenRepository.php b/src/Repository/PaymentTokenRepository.php new file mode 100644 index 000000000..8aee6367e --- /dev/null +++ b/src/Repository/PaymentTokenRepository.php @@ -0,0 +1,258 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Repository; + +use Db; +use DbQuery; +use Exception; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\Entity\PaymentToken; +use PrestaShop\Module\PrestashopCheckout\PayPal\PaymentToken\ValueObject\PaymentTokenId; + +class PaymentTokenRepository +{ + /** + * @var Db + */ + private $db; + + public function __construct(Db $db) + { + $this->db = $db; + } + + /** + * @param PaymentToken $paymentToken + * + * @return bool + * + * @throws PsCheckoutException + */ + public function save(PaymentToken $paymentToken) + { + try { + return $this->db->insert( + PaymentToken::TABLE, + [ + 'token_id' => pSQL($paymentToken->getId()->getValue()), + 'paypal_customer_id' => pSQL($paymentToken->getPayPalCustomerId()->getValue()), + 'payment_source' => pSQL($paymentToken->getPaymentSource()), + 'data' => pSQL(json_encode($paymentToken->getData())), + 'merchant_id' => pSQL($paymentToken->getMerchantId()), + 'status' => pSQL($paymentToken->getStatus()), + 'is_favorite' => (int) $paymentToken->isFavorite(), + ], + false, + true, + Db::REPLACE + ); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while saving PayPal Payment Token', 0, $exception); + } + } + + /** + * @param PaymentTokenId $paymentTokenId + * + * @return bool + * + * @throws PsCheckoutException + */ + public function deleteById(PaymentTokenId $paymentTokenId) + { + try { + return $this->db->delete(PaymentToken::TABLE, sprintf('`token_id` = "%s"', pSQL($paymentTokenId->getValue()))); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while deleting PayPal Payment Token', 0, $exception); + } + } + + /** + * @param int $psCustomerId + * + * @return PaymentToken[] + * + * @throws PsCheckoutException + */ + public function findByPrestaShopCustomerId($psCustomerId, $onlyVaulted = false, $merchantId = null) + { + try { + $query = new DbQuery(); + $query->select('t.*'); + $query->from(PaymentToken::TABLE, 't'); + $query->leftJoin('pscheckout_customer', 'c', 't.`paypal_customer_id` = c.`paypal_customer_id`'); + $query->where(sprintf('c.`id_customer` = %d', (int) $psCustomerId)); +// $query->orderBy('t.`is_favorite` DESC'); + $query->orderBy('t.`id` ASC'); + + if ($merchantId) { + $query->where(sprintf('t.`merchant_id` = "%s"', pSQL($merchantId))); + } + + if ($onlyVaulted) { + $query->where('t.`status` = "VAULTED"'); + } + + $queryResult = $this->db->executeS($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while fetching PayPal Payment Tokens', 0, $exception); + } + + if (empty($queryResult)) { + return []; + } + + return array_map(function ($paymentToken) { + return $this->buildPaymentTokenObject($paymentToken); + }, $queryResult); + } + + /** + * @param PayPalCustomerId $customerId + * + * @return PaymentToken[] + * + * @throws PsCheckoutException + */ + public function findByPayPalCustomerId(PayPalCustomerId $customerId) + { + try { + $query = new DbQuery(); + $query->select('t.*'); + $query->from(PaymentToken::TABLE, 't'); + $query->where(sprintf('t.`paypal_customer_id` = "%s"', pSQL($customerId->getValue()))); + $query->orderBy('t.`is_favorite` DESC'); + $query->orderBy('t.`id` ASC'); + $queryResult = $this->db->executeS($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while fetching PayPal Payment Tokens', 0, $exception); + } + + if (empty($queryResult)) { + return []; + } + + return array_map(function ($paymentToken) { + return $this->buildPaymentTokenObject($paymentToken); + }, $queryResult); + } + + /** + * @param PaymentTokenId $id + * + * @return PaymentToken|false + * + * @throws PsCheckoutException + */ + public function findById(PaymentTokenId $id) + { + try { + $query = new DbQuery(); + $query->select('*'); + $query->from(PaymentToken::TABLE); + $query->where(sprintf('`token_id` = "%s"', pSQL($id->getValue()))); + $result = $this->db->getRow($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while fetching PayPal Payment Token', 0, $exception); + } + + if ($result && is_array($result)) { + return $this->buildPaymentTokenObject($result); + } + + return false; + } + + /** + * @param PaymentTokenId $paymentTokenId + * + * @return bool + * + * @throws PsCheckoutException + */ + public function setTokenFavorite(PaymentTokenId $paymentTokenId) + { + $token = $this->findById($paymentTokenId); + + if ($token) { + $customerId = $token->getPayPalCustomerId()->getValue(); + + try { + $this->db->update(PaymentToken::TABLE, ['is_favorite' => 0], sprintf('`paypal_customer_id` = "%s"', pSQL($customerId))); + $this->db->update(PaymentToken::TABLE, ['is_favorite' => 1], sprintf('`token_id` = "%s"', pSQL($paymentTokenId->getValue()))); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while setting PayPal Payment Token as favorite', 0, $exception); + } + + return true; + } + + return false; + } + + /** + * @param int|null $customerId + * + * @return int + * + * @throws PsCheckoutException + */ + public function getCount($customerId = null, $merchantId = null) + { + try { + $query = new DbQuery(); + $query->select('COUNT(t.id)'); + $query->from(PaymentToken::TABLE, 't'); + + if ($merchantId) { + $query->where(sprintf('t.`merchant_id` = "%s"', pSQL($merchantId))); + } + + if ($customerId) { + $query->leftJoin('pscheckout_customer', 'c', 't.`paypal_customer_id` = c.`paypal_customer_id`'); + $query->where(sprintf('c.`id_customer` = %d', (int) $customerId)); + } + + return (int) $this->db->getValue($query); + } catch (Exception $exception) { + throw new PsCheckoutException('Error while counting PayPal Payment Tokens', 0, $exception); + } + } + + /** + * @param array $data + * + * @return PaymentToken + */ + private function buildPaymentTokenObject(array $data) + { + return new PaymentToken( + $data['token_id'], + $data['paypal_customer_id'], + $data['payment_source'], + json_decode($data['data'], true), + $data['merchant_id'], + $data['status'], + (bool) $data['is_favorite'] + ); + } +} diff --git a/src/Routing/Router.php b/src/Routing/Router.php index 55ced542c..e466284a1 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -44,6 +44,14 @@ public function getCheckoutValidateLink() return $this->context->link->getModuleLink('ps_checkout', 'validate', [], true, $this->context->language->id, $this->context->shop->id); } + /** + * @return string + */ + public function getCheckoutCancelLink() + { + return $this->context->link->getModuleLink('ps_checkout', 'cancel', [], true, $this->context->language->id, $this->context->shop->id); + } + /** * @param int|null $orderId * diff --git a/src/Routing/index.php b/src/Routing/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Routing/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Settings/index.php b/src/Settings/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Settings/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Shop/index.php b/src/Shop/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Shop/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/ShopContext.php b/src/ShopContext.php index 8e340ea9e..a538d30bc 100644 --- a/src/ShopContext.php +++ b/src/ShopContext.php @@ -20,11 +20,23 @@ namespace PrestaShop\Module\PrestashopCheckout; +use PrestaShop\Module\PrestashopCheckout\Environment\Env; + /** * Get the shop context */ class ShopContext { + /** + * @var Env + */ + private $env; + + public function __construct(Env $env) + { + $this->env = $env; + } + /** * Check if the module is installed on ready or download * @@ -43,13 +55,11 @@ public function isReady() */ public function getBnCode() { - $bnCode = 'PrestaShop_Cart_PSXO_PSDownload'; - if ($this->isReady()) { // if on ready send an empty bn-code - $bnCode = ''; + return ''; } - return $bnCode; + return $this->env->getBnCode(); } public function isShop17() diff --git a/src/Translations/Translations.php b/src/Translations/Translations.php index 087708e97..ebd3a2619 100644 --- a/src/Translations/Translations.php +++ b/src/Translations/Translations.php @@ -532,8 +532,22 @@ public function getTranslations() 'buttonPayerAction' => $this->module->l('Authenticate payment', 'translations'), 'externalRedirection' => $this->module->l('You will be redirected to an external secured page of our payment gateway.', 'translations'), 'contactLink' => $this->module->l('If you have any question, please contact us.', 'translations'), + 'paymentMethodStatus' => $this->module->l('Payment method status', 'translations'), + 'paymentTokenSaved' => $this->module->l('was saved for future purchases', 'translations'), + 'paymentTokenNotSaved' => $this->module->l('was not saved for future purchases', 'translations'), ], ], + 'google_pay' => [ + 'shipping' => $this->module->l('Shipping', 'translations'), + 'tax' => $this->module->l('Tax', 'translations'), + 'total' => $this->module->l('Total', 'translations'), + 'subtotal' => $this->module->l('Subtotal', 'translations'), + 'handling' => $this->module->l('Handling', 'translations'), + 'discount' => $this->module->l('Discount', 'translations'), + ], + 'apple_pay' => [ + 'total' => $this->module->l('Total', 'translations'), + ], ]; return $translations; diff --git a/src/Validator/index.php b/src/Validator/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Validator/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Version/index.php b/src/Version/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Version/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Webhook/index.php b/src/Webhook/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/src/Webhook/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/tests/IsoCodeDispatcherTest.php b/tests/IsoCodeDispatcherTest.php index 547dfd673..06c95fea4 100755 --- a/tests/IsoCodeDispatcherTest.php +++ b/tests/IsoCodeDispatcherTest.php @@ -17,10 +17,13 @@ * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) */ + +namespace Tests; + use PHPUnit\Framework\TestCase; use PrestaShop\Module\PrestashopCheckout\PaypalCountryCodeMatrice; -class PaypalCountryCodeMatriceTest extends TestCase +class IsoCodeDispatcherTest extends TestCase { /** * @dataProvider isoCodeDataProviderPaypal @@ -58,7 +61,7 @@ public function isoCodeDataProviderPaypal() } /** - * @dataProvider isoCodeDataProviderPrestashopl + * @dataProvider isoCodeDataProviderPrestashop */ public function testgetPrestashopIsoCode($resultExpect, $dataToValidate) { @@ -68,7 +71,7 @@ public function testgetPrestashopIsoCode($resultExpect, $dataToValidate) ); } - public function isoCodeDataProviderPrestashopl() + public function isoCodeDataProviderPrestashop() { return [ [ diff --git a/tests/OrderStatesTranslationsTest.php b/tests/OrderStatesTranslationsTest.php index de6756a84..ad58f5722 100755 --- a/tests/OrderStatesTranslationsTest.php +++ b/tests/OrderStatesTranslationsTest.php @@ -17,6 +17,9 @@ * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) */ + +namespace Tests; + use PHPUnit\Framework\TestCase; use PrestaShop\Module\PrestashopCheckout\Translations\OrderStatesTranslations; diff --git a/tests/PaymentCreateOrderTest.php b/tests/PaymentCreateOrderTest.php index b9004dff4..006bc3ff8 100755 --- a/tests/PaymentCreateOrderTest.php +++ b/tests/PaymentCreateOrderTest.php @@ -17,6 +17,9 @@ * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) */ + +namespace Tests; + use GuzzleHttp\Client; use GuzzleHttp\Message\Response; use GuzzleHttp\Stream\Stream; diff --git a/tests/PsxDataValidationTest.php b/tests/PsxDataValidationTest.php index 0cac95dc7..f85638254 100755 --- a/tests/PsxDataValidationTest.php +++ b/tests/PsxDataValidationTest.php @@ -17,6 +17,9 @@ * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) */ + +namespace Tests; + use PHPUnit\Framework\TestCase; use PrestaShop\Module\PrestashopCheckout\PsxData\PsxDataValidation; diff --git a/tests/Unit/Http/CheckoutHttpClientTest.php b/tests/Unit/Http/MaaslandHttpClientTest.php similarity index 91% rename from tests/Unit/Http/CheckoutHttpClientTest.php rename to tests/Unit/Http/MaaslandHttpClientTest.php index 3944e6b34..212b8d261 100644 --- a/tests/Unit/Http/CheckoutHttpClientTest.php +++ b/tests/Unit/Http/MaaslandHttpClientTest.php @@ -23,13 +23,13 @@ use Http\Client\Exception\HttpException; use PHPUnit\Framework\TestCase; use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException; -use PrestaShop\Module\PrestashopCheckout\Http\CheckoutHttpClient; use PrestaShop\Module\PrestashopCheckout\Http\HttpClientInterface; +use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; -class CheckoutHttpClientTest extends TestCase +class MaaslandHttpClientTest extends TestCase { /** * @dataProvider invalidRequestErrorsProvider @@ -111,6 +111,14 @@ public function testNotFoundErrorsCreateOrderLegacy($errorName, $errorCode) $this->handleTestErrorsCreateOrder(404, $errorName, $errorCode, true); } + /** + * @dataProvider notAuthorizedErrorsProvider + */ + public function testNotAuthorizedErrorsCaptureOrderLegacy($errorName, $errorCode) + { + $this->handleTestErrorsCaptureOrder(401, $errorName, $errorCode); + } + /** * @param int $statusCode * @param string $errorName @@ -132,8 +140,29 @@ private function handleTestErrorsCreateOrder($statusCode, $errorName, $errorCode $httpClient->method('sendRequest')->willThrowException(new HttpException('An error occurred', $requestMock, $responseMock)); $this->expectExceptionCode($errorCode); $this->expectException(PayPalException::class); - $checkoutHttpClient = new CheckoutHttpClient($httpClient); - $checkoutHttpClient->createOrder([]); + $maaslandHttpClient = new MaaslandHttpClient($httpClient); + $maaslandHttpClient->createOrder([]); + } + + private function handleTestErrorsCaptureOrder($statusCode, $errorName, $errorCode, $legacy = false) + { + $error = $this->getErrorResponse($statusCode, $errorName, $legacy); + $requestMock = $this->createMock(RequestInterface::class); + $streamMock = $this->createMock(StreamInterface::class); + $streamMock->method('__toString')->willReturn(json_encode($error)); + $responseMock = $this->createMock(ResponseInterface::class); + $responseMock->method('getStatusCode')->willReturn($statusCode); + $responseMock->method('getBody')->willReturn($streamMock); + $httpClient = $this->createMock(HttpClientInterface::class); + $httpClient->method('sendRequest')->willThrowException(new HttpException('An error occurred', $requestMock, $responseMock)); + $this->expectExceptionCode($errorCode); + $this->expectException(PayPalException::class); + $maaslandHttpClient = new MaaslandHttpClient($httpClient); + + $httpClient->expects($this->once()) + ->method('sendRequest'); + + $maaslandHttpClient->captureOrder([]); } private function getInvalidRequestError($issueError) diff --git a/tests/Unit/PayPal/Order/PaypalOrderDataProviderTest.php b/tests/Unit/PayPal/Order/PaypalOrderDataProviderTest.php index 67eaaef85..a44b3e7e9 100644 --- a/tests/Unit/PayPal/Order/PaypalOrderDataProviderTest.php +++ b/tests/Unit/PayPal/Order/PaypalOrderDataProviderTest.php @@ -21,6 +21,7 @@ namespace Tests\Unit\PayPal\Order; use PHPUnit\Framework\TestCase; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Entity\PayPalOrder; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\PaypalOrderDataProvider; class PaypalOrderDataProviderTest extends TestCase @@ -82,4 +83,84 @@ public function testPendingApproval() $this->assertEquals('PENDING_APPROVAL', $orderPayPalDataProvider->getOrderStatus()); $this->assertEquals('https://www.paypal.com/checkoutnow?token=5O190127TN364715T', $orderPayPalDataProvider->getApprovalLink()); } + + /** + * @dataProvider getPayPalOrder + */ + public function testVaultingData($order, $intentToVault, $isTokenSaved, $tokenIdentifier) + { + $orderPayPalDataProvider = new PaypalOrderDataProvider( + [], + $order + ); + $this->assertEquals($intentToVault, $orderPayPalDataProvider->isIntentToVault()); + $this->assertEquals($isTokenSaved, $orderPayPalDataProvider->isTokenSaved()); + $this->assertEquals($tokenIdentifier, $orderPayPalDataProvider->getPaymentTokenIdentifier()); + } + + public function getPayPalOrder() + { + return [ + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'card', 'COMPLETE', ['card' => ['last_digits' => '4242', 'brand' => 'VISA', 'attributes' => ['vault' => ['id' => '123', 'status' => 'VAULTED']]]], 'LIVE', false, false, [PayPalOrder::CUSTOMER_INTENT_VAULT]), + true, + true, + 'VISA *4242', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'card', 'COMPLETE', ['card' => ['last_digits' => '4242', 'brand' => 'VISA', 'attributes' => ['vault' => ['id' => '123', 'status' => 'APPROVED']]]], 'LIVE', false, false, [PayPalOrder::CUSTOMER_INTENT_VAULT]), + true, + false, + 'VISA *4242', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'card', 'COMPLETE', ['card' => ['last_digits' => '4242', 'brand' => 'VISA']], 'LIVE', false, false, [PayPalOrder::CUSTOMER_INTENT_VAULT]), + true, + false, + 'VISA *4242', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'card', 'COMPLETE', ['card' => ['last_digits' => '4242', 'brand' => 'VISA']], 'LIVE', false, false, []), + false, + false, + 'VISA *4242', + ], + [ + null, + false, + false, + '', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'paypal', 'COMPLETE', ['paypal' => ['email_address' => 'test@prestashop.com', 'attributes' => ['vault' => ['id' => '123', 'status' => 'VAULTED']]]], 'LIVE', false, false, [PayPalOrder::CUSTOMER_INTENT_VAULT]), + true, + true, + 'test@prestashop.com', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'paypal', 'COMPLETE', ['paypal' => ['email_address' => 'test@prestashop.com', 'attributes' => ['vault' => ['id' => '123', 'status' => 'VAULTED']]]], 'LIVE', false, false, []), + false, + true, + 'test@prestashop.com', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'paypal', 'COMPLETE', ['paypal' => ['email_address' => 'test@prestashop.com', 'attributes' => ['vault' => ['id' => '123', 'status' => 'APPROVED']]]], 'LIVE', false, false, []), + false, + false, + 'test@prestashop.com', + ], + [ + new PayPalOrder('5O190127TN364715T', '1', 'CAPTURE', 'paypal', 'COMPLETE', ['paypal' => ['email_address' => 'test@prestashop.com']], 'LIVE', false, false, []), + false, + false, + 'test@prestashop.com', + ], + [ + null, + false, + false, + '', + ], + ]; + } } diff --git a/tests/Unit/bootstrap.php b/tests/Unit/bootstrap.php new file mode 100644 index 000000000..ec5e8adab --- /dev/null +++ b/tests/Unit/bootstrap.php @@ -0,0 +1,6 @@ + diff --git a/tests/WebHookValidationTest.php b/tests/WebHookValidationTest.php index 9f2051f23..70579efa1 100755 --- a/tests/WebHookValidationTest.php +++ b/tests/WebHookValidationTest.php @@ -17,6 +17,9 @@ * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) */ + +namespace Tests; + use PHPUnit\Framework\TestCase; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\WebHookValidation; diff --git a/tests/phpstan/phpstan-PS-8.neon b/tests/phpstan/phpstan-PS-8.neon new file mode 100644 index 000000000..bb2f93ac4 --- /dev/null +++ b/tests/phpstan/phpstan-PS-8.neon @@ -0,0 +1,37 @@ +includes: + - %currentWorkingDirectory%/vendor/prestashop/php-dev-tools/phpstan/ps-module-extension.neon + +parameters: + paths: + # From PHPStan 0.12, paths to check are relative to the neon file + - ../../classes + - ../../controllers + - ../../src + - ../../ps_checkout.php + reportUnmatchedIgnoredErrors: false + ignoreErrors: + - '#Cannot assign offset "merchant
" to string\|true.#' + - '#Property ModuleCore::\$version \(float\) does not accept string.#' + - '#Strict comparison using === between false and string will always evaluate to false.#' + - '#Call to function is_array\(\) with Currency will always evaluate to false.#' + - '#Parameter \#1 \$id of class Customer constructor expects null, bool\|int<1, max>\|int given.#' + - '#Parameter \#1 \$id of class Customer constructor expects null, int\|int<1, max> given.#' + - '#Parameter \#1 \$id of class Customer constructor expects null, int given.#' + - '#Parameter \#1 \$hook_name of method ModuleCore::registerHook\(\) expects string, array given.#' + - '#Parameter \#6 \$idShop of method LinkCore::getModuleLink\(\) expects null, int given.#' + - '#Call to an undefined method\(\) AdminController|FrontController::getCheckoutProcess\(\).#' + - '#Parameter \#1 \$id_hook of method ModuleCore::updatePosition\(\) expects bool, int given.#' + - '#Property TabCore::\$name \(string\) does not accept array.#' + - '#Access to an undefined property PaymentModule::\$currentOrderReference.#' + - '#Property CustomerCore::\$passwd \(int\) does not accept bool\|string.#' + - '#Property CustomerCore::\$passwd \(int\) does not accept string.#' + - '#Parameter \#4 \$ssl of method LinkCore::getModuleLink\(\) expects null, true given.#' + - '#Parameter \#1 \$id of class Customer constructor expects null, int<1, max>\|int given.#' + - '#Property CustomerMessageCore::\$ip_address \(string\) does not accept int.#' + - '#Left side of \&\& is always true.#' + - '#Parameter \#7 \$currency_special of method PaymentModuleCore::validateOrder\(\) expects null, int given.#' + - '#Parameter \#9 \$secure_key of method PaymentModuleCore::validateOrder\(\) expects bool, string given.#' + - '#Property CustomerMessageCore::\$private \(int\) does not accept true.#' + - '#Parameter \#1 \$amount_paid of method OrderCore::addOrderPayment\(\) expects string, float\|int given.#' + + level: 5 diff --git a/translations/fr.php b/translations/fr.php index 98b266672..cb4988216 100644 --- a/translations/fr.php +++ b/translations/fr.php @@ -59,6 +59,12 @@ $_MODULE['<{ps_checkout}prestashop>ps_checkout_39dc86ebdd6c930447215d738bc4d15f'] = 'Une erreur est survenue lors de l\'authentification du titulaire de la carte, veuillez choisir un autre moyen de paiement ou essayez de nouveau.'; $_MODULE['<{ps_checkout}prestashop>ps_checkout_816565ccf105493c7b15166627f6fc16'] = 'Echec de l\'authentification du titulaire de la carte, veuillez choisir un autre moyen de paiement ou essayez de nouveau.'; $_MODULE['<{ps_checkout}prestashop>ps_checkout_52afb370f87a4acfe4f1aaee204835eb'] = 'L\'identitĂ© du titulaire de la carte n\'a pas pu ĂȘtre vĂ©rifiĂ©e, veuillez choisir un autre moyen de paiement ou essayez de nouveau.'; +$_MODULE['<{ps_checkout}prestashop>ps_checkout_a60852f204ed8028c1c58808b746d115'] = 'Ok'; +$_MODULE['<{ps_checkout}prestashop>ps_checkout_ea4788705e6873b424c65e91c2846b19'] = 'Annuler'; +$_MODULE['<{ps_checkout}prestashop>ps_checkout_5e1c8c70c8b2948157cbcafaef3dd7b9'] = 'Voulez-vous supprimer cette mĂ©thode de paiement ?'; +$_MODULE['<{ps_checkout}prestashop>ps_checkout_b54040e4e1fd364112517e8ce7b531fd'] = 'Cette mĂ©thode de paiement sera supprimĂ©e de votre compte :'; +$_MODULE['<{ps_checkout}prestashop>ps_checkout_1203190e2c25d0377afab032ddd9b608'] = 'Supprimer cette mĂ©thode de paiement'; +$_MODULE['<{ps_checkout}prestashop>ps_checkout_875e6e29b50c20a90d8c09435ab2c8b3'] = 'Veuillez patienter, nous traitons votre demande...'; $_MODULE['<{ps_checkout}prestashop>displayorderconfirmation_32187a5bef114c112c1ef96ca2e3da1a'] = 'Votre commande est confirmĂ©e.'; $_MODULE['<{ps_checkout}prestashop>displayorderconfirmation_034347c8ea2ce26879ee1fee0b5e58ca'] = 'Votre commande est en attente de confirmation de paiement. Vous recevrez un email lorsque votre paiement aura Ă©tĂ© validĂ©. Vous pouvez Ă©galement vĂ©rifier le statut de votre commande dans votre historique de commandes dans votre compte.'; $_MODULE['<{ps_checkout}prestashop>displaypaymenttop_733ea3e302b9c48da7777481ed50e59a'] = 'Traitement du paiement annulĂ©, veuillez choisir une autre mĂ©thode de paiement ou essayez de nouveau.'; @@ -66,7 +72,7 @@ $_MODULE['<{ps_checkout}prestashop>displaypayment_a44217022190f5734b2f72ba1e4f8a79'] = 'NumĂ©ro de carte'; $_MODULE['<{ps_checkout}prestashop>displaypayment_95b16127e70e8a90220404fb48343182'] = 'Date d\'expiration'; $_MODULE['<{ps_checkout}prestashop>displaypayment_5ea7f231296949070013bc43715aae01'] = 'Code de sĂ©curitĂ©'; -$_MODULE['<{ps_checkout}prestashop>displaypayment_fa29fdc19f1d3ac45b09645c15c5312b'] = 'Le code de sĂ©curitĂ© et un code Ă '; +$_MODULE['<{ps_checkout}prestashop>displaypayment_fa29fdc19f1d3ac45b09645c15c5312b'] = 'Le code de sĂ©curitĂ© est un code Ă '; $_MODULE['<{ps_checkout}prestashop>displaypayment_1e9307ff80da8e2e7053566f1613cf90'] = '3 chiffres'; $_MODULE['<{ps_checkout}prestashop>displaypayment_36883c97eb73307ac86b5ad32abbb49b'] = 'prĂ©sent sur le dos de votre carte. Dans certains cas, il est composĂ© de 4 chiffres ou se trouve Ă  l\'avant de la carte.'; $_MODULE['<{ps_checkout}prestashop>displaypayment_46b9e3665f187c739c55983f757ccda0'] = 'Je valide ma commande'; @@ -82,6 +88,15 @@ $_MODULE['<{ps_checkout}prestashop>incompatiblecodes_5041c9dced8f0d0a4d319be95b229ea5'] = 'Changer les pays activĂ©s pour ce module de paiement'; $_MODULE['<{ps_checkout}prestashop>incompatiblecodes_487a4ced3865f176965c1571a9f3c0fe'] = 'Changer les devises activĂ©es pour ce module de paiement'; $_MODULE['<{ps_checkout}prestashop>incompatiblecodes_cb2afa98a49d1ac44da748a5ee556a8a'] = 'En savoir plus sur les ISO Codes conformes'; +$_MODULE['<{ps_checkout}prestashop>payment_94a3acb3f16f07d0a2e3bfae65cfdb58'] = 'L\'authentification 3D secure a Ă©chouĂ©, veuillez rĂ©essayer.'; +$_MODULE['<{ps_checkout}prestashop>payment_fd6237b65b7bb37075277bba7d1aca08'] = 'Retour Ă  la page de commande'; +$_MODULE['<{ps_checkout}prestashop>vaultpaymentfields_8878480cb609084dbf1573e8cc53ff02'] = 'Sauvegardez en toute sĂ©curitĂ© vos informations de paiement'; +$_MODULE['<{ps_checkout}prestashop>vaultpaymentfields_2c391a491914670af81c0522a9091d7c'] = 'DĂ©finir comme mĂ©thode de paiement prĂ©fĂ©rĂ©e'; +$_MODULE['<{ps_checkout}prestashop>vaultpaymentfields_e6e2a83a209d8c2ca1793dfcda1eca49'] = 'DĂ©finir ce compte comme mĂ©thode de paiement prĂ©fĂ©rĂ©e'; +$_MODULE['<{ps_checkout}prestashop>vaulttokenform_ca3e15a8a9c7a796a1893277bf48b8ef'] = 'Cette mĂ©thode de paiement est enregistrĂ©e sur votre compte et dĂ©finie comme mĂ©thode de paiement prĂ©fĂ©rĂ©e pour vos futurs achats.'; +$_MODULE['<{ps_checkout}prestashop>vaulttokenform_6c493105989f12b2da5d1f770ac779f9'] = 'Cette mĂ©thode de paiement a Ă©tĂ© enregistrĂ©e sur votre compte.'; +$_MODULE['<{ps_checkout}prestashop>vaulttokenform_f2a6c498fb90ee345d997f888fce3b18'] = 'Supprimer'; +$_MODULE['<{ps_checkout}prestashop>vaulttokenform_0db443e338b016aae2b24ce0be40beda'] = 'DĂ©finir comme mĂ©thode de paiement prĂ©fĂ©rĂ©e'; $_MODULE['<{ps_checkout}prestashop>cardfields_f92103c13c44bded222d124f5b9743f3'] = 'Nom du titulaire de la carte'; $_MODULE['<{ps_checkout}prestashop>cardfields_01cd32f89f9f5807e07d58a002b09dee'] = 'Nom du titulaire de la carte invalide.'; $_MODULE['<{ps_checkout}prestashop>cardfields_a44217022190f5734b2f72ba1e4f8a79'] = 'NumĂ©ro de carte'; @@ -90,7 +105,7 @@ $_MODULE['<{ps_checkout}prestashop>cardfields_462256f533f152fa6b05baabb7919473'] = 'Date d\'expiration'; $_MODULE['<{ps_checkout}prestashop>cardfields_5284be11230ea808cbcb2bfa117eef0e'] = 'Date d\'expiration de la carte invalide.'; $_MODULE['<{ps_checkout}prestashop>cardfields_5ea7f231296949070013bc43715aae01'] = 'Code de sĂ©curitĂ©'; -$_MODULE['<{ps_checkout}prestashop>cardfields_fa29fdc19f1d3ac45b09645c15c5312b'] = 'Le code de sĂ©curitĂ© et un code Ă '; +$_MODULE['<{ps_checkout}prestashop>cardfields_fa29fdc19f1d3ac45b09645c15c5312b'] = 'Le code de sĂ©curitĂ© est un code Ă '; $_MODULE['<{ps_checkout}prestashop>cardfields_1e9307ff80da8e2e7053566f1613cf90'] = '3 chiffres'; $_MODULE['<{ps_checkout}prestashop>cardfields_36883c97eb73307ac86b5ad32abbb49b'] = 'prĂ©sent sur le dos de votre carte. Dans certains cas, il est composĂ© de 4 chiffres ou se trouve Ă  l\'avant de la carte.'; $_MODULE['<{ps_checkout}prestashop>cardfields_43da12b692a051ce433c2877b61d4c67'] = 'Code de sĂ©curitĂ© invalide.'; @@ -239,6 +254,7 @@ $_MODULE['<{ps_checkout}prestashop>adminajaxprestashopcheckoutcontroller_bc06e3a40808fc7351ff8f57b3bad7cf'] = 'Transaction PayPal invalide.'; $_MODULE['<{ps_checkout}prestashop>adminajaxprestashopcheckoutcontroller_5825dada06af7bef8ae4db80c2c5aeba'] = 'Montant de remboursement PayPal invalide.'; $_MODULE['<{ps_checkout}prestashop>adminajaxprestashopcheckoutcontroller_da74acca9d5669367fa982b7694f5303'] = 'Devise de remboursement PayPal invalide.'; +$_MODULE['<{ps_checkout}prestashop>adminajaxprestashopcheckoutcontroller_785e1b8c2c57d4ad6ed603778b4f6ba9'] = 'Le remboursement a Ă©tĂ© traitĂ© par PayPal, mais le changement de statut de la commande ou l\'envoi de l\'e-mail a Ă©chouĂ©.'; $_MODULE['<{ps_checkout}prestashop>adminajaxprestashopcheckoutcontroller_d1a7ac6d45dcb4a782b441e29380056a'] = 'Le remboursement a Ă©tĂ© effectuĂ© par PayPal.'; $_MODULE['<{ps_checkout}prestashop>adminajaxprestashopcheckoutcontroller_ee6403a0a4d60590a6b6634df2fdce3f'] = 'Le remboursement n\'a pas pu ĂȘtre effectuĂ© par PayPal.'; $_MODULE['<{ps_checkout}prestashop>adminpaypalonboardingprestashopcheckoutcontroller_f54c8c9ec6eb9489f860c4b04206c0db'] = 'Nous n\'avons pas reçu votre identifiant marchand PayPal.'; @@ -645,7 +661,11 @@ $_MODULE['<{ps_checkout}prestashop>translations_b147f642538c69e4fbd7ae6609fd62fe'] = 'Authentifier le paiemennt'; $_MODULE['<{ps_checkout}prestashop>translations_45a110be54ff9533824fc03578b06371'] = 'Vous serez redirigĂ© vers une page externe sĂ©curisĂ©.'; $_MODULE['<{ps_checkout}prestashop>translations_8fe57282806d2b6da782d1da9ab5d46c'] = 'Si vous avez une question, veuillez nous contacter.'; +$_MODULE['<{ps_checkout}prestashop>translations_20cb69d4c9adf02e582769f6b5e43353'] = 'Statut mĂ©thode de paiement'; +$_MODULE['<{ps_checkout}prestashop>translations_df7acad4a0ddd7ea87e21d06f4564041'] = 'a Ă©tĂ© enregistrĂ© pour vos achats futurs'; +$_MODULE['<{ps_checkout}prestashop>translations_1917b07d3afbf9408a6e91ede37479d3'] = 'n\'a pas Ă©tĂ© enregistrĂ© pour vos achats futurs'; $_MODULE['<{ps_checkout}prestashop>fundingsourcetranslationprovider_1d565b9e5303987bb1b1938d5d458bca'] = 'Carte'; +$_MODULE['<{ps_checkout}prestashop>fundingsourcetranslationprovider_35895cff7df70dab18783453e2bd241f'] = 'Payer avec %s'; $_MODULE['<{ps_checkout}prestashop>fundingsourcetranslationprovider_f990493af3321939ca512f8f2cace108'] = 'Payer par %s'; $_MODULE['<{ps_checkout}prestashop>fundingsourcetranslationprovider_34ace703adbf14df140d3c02234f67bd'] = 'Payer avec un compte PayPal'; $_MODULE['<{ps_checkout}prestashop>fundingsourcetranslationprovider_983fe12e91079dcb00c74772b50747a3'] = 'Payer par carte - paiements 100% sĂ©curisĂ©s'; diff --git a/upgrade/upgrade-7.4.2.2.php b/upgrade/upgrade-7.4.2.2.php new file mode 100644 index 000000000..6934da39a --- /dev/null +++ b/upgrade/upgrade-7.4.2.2.php @@ -0,0 +1,216 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Update main function for module version 7.4.2.2 + * + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_module_7_4_2_2($module) +{ + try { + $result = upgrade_7_4_0_0($module); + $result &= upgrade_7_4_1_0($module); + + $module->registerHook('moduleRoutes'); + + $db = Db::getInstance(); + $shopsList = \Shop::getShops(false, null, true); + + foreach ($shopsList as $shopId) { + $hasFundingSourceApplePay = (bool) $db->getValue(' + SELECT 1 + FROM `' . _DB_PREFIX_ . 'pscheckout_funding_source` + WHERE `name` = "apple_pay" + AND `id_shop` = ' . (int) $shopId + ); + + if (!$hasFundingSourceApplePay) { + $db->insert( + 'pscheckout_funding_source', + [ + 'name' => 'apple_pay', + 'position' => 12, + 'active' => 0, + 'id_shop' => (int) $shopId, + ] + ); + } + } + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return $result; +} + +/** + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_7_4_0_0($module) +{ + try { + $db = Db::getInstance(); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_order` ( + `id` varchar(50) NOT NULL, + `id_cart` int unsigned NOT NULL, + `status` varchar(30) NOT NULL, + `intent` varchar(50) DEFAULT "CAPTURE", + `funding_source` varchar(50) NOT NULL, + `payment_source` text, + `environment` varchar(50) NOT NULL, + `is_card_fields` tinyint(1) NOT NULL, + `is_express_checkout` tinyint(1) NOT NULL, + `customer_intent` varchar(50), + `payment_token_id` varchar(50), + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_capture` ( + `id` varchar(50) NOT NULL, + `id_order` varchar(50) NOT NULL, + `status` varchar(30) NOT NULL, + `final_capture` tinyint(1) NOT NULL, + `created_at` varchar(50) NOT NULL, + `updated_at` varchar(50) NOT NULL, + `seller_protection` text, + `seller_receivable_breakdown` text, + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_refund` ( + `id` varchar(50) NOT NULL, + `id_order` varchar(50) NOT NULL, + `status` varchar(30) NOT NULL, + `invoice_id` varchar(50) NOT NULL, + `custom_id` varchar(50) NOT NULL, + `acquirer_reference_number` varchar(50) NOT NULL, + `seller_payable_breakdown` text, + `id_order_slip` INT UNSIGNED, + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_authorization` ( + `id` varchar(50) NOT NULL, + `id_order` varchar(50) NOT NULL, + `status` varchar(30) NOT NULL, + `expiration_time` varchar(50) NOT NULL, + `seller_protection` text, + PRIMARY KEY (`id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_purchase_unit` ( + `id_order` varchar(50) NOT NULL, + `checksum` varchar(50) NOT NULL, + `reference_id` varchar(50) NOT NULL, + `items` text, + PRIMARY KEY (`reference_id`, `id_order`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_customer` ( + `id_customer` int unsigned NOT NULL, + `paypal_customer_id` varchar(50) NOT NULL, + PRIMARY KEY (`id_customer`, `paypal_customer_id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_payment_token` ( + `id` INT UNSIGNED AUTO_INCREMENT, + `token_id` varchar(50) NOT NULL, + `paypal_customer_id` varchar(50) NOT NULL, + `payment_source` varchar(50) NOT NULL, + `data` text NOT NULL, + `merchant_id` varchar(50) NOT NULL, + `status` varchar(50) NOT NULL, + `is_favorite` tinyint(1) unsigned DEFAULT 0 NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `token_id_merchant_id_paypal_customer_id` (`token_id`, `merchant_id`, `paypal_customer_id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + '); + $db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` CHANGE `paypal_status` `paypal_status` VARCHAR(30) NULL; '); + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return true; +} + +/** + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_7_4_1_0($module) +{ + try { + $db = Db::getInstance(); + $shopsList = \Shop::getShops(false, null, true); + + foreach ($shopsList as $shopId) { + $isGooglePayEligible = (bool) \Configuration::get( + 'PS_CHECKOUT_GOOGLE_PAY', + null, + null, + $shopId + ); + $hasFundingSourceGooglePay = (bool) $db->getValue(' + SELECT 1 + FROM `' . _DB_PREFIX_ . 'pscheckout_funding_source` + WHERE `name` = "google_pay" + AND `id_shop` = ' . (int) $shopId + ); + + if (!$hasFundingSourceGooglePay) { + $db->insert( + 'pscheckout_funding_source', + [ + 'name' => 'google_pay', + 'position' => 11, + 'active' => (int) $isGooglePayEligible, + 'id_shop' => (int) $shopId, + ] + ); + } + } + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return true; +} diff --git a/_dev/js/front/src/constants/ps-version.constants.js b/views/css/adminModules.css similarity index 74% rename from _dev/js/front/src/constants/ps-version.constants.js rename to views/css/adminModules.css index 9f9ce9542..b44ec63fa 100644 --- a/_dev/js/front/src/constants/ps-version.constants.js +++ b/views/css/adminModules.css @@ -4,7 +4,7 @@ * * NOTICE OF LICENSE * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) + * This source file is subject to the Academic Free License version 3.0 * that is bundled with this package in the file LICENSE.md. * It is also available through the world-wide-web at this URL: * https://opensource.org/licenses/AFL-3.0 @@ -12,9 +12,11 @@ * obtain it through the world-wide-web, please send an email * to license@prestashop.com so we can send you a copy immediately. * - * @author PrestaShop SA + * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ -export const PS_VERSION_1_6 = '1.6'; -export const PS_VERSION_1_7 = '1.7'; + +.toolbarBox .btn-toolbar .nav-pills { + display: none; +} diff --git a/views/css/payment.css b/views/css/payment.css new file mode 100644 index 000000000..9d49d6d2e --- /dev/null +++ b/views/css/payment.css @@ -0,0 +1,46 @@ +/** + * Copyright since 2007 PrestaShop SA and Contributors + * PrestaShop is an International Registered Trademark & Property of PrestaShop SA + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License version 3.0 + * that is bundled with this package in the file LICENSE.md. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * @author PrestaShop SA and Contributors + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +.ps-checkout.wrapper { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; +} + +.ps-checkout.content { + width: 500px; + height: 250px; + max-width: 90%; + border-radius: 15px; + border: 2px solid #AAAAAA; + padding: 50px; + box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.ps-checkout.order-link { + text-align: center; +} diff --git a/views/css/payments.css b/views/css/payments.css index ce6acaba6..23fde7c6b 100755 --- a/views/css/payments.css +++ b/views/css/payments.css @@ -63,6 +63,8 @@ visibility: hidden !important; } +#conditions-to-approve label, +.payment-options label, .paypal-label { cursor: pointer; } @@ -273,7 +275,7 @@ opacity: 100; } -.ps-checkout.popup { +.ps-checkout.popup, .ps-checkout.ps-checkout-modal { position: absolute; top: 0; left: 0; @@ -289,35 +291,103 @@ border-radius: 15px; } +.ps-checkout.ps-checkout-modal { + border-radius: 0; + height: fit-content; +} + @media (max-width: 992px) { - .ps-checkout.popup { + .ps-checkout.popup, .ps-checkout.ps-checkout-modal { width: 600px; } } @media (max-width: 768px) { - .ps-checkout.popup { + .ps-checkout.popup, .ps-checkout.ps-checkout-modal { width: 500px; } } @media (max-width: 576px) { - .ps-checkout.popup { + .ps-checkout.popup, .ps-checkout.ps-checkout-modal { width: 350px; } - .ps-checkout.text { + .ps-checkout.text, .ps-checkout.header, .ps-checkout.content { font-size: 20px; } } -.ps-checkout.text, .ps-checkout.loader { +.ps-checkout-modal .close-button { + position: absolute; + right: 20px; + top: 20px; + background: transparent; + border: none; + cursor: pointer; +} + +.ps-checkout.text, .ps-checkout.header, .ps-checkout.loader { display: block; margin: 0 auto; margin-top: 45px; text-align: center; } +.ps-checkout.header { + text-align: left; +} + +.ps-checkout-modal .ps-checkout.header .ps-checkout-modal-icon{ + width: 34px; + height: 34px; + display: inline-flex; + vertical-align: middle; + border-radius: 34px; + margin-right: 20px; + padding: 5px; +} + +.ps-checkout-modal .ps-checkout.header .ps-checkout-modal-icon.icon-danger { + background-color: #FFE4E6; +} + +.ps-checkout-modal .ps-checkout.header .ps-checkout-modal-icon.icon-alert { + background-color: #FFF5E5; +} + +.ps-checkout-modal .ps-checkout.header .ps-checkout-modal-icon.icon-success { + background-color: #EAF8EF; +} + +.ps-checkout-modal .ps-checkout.header .ps-checkout-modal-icon.icon-info { + background-color: #E8EDFD; +} + +.ps-checkout.ps-checkout-modal .ps-checkout.header { + margin: 40px 15px; +} + +.ps-checkout.content { + margin: 15px; +} + +.ps-checkout.footer { + padding: 15px; + width: 100%; + text-align: right; +} + +.ps-checkout.footer > button + button{ + margin-left: 10px; +} + +.ps-checkout.footer button.ps-checkout.btn.danger { + color: #fff; + background-color: #ff4c4c; + border-color: #ff4c4c; +} + .ps-checkout.subtext { margin-top: 25px; text-align: center; @@ -350,14 +420,14 @@ margin-top: 6px; } -#ps_checkout-card-fields-form label, -label[for="ps_checkout-hosted-fields-card-cvv"] { +#ps_checkout-card-fields-form label[for="ps_checkout-card-fields-cvv"] { white-space: nowrap; } .ps_checkout-payment-option span.custom-radio { float: none !important; - margin-right: 1.0rem !important; + /*TODO: Check if this margin is needed*/ + /*margin-right: 1rem !important;*/ } .ps_checkout-payment-option label { @@ -365,6 +435,18 @@ label[for="ps_checkout-hosted-fields-card-cvv"] { line-height: 2.5; } +.ps_checkout-vault-fields .ps_checkout-vault-label { + text-align: left; + white-space: normal; +} +.ps_checkout-vault-fields, .ps_checkout-favorite-payment{ + margin-bottom: 1rem; +} + +.ps_checkout-vault-token-form .ps_checkout-token-explanation { +font-size: 0.75rem; +} + .js-payment-ps_checkout.disabled .ps_checkout-button[data-funding-source="card"] button:disabled { /*TODO: This causes the button to be seen as not disabled on hummingbird. Do we keep it?*/ /*opacity: initial;*/ @@ -508,6 +590,17 @@ label[for="ps_checkout-hosted-fields-card-cvv"] { text-align: center; } +form button.ps_checkout-vault-token-delete { + cursor: pointer; + text-decoration: underline; + font-size: 0.75rem; + margin-bottom: 0.75rem; + display: inline-block; + background-color: transparent; + border: none; + padding: 0; +} + #ps_checkout-card-fields-form .ps_checkout-card-fields-cvv-label-wrapper { display: table; } @@ -523,3 +616,8 @@ label[for="ps_checkout-hosted-fields-card-cvv"] { .paypal-pay-later-banner > span { margin: auto; } + +.ps-checkout.icon-favorite { + width: 20px; + height: 20px; +} diff --git a/views/img/apple_pay.svg b/views/img/apple_pay.svg new file mode 100644 index 000000000..0c6ecafef --- /dev/null +++ b/views/img/apple_pay.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/views/img/google_pay.svg b/views/img/google_pay.svg new file mode 100644 index 000000000..3ddf1e493 --- /dev/null +++ b/views/img/google_pay.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/views/img/icons/close.svg b/views/img/icons/close.svg new file mode 100644 index 000000000..2c274ae2d --- /dev/null +++ b/views/img/icons/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/views/img/icons/delete_forever.svg b/views/img/icons/delete_forever.svg new file mode 100644 index 000000000..f5852a30c --- /dev/null +++ b/views/img/icons/delete_forever.svg @@ -0,0 +1 @@ + diff --git a/views/img/icons/delete_forever_fill.svg b/views/img/icons/delete_forever_fill.svg new file mode 100644 index 000000000..895bbfba2 --- /dev/null +++ b/views/img/icons/delete_forever_fill.svg @@ -0,0 +1 @@ + diff --git a/views/img/icons/favorite.svg b/views/img/icons/favorite.svg new file mode 100644 index 000000000..23f7c4c06 --- /dev/null +++ b/views/img/icons/favorite.svg @@ -0,0 +1,3 @@ + + + diff --git a/views/img/icons/favorite_fill.svg b/views/img/icons/favorite_fill.svg new file mode 100644 index 000000000..db148fca5 --- /dev/null +++ b/views/img/icons/favorite_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/views/img/icons/index.php b/views/img/icons/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/views/img/icons/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/views/img/icons/lock_fill.svg b/views/img/icons/lock_fill.svg new file mode 100644 index 000000000..0815d7841 --- /dev/null +++ b/views/img/icons/lock_fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/views/templates/front/payment.tpl b/views/templates/front/payment.tpl new file mode 100644 index 000000000..334917301 --- /dev/null +++ b/views/templates/front/payment.tpl @@ -0,0 +1,41 @@ +{** + * Copyright since 2007 PrestaShop SA and Contributors + * PrestaShop is an International Registered Trademark & Property of PrestaShop SA + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License version 3.0 + * that is bundled with this package in the file LICENSE.md. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * @author PrestaShop SA and Contributors + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + *} +{extends file='page.tpl'} +{block name='content'} +
+
+
+ {if isset($error)} + {$error} + {else} + {l s='3DS verification failed, please try again.' mod='ps_checkout'} + {/if} +
+ +
+
+{/block} +{block name='notifications'} +{/block} +{block name='header'} +{/block} +{block name="footer"} +{/block} diff --git a/views/templates/hook/adminAfterHeader/index.php b/views/templates/hook/adminAfterHeader/index.php new file mode 100644 index 000000000..296d682e8 --- /dev/null +++ b/views/templates/hook/adminAfterHeader/index.php @@ -0,0 +1,28 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/views/templates/hook/displayPaymentReturn.tpl b/views/templates/hook/displayPaymentReturn.tpl index ff0421437..f4f8c1a18 100644 --- a/views/templates/hook/displayPaymentReturn.tpl +++ b/views/templates/hook/displayPaymentReturn.tpl @@ -30,19 +30,30 @@
{$translations.fundingSource|escape:'html':'UTF-8'}
{$orderPayPalFundingSourceTranslated|escape:'html':'UTF-8'}
- {if $orderPayPalTransactionId} -
{$translations.transactionIdentifier|escape:'html':'UTF-8'}
-
{$orderPayPalTransactionId|escape:'html':'UTF-8'}
-
{$translations.transactionStatus|escape:'html':'UTF-8'}
-
{$orderPayPalTransactionStatusTranslated|escape:'html':'UTF-8'}
-
{$translations.amountPaid|escape:'html':'UTF-8'}
-
{$orderPayPalTransactionAmount|escape:'html':'UTF-8'}
+ {if $vault} +
{$translations.paymentMethodStatus|escape:'html':'UTF-8'}
+
+ {$tokenIdentifier|escape:'html':'UTF-8'} + {if $isTokenSaved} + {$translations.paymentTokenSaved|escape:'html':'UTF-8'} {else} -
{$translations.orderIdentifier|escape:'html':'UTF-8'}
-
{$orderPayPalId|escape:'html':'UTF-8'}
-
{$translations.orderStatus|escape:'html':'UTF-8'}
-
{$orderPayPalStatus|escape:'html':'UTF-8'}
+ {$translations.paymentTokenNotSaved|escape:'html':'UTF-8'} {/if} + + {/if} + {if $orderPayPalTransactionId} +
{$translations.transactionIdentifier|escape:'html':'UTF-8'}
+
{$orderPayPalTransactionId|escape:'html':'UTF-8'}
+
{$translations.transactionStatus|escape:'html':'UTF-8'}
+
{$orderPayPalTransactionStatusTranslated|escape:'html':'UTF-8'}
+
{$translations.amountPaid|escape:'html':'UTF-8'}
+
{$orderPayPalTransactionAmount|escape:'html':'UTF-8'}
+ {else} +
{$translations.orderIdentifier|escape:'html':'UTF-8'}
+
{$orderPayPalId|escape:'html':'UTF-8'}
+
{$translations.orderStatus|escape:'html':'UTF-8'}
+
{$orderPayPalStatus|escape:'html':'UTF-8'}
+ {/if}
{if $approvalLink && $orderPayPalStatus === 'PENDING_APPROVAL'} diff --git a/views/templates/hook/partials/cardFields.tpl b/views/templates/hook/partials/cardFields.tpl index 69bd482fe..433b101c3 100644 --- a/views/templates/hook/partials/cardFields.tpl +++ b/views/templates/hook/partials/cardFields.tpl @@ -26,6 +26,8 @@ * * Script tags will be removed and some HTML5 element can cause an Exception due to DOMDocument class *} +
+
@@ -63,8 +65,13 @@
+ {if $vaultingEnabled} + {include file='module:ps_checkout/views/templates/hook/partials/vaultPaymentFields.tpl' paymentIdentifier='card'} + {/if}
+
+ *} +
diff --git a/views/templates/hook/partials/vaultPaymentForm.tpl b/views/templates/hook/partials/vaultPaymentForm.tpl new file mode 100644 index 000000000..219b61b34 --- /dev/null +++ b/views/templates/hook/partials/vaultPaymentForm.tpl @@ -0,0 +1,33 @@ +{** + * Copyright since 2007 PrestaShop SA and Contributors + * PrestaShop is an International Registered Trademark & Property of PrestaShop SA + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License version 3.0 + * that is bundled with this package in the file LICENSE.md. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * @author PrestaShop SA and Contributors + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + *} + +{** + * WARNING + * + * This file allow only html + * + * It will be parsed by PrestaShop Core with PrestaShop\PrestaShop\Core\Payment\PaymentOptionFormDecorator + * + * Script tags will be removed and some HTML5 element can cause an Exception due to DOMDocument class + *} +{if $vaultingEnabled} +
+ {include file='module:ps_checkout/views/templates/hook/partials/vaultPaymentFields.tpl' paymentIdentifier=$paymentIdentifier} +
+{/if} diff --git a/views/templates/hook/partials/vaultTokenForm.tpl b/views/templates/hook/partials/vaultTokenForm.tpl new file mode 100644 index 000000000..0c2e18430 --- /dev/null +++ b/views/templates/hook/partials/vaultTokenForm.tpl @@ -0,0 +1,53 @@ +{** + * Copyright since 2007 PrestaShop SA and Contributors + * PrestaShop is an International Registered Trademark & Property of PrestaShop SA + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License version 3.0 + * that is bundled with this package in the file LICENSE.md. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * @author PrestaShop SA and Contributors + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + *} + +{** + * WARNING + * + * This file allow only html + * + * It will be parsed by PrestaShop Core with PrestaShop\PrestaShop\Core\Payment\PaymentOptionFormDecorator + * + * Script tags will be removed and some HTML5 element can cause an Exception due to DOMDocument class + *} +
+
+ + {if $isFavorite} + {l s='This payment method has been saved to your account and defined as favorite for future purchases.' mod='ps_checkout'} + {else} + {l s='This payment method has been saved to your account.' mod='ps_checkout'} + {/if} + +
+
+ +
+{* {if !$isFavorite}*} +{*
*} +{* *} +{*
*} +{* {/if}*} + + + +