@drawbridge/drawbridge-utils 0.0.53 → 0.0.55

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,192 @@
1
+ import { organization, page, connection, fields, field } from './features.js';
2
+ import { infinite, gigabyte } from './index.js';
3
+ import 'currency-codes';
4
+ import 'nanoid';
5
+
6
+ const featuresFor = ( array = [] ) => Object.values({
7
+ ...connection,
8
+ ...organization,
9
+ ...fields,
10
+ ...field,
11
+ ...page
12
+ }).reduce(
13
+ ( accumulator, { key, error, feature } ) => {
14
+
15
+ if( array.includes( key ) ){
16
+
17
+ accumulator.granted[ key ] = feature;
18
+
19
+ } else {
20
+
21
+ accumulator.denied[ key ] = error;
22
+
23
+ }
24
+
25
+ return accumulator;
26
+
27
+ },
28
+ { denied : {}, granted : {} }
29
+ );
30
+
31
+ const all = {
32
+ features : ( array = [] ) => featuresFor([
33
+ connection.mailchimp.key,
34
+ connection.sendgrid.key,
35
+ connection.shopify.key,
36
+ connection.twilio.key,
37
+ connection.webhook.key,
38
+ organization.affiliates.key,
39
+ organization.brands.key,
40
+ fields.additional.key,
41
+ fields.lead.key,
42
+ field.email.key,
43
+ field.name.key,
44
+ field.number.key,
45
+ field.phone.key,
46
+ field.select.key,
47
+ field.text.key,
48
+ field.textarea.key,
49
+ page.qrcode.key,
50
+ page.shortcode.key,
51
+ ...array
52
+ ]),
53
+ limits : ({ actions, members = infinite, storage }) => ({
54
+ campaign : {
55
+ advertisements : infinite,
56
+ links : infinite,
57
+ fields : infinite,
58
+ pages : infinite
59
+ },
60
+ organization : {
61
+ actions,
62
+ affiliates : infinite,
63
+ brands : infinite,
64
+ campaigns : infinite,
65
+ members,
66
+ storage
67
+ }
68
+ })
69
+ };
70
+
71
+ const free = {
72
+ conversion : 3,
73
+ features : all.features(),
74
+ limits : all.limits({
75
+ actions : 200,
76
+ members : 0,
77
+ storage : gigabyte * 5
78
+ }),
79
+ title : 'Free'
80
+ };
81
+
82
+ const plans = {
83
+ DB00002 : {
84
+ features : all.features([ organization.members.key ]),
85
+ limits : all.limits({ actions : 5000, members : 3, storage : gigabyte * 10 }),
86
+ marketing : {
87
+ description : 'Tools to fine-tune campaigns and improve lead quality.',
88
+ features : [],
89
+ limits : [
90
+ [ 'Actions per month', '5,000' ],
91
+ [ 'Affiliates', 'Unlimited' ],
92
+ [ 'Brands', 'Unlimited' ],
93
+ [ 'Campaigns', 'Unlimited' ],
94
+ [ 'Pages', 'Unlimited' ],
95
+ [ 'Members', '3' ],
96
+ [ 'Storage', '10GB' ]
97
+ ]
98
+ },
99
+ overages : { actions : '2.5' },
100
+ title : 'Starter',
101
+ conversion : 2
102
+ },
103
+ DB00003 : {
104
+ features : all.features([
105
+ organization.advertisements.key,
106
+ organization.analytics.key,
107
+ organization.members.key,
108
+ organization.subdomain.key,
109
+ page.slug.key
110
+ ]),
111
+ limits : all.limits({ actions : 15000, members : 5, storage : gigabyte * 20 }),
112
+ marketing : {
113
+ description : 'Expand your reach and grow your lead pipeline.',
114
+ features : [],
115
+ limits : [
116
+ [ 'Actions per month', '15,000' ],
117
+ [ 'Affiliates', 'Unlimited' ],
118
+ [ 'Brands', 'Unlimited' ],
119
+ [ 'Campaigns', 'Unlimited' ],
120
+ [ 'Pages', 'Unlimited' ],
121
+ [ 'Members', '5' ],
122
+ [ 'Storage', '20GB' ]
123
+ ]
124
+ },
125
+ overages : { actions : '2' },
126
+ title : 'Pro',
127
+ conversion : 1.5
128
+ },
129
+ DB00004 : {
130
+ features : all.features([
131
+ organization.advertisements.key,
132
+ organization.analytics.key,
133
+ organization.members.key,
134
+ organization.subdomain.key,
135
+ page.slug.key
136
+ ]),
137
+ limits : all.limits({ actions : 40000, members : 10, storage : gigabyte * 50 }),
138
+ marketing : {
139
+ description : 'Accelerate acquisition with more power and flexibility.',
140
+ features : [],
141
+ limits : [
142
+ [ 'Actions per month', '40,000' ],
143
+ [ 'Affiliates', 'Unlimited' ],
144
+ [ 'Brands', 'Unlimited' ],
145
+ [ 'Campaigns', 'Unlimited' ],
146
+ [ 'Pages', 'Unlimited' ],
147
+ [ 'Members', '10' ],
148
+ [ 'Storage', '50GB' ]
149
+ ]
150
+ },
151
+ overages : { actions : '1.85' },
152
+ title : 'Premium',
153
+ conversion : 1
154
+ },
155
+ DB00005 : {
156
+ features : all.features([
157
+ organization.advertisements.key,
158
+ organization.analytics.key,
159
+ organization.members.key,
160
+ organization.subdomain.key,
161
+ page.slug.key
162
+ ]),
163
+ limits : all.limits({ actions : 100000, members : infinite, storage : gigabyte * 100 }),
164
+ marketing : {
165
+ description : 'Built for brands focused on results.',
166
+ features : [],
167
+ limits : [
168
+ [ 'Actions per month', '100,000' ],
169
+ [ 'Affiliates', 'Unlimited' ],
170
+ [ 'Brands', 'Unlimited' ],
171
+ [ 'Campaigns', 'Unlimited' ],
172
+ [ 'Pages', 'Unlimited' ],
173
+ [ 'Members', 'Unlimited' ],
174
+ [ 'Storage', '100GB' ]
175
+ ]
176
+ },
177
+ overages : { actions : '1.5' },
178
+ title : 'Elite',
179
+ conversion : 0.5
180
+ }
181
+ };
182
+
183
+ // Resolve the conversion-fee percentage for an order's owning org.
184
+ // Precedence: explicit per-subscription override (admin/negotiated) →
185
+ // the plan's catalog default → the free-org rate. `subscription` is null
186
+ // for free orgs (they have no subscription doc).
187
+ const conversionRate = ( subscription ) =>
188
+ subscription?.conversion
189
+ ?? plans[ subscription?.plan ]?.conversion
190
+ ?? free.conversion;
191
+
192
+ export { conversionRate, free, plans };
package/dist/plans.js ADDED
@@ -0,0 +1,321 @@
1
+ // lib/features.js
2
+ var page = {
3
+ qrcode: {
4
+ key: "page:qrcode",
5
+ error: "Plan does not include qrcodes",
6
+ feature: "Page qrcode management"
7
+ },
8
+ shortcode: {
9
+ key: "page:shortcode",
10
+ error: "Plan does not include shortcodes",
11
+ feature: "Page shortcode management"
12
+ },
13
+ slug: {
14
+ key: "page:slug",
15
+ error: "Plan does not include url customization",
16
+ feature: "Page slug customization"
17
+ }
18
+ };
19
+ var fields = {
20
+ additional: {
21
+ key: "campaign:fields:additional",
22
+ error: "Plan does not include additional fields",
23
+ feature: "Campaign additional fields"
24
+ },
25
+ lead: {
26
+ key: "campaign:fields:lead",
27
+ error: "Plan does not include lead fields",
28
+ feature: "Campaign lead fields"
29
+ }
30
+ };
31
+ var field = {
32
+ email: {
33
+ key: "campaign:field:email",
34
+ error: "Plan does not include email field",
35
+ feature: "Campaign email field"
36
+ },
37
+ name: {
38
+ key: "campaign:field:name",
39
+ error: "Plan does not include name field",
40
+ feature: "Campaign name field"
41
+ },
42
+ number: {
43
+ key: "campaign:field:name",
44
+ error: "Plan does not include number field",
45
+ feature: "Campaign number field"
46
+ },
47
+ phone: {
48
+ key: "campaign:field:phone",
49
+ error: "Plan does not include phone field",
50
+ feature: "Campaign phone field"
51
+ },
52
+ select: {
53
+ key: "campaign:field:select",
54
+ error: "Plan does not include dropdown field",
55
+ feature: "Campaign dropdown field"
56
+ },
57
+ text: {
58
+ key: "campaign:field:text",
59
+ error: "Plan does not include short text field",
60
+ feature: "Campaign short text field"
61
+ },
62
+ textarea: {
63
+ key: "campaign:field:textarea",
64
+ error: "Plan does not include long text field",
65
+ feature: "Campaign long text field"
66
+ }
67
+ };
68
+ var connection = {
69
+ mailchimp: {
70
+ key: "organization:connection:mailchimp",
71
+ error: "Plan does not include Mailchimp connection",
72
+ feature: "Mailchimp connection"
73
+ },
74
+ sendgrid: {
75
+ key: "organization:connection:sendgrid",
76
+ error: "Plan does not include SendGrid connection",
77
+ feature: "SendGrid connection"
78
+ },
79
+ shopify: {
80
+ key: "organization:connection:shopify",
81
+ error: "Plan does not include Shopify connection",
82
+ feature: "Shopify connection"
83
+ },
84
+ twilio: {
85
+ key: "organization:connection:twilio",
86
+ error: "Plan does not include Twilio connection",
87
+ feature: "Twilio connection"
88
+ },
89
+ webhook: {
90
+ key: "organization:connection:webhook",
91
+ error: "Plan does not include Webhook connection",
92
+ feature: "Webhook connection"
93
+ }
94
+ };
95
+ var organization = {
96
+ advertisements: {
97
+ key: "organization:advertisements",
98
+ error: "Your plan does not include advertisements",
99
+ feature: "Organization advertisement management"
100
+ },
101
+ affiliates: {
102
+ key: "organization:affiliates",
103
+ error: "Your plan does not include affiliates",
104
+ feature: "Organization affiliates management"
105
+ },
106
+ analytics: {
107
+ key: "organization:analytics",
108
+ error: "Your plan does not include analytics",
109
+ feature: "Organization analytics management"
110
+ },
111
+ brands: {
112
+ key: "organization:brands",
113
+ error: "Your plan does not include brands",
114
+ feature: "Organization brands management"
115
+ },
116
+ members: {
117
+ key: "organization:members",
118
+ error: "Your plan does not include team members",
119
+ feature: "Organization members management"
120
+ },
121
+ reports: {
122
+ key: "organization:report",
123
+ error: "Plan does not include report generation",
124
+ feature: "Organization report generation"
125
+ },
126
+ subdomain: {
127
+ key: "organization:subdomain",
128
+ error: "Plan does not include subdomain customization",
129
+ feature: "Organization subdomain customization"
130
+ }
131
+ };
132
+
133
+ // index.js
134
+ import { code, data } from "currency-codes";
135
+ import { customAlphabet } from "nanoid";
136
+ var nanoid = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 8);
137
+ var infinite = 1e300;
138
+ var megabyte = 1024 * 1024;
139
+ var gigabyte = megabyte * 1024;
140
+ var currencies = data.map((item) => ({
141
+ ...item,
142
+ key: item.currency,
143
+ value: item.code
144
+ }));
145
+
146
+ // lib/plans.js
147
+ var featuresFor = (array = []) => Object.values({
148
+ ...connection,
149
+ ...organization,
150
+ ...fields,
151
+ ...field,
152
+ ...page
153
+ }).reduce(
154
+ (accumulator, { key, error, feature }) => {
155
+ if (array.includes(key)) {
156
+ accumulator.granted[key] = feature;
157
+ } else {
158
+ accumulator.denied[key] = error;
159
+ }
160
+ return accumulator;
161
+ },
162
+ { denied: {}, granted: {} }
163
+ );
164
+ var all = {
165
+ features: (array = []) => featuresFor([
166
+ connection.mailchimp.key,
167
+ connection.sendgrid.key,
168
+ connection.shopify.key,
169
+ connection.twilio.key,
170
+ connection.webhook.key,
171
+ organization.affiliates.key,
172
+ organization.brands.key,
173
+ fields.additional.key,
174
+ fields.lead.key,
175
+ field.email.key,
176
+ field.name.key,
177
+ field.number.key,
178
+ field.phone.key,
179
+ field.select.key,
180
+ field.text.key,
181
+ field.textarea.key,
182
+ page.qrcode.key,
183
+ page.shortcode.key,
184
+ ...array
185
+ ]),
186
+ limits: ({ actions, members = infinite, storage }) => ({
187
+ campaign: {
188
+ advertisements: infinite,
189
+ links: infinite,
190
+ fields: infinite,
191
+ pages: infinite
192
+ },
193
+ organization: {
194
+ actions,
195
+ affiliates: infinite,
196
+ brands: infinite,
197
+ campaigns: infinite,
198
+ members,
199
+ storage
200
+ }
201
+ })
202
+ };
203
+ var free = {
204
+ conversion: 3,
205
+ features: all.features(),
206
+ limits: all.limits({
207
+ actions: 200,
208
+ members: 0,
209
+ storage: gigabyte * 5
210
+ }),
211
+ title: "Free"
212
+ };
213
+ var plans = {
214
+ DB00002: {
215
+ features: all.features([organization.members.key]),
216
+ limits: all.limits({ actions: 5e3, members: 3, storage: gigabyte * 10 }),
217
+ marketing: {
218
+ description: "Tools to fine-tune campaigns and improve lead quality.",
219
+ features: [],
220
+ limits: [
221
+ ["Actions per month", "5,000"],
222
+ ["Affiliates", "Unlimited"],
223
+ ["Brands", "Unlimited"],
224
+ ["Campaigns", "Unlimited"],
225
+ ["Pages", "Unlimited"],
226
+ ["Members", "3"],
227
+ ["Storage", "10GB"]
228
+ ]
229
+ },
230
+ overages: { actions: "2.5" },
231
+ title: "Starter",
232
+ conversion: 2
233
+ },
234
+ DB00003: {
235
+ features: all.features([
236
+ organization.advertisements.key,
237
+ organization.analytics.key,
238
+ organization.members.key,
239
+ organization.subdomain.key,
240
+ page.slug.key
241
+ ]),
242
+ limits: all.limits({ actions: 15e3, members: 5, storage: gigabyte * 20 }),
243
+ marketing: {
244
+ description: "Expand your reach and grow your lead pipeline.",
245
+ features: [],
246
+ limits: [
247
+ ["Actions per month", "15,000"],
248
+ ["Affiliates", "Unlimited"],
249
+ ["Brands", "Unlimited"],
250
+ ["Campaigns", "Unlimited"],
251
+ ["Pages", "Unlimited"],
252
+ ["Members", "5"],
253
+ ["Storage", "20GB"]
254
+ ]
255
+ },
256
+ overages: { actions: "2" },
257
+ title: "Pro",
258
+ conversion: 1.5
259
+ },
260
+ DB00004: {
261
+ features: all.features([
262
+ organization.advertisements.key,
263
+ organization.analytics.key,
264
+ organization.members.key,
265
+ organization.subdomain.key,
266
+ page.slug.key
267
+ ]),
268
+ limits: all.limits({ actions: 4e4, members: 10, storage: gigabyte * 50 }),
269
+ marketing: {
270
+ description: "Accelerate acquisition with more power and flexibility.",
271
+ features: [],
272
+ limits: [
273
+ ["Actions per month", "40,000"],
274
+ ["Affiliates", "Unlimited"],
275
+ ["Brands", "Unlimited"],
276
+ ["Campaigns", "Unlimited"],
277
+ ["Pages", "Unlimited"],
278
+ ["Members", "10"],
279
+ ["Storage", "50GB"]
280
+ ]
281
+ },
282
+ overages: { actions: "1.85" },
283
+ title: "Premium",
284
+ conversion: 1
285
+ },
286
+ DB00005: {
287
+ features: all.features([
288
+ organization.advertisements.key,
289
+ organization.analytics.key,
290
+ organization.members.key,
291
+ organization.subdomain.key,
292
+ page.slug.key
293
+ ]),
294
+ limits: all.limits({ actions: 1e5, members: infinite, storage: gigabyte * 100 }),
295
+ marketing: {
296
+ description: "Built for brands focused on results.",
297
+ features: [],
298
+ limits: [
299
+ ["Actions per month", "100,000"],
300
+ ["Affiliates", "Unlimited"],
301
+ ["Brands", "Unlimited"],
302
+ ["Campaigns", "Unlimited"],
303
+ ["Pages", "Unlimited"],
304
+ ["Members", "Unlimited"],
305
+ ["Storage", "100GB"]
306
+ ]
307
+ },
308
+ overages: { actions: "1.5" },
309
+ title: "Elite",
310
+ conversion: 0.5
311
+ }
312
+ };
313
+ var conversionRate = (subscription) => {
314
+ var _a;
315
+ return (subscription == null ? void 0 : subscription.conversion) ?? ((_a = plans[subscription == null ? void 0 : subscription.plan]) == null ? void 0 : _a.conversion) ?? free.conversion;
316
+ };
317
+ export {
318
+ conversionRate,
319
+ free,
320
+ plans
321
+ };
package/package.json CHANGED
@@ -118,6 +118,16 @@
118
118
  "types": "./dist/transactions.d.ts",
119
119
  "import": "./dist/transactions.js",
120
120
  "require": "./dist/transactions.cjs"
121
+ },
122
+ "./features": {
123
+ "types": "./dist/features.d.ts",
124
+ "import": "./dist/features.js",
125
+ "require": "./dist/features.cjs"
126
+ },
127
+ "./plans": {
128
+ "types": "./dist/plans.d.ts",
129
+ "import": "./dist/plans.js",
130
+ "require": "./dist/plans.cjs"
121
131
  }
122
132
  },
123
133
  "files": [
@@ -135,5 +145,5 @@
135
145
  "build": "tsup && npm publish"
136
146
  },
137
147
  "types": "dist/index.d.ts",
138
- "version": "0.0.53"
148
+ "version": "0.0.55"
139
149
  }