Compare commits
15 commits
305fcce1ba
...
c61e631172
| Author | SHA1 | Date | |
|---|---|---|---|
| c61e631172 | |||
| 53d71ea183 | |||
| 50f2b67bc4 | |||
| de0a175624 | |||
| b643443b57 | |||
| c08717195a | |||
| 498ae877a1 | |||
| c66cf7faba | |||
| 4b5cadbc6e | |||
| 3e8982f11b | |||
| 0083e94084 | |||
| f0d1b4a3be | |||
| 8027006fde | |||
| 7f6f40cda4 | |||
| 869f8aeac4 |
17 changed files with 278 additions and 187 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
"!oxlint",
|
"!oxlint",
|
||||||
"!prettier",
|
"!prettier",
|
||||||
"!tailwindcss-language-server",
|
"!tailwindcss-language-server",
|
||||||
|
"!tsgo",
|
||||||
"!vtsls",
|
"!vtsls",
|
||||||
"..."
|
"..."
|
||||||
],
|
],
|
||||||
|
|
|
||||||
109
aube-lock.yaml
109
aube-lock.yaml
|
|
@ -13,13 +13,16 @@ importers:
|
||||||
version: 4.0.0-rc.5
|
version: 4.0.0-rc.5
|
||||||
'@sentry/browser':
|
'@sentry/browser':
|
||||||
specifier: ^10.50.0
|
specifier: ^10.50.0
|
||||||
version: 10.50.0
|
version: 10.51.0
|
||||||
a11y-dialog:
|
a11y-dialog:
|
||||||
specifier: ^8.1.5
|
specifier: ^8.1.5
|
||||||
version: 8.1.5
|
version: 8.1.5
|
||||||
effect:
|
effect:
|
||||||
specifier: ^4.0.0-beta.59
|
specifier: ^4.0.0-beta.59
|
||||||
version: 4.0.0-beta.59
|
version: 4.0.0-beta.59
|
||||||
|
html-template-tag:
|
||||||
|
specifier: ^5.0.0
|
||||||
|
version: 5.0.0
|
||||||
lit-html:
|
lit-html:
|
||||||
specifier: ^3.3.2
|
specifier: ^3.3.2
|
||||||
version: 3.3.2
|
version: 3.3.2
|
||||||
|
|
@ -52,8 +55,8 @@ importers:
|
||||||
specifier: ^0.85.1
|
specifier: ^0.85.1
|
||||||
version: 0.85.1
|
version: 0.85.1
|
||||||
'@effect/tsgo':
|
'@effect/tsgo':
|
||||||
specifier: 0.5.1
|
specifier: ^0.5.1
|
||||||
version: 0.5.1
|
version: 0.5.2
|
||||||
'@gcch/configuration-eslint':
|
'@gcch/configuration-eslint':
|
||||||
specifier: git+https://git.gcch.fr/gcch/configuration-eslint#888eb4aa54
|
specifier: git+https://git.gcch.fr/gcch/configuration-eslint#888eb4aa54
|
||||||
version: https://git.gcch.fr/gcch/configuration-eslint#888eb4aa54e5bfd6251566d7469ee99204c19f45
|
version: https://git.gcch.fr/gcch/configuration-eslint#888eb4aa54e5bfd6251566d7469ee99204c19f45
|
||||||
|
|
@ -68,7 +71,7 @@ importers:
|
||||||
version: 1.59.1
|
version: 1.59.1
|
||||||
'@sentry/core':
|
'@sentry/core':
|
||||||
specifier: ^10.50.0
|
specifier: ^10.50.0
|
||||||
version: 10.50.0
|
version: 10.51.0
|
||||||
'@types/bun':
|
'@types/bun':
|
||||||
specifier: ^1.3.13
|
specifier: ^1.3.13
|
||||||
version: 1.3.13
|
version: 1.3.13
|
||||||
|
|
@ -116,7 +119,7 @@ importers:
|
||||||
version: 2.6.1
|
version: 2.6.1
|
||||||
knip:
|
knip:
|
||||||
specifier: ^6.8.0
|
specifier: ^6.8.0
|
||||||
version: 6.8.0
|
version: 6.9.0
|
||||||
lightningcss:
|
lightningcss:
|
||||||
specifier: ^1.32.0
|
specifier: ^1.32.0
|
||||||
version: 1.32.0
|
version: 1.32.0
|
||||||
|
|
@ -740,15 +743,15 @@ packages:
|
||||||
resolution: {integrity: sha512-EXnJjIy6zQ3nUO/MZ+ynWUb8B895KZPotd1++oTs9JjDkplwM7cb6zo8Zq2zU6piwq+KflO7amXbEfj1UMpHkw==}
|
resolution: {integrity: sha512-EXnJjIy6zQ3nUO/MZ+ynWUb8B895KZPotd1++oTs9JjDkplwM7cb6zo8Zq2zU6piwq+KflO7amXbEfj1UMpHkw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
'@effect/tsgo-linux-x64@0.5.1':
|
'@effect/tsgo-linux-x64@0.5.2':
|
||||||
resolution: {integrity: sha512-70dMv3/H+P3KDNWb31qPXJiJh6s78k3+J+QXN8RatKiQYrJw2HhREYL6ToVx9y5WOV7XFvC0eCIIa4/AMwQLTw==}
|
resolution: {integrity: sha512-V6sHIZlKQv693ABb9REX0RzIvzyCbNg2uP5+4MXwetlSxz8pmeAUCpraAQLXBkKlYL5rG9kMIobDFU9A88Nqig==}
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
cpu:
|
cpu:
|
||||||
- x64
|
- x64
|
||||||
|
|
||||||
'@effect/tsgo@0.5.1':
|
'@effect/tsgo@0.5.2':
|
||||||
resolution: {integrity: sha512-INANZ/NK9akOwSQVWpQgSDLjlegrs4gui21nuQsgN7zCjCmj4m/ixUDuVgtW2C0UfqhPWWabyFWCDntu7ryCZQ==}
|
resolution: {integrity: sha512-LEKmx1rwP1j3l9mPW6Bx8VIdGKW+uEvvML89z4xiWnPC+h/uFm3y6FGHULop9Kl09Ybwn2TVuZzVPSZLj+ydmg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
'@es-joy/jsdoccomment@0.86.0':
|
'@es-joy/jsdoccomment@0.86.0':
|
||||||
|
|
@ -969,28 +972,28 @@ packages:
|
||||||
'@rolldown/pluginutils@1.0.0-rc.17':
|
'@rolldown/pluginutils@1.0.0-rc.17':
|
||||||
resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==}
|
resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==}
|
||||||
|
|
||||||
'@sentry-internal/browser-utils@10.50.0':
|
'@sentry-internal/browser-utils@10.51.0':
|
||||||
resolution: {integrity: sha512-42bxyRTxnCmYlWnvz4CxikuQNanw8UNma2WJrtxJ0f1MAJV2GhQGSHDLnA+lvFlmiz6qct3pfen/NXGyOTegTA==}
|
resolution: {integrity: sha512-lNKBS4P7RUvf1niojXQWe9bU3gnBUCbST4Dj0pSiyat1N96cXVyHkeE+uGxowD0RrVWhs+kGHiVX3FcmRWF6sA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@sentry-internal/feedback@10.50.0':
|
'@sentry-internal/feedback@10.51.0':
|
||||||
resolution: {integrity: sha512-0k9XZF0wn86f77mIO2U3gNNyDZooy139CnEanRzHinrN106vVzvBZ6TUEQoHtoO1fqQxr+nWWVrqV/PXUqk47w==}
|
resolution: {integrity: sha512-bCM95bcpphx28e6aU0bwRLxOgwosYsdNzezM1sM0pVOkb0TB3hDFRamramVDK+/Hp1o8qmRxS4c5w/A7YBZGkA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@sentry-internal/replay-canvas@10.50.0':
|
'@sentry-internal/replay-canvas@10.51.0':
|
||||||
resolution: {integrity: sha512-jx6RKBmcJSWdI92qDGS/sBv1w+7Cww879Z/moX7bw7ipHa/Ts3iDcB3rgZwvhmi17U+mvYsbJeL2DXkPo3TjPw==}
|
resolution: {integrity: sha512-8PW1Pp+Yl3lPwYqhBCr5SgkuhDanu9ZLzUqD2bPKL/ElqbM2eDVIWxq4z4ZzePrmZa6IcCjTv6sVQJ7Z4dLyLA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@sentry-internal/replay@10.50.0':
|
'@sentry-internal/replay@10.51.0':
|
||||||
resolution: {integrity: sha512-51FYNfnvVLAWw1rrEWPFfwHuMRb9mkVCFGA4J9/un7SpeGBsQDziGB0Di4fsCxI7+EdSBpfLHPF0csKtCCw0oQ==}
|
resolution: {integrity: sha512-jCpI5HXSwK6ZT2HX70+mDRciAocHzSiDk4DTgvzV69Wvd+Ei5WLgE+d39eaEPsm8lUC0Ydntb5sJIB6uG9D4bw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@sentry/browser@10.50.0':
|
'@sentry/browser@10.51.0':
|
||||||
resolution: {integrity: sha512-1f6rAvET6myiTaSeYqvaaBwvq1LfxqWjAPIoAW/NVC9bPMkeEcuvgDajHrnZMrBeWoJ81NMyoLkyX+iOc7MoFA==}
|
resolution: {integrity: sha512-Zdc0sKfenxUtW/OGhtJ7xHFN44bXR7YqxJ1zBDzlZfW0nTbeTTUZBq9z5NUw6qdS0Vs/i3V4qzAKTbRKWfqSEA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@sentry/core@10.50.0':
|
'@sentry/core@10.51.0':
|
||||||
resolution: {integrity: sha512-J4A+vzUO3adl0TkFCjaN1+4miamrjHiEIYuLHiuu1lmAjq5WIVw32ObvAh4yMwNtxyaEMosTrrh5M6f12XSJFg==}
|
resolution: {integrity: sha512-Y45V/YXvVLEXmOdkbD1oG1gkRWFi9guCEGg3PlIlIpRjAbZUrvLGgjRJIc1E7XpSzmOnWbs5BbUxMv4PDaPj2w==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@sindresorhus/base62@1.0.0':
|
'@sindresorhus/base62@1.0.0':
|
||||||
|
|
@ -1928,13 +1931,22 @@ packages:
|
||||||
hookified@2.2.0:
|
hookified@2.2.0:
|
||||||
resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==}
|
resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==}
|
||||||
|
|
||||||
|
html-element-attributes@3.5.0:
|
||||||
|
resolution: {integrity: sha512-rU2BFhp0kQla9sqPBI46C+zbP6PFOtD7z6XNAJ6as+cGecCDXLx0W3aIs6XdPLmBBG/Fy1meRi/n65Exofz4Qw==}
|
||||||
|
|
||||||
html-entities@2.6.0:
|
html-entities@2.6.0:
|
||||||
resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==}
|
resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==}
|
||||||
|
|
||||||
|
html-es6cape@2.0.2:
|
||||||
|
resolution: {integrity: sha512-utzhH8rq2VABdW1LsPdv5tmxeMNOtP83If0jKCa79xPBgLWfcMvdf9K+EZoxJ5P7KioCxTs6WBnSDWLQHJ2lWA==}
|
||||||
|
|
||||||
html-tags@5.1.0:
|
html-tags@5.1.0:
|
||||||
resolution: {integrity: sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==}
|
resolution: {integrity: sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==}
|
||||||
engines: {node: '>=20.10'}
|
engines: {node: '>=20.10'}
|
||||||
|
|
||||||
|
html-template-tag@5.0.0:
|
||||||
|
resolution: {integrity: sha512-FwF3Fi+v5Dr6ygxqqyJwJWdHteQtDusRXF5ae1syxTKbbVRC8UPtlfIua5KWbgXGneRAc7zNc+Z6x9efFl0W/w==}
|
||||||
|
|
||||||
ignore@5.3.2:
|
ignore@5.3.2:
|
||||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
@ -2164,8 +2176,8 @@ packages:
|
||||||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
knip@6.8.0:
|
knip@6.9.0:
|
||||||
resolution: {integrity: sha512-FaTrNiqc74KTUMI4KZ5CWWxR2oVTm/bEEik16NKz7usiUJXG4+Df2XA2SPAm+mG9bBY22NvBMM4IeBcUZFslyg==}
|
resolution: {integrity: sha512-2GLjxteBwmsSA3Z5sJZpPDaNPBIMnlm4/9Nx4CZadEK7YccJZ2/4kwKgPWhVYEqxhwhD0WO4txWXNGTO/Odkkg==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -3830,11 +3842,11 @@ snapshots:
|
||||||
|
|
||||||
'@effect/language-service@0.85.1': {}
|
'@effect/language-service@0.85.1': {}
|
||||||
|
|
||||||
'@effect/tsgo-linux-x64@0.5.1': {}
|
'@effect/tsgo-linux-x64@0.5.2': {}
|
||||||
|
|
||||||
'@effect/tsgo@0.5.1':
|
'@effect/tsgo@0.5.2':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@effect/tsgo-linux-x64': 0.5.1
|
'@effect/tsgo-linux-x64': 0.5.2
|
||||||
|
|
||||||
'@es-joy/jsdoccomment@0.86.0':
|
'@es-joy/jsdoccomment@0.86.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4007,33 +4019,33 @@ snapshots:
|
||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-rc.17': {}
|
'@rolldown/pluginutils@1.0.0-rc.17': {}
|
||||||
|
|
||||||
'@sentry-internal/browser-utils@10.50.0':
|
'@sentry-internal/browser-utils@10.51.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sentry/core': 10.50.0
|
'@sentry/core': 10.51.0
|
||||||
|
|
||||||
'@sentry-internal/feedback@10.50.0':
|
'@sentry-internal/feedback@10.51.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sentry/core': 10.50.0
|
'@sentry/core': 10.51.0
|
||||||
|
|
||||||
'@sentry-internal/replay-canvas@10.50.0':
|
'@sentry-internal/replay-canvas@10.51.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sentry-internal/replay': 10.50.0
|
'@sentry-internal/replay': 10.51.0
|
||||||
'@sentry/core': 10.50.0
|
'@sentry/core': 10.51.0
|
||||||
|
|
||||||
'@sentry-internal/replay@10.50.0':
|
'@sentry-internal/replay@10.51.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sentry-internal/browser-utils': 10.50.0
|
'@sentry-internal/browser-utils': 10.51.0
|
||||||
'@sentry/core': 10.50.0
|
'@sentry/core': 10.51.0
|
||||||
|
|
||||||
'@sentry/browser@10.50.0':
|
'@sentry/browser@10.51.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sentry-internal/browser-utils': 10.50.0
|
'@sentry-internal/browser-utils': 10.51.0
|
||||||
'@sentry-internal/feedback': 10.50.0
|
'@sentry-internal/feedback': 10.51.0
|
||||||
'@sentry-internal/replay': 10.50.0
|
'@sentry-internal/replay': 10.51.0
|
||||||
'@sentry-internal/replay-canvas': 10.50.0
|
'@sentry-internal/replay-canvas': 10.51.0
|
||||||
'@sentry/core': 10.50.0
|
'@sentry/core': 10.51.0
|
||||||
|
|
||||||
'@sentry/core@10.50.0': {}
|
'@sentry/core@10.51.0': {}
|
||||||
|
|
||||||
'@sindresorhus/base62@1.0.0': {}
|
'@sindresorhus/base62@1.0.0': {}
|
||||||
|
|
||||||
|
|
@ -5102,10 +5114,19 @@ snapshots:
|
||||||
|
|
||||||
hookified@2.2.0: {}
|
hookified@2.2.0: {}
|
||||||
|
|
||||||
|
html-element-attributes@3.5.0: {}
|
||||||
|
|
||||||
html-entities@2.6.0: {}
|
html-entities@2.6.0: {}
|
||||||
|
|
||||||
|
html-es6cape@2.0.2: {}
|
||||||
|
|
||||||
html-tags@5.1.0: {}
|
html-tags@5.1.0: {}
|
||||||
|
|
||||||
|
html-template-tag@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
html-element-attributes: 3.5.0
|
||||||
|
html-es6cape: 2.0.2
|
||||||
|
|
||||||
ignore@5.3.2: {}
|
ignore@5.3.2: {}
|
||||||
|
|
||||||
ignore@7.0.5: {}
|
ignore@7.0.5: {}
|
||||||
|
|
@ -5310,7 +5331,7 @@ snapshots:
|
||||||
|
|
||||||
kind-of@6.0.3: {}
|
kind-of@6.0.3: {}
|
||||||
|
|
||||||
knip@6.8.0:
|
knip@6.9.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
fdir: 6.5.0(picomatch@4.0.4)
|
fdir: 6.5.0(picomatch@4.0.4)
|
||||||
formatly: 0.3.0
|
formatly: 0.3.0
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Roots\WPConfig\Config;
|
use Roots\WPConfig\Config;
|
||||||
|
|
||||||
|
use function base64_encode;
|
||||||
use function Env\env;
|
use function Env\env;
|
||||||
|
|
||||||
Config::define('SAVEQUERIES', true);
|
Config::define('SAVEQUERIES', true);
|
||||||
|
|
@ -25,6 +26,10 @@ Config::define('DISALLOW_FILE_MODS', false);
|
||||||
// WooCommerce
|
// WooCommerce
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
||||||
|
Config::define(
|
||||||
|
'WOOCOMMERCE_API_AUTH_STRING',
|
||||||
|
base64_encode(env('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . env('WOOCOMMERCE_API_CONSUMER_SECRET')),
|
||||||
|
);
|
||||||
|
|
||||||
// Stripe
|
// Stripe
|
||||||
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Roots\WPConfig\Config;
|
use Roots\WPConfig\Config;
|
||||||
|
|
||||||
|
use function base64_encode;
|
||||||
use function Env\env;
|
use function Env\env;
|
||||||
|
|
||||||
Config::define('WP_DEBUG', true);
|
Config::define('WP_DEBUG', true);
|
||||||
|
|
@ -20,6 +21,10 @@ Config::define('DISALLOW_FILE_MODS', false);
|
||||||
|
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
||||||
|
Config::define(
|
||||||
|
'WOOCOMMERCE_API_AUTH_STRING',
|
||||||
|
base64_encode(env('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . env('WOOCOMMERCE_API_CONSUMER_SECRET')),
|
||||||
|
);
|
||||||
|
|
||||||
// Stripe
|
// Stripe
|
||||||
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,13 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Roots\WPConfig\Config;
|
use Roots\WPConfig\Config;
|
||||||
|
|
||||||
|
use function base64_encode;
|
||||||
use function Env\env;
|
use function Env\env;
|
||||||
|
|
||||||
Config::define('DISALLOW_INDEXING', true);
|
Config::define('DISALLOW_INDEXING', true);
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
||||||
|
Config::define(
|
||||||
|
'WOOCOMMERCE_API_AUTH_STRING',
|
||||||
|
base64_encode(env('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . env('WOOCOMMERCE_API_CONSUMER_SECRET')),
|
||||||
|
);
|
||||||
|
|
|
||||||
59
justfile
59
justfile
|
|
@ -1,7 +1,7 @@
|
||||||
set shell := ["fish", "-c"]
|
set shell := ["fish", "-c"]
|
||||||
|
|
||||||
# Recette par défaut.
|
# Recette par défaut.
|
||||||
default: dev
|
default: build-all
|
||||||
|
|
||||||
# Liste toutes les recettes
|
# Liste toutes les recettes
|
||||||
list:
|
list:
|
||||||
|
|
@ -12,7 +12,7 @@ list:
|
||||||
[group('php')]
|
[group('php')]
|
||||||
update:
|
update:
|
||||||
composer update
|
composer update
|
||||||
bun update
|
aube update
|
||||||
|
|
||||||
# Formatte avec treefmt.
|
# Formatte avec treefmt.
|
||||||
[group('qualité')]
|
[group('qualité')]
|
||||||
|
|
@ -22,7 +22,7 @@ treefmt:
|
||||||
# Formatte avec Prettier et treefmt.
|
# Formatte avec Prettier et treefmt.
|
||||||
[group('qualité')]
|
[group('qualité')]
|
||||||
format:
|
format:
|
||||||
bun prettier \
|
aube x prettier \
|
||||||
--cache --cache-location ".cache/prettiercache" \
|
--cache --cache-location ".cache/prettiercache" \
|
||||||
--config "cfg/prettier.config.ts" \
|
--config "cfg/prettier.config.ts" \
|
||||||
--ignore-path "cfg/prettierignore" \
|
--ignore-path "cfg/prettierignore" \
|
||||||
|
|
@ -41,40 +41,40 @@ format:
|
||||||
# Compile, minifie et optimise Sass vers CSS.
|
# Compile, minifie et optimise Sass vers CSS.
|
||||||
[group('css')]
|
[group('css')]
|
||||||
build-css:
|
build-css:
|
||||||
@bun sass \
|
@aube x sass \
|
||||||
--update \
|
--update \
|
||||||
"web/app/themes/haiku-atelier-2024/src/sass":"web/app/themes/haiku-atelier-2024/assets/css"
|
"web/app/themes/haiku-atelier-2024/src/sass":"web/app/themes/haiku-atelier-2024/assets/css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/main.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/main.min.css" \
|
||||||
-- "web/app/themes/haiku-atelier-2024/assets/css/main.css"
|
-- "web/app/themes/haiku-atelier-2024/assets/css/main.css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-panier.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-panier.min.css" \
|
||||||
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-panier.css"
|
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-panier.css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-accueil.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-accueil.min.css" \
|
||||||
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-accueil.css"
|
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-accueil.css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-boutique.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-boutique.min.css" \
|
||||||
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-boutique.css"
|
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-boutique.css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-a-propos.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-a-propos.min.css" \
|
||||||
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-a-propos.css"
|
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-a-propos.css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-modele-simple.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-modele-simple.min.css" \
|
||||||
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-modele-simple.css"
|
-- "web/app/themes/haiku-atelier-2024/assets/css/pages/page-modele-simple.css"
|
||||||
@bun lightningcss \
|
@aube x lightningcss \
|
||||||
--bundle \
|
--bundle \
|
||||||
--minify \
|
--minify \
|
||||||
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-succes-commande.min.css" \
|
--output-file "web/app/themes/haiku-atelier-2024/assets/css/pages/page-succes-commande.min.css" \
|
||||||
|
|
@ -88,7 +88,12 @@ watch-css:
|
||||||
# Compile TypeScript en JavaScript.
|
# Compile TypeScript en JavaScript.
|
||||||
[group('js')]
|
[group('js')]
|
||||||
build-js:
|
build-js:
|
||||||
bun --bun vite build --config "cfg/vite.config.ts"
|
aube x vite build --config "cfg/vite.config.ts"
|
||||||
|
|
||||||
|
# Compile TypeScript à chaque changement de fichier.
|
||||||
|
[group('js')]
|
||||||
|
watch-js:
|
||||||
|
@watchexec -w "web/app/themes/haiku-atelier-2024/src/scripts" -w "web/app/themes/haiku-atelier-2024/src/scripts-effect" -- just build-js treefmt
|
||||||
|
|
||||||
# Compile tout.
|
# Compile tout.
|
||||||
[group('css')]
|
[group('css')]
|
||||||
|
|
@ -98,22 +103,17 @@ build-all:
|
||||||
@just build-js
|
@just build-js
|
||||||
@just format
|
@just format
|
||||||
|
|
||||||
# Compile TypeScript à chaque changement de fichier.
|
|
||||||
[group('js')]
|
|
||||||
watch-js:
|
|
||||||
bun --bun vite build --config "cfg/vite.config.ts" --watch
|
|
||||||
|
|
||||||
# Vérifie le code TypeScript avec des analyseurs statiques.
|
# Vérifie le code TypeScript avec des analyseurs statiques.
|
||||||
[group('js')]
|
[group('js')]
|
||||||
[group('qualité')]
|
[group('qualité')]
|
||||||
lint-js:
|
lint-js:
|
||||||
-bun eslint "web/app/themes/haiku-atelier-2024/src/scripts"
|
-aube x eslint "web/app/themes/haiku-atelier-2024/src/scripts"
|
||||||
bun --bun oxlint \
|
-aube x oxlint \
|
||||||
--config cfg/oxlint.config.ts \
|
--config cfg/oxlint.config.ts \
|
||||||
--format stylish
|
--format stylish
|
||||||
|
|
||||||
fix-js:
|
fix-js:
|
||||||
bun --bun oxlint \
|
aube x oxlint \
|
||||||
--config cfg/oxlint.config.ts \
|
--config cfg/oxlint.config.ts \
|
||||||
--format stylish \
|
--format stylish \
|
||||||
--fix --fix-suggestions --fix-dangerously
|
--fix --fix-suggestions --fix-dangerously
|
||||||
|
|
@ -122,13 +122,13 @@ fix-js:
|
||||||
[group('css')]
|
[group('css')]
|
||||||
[group('qualité')]
|
[group('qualité')]
|
||||||
lint-css:
|
lint-css:
|
||||||
-bun stylelint --config "cfg/stylelint.config.ts" "web/app/themes/haiku-atelier-2024/src/sass/" --fix
|
-aube x stylelint --config "cfg/stylelint.config.ts" "web/app/themes/haiku-atelier-2024/src/sass/" --fix
|
||||||
|
|
||||||
# Vérifie le code TypeScript mort avec knip
|
# Vérifie le code TypeScript mort avec knip
|
||||||
[group('js')]
|
[group('js')]
|
||||||
[group('qualité')]
|
[group('qualité')]
|
||||||
lint-code-mort:
|
lint-code-mort:
|
||||||
-bun knip
|
-aube x knip
|
||||||
|
|
||||||
# Fusionne tous les changements actuels dans le commit précédent et pousse sur le répertoire distant avec Jujetsu.
|
# Fusionne tous les changements actuels dans le commit précédent et pousse sur le répertoire distant avec Jujetsu.
|
||||||
[group('vcs')]
|
[group('vcs')]
|
||||||
|
|
@ -143,19 +143,6 @@ lint-build-format-css:
|
||||||
-just build-css
|
-just build-css
|
||||||
-just format
|
-just format
|
||||||
|
|
||||||
# Lance un navigateur de développement.
|
|
||||||
[group('développement')]
|
|
||||||
dev:
|
|
||||||
@/opt/cromite/chrome --remote-debugging-address=127.0.0.1 --remote-debugging-port=9222 --profile-directory=Guest "https://haikuatelier.gcch.local" &
|
|
||||||
|
|
||||||
# Recharge le premier onglet du navigateur de développement.
|
|
||||||
[group('développement')]
|
|
||||||
reload-tab:
|
|
||||||
#!/usr/bin/fish
|
|
||||||
set -f WSURL (curl -s http://127.1:9222/json | fx '.[0].webSocketDebuggerUrl')
|
|
||||||
set -f REQUEST '{ "id": 2, "method": "Page.reload", "params": { "ignoreCache": true, "scriptToEvaluateOnLoad": "" } }'
|
|
||||||
echo $REQUEST | websocat $WSURL
|
|
||||||
|
|
||||||
# Créé l'image OCI.
|
# Créé l'image OCI.
|
||||||
[group('container')]
|
[group('container')]
|
||||||
build-wordpress-container:
|
build-wordpress-container:
|
||||||
|
|
@ -179,7 +166,7 @@ restart-services:
|
||||||
# Met à jour les conteneurs images des conteneurs.
|
# Met à jour les conteneurs images des conteneurs.
|
||||||
[group('container')]
|
[group('container')]
|
||||||
pull-images:
|
pull-images:
|
||||||
bun "scripts/pull-container-images.ts"
|
bun run "scripts/pull-container-images.ts"
|
||||||
|
|
||||||
export_production_db:
|
export_production_db:
|
||||||
fish "scripts/déclenche-sauvegarde-bdd-production.fish"
|
fish "scripts/déclenche-sauvegarde-bdd-production.fish"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
"@sentry/browser": "^10.50.0",
|
"@sentry/browser": "^10.50.0",
|
||||||
"a11y-dialog": "^8.1.5",
|
"a11y-dialog": "^8.1.5",
|
||||||
"effect": "^4.0.0-beta.59",
|
"effect": "^4.0.0-beta.59",
|
||||||
|
"html-template-tag": "^5.0.0",
|
||||||
"lit-html": "^3.3.2",
|
"lit-html": "^3.3.2",
|
||||||
"purify-ts": "2.1.2",
|
"purify-ts": "2.1.2",
|
||||||
"ts-pattern": "^5.9.0",
|
"ts-pattern": "^5.9.0",
|
||||||
|
|
@ -23,7 +24,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@effect/language-service": "^0.85.1",
|
"@effect/language-service": "^0.85.1",
|
||||||
"@effect/tsgo": "0.5.1",
|
"@effect/tsgo": "^0.5.1",
|
||||||
"@gcch/configuration-eslint": "git+https://git.gcch.fr/gcch/configuration-eslint#888eb4aa54",
|
"@gcch/configuration-eslint": "git+https://git.gcch.fr/gcch/configuration-eslint#888eb4aa54",
|
||||||
"@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#83547fc1ebfd",
|
"@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#83547fc1ebfd",
|
||||||
"@gcch/configuration-prettier": "git+https://git.gcch.fr/gcch/configuration-prettier#d267d6dc5e",
|
"@gcch/configuration-prettier": "git+https://git.gcch.fr/gcch/configuration-prettier#d267d6dc5e",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ use WC_Product;
|
||||||
use function add_action;
|
use function add_action;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
use function assert;
|
use function assert;
|
||||||
use function base64_encode;
|
|
||||||
use function is_string;
|
use function is_string;
|
||||||
use function wc_get_products;
|
use function wc_get_products;
|
||||||
use function wp_create_nonce;
|
use function wp_create_nonce;
|
||||||
|
|
@ -33,12 +32,7 @@ $products = array_map(callback: Product::from_wc_product(...), array: $wc_produc
|
||||||
$context['products'] = $products;
|
$context['products'] = $products;
|
||||||
|
|
||||||
// Injecte les états initiaux des données du Produit sous forme de JSON dans le contexte.
|
// Injecte les états initiaux des données du Produit sous forme de JSON dans le contexte.
|
||||||
$page_states = [
|
$page_states = ['authString' => Config::get('WOOCOMMERCE_API_AUTH_STRING'), 'nonce' => wp_create_nonce('wc_store_api')]
|
||||||
'nonce' => wp_create_nonce('wc_store_api'),
|
|
||||||
'authString' => base64_encode(
|
|
||||||
Config::get('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . Config::get('WOOCOMMERCE_API_CONSUMER_SECRET'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|> wp_json_encode(...);
|
|> wp_json_encode(...);
|
||||||
assert(is_string($page_states));
|
assert(is_string($page_states));
|
||||||
$context['page_states'] = $page_states;
|
$context['page_states'] = $page_states;
|
||||||
|
|
|
||||||
|
|
@ -462,8 +462,8 @@ input[type="checkbox"], input[type="radio"] {
|
||||||
transition: 0.2s background;
|
transition: 0.2s background;
|
||||||
}
|
}
|
||||||
input[type="checkbox"]:checked, input[type="radio"]:checked {
|
input[type="checkbox"]:checked, input[type="radio"]:checked {
|
||||||
color: var(--couleur-blanc);
|
color: var(--couleur-noir);
|
||||||
background: var(--couleur-gris-fonce);
|
background: var(--arriere-plan-points);
|
||||||
}
|
}
|
||||||
input[type="checkbox"]:checked::before, input[type="radio"]:checked::before {
|
input[type="checkbox"]:checked::before, input[type="radio"]:checked::before {
|
||||||
content: "x";
|
content: "x";
|
||||||
|
|
@ -492,7 +492,7 @@ input[type="radio"] + label {
|
||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
input[type="checkbox"]:hover, input[type="radio"]:hover {
|
input[type="checkbox"]:hover, input[type="radio"]:hover {
|
||||||
background: var(--couleur-gris-fonce);
|
background: var(--arriere-plan-points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -131,7 +131,8 @@ function retire_merdes_wc(): void {
|
||||||
*/
|
*/
|
||||||
function genere_balises_img_dans_produit_dans_reponse_rest(
|
function genere_balises_img_dans_produit_dans_reponse_rest(
|
||||||
WP_REST_Response $response,
|
WP_REST_Response $response,
|
||||||
mixed $_product,
|
WC_Data $_product,
|
||||||
|
WP_REST_Request $_request,
|
||||||
): WP_REST_Response {
|
): WP_REST_Response {
|
||||||
// Vérifie que la Réponse a des données
|
// Vérifie que la Réponse a des données
|
||||||
if (empty($response->data)) {
|
if (empty($response->data)) {
|
||||||
|
|
@ -169,37 +170,34 @@ function genere_balises_img_dans_produit_dans_reponse_rest(
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_filter('woocommerce_rest_prepare_product_object', 'genere_balises_img_dans_produit_dans_reponse_rest', 10, 2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO.
|
* TODO.
|
||||||
*/
|
*/
|
||||||
function genere_prix_maximal_produit_variable_dans_reponse_rest(
|
function genere_prix_maximal_produit_variable_dans_reponse_rest(
|
||||||
WP_REST_Response $reponse,
|
WP_REST_Response $response,
|
||||||
WC_Data $_produit,
|
WC_Data $_product,
|
||||||
|
WP_REST_Request $_request,
|
||||||
): WP_REST_Response {
|
): WP_REST_Response {
|
||||||
// Vérifie que la Réponse a des données
|
// Vérifie que la Réponse a des données
|
||||||
if (empty($reponse->data)) {
|
if (empty($response->data)) {
|
||||||
return $reponse;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si le Produit n'est pas Variable, assigner le prix du Produit comme prix maximal
|
// Si le Produit n'est pas Variable, assigner le prix du Produit comme prix maximal
|
||||||
if ('variable' !== $reponse->data['type']) {
|
if ('variable' !== $response->data['type']) {
|
||||||
$reponse->data['prix_maximal'] = $reponse->data['regular_price'];
|
$response->data['prix_maximal'] = $response->data['regular_price'];
|
||||||
|
|
||||||
return $reponse;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigne le prix de la Variation la plus chère dans la Réponse
|
// Assigne le prix de la Variation la plus chère dans la Réponse
|
||||||
$reponse->data['prix_maximal'] = collect($reponse->data['variations'])
|
$response->data['prix_maximal'] = collect($response->data['variations'])
|
||||||
->map(wc_get_product(...))
|
->map(wc_get_product(...))
|
||||||
->map(static fn($p) => $p->get_price())->max();
|
->map(static fn($p) => $p->get_price())->max();
|
||||||
|
|
||||||
return $reponse;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_filter('woocommerce_rest_prepare_product_object', 'genere_prix_maximal_produit_variable_dans_reponse_rest', 10, 2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retire la propagande commerciale de WooCommerce du menu.
|
* Retire la propagande commerciale de WooCommerce du menu.
|
||||||
*/
|
*/
|
||||||
|
|
@ -216,3 +214,8 @@ add_action('init', 'retire_script_galerie');
|
||||||
add_action('template_redirect', 'retire_merdes_wc');
|
add_action('template_redirect', 'retire_merdes_wc');
|
||||||
add_action('wp_enqueue_scripts', 'dequeue_woocommerce_styles_scripts');
|
add_action('wp_enqueue_scripts', 'dequeue_woocommerce_styles_scripts');
|
||||||
add_filter('woocommerce_enqueue_styles', '__return_empty_array');
|
add_filter('woocommerce_enqueue_styles', '__return_empty_array');
|
||||||
|
add_filter('woocommerce_rest_prepare_product_object', 'genere_balises_img_dans_produit_dans_reponse_rest', 10, 3);
|
||||||
|
add_filter('woocommerce_rest_prepare_product_object', 'genere_prix_maximal_produit_variable_dans_reponse_rest', 10, 3);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
// add_filter('woocommerce_store_api_disable_nonce_check', '__return_true');
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,8 @@ input[type="checkbox"], input[type="radio"] {
|
||||||
transition: 0.2s background;
|
transition: 0.2s background;
|
||||||
|
|
||||||
&:checked {
|
&:checked {
|
||||||
color: var(--couleur-blanc);
|
color: var(--couleur-noir);
|
||||||
background: var(--couleur-gris-fonce);
|
background: var(--arriere-plan-points);
|
||||||
|
|
||||||
// TODO: Utiliser un SVG plutôt qu'un « x » ?
|
// TODO: Utiliser un SVG plutôt qu'un « x » ?
|
||||||
&::before {
|
&::before {
|
||||||
|
|
@ -98,7 +98,7 @@ input[type="checkbox"], input[type="radio"] {
|
||||||
|
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--couleur-gris-fonce);
|
background: var(--arriere-plan-points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Console, Context, Effect, Layer, Match, pipe, Schedule, Schema, SchemaIssue } from "effect";
|
import { Console, Context, Effect, Layer, Match, pipe, References, Schedule, Schema, SchemaIssue } from "effect";
|
||||||
import type { SchemaError } from "effect/Schema";
|
import type { SchemaError } from "effect/Schema";
|
||||||
import type {
|
import type {
|
||||||
HttpClientError,
|
HttpClientError,
|
||||||
|
|
@ -11,6 +11,7 @@ import {
|
||||||
} from "effect/unstable/http";
|
} from "effect/unstable/http";
|
||||||
import { HttpClientErrorSchema } from "effect/unstable/http/HttpClientError";
|
import { HttpClientErrorSchema } from "effect/unstable/http/HttpClientError";
|
||||||
import type { CartProduct, GetProducts } from "../schemas/api.ts";
|
import type { CartProduct, GetProducts } from "../schemas/api.ts";
|
||||||
|
import { Product } from "../schemas/api.ts";
|
||||||
import { WooCommerceCart } from "../schemas/cart.ts";
|
import { WooCommerceCart } from "../schemas/cart.ts";
|
||||||
|
|
||||||
/** Le nombre maximal d'essais pour une Requête. */
|
/** Le nombre maximal d'essais pour une Requête. */
|
||||||
|
|
@ -52,7 +53,7 @@ const APIFetchClient = FetchHttpClient.layer.pipe(
|
||||||
Layer.succeed(
|
Layer.succeed(
|
||||||
FetchHttpClient.RequestInit,
|
FetchHttpClient.RequestInit,
|
||||||
{
|
{
|
||||||
credentials: "same-origin",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
@ -135,18 +136,22 @@ class APIClient extends Context.Service<APIClient>()("haikuatelier.fr/APIClient"
|
||||||
);
|
);
|
||||||
|
|
||||||
const GetProducts = Effect.fn("APIClient.GetProducts")(
|
const GetProducts = Effect.fn("APIClient.GetProducts")(
|
||||||
function*(nonce: string, authString: string, queryParams: GetProducts) {
|
function*(nonce: string, queryParams: GetProducts) {
|
||||||
const request = pipe(
|
const request = pipe(
|
||||||
HttpClientRequest.get(`/wp-json/wc/store/products`),
|
HttpClientRequest.get(`/wp-json/wc/v3/products`),
|
||||||
HttpClientRequest.setHeader("Nonce", nonce),
|
HttpClientRequest.setHeader("Nonce", nonce),
|
||||||
HttpClientRequest.bearerToken(authString),
|
// TODO: Utiliser l'environnement
|
||||||
|
HttpClientRequest.basicAuth(
|
||||||
|
"ck_eded693107df0dbc19dab937e0c71325db810a4a",
|
||||||
|
"cs_a68c0f3e711c4a21be51495d09e6fe807649bbfb",
|
||||||
|
),
|
||||||
// Le corps de la Requête a été validée en amont, on peut utiliser Unsafe.
|
// Le corps de la Requête a été validée en amont, on peut utiliser Unsafe.
|
||||||
HttpClientRequest.setUrlParams(queryParams),
|
HttpClientRequest.setUrlParams(queryParams),
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = yield* pipe(
|
const response = yield* pipe(
|
||||||
haikuHTTPClient.execute(request),
|
haikuHTTPClient.execute(request),
|
||||||
Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Unknown)),
|
Effect.flatMap(HttpClientResponse.schemaBodyJson(Schema.Array(Product))),
|
||||||
Effect.mapError(error => matchAPIError(error)),
|
Effect.mapError(error => matchAPIError(error)),
|
||||||
Effect.tapError(error => printErrorAsSuccinctMessage(error)),
|
Effect.tapError(error => printErrorAsSuccinctMessage(error)),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,47 @@ class GetProducts extends Schema.Class<GetProducts>("GetProducts")({
|
||||||
status: ProductStatus,
|
status: ProductStatus,
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
export { CartProduct, GetProducts };
|
class Product extends Schema.Class<Product>("Product")({
|
||||||
|
attributes: Schema.Unknown,
|
||||||
|
brands: Schema.Unknown,
|
||||||
|
// TODO: Pourrait être une énumération.
|
||||||
|
catalog_visibility: Schema.String,
|
||||||
|
categories: Schema.Unknown,
|
||||||
|
description: Schema.String,
|
||||||
|
dimensions: Schema.Unknown,
|
||||||
|
featured: Schema.Boolean,
|
||||||
|
grouped_products: Schema.Unknown,
|
||||||
|
has_options: Schema.Boolean,
|
||||||
|
id: Schema.Int,
|
||||||
|
// NOTE: Non-standard, injecté dans la Réponse.
|
||||||
|
image_repos: Schema.String,
|
||||||
|
// NOTE: Non-standard, injecté dans la Réponse.
|
||||||
|
image_survol: Schema.String,
|
||||||
|
images: Schema.Unknown,
|
||||||
|
low_stock_amount: Schema.Union([Schema.Number, Schema.Null]),
|
||||||
|
menu_order: Schema.Int,
|
||||||
|
meta_data: Schema.Unknown,
|
||||||
|
name: Schema.String,
|
||||||
|
on_sale: Schema.Boolean,
|
||||||
|
parent_id: Schema.Int,
|
||||||
|
permalink: Schema.URLFromString,
|
||||||
|
price: Schema.String,
|
||||||
|
// NOTE: Non-standard, injecté dans la Réponse.
|
||||||
|
prix_maximal: Schema.String,
|
||||||
|
regular_price: Schema.String,
|
||||||
|
sale_price: Schema.String,
|
||||||
|
short_description: Schema.String,
|
||||||
|
sku: Schema.String,
|
||||||
|
slug: Schema.String,
|
||||||
|
sold_individually: Schema.Boolean,
|
||||||
|
stock_quantity: Schema.Union([Schema.Int, Schema.Null]),
|
||||||
|
// TODO: Pourrait être une énumération.
|
||||||
|
stock_status: Schema.String,
|
||||||
|
tags: Schema.Unknown,
|
||||||
|
type: Schema.Literals(["external", "grouped", "simple", "variable"]),
|
||||||
|
variations: Schema.Array(Schema.Int),
|
||||||
|
virtual: Schema.Boolean,
|
||||||
|
weight: Schema.String,
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
export { CartProduct, GetProducts, Product };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
Array as FxArray,
|
||||||
Console,
|
Console,
|
||||||
Context,
|
Context,
|
||||||
Effect,
|
Effect,
|
||||||
|
|
@ -12,55 +13,111 @@ import {
|
||||||
SubscriptionRef,
|
SubscriptionRef,
|
||||||
} from "effect";
|
} from "effect";
|
||||||
import { SchemaError } from "effect/Schema";
|
import { SchemaError } from "effect/Schema";
|
||||||
|
import html from "html-template-tag";
|
||||||
import { APIClient } from "../../scripts-effect/lib/api.ts";
|
import { APIClient } from "../../scripts-effect/lib/api.ts";
|
||||||
import { setLoadingState } from "../../scripts-effect/lib/elements.ts";
|
import { setLoadingState } from "../../scripts-effect/lib/elements.ts";
|
||||||
import { GetProducts } from "../../scripts-effect/schemas/api.ts";
|
import { GetProducts, Product } from "../../scripts-effect/schemas/api.ts";
|
||||||
import { ATTRIBUT_ID_CATEGORIE_PRODUITS } from "../constantes/dom.ts";
|
import { ATTRIBUT_HIDDEN, ATTRIBUT_ID_CATEGORIE_PRODUITS, ATTRIBUT_PAGE } from "../constantes/dom.ts";
|
||||||
import ShopPageElements from "./service-elements.ts";
|
import ShopPageElements from "./service-elements.ts";
|
||||||
import ShopPageMessages from "./service-messages.ts";
|
import ShopPageMessages from "./service-messages.ts";
|
||||||
|
|
||||||
|
/** Le nombre de Produits à afficher par « page ». */
|
||||||
const PRODUCTS_PER_PAGE = 18;
|
const PRODUCTS_PER_PAGE = 18;
|
||||||
|
|
||||||
const PageStatesSchema = Schema.Struct({
|
/** Forme attendue des données injectées dans la page sous forme de JSON. */
|
||||||
authString: Schema.NonEmptyString,
|
class PageStates extends Schema.Opaque<PageStates>()(
|
||||||
nonce: Schema.NonEmptyString,
|
Schema.Struct({
|
||||||
});
|
authString: Schema.NonEmptyString,
|
||||||
|
nonce: Schema.NonEmptyString,
|
||||||
|
}),
|
||||||
|
) {}
|
||||||
|
|
||||||
class InvalidPageStateError extends Schema.TaggedErrorClass<InvalidPageStateError>()("InvalidPageStateError", {
|
/** Représente une Erreur liée à un état de page invalide ou incohérent empêchant la poursuite des interactions/de la navigation. */
|
||||||
cause: Schema.String,
|
class InvalidShopPageStateError
|
||||||
}) {
|
extends Schema.TaggedErrorClass<InvalidShopPageStateError>()("InvalidShopPageStateError", {
|
||||||
static readonly fromSchemaError = (schemaError: SchemaError): InvalidPageStateError =>
|
cause: Schema.String,
|
||||||
new InvalidPageStateError({
|
})
|
||||||
|
{
|
||||||
|
/** Créé une `InvalidShopPageStateError` depuis une `SchemaError` levée suite à une validation. */
|
||||||
|
static readonly fromSchemaError = (schemaError: SchemaError): InvalidShopPageStateError =>
|
||||||
|
new InvalidShopPageStateError({
|
||||||
cause: SchemaIssue.makeFormatterDefault()(schemaError.issue),
|
cause: SchemaIssue.makeFormatterDefault()(schemaError.issue),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShopPageDOM extends Context.Service<ShopPageDOM>()("haikuatelier.fr/Shop/ShopPageDOM", {
|
class ShopPageDOM extends Context.Service<ShopPageDOM>()("haikuatelier.fr/Shop/ShopPageDOM", {
|
||||||
make: Effect.gen(function*() {
|
make: Effect.gen(function*() {
|
||||||
const Elements = yield* ShopPageElements;
|
const { PageStatesRawJson, ProductsGrid, ShowMoreButton } = yield* ShopPageElements;
|
||||||
const Messages = yield* ShopPageMessages;
|
const { ShowMoreButtonText } = yield* ShopPageMessages;
|
||||||
const API = yield* APIClient;
|
const API = yield* APIClient;
|
||||||
|
|
||||||
const PageStates = yield* pipe(
|
const { authString, nonce } = yield* pipe(
|
||||||
Elements.PageStatesRawJson.textContent,
|
PageStatesRawJson.textContent,
|
||||||
(textContent: string) =>
|
(textContent: string) =>
|
||||||
Schema.decodeUnknownEffect(Schema.fromJsonString(PageStatesSchema))(textContent, { errors: "all" }),
|
Schema.decodeUnknownEffect(Schema.fromJsonString(PageStates))(textContent, { errors: "all" }),
|
||||||
Effect.mapError(InvalidPageStateError.fromSchemaError),
|
Effect.mapError(InvalidShopPageStateError.fromSchemaError),
|
||||||
);
|
);
|
||||||
|
|
||||||
/** ID de la Catégorie des Produits de la Page, si la Page courante est une Archive. */
|
/** ID de la Catégorie des Produits de la Page, si la Page courante est une Archive. */
|
||||||
const ProductsCategoryId: Ref.Ref<Option.Option<number>> = yield* Ref.make(
|
const ProductsCategoryId = yield* pipe(
|
||||||
Option.fromNullishOr(Number(Elements.ProductsGrid.getAttribute(ATTRIBUT_ID_CATEGORIE_PRODUITS))),
|
ProductsGrid.getAttribute(ATTRIBUT_ID_CATEGORIE_PRODUITS),
|
||||||
|
Number,
|
||||||
|
Option.fromNullishOr,
|
||||||
|
Ref.make,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: Créer une SubscriptionRef mettant à jour le DOM au changement de valeur.
|
// TODO: Créer une SubscriptionRef mettant à jour le DOM au changement de valeur.
|
||||||
const PageNumber = yield* Ref.make(1);
|
const PageNumber = yield* Ref.make(1);
|
||||||
|
|
||||||
|
const createProductDOM = (product: Product): HTMLElement => {
|
||||||
|
const article = document.createElement("article");
|
||||||
|
article.classList.add("produit");
|
||||||
|
article.innerHTML = html`<figure>
|
||||||
|
<a href="/product/${product.slug}">
|
||||||
|
<picture class="produit__illustration produit__illustration__principale">
|
||||||
|
$${product.image_repos}
|
||||||
|
</picture>
|
||||||
|
|
||||||
|
<picture class="produit__illustration produit__illustration__survol">
|
||||||
|
$${product.image_survol}
|
||||||
|
</picture>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<figcaption class="produit__textuel">
|
||||||
|
<h3 class="produit__textuel__titre">
|
||||||
|
<a href="$${product.permalink.toString()}">${product.name}</a>
|
||||||
|
</h3>
|
||||||
|
<p class="produit__textuel__prix">
|
||||||
|
${product.prix_maximal}€
|
||||||
|
</p>
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
`;
|
||||||
|
return article;
|
||||||
|
};
|
||||||
|
const createNewPageDOM = (products: ReadonlyArray<Product>) => {
|
||||||
|
const fragment: DocumentFragment = document.createDocumentFragment();
|
||||||
|
|
||||||
|
// Ajoute le HTML des cartes des Produits au fragment.
|
||||||
|
pipe(
|
||||||
|
FxArray.take(products, PRODUCTS_PER_PAGE),
|
||||||
|
FxArray.forEach(product => {
|
||||||
|
const productHTML = createProductDOM(product);
|
||||||
|
fragment.append(productHTML);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
};
|
||||||
|
|
||||||
const onMoreProductedWantedHandler = Effect.fn("onMoreProductedWantedHandler")(function*() {
|
const onMoreProductedWantedHandler = Effect.fn("onMoreProductedWantedHandler")(function*() {
|
||||||
yield* Console.debug("onMoreProductedWantedHandler");
|
yield* Console.debug("onMoreProductedWantedHandler");
|
||||||
|
|
||||||
const newPageNumber = yield* Ref.getAndUpdate(PageNumber, pageNumber => pageNumber + 1);
|
/** Le numéro de page souhaitée. */
|
||||||
|
const newPageNumber = yield* Ref.updateAndGet(PageNumber, pageNumber => pageNumber + 1);
|
||||||
|
/** L'ID de la Catégorie de Produits affichée dans la page si elle existe. */
|
||||||
const categoryId = pipe(yield* Ref.get(ProductsCategoryId), Option.getOrUndefined);
|
const categoryId = pipe(yield* Ref.get(ProductsCategoryId), Option.getOrUndefined);
|
||||||
|
|
||||||
const requestBody = yield* GetProducts.makeEffect({
|
const requestBody = yield* GetProducts.makeEffect({
|
||||||
page: newPageNumber,
|
page: newPageNumber,
|
||||||
per_page: PRODUCTS_PER_PAGE,
|
per_page: PRODUCTS_PER_PAGE,
|
||||||
|
|
@ -69,63 +126,27 @@ class ShopPageDOM extends Context.Service<ShopPageDOM>()("haikuatelier.fr/Shop/S
|
||||||
});
|
});
|
||||||
|
|
||||||
// Désactive les interactions et affiche un texte de chargement le temps de la requête.
|
// Désactive les interactions et affiche un texte de chargement le temps de la requête.
|
||||||
yield* setLoadingState(Elements.ShowMoreButton, true);
|
yield* setLoadingState(ShowMoreButton, true);
|
||||||
yield* SubscriptionRef.set(Messages.ShowMoreButtonText, "Getting Products...");
|
yield* SubscriptionRef.set(ShowMoreButtonText, "Getting Products...");
|
||||||
|
|
||||||
const newProducts = yield* API.GetProducts(PageStates.nonce, PageStates.authString, requestBody);
|
const newProducts = yield* API.GetProducts(nonce, requestBody);
|
||||||
yield* Console.debug("onMoreProductedWantedHandler", newProducts);
|
yield* Console.debug("onMoreProductedWantedHandler", newProducts);
|
||||||
|
|
||||||
// Rétablis le texte du Bouton et réactive les interactions.
|
// Rétablis le texte du Bouton et réactive les interactions.
|
||||||
yield* SubscriptionRef.set(Messages.ShowMoreButtonText, "Show more");
|
yield* SubscriptionRef.set(ShowMoreButtonText, "Show more");
|
||||||
yield* setLoadingState(Elements.ShowMoreButton, false);
|
yield* setLoadingState(ShowMoreButton, false);
|
||||||
|
|
||||||
// Cache le bouton s'il y a moins de PRODUCTS_PER_PAGE Produits disponibles (que l'on est à la dernière page)
|
// Cache le bouton s'il y a moins de Produits disponibles que PRODUCTS_PER_PAGE (que l'on est donc à la dernière page).
|
||||||
if (donnees.length < PRODUCTS_PER_PAGE) {
|
ShowMoreButton.toggleAttribute(ATTRIBUT_HIDDEN, newProducts.length < PRODUCTS_PER_PAGE);
|
||||||
E.BOUTON_PLUS_DE_PRODUITS.toggleAttribute(ATTRIBUT_HIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Créé un DocumentFragment qui recevra tous les nouveaux Produits
|
// Ajoute les nouveaux Produits dans le DOM.
|
||||||
const fragment: DocumentFragment = document.createDocumentFragment();
|
ProductsGrid.append(fragment);
|
||||||
|
ProductsGrid.setAttribute(ATTRIBUT_PAGE, String(newPageNumber));
|
||||||
// Créé les Éléments <article> à insérer
|
|
||||||
for (const produit of donnees.slice(0, PRODUCTS_PER_PAGE)) {
|
|
||||||
pipe(
|
|
||||||
html`
|
|
||||||
<article class="produit">
|
|
||||||
<figure>
|
|
||||||
<a href="/product/${produit.slug}">
|
|
||||||
<picture class="produit__illustration produit__illustration__principale">
|
|
||||||
${produit.image_repos ?? ""}
|
|
||||||
</picture>
|
|
||||||
|
|
||||||
<picture class="produit__illustration produit__illustration__survol">
|
|
||||||
${produit.image_survol ?? ""}
|
|
||||||
</picture>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<figcaption class="produit__textuel">
|
|
||||||
<h3 class="produit__textuel__titre">
|
|
||||||
<a href="${produit.permalink}">${produit.name}</a>
|
|
||||||
</h3>
|
|
||||||
<p class="produit__textuel__prix">
|
|
||||||
${produit.prix_maximal}€
|
|
||||||
</p>
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
</article>
|
|
||||||
`,
|
|
||||||
tap(article => fragment.append(article)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ajoute les nouveaux Produits dans le DOM
|
|
||||||
E.GRILLE_PRODUITS.append(fragment);
|
|
||||||
E.GRILLE_PRODUITS.setAttribute(ATTRIBUT_PAGE, String(nouveauNumeroPage));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const initLoadMoreProductsOnButtonClick = Effect.fn("initLoadMoreProductsOnButtonClick")(function*() {
|
const initLoadMoreProductsOnButtonClick = Effect.fn("initLoadMoreProductsOnButtonClick")(function*() {
|
||||||
return yield* pipe(
|
return yield* pipe(
|
||||||
Stream.fromEventListener(Elements.ShowMoreButton, "click"),
|
Stream.fromEventListener(ShowMoreButton, "click"),
|
||||||
Stream.tap(onMoreProductedWantedHandler),
|
Stream.tap(onMoreProductedWantedHandler),
|
||||||
Stream.runDrain,
|
Stream.runDrain,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ class ShopPageMessages extends Context.Service<ShopPageMessages>()("haikuatelier
|
||||||
make: Effect.gen(function*() {
|
make: Effect.gen(function*() {
|
||||||
const { ShowMoreButton } = yield* ShopPageElements;
|
const { ShowMoreButton } = yield* ShopPageElements;
|
||||||
|
|
||||||
const ShowMoreButtonText = yield* SubscriptionRef.make("Add to cart");
|
const ShowMoreButtonText = yield* SubscriptionRef.make("Show more");
|
||||||
// Const ShowMoreErrorText = yield* SubscriptionRef.make<Option.Option<string>>(Option.none());
|
// Const ShowMoreErrorText = yield* SubscriptionRef.make<Option.Option<string>>(Option.none());
|
||||||
|
|
||||||
const initShowMoreButtonUpdates = Effect.fn("initShowMoreButtonUpdates")(function*() {
|
const initShowMoreButtonUpdates = Effect.fn("initShowMoreButtonUpdates")(function*() {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* Scripts pour les fonctionnalités de la page Boutique.
|
* Scripts pour les fonctionnalités de la page Boutique.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Effect } from "effect";
|
import { Console, Effect } from "effect";
|
||||||
import ShopPageRuntime from "./page-boutique/runtime.ts";
|
import ShopPageRuntime from "./page-boutique/runtime.ts";
|
||||||
import ShopPageDOM from "./page-boutique/service-dom.ts";
|
import ShopPageDOM from "./page-boutique/service-dom.ts";
|
||||||
import ShopPageElements from "./page-boutique/service-elements.ts";
|
import ShopPageElements from "./page-boutique/service-elements.ts";
|
||||||
|
|
@ -18,7 +18,7 @@ document.addEventListener("DOMContentLoaded", (): void => {
|
||||||
|
|
||||||
yield* Effect.all([DOM.initLoadMoreProductsOnButtonClick(), Messages.initShowMoreButtonUpdates()], {
|
yield* Effect.all([DOM.initLoadMoreProductsOnButtonClick(), Messages.initShowMoreButtonUpdates()], {
|
||||||
concurrency: "unbounded",
|
concurrency: "unbounded",
|
||||||
});
|
}).pipe(Effect.tapError(Console.error));
|
||||||
|
|
||||||
console.debug(Elements.ProductsGrid);
|
console.debug(Elements.ProductsGrid);
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue