@drawbridge/drawbridge-utils 0.0.131 → 0.0.133

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.
@@ -1370,10 +1370,6 @@ var featuresFor = (array = []) => Object.values({
1370
1370
  },
1371
1371
  { denied: {}, granted: {} }
1372
1372
  );
1373
- var overage = (actionCents) => ({
1374
- actionCents,
1375
- overages: { actions: String(actionCents) }
1376
- });
1377
1373
  var all = {
1378
1374
  features: (array = []) => featuresFor([
1379
1375
  connection.attentive.key,
@@ -1455,7 +1451,7 @@ var plans = {
1455
1451
  ["Storage", "10GB"]
1456
1452
  ]
1457
1453
  },
1458
- ...overage(2.5),
1454
+ actionCents: 2.5,
1459
1455
  title: "Starter",
1460
1456
  conversion: 2
1461
1457
  },
@@ -1486,7 +1482,7 @@ var plans = {
1486
1482
  ["Storage", "20GB"]
1487
1483
  ]
1488
1484
  },
1489
- ...overage(2),
1485
+ actionCents: 2,
1490
1486
  title: "Pro",
1491
1487
  conversion: 1.5
1492
1488
  },
@@ -1517,7 +1513,7 @@ var plans = {
1517
1513
  ["Storage", "50GB"]
1518
1514
  ]
1519
1515
  },
1520
- ...overage(1.85),
1516
+ actionCents: 1.85,
1521
1517
  title: "Premium",
1522
1518
  conversion: 1
1523
1519
  },
@@ -1548,7 +1544,7 @@ var plans = {
1548
1544
  ["Storage", "100GB"]
1549
1545
  ]
1550
1546
  },
1551
- ...overage(1.5),
1547
+ actionCents: 1.5,
1552
1548
  title: "Elite",
1553
1549
  conversion: 0.5
1554
1550
  }
@@ -1570,12 +1566,10 @@ var resolvePlan = (subscription) => {
1570
1566
  // silently lacking it would be a support ticket, not a pricing decision.
1571
1567
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
1572
1568
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
1573
- // A custom plan stores its overage BARE on `custom.overages` a different
1574
- // shape from the catalog's nested one. Number() so a deal stored as a string
1575
- // still resolves to cents-per-action; an unnamed overage stays undefined
1576
- // (it bills nothing) rather than becoming NaN.
1569
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
1570
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
1571
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
1577
1572
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
1578
- overages: { actions: custom.overages },
1579
1573
  title: custom.title || "Custom"
1580
1574
  };
1581
1575
  };
@@ -1296,10 +1296,6 @@ var featuresFor = (array = []) => Object.values({
1296
1296
  },
1297
1297
  { denied: {}, granted: {} }
1298
1298
  );
1299
- var overage = (actionCents) => ({
1300
- actionCents,
1301
- overages: { actions: String(actionCents) }
1302
- });
1303
1299
  var all = {
1304
1300
  features: (array = []) => featuresFor([
1305
1301
  connection.attentive.key,
@@ -1381,7 +1377,7 @@ var plans = {
1381
1377
  ["Storage", "10GB"]
1382
1378
  ]
1383
1379
  },
1384
- ...overage(2.5),
1380
+ actionCents: 2.5,
1385
1381
  title: "Starter",
1386
1382
  conversion: 2
1387
1383
  },
@@ -1412,7 +1408,7 @@ var plans = {
1412
1408
  ["Storage", "20GB"]
1413
1409
  ]
1414
1410
  },
1415
- ...overage(2),
1411
+ actionCents: 2,
1416
1412
  title: "Pro",
1417
1413
  conversion: 1.5
1418
1414
  },
@@ -1443,7 +1439,7 @@ var plans = {
1443
1439
  ["Storage", "50GB"]
1444
1440
  ]
1445
1441
  },
1446
- ...overage(1.85),
1442
+ actionCents: 1.85,
1447
1443
  title: "Premium",
1448
1444
  conversion: 1
1449
1445
  },
@@ -1474,7 +1470,7 @@ var plans = {
1474
1470
  ["Storage", "100GB"]
1475
1471
  ]
1476
1472
  },
1477
- ...overage(1.5),
1473
+ actionCents: 1.5,
1478
1474
  title: "Elite",
1479
1475
  conversion: 0.5
1480
1476
  }
@@ -1496,12 +1492,10 @@ var resolvePlan = (subscription) => {
1496
1492
  // silently lacking it would be a support ticket, not a pricing decision.
1497
1493
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
1498
1494
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
1499
- // A custom plan stores its overage BARE on `custom.overages` a different
1500
- // shape from the catalog's nested one. Number() so a deal stored as a string
1501
- // still resolves to cents-per-action; an unnamed overage stays undefined
1502
- // (it bills nothing) rather than becoming NaN.
1495
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
1496
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
1497
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
1503
1498
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
1504
- overages: { actions: custom.overages },
1505
1499
  title: custom.title || "Custom"
1506
1500
  };
1507
1501
  };
package/dist/plans.cjs CHANGED
@@ -291,10 +291,6 @@ var featuresFor = (array = []) => Object.values({
291
291
  },
292
292
  { denied: {}, granted: {} }
293
293
  );
294
- var overage = (actionCents) => ({
295
- actionCents,
296
- overages: { actions: String(actionCents) }
297
- });
298
294
  var unitAmountDecimal = (cents) => {
299
295
  const value = Number(cents);
300
296
  if (cents == null || !Number.isFinite(value)) throw new Error(`Invalid overage rate: ${cents}`);
@@ -381,7 +377,7 @@ var plans = {
381
377
  ["Storage", "10GB"]
382
378
  ]
383
379
  },
384
- ...overage(2.5),
380
+ actionCents: 2.5,
385
381
  title: "Starter",
386
382
  conversion: 2
387
383
  },
@@ -412,7 +408,7 @@ var plans = {
412
408
  ["Storage", "20GB"]
413
409
  ]
414
410
  },
415
- ...overage(2),
411
+ actionCents: 2,
416
412
  title: "Pro",
417
413
  conversion: 1.5
418
414
  },
@@ -443,7 +439,7 @@ var plans = {
443
439
  ["Storage", "50GB"]
444
440
  ]
445
441
  },
446
- ...overage(1.85),
442
+ actionCents: 1.85,
447
443
  title: "Premium",
448
444
  conversion: 1
449
445
  },
@@ -474,7 +470,7 @@ var plans = {
474
470
  ["Storage", "100GB"]
475
471
  ]
476
472
  },
477
- ...overage(1.5),
473
+ actionCents: 1.5,
478
474
  title: "Elite",
479
475
  conversion: 0.5
480
476
  }
@@ -496,12 +492,10 @@ var resolvePlan = (subscription) => {
496
492
  // silently lacking it would be a support ticket, not a pricing decision.
497
493
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
498
494
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
499
- // A custom plan stores its overage BARE on `custom.overages` a different
500
- // shape from the catalog's nested one. Number() so a deal stored as a string
501
- // still resolves to cents-per-action; an unnamed overage stays undefined
502
- // (it bills nothing) rather than becoming NaN.
495
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
496
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
497
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
503
498
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
504
- overages: { actions: custom.overages },
505
499
  title: custom.title || "Custom"
506
500
  };
507
501
  };
package/dist/plans.d.cts CHANGED
@@ -31,21 +31,12 @@ const featuresFor = ( array = [] ) => Object.values({
31
31
  { denied : {}, granted : {} }
32
32
  );
33
33
 
34
- // Overage pricing, unit-explicit.
35
- //
36
- // `actionCents` is CENTS PER ACTION, as a number: 2.5 = $0.025. Before
37
- // 2026-05-31 the same rate was encoded as dollars-per-1,000-actions, Stripe read
38
- // it as per-action, and every paid tier billed 10x. `overages.actions` — the
39
- // string this used to be the only name for — is kept as a byte-identical alias
40
- // so consumers can be pin-bumped in any order; drop it once they all read
41
- // `actionCents`.
34
+ // Each paid plan's `actionCents` is CENTS PER ACTION, as a number: 2.5 = $0.025.
35
+ // Before 2026-05-31 the rate was encoded as dollars-per-1,000-actions, Stripe
36
+ // read it as per-action, and every paid tier billed 10x.
42
37
  //
43
38
  // Sub-cent precision is deliberate: Premium's 1.85¢ does not fit integer cents
44
39
  // (2¢ is +8%, 1¢ is −46%).
45
- const overage = ( actionCents ) => ({
46
- actionCents,
47
- overages : { actions : String( actionCents ) }
48
- });
49
40
 
50
41
  // Cents → Stripe's `unit_amount_decimal`.
51
42
  //
@@ -148,7 +139,7 @@ const plans = {
148
139
  [ 'Storage', '10GB' ]
149
140
  ]
150
141
  },
151
- ...overage( 2.5 ),
142
+ actionCents : 2.5,
152
143
  title : 'Starter',
153
144
  conversion : 2
154
145
  },
@@ -179,7 +170,7 @@ const plans = {
179
170
  [ 'Storage', '20GB' ]
180
171
  ]
181
172
  },
182
- ...overage( 2 ),
173
+ actionCents : 2,
183
174
  title : 'Pro',
184
175
  conversion : 1.5
185
176
  },
@@ -210,7 +201,7 @@ const plans = {
210
201
  [ 'Storage', '50GB' ]
211
202
  ]
212
203
  },
213
- ...overage( 1.85 ),
204
+ actionCents : 1.85,
214
205
  title : 'Premium',
215
206
  conversion : 1
216
207
  },
@@ -241,7 +232,7 @@ const plans = {
241
232
  [ 'Storage', '100GB' ]
242
233
  ]
243
234
  },
244
- ...overage( 1.5 ),
235
+ actionCents : 1.5,
245
236
  title : 'Elite',
246
237
  conversion : 0.5
247
238
  },
@@ -279,12 +270,10 @@ const resolvePlan = ( subscription ) => {
279
270
  // silently lacking it would be a support ticket, not a pricing decision.
280
271
  features : all.features([ organization.networking.key, ...( custom.features?.granted || [] ) ]),
281
272
  limits : all.limits( custom.limits?.organization || {} ),
282
- // A custom plan stores its overage BARE on `custom.overages` a different
283
- // shape from the catalog's nested one. Number() so a deal stored as a string
284
- // still resolves to cents-per-action; an unnamed overage stays undefined
285
- // (it bills nothing) rather than becoming NaN.
273
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
274
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
275
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
286
276
  actionCents : custom.overages == null ? undefined : Number( custom.overages ),
287
- overages : { actions : custom.overages },
288
277
  title : custom.title || 'Custom'
289
278
  };
290
279
 
package/dist/plans.d.ts CHANGED
@@ -31,21 +31,12 @@ const featuresFor = ( array = [] ) => Object.values({
31
31
  { denied : {}, granted : {} }
32
32
  );
33
33
 
34
- // Overage pricing, unit-explicit.
35
- //
36
- // `actionCents` is CENTS PER ACTION, as a number: 2.5 = $0.025. Before
37
- // 2026-05-31 the same rate was encoded as dollars-per-1,000-actions, Stripe read
38
- // it as per-action, and every paid tier billed 10x. `overages.actions` — the
39
- // string this used to be the only name for — is kept as a byte-identical alias
40
- // so consumers can be pin-bumped in any order; drop it once they all read
41
- // `actionCents`.
34
+ // Each paid plan's `actionCents` is CENTS PER ACTION, as a number: 2.5 = $0.025.
35
+ // Before 2026-05-31 the rate was encoded as dollars-per-1,000-actions, Stripe
36
+ // read it as per-action, and every paid tier billed 10x.
42
37
  //
43
38
  // Sub-cent precision is deliberate: Premium's 1.85¢ does not fit integer cents
44
39
  // (2¢ is +8%, 1¢ is −46%).
45
- const overage = ( actionCents ) => ({
46
- actionCents,
47
- overages : { actions : String( actionCents ) }
48
- });
49
40
 
50
41
  // Cents → Stripe's `unit_amount_decimal`.
51
42
  //
@@ -148,7 +139,7 @@ const plans = {
148
139
  [ 'Storage', '10GB' ]
149
140
  ]
150
141
  },
151
- ...overage( 2.5 ),
142
+ actionCents : 2.5,
152
143
  title : 'Starter',
153
144
  conversion : 2
154
145
  },
@@ -179,7 +170,7 @@ const plans = {
179
170
  [ 'Storage', '20GB' ]
180
171
  ]
181
172
  },
182
- ...overage( 2 ),
173
+ actionCents : 2,
183
174
  title : 'Pro',
184
175
  conversion : 1.5
185
176
  },
@@ -210,7 +201,7 @@ const plans = {
210
201
  [ 'Storage', '50GB' ]
211
202
  ]
212
203
  },
213
- ...overage( 1.85 ),
204
+ actionCents : 1.85,
214
205
  title : 'Premium',
215
206
  conversion : 1
216
207
  },
@@ -241,7 +232,7 @@ const plans = {
241
232
  [ 'Storage', '100GB' ]
242
233
  ]
243
234
  },
244
- ...overage( 1.5 ),
235
+ actionCents : 1.5,
245
236
  title : 'Elite',
246
237
  conversion : 0.5
247
238
  },
@@ -279,12 +270,10 @@ const resolvePlan = ( subscription ) => {
279
270
  // silently lacking it would be a support ticket, not a pricing decision.
280
271
  features : all.features([ organization.networking.key, ...( custom.features?.granted || [] ) ]),
281
272
  limits : all.limits( custom.limits?.organization || {} ),
282
- // A custom plan stores its overage BARE on `custom.overages` a different
283
- // shape from the catalog's nested one. Number() so a deal stored as a string
284
- // still resolves to cents-per-action; an unnamed overage stays undefined
285
- // (it bills nothing) rather than becoming NaN.
273
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
274
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
275
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
286
276
  actionCents : custom.overages == null ? undefined : Number( custom.overages ),
287
- overages : { actions : custom.overages },
288
277
  title : custom.title || 'Custom'
289
278
  };
290
279
 
package/dist/plans.js CHANGED
@@ -252,10 +252,6 @@ var featuresFor = (array = []) => Object.values({
252
252
  },
253
253
  { denied: {}, granted: {} }
254
254
  );
255
- var overage = (actionCents) => ({
256
- actionCents,
257
- overages: { actions: String(actionCents) }
258
- });
259
255
  var unitAmountDecimal = (cents) => {
260
256
  const value = Number(cents);
261
257
  if (cents == null || !Number.isFinite(value)) throw new Error(`Invalid overage rate: ${cents}`);
@@ -342,7 +338,7 @@ var plans = {
342
338
  ["Storage", "10GB"]
343
339
  ]
344
340
  },
345
- ...overage(2.5),
341
+ actionCents: 2.5,
346
342
  title: "Starter",
347
343
  conversion: 2
348
344
  },
@@ -373,7 +369,7 @@ var plans = {
373
369
  ["Storage", "20GB"]
374
370
  ]
375
371
  },
376
- ...overage(2),
372
+ actionCents: 2,
377
373
  title: "Pro",
378
374
  conversion: 1.5
379
375
  },
@@ -404,7 +400,7 @@ var plans = {
404
400
  ["Storage", "50GB"]
405
401
  ]
406
402
  },
407
- ...overage(1.85),
403
+ actionCents: 1.85,
408
404
  title: "Premium",
409
405
  conversion: 1
410
406
  },
@@ -435,7 +431,7 @@ var plans = {
435
431
  ["Storage", "100GB"]
436
432
  ]
437
433
  },
438
- ...overage(1.5),
434
+ actionCents: 1.5,
439
435
  title: "Elite",
440
436
  conversion: 0.5
441
437
  }
@@ -457,12 +453,10 @@ var resolvePlan = (subscription) => {
457
453
  // silently lacking it would be a support ticket, not a pricing decision.
458
454
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
459
455
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
460
- // A custom plan stores its overage BARE on `custom.overages` a different
461
- // shape from the catalog's nested one. Number() so a deal stored as a string
462
- // still resolves to cents-per-action; an unnamed overage stays undefined
463
- // (it bills nothing) rather than becoming NaN.
456
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
457
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
458
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
464
459
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
465
- overages: { actions: custom.overages },
466
460
  title: custom.title || "Custom"
467
461
  };
468
462
  };
package/dist/pricing.cjs CHANGED
@@ -303,10 +303,6 @@ var featuresFor = (array = []) => Object.values({
303
303
  },
304
304
  { denied: {}, granted: {} }
305
305
  );
306
- var overage = (actionCents) => ({
307
- actionCents,
308
- overages: { actions: String(actionCents) }
309
- });
310
306
  var unitAmountDecimal = (cents) => {
311
307
  const value = Number(cents);
312
308
  if (cents == null || !Number.isFinite(value)) throw new Error(`Invalid overage rate: ${cents}`);
@@ -393,7 +389,7 @@ var plans = {
393
389
  ["Storage", "10GB"]
394
390
  ]
395
391
  },
396
- ...overage(2.5),
392
+ actionCents: 2.5,
397
393
  title: "Starter",
398
394
  conversion: 2
399
395
  },
@@ -424,7 +420,7 @@ var plans = {
424
420
  ["Storage", "20GB"]
425
421
  ]
426
422
  },
427
- ...overage(2),
423
+ actionCents: 2,
428
424
  title: "Pro",
429
425
  conversion: 1.5
430
426
  },
@@ -455,7 +451,7 @@ var plans = {
455
451
  ["Storage", "50GB"]
456
452
  ]
457
453
  },
458
- ...overage(1.85),
454
+ actionCents: 1.85,
459
455
  title: "Premium",
460
456
  conversion: 1
461
457
  },
@@ -486,7 +482,7 @@ var plans = {
486
482
  ["Storage", "100GB"]
487
483
  ]
488
484
  },
489
- ...overage(1.5),
485
+ actionCents: 1.5,
490
486
  title: "Elite",
491
487
  conversion: 0.5
492
488
  }
@@ -508,12 +504,10 @@ var resolvePlan = (subscription) => {
508
504
  // silently lacking it would be a support ticket, not a pricing decision.
509
505
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
510
506
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
511
- // A custom plan stores its overage BARE on `custom.overages` a different
512
- // shape from the catalog's nested one. Number() so a deal stored as a string
513
- // still resolves to cents-per-action; an unnamed overage stays undefined
514
- // (it bills nothing) rather than becoming NaN.
507
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
508
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
509
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
515
510
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
516
- overages: { actions: custom.overages },
517
511
  title: custom.title || "Custom"
518
512
  };
519
513
  };
@@ -25,8 +25,6 @@ import '@drawbridge/drawbridge-telemetry';
25
25
  // actionCents CENTS per action, number. 2.5 = $0.025.
26
26
  // Starter 2.5 · Pro 2 · Premium 1.85 · Elite 1.5.
