@blamejs/blamejs-shop 0.3.54 → 0.3.56

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.
@@ -404,6 +404,26 @@ function create(opts) {
404
404
  return r.rows.length > 0;
405
405
  }
406
406
 
407
+ // Customer re-opt-in lever — the inverse of unsubscribeFromAlertKind.
408
+ // DELETEs the (customer_id, trigger) opt-out row so the dispatcher
409
+ // resumes firing that trigger for the customer. Idempotent: deleting a
410
+ // row that isn't there returns `{ status: "already-subscribed" }`.
411
+ // Same input validation as the unsubscribe verb (UUID-shape customer,
412
+ // enum trigger) so a bad caller fails with a typed error the route
413
+ // turns into HTTP 400.
414
+ async function resubscribeToAlertKind(input) {
415
+ if (!input || typeof input !== "object") {
416
+ throw new TypeError("wishlistAlerts.resubscribeToAlertKind: input object required");
417
+ }
418
+ var customerId = _uuid(input.customer_id, "customer_id");
419
+ var trigger = _trigger(input.trigger);
420
+ var r = await query(
421
+ "DELETE FROM wishlist_alert_unsubscribes WHERE customer_id = ?1 AND trigger = ?2",
422
+ [customerId, trigger],
423
+ );
424
+ return { status: Number(r.rowCount || 0) > 0 ? "resubscribed" : "already-subscribed" };
425
+ }
426
+
407
427
  // ---- ledger reads -----------------------------------------------------
408
428
 
409
429
  async function customerAlertHistory(input) {
@@ -830,6 +850,8 @@ function create(opts) {
830
850
  markAlertSent: markAlertSent,
831
851
  customerAlertHistory: customerAlertHistory,
832
852
  unsubscribeFromAlertKind: unsubscribeFromAlertKind,
853
+ resubscribeToAlertKind: resubscribeToAlertKind,
854
+ isUnsubscribedFromTrigger: isUnsubscribedFromTrigger,
833
855
  metricsForPolicy: metricsForPolicy,
834
856
  };
835
857
  }
@@ -622,6 +622,23 @@ function create(opts) {
622
622
  return _shapeSchedule(await _getScheduleBySlug(slug));
623
623
  }
624
624
 
625
+ // List the defined schedules, newest-first by created_at. With
626
+ // `active_only` (default) only non-archived schedules are returned —
627
+ // the customer-portal toggle renders a digest opt-in per LIVE schedule
628
+ // slug; the admin console passes `active_only: false` to show archived
629
+ // rows too. Pure read; no writes.
630
+ async function listSchedules(listOpts) {
631
+ listOpts = listOpts || {};
632
+ var activeOnly = listOpts.active_only !== false;
633
+ var sql = "SELECT * FROM wishlist_digest_schedules ";
634
+ if (activeOnly) sql += "WHERE archived_at IS NULL ";
635
+ sql += "ORDER BY created_at DESC, slug ASC LIMIT ?1";
636
+ var r = await query(sql, [MAX_LIMIT]);
637
+ var out = [];
638
+ for (var i = 0; i < r.rows.length; i += 1) out.push(_shapeSchedule(r.rows[i]));
639
+ return out;
640
+ }
641
+
625
642
  // ---- enrollCustomer ----------------------------------------------
626
643
 
627
644
  async function enrollCustomer(input) {
@@ -1056,6 +1073,7 @@ function create(opts) {
1056
1073
 
1057
1074
  defineSchedule: defineSchedule,
1058
1075
  getSchedule: getSchedule,
1076
+ listSchedules: listSchedules,
1059
1077
  enrollCustomer: enrollCustomer,
1060
1078
  pauseEnrollment: pauseEnrollment,
1061
1079
  resumeEnrollment: resumeEnrollment,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/blamejs-shop",
3
- "version": "0.3.54",
3
+ "version": "0.3.56",
4
4
  "description": "Open-source framework built on blamejs. Vendored stack, zero npm runtime deps, PQC-first crypto, security-on by default.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {