@drawbridge/drawbridge-utils 0.0.92 → 0.0.94

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/dist/plans.cjs CHANGED
@@ -31,7 +31,8 @@ var plans_exports = {};
31
31
  __export(plans_exports, {
32
32
  conversionRate: () => conversionRate,
33
33
  free: () => free,
34
- plans: () => plans
34
+ plans: () => plans,
35
+ resolvePlan: () => resolvePlan
35
36
  });
36
37
  module.exports = __toCommonJS(plans_exports);
37
38
 
@@ -422,13 +423,31 @@ var plans = {
422
423
  conversion: 0.5
423
424
  }
424
425
  };
426
+ var resolvePlan = (subscription) => {
427
+ var _a, _b;
428
+ const custom = subscription == null ? void 0 : subscription.custom;
429
+ if (!custom) return plans[subscription == null ? void 0 : subscription.plan] ?? free;
430
+ return {
431
+ // Reusing all.features / all.limits is what keeps a custom plan the same
432
+ // SHAPE as a catalog one: the base feature grants every plan carries, the
433
+ // campaign limits that are always infinite, and members defaulting to
434
+ // infinite when a deal does not name it.
435
+ conversion: custom.conversion ?? free.conversion,
436
+ custom: true,
437
+ features: all.features(((_a = custom.features) == null ? void 0 : _a.granted) || []),
438
+ limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
439
+ overages: { actions: custom.overages },
440
+ title: custom.title || "Custom"
441
+ };
442
+ };
425
443
  var conversionRate = (subscription) => {
426
444
  var _a, _b;
427
- return ((_a = subscription == null ? void 0 : subscription.overrides) == null ? void 0 : _a.conversion) ?? (subscription == null ? void 0 : subscription.conversion) ?? ((_b = plans[subscription == null ? void 0 : subscription.plan]) == null ? void 0 : _b.conversion) ?? free.conversion;
445
+ return ((_a = subscription == null ? void 0 : subscription.overrides) == null ? void 0 : _a.conversion) ?? (subscription == null ? void 0 : subscription.conversion) ?? ((_b = resolvePlan(subscription)) == null ? void 0 : _b.conversion) ?? free.conversion;
428
446
  };
429
447
  // Annotate the CommonJS export names for ESM import in node:
430
448
  0 && (module.exports = {
431
449
  conversionRate,
432
450
  free,
433
- plans
451
+ plans,
452
+ resolvePlan
434
453
  });
package/dist/plans.d.cts CHANGED
@@ -192,7 +192,41 @@ const plans = {
192
192
  overages : { actions : '1.5' },
193
193
  title : 'Elite',
194
194
  conversion : 0.5
195
- }
195
+ },
196
+
197
+ };
198
+
199
+ // The effective plan for a subscription.
200
+ //
201
+ // A CUSTOM plan is not in this catalog and never will be: it belongs to one
202
+ // organization, so it is stored on that organization's subscription and is
203
+ // self-describing. Everything a plan needs is built here from what it carries,
204
+ // which is why `subscription.plan` is empty for one.
205
+ //
206
+ // This is the single resolver. drawbridge-api mirrors it as an aggregation
207
+ // expression for the organization payload, and drawbridge-sync calls it
208
+ // directly on raw documents — sync never touches extend, so without this it
209
+ // would resolve `plans[ null ]`, bill every custom-plan cycle at $0 and charge
210
+ // the free 3% conversion rate. A parity test pins the two expressions together.
211
+ const resolvePlan = ( subscription ) => {
212
+
213
+ const custom = subscription?.custom;
214
+
215
+ if( ! custom ) return plans[ subscription?.plan ] ?? free;
216
+
217
+ return {
218
+ // Reusing all.features / all.limits is what keeps a custom plan the same
219
+ // SHAPE as a catalog one: the base feature grants every plan carries, the
220
+ // campaign limits that are always infinite, and members defaulting to
221
+ // infinite when a deal does not name it.
222
+ conversion : custom.conversion ?? free.conversion,
223
+ custom : true,
224
+ features : all.features( custom.features?.granted || [] ),
225
+ limits : all.limits( custom.limits?.organization || {} ),
226
+ overages : { actions : custom.overages },
227
+ title : custom.title || 'Custom'
228
+ };
229
+
196
230
  };
197
231
 
198
232
  // Resolve the conversion-fee percentage for an order's owning org.