27
27
  // Free has none — it is hard-capped at 200 actions.
28
- // overages.actions DEPRECATED alias of actionCents, as a string. Kept for
29
- // one release so consumers pin-bump in any order.
30
28
  // unitAmountDecimal() cents → Stripe `unit_amount_decimal` (a cents string).
31
29
  // plans[ id ].conversion PERCENT of order value taken as the conversion fee.
32
30
  // limits.* counts, except storage which is BYTES.
package/dist/pricing.d.ts CHANGED
@@ -25,8 +25,6 @@ import '@drawbridge/drawbridge-telemetry';
25
25
  // actionCents CENTS per action, number. 2.5 = $0.025.
26
26
  // Starter 2.5 · Pro 2 · Premium 1.85 · Elite 1.5.
27
27
  // Free has none — it is hard-capped at 200 actions.
28
- // overages.actions DEPRECATED alias of actionCents, as a string. Kept for
29
- // one release so consumers pin-bump in any order.
30
28
  // unitAmountDecimal() cents → Stripe `unit_amount_decimal` (a cents string).
31
29
  // plans[ id ].conversion PERCENT of order value taken as the conversion fee.
32
30
  // limits.* counts, except storage which is BYTES.
package/dist/pricing.js CHANGED
@@ -252,10 +252,6 @@ var featuresFor = (array = []) => Object.values({
252
252
  },
253
253
  { denied: {}, granted: {} }
254
254
  );
255
- var overage = (actionCents) => ({
256
- actionCents,
257
- overages: { actions: String(actionCents) }
258
- });
259
255
  var unitAmountDecimal = (cents) => {
260
256
  const value = Number(cents);
261
257
  if (cents == null || !Number.isFinite(value)) throw new Error(`Invalid overage rate: ${cents}`);
@@ -342,7 +338,7 @@ var plans = {
342
338
  ["Storage", "10GB"]
343
339
  ]
344
340
  },
345
- ...overage(2.5),
341
+ actionCents: 2.5,
346
342
  title: "Starter",
347
343
  conversion: 2
348
344
  },
@@ -373,7 +369,7 @@ var plans = {
373
369
  ["Storage", "20GB"]
374
370
  ]
375
371
  },
376
- ...overage(2),
372
+ actionCents: 2,
377
373
  title: "Pro",
378
374
  conversion: 1.5
379
375
  },
@@ -404,7 +400,7 @@ var plans = {
404
400
  ["Storage", "50GB"]
405
401
  ]
406
402
  },
407
- ...overage(1.85),
403
+ actionCents: 1.85,
408
404
  title: "Premium",
409
405
  conversion: 1
410
406
  },
@@ -435,7 +431,7 @@ var plans = {
435
431
  ["Storage", "100GB"]
436
432
  ]
437
433
  },
438
- ...overage(1.5),
434
+ actionCents: 1.5,
439
435
  title: "Elite",
440
436
  conversion: 0.5
441
437
  }
@@ -457,12 +453,10 @@ var resolvePlan = (subscription) => {
457
453
  // silently lacking it would be a support ticket, not a pricing decision.
458
454
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
459
455
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
460
- // A custom plan stores its overage BARE on `custom.overages` a different
461
- // shape from the catalog's nested one. Number() so a deal stored as a string
462
- // still resolves to cents-per-action; an unnamed overage stays undefined
463
- // (it bills nothing) rather than becoming NaN.
456
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
457
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
458
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
464
459
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
465
- overages: { actions: custom.overages },
466
460
  title: custom.title || "Custom"
467
461
  };
468
462
  };
@@ -1276,10 +1276,6 @@ var featuresFor = (array = []) => Object.values({
1276
1276
  },
1277
1277
  { denied: {}, granted: {} }
1278
1278
  );
1279
- var overage = (actionCents) => ({
1280
- actionCents,
1281
- overages: { actions: String(actionCents) }
1282
- });
1283
1279
  var all = {
1284
1280
  features: (array = []) => featuresFor([
1285
1281
  connection.attentive.key,
@@ -1361,7 +1357,7 @@ var plans = {
1361
1357
  ["Storage", "10GB"]
1362
1358
  ]
1363
1359
  },
1364
- ...overage(2.5),
1360
+ actionCents: 2.5,
1365
1361
  title: "Starter",
1366
1362
  conversion: 2
1367
1363
  },
@@ -1392,7 +1388,7 @@ var plans = {
1392
1388
  ["Storage", "20GB"]
1393
1389
  ]
1394
1390
  },
1395
- ...overage(2),
1391
+ actionCents: 2,
1396
1392
  title: "Pro",
1397
1393
  conversion: 1.5
1398
1394
  },
@@ -1423,7 +1419,7 @@ var plans = {
1423
1419
  ["Storage", "50GB"]
1424
1420
  ]
