2024-10-07

This commit is contained in:
gcch 2024-10-07 15:58:56 +02:00
commit 03d86b3a64
41 changed files with 610 additions and 418 deletions

View file

@ -3,11 +3,11 @@ repository: s2b/ddev-vite-sidecar
version: 1.1.0
install_date: "2024-10-02T19:02:43+02:00"
project_files:
- commands/web/vite
- apache/vite.conf
- nginx_full/vite.conf
- vite/vite-server-not-running.html
- config.vite.yaml
- web-build/Dockerfile.vite
- commands/web/vite
- apache/vite.conf
- nginx_full/vite.conf
- vite/vite-server-not-running.html
- config.vite.yaml
- web-build/Dockerfile.vite
global_files: []
removal_actions: []

View file

@ -1,49 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<head>
<!-- #ddev-generated -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vite not running</title>
<style>
html, body {
height: 100%;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
}
html, body {
height: 100%;
margin: 0;
font-family:
-apple-system,
BlinkMacSystemFont,
avenir next,
avenir,
segoe ui,
helvetica neue,
helvetica,
Cantarell,
Ubuntu,
roboto,
noto,
arial,
sans-serif;
}
body {
background: #DDD;
display: grid;
align-items: center;
justify-items: center;
}
body {
background: #ddd;
display: grid;
align-items: center;
justify-items: center;
}
h1 {
margin-top: 0;
}
h1 {
margin-top: 0;
}
main {
max-width: 36rem;
background: #FFF;
padding: 1.5rem;
border: 1px #999 solid;
}
main {
max-width: 36rem;
background: #fff;
padding: 1.5rem;
border: 1px #999 solid;
}
code {
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
font-size: 180%;
color: #9499ff;
font-weight: bold;
}
code {
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
font-size: 180%;
color: #9499ff;
font-weight: bold;
}
</style>
</head>
<body>
</head>
<body>
<main>
<h1>vite not running</h1>
<p>Apparently, you tried to access resources from the vite development server. However, the server is currently not running.</p>
<p>You can start the server by running the following command in your terminal:</p>
<code>ddev vite</code>
<h1>vite not running</h1>
<p>
Apparently, you tried to access resources from the vite development server. However, the server is currently not
running.
</p>
<p>You can start the server by running the following command in your terminal:</p>
<code>ddev vite</code>
</main>
</body>
</body>
</html>

View file

@ -8,6 +8,7 @@
"defini",
"deplie",
"Ecoute",
"emet",
"ENTETE",
"etats",
"ETATS",

View file

@ -37,6 +37,11 @@ export default tseslint.config(
"ignoreArrowShorthand": true,
"ignoreVoidOperator": false,
}],
/* Cette règle empêche l'usage de génériques précisant les types de retour de fonctions. */
"@typescript-eslint/no-unnecessary-type-parameters": "off",
"@typescript-eslint/no-unused-expressions": ["error", {
"allowTernary": true,
}],
/* Cette règle est doublon avec les règles noUnused* de TypeScript. */
"@typescript-eslint/no-unused-vars": "off",
/* Cette règle empêche de lever des erreurs génériques (p.ex. `E extends Error`). */

View file

