@vrplatform/hyperline-client 1.0.25 → 1.0.26
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/build/main/client.d.ts +2 -2
- package/build/main/client.js.map +1 -1
- package/build/main/const.d.ts +0 -7
- package/build/main/const.js +0 -7
- package/build/main/const.js.map +1 -1
- package/build/main/src/_types.generated.d.ts +22310 -0
- package/build/main/src/_types.generated.js +6 -0
- package/build/main/src/_types.generated.js.map +1 -0
- package/build/main/src/client.d.ts +1706 -0
- package/build/main/src/client.js +294 -0
- package/build/main/src/client.js.map +1 -0
- package/build/main/src/const.d.ts +73 -0
- package/build/main/src/const.js +257 -0
- package/build/main/src/const.js.map +1 -0
- package/build/main/src/hooks.d.ts +10 -0
- package/build/main/src/hooks.js +13 -0
- package/build/main/src/hooks.js.map +1 -0
- package/build/main/src/index.d.ts +5 -0
- package/build/main/src/index.js +6 -0
- package/build/main/src/index.js.map +1 -0
- package/build/main/src/types.d.ts +35 -0
- package/build/main/src/types.js +2 -0
- package/build/main/src/types.js.map +1 -0
- package/build/main/src/utils/arrayBufferToBase64.d.ts +1 -0
- package/build/main/src/utils/arrayBufferToBase64.js +9 -0
- package/build/main/src/utils/arrayBufferToBase64.js.map +1 -0
- package/build/main/src/utils/calculateMrr.d.ts +45 -0
- package/build/main/src/utils/calculateMrr.js +107 -0
- package/build/main/src/utils/calculateMrr.js.map +1 -0
- package/build/main/src/utils/getMrrDiffReasons.d.ts +15 -0
- package/build/main/src/utils/getMrrDiffReasons.js +217 -0
- package/build/main/src/utils/getMrrDiffReasons.js.map +1 -0
- package/build/main/src/utils/index.d.ts +3 -0
- package/build/main/src/utils/index.js +4 -0
- package/build/main/src/utils/index.js.map +1 -0
- package/build/main/tsconfig.main.tsbuildinfo +1 -0
- package/build/main/types.d.ts +0 -43
- package/build/main/types.js.map +1 -1
- package/build/main/utils/calculateMrr.d.ts +45 -0
- package/build/main/utils/calculateMrr.js +107 -0
- package/build/main/utils/calculateMrr.js.map +1 -0
- package/build/main/utils/index.d.ts +1 -0
- package/build/main/utils/index.js +1 -0
- package/build/main/utils/index.js.map +1 -1
- package/build/module/client.d.ts +2 -2
- package/build/module/client.js.map +1 -1
- package/build/module/const.d.ts +0 -7
- package/build/module/const.js +0 -7
- package/build/module/const.js.map +1 -1
- package/build/module/src/_types.generated.d.ts +22310 -0
- package/build/module/src/_types.generated.js +6 -0
- package/build/module/src/_types.generated.js.map +1 -0
- package/build/module/src/client.d.ts +1706 -0
- package/build/module/src/client.js +296 -0
- package/build/module/src/client.js.map +1 -0
- package/build/module/src/const.d.ts +73 -0
- package/build/module/src/const.js +257 -0
- package/build/module/src/const.js.map +1 -0
- package/build/module/src/hooks.d.ts +10 -0
- package/build/module/src/hooks.js +13 -0
- package/build/module/src/hooks.js.map +1 -0
- package/build/module/src/index.d.ts +5 -0
- package/build/module/src/index.js +6 -0
- package/build/module/src/index.js.map +1 -0
- package/build/module/src/types.d.ts +35 -0
- package/build/module/src/types.js +2 -0
- package/build/module/src/types.js.map +1 -0
- package/build/module/src/utils/arrayBufferToBase64.d.ts +1 -0
- package/build/module/src/utils/arrayBufferToBase64.js +9 -0
- package/build/module/src/utils/arrayBufferToBase64.js.map +1 -0
- package/build/module/src/utils/calculateMrr.d.ts +45 -0
- package/build/module/src/utils/calculateMrr.js +107 -0
- package/build/module/src/utils/calculateMrr.js.map +1 -0
- package/build/module/src/utils/getMrrDiffReasons.d.ts +15 -0
- package/build/module/src/utils/getMrrDiffReasons.js +217 -0
- package/build/module/src/utils/getMrrDiffReasons.js.map +1 -0
- package/build/module/src/utils/index.d.ts +3 -0
- package/build/module/src/utils/index.js +4 -0
- package/build/module/src/utils/index.js.map +1 -0
- package/build/module/tsconfig.esm.tsbuildinfo +1 -0
- package/build/module/types.d.ts +0 -43
- package/build/module/types.js.map +1 -1
- package/build/module/utils/calculateMrr.d.ts +45 -0
- package/build/module/utils/calculateMrr.js +107 -0
- package/build/module/utils/calculateMrr.js.map +1 -0
- package/build/module/utils/index.d.ts +1 -0
- package/build/module/utils/index.js +1 -0
- package/build/module/utils/index.js.map +1 -1
- package/package.json +2 -4
- package/src/client.ts +6 -6
- package/src/const.ts +0 -14
- package/src/types.ts +0 -55
- package/src/utils/calculateMrr.ts +206 -0
- package/src/utils/index.ts +1 -0
package/src/types.ts
CHANGED
|
@@ -14,61 +14,6 @@ export type HyperlinePayload<T extends HyperlineWebhook> = {
|
|
|
14
14
|
data: Record<string, any>;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export type HyperlineCreateSubscriptionPayload = {
|
|
18
|
-
customer_id: string;
|
|
19
|
-
invoicing_entity_id?: string | null;
|
|
20
|
-
activation_strategy?: 'start_date' | 'manually' | 'checkout';
|
|
21
|
-
starts_at?: string;
|
|
22
|
-
plan_id?: string;
|
|
23
|
-
template_id?: string;
|
|
24
|
-
template_configuration_id?: string;
|
|
25
|
-
trial?: {
|
|
26
|
-
end_strategy: 'manual' | 'end_date' | 'duration';
|
|
27
|
-
starts_at?: string;
|
|
28
|
-
ends_at?: string;
|
|
29
|
-
duration?: {
|
|
30
|
-
period: 'days' | 'weeks' | 'months' | 'years';
|
|
31
|
-
count: number;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
cancellation_strategy?:
|
|
35
|
-
| 'refund_prorata'
|
|
36
|
-
| 'refund_custom'
|
|
37
|
-
| 'charge_prorata'
|
|
38
|
-
| 'charge_custom'
|
|
39
|
-
| 'end_of_period'
|
|
40
|
-
| 'do_nothing';
|
|
41
|
-
generate_draft_invoices?: boolean;
|
|
42
|
-
renew_automatically?: boolean;
|
|
43
|
-
contract_terms?: {
|
|
44
|
-
activation_strategy:
|
|
45
|
-
| 'start_date'
|
|
46
|
-
| 'immediately'
|
|
47
|
-
| 'manual'
|
|
48
|
-
| 'quote_signature'
|
|
49
|
-
| 'checkout';
|
|
50
|
-
end_strategy: 'end_date' | 'duration' | 'manual';
|
|
51
|
-
starts_at?: string;
|
|
52
|
-
duration?: {
|
|
53
|
-
period: 'days' | 'weeks' | 'months' | 'years';
|
|
54
|
-
count: number;
|
|
55
|
-
};
|
|
56
|
-
renew_automatically?: boolean;
|
|
57
|
-
renew_for_duration?: {
|
|
58
|
-
period: 'days' | 'weeks' | 'months' | 'years';
|
|
59
|
-
count: number;
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
billing_cycle_alignment?: 'calendar_period' | 'anniversary';
|
|
63
|
-
coupons?: {
|
|
64
|
-
id: string;
|
|
65
|
-
repeat: 'once' | 'forever' | 'custom';
|
|
66
|
-
expires_at?: string;
|
|
67
|
-
apply_at?: string;
|
|
68
|
-
product_ids?: string[];
|
|
69
|
-
}[];
|
|
70
|
-
};
|
|
71
|
-
|
|
72
17
|
export type BillableEvent = {
|
|
73
18
|
record: {
|
|
74
19
|
id: '202408_cus_w_Q7M9bXcHMKB6';
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GL_HYPERLINE_DEFAULT_DEV_PLAN_ID,
|
|
3
|
+
GL_HYPERLINE_DEFAULT_MIN_AMOUNT,
|
|
4
|
+
GL_HYPERLINE_DEFAULT_PLAN_ID,
|
|
5
|
+
HYPERLINE_DEFAULT_DEV_PLAN_ID,
|
|
6
|
+
HYPERLINE_DEFAULT_MIN_AMOUNT,
|
|
7
|
+
HYPERLINE_DEFAULT_PLAN_ID,
|
|
8
|
+
} from '../const';
|
|
9
|
+
import { useHyperlineByToken } from '../hooks';
|
|
10
|
+
|
|
11
|
+
export async function calculateMrr(
|
|
12
|
+
subscriptionId: string,
|
|
13
|
+
estimated = false,
|
|
14
|
+
_activeListings?: number,
|
|
15
|
+
hyperline: {
|
|
16
|
+
getSubscription(
|
|
17
|
+
id: string,
|
|
18
|
+
liveBilling?: boolean
|
|
19
|
+
): Promise<{
|
|
20
|
+
customer_id: string;
|
|
21
|
+
plan_id: string | null;
|
|
22
|
+
products?: unknown[];
|
|
23
|
+
coupons?: (
|
|
24
|
+
| {
|
|
25
|
+
type: 'amount';
|
|
26
|
+
repeat: 'once' | 'forever' | 'custom';
|
|
27
|
+
discount_amount: number;
|
|
28
|
+
}
|
|
29
|
+
| {
|
|
30
|
+
type: 'percent';
|
|
31
|
+
repeat: 'once' | 'forever' | 'custom';
|
|
32
|
+
discount_percent: number;
|
|
33
|
+
}
|
|
34
|
+
)[];
|
|
35
|
+
phases?: {
|
|
36
|
+
type: 'setup' | 'trial' | 'standard';
|
|
37
|
+
status: 'pending' | 'active' | 'finished';
|
|
38
|
+
products: {
|
|
39
|
+
min_amount?: number | null;
|
|
40
|
+
max_amount?: number | null;
|
|
41
|
+
prices: (
|
|
42
|
+
| {
|
|
43
|
+
type: 'volume';
|
|
44
|
+
amount: number;
|
|
45
|
+
from: number;
|
|
46
|
+
to: number | null;
|
|
47
|
+
unit_count: number;
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
type:
|
|
51
|
+
| 'bps'
|
|
52
|
+
| 'bulk'
|
|
53
|
+
| 'bundle'
|
|
54
|
+
| 'fee'
|
|
55
|
+
| 'flat_fee'
|
|
56
|
+
| 'packaged';
|
|
57
|
+
}
|
|
58
|
+
)[];
|
|
59
|
+
}[];
|
|
60
|
+
}[];
|
|
61
|
+
live_billing?: { total_amount: number };
|
|
62
|
+
} | null>;
|
|
63
|
+
getInvoicesByCustomerId(id: string): Promise<{
|
|
64
|
+
data: {
|
|
65
|
+
emitted_at: string;
|
|
66
|
+
total_amount: number;
|
|
67
|
+
}[];
|
|
68
|
+
} | null>;
|
|
69
|
+
} = useHyperlineByToken(process.env.HYPERLINE_TOKEN!),
|
|
70
|
+
includeLiveBilling = false
|
|
71
|
+
) {
|
|
72
|
+
const _subscription = await hyperline.getSubscription(
|
|
73
|
+
subscriptionId,
|
|
74
|
+
includeLiveBilling
|
|
75
|
+
);
|
|
76
|
+
if (!_subscription) throw new Error('Subscription not found');
|
|
77
|
+
|
|
78
|
+
const { products, phases, ...subscription } = _subscription;
|
|
79
|
+
|
|
80
|
+
let mrr = 0;
|
|
81
|
+
const activeListings = _activeListings || 0;
|
|
82
|
+
const phase = phases?.filter((x) =>
|
|
83
|
+
estimated
|
|
84
|
+
? x.type === 'standard'
|
|
85
|
+
: (x.type === 'trial' && x.status === 'active') || x.type === 'standard'
|
|
86
|
+
)?.[0];
|
|
87
|
+
const product = phase?.products?.[0];
|
|
88
|
+
const type = product?.prices?.[0].type;
|
|
89
|
+
if (type === 'volume') {
|
|
90
|
+
const volumePrices: Array<{
|
|
91
|
+
amount: number;
|
|
92
|
+
from: number;
|
|
93
|
+
to: number | null;
|
|
94
|
+
unit_count: number;
|
|
95
|
+
}> = [];
|
|
96
|
+
|
|
97
|
+
product?.prices?.forEach((price) => {
|
|
98
|
+
if (
|
|
99
|
+
price.type !== 'volume' ||
|
|
100
|
+
!('amount' in price) ||
|
|
101
|
+
!('from' in price) ||
|
|
102
|
+
!('to' in price) ||
|
|
103
|
+
!('unit_count' in price)
|
|
104
|
+
)
|
|
105
|
+
return;
|
|
106
|
+
|
|
107
|
+
volumePrices.push({
|
|
108
|
+
amount: price.amount,
|
|
109
|
+
from: price.from,
|
|
110
|
+
to: price.to,
|
|
111
|
+
unit_count: price.unit_count,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
volumePrices.sort((a, b) => a.from - b.from);
|
|
115
|
+
|
|
116
|
+
mrr =
|
|
117
|
+
volumePrices.reduce((acc, price) => {
|
|
118
|
+
const listings =
|
|
119
|
+
price.to && activeListings >= price.to
|
|
120
|
+
? price.to - price.from
|
|
121
|
+
: activeListings >= price.from
|
|
122
|
+
? activeListings - price.from
|
|
123
|
+
: 0;
|
|
124
|
+
|
|
125
|
+
acc += (price.amount / 100) * (listings / price.unit_count);
|
|
126
|
+
|
|
127
|
+
return acc;
|
|
128
|
+
}, 0) || 0;
|
|
129
|
+
|
|
130
|
+
const firstTier = volumePrices[0];
|
|
131
|
+
const secondTier = volumePrices[1];
|
|
132
|
+
const product_min_amount =
|
|
133
|
+
product &&
|
|
134
|
+
'min_amount' in product &&
|
|
135
|
+
typeof product.min_amount === 'number'
|
|
136
|
+
? product.min_amount
|
|
137
|
+
: null;
|
|
138
|
+
const product_max_amount =
|
|
139
|
+
product &&
|
|
140
|
+
'max_amount' in product &&
|
|
141
|
+
typeof product.max_amount === 'number'
|
|
142
|
+
? product.max_amount
|
|
143
|
+
: null;
|
|
144
|
+
const inferred_min_amount =
|
|
145
|
+
firstTier &&
|
|
146
|
+
secondTier &&
|
|
147
|
+
firstTier.from === 0 &&
|
|
148
|
+
firstTier.to != null &&
|
|
149
|
+
secondTier.from === firstTier.to &&
|
|
150
|
+
firstTier.amount === secondTier.amount &&
|
|
151
|
+
firstTier.unit_count === secondTier.unit_count
|
|
152
|
+
? firstTier.amount *
|
|
153
|
+
((firstTier.to - firstTier.from) / firstTier.unit_count)
|
|
154
|
+
: 0;
|
|
155
|
+
const plan_min_amount = [
|
|
156
|
+
GL_HYPERLINE_DEFAULT_PLAN_ID,
|
|
157
|
+
GL_HYPERLINE_DEFAULT_DEV_PLAN_ID,
|
|
158
|
+
].includes(subscription.plan_id!)
|
|
159
|
+
? GL_HYPERLINE_DEFAULT_MIN_AMOUNT
|
|
160
|
+
: [HYPERLINE_DEFAULT_PLAN_ID, HYPERLINE_DEFAULT_DEV_PLAN_ID].includes(
|
|
161
|
+
subscription.plan_id!
|
|
162
|
+
)
|
|
163
|
+
? HYPERLINE_DEFAULT_MIN_AMOUNT
|
|
164
|
+
: 0;
|
|
165
|
+
|
|
166
|
+
const min_amount =
|
|
167
|
+
((product_min_amount || plan_min_amount || inferred_min_amount) ?? 0) /
|
|
168
|
+
100;
|
|
169
|
+
mrr = Math.max(mrr, min_amount);
|
|
170
|
+
|
|
171
|
+
const max_amount = ((product_max_amount || 0) ?? 0) / 100;
|
|
172
|
+
mrr = max_amount > 0 ? Math.min(mrr, max_amount) : mrr;
|
|
173
|
+
|
|
174
|
+
// apply discounts (only these who repeat forever if estimated is true)
|
|
175
|
+
(subscription.coupons || [])
|
|
176
|
+
.filter((coupon) => (estimated ? coupon.repeat === 'forever' : true))
|
|
177
|
+
.forEach((x) => {
|
|
178
|
+
if ('discount_amount' in x && x.discount_amount)
|
|
179
|
+
mrr -= x.discount_amount / 100;
|
|
180
|
+
else if ('discount_percent' in x && x.discount_percent)
|
|
181
|
+
mrr -= (x.discount_percent / 100) * mrr;
|
|
182
|
+
});
|
|
183
|
+
} else if (type === 'bps') {
|
|
184
|
+
const { data } = subscription?.customer_id
|
|
185
|
+
? (await hyperline.getInvoicesByCustomerId(subscription.customer_id)) || {
|
|
186
|
+
data: [],
|
|
187
|
+
}
|
|
188
|
+
: { data: [] };
|
|
189
|
+
|
|
190
|
+
// sort invoices by date
|
|
191
|
+
const invoices = data
|
|
192
|
+
?.sort((a, b) => a.emitted_at.localeCompare(b.emitted_at))
|
|
193
|
+
.reverse();
|
|
194
|
+
|
|
195
|
+
// get the last invoice
|
|
196
|
+
mrr = (invoices[0]?.total_amount || 0) / 100;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
mrr,
|
|
201
|
+
mrrAlt:
|
|
202
|
+
subscription.live_billing?.total_amount == null
|
|
203
|
+
? null
|
|
204
|
+
: subscription.live_billing.total_amount / 100,
|
|
205
|
+
};
|
|
206
|
+
}
|
package/src/utils/index.ts
CHANGED