@visa/cli 4.1.0-rc.45 → 4.1.0-rc.47

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.
@@ -130,7 +130,7 @@ export async function createCardMandate(input, deps) {
130
130
  draws: [],
131
131
  ...(input.crossMerchant ? { crossMerchant: true } : {}),
132
132
  };
133
- await deps.ledger.create(record);
133
+ await deps.ledger.create(record, now);
134
134
  return {
135
135
  mandateId: record.mandateId,
136
136
  ceilingMinor: record.ceilingMinor,
@@ -94,8 +94,14 @@ export declare class MandateLedger {
94
94
  private run;
95
95
  private load;
96
96
  private save;
97
- /** Append a freshly-created mandate record. */
98
- create(record: CardMandateRecord): Promise<CardMandateRecord>;
97
+ /**
98
+ * Append a freshly-created mandate record. `now` drives the expired-mandate
99
+ * prune below; it defaults to the wall clock but is injectable so callers (and
100
+ * tests) can pin it — every other mutating method takes the same clock, and a
101
+ * real `new Date()` here would otherwise make the prune non-deterministic
102
+ * against fixtures dated relative to a fixed reference time.
103
+ */
104
+ create(record: CardMandateRecord, now?: Date): Promise<CardMandateRecord>;
99
105
  /** Read a single mandate (no lock — a snapshot copy). */
100
106
  get(mandateId: string): Promise<CardMandateRecord | null>;
101
107
  /**
@@ -136,8 +136,14 @@ export class MandateLedger {
136
136
  async save(file) {
137
137
  await writeOwnerOnlyJson(this.path, file);
138
138
  }
139
- /** Append a freshly-created mandate record. */
140
- create(record) {
139
+ /**
140
+ * Append a freshly-created mandate record. `now` drives the expired-mandate
141
+ * prune below; it defaults to the wall clock but is injectable so callers (and
142
+ * tests) can pin it — every other mutating method takes the same clock, and a
143
+ * real `new Date()` here would otherwise make the prune non-deterministic
144
+ * against fixtures dated relative to a fixed reference time.
145
+ */
146
+ create(record, now = new Date()) {
141
147
  return this.run(async () => {
142
148
  const file = await this.load();
143
149
  if (file.mandates.some((m) => m.mandateId === record.mandateId)) {
@@ -147,7 +153,7 @@ export class MandateLedger {
147
153
  // are already invisible to `mandate list` and unselectable by findCovering,
148
154
  // so nothing references them. A mandate with an unparseable expiry is kept
149
155
  // (fail-safe — never prune what we cannot date).
150
- const pruneBefore = new Date().getTime() - EXPIRED_PRUNE_GRACE_MS;
156
+ const pruneBefore = now.getTime() - EXPIRED_PRUNE_GRACE_MS;
151
157
  file.mandates = file.mandates.filter((m) => {
152
158
  const exp = Date.parse(m.expiresAt);
153
159
  return !Number.isFinite(exp) || exp >= pruneBefore;