@ -9,21 +9,29 @@
"name": "chunk-7BKSRZNG",
"integrity": "sha512-anrnk3Aeg5QzrGrQSN13d9vtJoAghYnQnliQ2g5EedXKkd7Soljn6qW7LPbuKU5EjwikIGr+seO7qfNLu1iY7w=="
},
"_chunk-RU7WR4KH.D5j7HXCF.js": {
"file": "chunk-RU7WR4KH.D5j7HXCF.js",
"name": "chunk-RU7WR4KH",
"imports": [
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts"
],
"integrity": "sha512-BrOGLIo6Hd2bL9MbCd5YcISzpVZjfEBeq9PVKcKIWza4ycU1qmwPIyE2D/z4wLgps5iNAtHsGUI0JE0FzkdqCw=="
},
"_exports.DNZBdkMD.js": {
"file": "exports.DNZBdkMD.js",
"name": "exports",
"integrity": "sha512-aYGtBzQ/fess8aZnfmsI/TdNNom1Dd1BfM2g/AXaeZdTjhzD2Ul5kLl1RuXv1nM1/k2HWy0eFaasBtiz5l8YHA=="
},
"_index.CeK6pfoJ.js": {
"file": "index.CeK6pfoJ.js",
"name": "index",
"integrity": "sha512-cxTw0sKKut2H95JwMgiKgEVLyZ0QswK/HydKTapcqcs3w6xHIHNUpYBLdRzEYdeRfHKUsA0kvPNBXBk/QeazjQ=="
},
"_index.DD7qm8S6.js": {
"file": "index.DD7qm8S6.js",
"name": "index",
"integrity": "sha512-dZ1dcfuB5XOKbN4ien9D6aGQ6O9ghxM4BXEuBnrAX4/oG2pkzPt+/S1hXGkkJk7HNcq+w6Eul+vn19rj+sjA1w=="
},
"_index.y02cst4L.js": {
"file": "index.y02cst4L.js",
"name": "index",
"integrity": "sha512-o9wA9YQlHsY4C1xPeqh8EkKHXWmS+2vT32YYJ1FXthFt862OI7Qwr5Y0HGkf3C81sjgRcARaurFKSqeKNHVoFg=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/api.ts": {
"file": "api2.js",
"name": "api",
@ -43,7 +51,7 @@
"name": "dom",
"src": "web/app/themes/haiku-atelier-2024/src/scripts/constantes/dom.ts",
"isEntry": true,
"integrity": "sha512-L8mxbF9f2n5cYtdQQyo4B3gwIRnoPtiC2KFSWpKcot7YgSQW6JR96pSGhOmjHbr579//9UwtjoCi0ZCAZi3VwQ=="
"integrity": "sha512-g5Of6R9ri+kdLCyHR4tX7pb/JnEhcnJfPqRLLRvs8lHGeRHRzDI4ekFgPR7+7MnRWPxbYlSnXmjq7SM+SV4QZg=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/messages.ts": {
"file": "messages3.js",
@ -96,7 +104,7 @@
"imports": [
"_exports.DNZBdkMD.js"
],
"integrity": "sha512-tVMlAurSgVwpsKmwm4ec8QM+faI+bs+YFbP+g3qaIQozCOCuYOuwboygxSz1ajQDrI4V+ECFoqa77jOnQIbptQ=="
"integrity": "sha512-ykMBUQPjclsVL4qWGXkiq+tqGW52l1MSRhIWNvdsYtEzvzi1Re3NjJGIpY7a+lWjRN16X+/4aJv51RseE5QJLA=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/lib/gardes.ts": {
"file": "gardes.js",
@ -123,15 +131,15 @@
"isEntry": true,
"imports": [
"_index.DD7qm8S6.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/messages.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/messages.ts",
"_Either.wHNxn7Os.js",
"_exports.DNZBdkMD.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/messages.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/cart.ts"
],
"integrity": "sha512-O8W53Nt7AVJywhODKFp5YKrDFfYwYE0W71UMGRCDZoq4g6JQUhFyu5FwKjjE2RfNNH8LVVeCuoSPxjBBwgLrTg=="
"integrity": "sha512-fbxkHJ+dD78V3jJxNI22q9vRA/87xL/1csLbOPh/vGSeFSqL868iQllvYrrvBYYS8BHU/zuFie8FKU8ViOI4pg=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/lib/reseau.ts": {
"file": "reseau.js",
@ -139,9 +147,15 @@
"src": "web/app/themes/haiku-atelier-2024/src/scripts/lib/reseau.ts",
"isEntry": true,
"imports": [
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/api.ts"
"_chunk-7BKSRZNG.C39W3Wne.js",
"_index.CeK6pfoJ.js",
"_index.DD7qm8S6.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/api.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/erreurs.ts",
"_exports.DNZBdkMD.js"
],
"integrity": "sha512-nMhRswO45OQHAsc0QtgVDlXpv5ytRhb4VjVl7K6mxz5cteVMMqmNu6Jx2jYXRFQxYKXhGxMWjLTLczPzhpDlJQ=="
"integrity": "sha512-rYJVfAjK4yjdel1Hj/dSSjrMmmohoh3ZgxV8axshZRzWCRx+kHXdlSdbCQkjkVf2gBogyxR2XdPA1FeggbBRwA=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart-add-item.ts": {
"file": "cart-add-item.js",
@ -182,7 +196,7 @@
"_index.DD7qm8S6.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/cart.ts"
],
"integrity": "sha512-Plqlr1vvCpeqBp5n4nLaXI37IkKx3XoW0Pni1XGFYfSu7vbfAkeFMcOQbzETBGWsrEil7QF7kpK505UInNQ3Pg=="
"integrity": "sha512-MQsu03fXIuryciKJ8JleDihgKPWeBCpwnlfe8gd9eInUVHNhFKQ0mm9d+y4YzqSgOqzyJBWPJPDuNE/rgh+oFw=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/erreurs.ts": {
"file": "erreurs2.js",
@ -205,7 +219,7 @@
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/cart.ts"
],
"integrity": "sha512-3VF2Yi9bJU3Gm/NN3L+KkrsEP0fawRw+j1OmEC6/WTy39q6HRP12HEa7Z1F9ny0t12YIWOT/2vfnSXfBhmRvUw=="
"integrity": "sha512-yH1YmpJ/akKOxNm2jJ8St8ogWDg0BzW6PHFoxnJUKPFUS9s8Po5n1d7mta5H36RW+YPWi5HBKwwPwpHKTi5x2g=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts": {
"file": "utils.js",
@ -214,12 +228,12 @@
"isEntry": true,
"imports": [
"web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts",
"_chunk-7BKSRZNG.C39W3Wne.js",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
"_exports.DNZBdkMD.js",
"_Either.wHNxn7Os.js"
"_Either.wHNxn7Os.js",
"_chunk-7BKSRZNG.C39W3Wne.js",
"_exports.DNZBdkMD.js"
],
"integrity": "sha512-i4uspvXHfW//gmEw3Z5PRVKHA8LpzBiaiK2djkgxH71LCo0YHlxROvKEjES66FzivjWCk3DOT9XX7HMgyrqctg=="
"integrity": "sha512-Esz8GswJlts6K+9frxi4+X4VLqIIUg32rBo3uHKZemX6I4B8nwV/lQfoEUmVTfv+XriXpDBB4MAcH2FoS5LHuA=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/scripts-bouton-panier.ts": {
"file": "scripts-bouton-panier.js",
@ -241,7 +255,7 @@
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/cart.ts"
],
"integrity": "sha512-nPmgcq2Zg6mj3/8wEV7JYjpoGRyD0PDatWRghJaFhlYL3qaZB2T6YuRTyJFfnMxncTCrCveyvPNdW3m8pVKnSQ=="
"integrity": "sha512-jtkypPcc0juXoJRSdseHumcbNvkrCPOckgzxhtvo5R40QKZU5yrMZw7Zx7s98AgRF8tu9MOX2Ffc/3m+zVPrxQ=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-panier.ts": {
"file": "scripts-page-panier.js",
@ -249,7 +263,8 @@
"src": "web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-panier.ts",
"isEntry": true,
"imports": [
"_index.y02cst4L.js",
"_chunk-RU7WR4KH.D5j7HXCF.js",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts",
"_chunk-7BKSRZNG.C39W3Wne.js",
"_index.DD7qm8S6.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/api.ts",
@ -263,14 +278,14 @@
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart-remove-item.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart-update-item.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/erreurs.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts",
"_Either.wHNxn7Os.js",
"_exports.DNZBdkMD.js",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/messages.ts",
"_index.CeK6pfoJ.js",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/erreurs.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/cart.ts"
],
"integrity": "sha512-2q6FNf/gPxKEeYnS/ETOUMUiFopYflti5OCPgsjba1riIg+PxS6rW99ja00nISXwsHdDuvLum4gYXkqd6yX3fg=="
"integrity": "sha512-1b76Uu/mQmAiuYRm8ABDYTWd1OBkR/ndy+AI6QXv2etYAt9yM6n2g7pJQrqXa5Jf+aWNUaYFffyBsec6R9M48w=="
},
"web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts": {
"file": "scripts-page-produit.js",
@ -278,23 +293,26 @@
"src": "web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts",
"isEntry": true,
"imports": [
"_index.y02cst4L.js",
"_chunk-RU7WR4KH.D5j7HXCF.js",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts",
"_chunk-7BKSRZNG.C39W3Wne.js",
"_index.CeK6pfoJ.js",
"_index.DD7qm8S6.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/api.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/dom.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/messages.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/dom.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/gardes.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/messages.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart-add-item.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/cart.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/erreurs.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts",
"_Either.wHNxn7Os.js",
"_exports.DNZBdkMD.js",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/messages.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/messages.ts",
"web/app/themes/haiku-atelier-2024/src/scripts/constantes/cart.ts"
],
"integrity": "sha512-bv6BRll5MJeydJ8deu0p1NjcwGZTRhDeKDgbZSnb3YLSk96UZ3uDHjPEb9CjTLRPywQWTnZoZ85U04QaUdji3g=="
"integrity": "sha512-yg9MYQDB+arRyL7GeJr/W0NFNSvYVsRor8WQzEeNAM6etWm+QqqNr1n3BfqG0o7eOZrx2ak6He1SaWpflLjtxw=="
}
}

View file

@ -36,6 +36,26 @@ const WCStoreCartItemSchema = object({
"type": string(),
"variation": array(unknown())
});
const WCStoreCartTotalsSchema = object({
"currency_code": string(),
"currency_decimal_separator": string(),
"currency_minor_unit": number(),
"currency_prefix": string(),
"currency_suffix": string(),
"currency_symbol": string(),
"currency_thousand_separator": string(),
"tax_lines": array(unknown()),
"total_discount": string(),
"total_discount_tax": string(),
"total_fees": string(),
"total_fees_tax": string(),
"total_items": string(),
"total_items_tax": string(),
"total_price": string(),
"total_shipping": union([string(), null_()]),
"total_shipping_tax": union([string(), null_()]),
"total_tax": string()
});
const WCStoreCartSchema = object({
billing_address: unknown(),
coupons: unknown(),
@ -53,7 +73,7 @@ const WCStoreCartSchema = object({
payment_requirements: unknown(),
shipping_address: unknown(),
shipping_rates: unknown(),
totals: unknown()
totals: WCStoreCartTotalsSchema
});
export {
WCStoreCartSchema as W,

View file

@ -1 +1 @@
{"version":3,"file":"cart.js","sources":["../../src/scripts/lib/schemas/cart.ts"],"sourcesContent":["import * as v from \"valibot\";\n\nimport { CATALOG_VISIBILITIES } from \"../../constantes/cart.ts\";\n\nexport const WCStoreCartItemTotalsSchema = v.object({\n \"currency_code\": v.string(),\n \"currency_decimal_separator\": v.string(),\n \"currency_minor_unit\": v.number(),\n \"currency_prefix\": v.string(),\n \"currency_suffix\": v.string(),\n \"currency_symbol\": v.string(),\n \"currency_thousand_separator\": v.string(),\n \"line_subtotal\": v.string(),\n \"line_subtotal_tax\": v.string(),\n \"line_total\": v.string(),\n \"line_total_tax\": v.string(),\n});\n\nexport const WCStoreCartItemSchema = v.object({\n \"backorders_allowed\": v.boolean(),\n \"catalog_visibility\": v.enum(CATALOG_VISIBILITIES),\n \"description\": v.string(),\n \"extensions\": v.unknown(),\n \"id\": v.number(),\n \"images\": v.array(v.unknown()),\n \"item_data\": v.array(v.unknown()),\n \"key\": v.string(),\n \"low_stock_remaining\": v.union([v.null()]),\n \"name\": v.string(),\n \"permalink\": v.pipe(v.string(), v.url()),\n \"prices\": v.unknown(),\n \"quantity\": v.number(),\n \"quantity_limits\": v.unknown(),\n \"short_description\": v.string(),\n \"show_backorder_badge\": v.boolean(),\n \"sku\": v.string(),\n \"sold_individually\": v.boolean(),\n \"totals\": WCStoreCartItemTotalsSchema,\n \"type\": v.string(),\n \"variation\": v.array(v.unknown()),\n});\n\nexport const WCStoreCartSchema = v.object({\n billing_address: v.unknown(),\n coupons: v.unknown(),\n cross_sells: v.unknown(),\n errors: v.unknown(),\n extensions: v.unknown(),\n fees: v.unknown(),\n has_calculated_shipping: v.unknown(),\n items: v.array(WCStoreCartItemSchema),\n items_count: v.pipe(v.number(), v.integer()),\n items_weight: v.unknown(),\n needs_payment: v.unknown(),\n needs_shipping: v.unknown(),\n payment_methods: v.unknown(),\n payment_requirements: v.unknown(),\n shipping_address: v.unknown(),\n shipping_rates: v.unknown(),\n totals: v.unknown(),\n});\n"],"names":["v.object","v.string","v.number","v.boolean","v.enum","v.unknown","v.array","v.union","v.null","v.pipe","v.url","v.integer"],"mappings":";;AAIa,MAAA,8BAA8BA,OAAS;AAAA,EAClD,iBAAiBC,OAAS;AAAA,EAC1B,8BAA8BA,OAAS;AAAA,EACvC,uBAAuBC,OAAS;AAAA,EAChC,mBAAmBD,OAAS;AAAA,EAC5B,mBAAmBA,OAAS;AAAA,EAC5B,mBAAmBA,OAAS;AAAA,EAC5B,+BAA+BA,OAAS;AAAA,EACxC,iBAAiBA,OAAS;AAAA,EAC1B,qBAAqBA,OAAS;AAAA,EAC9B,cAAcA,OAAS;AAAA,EACvB,kBAAkBA,OAAS;AAC7B,CAAC;AAEY,MAAA,wBAAwBD,OAAS;AAAA,EAC5C,sBAAsBG,QAAU;AAAA,EAChC,sBAAsBC,MAAO,oBAAoB;AAAA,EACjD,eAAeH,OAAS;AAAA,EACxB,cAAcI,QAAU;AAAA,EACxB,MAAMH,OAAS;AAAA,EACf,UAAUI,MAAQD,SAAW;AAAA,EAC7B,aAAaC,MAAQD,SAAW;AAAA,EAChC,OAAOJ,OAAS;AAAA,EAChB,uBAAuBM,MAAQ,CAACC,MAAE,CAAM,CAAC;AAAA,EACzC,QAAQP,OAAS;AAAA,EACjB,aAAaQ,KAAOR,OAAY,GAAAS,KAAO;AAAA,EACvC,UAAUL,QAAU;AAAA,EACpB,YAAYH,OAAS;AAAA,EACrB,mBAAmBG,QAAU;AAAA,EAC7B,qBAAqBJ,OAAS;AAAA,EAC9B,wBAAwBE,QAAU;AAAA,EAClC,OAAOF,OAAS;AAAA,EAChB,qBAAqBE,QAAU;AAAA,EAC/B,UAAU;AAAA,EACV,QAAQF,OAAS;AAAA,EACjB,aAAaK,MAAQD,SAAW;AAClC,CAAC;AAEY,MAAA,oBAAoBL,OAAS;AAAA,EACxC,iBAAiBK,QAAU;AAAA,EAC3B,SAASA,QAAU;AAAA,EACnB,aAAaA,QAAU;AAAA,EACvB,QAAQA,QAAU;AAAA,EAClB,YAAYA,QAAU;AAAA,EACtB,MAAMA,QAAU;AAAA,EAChB,yBAAyBA,QAAU;AAAA,EACnC,OAAOC,MAAQ,qBAAqB;AAAA,EACpC,aAAaG,KAAOP,OAAY,GAAAS,SAAW;AAAA,EAC3C,cAAcN,QAAU;AAAA,EACxB,eAAeA,QAAU;AAAA,EACzB,gBAAgBA,QAAU;AAAA,EAC1B,iBAAiBA,QAAU;AAAA,EAC3B,sBAAsBA,QAAU;AAAA,EAChC,kBAAkBA,QAAU;AAAA,EAC5B,gBAAgBA,QAAU;AAAA,EAC1B,QAAQA,QAAU;AACpB,CAAC;"}
{"version":3,"file":"cart.js","sources":["../../src/scripts/lib/schemas/cart.ts"],"sourcesContent":["import * as v from \"valibot\";\n\nimport { CATALOG_VISIBILITIES } from \"../../constantes/cart.ts\";\n\nexport const WCStoreCartItemTotalsSchema = v.object({\n \"currency_code\": v.string(),\n \"currency_decimal_separator\": v.string(),\n \"currency_minor_unit\": v.number(),\n \"currency_prefix\": v.string(),\n \"currency_suffix\": v.string(),\n \"currency_symbol\": v.string(),\n \"currency_thousand_separator\": v.string(),\n \"line_subtotal\": v.string(),\n \"line_subtotal_tax\": v.string(),\n \"line_total\": v.string(),\n \"line_total_tax\": v.string(),\n});\n\nexport const WCStoreCartItemSchema = v.object({\n \"backorders_allowed\": v.boolean(),\n \"catalog_visibility\": v.enum(CATALOG_VISIBILITIES),\n \"description\": v.string(),\n \"extensions\": v.unknown(),\n \"id\": v.number(),\n \"images\": v.array(v.unknown()),\n \"item_data\": v.array(v.unknown()),\n \"key\": v.string(),\n \"low_stock_remaining\": v.union([v.null()]),\n \"name\": v.string(),\n \"permalink\": v.pipe(v.string(), v.url()),\n \"prices\": v.unknown(),\n \"quantity\": v.number(),\n \"quantity_limits\": v.unknown(),\n \"short_description\": v.string(),\n \"show_backorder_badge\": v.boolean(),\n \"sku\": v.string(),\n \"sold_individually\": v.boolean(),\n \"totals\": WCStoreCartItemTotalsSchema,\n \"type\": v.string(),\n \"variation\": v.array(v.unknown()),\n});\n\nexport const WCStoreCartTotalsSchema = v.object({\n \"currency_code\": v.string(),\n \"currency_decimal_separator\": v.string(),\n \"currency_minor_unit\": v.number(),\n \"currency_prefix\": v.string(),\n \"currency_suffix\": v.string(),\n \"currency_symbol\": v.string(),\n \"currency_thousand_separator\": v.string(),\n \"tax_lines\": v.array(v.unknown()),\n \"total_discount\": v.string(),\n \"total_discount_tax\": v.string(),\n \"total_fees\": v.string(),\n \"total_fees_tax\": v.string(),\n \"total_items\": v.string(),\n \"total_items_tax\": v.string(),\n \"total_price\": v.string(),\n \"total_shipping\": v.union([v.string(), v.null()]),\n \"total_shipping_tax\": v.union([v.string(), v.null()]),\n \"total_tax\": v.string(),\n});\n\nexport const WCStoreCartSchema = v.object({\n billing_address: v.unknown(),\n coupons: v.unknown(),\n cross_sells: v.unknown(),\n errors: v.unknown(),\n extensions: v.unknown(),\n fees: v.unknown(),\n has_calculated_shipping: v.unknown(),\n items: v.array(WCStoreCartItemSchema),\n items_count: v.pipe(v.number(), v.integer()),\n items_weight: v.unknown(),\n needs_payment: v.unknown(),\n needs_shipping: v.unknown(),\n payment_methods: v.unknown(),\n payment_requirements: v.unknown(),\n shipping_address: v.unknown(),\n shipping_rates: v.unknown(),\n totals: WCStoreCartTotalsSchema,\n});\n"],"names":["v.object","v.string","v.number","v.boolean","v.enum","v.unknown","v.array","v.union","v.null","v.pipe","v.url","v.integer"],"mappings":";;AAIa,MAAA,8BAA8BA,OAAS;AAAA,EAClD,iBAAiBC,OAAS;AAAA,EAC1B,8BAA8BA,OAAS;AAAA,EACvC,uBAAuBC,OAAS;AAAA,EAChC,mBAAmBD,OAAS;AAAA,EAC5B,mBAAmBA,OAAS;AAAA,EAC5B,mBAAmBA,OAAS;AAAA,EAC5B,+BAA+BA,OAAS;AAAA,EACxC,iBAAiBA,OAAS;AAAA,EAC1B,qBAAqBA,OAAS;AAAA,EAC9B,cAAcA,OAAS;AAAA,EACvB,kBAAkBA,OAAS;AAC7B,CAAC;AAEY,MAAA,wBAAwBD,OAAS;AAAA,EAC5C,sBAAsBG,QAAU;AAAA,EAChC,sBAAsBC,MAAO,oBAAoB;AAAA,EACjD,eAAeH,OAAS;AAAA,EACxB,cAAcI,QAAU;AAAA,EACxB,MAAMH,OAAS;AAAA,EACf,UAAUI,MAAQD,SAAW;AAAA,EAC7B,aAAaC,MAAQD,SAAW;AAAA,EAChC,OAAOJ,OAAS;AAAA,EAChB,uBAAuBM,MAAQ,CAACC,MAAE,CAAM,CAAC;AAAA,EACzC,QAAQP,OAAS;AAAA,EACjB,aAAaQ,KAAOR,OAAY,GAAAS,KAAO;AAAA,EACvC,UAAUL,QAAU;AAAA,EACpB,YAAYH,OAAS;AAAA,EACrB,mBAAmBG,QAAU;AAAA,EAC7B,qBAAqBJ,OAAS;AAAA,EAC9B,wBAAwBE,QAAU;AAAA,EAClC,OAAOF,OAAS;AAAA,EAChB,qBAAqBE,QAAU;AAAA,EAC/B,UAAU;AAAA,EACV,QAAQF,OAAS;AAAA,EACjB,aAAaK,MAAQD,SAAW;AAClC,CAAC;AAEY,MAAA,0BAA0BL,OAAS;AAAA,EAC9C,iBAAiBC,OAAS;AAAA,EAC1B,8BAA8BA,OAAS;AAAA,EACvC,uBAAuBC,OAAS;AAAA,EAChC,mBAAmBD,OAAS;AAAA,EAC5B,mBAAmBA,OAAS;AAAA,EAC5B,mBAAmBA,OAAS;AAAA,EAC5B,+BAA+BA,OAAS;AAAA,EACxC,aAAaK,MAAQD,SAAW;AAAA,EAChC,kBAAkBJ,OAAS;AAAA,EAC3B,sBAAsBA,OAAS;AAAA,EAC/B,cAAcA,OAAS;AAAA,EACvB,kBAAkBA,OAAS;AAAA,EAC3B,eAAeA,OAAS;AAAA,EACxB,mBAAmBA,OAAS;AAAA,EAC5B,eAAeA,OAAS;AAAA,EACxB,kBAAkBM,MAAQ,CAACN,UAAYO,MAAQ,CAAA,CAAC;AAAA,EAChD,sBAAsBD,MAAQ,CAACN,UAAYO,MAAQ,CAAA,CAAC;AAAA,EACpD,aAAaP,OAAS;AACxB,CAAC;AAEY,MAAA,oBAAoBD,OAAS;AAAA,EACxC,iBAAiBK,QAAU;AAAA,EAC3B,SAASA,QAAU;AAAA,EACnB,aAAaA,QAAU;AAAA,EACvB,QAAQA,QAAU;AAAA,EAClB,YAAYA,QAAU;AAAA,EACtB,MAAMA,QAAU;AAAA,EAChB,yBAAyBA,QAAU;AAAA,EACnC,OAAOC,MAAQ,qBAAqB;AAAA,EACpC,aAAaG,KAAOP,OAAY,GAAAS,SAAW;AAAA,EAC3C,cAAcN,QAAU;AAAA,EACxB,eAAeA,QAAU;AAAA,EACzB,gBAAgBA,QAAU;AAAA,EAC1B,iBAAiBA,QAAU;AAAA,EAC3B,sBAAsBA,QAAU;AAAA,EAChC,kBAAkBA,QAAU;AAAA,EAC5B,gBAAgBA,QAAU;AAAA,EAC1B,QAAQ;AACV,CAAC;"}

View file

@ -0,0 +1,11 @@
import { u } from "./utils.js";
function r(...n) {
return u(e, n);
}
function e(n, o) {
return o(n), n;
}
export {
r
};
//# sourceMappingURL=chunk-RU7WR4KH.D5j7HXCF.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"chunk-RU7WR4KH.D5j7HXCF.js","sources":["../../../../../../node_modules/.pnpm/remeda@2.14.0/node_modules/remeda/dist/chunk-RU7WR4KH.js"],"sourcesContent":["import{a as t}from\"./chunk-RAAYCPUM.js\";function r(...n){return t(e,n)}function e(n,o){return o(n),n}export{r as a};\n"],"names":["t"],"mappings":";AAAwC,SAAS,KAAK,GAAE;AAAC,SAAOA,EAAE,GAAE,CAAC;AAAC;AAAC,SAAS,EAAE,GAAE,GAAE;AAAC,SAAO,EAAE,CAAC,GAAE;AAAC;","x_google_ignoreList":[0]}

View file

@ -15,25 +15,27 @@ const SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE = "button.detail-produit__actions__
const SELECTEUR_BOUTON_ADDITION_QUANTITE = "button.detail-produit__actions__addition";
const SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER = "input";
const SELECTEUR_PRIX_LIGNE_PANIER = ".detail-produit__nom-prix span";
const SELECTEUR_SOUS_TOTAL_PANIER = "#panneau-panier .panneau__sous-totaux__ligne strong";
const SELECTEUR_TOTAL_PANIER = "#panneau-panier .panneau__pied-de-page p span";
export {
ATTRIBUT_CONTIENT_ARTICLES as A,
SELECTEUR_BOUTON_PANIER as S,
SELECTEUR_ENTREES_PANIER as a,
SELECTEUR_CONTENEUR_PANIER as b,
SELECTEUR_TOTAL_PANIER as c,
ATTRIBUT_CLE_PANIER as d,
SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE as e,
SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER as f,
SELECTEUR_BOUTON_ADDITION_QUANTITE as g,
SELECTEUR_BOUTON_SUPPRESSION_PANIER as h,
SELECTEUR_PRIX_LIGNE_PANIER as i,
SELECTEUR_BOUTON_AJOUT_PANIER as j,
SELECTEUR_SELECTEUR_QUANTITE as k,
SELECTEUR_LIENS_ONGLETS as l,
SELECTEUR_SECTIONS_CONTENUS as m,
ATTRIBUT_ARIA_SELECTED as n,
ATTRIBUT_HIDDEN as o,
ATTRIBUT_DESACTIVE as p
SELECTEUR_SOUS_TOTAL_PANIER as c,
SELECTEUR_TOTAL_PANIER as d,
ATTRIBUT_CLE_PANIER as e,
SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE as f,
SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER as g,
SELECTEUR_BOUTON_ADDITION_QUANTITE as h,
SELECTEUR_BOUTON_SUPPRESSION_PANIER as i,
SELECTEUR_PRIX_LIGNE_PANIER as j,
ATTRIBUT_DESACTIVE as k,
SELECTEUR_BOUTON_AJOUT_PANIER as l,
SELECTEUR_SELECTEUR_QUANTITE as m,
SELECTEUR_LIENS_ONGLETS as n,
SELECTEUR_SECTIONS_CONTENUS as o,
ATTRIBUT_ARIA_SELECTED as p,
ATTRIBUT_HIDDEN as q
};
//# sourceMappingURL=dom.js.map

View file

@ -1 +1 @@
{"version":3,"file":"dom.js","sources":["../../src/scripts/constantes/dom.ts"],"sourcesContent":["/** Constantes de valeurs pour la manipulation du DOM : sélecteurs et attributs. */\n\nexport const ATTRIBUT_ARIA_SELECTED = \"aria-selected\";\nexport const ATTRIBUT_ARIA_HIDDEN = \"aria-hidden\";\nexport const ATTRIBUT_HIDDEN = \"hidden\";\nexport const ATTRIBUT_CONTIENT_ARTICLES = \"data-contient-articles\";\nexport const ATTRIBUT_DESACTIVE = \"disabled\";\nexport const ATTRIBUT_CLE_PANIER = \"data-cle-panier\";\n\nexport const SELECTEUR_CONTENEUR_PANIER = \"#page-panier\";\nexport const SELECTEUR_BOUTON_PANIER = \".compte-panier a[rel='cart']\";\nexport const SELECTEUR_SELECTEUR_QUANTITE = \"#selecteur-variation\";\nexport const SELECTEUR_BOUTON_AJOUT_PANIER = \"#bouton-ajout-panier\";\nexport const SELECTEUR_LIENS_ONGLETS = \"a[role='tab']\";\nexport const SELECTEUR_SECTIONS_CONTENUS = \"section[role='tabpanel']\";\n\n// Panier\nexport const SELECTEUR_ENTREES_PANIER = \"article\";\nexport const SELECTEUR_BOUTON_SUPPRESSION_PANIER = \"button.detail-produit__actions__suppression\";\nexport const SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE = \"button.detail-produit__actions__soustraction\";\nexport const SELECTEUR_BOUTON_ADDITION_QUANTITE = \"button.detail-produit__actions__addition\";\nexport const SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER = \"input\";\nexport const SELECTEUR_PRIX_LIGNE_PANIER = \".detail-produit__nom-prix span\";\nexport const SELECTEUR_TOTAL_PANIER = \"#panneau-panier .panneau__pied-de-page p span\";\n"],"names":[],"mappings":"AAEO,MAAM,yBAAyB;AAE/B,MAAM,kBAAkB;AACxB,MAAM,6BAA6B;AACnC,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAE5B,MAAM,6BAA6B;AACnC,MAAM,0BAA0B;AAChC,MAAM,+BAA+B;AACrC,MAAM,gCAAgC;AACtC,MAAM,0BAA0B;AAChC,MAAM,8BAA8B;AAGpC,MAAM,2BAA2B;AACjC,MAAM,sCAAsC;AAC5C,MAAM,yCAAyC;AAC/C,MAAM,qCAAqC;AAC3C,MAAM,wCAAwC;AAC9C,MAAM,8BAA8B;AACpC,MAAM,yBAAyB;"}
{"version":3,"file":"dom.js","sources":["../../src/scripts/constantes/dom.ts"],"sourcesContent":["/** Constantes de valeurs pour la manipulation du DOM : sélecteurs et attributs. */\n\nexport const ATTRIBUT_ARIA_SELECTED = \"aria-selected\";\nexport const ATTRIBUT_ARIA_HIDDEN = \"aria-hidden\";\nexport const ATTRIBUT_HIDDEN = \"hidden\";\nexport const ATTRIBUT_CONTIENT_ARTICLES = \"data-contient-articles\";\nexport const ATTRIBUT_DESACTIVE = \"disabled\";\nexport const ATTRIBUT_CLE_PANIER = \"data-cle-panier\";\n\nexport const SELECTEUR_CONTENEUR_PANIER = \"#page-panier\";\nexport const SELECTEUR_BOUTON_PANIER = \".compte-panier a[rel='cart']\";\nexport const SELECTEUR_SELECTEUR_QUANTITE = \"#selecteur-variation\";\nexport const SELECTEUR_BOUTON_AJOUT_PANIER = \"#bouton-ajout-panier\";\nexport const SELECTEUR_LIENS_ONGLETS = \"a[role='tab']\";\nexport const SELECTEUR_SECTIONS_CONTENUS = \"section[role='tabpanel']\";\n\n// Panier\nexport const SELECTEUR_ENTREES_PANIER = \"article\";\nexport const SELECTEUR_BOUTON_SUPPRESSION_PANIER = \"button.detail-produit__actions__suppression\";\nexport const SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE = \"button.detail-produit__actions__soustraction\";\nexport const SELECTEUR_BOUTON_ADDITION_QUANTITE = \"button.detail-produit__actions__addition\";\nexport const SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER = \"input\";\nexport const SELECTEUR_PRIX_LIGNE_PANIER = \".detail-produit__nom-prix span\";\nexport const SELECTEUR_SOUS_TOTAL_PANIER = \"#panneau-panier .panneau__sous-totaux__ligne strong\";\nexport const SELECTEUR_TOTAL_PANIER = \"#panneau-panier .panneau__pied-de-page p span\";\n"],"names":[],"mappings":"AAEO,MAAM,yBAAyB;AAE/B,MAAM,kBAAkB;AACxB,MAAM,6BAA6B;AACnC,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAE5B,MAAM,6BAA6B;AACnC,MAAM,0BAA0B;AAChC,MAAM,+BAA+B;AACrC,MAAM,gCAAgC;AACtC,MAAM,0BAA0B;AAChC,MAAM,8BAA8B;AAGpC,MAAM,2BAA2B;AACjC,MAAM,sCAAsC;AAC5C,MAAM,yCAAyC;AAC/C,MAAM,qCAAqC;AAC3C,MAAM,wCAAwC;AAC9C,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC,MAAM,yBAAyB;"}

View file

@ -32,6 +32,12 @@ class UnknownError extends Error {
this.name = "UnknownError";
}
}
class CleNonTrouveError extends Error {
constructor(message) {
super(JSON.stringify(message));
this.name = "CleNonTrouveError";
}
}
const ErreurInconnue = (erreur) => new UnknownError(erreur);
const leveErreur = (erreur) => {
throw erreur;
@ -57,6 +63,7 @@ const reporteEtLeveErreur = (erreur) => {
throw erreur;
};
export {
CleNonTrouveError as C,
ErreurInconnue as E,
leveBadRequestError as a,
leveUnauthorizedError as b,

File diff suppressed because one or more lines are too long

View file

@ -1,23 +1,3 @@
function u$2(t2, n2, a2) {
let o2 = (r2) => t2(r2, ...n2);
return a2 === void 0 ? o2 : Object.assign(o2, { lazy: a2, lazyArgs: n2 });
}
function u$1(r2, n2, a2) {
let o2 = r2.length - n2.length;
if (o2 === 0) return r2(...n2);
if (o2 === 1) return u$2(r2, n2, a2);
throw new Error("Wrong number of arguments");
}
function r$1(...n2) {
return u$1(e$1, n2);
}
function e$1(n2, o2) {
return o2(n2), n2;
}
function p$1(...o2) {
return u$1(t$1, o2);
}
var t$1 = (o2, e2) => o2[e2];
const t = Symbol.for("@ts-pattern/matcher"), e = Symbol.for("@ts-pattern/isVariadic"), n = "@ts-pattern/anonymous-select-key", r = (t2) => Boolean(t2 && "object" == typeof t2), i = (e2) => e2 && !!e2[t], s = (n2, o2, c2) => {
if (i(n2)) {
const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(o2);
@ -258,8 +238,6 @@ class I {
}
export {
N,
p$1 as p,
r$1 as r,
z
};
//# sourceMappingURL=index.y02cst4L.js.map
//# sourceMappingURL=index.CeK6pfoJ.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,23 +1,37 @@
import { p as parse } from "./index.DD7qm8S6.js";
import { N as NOM_CANAL_BOUTON_PANIER, T as TYPES_MESSAGES, a as NOM_CANAL_CONTENU_PANIER } from "./messages3.js";
import { r as reporteErreur } from "./erreurs.js";
import { M as MessageMajBoutonPanierSchema, a as MessageMajContenuPanierSchema } from "./messages2.js";
import { E as Either } from "./Either.wHNxn7Os.js";
import "./exports.DNZBdkMD.js";
import "./messages3.js";
import "./cart.js";
import "./cart2.js";
const emetMessageMajBoutonPanier = (args) => {
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: {
quantiteProduits: args.quantiteProduits
},
type: TYPES_MESSAGES.MajBoutonPanier
});
};
const emetMessageMajContenuPanier = (args) => new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: args.produits,
sousTotalPanier: args.sousTotalPanier,
totalPanier: args.totalPanier
},
type: TYPES_MESSAGES.MajContenuPanier
});
const valideMessageMajBoutonPanier = (evenementMessage) => Either.of(
parse(MessageMajBoutonPanierSchema, evenementMessage.data)
).ifLeft((erreur) => {
reporteErreur(erreur);
});
).ifLeft((erreur) => reporteErreur(erreur));
const valideMessageMajContenuPanier = (evenementMessage) => Either.of(
parse(MessageMajContenuPanierSchema, evenementMessage.data)
).ifLeft((erreur) => {
reporteErreur(erreur);
});
).ifLeft((erreur) => reporteErreur(erreur));
export {
valideMessageMajContenuPanier as a,
emetMessageMajContenuPanier as b,
emetMessageMajBoutonPanier as e,
valideMessageMajBoutonPanier as v
};
//# sourceMappingURL=messages.js.map

View file

@ -1 +1 @@
{"version":3,"file":"messages.js","sources":["../../src/scripts/lib/messages.ts"],"sourcesContent":["import { Either } from \"purify-ts\";\nimport { parse, type ValiError } from \"valibot\";\n\nimport type { MessageMajBoutonPanier, MessageMajContenuPanier } from \"./types/messages\";\n\nimport { reporteErreur } from \"./erreurs.ts\";\nimport { MessageMajBoutonPanierSchema, MessageMajContenuPanierSchema } from \"./schemas/messages.ts\";\n\nexport const valideMessageMajBoutonPanier = (\n evenementMessage: MessageEvent<unknown>,\n): Either<ValiError<typeof MessageMajBoutonPanierSchema>, MessageMajBoutonPanier> =>\n Either\n .of<ValiError<typeof MessageMajBoutonPanierSchema>, MessageMajBoutonPanier>(\n parse(MessageMajBoutonPanierSchema, evenementMessage.data),\n )\n .ifLeft(erreur => {\n reporteErreur(erreur);\n });\n\nexport const valideMessageMajContenuPanier = (\n evenementMessage: MessageEvent<unknown>,\n): Either<ValiError<typeof MessageMajContenuPanierSchema>, MessageMajContenuPanier> =>\n Either\n .of<ValiError<typeof MessageMajContenuPanierSchema>, MessageMajContenuPanier>(\n parse(MessageMajContenuPanierSchema, evenementMessage.data),\n )\n .ifLeft(erreur => {\n reporteErreur(erreur);\n });\n"],"names":[],"mappings":";;;;;;;;AAQa,MAAA,+BAA+B,CAC1C,qBAEA,OACG;AAAA,EACC,MAAM,8BAA8B,iBAAiB,IAAI;AAC3D,EACC,OAAO,CAAU,WAAA;AAChB,gBAAc,MAAM;AACtB,CAAC;AAEQ,MAAA,gCAAgC,CAC3C,qBAEA,OACG;AAAA,EACC,MAAM,+BAA+B,iBAAiB,IAAI;AAC5D,EACC,OAAO,CAAU,WAAA;AAChB,gBAAc,MAAM;AACtB,CAAC;"}
{"version":3,"file":"messages.js","sources":["../../src/scripts/lib/messages.ts"],"sourcesContent":["import { Either } from \"purify-ts\";\nimport { parse, type ValiError } from \"valibot\";\n\nimport type {\n MessageMajBoutonPanier,\n MessageMajBoutonPanierDonnees,\n MessageMajContenuPanier,\n MessageMajContenuPanierDonnees,\n} from \"./types/messages\";\n\nimport { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER, TYPES_MESSAGES } from \"../constantes/messages.ts\";\nimport { reporteErreur } from \"./erreurs.ts\";\nimport { MessageMajBoutonPanierSchema, MessageMajContenuPanierSchema } from \"./schemas/messages.ts\";\n\n// Émissions\nexport const emetMessageMajBoutonPanier = (args: MessageMajBoutonPanierDonnees): void => {\n new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({\n donnees: {\n quantiteProduits: args.quantiteProduits,\n },\n type: TYPES_MESSAGES.MajBoutonPanier,\n } as MessageMajBoutonPanier);\n};\n\nexport const emetMessageMajContenuPanier = (args: MessageMajContenuPanierDonnees): void =>\n new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({\n donnees: {\n produits: args.produits,\n sousTotalPanier: args.sousTotalPanier,\n totalPanier: args.totalPanier,\n },\n type: TYPES_MESSAGES.MajContenuPanier,\n } as MessageMajContenuPanier);\n\n// Validations\nexport const valideMessageMajBoutonPanier = (\n evenementMessage: MessageEvent<unknown>,\n): Either<ValiError<typeof MessageMajBoutonPanierSchema>, MessageMajBoutonPanier> =>\n Either\n .of<ValiError<typeof MessageMajBoutonPanierSchema>, MessageMajBoutonPanier>(\n parse(MessageMajBoutonPanierSchema, evenementMessage.data),\n )\n .ifLeft(erreur => reporteErreur(erreur));\n\nexport const valideMessageMajContenuPanier = (\n evenementMessage: MessageEvent<unknown>,\n): Either<ValiError<typeof MessageMajContenuPanierSchema>, MessageMajContenuPanier> =>\n Either\n .of<ValiError<typeof MessageMajContenuPanierSchema>, MessageMajContenuPanier>(\n parse(MessageMajContenuPanierSchema, evenementMessage.data),\n )\n .ifLeft(erreur => reporteErreur(erreur));\n"],"names":[],"mappings":";;;;;;;;AAea,MAAA,6BAA6B,CAAC,SAA8C;AACnF,MAAA,iBAAiB,uBAAuB,EAAE,YAAY;AAAA,IACxD,SAAS;AAAA,MACP,kBAAkB,KAAK;AAAA,IACzB;AAAA,IACA,MAAM,eAAe;AAAA,EAAA,CACI;AAC7B;AAEO,MAAM,8BAA8B,CAAC,SAC1C,IAAI,iBAAiB,wBAAwB,EAAE,YAAY;AAAA,EACzD,SAAS;AAAA,IACP,UAAU,KAAK;AAAA,IACf,iBAAiB,KAAK;AAAA,IACtB,aAAa,KAAK;AAAA,EACpB;AAAA,EACA,MAAM,eAAe;AACvB,CAA4B;AAGjB,MAAA,+BAA+B,CAC1C,qBAEA,OACG;AAAA,EACC,MAAM,8BAA8B,iBAAiB,IAAI;AAC3D,EACC,OAAO,CAAA,WAAU,cAAc,MAAM,CAAC;AAE9B,MAAA,gCAAgC,CAC3C,qBAEA,OACG;AAAA,EACC,MAAM,+BAA+B,iBAAiB,IAAI;AAC5D,EACC,OAAO,CAAA,WAAU,cAAc,MAAM,CAAC;"}

View file

@ -1,14 +1,18 @@
import { e as enum_, o as object, n as number, c as pipe, v as value, s as string, b as array } from "./index.DD7qm8S6.js";
import { e as enum_, o as object, c as pipe, v as value, s as string, n as number, b as array } from "./index.DD7qm8S6.js";
import { T as TYPES_MESSAGES } from "./messages3.js";
import { a as WCStoreCartItemSchema } from "./cart.js";
import "./cart2.js";
enum_(TYPES_MESSAGES);
const MessageMajBoutonPanierDonneesSchema = object({
quantiteProduits: number()
});
const MessageMajBoutonPanierSchema = object({
donnees: number(),
donnees: MessageMajBoutonPanierDonneesSchema,
type: pipe(string(), value(TYPES_MESSAGES.MajBoutonPanier))
});
const MessageMajContenuPanierDonneesSchema = object({
produits: array(WCStoreCartItemSchema),
sousTotalPanier: number(),
totalPanier: number()
});
const MessageMajContenuPanierSchema = object({

View file

@ -1 +1 @@
{"version":3,"file":"messages2.js","sources":["../../src/scripts/lib/schemas/messages.ts"],"sourcesContent":["/**\n * Schémas des Messages passés avec BroadcastChannel.\n */\n\nimport * as v from \"valibot\";\n\nimport { TYPES_MESSAGES } from \"../../constantes/messages.ts\";\nimport { WCStoreCartItemSchema } from \"./cart.ts\";\n\nexport const TypesMessagesSchema = v.enum(TYPES_MESSAGES);\n\nexport const MessageMajBoutonPanierSchema = v.object({\n donnees: v.number(),\n type: v.pipe(v.string(), v.value(TYPES_MESSAGES.MajBoutonPanier)),\n});\n\nexport const MessageMajContenuPanierDonneesSchema = v.object({\n produits: v.array(WCStoreCartItemSchema),\n totalPanier: v.number(),\n});\n\nexport const MessageMajContenuPanierSchema = v.object({\n donnees: MessageMajContenuPanierDonneesSchema,\n type: v.pipe(v.string(), v.value(TYPES_MESSAGES.MajContenuPanier)),\n});\n"],"names":["v.enum","v.object","v.number","v.pipe","v.string","v.value","v.array"],"mappings":";;;;AASmCA,MAAO,cAAc;AAE3C,MAAA,+BAA+BC,OAAS;AAAA,EACnD,SAASC,OAAS;AAAA,EAClB,MAAMC,KAAOC,OAAE,GAAUC,MAAQ,eAAe,eAAe,CAAC;AAClE,CAAC;AAEY,MAAA,uCAAuCJ,OAAS;AAAA,EAC3D,UAAUK,MAAQ,qBAAqB;AAAA,EACvC,aAAaJ,OAAS;AACxB,CAAC;AAEY,MAAA,gCAAgCD,OAAS;AAAA,EACpD,SAAS;AAAA,EACT,MAAME,KAAOC,OAAE,GAAUC,MAAQ,eAAe,gBAAgB,CAAC;AACnE,CAAC;"}
{"version":3,"file":"messages2.js","sources":["../../src/scripts/lib/schemas/messages.ts"],"sourcesContent":["/**\n * Schémas des Messages passés avec BroadcastChannel.\n */\n\nimport * as v from \"valibot\";\n\nimport { TYPES_MESSAGES } from \"../../constantes/messages.ts\";\nimport { WCStoreCartItemSchema } from \"./cart.ts\";\n\nexport const TypesMessagesSchema = v.enum(TYPES_MESSAGES);\n\nexport const MessageMajBoutonPanierDonneesSchema = v.object({\n quantiteProduits: v.number(),\n});\n\nexport const MessageMajBoutonPanierSchema = v.object({\n donnees: MessageMajBoutonPanierDonneesSchema,\n type: v.pipe(v.string(), v.value(TYPES_MESSAGES.MajBoutonPanier)),\n});\n\nexport const MessageMajContenuPanierDonneesSchema = v.object({\n produits: v.array(WCStoreCartItemSchema),\n sousTotalPanier: v.number(),\n totalPanier: v.number(),\n});\n\nexport const MessageMajContenuPanierSchema = v.object({\n donnees: MessageMajContenuPanierDonneesSchema,\n type: v.pipe(v.string(), v.value(TYPES_MESSAGES.MajContenuPanier)),\n});\n"],"names":["v.enum","v.object","v.number","v.pipe","v.string","v.value","v.array"],"mappings":";;;;AASmCA,MAAO,cAAc;AAE3C,MAAA,sCAAsCC,OAAS;AAAA,EAC1D,kBAAkBC,OAAS;AAC7B,CAAC;AAEY,MAAA,+BAA+BD,OAAS;AAAA,EACnD,SAAS;AAAA,EACT,MAAME,KAAOC,OAAE,GAAUC,MAAQ,eAAe,eAAe,CAAC;AAClE,CAAC;AAEY,MAAA,uCAAuCJ,OAAS;AAAA,EAC3D,UAAUK,MAAQ,qBAAqB;AAAA,EACvC,iBAAiBJ,OAAS;AAAA,EAC1B,aAAaA,OAAS;AACxB,CAAC;AAEY,MAAA,gCAAgCD,OAAS;AAAA,EACpD,SAAS;AAAA,EACT,MAAME,KAAOC,OAAE,GAAUC,MAAQ,eAAe,gBAAgB,CAAC;AACnE,CAAC;"}

View file

@ -1,5 +1,11 @@
import { x } from "./chunk-7BKSRZNG.C39W3Wne.js";
import { z, N } from "./index.CeK6pfoJ.js";
import { p as parse } from "./index.DD7qm8S6.js";
import { d as ENTETE_WC_NONCE } from "./api2.js";
const postBackendWC = (args) => fetch(
import { a as leveBadRequestError, b as leveUnauthorizedError, c as leveNotFoundError, d as leveErreur, E as ErreurInconnue } from "./erreurs.js";
import { e as estWCError } from "./erreurs2.js";
import "./exports.DNZBdkMD.js";
const postBackend = (args) => fetch(
args.route,
{
body: args.corps,
@ -14,7 +20,9 @@ const postBackendWC = (args) => fetch(
signal: AbortSignal.timeout(5e3)
}
);
const traiteReponseBackendWCSelonCodesHTTP = (corpsReponse, schemaReponse) => z(corpsReponse).with({ body: N.select(), status: 400 }, estWCError, leveBadRequestError).with({ body: N.select(), status: 401 }, estWCError, leveUnauthorizedError).with({ body: N.select(), status: 404 }, estWCError, leveNotFoundError).with(N._, (corpsOkInconnu) => parse(schemaReponse, corpsOkInconnu)).otherwise((e) => x(e, ErreurInconnue, leveErreur));
export {
postBackendWC as p
postBackend as p,
traiteReponseBackendWCSelonCodesHTTP as t
};
//# sourceMappingURL=reseau.js.map

View file

@ -1 +1 @@
{"version":3,"file":"reseau.js","sources":["../../src/scripts/lib/reseau.ts"],"sourcesContent":["import { pipe } from \"remeda\";\nimport { match, P } from \"ts-pattern\";\nimport { type GenericSchema, parse } from \"valibot\";\n\nimport { ENTETE_WC_NONCE } from \"../constantes/api.ts\";\nimport {\n ErreurInconnue,\n leveBadRequestError,\n leveErreur,\n leveNotFoundError,\n leveUnauthorizedError,\n type UnknownError,\n} from \"./erreurs.ts\";\nimport { estWCError } from \"./schemas/erreurs.ts\";\n\ntype ArgumentsPostBackendWC = {\n corps: BodyInit;\n nonce: string;\n route: string;\n};\n\nexport const postBackendWC = (args: ArgumentsPostBackendWC) =>\n fetch(\n args.route,\n {\n body: args.corps,\n credentials: \"same-origin\",\n headers: {\n \"Accept\": \"application/json\",\n \"Content-Type\": \"application/json\",\n [ENTETE_WC_NONCE]: args.nonce,\n },\n method: \"POST\",\n mode: \"same-origin\",\n signal: AbortSignal.timeout(5000),\n },\n );\n\nexport const traiteReponseBackendWCSelonCodesHTTP = (corpsReponse: unknown, schemaReponse: GenericSchema) =>\n match(corpsReponse)\n // Réponses problématiques\n .with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)\n .with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)\n .with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)\n // Réponse OK (201)\n .with(P._, corpsOkInconnu => parse(schemaReponse, corpsOkInconnu))\n // Réponses inconnues\n .otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>));\n"],"names":[],"mappings":";AAqBa,MAAA,gBAAgB,CAAC,SAC5B;AAAA,EACE,KAAK;AAAA,EACL;AAAA,IACE,MAAM,KAAK;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,MACP,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,CAAC,eAAe,GAAG,KAAK;AAAA,IAC1B;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,YAAY,QAAQ,GAAI;AAAA,EAClC;AACF;"}
{"version":3,"file":"reseau.js","sources":["../../src/scripts/lib/reseau.ts"],"sourcesContent":["import { pipe } from \"remeda\";\nimport { match, P } from \"ts-pattern\";\nimport { type GenericSchema, parse } from \"valibot\";\n\nimport { ENTETE_WC_NONCE } from \"../constantes/api.ts\";\nimport {\n ErreurInconnue,\n leveBadRequestError,\n leveErreur,\n leveNotFoundError,\n leveUnauthorizedError,\n type UnknownError,\n} from \"./erreurs.ts\";\nimport { estWCError } from \"./schemas/erreurs.ts\";\n\ntype ArgumentsPostBackendWC = {\n /** Le corps de la requête (ses arguments). */\n corps: BodyInit;\n /** Une chaîne de caractères généré par le backend et à joindre à chaque requête pour l'authentifier. */\n nonce: string;\n /** La route, ou chemin, de l'API à demander au backend. */\n route: string;\n};\n\nexport const postBackend = (args: ArgumentsPostBackendWC) =>\n fetch(\n args.route,\n {\n body: args.corps,\n credentials: \"same-origin\",\n headers: {\n \"Accept\": \"application/json\",\n \"Content-Type\": \"application/json\",\n [ENTETE_WC_NONCE]: args.nonce,\n },\n method: \"POST\",\n mode: \"same-origin\",\n signal: AbortSignal.timeout(5000),\n },\n );\n\nexport const traiteReponseBackendWCSelonCodesHTTP = <R, S extends GenericSchema<R>>(\n corpsReponse: unknown,\n schemaReponse: S,\n): R =>\n match(corpsReponse)\n // Réponses problématiques\n .with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)\n .with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)\n .with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)\n // Réponse OK (201)\n .with(P._, corpsOkInconnu => parse<S>(schemaReponse, corpsOkInconnu))\n // Réponses inconnues\n .otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>));\n"],"names":["match","P","pipe"],"mappings":";;;;;;;AAwBa,MAAA,cAAc,CAAC,SAC1B;AAAA,EACE,KAAK;AAAA,EACL;AAAA,IACE,MAAM,KAAK;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,MACP,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,CAAC,eAAe,GAAG,KAAK;AAAA,IAC1B;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,YAAY,QAAQ,GAAI;AAAA,EAClC;AACF;AAEW,MAAA,uCAAuC,CAClD,cACA,kBAEAA,EAAM,YAAY,EAEf,KAAK,EAAE,MAAMC,EAAE,OAAO,GAAG,QAAQ,IAAO,GAAA,YAAY,mBAAmB,EACvE,KAAK,EAAE,MAAMA,EAAE,UAAU,QAAQ,IAAA,GAAO,YAAY,qBAAqB,EACzE,KAAK,EAAE,MAAMA,EAAE,OAAA,GAAU,QAAQ,IAAI,GAAG,YAAY,iBAAiB,EAErE,KAAKA,EAAE,GAAG,CAAkB,mBAAA,MAAS,eAAe,cAAc,CAAC,EAEnE,UAAU,CAAA,MAAKC,EAAK,GAAG,gBAAgB,UAAwB,CAAC;"}

View file

@ -19,8 +19,8 @@ const initialiseBoutonPanier = () => {
const CANAL_BOUTON_PANIER = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
CANAL_BOUTON_PANIER.onmessage = (evenementMessage) => {
valideMessageMajBoutonPanier(evenementMessage).ifRight((message) => {
BOUTON_PANIER.textContent = `cart (${String(message.donnees)})`;
BOUTON_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees > 0));
BOUTON_PANIER.textContent = `cart (${String(message.donnees.quantiteProduits)})`;
BOUTON_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees.quantiteProduits > 0));
});
};
};

View file

@ -1 +1 @@
{"version":3,"file":"scripts-bouton-panier.js","sources":["../../src/scripts/scripts-bouton-panier.ts"],"sourcesContent":["/**\n * Scripts pour la mise à jour trans-fenêtres/trans-onglets du Bouton du Panier.\n */\n\nimport { pipe } from \"remeda\";\n\nimport type { MessageMajBoutonPanier } from \"./lib/types/messages\";\n\nimport { ATTRIBUT_CONTIENT_ARTICLES, SELECTEUR_BOUTON_PANIER } from \"./constantes/dom.ts\";\nimport { NOM_CANAL_BOUTON_PANIER } from \"./constantes/messages.ts\";\nimport { recupereElementOuLeve } from \"./lib/dom.ts\";\nimport { valideMessageMajBoutonPanier } from \"./lib/messages.ts\";\nimport { recupereElementDocumentEither } from \"./lib/utils.ts\";\n\nconst initialiseBoutonPanier = (): void => {\n /** Le « Bouton » vers le Panier dont le texte est un indicateur du nombre de Produits dedans. */\n const BOUTON_PANIER: HTMLAnchorElement = pipe(\n recupereElementDocumentEither<HTMLAnchorElement>(SELECTEUR_BOUTON_PANIER),\n recupereElementOuLeve,\n );\n const CANAL_BOUTON_PANIER: BroadcastChannel = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);\n\n CANAL_BOUTON_PANIER.onmessage = (evenementMessage: MessageEvent<unknown>): void => {\n valideMessageMajBoutonPanier(evenementMessage)\n // Met à jour le Bouton du Panier\n .ifRight((message: MessageMajBoutonPanier) => {\n BOUTON_PANIER.textContent = `cart (${String(message.donnees)})`;\n BOUTON_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees > 0));\n });\n };\n};\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n initialiseBoutonPanier();\n});\n"],"names":["pipe"],"mappings":";;;;;;;;;;;;;AAcA,MAAM,yBAAyB,MAAY;AAEzC,QAAM,gBAAmCA;AAAAA,IACvC,8BAAiD,uBAAuB;AAAA,IACxE;AAAA,EAAA;AAEI,QAAA,sBAAwC,IAAI,iBAAiB,uBAAuB;AAEtE,sBAAA,YAAY,CAAC,qBAAkD;AACjF,iCAA6B,gBAAgB,EAE1C,QAAQ,CAAC,YAAoC;AAC5C,oBAAc,cAAc,SAAS,OAAO,QAAQ,OAAO,CAAC;AAC5D,oBAAc,aAAa,4BAA4B,OAAO,QAAQ,UAAU,CAAC,CAAC;AAAA,IAAA,CACnF;AAAA,EAAA;AAEP;AAEA,SAAS,iBAAiB,oBAAoB,MAAM;AAC3B;AACzB,CAAC;"}
{"version":3,"file":"scripts-bouton-panier.js","sources":["../../src/scripts/scripts-bouton-panier.ts"],"sourcesContent":["/**\n * Scripts pour la mise à jour trans-fenêtres/trans-onglets du Bouton du Panier.\n */\n\nimport { pipe } from \"remeda\";\n\nimport type { MessageMajBoutonPanier } from \"./lib/types/messages\";\n\nimport { ATTRIBUT_CONTIENT_ARTICLES, SELECTEUR_BOUTON_PANIER } from \"./constantes/dom.ts\";\nimport { NOM_CANAL_BOUTON_PANIER } from \"./constantes/messages.ts\";\nimport { recupereElementOuLeve } from \"./lib/dom.ts\";\nimport { valideMessageMajBoutonPanier } from \"./lib/messages.ts\";\nimport { recupereElementDocumentEither } from \"./lib/utils.ts\";\n\nconst initialiseBoutonPanier = (): void => {\n /** Le « Bouton » vers le Panier dont le texte est un indicateur du nombre de Produits dedans. */\n const BOUTON_PANIER: HTMLAnchorElement = pipe(\n recupereElementDocumentEither<HTMLAnchorElement>(SELECTEUR_BOUTON_PANIER),\n recupereElementOuLeve,\n );\n const CANAL_BOUTON_PANIER: BroadcastChannel = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);\n\n CANAL_BOUTON_PANIER.onmessage = (evenementMessage: MessageEvent<unknown>): void => {\n valideMessageMajBoutonPanier(evenementMessage)\n // Met à jour le Bouton du Panier\n .ifRight((message: MessageMajBoutonPanier) => {\n BOUTON_PANIER.textContent = `cart (${String(message.donnees.quantiteProduits)})`;\n BOUTON_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees.quantiteProduits > 0));\n });\n };\n};\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n initialiseBoutonPanier();\n});\n"],"names":["pipe"],"mappings":";;;;;;;;;;;;;AAcA,MAAM,yBAAyB,MAAY;AAEzC,QAAM,gBAAmCA;AAAAA,IACvC,8BAAiD,uBAAuB;AAAA,IACxE;AAAA,EAAA;AAEI,QAAA,sBAAwC,IAAI,iBAAiB,uBAAuB;AAEtE,sBAAA,YAAY,CAAC,qBAAkD;AACjF,iCAA6B,gBAAgB,EAE1C,QAAQ,CAAC,YAAoC;AAC5C,oBAAc,cAAc,SAAS,OAAO,QAAQ,QAAQ,gBAAgB,CAAC;AAC7E,oBAAc,aAAa,4BAA4B,OAAO,QAAQ,QAAQ,mBAAmB,CAAC,CAAC;AAAA,IAAA,CACpG;AAAA,EAAA;AAEP;AAEA,SAAS,iBAAiB,oBAAoB,MAAM;AAC3B;AACzB,CAAC;"}

View file

@ -1,22 +1,23 @@
import { r, z, N, p } from "./index.y02cst4L.js";
import { r } from "./chunk-RU7WR4KH.D5j7HXCF.js";
import { a as recupereElementsDocumentEither, r as recupereElementDocumentEither, p, b as propEither } from "./utils.js";
import { x } from "./chunk-7BKSRZNG.C39W3Wne.js";
import { p as parse } from "./index.DD7qm8S6.js";
import { R as ROUTE_API_RETIRE_ARTICLE_PANIER, b as ROUTE_API_MAJ_ARTICLE_PANIER } from "./api2.js";
import { a as SELECTEUR_ENTREES_PANIER, b as SELECTEUR_CONTENEUR_PANIER, c as SELECTEUR_TOTAL_PANIER, d as ATTRIBUT_CLE_PANIER, e as SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE, f as SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER, g as SELECTEUR_BOUTON_ADDITION_QUANTITE, h as SELECTEUR_BOUTON_SUPPRESSION_PANIER, A as ATTRIBUT_CONTIENT_ARTICLES, i as SELECTEUR_PRIX_LIGNE_PANIER } from "./dom.js";
import { N as NOM_CANAL_BOUTON_PANIER, a as NOM_CANAL_CONTENU_PANIER, T as TYPES_MESSAGES } from "./messages3.js";
import { a as SELECTEUR_ENTREES_PANIER, b as SELECTEUR_CONTENEUR_PANIER, c as SELECTEUR_SOUS_TOTAL_PANIER, d as SELECTEUR_TOTAL_PANIER, e as ATTRIBUT_CLE_PANIER, f as SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE, g as SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER, h as SELECTEUR_BOUTON_ADDITION_QUANTITE, i as SELECTEUR_BOUTON_SUPPRESSION_PANIER, A as ATTRIBUT_CONTIENT_ARTICLES, j as SELECTEUR_PRIX_LIGNE_PANIER, k as ATTRIBUT_DESACTIVE } from "./dom.js";
import { N as NOM_CANAL_BOUTON_PANIER, a as NOM_CANAL_CONTENU_PANIER } from "./messages3.js";
import { r as recupereElementOuLeve, a as recupereElementAvecSelecteur } from "./dom2.js";
import { l as leveServerError, a as leveBadRequestError, b as leveUnauthorizedError, c as leveNotFoundError, E as ErreurInconnue, d as leveErreur, r as reporteErreur } from "./erreurs.js";
import { l as leveServerError, r as reporteErreur } from "./erreurs.js";
import { e as estReponse500, a as estError } from "./gardes.js";
import { v as valideMessageMajBoutonPanier, a as valideMessageMajContenuPanier } from "./messages.js";
import { p as postBackendWC } from "./reseau.js";
import { v as valideMessageMajBoutonPanier, a as valideMessageMajContenuPanier, e as emetMessageMajBoutonPanier, b as emetMessageMajContenuPanier } from "./messages.js";
import { p as postBackend, t as traiteReponseBackendWCSelonCodesHTTP } from "./reseau.js";
import { W as WCStoreCartRemoveItemArgsSchema } from "./cart-remove-item.js";
import { W as WCStoreCartUpdateItemArgsSchema } from "./cart-update-item.js";
import { W as WCStoreCartSchema } from "./cart.js";
import { e as estWCError } from "./erreurs2.js";
import { a as recupereElementsDocumentEither, r as recupereElementDocumentEither } from "./utils.js";
import { M as Maybe, E as Either } from "./Either.wHNxn7Os.js";
import "./exports.DNZBdkMD.js";
import "./messages2.js";
import "./index.CeK6pfoJ.js";
import "./erreurs2.js";
import "./cart2.js";
const ETATS_PAGE = _etats;
const ENTREES_PANIER_EITHER = recupereElementsDocumentEither(
@ -26,21 +27,46 @@ const CONTENEUR_PANIER = x(
recupereElementDocumentEither(SELECTEUR_CONTENEUR_PANIER),
recupereElementOuLeve
);
const SOUS_TOTAL_PANIER = x(
recupereElementDocumentEither(SELECTEUR_SOUS_TOTAL_PANIER),
recupereElementOuLeve
);
const TOTAL_PANIER = x(
recupereElementDocumentEither(SELECTEUR_TOTAL_PANIER),
recupereElementOuLeve
);
const recupereElementDansEntreePanierOuLeve = (
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- Nécessaire pour
documenter le type d'Element attendu */
(entree) => (selecteur) => x(
recupereElementAvecSelecteur(entree)(selecteur),
recupereElementOuLeve
)
const recupereElementDansEntreePanierOuLeve = (entree) => (selecteur) => x(
recupereElementAvecSelecteur(entree)(selecteur),
recupereElementOuLeve
);
const initialiseScriptsPagePanier = () => {
ENTREES_PANIER_EITHER.ifRight(
(entrees) => entrees.forEach((entree) => {
const desactiveBoutonsEntreesPanier = (entrees) => entrees.forEach((entree) => {
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
const elements = {
boutonAddition: recupereElementDansEntree(SELECTEUR_BOUTON_ADDITION_QUANTITE),
boutonSoustraction: recupereElementDansEntree(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
boutonSuppression: recupereElementDansEntree(SELECTEUR_BOUTON_SUPPRESSION_PANIER)
};
elements.boutonSoustraction.setAttribute(ATTRIBUT_DESACTIVE, "");
elements.boutonAddition.setAttribute(ATTRIBUT_DESACTIVE, "");
elements.boutonSuppression.setAttribute(ATTRIBUT_DESACTIVE, "");
elements.boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
});
const majEtatsActivationBoutons = (entrees) => entrees.forEach((entree) => {
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
const elements = {
boutonAddition: recupereElementDansEntree(SELECTEUR_BOUTON_ADDITION_QUANTITE),
boutonSoustraction: recupereElementDansEntree(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
boutonSuppression: recupereElementDansEntree(SELECTEUR_BOUTON_SUPPRESSION_PANIER),
champQuantite: recupereElementDansEntree(SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER)
};
Number(elements.champQuantite?.value) === 1 ? elements.boutonSoustraction.setAttribute(ATTRIBUT_DESACTIVE, "") : elements.boutonSoustraction.removeAttribute(ATTRIBUT_DESACTIVE);
elements.boutonAddition.removeAttribute(ATTRIBUT_DESACTIVE);
elements.boutonSuppression.removeAttribute(ATTRIBUT_DESACTIVE);
elements.boutonSuppression.textContent = "Remove";
});
const initialiseMajEntreesPanier = () => {
ENTREES_PANIER_EITHER.ifRight((entrees) => {
entrees.forEach((entree) => {
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
const clePanier = Maybe.fromNullable(entree.getAttribute(ATTRIBUT_CLE_PANIER)).ifNothing(() => {
entree.remove();
@ -51,10 +77,12 @@ const initialiseScriptsPagePanier = () => {
const boutonAddition = recupereElementDansEntree(SELECTEUR_BOUTON_ADDITION_QUANTITE);
const boutonSuppression = recupereElementDansEntree(SELECTEUR_BOUTON_SUPPRESSION_PANIER);
boutonSuppression.addEventListener("click", () => {
boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
Either.encase(() => parse(WCStoreCartRemoveItemArgsSchema, { key: clePanier })).map(
(args) => {
postBackendWC({
Either.encase(
() => parse(WCStoreCartRemoveItemArgsSchema, { key: clePanier })
).map(
async (args) => {
desactiveBoutonsEntreesPanier(entrees);
await postBackend({
corps: JSON.stringify(args),
nonce: ETATS_PAGE.nonce,
route: ROUTE_API_RETIRE_ARTICLE_PANIER
@ -64,18 +92,17 @@ const initialiseScriptsPagePanier = () => {
// Récupère la Réponse
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse) => z(corpsReponse).with({ body: N.select(), status: 400 }, estWCError, leveBadRequestError).with({ body: N.select(), status: 401 }, estWCError, leveUnauthorizedError).with({ body: N.select(), status: 404 }, estWCError, leveNotFoundError).with(N._, (corpsOkInconnu) => parse(WCStoreCartSchema, corpsOkInconnu)).otherwise((e) => x(e, ErreurInconnue, leveErreur)),
(corpsReponse) => traiteReponseBackendWCSelonCodesHTTP(
corpsReponse,
WCStoreCartSchema
),
// Émets des Messages via BroadcastChannels pour la mise à jour de la page
r((panier) => {
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: panier.items,
totalPanier: Number(panier.totals.total_items / 100)
},
type: TYPES_MESSAGES.MajContenuPanier
});
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: panier.items_count,
type: TYPES_MESSAGES.MajBoutonPanier
emetMessageMajBoutonPanier({ quantiteProduits: panier.items_count });
emetMessageMajContenuPanier({
produits: panier.items,
sousTotalPanier: Number(panier.totals.total_price) / 100,
totalPanier: Number(panier.totals.total_items) / 100
});
entree.remove();
})
@ -86,21 +113,19 @@ const initialiseScriptsPagePanier = () => {
} else {
console.error("e n'est pas une Erreur ?!", e);
}
majEtatsActivationBoutons(entrees);
});
}
);
).ifLeft((erreur) => reporteErreur(erreur));
});
boutonSoustraction.addEventListener("click", () => {
Maybe.fromNullable(champQuantite.valueAsNumber).filter((valeur) => valeur > 1).ifJust((valeur) => {
boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
Either.encase(
() => parse(WCStoreCartUpdateItemArgsSchema, { key: clePanier, quantity: valeur - 1 })
).map(
(args) => {
postBackendWC({
async (args) => {
desactiveBoutonsEntreesPanier(entrees);
await postBackend({
corps: JSON.stringify(args),
nonce: ETATS_PAGE.nonce,
route: ROUTE_API_MAJ_ARTICLE_PANIER
@ -110,23 +135,17 @@ const initialiseScriptsPagePanier = () => {
// Récupère la Réponse
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse) => z(corpsReponse).with({ body: N.select(), status: 400 }, estWCError, leveBadRequestError).with({ body: N.select(), status: 401 }, estWCError, leveUnauthorizedError).with({ body: N.select(), status: 404 }, estWCError, leveNotFoundError).with(N._, (corpsOkInconnu) => parse(WCStoreCartSchema, corpsOkInconnu)).otherwise((e) => x(e, ErreurInconnue, leveErreur)),
(corpsReponse) => traiteReponseBackendWCSelonCodesHTTP(
corpsReponse,
WCStoreCartSchema
),
r((panier) => {
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: panier.items_count,
type: TYPES_MESSAGES.MajBoutonPanier
emetMessageMajBoutonPanier({ quantiteProduits: panier.items_count });
emetMessageMajContenuPanier({
produits: panier.items,
sousTotalPanier: Number(panier.totals.total_price) / 100,
totalPanier: Number(panier.totals.total_items) / 100
});
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: panier.items,
totalPanier: Number(panier.totals.total_items / 100)
},
type: TYPES_MESSAGES.MajContenuPanier
});
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
boutonSuppression.textContent = "Remove";
})
);
}).catch((e) => {
@ -135,6 +154,7 @@ const initialiseScriptsPagePanier = () => {
} else {
console.error("e n'est pas une Erreur ?!", e);
}
majEtatsActivationBoutons(entrees);
});
}
);
@ -142,15 +162,12 @@ const initialiseScriptsPagePanier = () => {
});
boutonAddition.addEventListener("click", () => {
Maybe.fromNullable(champQuantite.valueAsNumber).ifJust((valeur) => {
boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
desactiveBoutonsEntreesPanier(entrees);
Either.encase(
() => parse(WCStoreCartUpdateItemArgsSchema, { key: clePanier, quantity: valeur + 1 })
).map(
(args) => {
postBackendWC({
async (args) => {
await postBackend({
corps: JSON.stringify(args),
nonce: ETATS_PAGE.nonce,
route: ROUTE_API_MAJ_ARTICLE_PANIER
@ -160,23 +177,17 @@ const initialiseScriptsPagePanier = () => {
// Récupère la Réponse
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse) => z(corpsReponse).with({ body: N.select(), status: 400 }, estWCError, leveBadRequestError).with({ body: N.select(), status: 401 }, estWCError, leveUnauthorizedError).with({ body: N.select(), status: 404 }, estWCError, leveNotFoundError).with(N._, (corpsOkInconnu) => parse(WCStoreCartSchema, corpsOkInconnu)).otherwise((e) => x(e, ErreurInconnue, leveErreur)),
(corpsReponse) => traiteReponseBackendWCSelonCodesHTTP(
corpsReponse,
WCStoreCartSchema
),
r((panier) => {
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: panier.items_count,
type: TYPES_MESSAGES.MajBoutonPanier
emetMessageMajBoutonPanier({ quantiteProduits: panier.items_count });
emetMessageMajContenuPanier({
produits: panier.items,
sousTotalPanier: Number(panier.totals.total_price) / 100,
totalPanier: Number(panier.totals.total_items) / 100
});
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: panier.items,
totalPanier: Number(panier.totals.total_items / 100)
},
type: TYPES_MESSAGES.MajContenuPanier
});
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
boutonSuppression.textContent = "Remove";
})
);
}).catch((e) => {
@ -185,25 +196,25 @@ const initialiseScriptsPagePanier = () => {
} else {
console.error("e n'est pas une Erreur ?!", e);
}
majEtatsActivationBoutons(entrees);
});
}
);
});
});
})
);
});
});
};
const initialiseMajConteneurPanier = () => {
const CANAL_BOUTON_PANIER = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
CANAL_BOUTON_PANIER.onmessage = (evenementMessage) => {
valideMessageMajBoutonPanier(evenementMessage).ifRight((message) => {
CONTENEUR_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees !== 0));
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).onmessage = (evenementMessage) => {
valideMessageMajBoutonPanier(evenementMessage).map(p("donnees")).ifRight((donnees) => {
CONTENEUR_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(donnees.quantiteProduits !== 0));
});
};
};
const initialiseEcouteCanalMajContenuPanier = () => {
const initialiseMajContenuPanier = () => {
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).onmessage = (evenementMessage) => {
valideMessageMajContenuPanier(evenementMessage).map(p("donnees")).ifRight((donnees) => {
valideMessageMajContenuPanier(evenementMessage).chain(propEither("donnees")).ifRight((donnees) => {
donnees.produits.forEach((ligne) => {
ENTREES_PANIER_EITHER.ifRight((entrees) => {
Maybe.fromNullable(entrees.find((entree) => entree.getAttribute(ATTRIBUT_CLE_PANIER) === ligne.key)).ifJust((entree) => {
@ -214,16 +225,21 @@ const initialiseEcouteCanalMajContenuPanier = () => {
);
prixLigne.textContent = `${String(Number(ligne.totals.line_total) / 100)} €`;
champQuantite.setAttribute("value", String(ligne.quantity));
TOTAL_PANIER.textContent = `${donnees.totalPanier} €`;
majEtatsActivationBoutons(entrees);
});
SOUS_TOTAL_PANIER.textContent = `${String(donnees.totalPanier)} €`;
TOTAL_PANIER.textContent = `${String(donnees.totalPanier)} €`;
});
});
}).ifLeft((erreur) => {
reporteErreur(erreur);
ENTREES_PANIER_EITHER.ifRight((entrees) => majEtatsActivationBoutons(entrees));
});
};
};
document.addEventListener("DOMContentLoaded", () => {
initialiseScriptsPagePanier();
initialiseMajEntreesPanier();
initialiseMajConteneurPanier();
initialiseEcouteCanalMajContenuPanier();
initialiseMajContenuPanier();
});
//# sourceMappingURL=scripts-page-panier.js.map

File diff suppressed because one or more lines are too long

View file

@ -1,18 +1,21 @@
import { r, p, z, N } from "./index.y02cst4L.js";
import { r } from "./chunk-RU7WR4KH.D5j7HXCF.js";
import { r as recupereElementDocumentEither, a as recupereElementsDocumentEither, p } from "./utils.js";
import { x } from "./chunk-7BKSRZNG.C39W3Wne.js";
import { z, N } from "./index.CeK6pfoJ.js";
import { p as parse } from "./index.DD7qm8S6.js";
import { c as ROUTE_API_AJOUTE_ARTICLE_PANIER, d as ENTETE_WC_NONCE } from "./api2.js";
import { j as SELECTEUR_BOUTON_AJOUT_PANIER, k as SELECTEUR_SELECTEUR_QUANTITE, l as SELECTEUR_LIENS_ONGLETS, m as SELECTEUR_SECTIONS_CONTENUS, n as ATTRIBUT_ARIA_SELECTED, o as ATTRIBUT_HIDDEN, p as ATTRIBUT_DESACTIVE } from "./dom.js";
import { N as NOM_CANAL_BOUTON_PANIER, T as TYPES_MESSAGES } from "./messages3.js";
import { l as SELECTEUR_BOUTON_AJOUT_PANIER, m as SELECTEUR_SELECTEUR_QUANTITE, n as SELECTEUR_LIENS_ONGLETS, o as SELECTEUR_SECTIONS_CONTENUS, p as ATTRIBUT_ARIA_SELECTED, q as ATTRIBUT_HIDDEN, k as ATTRIBUT_DESACTIVE } from "./dom.js";
import { r as recupereElementOuLeve, b as recupereElementsOuLeve } from "./dom2.js";
import { l as leveServerError, a as leveBadRequestError, b as leveUnauthorizedError, c as leveNotFoundError, E as ErreurInconnue, d as leveErreur, r as reporteErreur } from "./erreurs.js";
import { b as estHTMLSelectElement, e as estReponse500, a as estError } from "./gardes.js";
import { e as emetMessageMajBoutonPanier } from "./messages.js";
import { p as parseWCStoreCartAddItemArgs } from "./cart-add-item.js";
import { W as WCStoreCartSchema } from "./cart.js";
import { e as estWCError } from "./erreurs2.js";
import { r as recupereElementDocumentEither, a as recupereElementsDocumentEither } from "./utils.js";
import { M as Maybe, E as Either } from "./Either.wHNxn7Os.js";
import "./exports.DNZBdkMD.js";
import "./messages3.js";
import "./messages2.js";
import "./cart2.js";
const ETATS_PAGE = _etats;
const deplieToutesSections = (ensembleLiensContenus) => {
@ -94,14 +97,13 @@ const ajouteProduitAuPanier = () => {
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse) => z(corpsReponse).with({ body: N.select(), status: 400 }, estWCError, leveBadRequestError).with({ body: N.select(), status: 401 }, estWCError, leveUnauthorizedError).with({ body: N.select(), status: 404 }, estWCError, leveNotFoundError).with(N._, (corpsOkInconnu) => parse(WCStoreCartSchema, corpsOkInconnu)).otherwise((e) => x(e, ErreurInconnue, leveErreur)),
r((panier) => console.debug("Panier", panier)),
// tap((panier: WCStoreCart) => console.debug("Panier", panier)),
// Récupère le nombre de Produits dans la Panier
p("items_count"),
// Déclenche les effets pour la mise à jour de l'IU
r((nombreArticlesPanier) => {
BOUTON_AJOUT_PANIER.textContent = "Added to cart!";
const CANAL_BOUTON_PANIER = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
CANAL_BOUTON_PANIER.postMessage({ donnees: nombreArticlesPanier, type: TYPES_MESSAGES.MajBoutonPanier });
emetMessageMajBoutonPanier({ quantiteProduits: nombreArticlesPanier });
setTimeout(() => {
SELECTEUR_VARIATION.value = SELECTEUR_VARIATION.options.item(0)?.value ?? "--";
BOUTON_AJOUT_PANIER.toggleAttribute(ATTRIBUT_DESACTIVE, true);

File diff suppressed because one or more lines are too long

View file

@ -1,12 +1,32 @@
import { c as recupereElementsAvecSelecteur, a as recupereElementAvecSelecteur } from "./dom2.js";
import { C as CleNonTrouveError } from "./erreurs.js";
import { M as Maybe } from "./Either.wHNxn7Os.js";
import "./chunk-7BKSRZNG.C39W3Wne.js";
import "./erreurs.js";
import "./exports.DNZBdkMD.js";
import "./Either.wHNxn7Os.js";
function u$1(t2, n, a) {
let o = (r) => t2(r, ...n);
return a === void 0 ? o : Object.assign(o, { lazy: a, lazyArgs: n });
}
function u(r, n, a) {
let o = r.length - n.length;
if (o === 0) return r(...n);
if (o === 1) return u$1(r, n, a);
throw new Error("Wrong number of arguments");
}
function p(...o) {
return u(t, o);
}
var t = (o, e) => o[e];
const recupereElementsDocumentEither = recupereElementsAvecSelecteur(document);
const recupereElementDocumentEither = recupereElementAvecSelecteur(document);
const propEither = (cle) => (donnees) => Maybe.fromNullable(p(donnees, cle)).toEither(
new CleNonTrouveError(`La clé « ${String(cle)} » n'a pas été trouvé dans l'objet.`, { objet: donnees })
);
export {
recupereElementsDocumentEither as a,
recupereElementDocumentEither as r
propEither as b,
p,
recupereElementDocumentEither as r,
u
};
//# sourceMappingURL=utils.js.map

View file

@ -1 +1 @@
{"version":3,"file":"utils.js","sources":["../../src/scripts/lib/utils.ts"],"sourcesContent":["import type { Either } from \"purify-ts\";\n\nimport { recupereElementAvecSelecteur, recupereElementsAvecSelecteur } from \"./dom.ts\";\n\nexport const recupereElementsDocumentEither: <E extends Element = Element>(\n selecteur: string,\n) => Either<SyntaxError, Array<E>> = recupereElementsAvecSelecteur(document);\n\nexport const recupereElementDocumentEither: <E extends Element = Element>(selecteur: string) => Either<SyntaxError, E> =\n recupereElementAvecSelecteur(document);\n"],"names":[],"mappings":";;;;;AAIa,MAAA,iCAEwB,8BAA8B,QAAQ;AAE9D,MAAA,gCACX,6BAA6B,QAAQ;"}
{"version":3,"file":"utils.js","sources":["../../../../../../node_modules/.pnpm/remeda@2.14.0/node_modules/remeda/dist/chunk-K26VP6CL.js","../../../../../../node_modules/.pnpm/remeda@2.14.0/node_modules/remeda/dist/chunk-RAAYCPUM.js","../../../../../../node_modules/.pnpm/remeda@2.14.0/node_modules/remeda/dist/chunk-VROY5Y5B.js","../../src/scripts/lib/utils.ts"],"sourcesContent":["function u(t,n,a){let o=r=>t(r,...n);return a===void 0?o:Object.assign(o,{lazy:a,lazyArgs:n})}export{u as a};\n","import{a as t}from\"./chunk-K26VP6CL.js\";function u(r,n,a){let o=r.length-n.length;if(o===0)return r(...n);if(o===1)return t(r,n,a);throw new Error(\"Wrong number of arguments\")}export{u as a};\n","import{a as n}from\"./chunk-RAAYCPUM.js\";function p(...o){return n(t,o)}var t=(o,e)=>o[e];export{p as a,t as b};\n","import { type Either, Maybe } from \"purify-ts\";\nimport { prop } from \"remeda\";\n\nimport { recupereElementAvecSelecteur, recupereElementsAvecSelecteur } from \"./dom.ts\";\nimport { CleNonTrouveError } from \"./erreurs.ts\";\n\nexport const recupereElementsDocumentEither: <E extends Element = Element>(\n selecteur: string,\n) => Either<SyntaxError, Array<E>> = recupereElementsAvecSelecteur(document);\n\nexport const recupereElementDocumentEither: <E extends Element = Element>(selecteur: string) => Either<SyntaxError, E> =\n recupereElementAvecSelecteur(document);\n\nexport const propEither = <T, K extends keyof T>(cle: K) => (donnees: T): Either<CleNonTrouveError, T[K]> =>\n Maybe\n .fromNullable(prop(donnees, cle))\n .toEither(\n new CleNonTrouveError(`La clé « ${String(cle)} » n'a pas été trouvé dans l'objet.`, { objet: donnees }),\n );\n"],"names":["u","t","n","prop"],"mappings":";;;;;AAAA,SAASA,IAAEC,IAAE,GAAE,GAAE;AAAC,MAAI,IAAE,OAAGA,GAAE,GAAE,GAAG,CAAC;AAAE,SAAO,MAAI,SAAO,IAAE,OAAO,OAAO,GAAE,EAAC,MAAK,GAAE,UAAS,EAAC,CAAC;AAAC;ACArD,SAAS,EAAE,GAAE,GAAE,GAAE;AAAC,MAAI,IAAE,EAAE,SAAO,EAAE;AAAO,MAAG,MAAI,EAAE,QAAO,EAAE,GAAG,CAAC;AAAE,MAAG,MAAI,EAAE,QAAOA,IAAE,GAAE,GAAE,CAAC;AAAE,QAAM,IAAI,MAAM,2BAA2B;AAAC;ACAvI,SAAS,KAAK,GAAE;AAAC,SAAOC,EAAE,GAAE,CAAC;AAAC;AAAC,IAAI,IAAE,CAAC,GAAE,MAAI,EAAE,CAAC;ACM1E,MAAA,iCAEwB,8BAA8B,QAAQ;AAE9D,MAAA,gCACX,6BAA6B,QAAQ;AAE1B,MAAA,aAAa,CAAuB,QAAW,CAAC,YAC3D,MACG,aAAaC,EAAK,SAAS,GAAG,CAAC,EAC/B;AAAA,EACC,IAAI,kBAAkB,YAAY,OAAO,GAAG,CAAC,uCAAuC,EAAE,OAAO,SAAS;AACxG;","x_google_ignoreList":[0,1,2]}

View file

@ -21,4 +21,5 @@ export const SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE = "button.detail-produit__ac
export const SELECTEUR_BOUTON_ADDITION_QUANTITE = "button.detail-produit__actions__addition";
export const SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER = "input";
export const SELECTEUR_PRIX_LIGNE_PANIER = ".detail-produit__nom-prix span";
export const SELECTEUR_SOUS_TOTAL_PANIER = "#panneau-panier .panneau__sous-totaux__ligne strong";
export const SELECTEUR_TOTAL_PANIER = "#panneau-panier .panneau__pied-de-page p span";

View file

@ -3,6 +3,7 @@
*/
import { captureException } from "@sentry/browser";
import { pipe } from "remeda";
import type { WCErrorBody } from "./types/api/erreurs";
@ -51,13 +52,17 @@ export class DOMElementAbsentError extends Error {
this.name = "DOMElementAbsentError";
}
}
export class CleNonTrouveError extends Error {
constructor(message: unknown) {
super(JSON.stringify(message));
this.name = "CleNonTrouveError";
}
}
/* Fonction utilitaire pour créer ou lever des Erreurs */
export const Erreur = (message: string): Error => new Error(message);
export const ErreurInconnue = (erreur: unknown): UnknownError => new UnknownError(erreur);
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- Permet d'indiquer
le type d'Erreur à l'appel de la fonction. */
export const leveErreur = <E extends Error = Error>(erreur: E): never => {
throw erreur;
};
@ -83,8 +88,7 @@ export const leveUnknownError = (erreur: unknown): never => {
* @param erreur
* @returns L'ID Sentry de l'évènement capturé.
*/
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- Permet d'indiquer
le type d'Erreur à l'appel de la fonction. */
export const reporteErreur = <E extends Error>(erreur: E): string => {
console.error(erreur);
return captureException(erreur);
@ -97,9 +101,19 @@ export const reporteErreur = <E extends Error>(erreur: E): string => {
* @param erreur
* @returns never Lève une Erreur et ne retourne donc rien.
*/
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- Permet d'indiquer
le type d'Erreur à l'appel de la fonction. */
export const reporteEtLeveErreur = <E extends Error>(erreur: E): never => {
reporteErreur<E>(erreur);
throw erreur;
};
/**
* Fonction utilitaire pour rapidement créer et reporter une Erreur DOMElementAbsent.
*
* @param message
* @returns L'ID Sentry de l'évènement capturé.
*/
export const reporteErreurDOMElementAbsent = (message: string): string =>
pipe(
new DOMElementAbsentError(message),
reporteErreur,
);

View file

@ -1,11 +1,38 @@
import { Either } from "purify-ts";
import { parse, type ValiError } from "valibot";
import type { MessageMajBoutonPanier, MessageMajContenuPanier } from "./types/messages";
import type {
MessageMajBoutonPanier,
MessageMajBoutonPanierDonnees,
MessageMajContenuPanier,
MessageMajContenuPanierDonnees,
} from "./types/messages";
import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER, TYPES_MESSAGES } from "../constantes/messages.ts";
import { reporteErreur } from "./erreurs.ts";
import { MessageMajBoutonPanierSchema, MessageMajContenuPanierSchema } from "./schemas/messages.ts";
// Émissions
export const emetMessageMajBoutonPanier = (args: MessageMajBoutonPanierDonnees): void => {
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: {
quantiteProduits: args.quantiteProduits,
},
type: TYPES_MESSAGES.MajBoutonPanier,
} as MessageMajBoutonPanier);
};
export const emetMessageMajContenuPanier = (args: MessageMajContenuPanierDonnees): void =>
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: args.produits,
sousTotalPanier: args.sousTotalPanier,
totalPanier: args.totalPanier,
},
type: TYPES_MESSAGES.MajContenuPanier,
} as MessageMajContenuPanier);
// Validations
export const valideMessageMajBoutonPanier = (
evenementMessage: MessageEvent<unknown>,
): Either<ValiError<typeof MessageMajBoutonPanierSchema>, MessageMajBoutonPanier> =>
@ -13,9 +40,7 @@ export const valideMessageMajBoutonPanier = (
.of<ValiError<typeof MessageMajBoutonPanierSchema>, MessageMajBoutonPanier>(
parse(MessageMajBoutonPanierSchema, evenementMessage.data),
)
.ifLeft(erreur => {
reporteErreur(erreur);
});
.ifLeft(erreur => reporteErreur(erreur));
export const valideMessageMajContenuPanier = (
evenementMessage: MessageEvent<unknown>,
@ -24,6 +49,4 @@ export const valideMessageMajContenuPanier = (
.of<ValiError<typeof MessageMajContenuPanierSchema>, MessageMajContenuPanier>(
parse(MessageMajContenuPanierSchema, evenementMessage.data),
)
.ifLeft(erreur => {
reporteErreur(erreur);
});
.ifLeft(erreur => reporteErreur(erreur));

View file

@ -14,12 +14,15 @@ import {
import { estWCError } from "./schemas/erreurs.ts";
type ArgumentsPostBackendWC = {
/** Le corps de la requête (ses arguments). */
corps: BodyInit;
/** Une chaîne de caractères généré par le backend et à joindre à chaque requête pour l'authentifier. */
nonce: string;
/** La route, ou chemin, de l'API à demander au backend. */
route: string;
};
export const postBackendWC = (args: ArgumentsPostBackendWC) =>
export const postBackend = (args: ArgumentsPostBackendWC) =>
fetch(
args.route,
{
@ -36,13 +39,16 @@ export const postBackendWC = (args: ArgumentsPostBackendWC) =>
},
);
export const traiteReponseBackendWCSelonCodesHTTP = (corpsReponse: unknown, schemaReponse: GenericSchema) =>
export const traiteReponseBackendWCSelonCodesHTTP = <R, S extends GenericSchema<R>>(
corpsReponse: unknown,
schemaReponse: S,
): R =>
match(corpsReponse)
// Réponses problématiques
.with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)
.with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)
.with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)
// Réponse OK (201)
.with(P._, corpsOkInconnu => parse(schemaReponse, corpsOkInconnu))
.with(P._, corpsOkInconnu => parse<S>(schemaReponse, corpsOkInconnu))
// Réponses inconnues
.otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>));

View file

@ -40,6 +40,27 @@ export const WCStoreCartItemSchema = v.object({
"variation": v.array(v.unknown()),
});
export const WCStoreCartTotalsSchema = v.object({
"currency_code": v.string(),
"currency_decimal_separator": v.string(),
"currency_minor_unit": v.number(),
"currency_prefix": v.string(),
"currency_suffix": v.string(),
"currency_symbol": v.string(),
"currency_thousand_separator": v.string(),
"tax_lines": v.array(v.unknown()),
"total_discount": v.string(),
"total_discount_tax": v.string(),
"total_fees": v.string(),
"total_fees_tax": v.string(),
"total_items": v.string(),
"total_items_tax": v.string(),
"total_price": v.string(),
"total_shipping": v.union([v.string(), v.null()]),
"total_shipping_tax": v.union([v.string(), v.null()]),
"total_tax": v.string(),
});
export const WCStoreCartSchema = v.object({
billing_address: v.unknown(),
coupons: v.unknown(),
@ -57,5 +78,5 @@ export const WCStoreCartSchema = v.object({
payment_requirements: v.unknown(),
shipping_address: v.unknown(),
shipping_rates: v.unknown(),
totals: v.unknown(),
totals: WCStoreCartTotalsSchema,
});

View file

@ -9,13 +9,18 @@ import { WCStoreCartItemSchema } from "./cart.ts";
export const TypesMessagesSchema = v.enum(TYPES_MESSAGES);
export const MessageMajBoutonPanierDonneesSchema = v.object({
quantiteProduits: v.number(),
});
export const MessageMajBoutonPanierSchema = v.object({
donnees: v.number(),
donnees: MessageMajBoutonPanierDonneesSchema,
type: v.pipe(v.string(), v.value(TYPES_MESSAGES.MajBoutonPanier)),
});
export const MessageMajContenuPanierDonneesSchema = v.object({
produits: v.array(WCStoreCartItemSchema),
sousTotalPanier: v.number(),
totalPanier: v.number(),
});

View file

@ -1,11 +1,14 @@
import type { InferOutput } from "valibot";
import type {
MessageMajBoutonPanierDonneesSchema,
MessageMajBoutonPanierSchema,
MessageMajContenuPanierDonneesSchema,
MessageMajContenuPanierSchema,
} from "../schemas/messages.ts";
export type MessageMajBoutonPanierDonnees = InferOutput<typeof MessageMajBoutonPanierDonneesSchema>;
export type MessageMajBoutonPanier = InferOutput<typeof MessageMajBoutonPanierSchema>;
export type MessageMajContenuPanierDonnees = InferOutput<typeof MessageMajContenuPanierDonneesSchema>;
export type MessageMajContenuPanier = InferOutput<typeof MessageMajContenuPanierSchema>;

View file

@ -1,6 +1,8 @@
import type { Either } from "purify-ts";
import { type Either, Maybe } from "purify-ts";
import { prop } from "remeda";
import { recupereElementAvecSelecteur, recupereElementsAvecSelecteur } from "./dom.ts";
import { CleNonTrouveError } from "./erreurs.ts";
export const recupereElementsDocumentEither: <E extends Element = Element>(
selecteur: string,
@ -8,3 +10,10 @@ export const recupereElementsDocumentEither: <E extends Element = Element>(
export const recupereElementDocumentEither: <E extends Element = Element>(selecteur: string) => Either<SyntaxError, E> =
recupereElementAvecSelecteur(document);
export const propEither = <T, K extends keyof T>(cle: K) => (donnees: T): Either<CleNonTrouveError, T[K]> =>
Maybe
.fromNullable(prop(donnees, cle))
.toEither(
new CleNonTrouveError(`La clé « ${String(cle)} » n'a pas été trouvé dans l'objet.`, { objet: donnees }),
);

View file

@ -24,8 +24,8 @@ const initialiseBoutonPanier = (): void => {
valideMessageMajBoutonPanier(evenementMessage)
// Met à jour le Bouton du Panier
.ifRight((message: MessageMajBoutonPanier) => {
BOUTON_PANIER.textContent = `cart (${String(message.donnees)})`;
BOUTON_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees > 0));
BOUTON_PANIER.textContent = `cart (${String(message.donnees.quantiteProduits)})`;
BOUTON_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees.quantiteProduits > 0));
});
};
};

View file

@ -1,21 +1,18 @@
import { Either, Maybe } from "purify-ts";
import { pipe, prop, tap } from "remeda";
import { match, P } from "ts-pattern";
import { parse } from "valibot";
import { parse, type ValiError } from "valibot";
import type { MessageMajContenuPanierSchema } from "./lib/schemas/messages.ts";
import type { WCStoreCart, WCStoreCartItem } from "./lib/types/api/cart";
import type { WCStoreCartRemoveItemArgs } from "./lib/types/api/cart-remove-item";
import type { WCStoreCartUpdateItemArgs } from "./lib/types/api/cart-update-item";
import type {
MessageMajBoutonPanier,
MessageMajContenuPanier,
MessageMajContenuPanierDonnees,
} from "./lib/types/messages";
import type { MessageMajBoutonPanierDonnees, MessageMajContenuPanierDonnees } from "./lib/types/messages";
import { ROUTE_API_MAJ_ARTICLE_PANIER, ROUTE_API_RETIRE_ARTICLE_PANIER } from "./constantes/api.ts";
import {
ATTRIBUT_CLE_PANIER,
ATTRIBUT_CONTIENT_ARTICLES,
ATTRIBUT_DESACTIVE,
SELECTEUR_BOUTON_ADDITION_QUANTITE,
SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE,
SELECTEUR_BOUTON_SUPPRESSION_PANIER,
@ -23,29 +20,24 @@ import {
SELECTEUR_CONTENEUR_PANIER,
SELECTEUR_ENTREES_PANIER,
SELECTEUR_PRIX_LIGNE_PANIER,
SELECTEUR_SOUS_TOTAL_PANIER,
SELECTEUR_TOTAL_PANIER,
} from "./constantes/dom.ts";
import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER, TYPES_MESSAGES } from "./constantes/messages.ts";
import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER } from "./constantes/messages.ts";
import { recupereElementAvecSelecteur, recupereElementOuLeve } from "./lib/dom.ts";
import {
DOMElementAbsentError,
ErreurInconnue,
leveBadRequestError,
leveErreur,
leveNotFoundError,
leveServerError,
leveUnauthorizedError,
reporteErreur,
type UnknownError,
} from "./lib/erreurs.ts";
import { type CleNonTrouveError, leveServerError, reporteErreur } from "./lib/erreurs.ts";
import { estError, estReponse500 } from "./lib/gardes.ts";
import { valideMessageMajBoutonPanier, valideMessageMajContenuPanier } from "./lib/messages.ts";
import { postBackendWC } from "./lib/reseau.ts";
import {
emetMessageMajBoutonPanier,
emetMessageMajContenuPanier,
valideMessageMajBoutonPanier,
valideMessageMajContenuPanier,
} from "./lib/messages.ts";
import { postBackend, traiteReponseBackendWCSelonCodesHTTP } from "./lib/reseau.ts";
import { WCStoreCartRemoveItemArgsSchema } from "./lib/schemas/cart-remove-item.ts";
import { WCStoreCartUpdateItemArgsSchema } from "./lib/schemas/cart-update-item.ts";
import { WCStoreCartSchema } from "./lib/schemas/cart.ts";
import { estWCError } from "./lib/schemas/erreurs.ts";
import { recupereElementDocumentEither, recupereElementsDocumentEither } from "./lib/utils.ts";
import { propEither, recupereElementDocumentEither, recupereElementsDocumentEither } from "./lib/utils.ts";
/** États utiles pour les scripts de la page. */
type EtatsPage = {
@ -53,6 +45,13 @@ type EtatsPage = {
nonce: string;
};
type ElementsEntreePanier = {
boutonAddition: HTMLButtonElement;
boutonSoustraction: HTMLButtonElement;
boutonSuppression: HTMLButtonElement;
champQuantite?: HTMLInputElement;
};
// @ts-expect-error -- États injectés par le modèle PHP
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- États injectés par le modèle PHP
const ETATS_PAGE: EtatsPage = _etats;
@ -61,40 +60,73 @@ const ETATS_PAGE: EtatsPage = _etats;
const ENTREES_PANIER_EITHER: Either<SyntaxError, Array<HTMLElement>> = recupereElementsDocumentEither<HTMLElement>(
SELECTEUR_ENTREES_PANIER,
);
const CONTENEUR_PANIER: HTMLElement = pipe(
recupereElementDocumentEither<HTMLElement>(SELECTEUR_CONTENEUR_PANIER),
recupereElementOuLeve,
);
const SOUS_TOTAL_PANIER: HTMLElement = pipe(
recupereElementDocumentEither<HTMLParagraphElement>(SELECTEUR_SOUS_TOTAL_PANIER),
recupereElementOuLeve,
);
const TOTAL_PANIER: HTMLParagraphElement = pipe(
recupereElementDocumentEither<HTMLParagraphElement>(SELECTEUR_TOTAL_PANIER),
recupereElementOuLeve,
);
/**
* Fonction utilitaire pour rapidement créer et reporter une Erreur DOMElementAbsent.
* Fonction utilitaire pour récupérer un Élément dans une ligne (entrée) du Panier, en levant une
* Erreur s'il n'existe pas.
*
* @param message
* @returns L'ID Sentry de l'évènement capturé.
* @param entree L'entrée du Panier sous forme d'Élément dans le DOM.
* @returns L'Élément demandé.
* @throws Une SyntaxError si l'Élément n'est pas trouvé.
*/
const reporteErreurDOMElementAbsent = (message: string): string =>
pipe(
new DOMElementAbsentError(message),
reporteErreur,
);
const recupereElementDansEntreePanierOuLeve =
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- Nécessaire pour
documenter le type d'Element attendu */
(entree: HTMLElement) => <E extends Element = Element>(selecteur: string) =>
pipe(
recupereElementAvecSelecteur(entree)<E>(selecteur),
recupereElementOuLeve,
);
const initialiseScriptsPagePanier = (): void => {
ENTREES_PANIER_EITHER.ifRight((entrees: Array<HTMLElement>) =>
const desactiveBoutonsEntreesPanier = (entrees: Array<HTMLElement>): void =>
entrees.forEach((entree: HTMLElement) => {
// Fonction utilitaire
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
const elements: ElementsEntreePanier = {
boutonAddition: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_ADDITION_QUANTITE),
boutonSoustraction: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
boutonSuppression: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_SUPPRESSION_PANIER),
};
elements.boutonSoustraction.setAttribute(ATTRIBUT_DESACTIVE, "");
elements.boutonAddition.setAttribute(ATTRIBUT_DESACTIVE, "");
elements.boutonSuppression.setAttribute(ATTRIBUT_DESACTIVE, "");
elements.boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
});
const majEtatsActivationBoutons = (entrees: Array<HTMLElement>): void =>
entrees.forEach((entree: HTMLElement) => {
// Fonction utilitaire
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
const elements: ElementsEntreePanier = {
boutonAddition: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_ADDITION_QUANTITE),
boutonSoustraction: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
boutonSuppression: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_SUPPRESSION_PANIER),
champQuantite: recupereElementDansEntree<HTMLInputElement>(SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER),
};
Number(elements.champQuantite?.value) === 1
? elements.boutonSoustraction.setAttribute(ATTRIBUT_DESACTIVE, "")
: elements.boutonSoustraction.removeAttribute(ATTRIBUT_DESACTIVE);
elements.boutonAddition.removeAttribute(ATTRIBUT_DESACTIVE);
elements.boutonSuppression.removeAttribute(ATTRIBUT_DESACTIVE);
elements.boutonSuppression.textContent = "Remove";
});
const initialiseMajEntreesPanier = (): void => {
ENTREES_PANIER_EITHER.ifRight((entrees: Array<HTMLElement>) => {
entrees.forEach((entree: HTMLElement) => {
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
@ -115,15 +147,18 @@ const initialiseScriptsPagePanier = (): void => {
// Supprime la ligne du Panier au clic sur le bouton de suppression
boutonSuppression.addEventListener("click", (): void => {
// TODO: Créer une boucle d'animation
// Affiche un texte de chargement dans le Bouton
boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
Either
.encase<Error, WCStoreCartRemoveItemArgs>(() => parse(WCStoreCartRemoveItemArgsSchema, { key: clePanier }))
// Valide un corps de requête
.encase<ValiError<typeof WCStoreCartRemoveItemArgsSchema>, WCStoreCartRemoveItemArgs>(() =>
parse(WCStoreCartRemoveItemArgsSchema, { key: clePanier })
)
.map(
(args: WCStoreCartRemoveItemArgs) => {
postBackendWC({
async (args: WCStoreCartRemoveItemArgs) => {
// Modifie des éléments du DOM pour signaler la requête et empêcher des doubles exécutions
desactiveBoutonsEntreesPanier(entrees);
// Réalise la requête auprès du backend
await postBackend({
corps: JSON.stringify(args),
nonce: ETATS_PAGE.nonce,
route: ROUTE_API_RETIRE_ARTICLE_PANIER,
@ -137,30 +172,19 @@ const initialiseScriptsPagePanier = (): void => {
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse: unknown) =>
match(corpsReponse)
// Réponses problématiques
.with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)
.with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)
.with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)
// Réponse OK (201)
.with(P._, corpsOkInconnu => parse(WCStoreCartSchema, corpsOkInconnu))
// Réponses inconnues
.otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>)),
traiteReponseBackendWCSelonCodesHTTP<WCStoreCart, typeof WCStoreCartSchema>(
corpsReponse,
WCStoreCartSchema,
),
// Émets des Messages via BroadcastChannels pour la mise à jour de la page
tap((panier: WCStoreCart) => {
// Émet un Message avec le nouveau contenu du Panier
// TODO: Valider le Message avant de l'émettre
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: panier.items,
totalPanier: Number(panier.totals.total_items / 100),
},
type: TYPES_MESSAGES.MajContenuPanier,
} as MessageMajContenuPanier);
// Émet un Message avec le nouveau nombre de Produits dans le Panier
// TODO: Valider le Message avant de l'émettre
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: panier.items_count,
type: TYPES_MESSAGES.MajBoutonPanier,
emetMessageMajBoutonPanier({ quantiteProduits: panier.items_count });
// Émet un Message avec le nouveau contenu du Panier
emetMessageMajContenuPanier({
produits: panier.items,
sousTotalPanier: Number(panier.totals.total_price) / 100,
totalPanier: Number(panier.totals.total_items) / 100,
});
// Retire l'entrée du Panier du DOM
entree.remove();
@ -173,32 +197,31 @@ const initialiseScriptsPagePanier = (): void => {
} else {
console.error("e n'est pas une Erreur ?!", e);
}
majEtatsActivationBoutons(entrees);
});
},
);
)
.ifLeft((erreur: ValiError<typeof WCStoreCartRemoveItemArgsSchema>) => reporteErreur(erreur));
});
// Retire une unité à une ligne du Panier au clic sur le bouton de soustraction
boutonSoustraction.addEventListener("click", () => {
boutonSoustraction.addEventListener("click", (): void => {
Maybe
.fromNullable(champQuantite.valueAsNumber)
.filter((valeur) => valeur > 1)
.ifJust((valeur) => {
// Modifie des éléments du DOM pour signaler la requête et empêcher des doubles exécutions
boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
Either
// Valide les arguments de la requête
.encase<Error, WCStoreCartUpdateItemArgs>(() =>
parse(WCStoreCartUpdateItemArgsSchema, { key: clePanier, quantity: valeur - 1 })
)
.map(
(args: WCStoreCartUpdateItemArgs) => {
async (args: WCStoreCartUpdateItemArgs) => {
// Modifie des éléments du DOM pour signaler la requête et empêcher des doubles exécutions
desactiveBoutonsEntreesPanier(entrees);
// Réalise la requête
postBackendWC({
await postBackend({
corps: JSON.stringify(args),
nonce: ETATS_PAGE.nonce,
route: ROUTE_API_MAJ_ARTICLE_PANIER,
@ -212,36 +235,19 @@ const initialiseScriptsPagePanier = (): void => {
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse: unknown) =>
match(corpsReponse)
// Réponses problématiques
.with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)
.with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)
.with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)
// Réponse OK (201)
.with(P._, corpsOkInconnu => parse(WCStoreCartSchema, corpsOkInconnu))
// Réponses inconnues
.otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>)),
traiteReponseBackendWCSelonCodesHTTP<WCStoreCart, typeof WCStoreCartSchema>(
corpsReponse,
WCStoreCartSchema,
),
tap((panier: WCStoreCart) => {
// Émet un message pour la mise à jour du bouton du Panier
// TODO: Valider le Message avant de l'émettre
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: panier.items_count,
type: TYPES_MESSAGES.MajBoutonPanier,
});
// Émet un Message avec le nouveau nombre de Produits dans le Panier
emetMessageMajBoutonPanier({ quantiteProduits: panier.items_count });
// Émet un Message avec le nouveau contenu du Panier
// TODO: Valider le Message avant de l'émettre
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: panier.items,
totalPanier: Number(panier.totals.total_items / 100),
},
type: TYPES_MESSAGES.MajContenuPanier,
} as MessageMajContenuPanier);
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
boutonSuppression.textContent = "Remove";
emetMessageMajContenuPanier({
produits: panier.items,
sousTotalPanier: Number(panier.totals.total_price) / 100,
totalPanier: Number(panier.totals.total_items) / 100,
});
}),
);
})
@ -251,6 +257,8 @@ const initialiseScriptsPagePanier = (): void => {
} else {
console.error("e n'est pas une Erreur ?!", e);
}
majEtatsActivationBoutons(entrees);
});
},
);
@ -258,16 +266,12 @@ const initialiseScriptsPagePanier = (): void => {
});
// Ajoute une unité à une ligne du Panier au clic sur le bouton d'addition
boutonAddition.addEventListener("click", () => {
boutonAddition.addEventListener("click", (): void => {
Maybe
.fromNullable(champQuantite.valueAsNumber)
.ifJust((valeur) => {
// Modifie des éléments du DOM pour signifier le traitement de la requête et empêcher des
// doubles exécutions
boutonSuppression.textContent = "C= C= C= C= C=┌(;・ω・)┘";
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
// Modifie des éléments du DOM pour signaler la requête et empêcher des doubles exécutions
desactiveBoutonsEntreesPanier(entrees);
Either
// Valide les arguments de la requête
@ -275,9 +279,9 @@ const initialiseScriptsPagePanier = (): void => {
parse(WCStoreCartUpdateItemArgsSchema, { key: clePanier, quantity: valeur + 1 })
)
.map(
(args: WCStoreCartUpdateItemArgs) => {
async (args: WCStoreCartUpdateItemArgs) => {
// Réalise la requête
postBackendWC({
await postBackend({
corps: JSON.stringify(args),
nonce: ETATS_PAGE.nonce,
route: ROUTE_API_MAJ_ARTICLE_PANIER,
@ -291,36 +295,19 @@ const initialiseScriptsPagePanier = (): void => {
await reponse.json(),
// Traite tous les codes HTTPs possibles
(corpsReponse: unknown) =>
match(corpsReponse)
// Réponses problématiques
.with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)
.with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)
.with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)
// Réponse OK (201)
.with(P._, corpsOkInconnu => parse(WCStoreCartSchema, corpsOkInconnu))
// Réponses inconnues
.otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>)),
traiteReponseBackendWCSelonCodesHTTP<WCStoreCart, typeof WCStoreCartSchema>(
corpsReponse,
WCStoreCartSchema,
),
tap((panier: WCStoreCart) => {
// Émet un message pour la mise à jour du bouton du Panier
// TODO: Valider le Message avant de l'émettre
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).postMessage({
donnees: panier.items_count,
type: TYPES_MESSAGES.MajBoutonPanier,
});
// Émet un Message avec le nouveau nombre de Produits dans le Panier
emetMessageMajBoutonPanier({ quantiteProduits: panier.items_count });
// Émet un Message avec le nouveau contenu du Panier
// TODO: Valider le Message avant de l'émettre
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).postMessage({
donnees: {
produits: panier.items,
totalPanier: Number(panier.totals.total_items / 100),
},
type: TYPES_MESSAGES.MajContenuPanier,
} as MessageMajContenuPanier);
boutonSoustraction.toggleAttribute("disabled");
boutonAddition.toggleAttribute("disabled");
boutonSuppression.toggleAttribute("disabled");
boutonSuppression.textContent = "Remove";
emetMessageMajContenuPanier({
produits: panier.items,
sousTotalPanier: Number(panier.totals.total_price) / 100,
totalPanier: Number(panier.totals.total_items) / 100,
});
}),
);
})
@ -330,42 +317,40 @@ const initialiseScriptsPagePanier = (): void => {
} else {
console.error("e n'est pas une Erreur ?!", e);
}
majEtatsActivationBoutons(entrees);
});
},
);
});
});
})
);
});
});
};
const initialiseMajConteneurPanier = (): void => {
const CANAL_BOUTON_PANIER: BroadcastChannel = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
CANAL_BOUTON_PANIER.onmessage = (evenementMessage: MessageEvent<unknown>): void => {
new BroadcastChannel(NOM_CANAL_BOUTON_PANIER).onmessage = (evenementMessage: MessageEvent<unknown>): void => {
valideMessageMajBoutonPanier(evenementMessage)
.map(prop("donnees"))
// Met à jour le Bouton du Panier
.ifRight((message: MessageMajBoutonPanier) => {
CONTENEUR_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(message.donnees !== 0));
.ifRight((donnees: MessageMajBoutonPanierDonnees) => {
CONTENEUR_PANIER.setAttribute(ATTRIBUT_CONTIENT_ARTICLES, String(donnees.quantiteProduits !== 0));
});
};
};
const initialiseEcouteCanalMajContenuPanier = (): void => {
const initialiseMajContenuPanier = (): void => {
new BroadcastChannel(NOM_CANAL_CONTENU_PANIER).onmessage = (evenementMessage: MessageEvent<unknown>): void => {
/**
* À la réception d'un Événement (contenu le Panier), mettre à jour :
* - les quantités ;
* - les prix ;
*/
valideMessageMajContenuPanier(evenementMessage)
.chain(propEither("donnees"))
// Met à jour le contenu du Panier
.map(prop("donnees"))
.ifRight((donnees: MessageMajContenuPanierDonnees) => {
donnees.produits.forEach((ligne: WCStoreCartItem) => {
// Met à jour les entrées du Panier
ENTREES_PANIER_EITHER.ifRight((entrees: Array<HTMLElement>) => {
Maybe
.fromNullable(entrees.find((entree) => entree.getAttribute(ATTRIBUT_CLE_PANIER) === ligne.key))
.ifJust((entree) => {
.ifJust((entree: HTMLElement) => {
// Fonction utilitaire
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
@ -376,16 +361,26 @@ const initialiseEcouteCanalMajContenuPanier = (): void => {
prixLigne.textContent = `${String(Number(ligne.totals.line_total) / 100)} €`;
champQuantite.setAttribute("value", String(ligne.quantity));
TOTAL_PANIER.textContent = `${donnees.totalPanier} €`;
majEtatsActivationBoutons(entrees);
});
// Met à jour les totaux du Panier
SOUS_TOTAL_PANIER.textContent = `${String(donnees.totalPanier)} €`;
TOTAL_PANIER.textContent = `${String(donnees.totalPanier)} €`;
});
});
})
// Reporte tout Erreur et réactive les Boutons
.ifLeft((erreur: CleNonTrouveError | ValiError<typeof MessageMajContenuPanierSchema>) => {
reporteErreur(erreur);
ENTREES_PANIER_EITHER.ifRight(entrees => majEtatsActivationBoutons(entrees));
});
};
};
document.addEventListener("DOMContentLoaded", () => {
initialiseScriptsPagePanier();
document.addEventListener("DOMContentLoaded", (): void => {
initialiseMajEntreesPanier();
initialiseMajConteneurPanier();
initialiseEcouteCanalMajContenuPanier();
initialiseMajContenuPanier();
});

View file

@ -5,7 +5,6 @@ import { pipe, prop, tap } from "remeda";
import { match, P } from "ts-pattern";
import { parse } from "valibot";
import type { WCStoreCart } from "./lib/types/api/cart";
import type { WCStoreCartAddItemArgs } from "./lib/types/api/cart-add-item.ts";
import { ENTETE_WC_NONCE, ROUTE_API_AJOUTE_ARTICLE_PANIER } from "./constantes/api.ts";
@ -18,7 +17,6 @@ import {
SELECTEUR_SECTIONS_CONTENUS,
SELECTEUR_SELECTEUR_QUANTITE,
} from "./constantes/dom";
import { NOM_CANAL_BOUTON_PANIER, TYPES_MESSAGES } from "./constantes/messages.ts";
import { recupereElementOuLeve, recupereElementsOuLeve } from "./lib/dom.ts";
import {
ErreurInconnue,
@ -31,6 +29,7 @@ import {
type UnknownError,
} from "./lib/erreurs.ts";
import { estError, estHTMLSelectElement, estReponse500 } from "./lib/gardes.ts";
import { emetMessageMajBoutonPanier } from "./lib/messages.ts";
import { parseWCStoreCartAddItemArgs } from "./lib/schemas/cart-add-item.ts";
import { WCStoreCartSchema } from "./lib/schemas/cart.ts";
import { estWCError } from "./lib/schemas/erreurs.ts";
@ -188,20 +187,13 @@ const ajouteProduitAuPanier = () => {
.with(P._, corpsOkInconnu => parse(WCStoreCartSchema, corpsOkInconnu))
// Réponses inconnues
.otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>)),
tap((panier: WCStoreCart) => console.debug("Panier", panier)),
// tap((panier: WCStoreCart) => console.debug("Panier", panier)),
// Récupère le nombre de Produits dans la Panier
prop("items_count"),
// Déclenche les effets pour la mise à jour de l'IU
tap((nombreArticlesPanier: number) => {
/**
* À la réception du nouveau Panier du backend :
* 1. Met à jour la quantité de Produits dans le Bouton du Panier
* 2. Met à jour le Bouton d'ajout au Panier avec un message de succès
* 3. (3 secondes) Réinitialise le Sélecteur de Quantité et le Bouton d'Ajout au Panier
*/
BOUTON_AJOUT_PANIER.textContent = "Added to cart!";
const CANAL_BOUTON_PANIER: BroadcastChannel = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
CANAL_BOUTON_PANIER.postMessage({ donnees: nombreArticlesPanier, type: TYPES_MESSAGES.MajBoutonPanier });
emetMessageMajBoutonPanier({ quantiteProduits: nombreArticlesPanier });
// TODO: Prévoir un cas où ce Timeout est annulé quand l'Utilisateur agit avant sur le Sélecteur
setTimeout(() => {