react-shopwave-connect 0.4.0 → 0.4.2
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 +5 -4
- package/dist/core/index.cjs +116 -11
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +95 -7
- package/dist/core/index.d.ts +95 -7
- package/dist/core/index.js +114 -12
- package/dist/core/index.js.map +1 -1
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +116 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -7
- package/dist/index.d.ts +95 -7
- package/dist/index.js +114 -12
- package/dist/index.js.map +1 -1
- package/dist/next/index.cjs +59 -2
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +18 -3
- package/dist/next/index.d.ts +18 -3
- package/dist/next/index.js +59 -2
- package/dist/next/index.js.map +1 -1
- package/dist/server/index.cjs +59 -2
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +18 -3
- package/dist/server/index.d.ts +18 -3
- package/dist/server/index.js +59 -2
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/next/index.js
CHANGED
|
@@ -255,7 +255,10 @@ function safeEqual(a, b) {
|
|
|
255
255
|
* (https://developer.merchantstack.com/api-reference.html) and checked against
|
|
256
256
|
* the live API where noted:
|
|
257
257
|
* - category/product/store: GET filtered by `<x>Ids`, POST upsert, DELETE with `<x>Id` → 205.
|
|
258
|
-
* - promotion: no DELETE;
|
|
258
|
+
* - promotion: no DELETE; promotions are never deleted, only expired. Expiring
|
|
259
|
+
* reads the promotion and saves the whole record back with `endDate` = now (and
|
|
260
|
+
* `startDate` = now too if it hadn't started); the live API rejects a partial
|
|
261
|
+
* `{ id, endDate }` save with error 899. Dates are UTC `YYYY-MM-DD HH:mm:ss`.
|
|
259
262
|
* - employee: POST updates `roleId`, `joinedDate`, `exitDate` (names can't be
|
|
260
263
|
* changed); no DELETE (live API: "Cannot DELETE /employee") → retired via `exitDate`.
|
|
261
264
|
* - consumer: read-only (`GET` with `ids`, comma-separated); live POST → 404.
|
|
@@ -296,7 +299,9 @@ const SHOPWAVE_ENTITIES = Object.freeze({
|
|
|
296
299
|
idHeader: "promotionId",
|
|
297
300
|
writable: true,
|
|
298
301
|
deleteMode: "retire",
|
|
299
|
-
retireField: "endDate"
|
|
302
|
+
retireField: "endDate",
|
|
303
|
+
retireWithRecord: true,
|
|
304
|
+
retireStartField: "startDate"
|
|
300
305
|
},
|
|
301
306
|
employee: {
|
|
302
307
|
route: "employees",
|
|
@@ -495,6 +500,18 @@ function jsonError(status, error, message) {
|
|
|
495
500
|
function shopwaveDateTime(date = /* @__PURE__ */ new Date()) {
|
|
496
501
|
return date.toISOString().slice(0, 19).replace("T", " ");
|
|
497
502
|
}
|
|
503
|
+
/**
|
|
504
|
+
* Reads a Shopwave datetime: ISO with a zone (what reads return, e.g.
|
|
505
|
+
* `2026-10-20T16:00:00.000Z`) or a zoneless `YYYY-MM-DD HH:mm:ss`, which is UTC.
|
|
506
|
+
* `null` when the value isn't a date.
|
|
507
|
+
*/
|
|
508
|
+
function parseShopwaveDateTime(value) {
|
|
509
|
+
if (typeof value !== "string" || !value.trim()) return null;
|
|
510
|
+
const text = value.trim();
|
|
511
|
+
const zoneless = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/.test(text);
|
|
512
|
+
const date = new Date(zoneless ? `${text.replace(" ", "T")}Z` : text);
|
|
513
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
514
|
+
}
|
|
498
515
|
const NULL_BODY_STATUS = new Set([
|
|
499
516
|
101,
|
|
500
517
|
103,
|
|
@@ -694,6 +711,45 @@ function createShopwaveApiHandlers(config) {
|
|
|
694
711
|
function badId() {
|
|
695
712
|
return jsonError(400, "invalid_id", "Missing or invalid id");
|
|
696
713
|
}
|
|
714
|
+
/**
|
|
715
|
+
* Retires a record the API won't take a partial save for (promotions): reads it,
|
|
716
|
+
* sets `field` to now (and `def.retireStartField` to now too when the record
|
|
717
|
+
* hasn't started yet), and POSTs the whole record back. Both dates are sent as
|
|
718
|
+
* UTC `YYYY-MM-DD HH:mm:ss`; reads return them as ISO with `Z`.
|
|
719
|
+
*/
|
|
720
|
+
async function retireWithRecord(request, def, id, field) {
|
|
721
|
+
const read = await forward(request, {
|
|
722
|
+
path: def.upstream,
|
|
723
|
+
headers: { [def.idsHeader]: id },
|
|
724
|
+
forwardExtras: false
|
|
725
|
+
});
|
|
726
|
+
if (!read.ok) return read;
|
|
727
|
+
let body;
|
|
728
|
+
try {
|
|
729
|
+
body = await read.json();
|
|
730
|
+
} catch {
|
|
731
|
+
return jsonError(502, "invalid_upstream", `The Shopwave API's ${def.upstream} read wasn't JSON`);
|
|
732
|
+
}
|
|
733
|
+
const map = isPlainObject(body) && isPlainObject(body[def.collection]) ? body[def.collection] : {};
|
|
734
|
+
const record = Object.values(map).find((entry) => isPlainObject(entry) && String(entry.id) === id);
|
|
735
|
+
if (!record) return jsonError(404, "not_found", `No ${def.upstream} with id ${id}`);
|
|
736
|
+
const now = /* @__PURE__ */ new Date();
|
|
737
|
+
const retired = {
|
|
738
|
+
...record,
|
|
739
|
+
[field]: shopwaveDateTime(now)
|
|
740
|
+
};
|
|
741
|
+
const startField = def.retireStartField;
|
|
742
|
+
if (startField) {
|
|
743
|
+
const start = parseShopwaveDateTime(record[startField]);
|
|
744
|
+
if (start) retired[startField] = shopwaveDateTime(start > now ? now : start);
|
|
745
|
+
}
|
|
746
|
+
return forward(request, {
|
|
747
|
+
method: "POST",
|
|
748
|
+
path: def.upstream,
|
|
749
|
+
postBody: { [def.collection]: { 0: retired } },
|
|
750
|
+
forwardExtras: false
|
|
751
|
+
});
|
|
752
|
+
}
|
|
697
753
|
return {
|
|
698
754
|
forward,
|
|
699
755
|
entity,
|
|
@@ -729,6 +785,7 @@ function createShopwaveApiHandlers(config) {
|
|
|
729
785
|
if (def.deleteMode === "none") return notSupported(def, "deletes");
|
|
730
786
|
if (def.deleteMode === "retire") {
|
|
731
787
|
const field = def.retireField ?? "exitDate";
|
|
788
|
+
if (def.retireWithRecord) return retireWithRecord(request, def, id, field);
|
|
732
789
|
return forward(request, {
|
|
733
790
|
method: "POST",
|
|
734
791
|
path: def.upstream,
|