@drawbridge/drawbridge-utils 0.0.103 → 0.0.105

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.
@@ -0,0 +1,111 @@
1
+ export { conversionRate, free, plans, resolvePlan, unitAmountDecimal } from './plans.cjs';
2
+ export { LOCAL_FLAT_CENTS, MARKUP, PREMIUM_CPM_CENTS, PREMIUM_RATE_PER_GB, REUSE_FLAT_CENTS, STANDARD_CPM_CENTS, STANDARD_RATE_PER_GB, ai, scrape } from './billing.cjs';
3
+ import './features.cjs';
4
+ import './index.cjs';
5
+ import 'currency-codes';
6
+ import 'nanoid';
7
+ import './color.cjs';
8
+ import 'tinycolor2';
9
+ import './usage.cjs';
10
+ import './transactions.cjs';
11
+ import '@drawbridge/drawbridge-telemetry';
12
+
13
+ // Pricing — the one file you open to see every customer-facing number.
14
+ //
15
+ // Nothing is DEFINED here except the channel weights: the values still live
16
+ // where their accounting lives, and this file re-exports them so a rate can be
17
+ // found without knowing which module owns it. It is also the seam if we ever
18
+ // migrate the values for real.
19
+ //
20
+ // Every number below carries its UNIT in the map, because the unit is exactly
21
+ // what got lost: `overages.actions` was '2.5' and read as $2.50 by everyone who
22
+ // met it — twice, once in production (2026-05-31, every paid tier billed 10x).
23
+ //
24
+ // ─── Plan overages (lib/plans.js) ─────────────────────────────────────────────
25
+ // actionCents CENTS per action, number. 2.5 = $0.025.
26
+ // Starter 2.5 · Pro 2 · Premium 1.85 · Elite 1.5.
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
+ // unitAmountDecimal() cents → Stripe `unit_amount_decimal` (a cents string).
31
+ // plans[ id ].conversion PERCENT of order value taken as the conversion fee.
32
+ // limits.* counts, except storage which is BYTES.
33
+ //
34
+ // ─── Channel weights (owned here) ─────────────────────────────────────────────
35
+ // channels.email.actionsPerSend ACTIONS per email send.
36
+ // channels.sms.actionsPerSegment ACTIONS per SMS segment.
37
+ // channels.*.includedInAllowance whether the plan's included actions cover it.
38
+ //
39
+ // ─── Provider capacity (owned here) ───────────────────────────────────────────
40
+ // sending.email.monthlyCeiling EMAILS per calendar month we have BOUGHT,
41
+ // platform-wide across every send path.
42
+ // sending.email.alertThreshold FRACTION of that ceiling which alarms.
43
+ //
44
+ // ─── Scrape + AI (lib/billing.js) ─────────────────────────────────────────────
45
+ // MARKUP MULTIPLIER on provider cost (1.3 = 30% margin).
46
+ // STANDARD_RATE_PER_GB DOLLARS per GB, BrightData Scraping Browser.
47
+ // PREMIUM_RATE_PER_GB DOLLARS per GB, premium hosts.
48
+ // STANDARD_CPM_CENTS CENTS per request, BrightData Web Unlocker.
49
+ // PREMIUM_CPM_CENTS CENTS per request, premium hosts.
50
+ // LOCAL_FLAT_CENTS CENTS per cold local render.
51
+ // REUSE_FLAT_CENTS CENTS per cache reuse.
52
+ // ai.rates CENTS per 1,000,000 tokens, wholesale + retail, per
53
+ // model; ai.rates.tools is CENTS per request.
54
+ //
55
+ // lib/ai.js is NOT re-exported here on purpose: its `models` registry names WHICH
56
+ // model we call, not what it costs (the rate table lives in billing.js), and
57
+ // importing it would pull @google/genai and construct a client into every
58
+ // consumer of this file.
59
+
60
+
61
+ // What we have BOUGHT from the sending providers, against what the plans above
62
+ // SELL. Here rather than in an env because it is a rate like every other number
63
+ // in this file, and the whole point of this file is that you do not have to
64
+ // know which environment to look in to find one. Changing it is a publish and a
65
+ // pin bump, which is the right friction for a number that changes when a
66
+ // contract changes.
67
+ //
68
+ // READ THIS BEFORE RAISING A PLAN ALLOWANCE. The ceiling is PLATFORM-WIDE while
69
+ // every allowance above is PER ORGANIZATION, and an allowance can be spent
70
+ // entirely on email — so the two are denominated against very different things:
71
+ //
72
+ // Elite 100,000 = 200% of the whole platform's email ceiling
73
+ // Premium 40,000 = 80%
74
+ // Pro 15,000 = 30%
75
+ // Starter 5,000 = 10%
76
+ //
77
+ // As of 2026-08-30 we sell about 2x the email we buy. That is fine while real
78
+ // usage sits far below the allowances, and it is not a margin problem — at this
79
+ // ceiling an email costs a fraction of a cent, far under the 1.5-2.5c overage.
80
+ // It is a CAPACITY problem: running out does not cost a few dollars, it stops
81
+ // every merchant's mail at once. Raising a tier's allowance moves this number
82
+ // too, or the ceiling quietly becomes the real limit.
83
+ const sending = {
84
+ email : {
85
+ // Fraction of monthlyCeiling that raises the alarm. Far enough ahead of
86
+ // the wall to act on, high enough not to fire on ordinary growth.
87
+ alertThreshold : 0.8,
88
+ // SendGrid Essentials 50K — emails per calendar month, PLATFORM-WIDE and
89
+ // across every send path: lead-facing mail, workflow steps, and the sign-in
90
+ // codes and account mail that no plan allowance meters.
91
+ monthlyCeiling : 50000
92
+ }
93
+ };
94
+
95
+ // Weighted actions: what one message of each channel costs against a plan.
96
+ // Named per unit so a bare `2` can never be read as cents.
97
+ const channels = {
98
+ email : {
99
+ actionsPerSend : 1,
100
+ includedInAllowance : true
101
+ },
102
+ sms : {
103
+ // Two actions PER SEGMENT (a long message is several segments), billed from
104
+ // the FIRST segment and never drawn from the plan's included allowance —
105
+ // carrier cost is real from message one, so there is no free tier of it.
106
+ actionsPerSegment : 2,
107
+ includedInAllowance : false
108
+ }
109
+ };
110
+
111
+ export { channels, sending };
@@ -0,0 +1,111 @@
1
+ export { conversionRate, free, plans, resolvePlan, unitAmountDecimal } from './plans.js';
2
+ export { LOCAL_FLAT_CENTS, MARKUP, PREMIUM_CPM_CENTS, PREMIUM_RATE_PER_GB, REUSE_FLAT_CENTS, STANDARD_CPM_CENTS, STANDARD_RATE_PER_GB, ai, scrape } from './billing.js';
3
+ import './features.js';
4
+ import './index.js';
5
+ import 'currency-codes';
6
+ import 'nanoid';
7
+ import './color.js';
8
+ import 'tinycolor2';
9
+ import './usage.js';
10
+ import './transactions.js';
11
+ import '@drawbridge/drawbridge-telemetry';
12
+
13
+ // Pricing — the one file you open to see every customer-facing number.
14
+ //
15
+ // Nothing is DEFINED here except the channel weights: the values still live
16
+ // where their accounting lives, and this file re-exports them so a rate can be
17
+ // found without knowing which module owns it. It is also the seam if we ever
18
+ // migrate the values for real.
19
+ //
20
+ // Every number below carries its UNIT in the map, because the unit is exactly
21
+ // what got lost: `overages.actions` was '2.5' and read as $2.50 by everyone who
22
+ // met it — twice, once in production (2026-05-31, every paid tier billed 10x).
23
+ //
24
+ // ─── Plan overages (lib/plans.js) ─────────────────────────────────────────────
25
+ // actionCents CENTS per action, number. 2.5 = $0.025.
26
+ // Starter 2.5 · Pro 2 · Premium 1.85 · Elite 1.5.
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
+ // unitAmountDecimal() cents → Stripe `unit_amount_decimal` (a cents string).
31
+ // plans[ id ].conversion PERCENT of order value taken as the conversion fee.
32
+ // limits.* counts, except storage which is BYTES.
33
+ //
34
+ // ─── Channel weights (owned here) ─────────────────────────────────────────────
35
+ // channels.email.actionsPerSend ACTIONS per email send.
36
+ // channels.sms.actionsPerSegment ACTIONS per SMS segment.
37
+ // channels.*.includedInAllowance whether the plan's included actions cover it.
38
+ //
39
+ // ─── Provider capacity (owned here) ───────────────────────────────────────────
40
+ // sending.email.monthlyCeiling EMAILS per calendar month we have BOUGHT,
41
+ // platform-wide across every send path.
42
+ // sending.email.alertThreshold FRACTION of that ceiling which alarms.
43
+ //
44
+ // ─── Scrape + AI (lib/billing.js) ─────────────────────────────────────────────
45
+ // MARKUP MULTIPLIER on provider cost (1.3 = 30% margin).
46
+ // STANDARD_RATE_PER_GB DOLLARS per GB, BrightData Scraping Browser.
47
+ // PREMIUM_RATE_PER_GB DOLLARS per GB, premium hosts.
48
+ // STANDARD_CPM_CENTS CENTS per request, BrightData Web Unlocker.
49
+ // PREMIUM_CPM_CENTS CENTS per request, premium hosts.
50
+ // LOCAL_FLAT_CENTS CENTS per cold local render.
51
+ // REUSE_FLAT_CENTS CENTS per cache reuse.
52
+ // ai.rates CENTS per 1,000,000 tokens, wholesale + retail, per
53
+ // model; ai.rates.tools is CENTS per request.
54
+ //
55
+ // lib/ai.js is NOT re-exported here on purpose: its `models` registry names WHICH
56
+ // model we call, not what it costs (the rate table lives in billing.js), and
57
+ // importing it would pull @google/genai and construct a client into every
58
+ // consumer of this file.
59
+
60
+
61
+ // What we have BOUGHT from the sending providers, against what the plans above
62
+ // SELL. Here rather than in an env because it is a rate like every other number
63
+ // in this file, and the whole point of this file is that you do not have to
64
+ // know which environment to look in to find one. Changing it is a publish and a
65
+ // pin bump, which is the right friction for a number that changes when a
66
+ // contract changes.
67
+ //
68
+ // READ THIS BEFORE RAISING A PLAN ALLOWANCE. The ceiling is PLATFORM-WIDE while
69
+ // every allowance above is PER ORGANIZATION, and an allowance can be spent
70
+ // entirely on email — so the two are denominated against very different things:
71
+ //
72
+ // Elite 100,000 = 200% of the whole platform's email ceiling
73
+ // Premium 40,000 = 80%
74
+ // Pro 15,000 = 30%
75
+ // Starter 5,000 = 10%
76
+ //
77
+ // As of 2026-08-30 we sell about 2x the email we buy. That is fine while real
78
+ // usage sits far below the allowances, and it is not a margin problem — at this
79
+ // ceiling an email costs a fraction of a cent, far under the 1.5-2.5c overage.
80
+ // It is a CAPACITY problem: running out does not cost a few dollars, it stops
81
+ // every merchant's mail at once. Raising a tier's allowance moves this number
82
+ // too, or the ceiling quietly becomes the real limit.
83
+ const sending = {
84
+ email : {
85
+ // Fraction of monthlyCeiling that raises the alarm. Far enough ahead of
86
+ // the wall to act on, high enough not to fire on ordinary growth.
87
+ alertThreshold : 0.8,
88
+ // SendGrid Essentials 50K — emails per calendar month, PLATFORM-WIDE and
89
+ // across every send path: lead-facing mail, workflow steps, and the sign-in
90
+ // codes and account mail that no plan allowance meters.
91
+ monthlyCeiling : 50000
92
+ }
93
+ };
94
+
95
+ // Weighted actions: what one message of each channel costs against a plan.
96
+ // Named per unit so a bare `2` can never be read as cents.
97
+ const channels = {
98
+ email : {
99
+ actionsPerSend : 1,
100
+ includedInAllowance : true
101
+ },
102
+ sms : {
103
+ // Two actions PER SEGMENT (a long message is several segments), billed from
104
+ // the FIRST segment and never drawn from the plan's included allowance —
105
+ // carrier cost is real from message one, so there is no free tier of it.
106
+ actionsPerSegment : 2,
107
+ includedInAllowance : false
108
+ }
109
+ };
110
+
111
+ export { channels, sending };