1425
1421
  },
1426
- ...overage(1.85),
1422
+ actionCents: 1.85,
1427
1423
  title: "Premium",
1428
1424
  conversion: 1
1429
1425
  },
@@ -1454,7 +1450,7 @@ var plans = {
1454
1450
  ["Storage", "100GB"]
1455
1451
  ]
1456
1452
  },
1457
- ...overage(1.5),
1453
+ actionCents: 1.5,
1458
1454
  title: "Elite",
1459
1455
  conversion: 0.5
1460
1456
  }
@@ -1476,12 +1472,10 @@ var resolvePlan = (subscription) => {
1476
1472
  // silently lacking it would be a support ticket, not a pricing decision.
1477
1473
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
1478
1474
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
1479
- // A custom plan stores its overage BARE on `custom.overages` a different
1480
- // shape from the catalog's nested one. Number() so a deal stored as a string
1481
- // still resolves to cents-per-action; an unnamed overage stays undefined
1482
- // (it bills nothing) rather than becoming NaN.
1475
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
1476
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
1477
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
1483
1478
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
1484
- overages: { actions: custom.overages },
1485
1479
  title: custom.title || "Custom"
1486
1480
  };
1487
1481
  };
package/dist/providers.js CHANGED
@@ -1232,10 +1232,6 @@ var featuresFor = (array = []) => Object.values({
1232
1232
  },
1233
1233
  { denied: {}, granted: {} }
1234
1234
  );
1235
- var overage = (actionCents) => ({
1236
- actionCents,
1237
- overages: { actions: String(actionCents) }
1238
- });
1239
1235
  var all = {
1240
1236
  features: (array = []) => featuresFor([
1241
1237
  connection.attentive.key,
@@ -1317,7 +1313,7 @@ var plans = {
1317
1313
  ["Storage", "10GB"]
1318
1314
  ]
1319
1315
  },
1320
- ...overage(2.5),
1316
+ actionCents: 2.5,
1321
1317
  title: "Starter",
1322
1318
  conversion: 2
1323
1319
  },
@@ -1348,7 +1344,7 @@ var plans = {
1348
1344
  ["Storage", "20GB"]
1349
1345
  ]
1350
1346
  },
1351
- ...overage(2),
1347
+ actionCents: 2,
1352
1348
  title: "Pro",
1353
1349
  conversion: 1.5
1354
1350
  },
@@ -1379,7 +1375,7 @@ var plans = {
1379
1375
  ["Storage", "50GB"]
1380
1376
  ]
1381
1377
  },
1382
- ...overage(1.85),
1378
+ actionCents: 1.85,
1383
1379
  title: "Premium",
1384
1380
  conversion: 1
1385
1381
  },
@@ -1410,7 +1406,7 @@ var plans = {
1410
1406
  ["Storage", "100GB"]
1411
1407
  ]
1412
1408
  },
1413
- ...overage(1.5),
1409
+ actionCents: 1.5,
1414
1410
  title: "Elite",
1415
1411
  conversion: 0.5
1416
1412
  }
@@ -1432,12 +1428,10 @@ var resolvePlan = (subscription) => {
1432
1428
  // silently lacking it would be a support ticket, not a pricing decision.
1433
1429
  features: all.features([organization.networking.key, ...((_a = custom.features) == null ? void 0 : _a.granted) || []]),
1434
1430
  limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
1435
- // A custom plan stores its overage BARE on `custom.overages` a different
1436
- // shape from the catalog's nested one. Number() so a deal stored as a string
1437
- // still resolves to cents-per-action; an unnamed overage stays undefined
1438
- // (it bills nothing) rather than becoming NaN.
1431
+ // A custom plan stores its overage BARE on `custom.overages`. Number() so
1432
+ // a deal stored as a string still resolves to cents-per-action; an unnamed
1433
+ // overage stays undefined (it bills nothing) rather than becoming NaN.
1439
1434
  actionCents: custom.overages == null ? void 0 : Number(custom.overages),
1440
- overages: { actions: custom.overages },
1441
1435
  title: custom.title || "Custom"
1442
1436
  };
1443
1437
  };
