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.cjs
CHANGED
|
@@ -281,7 +281,10 @@ function safeEqual(a, b) {
|
|
|
281
281
|
* (https://developer.merchantstack.com/api-reference.html) and checked against
|
|
282
282
|
* the live API where noted:
|
|
283
283
|
* - category/product/store: GET filtered by `<x>Ids`, POST upsert, DELETE with `<x>Id` → 205.
|
|
284
|
-
* - promotion: no DELETE;
|
|
284
|
+
* - promotion: no DELETE; promotions are never deleted, only expired. Expiring
|
|
285
|
+
* reads the promotion and saves the whole record back with `endDate` = now (and
|
|
286
|
+
* `startDate` = now too if it hadn't started); the live API rejects a partial
|
|
287
|
+
* `{ id, endDate }` save with error 899. Dates are UTC `YYYY-MM-DD HH:mm:ss`.
|
|
285
288
|
* - employee: POST updates `roleId`, `joinedDate`, `exitDate` (names can't be
|
|
286
289
|
* changed); no DELETE (live API: "Cannot DELETE /employee") → retired via `exitDate`.
|
|
287
290
|
* - consumer: read-only (`GET` with `ids`, comma-separated); live POST → 404.
|
|
@@ -322,7 +325,9 @@ const SHOPWAVE_ENTITIES = Object.freeze({
|
|
|
322
325
|
idHeader: "promotionId",
|
|
323
326
|
writable: true,
|
|
324
327
|
deleteMode: "retire",
|
|
325
|
-
retireField: "endDate"
|
|
328
|
+
retireField: "endDate",
|
|
329
|
+
retireWithRecord: true,
|
|
330
|
+
retireStartField: "startDate"
|
|
326
331
|
},
|
|
327
332
|
employee: {
|
|
328
333
|
route: "employees",
|
|
@@ -521,6 +526,18 @@ function jsonError(status, error, message) {
|
|
|
521
526
|
function shopwaveDateTime(date = /* @__PURE__ */ new Date()) {
|
|
522
527
|
return date.toISOString().slice(0, 19).replace("T", " ");
|
|
523
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Reads a Shopwave datetime: ISO with a zone (what reads return, e.g.
|
|
531
|
+
* `2026-10-20T16:00:00.000Z`) or a zoneless `YYYY-MM-DD HH:mm:ss`, which is UTC.
|
|
532
|
+
* `null` when the value isn't a date.
|
|
533
|
+
*/
|
|
534
|
+
function parseShopwaveDateTime(value) {
|
|
535
|
+
if (typeof value !== "string" || !value.trim()) return null;
|
|
536
|
+
const text = value.trim();
|
|
537
|
+
const zoneless = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/.test(text);
|
|
538
|
+
const date = new Date(zoneless ? `${text.replace(" ", "T")}Z` : text);
|
|
539
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
540
|
+
}
|
|
524
541
|
const NULL_BODY_STATUS = new Set([
|
|
525
542
|
101,
|
|
526
543
|
103,
|
|
@@ -720,6 +737,45 @@ function createShopwaveApiHandlers(config) {
|
|
|
720
737
|
function badId() {
|
|
721
738
|
return jsonError(400, "invalid_id", "Missing or invalid id");
|
|
722
739
|
}
|
|
740
|
+
/**
|
|
741
|
+
* Retires a record the API won't take a partial save for (promotions): reads it,
|
|
742
|
+
* sets `field` to now (and `def.retireStartField` to now too when the record
|
|
743
|
+
* hasn't started yet), and POSTs the whole record back. Both dates are sent as
|
|
744
|
+
* UTC `YYYY-MM-DD HH:mm:ss`; reads return them as ISO with `Z`.
|
|
745
|
+
*/
|
|
746
|
+
async function retireWithRecord(request, def, id, field) {
|
|
747
|
+
const read = await forward(request, {
|
|
748
|
+
path: def.upstream,
|
|
749
|
+
headers: { [def.idsHeader]: id },
|
|
750
|
+
forwardExtras: false
|
|
751
|
+
});
|
|
752
|
+
if (!read.ok) return read;
|
|
753
|
+
let body;
|
|
754
|
+
try {
|
|
755
|
+
body = await read.json();
|
|
756
|
+
} catch {
|
|
757
|
+
return jsonError(502, "invalid_upstream", `The Shopwave API's ${def.upstream} read wasn't JSON`);
|
|
758
|
+
}
|
|
759
|
+
const map = isPlainObject(body) && isPlainObject(body[def.collection]) ? body[def.collection] : {};
|
|
760
|
+
const record = Object.values(map).find((entry) => isPlainObject(entry) && String(entry.id) === id);
|
|
761
|
+
if (!record) return jsonError(404, "not_found", `No ${def.upstream} with id ${id}`);
|
|
762
|
+
const now = /* @__PURE__ */ new Date();
|
|
763
|
+
const retired = {
|
|
764
|
+
...record,
|
|
765
|
+
[field]: shopwaveDateTime(now)
|
|
766
|
+
};
|
|
767
|
+
const startField = def.retireStartField;
|
|
768
|
+
if (startField) {
|
|
769
|
+
const start = parseShopwaveDateTime(record[startField]);
|
|
770
|
+
if (start) retired[startField] = shopwaveDateTime(start > now ? now : start);
|
|
771
|
+
}
|
|
772
|
+
return forward(request, {
|
|
773
|
+
method: "POST",
|
|
774
|
+
path: def.upstream,
|
|
775
|
+
postBody: { [def.collection]: { 0: retired } },
|
|
776
|
+
forwardExtras: false
|
|
777
|
+
});
|
|
778
|
+
}
|
|
723
779
|
return {
|
|
724
780
|
forward,
|
|
725
781
|
entity,
|
|
@@ -755,6 +811,7 @@ function createShopwaveApiHandlers(config) {
|
|
|
755
811
|
if (def.deleteMode === "none") return notSupported(def, "deletes");
|
|
756
812
|
if (def.deleteMode === "retire") {
|
|
757
813
|
const field = def.retireField ?? "exitDate";
|
|
814
|
+
if (def.retireWithRecord) return retireWithRecord(request, def, id, field);
|
|
758
815
|
return forward(request, {
|
|
759
816
|
method: "POST",
|
|
760
817
|
path: def.upstream,
|