react-shopwave-connect 0.4.6 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -3
- package/dist/core/index.cjs +274 -130
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +292 -145
- package/dist/core/index.d.ts +292 -145
- package/dist/core/index.js +269 -131
- package/dist/core/index.js.map +1 -1
- package/dist/hooks/index.cjs +265 -112
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +90 -23
- package/dist/hooks/index.d.ts +90 -23
- package/dist/hooks/index.js +265 -113
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +294 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +301 -145
- package/dist/index.d.ts +301 -145
- package/dist/index.js +288 -131
- package/dist/index.js.map +1 -1
- package/dist/next/index.cjs +67 -0
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +33 -2
- package/dist/next/index.d.ts +33 -2
- package/dist/next/index.js +67 -0
- package/dist/next/index.js.map +1 -1
- package/dist/server/index.cjs +68 -0
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +40 -3
- package/dist/server/index.d.ts +40 -3
- package/dist/server/index.js +68 -1
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/next/index.cjs
CHANGED
|
@@ -356,6 +356,27 @@ const SHOPWAVE_LOOKUPS = Object.freeze({
|
|
|
356
356
|
* - employee: POST updates `roleId`, `joinedDate`, `exitDate` (names can't be
|
|
357
357
|
* changed); no DELETE (live API: "Cannot DELETE /employee") → retired via `exitDate`.
|
|
358
358
|
* - consumer: read-only (`GET` with `ids`, comma-separated); live POST → 404.
|
|
359
|
+
* - productComponent: modifier groups, `/product/component` (live, staging, 11 Nov 2026). The
|
|
360
|
+
* API reference lists no read filters; these are what the live API does:
|
|
361
|
+
* - Reads filter by `componentIds` (group ids) or `productIds` (the parent product; option
|
|
362
|
+
* products don't match). `productComponentIds` is ignored on reads: every group comes back.
|
|
363
|
+
* `deleted: false` gives live groups only, `true` deleted groups only, no header both.
|
|
364
|
+
* No match → 204 with an empty body. No order, sort, priority or position field anywhere.
|
|
365
|
+
* - Groups are keyed by id; `products` (option products) by product id; `productInstances`
|
|
366
|
+
* (option rows) by row id. Reads reformat values: price `"100"` → `"100.0"`,
|
|
367
|
+
* vatPercentage `"0.2000"` → `"0.200"`. `tags` and `name` are stored as sent (no trimming;
|
|
368
|
+
* a `tags` array is joined with commas; `tags` null or left out → null).
|
|
369
|
+
* - POST upserts (201, echoed under the ref). For each option product in `products`, its rows
|
|
370
|
+
* are replaced: every row sent is created afresh with a new id (a row `id` is ignored, also
|
|
371
|
+
* on a price change) and rows left out are removed. Option products left out of the save
|
|
372
|
+
* are untouched, and an empty `productInstances` removes nothing. A save without `products`
|
|
373
|
+
* updates only the group's own fields. The echo isn't proof of what was stored: renames of
|
|
374
|
+
* groups created moments earlier by a test run echoed the new name but never stuck (re-read
|
|
375
|
+
* for 90 s), while older groups, and groups created in Shopwave's own admin, renamed at
|
|
376
|
+
* once. Cause not yet known.
|
|
377
|
+
* - DELETE with `productComponentIds` (plural, comma list) → 205, soft delete. Adding
|
|
378
|
+
* `productComponentInstanceIds` deletes just those rows (205); they stay in live reads with
|
|
379
|
+
* `deleteDate` set. The singular `productComponentId` hangs (504 after 60 s).
|
|
359
380
|
*/
|
|
360
381
|
const SHOPWAVE_ENTITIES = Object.freeze({
|
|
361
382
|
product: {
|
|
@@ -415,6 +436,16 @@ const SHOPWAVE_ENTITIES = Object.freeze({
|
|
|
415
436
|
idHeader: "consumerId",
|
|
416
437
|
writable: false,
|
|
417
438
|
deleteMode: "none"
|
|
439
|
+
},
|
|
440
|
+
productComponent: {
|
|
441
|
+
route: "product-components",
|
|
442
|
+
collection: "productComponents",
|
|
443
|
+
upstream: "product/component",
|
|
444
|
+
idsHeader: "componentIds",
|
|
445
|
+
idHeader: "productComponentIds",
|
|
446
|
+
writable: true,
|
|
447
|
+
deleteMode: "delete",
|
|
448
|
+
childIdsHeader: "productComponentInstanceIds"
|
|
418
449
|
}
|
|
419
450
|
});
|
|
420
451
|
|
|
@@ -588,6 +619,29 @@ async function readUpstream(response) {
|
|
|
588
619
|
};
|
|
589
620
|
}
|
|
590
621
|
}
|
|
622
|
+
/**
|
|
623
|
+
* The child ids a DELETE names in `extras` under `header` (case-insensitive), as one comma
|
|
624
|
+
* list: `undefined` when the key is absent, `null` when `extras` or the value is invalid (not a
|
|
625
|
+
* JSON object, or not a non-empty list of ids). The key may hold an array or a comma string.
|
|
626
|
+
*/
|
|
627
|
+
function readChildIds(raw, header) {
|
|
628
|
+
if (!raw) return void 0;
|
|
629
|
+
let parsed;
|
|
630
|
+
try {
|
|
631
|
+
parsed = JSON.parse(raw);
|
|
632
|
+
} catch {
|
|
633
|
+
return null;
|
|
634
|
+
}
|
|
635
|
+
if (!isPlainObject(parsed)) return null;
|
|
636
|
+
const key = Object.keys(parsed).find((k) => k.toLowerCase() === header.toLowerCase());
|
|
637
|
+
if (key === void 0) return void 0;
|
|
638
|
+
const value = parsed[key];
|
|
639
|
+
const list = Array.isArray(value) ? value : typeof value === "string" || typeof value === "number" ? String(value).split(",") : null;
|
|
640
|
+
if (!list) return null;
|
|
641
|
+
const ids = list.map((v) => typeof v === "string" || typeof v === "number" ? String(v).trim() : "");
|
|
642
|
+
if (ids.length === 0 || ids.some((id) => !ID_PATTERN.test(id))) return null;
|
|
643
|
+
return ids.join(",");
|
|
644
|
+
}
|
|
591
645
|
async function routeParam(context, name) {
|
|
592
646
|
const value = (await context?.params)?.[name];
|
|
593
647
|
const id = Array.isArray(value) ? value[0] : value;
|
|
@@ -838,6 +892,19 @@ function createShopwaveApiHandlers(config) {
|
|
|
838
892
|
const id = await routeParam(context, param);
|
|
839
893
|
if (!id) return badId();
|
|
840
894
|
if (def.deleteMode === "none") return notSupported(def, "deletes");
|
|
895
|
+
if (def.deleteMode === "delete" && def.childIdsHeader) {
|
|
896
|
+
const childIds = readChildIds(request.headers.get("extras"), def.childIdsHeader);
|
|
897
|
+
if (childIds === null) return jsonError(400, "invalid_extras", `"${def.childIdsHeader}" must be a non-empty list of ids`);
|
|
898
|
+
if (childIds !== void 0) return forward(request, {
|
|
899
|
+
method: "DELETE",
|
|
900
|
+
path: def.upstream,
|
|
901
|
+
headers: {
|
|
902
|
+
[def.idHeader]: id,
|
|
903
|
+
[def.childIdsHeader]: childIds
|
|
904
|
+
},
|
|
905
|
+
forwardExtras: false
|
|
906
|
+
});
|
|
907
|
+
}
|
|
841
908
|
if (def.deleteMode === "retire") {
|
|
842
909
|
const field = def.retireField ?? "exitDate";
|
|
843
910
|
if (def.retireWithRecord) return retireWithRecord(request, def, id, field);
|