package/dist/twilio.cjs CHANGED
@@ -115,7 +115,7 @@ var twilio = {
115
115
  // Basic auth throughout, like Messages.
116
116
  searchNumbers: async ({ accountSid, areaCode, authToken, contains, country = "US", cursor, limit = 10, request: request2 = request }) => {
117
117
  if (!accountSid || !authToken) throw new Error("Twilio credentials missing \u2014 accountSid, authToken");
118
- const [page, token] = String(cursor || "").split("~");
118
+ const page = Number(cursor) || 0;
119
119
  const result = await request2({
120
120
  method: "GET",
121
121
  url: "https://api.twilio.com/2010-04-01/Accounts/" + accountSid + "/AvailablePhoneNumbers/" + country + "/Local.json",
@@ -130,18 +130,17 @@ var twilio = {
130
130
  // match anywhere in the number, so one search box serves "my
131
131
  // area code" and "ends in 7777" alike.
132
132
  ...contains && { Contains: contains },
133
- ...token && { Page: page, PageToken: token }
133
+ ...page && { Page: page }
134
134
  }
135
135
  });
136
- const nextQuery = (result == null ? void 0 : result.next_page_uri) ? new URLSearchParams(String(result.next_page_uri).split("?")[1] || "") : null;
137
- const nextToken = nextQuery == null ? void 0 : nextQuery.get("PageToken");
136
+ const items = ((result == null ? void 0 : result.available_phone_numbers) || []).map((entry) => ({
137
+ friendly: entry.friendly_name,
138
+ locality: entry.locality || entry.region || null,
139
+ number: entry.phone_number
140
+ }));
138
141
  return {
139
- cursor: nextToken ? (nextQuery.get("Page") || "") + "~" + nextToken : null,
140
- items: ((result == null ? void 0 : result.available_phone_numbers) || []).map((entry) => ({
141
- friendly: entry.friendly_name,
142
- locality: entry.locality || entry.region || null,
143
- number: entry.phone_number
144
- }))
142
+ cursor: items.length === limit ? String(page + 1) : null,
143
+ items
145
144
  };
146
145
  },
147
146
  purchaseNumber: async ({ accountSid, authToken, number, request: request2 = request, smsUrl }) => {
package/dist/twilio.d.cts CHANGED
@@ -81,11 +81,15 @@ const twilio = {
81
81
 
82
82
  if( ! accountSid || ! authToken ) throw new Error( 'Twilio credentials missing — accountSid, authToken' );
83
83
 
84
- // The vendor pages with Page + PageToken and answers next_page_uri
85
- // (AvailablePhoneNumbers resource docs). Ours is one opaque cursor —
86
- // `<Page>~<PageToken>` so the caller never learns the vendor's two
87
- // halves and cannot recombine them wrong.
88
- const [ page, token ] = String( cursor || '' ).split( '~' );
84
+ // PAGING, as the vendor actually does it rather than as its docs say.
85
+ // The AvailablePhoneNumbers reference lists PageToken/next_page_uri, but
86
+ // the resource returns NO next_page_uri at all (measured 2026-09-03)
87
+ // while a bare Page index works and answers a different set. So the
88
+ // cursor is simply the page number, and "is there a next page" is the
89
+ // full-page heuristic: a short page is the last one. (A page-boundary
90
+ // exact fit costs one empty page at the end — the trade for a vendor
91
+ // that will not say how much inventory it has.)
92
+ const page = Number( cursor ) || 0;
89
93
 
90
94
  const result = await request$1({
91
95
  method : 'GET',
@@ -101,24 +105,20 @@ const twilio = {
101
105
  // match anywhere in the number, so one search box serves "my
102
106
  // area code" and "ends in 7777" alike.
103
107
  ...( contains && { Contains : contains } ),
104
- ...( token && { Page : page, PageToken : token } )
108
+ ...( page && { Page : page } )
105
109
  }
106
110
  });
107
111
 
108
- const nextQuery = result?.next_page_uri
109
- ? new URLSearchParams( String( result.next_page_uri ).split( '?' )[ 1 ] || '' )
110
- : null;
111
-
112
- const nextToken = nextQuery?.get( 'PageToken' );
112
+ const items = ( result?.available_phone_numbers || [] ).map( ( entry ) => ({
113
+ friendly : entry.friendly_name,
114
+ locality : entry.locality || entry.region || null,
115
+ number : entry.phone_number
116
+ }) );
113
117
 
114
118
  // The caller-facing shape is ours; the vendor's field names stay here.
115
119
  return {
116
- cursor : nextToken ? ( nextQuery.get( 'Page' ) || '' ) + '~' + nextToken : null,
117
- items : ( result?.available_phone_numbers || [] ).map( ( entry ) => ({
118
- friendly : entry.friendly_name,
119
- locality : entry.locality || entry.region || null,
120
- number : entry.phone_number
121
- }) )
120
+ cursor : items.length === limit ? String( page + 1 ) : null,
121
+ items
122
122
  };
123
123
 
124
124
  },
package/dist/twilio.d.ts CHANGED
@@ -81,11 +81,15 @@ const twilio = {
81
81
 
82
82
  if( ! accountSid || ! authToken ) throw new Error( 'Twilio credentials missing — accountSid, authToken' );
83
83
 
84
- // The vendor pages with Page + PageToken and answers next_page_uri
85
- // (AvailablePhoneNumbers resource docs). Ours is one opaque cursor —
86
- // `<Page>~<PageToken>` so the caller never learns the vendor's two
87
- // halves and cannot recombine them wrong.
88
- const [ page, token ] = String( cursor || '' ).split( '~' );
84
+ // PAGING, as the vendor actually does it rather than as its docs say.
85
+ // The AvailablePhoneNumbers reference lists PageToken/next_page_uri, but
86
+ // the resource returns NO next_page_uri at all (measured 2026-09-03)
87
+ // while a bare Page index works and answers a different set. So the
88
+ // cursor is simply the page number, and "is there a next page" is the
89
+ // full-page heuristic: a short page is the last one. (A page-boundary
90
+ // exact fit costs one empty page at the end — the trade for a vendor
91
+ // that will not say how much inventory it has.)
92
+ const page = Number( cursor ) || 0;
89
93
 
90
94
  const result = await request$1({
91
95
  method : 'GET',
@@ -101,24 +105,20 @@ const twilio = {
101
105
  // match anywhere in the number, so one search box serves "my
102
106
  // area code" and "ends in 7777" alike.
103
107
  ...( contains && { Contains : contains } ),
104
- ...( token && { Page : page, PageToken : token } )
108
+ ...( page && { Page : page } )
105
109
  }
106
110
  });
107
111
 
108
- const nextQuery = result?.next_page_uri
109
- ? new URLSearchParams( String( result.next_page_uri ).split( '?' )[ 1 ] || '' )
110
- : null;
111
-
112
- const nextToken = nextQuery?.get( 'PageToken' );
112
+ const items = ( result?.available_phone_numbers || [] ).map( ( entry ) => ({
113
+ friendly : entry.friendly_name,
114
+ locality : entry.locality || entry.region || null,
115
+ number : entry.phone_number
116
+ }) );
113
117
 
114
118
  // The caller-facing shape is ours; the vendor's field names stay here.
115
119
  return {
116
- cursor : nextToken ? ( nextQuery.get( 'Page' ) || '' ) + '~' + nextToken : null,
117
- items : ( result?.available_phone_numbers || [] ).map( ( entry ) => ({
118
- friendly : entry.friendly_name,
119
- locality : entry.locality || entry.region || null,
120
- number : entry.phone_number
121
- }) )
120
+ cursor : items.length === limit ? String( page + 1 ) : null,
121
+ items
122
122
  };
123
123
 
124
124
  },
package/dist/twilio.js CHANGED
@@ -90,7 +90,7 @@ var twilio = {
90
90
  // Basic auth throughout, like Messages.
91
91
  searchNumbers: async ({ accountSid, areaCode, authToken, contains, country = "US", cursor, limit = 10, request: request2 = request }) => {
92
92
  if (!accountSid || !authToken) throw new Error("Twilio credentials missing \u2014 accountSid, authToken");
93
- const [page, token] = String(cursor || "").split("~");
93
+ const page = Number(cursor) || 0;
94
94
  const result = await request2({
95
95
  method: "GET",
96
96
  url: "https://api.twilio.com/2010-04-01/Accounts/" + accountSid + "/AvailablePhoneNumbers/" + country + "/Local.json",
@@ -105,18 +105,17 @@ var twilio = {
105
105
  // match anywhere in the number, so one search box serves "my
106
106
  // area code" and "ends in 7777" alike.
107
107
  ...contains && { Contains: contains },
108
- ...token && { Page: page, PageToken: token }
108
+ ...page && { Page: page }
109
109
  }
110
110
  });
111
- const nextQuery = (result == null ? void 0 : result.next_page_uri) ? new URLSearchParams(String(result.next_page_uri).split("?")[1] || "") : null;
112
- const nextToken = nextQuery == null ? void 0 : nextQuery.get("PageToken");
111
+ const items = ((result == null ? void 0 : result.available_phone_numbers) || []).map((entry) => ({
112
+ friendly: entry.friendly_name,
113
+ locality: entry.locality || entry.region || null,
114
+ number: entry.phone_number
115
+ }));
113
116
  return {
114
- cursor: nextToken ? (nextQuery.get("Page") || "") + "~" + nextToken : null,
115
- items: ((result == null ? void 0 : result.available_phone_numbers) || []).map((entry) => ({
116
- friendly: entry.friendly_name,
117
- locality: entry.locality || entry.region || null,
118
- number: entry.phone_number
119
- }))
117
+ cursor: items.length === limit ? String(page + 1) : null,
118
+ items
120
119
  };
121
120
  },
122
121
  purchaseNumber: async ({ accountSid, authToken, number, request: request2 = request, smsUrl }) => {
package/package.json CHANGED
@@ -215,5 +215,5 @@
215
215
  "test": ". \"$HOME/.nvm/nvm.sh\" && nvm use && node --test"
216
216
  },
217
217
  "types": "dist/index.d.ts",
218
- "version": "0.0.131"
218
+ "version": "0.0.133"
219
219
  }