@@ -204,7 +238,7 @@ const plans = {
204
238
  const conversionRate = ( subscription ) =>
205
239
  subscription?.overrides?.conversion
206
240
  ?? subscription?.conversion
207
- ?? plans[ subscription?.plan ]?.conversion
241
+ ?? resolvePlan( subscription )?.conversion
208
242
  ?? free.conversion;
209
243
 
210
- export { conversionRate, free, plans };
244
+ export { conversionRate, free, plans, resolvePlan };
package/dist/plans.d.ts CHANGED
@@ -192,7 +192,41 @@ const plans = {
192
192
  overages : { actions : '1.5' },
193
193
  title : 'Elite',
194
194
  conversion : 0.5
195
- }
195
+ },
196
+
197
+ };
198
+
199
+ // The effective plan for a subscription.
200
+ //
201
+ // A CUSTOM plan is not in this catalog and never will be: it belongs to one
202
+ // organization, so it is stored on that organization's subscription and is
203
+ // self-describing. Everything a plan needs is built here from what it carries,
204
+ // which is why `subscription.plan` is empty for one.
205
+ //
206
+ // This is the single resolver. drawbridge-api mirrors it as an aggregation
207
+ // expression for the organization payload, and drawbridge-sync calls it
208
+ // directly on raw documents — sync never touches extend, so without this it
209
+ // would resolve `plans[ null ]`, bill every custom-plan cycle at $0 and charge
210
+ // the free 3% conversion rate. A parity test pins the two expressions together.
211
+ const resolvePlan = ( subscription ) => {
212
+
213
+ const custom = subscription?.custom;
214
+
215
+ if( ! custom ) return plans[ subscription?.plan ] ?? free;
216
+
217
+ return {
218
+ // Reusing all.features / all.limits is what keeps a custom plan the same
219
+ // SHAPE as a catalog one: the base feature grants every plan carries, the
220
+ // campaign limits that are always infinite, and members defaulting to
221
+ // infinite when a deal does not name it.
222
+ conversion : custom.conversion ?? free.conversion,
223
+ custom : true,
224
+ features : all.features( custom.features?.granted || [] ),
225
+ limits : all.limits( custom.limits?.organization || {} ),
226
+ overages : { actions : custom.overages },
227
+ title : custom.title || 'Custom'
228
+ };
229
+
196
230
  };
197
231
 
198
232
  // Resolve the conversion-fee percentage for an order's owning org.
@@ -204,7 +238,7 @@ const plans = {
204
238
  const conversionRate = ( subscription ) =>
205
239
  subscription?.overrides?.conversion
206
240
  ?? subscription?.conversion
207
- ?? plans[ subscription?.plan ]?.conversion
241
+ ?? resolvePlan( subscription )?.conversion
208
242
  ?? free.conversion;
209
243
 
210
- export { conversionRate, free, plans };
244
+ export { conversionRate, free, plans, resolvePlan };
package/dist/plans.js CHANGED
@@ -385,12 +385,30 @@ var plans = {
385
385
  conversion: 0.5
386
386
  }
387
387
  };
388
+ var resolvePlan = (subscription) => {
389
+ var _a, _b;
390
+ const custom = subscription == null ? void 0 : subscription.custom;
391
+ if (!custom) return plans[subscription == null ? void 0 : subscription.plan] ?? free;
392
+ return {
393
+ // Reusing all.features / all.limits is what keeps a custom plan the same
394
+ // SHAPE as a catalog one: the base feature grants every plan carries, the
395
+ // campaign limits that are always infinite, and members defaulting to
396
+ // infinite when a deal does not name it.
397
+ conversion: custom.conversion ?? free.conversion,
398
+ custom: true,
399
+ features: all.features(((_a = custom.features) == null ? void 0 : _a.granted) || []),
400
+ limits: all.limits(((_b = custom.limits) == null ? void 0 : _b.organization) || {}),
401
+ overages: { actions: custom.overages },
402
+ title: custom.title || "Custom"
403
+ };
404
+ };
388
405
  var conversionRate = (subscription) => {
389
406
  var _a, _b;
390
- return ((_a = subscription == null ? void 0 : subscription.overrides) == null ? void 0 : _a.conversion) ?? (subscription == null ? void 0 : subscription.conversion) ?? ((_b = plans[subscription == null ? void 0 : subscription.plan]) == null ? void 0 : _b.conversion) ?? free.conversion;
407
+ return ((_a = subscription == null ? void 0 : subscription.overrides) == null ? void 0 : _a.conversion) ?? (subscription == null ? void 0 : subscription.conversion) ?? ((_b = resolvePlan(subscription)) == null ? void 0 : _b.conversion) ?? free.conversion;
391
408
  };
392
409
  export {
393
410
  conversionRate,
394
411
  free,
395
- plans
412
+ plans,
413
+ resolvePlan
396
414
  };
package/package.json CHANGED
@@ -169,5 +169,5 @@
169
169
  "test": ". \"$HOME/.nvm/nvm.sh\" && nvm use && node --test"
170
170
  },
171
171
  "types": "dist/index.d.ts",
172
- "version": "0.0.92"
172
+ "version": "0.0.94"
173
173
  }