diff --git a/enabler/.env.template b/enabler/.env.template new file mode 100644 index 0000000..fbadc16 --- /dev/null +++ b/enabler/.env.template @@ -0,0 +1,5 @@ +VITE_ADMIN_CLIENT_ID=IYg3zsamDxEtBVhN0GXPfSyz +VITE_ADMIN_CLIENT_SECRET=Ti5_ciOUgU76hu0hq75shf0V3Fg4Oean +VITE_ADMIN_SCOPE=manage_project:commercetools-checkout +VITE_REGION=europe-west1.gcp +VITE_CART_ID=f49ea44e-a189-4f9f-b17f-b09f29da49c9 diff --git a/enabler/.gitignore b/enabler/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/enabler/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/enabler/decs.d.ts b/enabler/decs.d.ts new file mode 100644 index 0000000..cbc82b1 --- /dev/null +++ b/enabler/decs.d.ts @@ -0,0 +1,7 @@ +declare module "@adyen/adyen-web" +declare module "@adyen/adyen-web/dist/types/components/ApplePay" +declare module "@adyen/adyen-web/dist/types/components/GooglePay" +declare module "@adyen/adyen-web/dist/types/core" +declare module "@adyen/adyen-web/dist/types/core/core" +declare module "@adyen/adyen-web/dist/types/components/Redirect/Redirect" +declare module "@adyen/adyen-web/dist/types/core/types" diff --git a/enabler/index.html b/enabler/index.html new file mode 100644 index 0000000..4addda9 --- /dev/null +++ b/enabler/index.html @@ -0,0 +1,73 @@ + + + + + + + Vite + TS + + + + +
+ + +
+
+
Adyen dropin component:
+
+
+
+
Adyen card component:
+
+
+
+
Ideal component:
+
+
+
+
Googlepay component:
+
+
+
+ + diff --git a/enabler/package-lock.json b/enabler/package-lock.json new file mode 100644 index 0000000..d0a266a --- /dev/null +++ b/enabler/package-lock.json @@ -0,0 +1,1133 @@ +{ + "name": "pay-adyen-connect-client", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pay-adyen-connect-client", + "version": "0.0.0", + "dependencies": { + "@adyen/adyen-web": "5.51.0", + "http-server": "^14.1.1" + }, + "devDependencies": { + "@adyen/adyen-web": "5.51.0", + "@types/node": "^20.11.0", + "typescript": "5.2.2", + "vite": "4.4.9", + "vite-plugin-css-injected-by-js": "3.3.0" + } + }, + "node_modules/@adyen/adyen-web": { + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/@adyen/adyen-web/-/adyen-web-5.51.0.tgz", + "integrity": "sha512-jH3Us9k57AhdOrwBL444EQdQ+xTgg4BTD/9/RSOmldw9EM1LzX1+6AKkX/7QioJoYO6L7gI5DUu5iq915ju0IA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.15.4", + "@babel/runtime-corejs3": "^7.20.1", + "@types/applepayjs": "^3.0.4", + "@types/googlepay": "^0.7.0", + "classnames": "^2.3.1", + "core-js-pure": "^3.25.3", + "preact": "10.13.2" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.8.tgz", + "integrity": "sha512-2ZzmcDugdm0/YQKFVYsXiwUN7USPX8PM7cytpb4PFl87fM+qYPSvTZX//8tyeJB1j0YDmafBJEbl5f8NfLyuKw==", + "dev": true, + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/applepayjs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/applepayjs/-/applepayjs-3.0.4.tgz", + "integrity": "sha512-RqaVZWy1Kj4e1PoUoOI8uA+4UuuLpicQFxfU9Y/xWJFZFT6mFB4PiiY911iDxFk7pdvaj5HKH7VsWRisRca1Rg==", + "dev": true + }, + "node_modules/@types/googlepay": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@types/googlepay/-/googlepay-0.7.5.tgz", + "integrity": "sha512-158egcRaqkMSpW6unyGV4uG4FpoCklRf3J5emCzOXSRVAohMfIuZ481JNvp4X6+KxoNjxWiGtMx5vb1YfQADPw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", + "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "dev": true + }, + "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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==" + }, + "node_modules/core-js-pure": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.0.tgz", + "integrity": "sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": 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==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "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==", + "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==", + "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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "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==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "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/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/postcss": { + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", + "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "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==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" + }, + "node_modules/set-function-length": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "node_modules/vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-css-injected-by-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-3.3.0.tgz", + "integrity": "sha512-xG+jyHNCmUqi/TXp6q88wTJGeAOrNLSyUUTp4qEQ9QZLGcHWQQsCsSSKa59rPMQr8sOzfzmWDd8enGqfH/dBew==", + "dev": true, + "peerDependencies": { + "vite": ">2.0.0-0" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + } + } +} diff --git a/enabler/package.json b/enabler/package.json new file mode 100644 index 0000000..1ab414b --- /dev/null +++ b/enabler/package.json @@ -0,0 +1,24 @@ +{ + "name": "pay-adyen-connect-client", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite --port 3000", + "start": "http-server dist --port=8082 --cors", + "build": "tsc && vite build", + "preview": "vite preview", + "serve": "npm run build && npx http-server dist --port=3000 --cors" + }, + "dependencies": { + "@adyen/adyen-web": "5.51.0", + "http-server": "^14.1.1" + }, + "devDependencies": { + "@adyen/adyen-web": "5.51.0", + "@types/node": "^20.11.0", + "typescript": "5.2.2", + "vite": "4.4.9", + "vite-plugin-css-injected-by-js": "3.3.0" + } +} diff --git a/enabler/public/session.js b/enabler/public/session.js new file mode 100644 index 0000000..e511a68 --- /dev/null +++ b/enabler/public/session.js @@ -0,0 +1,57 @@ +const projectKey = 'commercetools-checkout'; + +const fetchAdminToken = async () => { + const myHeaders = new Headers(); + + myHeaders.append('Authorization', `Basic ${btoa(`${__VITE_ADMIN_CLIENT_ID__}:${__VITE_ADMIN_CLIENT_SECRET__}`)}`); + myHeaders.append('Content-Type', 'application/x-www-form-urlencoded'); + + var urlencoded = new URLSearchParams(); + urlencoded.append('grant_type', 'client_credentials'); + urlencoded.append('scope', __VITE_ADMIN_SCOPE__); + + const response = await fetch(`https://auth.${__VITE_REGION__}.commercetools.com/oauth/token`, { + body: urlencoded, + headers: myHeaders, + method: 'POST', + redirect: 'follow', + }); + + const token = await response.json(); + + if (response.status !== 200) { + console.log({ + title: 'Token fetch failed', + message: `Error ${response.status} while fetching token`, + }); + return; + } else { + console.log({ + title: 'Token fetched', + message: `Token fetched: ${token.access_token}`, + }); + } + return token.access_token; +} + +const getSessionId = async() => { + const accessToken = await fetchAdminToken(); + + const sessionMetadata = { + cartId: '', + allowedPaymentMethods: ['card', 'ideal', 'googlepay'], + }; + + const res = await fetch(`http://localhost:3004/api/${projectKey}/sessions`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ + metadata: sessionMetadata, + }), + }); + const data = await res.json(); + return data.id; +} diff --git a/enabler/public/vite.svg b/enabler/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/enabler/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/enabler/src/components/base.ts b/enabler/src/components/base.ts new file mode 100644 index 0000000..00aeb02 --- /dev/null +++ b/enabler/src/components/base.ts @@ -0,0 +1,75 @@ +import Core from '@adyen/adyen-web/dist/types/core/core'; +import { ComponentOptions, PaymentResult } from '../payment-connector/paymentConnector'; +import ApplePay from '@adyen/adyen-web/dist/types/components/ApplePay'; +import GooglePay from '@adyen/adyen-web/dist/types/components/GooglePay'; +import RedirectElement from '@adyen/adyen-web/dist/types/components/Redirect/Redirect'; + +export type ElementOptions = { + adyenPaymentMethod: 'card' | 'ideal' | 'googlepay' | 'dropin' | 'applepay' | string; + isOffsite?: boolean; +}; + +/** + * Base Component + */ +export class BaseComponent { + protected _paymentMethod: string; + protected _offsite: boolean = false; + protected _adyenCheckout: typeof Core; + protected _config: any; + + public component: typeof ApplePay | typeof GooglePay | typeof RedirectElement; + + constructor(opts: ElementOptions, componentOptions: ComponentOptions, adyenCheckout: typeof Core) { + this._paymentMethod = opts.adyenPaymentMethod; + this._offsite = !!opts.isOffsite; + this._adyenCheckout = adyenCheckout; + this.beforePay = componentOptions.beforePay || (() => Promise.resolve()); + this.onError = componentOptions.onError; + this.onComplete = componentOptions.onComplete; + this.component = this._create(); + } + + beforePay: () => Promise; + + protected _create(): typeof ApplePay | typeof GooglePay | typeof RedirectElement { + return this._adyenCheckout.create(this._paymentMethod, this._config); + } + + submit() { + this.beforePay().then(() => { + this.component.submit(); + }); + } + + hasSubmit() { + return true; + } + + isOffsite() { + return this._offsite; + } + + isAvailable() { + return 'isAvailable' in this.component ? this.component.isAvailable() : Promise.resolve(); + } + + isValid() { + return this.component.isValid; + } + + mount(selector: string) { + this + .isAvailable() + .then(() => { + this.component.mount(selector); + }) + .catch((e: unknown) => { + console.log(`${this._paymentMethod } is not available`, e); + }); + } + + onComplete: ((result: PaymentResult) => Promise) | undefined; + + onError: ((error: any) => Promise) | undefined; +} diff --git a/enabler/src/components/payment-methods/applepay.ts b/enabler/src/components/payment-methods/applepay.ts new file mode 100644 index 0000000..e646f13 --- /dev/null +++ b/enabler/src/components/payment-methods/applepay.ts @@ -0,0 +1,31 @@ +import { BaseComponent } from '../base'; +import ApplePay from '@adyen/adyen-web/dist/types/components/ApplePay'; +import Core from '@adyen/adyen-web/dist/types/core'; +import { ComponentOptions } from '../../payment-connector/paymentConnector'; + +/** + * Apple pay component + * + * Configuration options: + * https://docs.adyen.com/payment-methods/apple-pay/web-component/ + */ +export class Applepay extends BaseComponent { + constructor(componentOptions: ComponentOptions, adyenCheckout: typeof Core) { + super({ adyenPaymentMethod: 'applepay' }, componentOptions, adyenCheckout); + } + + protected _create() { + return this._adyenCheckout.create(this._paymentMethod, { + onClick: (resolve, reject) => { + this.beforePay() + .then(() => resolve()) + .catch(() => reject()); + }, + ...this._config, + }) as unknown as typeof ApplePay; + } + + hasSubmit() { + return false; + } +} diff --git a/enabler/src/components/payment-methods/card.ts b/enabler/src/components/payment-methods/card.ts new file mode 100644 index 0000000..ab199ac --- /dev/null +++ b/enabler/src/components/payment-methods/card.ts @@ -0,0 +1,17 @@ +import { BaseComponent } from '../base'; +import { ComponentOptions } from '../../payment-connector/paymentConnector'; +import Core from '@adyen/adyen-web/dist/types/core'; + +/** + * Credit card component + * + * Configuration options: + * https://docs.adyen.com/payment-methods/cards/web-component/ + */ + + +export class Card extends BaseComponent { + constructor(componentOptions: ComponentOptions, adyenCheckout: typeof Core) { + super({ adyenPaymentMethod: 'card' }, componentOptions, adyenCheckout); + } +} diff --git a/enabler/src/components/payment-methods/dropin.ts b/enabler/src/components/payment-methods/dropin.ts new file mode 100644 index 0000000..269f4f9 --- /dev/null +++ b/enabler/src/components/payment-methods/dropin.ts @@ -0,0 +1,18 @@ +import { BaseComponent } from '../base'; +import Core from '@adyen/adyen-web/dist/types/core'; +import { ComponentOptions } from '../../payment-connector/paymentConnector'; + +/** + * Dropin component + * + * Configuration options: + * https://docs.adyen.com/payment-methods/ideal/web-component/ + */ +export class Dropin extends BaseComponent { + constructor(componentOptions: ComponentOptions, adyenCheckout: typeof Core) { + super({ + adyenPaymentMethod: 'dropin', + isOffsite: true, + }, componentOptions, adyenCheckout); + } +} diff --git a/enabler/src/components/payment-methods/googlepay.ts b/enabler/src/components/payment-methods/googlepay.ts new file mode 100644 index 0000000..ae89209 --- /dev/null +++ b/enabler/src/components/payment-methods/googlepay.ts @@ -0,0 +1,33 @@ +import { BaseComponent } from '../base'; +import GooglePay from '@adyen/adyen-web/dist/types/components/GooglePay'; +import Core from '@adyen/adyen-web/dist/types/core'; +import { ComponentOptions } from '../../payment-connector/paymentConnector'; + +/** + * Google pay component + * + * Configuration options: + * https://docs.adyen.com/payment-methods/google-pay/web-component/ + */ +export class Googlepay extends BaseComponent { + constructor(componentOptions: ComponentOptions, adyenCheckout: typeof Core) { + super({ + adyenPaymentMethod: 'googlepay', + }, componentOptions, adyenCheckout); + } + + protected _create() { + return this._adyenCheckout.create(this._paymentMethod, { + onClick: (resolve, reject) => { + this.beforePay() + .then(() => resolve()) + .catch(() => reject()); + }, + ...this._config, + }) as unknown as typeof GooglePay; + } + + hasSubmit() { + return false; + } +} diff --git a/enabler/src/components/payment-methods/ideal.ts b/enabler/src/components/payment-methods/ideal.ts new file mode 100644 index 0000000..da817f6 --- /dev/null +++ b/enabler/src/components/payment-methods/ideal.ts @@ -0,0 +1,18 @@ +import { BaseComponent } from '../base'; +import Core from '@adyen/adyen-web/dist/types/core'; +import { ComponentOptions } from '../../payment-connector/paymentConnector'; + +/** + * Ideal component + * + * Configuration options: + * https://docs.adyen.com/payment-methods/ideal/web-component/ + */ +export class Ideal extends BaseComponent { + constructor(componentOptions: ComponentOptions, adyenCheckout: typeof Core) { + super({ + adyenPaymentMethod: 'ideal', + isOffsite: true, + }, componentOptions, adyenCheckout); + } +} diff --git a/enabler/src/main.ts b/enabler/src/main.ts new file mode 100644 index 0000000..e4fdbe8 --- /dev/null +++ b/enabler/src/main.ts @@ -0,0 +1,4 @@ +import '@adyen/adyen-web/dist/adyen.css'; +import { AdyenPaymentConnector } from './payment-connector/adyenPaymentConnector'; + +export { AdyenPaymentConnector as Connector }; diff --git a/enabler/src/payment-connector/adyenPaymentConnector.ts b/enabler/src/payment-connector/adyenPaymentConnector.ts new file mode 100644 index 0000000..84ee48d --- /dev/null +++ b/enabler/src/payment-connector/adyenPaymentConnector.ts @@ -0,0 +1,162 @@ +import AdyenCheckout from '@adyen/adyen-web'; +import Core from '@adyen/adyen-web/dist/types/core/core'; +import { CoreOptions } from '@adyen/adyen-web/dist/types/core/types'; + +import { ComponentOptions, PaymentConnector, PaymentError, PaymentResult } from './paymentConnector'; +import { Dropin } from '../components/payment-methods/dropin'; +import { Card } from '../components/payment-methods/card'; +import { Applepay } from '../components/payment-methods/applepay'; +import { Ideal } from '../components/payment-methods/ideal'; +import { Googlepay } from '../components/payment-methods/googlepay'; + +declare global { + interface ImportMeta { + env: any; + } +} + +type AdyenConnectorOptions = { + connectorUrl: string; + sessionId: string; + config: Omit; + beforePay?: () => Promise; + onComplete: (result: PaymentResult) => Promise; + onError?: (error: PaymentError) => Promise; +}; + +enum AdyenComponentType { + dropin = "dropin", + card = "card", + applepay = "applepay", + ideal = "ideal", + googlepay = "googlepay", +} + +export class AdyenPaymentConnector implements PaymentConnector { + adyenCheckout: typeof Core; + sessionId: AdyenConnectorOptions['sessionId']; + connectorUrl: AdyenConnectorOptions['connectorUrl']; + config: AdyenConnectorOptions['config']; + beforePay: AdyenConnectorOptions['beforePay']; + onComplete: AdyenConnectorOptions['onComplete']; + onError: AdyenConnectorOptions['onError']; + setupData: Promise<{ adyenCheckout: typeof Core }>; + + private constructor(props: AdyenConnectorOptions) { + this.sessionId = props.sessionId; + this.connectorUrl = props.connectorUrl; + this.config = props.config; + this.beforePay = props.beforePay; + this.onComplete = props.onComplete; + this.onError = props.onError; + this.setupData = AdyenPaymentConnector._Setup(this); + } + + private static _Setup = async (instance: AdyenPaymentConnector): Promise<{ adyenCheckout: typeof Core }> => { + const [sessionResponse, configResponse] = await Promise.all([ + fetch(instance.connectorUrl + '/payment-sessions', { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-Session-Id': instance.sessionId }, + body: JSON.stringify({}), + }), + fetch(instance.connectorUrl + '/config', { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }), + ]); + + const [sessionJson, configJson] = await Promise.all([sessionResponse.json(), configResponse.json()]); + + const { sessionData: data, paymentReference } = sessionJson; + + const adyenCheckout = await AdyenCheckout({ + onPaymentCompleted: (result, component) => { + debugger; + console.info(result, component); + window.location.href = instance.connectorUrl + '/confirm'; + }, + onError: (error, component) => { + console.error(error.name, error.message, error.stack, component); + }, + onSubmit: async (state, component) => { + const reqData = { + ...state.data, + channel: 'Web', + paymentReference, + }; + const response = await fetch(instance.connectorUrl + '/payments', { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-Session-Id': instance.sessionId }, + body: JSON.stringify(reqData), + }); + const data = await response.json(); + console.log('onSubmit', state, component, data) + if (data.action) { + component.handleAction(data.action); + } else { + if (data.resultCode === 'Authorised') { + component.setStatus('success'); + instance.onComplete && instance.onComplete({ isSuccess: true, paymentReference }); + } else { + instance.onComplete && instance.onComplete({ isSuccess: false, paymentReference }); + component.setStatus('error'); + } + } + }, + onAdditionalDetails: async (state, component) => { + console.log('onAdditionalDetails', state, component); + const requestData = { + ...state.data, + paymentReference, + }; + const response = await fetch(instance.connectorUrl + '/payments/confirmations', { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-Session-Id': instance.sessionId }, + body: JSON.stringify(requestData), + }); + const data = await response.json(); + if (data.resultCode === 'Authorised') { + component?.setStatus('success'); + component?.onComplete({ isSuccess: true, paymentReference }); + } else { + component?.onComplete({ isSuccess: false, paymentReference }); + component?.setStatus('error'); + } + }, + analytics: { + enabled: true, + }, + // Above properties can be rewritten externally + + // Spread options passed as parameter + ...instance.config, + + // Below options are always overwritten + environment: configJson.environment, + clientKey: configJson.clientKey, + session: { + id: data.id, + sessionData: data.sessionData, + }, + }); + + return { adyenCheckout }; + } + + async createComponent(type: string, opts: ComponentOptions) { + const { adyenCheckout } = await this.setupData; + switch (type) { + case AdyenComponentType.dropin: + return new Dropin(opts, adyenCheckout); + case AdyenComponentType.card: + return new Card(opts, adyenCheckout); + case AdyenComponentType.applepay: + return new Applepay(opts, adyenCheckout); + case AdyenComponentType.ideal: + return new Ideal(opts, adyenCheckout); + case AdyenComponentType.googlepay: + return new Googlepay(opts, adyenCheckout); + } + throw new Error(`Component type not supported: ${type}. Supported types: ${Object.keys(AdyenComponentType).join(', ')}`); + } +} diff --git a/enabler/src/payment-connector/paymentConnector.ts b/enabler/src/payment-connector/paymentConnector.ts new file mode 100644 index 0000000..6586c7d --- /dev/null +++ b/enabler/src/payment-connector/paymentConnector.ts @@ -0,0 +1,26 @@ +import { BaseComponent } from '../components/base'; + +export type PaymentResult = { + isSuccess: boolean; + paymentReference: string; +}; + +export type PaymentError = { + error: string; + paymentReference?: string; +}; + +export type ComponentOptions = { + id: string; + config: any; + beforePay?: () => Promise; + onComplete: (result: PaymentResult) => Promise; + onError?: (error: PaymentError) => Promise; +}; + +export interface PaymentConnector { + /** + * @throws {Error} + */ + createComponent: (type: string, opts: ComponentOptions) => Promise +} diff --git a/enabler/tsconfig.json b/enabler/tsconfig.json new file mode 100644 index 0000000..e08f422 --- /dev/null +++ b/enabler/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + // "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": [ + "src", "decs.d.ts"] +} diff --git a/enabler/vite.config.ts b/enabler/vite.config.ts new file mode 100644 index 0000000..028d909 --- /dev/null +++ b/enabler/vite.config.ts @@ -0,0 +1,19 @@ +import { resolve } from 'path' +import { defineConfig } from 'vite' +import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js"; + +export default defineConfig({ + plugins: [ + cssInjectedByJsPlugin(), + ], + build: { + lib: { + // Could also be a dictionary or array of multiple entry points + entry: resolve(__dirname, 'src/main.ts'), + name: 'Connector', + formats: ['es','umd'], + // the proper extensions will be added + fileName: 'connector', + }, + }, +})