@boltclaw/referrals 0.0.0-stage → 0.4.0

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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +500 -3
  3. package/dist/api-types.d.ts +245 -0
  4. package/dist/api-types.js +2 -0
  5. package/dist/api-types.js.map +1 -0
  6. package/dist/assistant-tools.d.ts +40 -0
  7. package/dist/assistant-tools.js +120 -0
  8. package/dist/assistant-tools.js.map +1 -0
  9. package/dist/assistant.d.ts +62 -0
  10. package/dist/assistant.js +305 -0
  11. package/dist/assistant.js.map +1 -0
  12. package/dist/case.d.ts +2 -0
  13. package/dist/case.js +30 -0
  14. package/dist/case.js.map +1 -0
  15. package/dist/client.d.ts +22 -0
  16. package/dist/client.js +80 -0
  17. package/dist/client.js.map +1 -0
  18. package/dist/element.d.ts +4 -0
  19. package/dist/element.js +204 -0
  20. package/dist/element.js.map +1 -0
  21. package/dist/errors.d.ts +19 -0
  22. package/dist/errors.js +62 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/generated/api.d.ts +6477 -0
  25. package/dist/generated/api.js +891 -0
  26. package/dist/generated/api.js.map +1 -0
  27. package/dist/index.d.ts +18 -0
  28. package/dist/index.js +10 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/loader.d.ts +118 -0
  31. package/dist/loader.js +524 -0
  32. package/dist/loader.js.map +1 -0
  33. package/dist/middleware.d.ts +100 -0
  34. package/dist/middleware.js +378 -0
  35. package/dist/middleware.js.map +1 -0
  36. package/dist/origin.d.ts +3 -0
  37. package/dist/origin.js +22 -0
  38. package/dist/origin.js.map +1 -0
  39. package/dist/react.d.ts +69 -0
  40. package/dist/react.js +328 -0
  41. package/dist/react.js.map +1 -0
  42. package/dist/server-index.d.ts +17 -0
  43. package/dist/server-index.js +9 -0
  44. package/dist/server-index.js.map +1 -0
  45. package/dist/server.d.ts +106 -0
  46. package/dist/server.js +511 -0
  47. package/dist/server.js.map +1 -0
  48. package/dist/typed-code.d.ts +78 -0
  49. package/dist/typed-code.js +234 -0
  50. package/dist/typed-code.js.map +1 -0
  51. package/dist/types.d.ts +254 -0
  52. package/dist/types.js +61 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/webhooks.d.ts +20 -0
  55. package/dist/webhooks.js +90 -0
  56. package/dist/webhooks.js.map +1 -0
  57. package/package.json +97 -6
@@ -0,0 +1,234 @@
1
+ export const BOLTCLAW_LINK_HOSTS = ["boltclaw.ai", "www.boltclaw.ai"];
2
+ export const DEFAULT_LINK_PARAM = "via";
3
+ export const TYPED_INPUT_MAX = 2048;
4
+ const CODE_FORMAT = /^[a-z0-9]+(-[a-z0-9]+)*$/;
5
+ const CODE_MIN = 3;
6
+ const CODE_MAX = 40;
7
+ const RESERVED = [
8
+ "join", "invite", "api", "assets", "static", "qr", "preview", "embed", "admin", "test", "dashboard",
9
+ "payouts", "tax", "programs", "signin", "signout", "auth",
10
+ ];
11
+ const SEPARATORS = new RegExp("[\\s\\p{Pd}" + String.fromCharCode(0x2212) + "]+", "gu");
12
+ const INVISIBLE = /\p{Cf}/gu;
13
+ export function typedCodeLooksLikeLink(input) {
14
+ if (typeof input !== "string")
15
+ return false;
16
+ const s = input.trim();
17
+ return /^[a-z][a-z0-9+.-]*:\/\//i.test(s) || s.includes("/") || /^[a-z0-9-]+(\.[a-z0-9-]+)+([/?#:]|$)/i.test(s);
18
+ }
19
+ function cleanCode(raw) {
20
+ const folded = raw
21
+ .normalize("NFKC")
22
+ .replace(INVISIBLE, "")
23
+ .toLowerCase()
24
+ .replace(SEPARATORS, "-")
25
+ .replace(/^-+|-+$/g, "");
26
+ if (folded.length < CODE_MIN || folded.length > CODE_MAX || !CODE_FORMAT.test(folded))
27
+ return null;
28
+ if (RESERVED.includes(folded))
29
+ return null;
30
+ return folded;
31
+ }
32
+ function hostSet(list) {
33
+ return (list ?? [])
34
+ .filter((h) => typeof h === "string")
35
+ .map((h) => h.trim().toLowerCase().replace(/\.$/, ""))
36
+ .filter((h) => h.length > 0);
37
+ }
38
+ function codeFromLink(input, hosts) {
39
+ const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(input) ? input : `https://${input}`;
40
+ let url;
41
+ try {
42
+ url = new URL(withScheme);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ if (url.protocol !== "https:" && url.protocol !== "http:")
48
+ return null;
49
+ if (url.username !== "" || url.password !== "")
50
+ return null;
51
+ const host = url.hostname.toLowerCase().replace(/\.$/, "");
52
+ const linkHosts = hostSet(hosts.linkHosts);
53
+ const allowed = new Set([...BOLTCLAW_LINK_HOSTS, ...hostSet(hosts.hosts), ...linkHosts]);
54
+ if (!allowed.has(host))
55
+ return null;
56
+ const segments = url.pathname.split("/").filter((s) => s.length > 0);
57
+ let segment = null;
58
+ if (segments.length === 2 && segments[0] === "r")
59
+ segment = segments[1] ?? null;
60
+ else if (segments.length === 1 && linkHosts.includes(host))
61
+ segment = segments[0] ?? null;
62
+ let raw;
63
+ if (segment !== null) {
64
+ try {
65
+ raw = decodeURIComponent(segment);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ else {
72
+ const param = typeof hosts.param === "string" && /^[a-z0-9_-]{1,40}$/i.test(hosts.param) ? hosts.param : DEFAULT_LINK_PARAM;
73
+ raw = url.searchParams.get(param);
74
+ }
75
+ if (raw === null || raw.length === 0)
76
+ return null;
77
+ return cleanCode(raw);
78
+ }
79
+ export function parseTypedCode(input, hosts = {}) {
80
+ if (typeof input !== "string")
81
+ return null;
82
+ const s = input.normalize("NFKC").replace(INVISIBLE, "").trim();
83
+ if (s.length === 0 || s.length > TYPED_INPUT_MAX)
84
+ return null;
85
+ if (typedCodeLooksLikeLink(s))
86
+ return codeFromLink(s, hosts);
87
+ return cleanCode(s);
88
+ }
89
+ export function codeKeyOf(code) {
90
+ return code.replace(/-/g, "");
91
+ }
92
+ export const CODE_STYLES = ["standard", "typed"];
93
+ export const CODE_PREFIXES = ["none", "name"];
94
+ export const TYPED_CODE_LENGTH_MIN = 6;
95
+ export const TYPED_CODE_LENGTH_MAX = 8;
96
+ export const TYPED_CODE_LENGTH_DEFAULT = 8;
97
+ export const STANDARD_CODE_LENGTH = 10;
98
+ export const NAME_PREFIX_MAX = 8;
99
+ export const NAME_RANDOM_LENGTH = 4;
100
+ export const STANDARD_CODE_STYLE = { style: "standard", length: null, prefix: "none" };
101
+ export function codeStyleOf(row) {
102
+ if (!row || row.codeStyle !== "typed")
103
+ return STANDARD_CODE_STYLE;
104
+ const length = typeof row.codeLength === "number" && Number.isInteger(row.codeLength) && row.codeLength >= TYPED_CODE_LENGTH_MIN && row.codeLength <= TYPED_CODE_LENGTH_MAX
105
+ ? row.codeLength
106
+ : TYPED_CODE_LENGTH_DEFAULT;
107
+ return { style: "typed", length, prefix: row.codePrefix === "name" ? "name" : "none" };
108
+ }
109
+ export function parseCodeStyle(input, current = STANDARD_CODE_STYLE) {
110
+ const style = input.style === undefined ? current.style : input.style;
111
+ if (style !== "standard" && style !== "typed")
112
+ return { ok: false, error: "code_style is standard or typed." };
113
+ if (style === "standard") {
114
+ if (input.length !== undefined && input.length !== null)
115
+ return { ok: false, error: "code_length is only for code_style typed." };
116
+ if (input.prefix !== undefined && input.prefix !== null && input.prefix !== "none") {
117
+ return { ok: false, error: "code_prefix is only for code_style typed." };
118
+ }
119
+ return { ok: true, value: STANDARD_CODE_STYLE };
120
+ }
121
+ const length = input.length === undefined || input.length === null ? (current.length ?? TYPED_CODE_LENGTH_DEFAULT) : input.length;
122
+ if (typeof length !== "number" || !Number.isInteger(length) || length < TYPED_CODE_LENGTH_MIN || length > TYPED_CODE_LENGTH_MAX) {
123
+ return { ok: false, error: `code_length is a whole number from ${TYPED_CODE_LENGTH_MIN} to ${TYPED_CODE_LENGTH_MAX}.` };
124
+ }
125
+ const whole = Math.trunc(length);
126
+ const prefix = input.prefix === undefined || input.prefix === null ? current.prefix : input.prefix;
127
+ if (prefix !== "none" && prefix !== "name")
128
+ return { ok: false, error: "code_prefix is none or name." };
129
+ return { ok: true, value: { style: "typed", length: whole, prefix } };
130
+ }
131
+ export function foldNameForCode(name) {
132
+ if (typeof name !== "string")
133
+ return "";
134
+ return name
135
+ .normalize("NFKD")
136
+ .replace(/\p{M}/gu, "")
137
+ .toLowerCase()
138
+ .replace(/[^a-z]/g, "")
139
+ .slice(0, NAME_PREFIX_MAX);
140
+ }
141
+ export function codeInStyle(style, name, draw) {
142
+ if (style.style !== "typed")
143
+ return draw(STANDARD_CODE_LENGTH);
144
+ if (style.prefix === "name") {
145
+ const letters = foldNameForCode(name);
146
+ if (letters.length > 0)
147
+ return `${letters}-${draw(NAME_RANDOM_LENGTH)}`;
148
+ }
149
+ return draw(style.length ?? TYPED_CODE_LENGTH_DEFAULT);
150
+ }
151
+ export function displayCode(code, style) {
152
+ const s = typeof style === "string" ? style : style.style;
153
+ return s === "typed" ? code.toUpperCase() : code;
154
+ }
155
+ export const CODE_WINDOWS = ["account_age", "first_payment"];
156
+ export const CODE_WINDOW_ENTRIES = ["link", "typed", "checkout_code"];
157
+ export const CODE_WINDOW_DAYS_MIN = 1;
158
+ export const CODE_WINDOW_DAYS_MAX = 365;
159
+ export const CODE_WINDOW_DAYS_DEFAULT = 30;
160
+ export const ACCOUNT_AGE_WINDOW = { until: "account_age", days: CODE_WINDOW_DAYS_DEFAULT, entries: null };
161
+ export function codeWindowOf(row) {
162
+ const days = row && typeof row.codeWindowDays === "number" && Number.isInteger(row.codeWindowDays) &&
163
+ row.codeWindowDays >= CODE_WINDOW_DAYS_MIN && row.codeWindowDays <= CODE_WINDOW_DAYS_MAX
164
+ ? row.codeWindowDays
165
+ : CODE_WINDOW_DAYS_DEFAULT;
166
+ const entries = Array.isArray(row?.codeWindowEntries)
167
+ ? CODE_WINDOW_ENTRIES.filter((e) => row.codeWindowEntries.includes(e))
168
+ : null;
169
+ return {
170
+ until: row?.codeWindow === "first_payment" ? "first_payment" : "account_age",
171
+ days,
172
+ entries: entries !== null && entries.length > 0 ? entries : null,
173
+ };
174
+ }
175
+ export function parseCodeWindow(input, current = ACCOUNT_AGE_WINDOW) {
176
+ const until = input.until === undefined ? current.until : input.until;
177
+ if (until !== "account_age" && until !== "first_payment")
178
+ return { ok: false, error: "code_window is account_age or first_payment." };
179
+ const days = input.days === undefined ? current.days : input.days;
180
+ if (typeof days !== "number" || !Number.isInteger(days) || days < CODE_WINDOW_DAYS_MIN || days > CODE_WINDOW_DAYS_MAX) {
181
+ return { ok: false, error: `code_window_days is a whole number from ${CODE_WINDOW_DAYS_MIN} to ${CODE_WINDOW_DAYS_MAX}.` };
182
+ }
183
+ let entries = current.entries;
184
+ if (input.entries !== undefined) {
185
+ if (input.entries === null)
186
+ entries = null;
187
+ else if (!Array.isArray(input.entries) || input.entries.length === 0 || input.entries.length > CODE_WINDOW_ENTRIES.length) {
188
+ return { ok: false, error: "code_window_entries is null (every entry) or a list of link, typed and checkout_code." };
189
+ }
190
+ else {
191
+ const seen = [];
192
+ for (const e of input.entries) {
193
+ if (!CODE_WINDOW_ENTRIES.includes(e) || seen.includes(e)) {
194
+ return { ok: false, error: "code_window_entries is null (every entry) or a list of link, typed and checkout_code, each once." };
195
+ }
196
+ seen.push(e);
197
+ }
198
+ entries = CODE_WINDOW_ENTRIES.filter((e) => seen.includes(e));
199
+ }
200
+ }
201
+ return { ok: true, value: { until, days, entries } };
202
+ }
203
+ export function firstPaymentWindowApplies(window, entry) {
204
+ if (window.until !== "first_payment")
205
+ return false;
206
+ if (window.entries === null)
207
+ return true;
208
+ return entry !== null && window.entries.includes(entry);
209
+ }
210
+ export const REFERRAL_REFUSALS = [
211
+ "late_code",
212
+ "self_referral",
213
+ "unknown_code",
214
+ "inactive_code",
215
+ "too_many_attempts",
216
+ "paid_before",
217
+ "already_referred",
218
+ ];
219
+ export function isReferralRefusal(value) {
220
+ return typeof value === "string" && REFERRAL_REFUSALS.includes(value);
221
+ }
222
+ export const REFUSAL_SENTENCES_EN = {
223
+ late_code: "Referral codes can only be added soon after you sign up.",
224
+ self_referral: "You can't use your own referral code.",
225
+ unknown_code: "We don't recognise that referral code. Check it and try again.",
226
+ inactive_code: "That referral code is no longer active.",
227
+ too_many_attempts: "Too many codes were tried. Please wait an hour and try again.",
228
+ paid_before: "Referral codes can only be added before your first payment.",
229
+ already_referred: "Your account already has a referral, so another code can't be added.",
230
+ };
231
+ export const CODE_ATTEMPTS_PER_CUSTOMER_HOUR = 10;
232
+ export const CODE_ATTEMPTS_PER_NETWORK_HOUR = 30;
233
+ export const CODE_GUESSING_MIN = 5;
234
+ //# sourceMappingURL=typed-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-code.js","sourceRoot":"","sources":["../src/typed-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,254 @@
1
+ export declare const SHARE_CHANNELS: readonly ["native", "whatsapp", "x", "linkedin", "facebook", "messenger", "telegram", "sms", "email"];
2
+ export type ShareChannel = (typeof SHARE_CHANNELS)[number];
3
+ export declare const SHARE_EVENT_CHANNELS: readonly ["native", "whatsapp", "x", "linkedin", "facebook", "messenger", "telegram", "sms", "email", "copy", "qr"];
4
+ export type ShareEventChannel = (typeof SHARE_EVENT_CHANNELS)[number];
5
+ export declare const EMBED_THEMES: readonly ["light", "dark", "auto"];
6
+ export type EmbedTheme = (typeof EMBED_THEMES)[number];
7
+ export declare const EMBED_LINK_MODES: readonly ["boltclaw", "direct"];
8
+ export type EmbedLinkMode = (typeof EMBED_LINK_MODES)[number];
9
+ export declare const EMBED_MODES: readonly ["panel", "preview"];
10
+ export type EmbedMode = (typeof EMBED_MODES)[number];
11
+ export declare const EMBED_COPY_KEYS: {
12
+ readonly headline: 120;
13
+ readonly subline: 240;
14
+ readonly step_1: 120;
15
+ readonly step_2: 120;
16
+ readonly step_3: 120;
17
+ readonly copy_button: 30;
18
+ readonly copied_label: 30;
19
+ readonly share_button: 30;
20
+ readonly email_button: 30;
21
+ readonly email_title: 60;
22
+ readonly terms_label: 40;
23
+ readonly empty_title: 80;
24
+ readonly empty_body: 240;
25
+ readonly payout_title: 80;
26
+ readonly payout_body: 240;
27
+ readonly rules_title: 60;
28
+ readonly history_title: 60;
29
+ readonly expired_title: 80;
30
+ readonly expired_body: 240;
31
+ };
32
+ export type EmbedCopyKey = keyof typeof EMBED_COPY_KEYS;
33
+ export declare const EMBED_TOKEN_FORMAT: RegExp;
34
+ export declare const EMBED_TTL_MIN_SECONDS = 60;
35
+ export declare const EMBED_TTL_MAX_SECONDS = 86400;
36
+ export declare const EMBED_TTL_DEFAULT_SECONDS = 3600;
37
+ export declare const REASON_CODES: readonly ["awaiting_payment", "on_hold_until", "reward_ready", "reward_paid", "under_review", "refunded", "no_reward", "referrer_not_approved", "reward_expired", "reward_not_eligible"];
38
+ export type ReasonCode = (typeof REASON_CODES)[number];
39
+ export declare const HISTORY_STAGES: readonly ["joined", "paid", "rewarded", "not_counted"];
40
+ export type HistoryStage = (typeof HISTORY_STAGES)[number];
41
+ export declare const PANEL_NOTICE_CODES: readonly ["program_paused", "referrer_not_approved", "test_referrer"];
42
+ export type PanelNoticeCode = (typeof PANEL_NOTICE_CODES)[number];
43
+ export declare const PAYOUT_METHODS_FOR_REFERRERS: readonly ["paypal", "wise"];
44
+ export type ReferrerPayoutMethod = (typeof PAYOUT_METHODS_FOR_REFERRERS)[number];
45
+ export type ReferrerStatus = "approved" | "pending" | "banned";
46
+ export interface PanelHistoryRow {
47
+ id: string;
48
+ label: string;
49
+ stage: HistoryStage;
50
+ reasonCode: ReasonCode;
51
+ reason: string;
52
+ occurredAt: string;
53
+ holdUntil: string | null;
54
+ reward: {
55
+ amountMinor: number;
56
+ currency: string;
57
+ } | null;
58
+ }
59
+ export interface ReferrerPanelView {
60
+ mode: EmbedMode;
61
+ generatedAt: string;
62
+ locale?: string;
63
+ dir?: "ltr" | "rtl";
64
+ register?: "formal" | "informal" | null;
65
+ referrer: {
66
+ externalId: string;
67
+ name: string | null;
68
+ status: ReferrerStatus;
69
+ code: string;
70
+ linkUrl: string;
71
+ };
72
+ program: {
73
+ name: string;
74
+ currency: string;
75
+ status: "active" | "paused";
76
+ };
77
+ notice: {
78
+ code: PanelNoticeCode;
79
+ text: string;
80
+ } | null;
81
+ offer: {
82
+ headline: string;
83
+ subline: string | null;
84
+ rewardText: string | null;
85
+ friendText: string | null;
86
+ steps: [string, string, string];
87
+ rules: Array<{
88
+ kind: "counts" | "doesnt_count" | "timing";
89
+ text: string;
90
+ }>;
91
+ faq: Array<{
92
+ question: string;
93
+ answer: string;
94
+ }>;
95
+ terms: {
96
+ text: string;
97
+ version: number;
98
+ } | null;
99
+ };
100
+ stats: {
101
+ clicks: number;
102
+ friendsJoined: number;
103
+ friendsPaid: number;
104
+ rewards: Array<{
105
+ currency: string;
106
+ waitingMinor: number;
107
+ readyMinor: number;
108
+ paidMinor: number;
109
+ }>;
110
+ };
111
+ history: PanelHistoryRow[];
112
+ payout: {
113
+ needed: boolean;
114
+ set: boolean;
115
+ method: ReferrerPayoutMethod | null;
116
+ methods: ReferrerPayoutMethod[];
117
+ };
118
+ share: {
119
+ mode: EmbedLinkMode;
120
+ channels: ShareChannel[];
121
+ messages: Partial<Record<ShareChannel, string>>;
122
+ emailSubject: string;
123
+ emailBody: string;
124
+ inviteFromOwnSystem: boolean;
125
+ };
126
+ look: {
127
+ accent: string | null;
128
+ radius: number | null;
129
+ theme: EmbedTheme;
130
+ };
131
+ copy: Partial<Record<EmbedCopyKey, string>>;
132
+ grants: PanelGrantRow[];
133
+ ask: {
134
+ shouldAsk: boolean;
135
+ snoozedUntil: string | null;
136
+ };
137
+ thankYou: {
138
+ headline: string;
139
+ afterShare: string;
140
+ };
141
+ }
142
+ export type GrantStatus = "pending" | "ready" | "fulfilled" | "failed" | "cancelled" | "reversed" | "expired" | "not_eligible";
143
+ export interface PanelGrantRow {
144
+ id: string;
145
+ text: string;
146
+ status: GrantStatus;
147
+ statusText: string;
148
+ occurredAt: string;
149
+ claimable?: boolean;
150
+ claimBy?: string | null;
151
+ }
152
+ export declare const OFFER_REASON_CODES: readonly ["unknown_code", "program_paused", "self_referral", "already_referred", "not_new", "already_rewarded", "paid_before", "too_many_attempts"];
153
+ export type OfferReasonCode = (typeof OFFER_REASON_CODES)[number];
154
+ export declare const OFFER_CHECK_SOURCES: readonly ["program", "stripe", "stripe_unavailable", "stripe_not_connected"];
155
+ export type OfferCheckSource = (typeof OFFER_CHECK_SOURCES)[number];
156
+ export declare const OFFER_INTERVALS: readonly ["month", "year", "one_time"];
157
+ export type OfferInterval = (typeof OFFER_INTERVALS)[number];
158
+ export declare const OFFER_DISCOUNT_KINDS: readonly ["percent", "amount", "free_period", "credit", "perk", "gift_card"];
159
+ export type OfferDiscountKind = (typeof OFFER_DISCOUNT_KINDS)[number];
160
+ export declare const WELCOME_STYLES: readonly ["bar", "corner", "sheet"];
161
+ export type WelcomeStyle = (typeof WELCOME_STYLES)[number];
162
+ export declare const WELCOME_POSITIONS: readonly ["top", "bottom"];
163
+ export type WelcomePosition = (typeof WELCOME_POSITIONS)[number];
164
+ export interface Offer {
165
+ register?: "formal" | "informal" | null;
166
+ inviter: string | null;
167
+ headline: string;
168
+ gift: string;
169
+ conditions: string;
170
+ disclosure: string | null;
171
+ discount: {
172
+ kind: OfferDiscountKind;
173
+ value: number | null;
174
+ currency: string | null;
175
+ unit: "day" | "month" | null;
176
+ duration: "once" | "months" | "forever" | null;
177
+ months: number | null;
178
+ text: string | null;
179
+ code: string | null;
180
+ };
181
+ stripe: {
182
+ promotionCode: string;
183
+ } | null;
184
+ cta: {
185
+ label: string;
186
+ url: string;
187
+ } | null;
188
+ look: {
189
+ style: WelcomeStyle;
190
+ position: WelcomePosition;
191
+ accent: string | null;
192
+ radius: number | null;
193
+ theme: EmbedTheme;
194
+ };
195
+ }
196
+ export type CheckoutDiscount = {
197
+ promotion_code: string;
198
+ } | {
199
+ coupon: string;
200
+ };
201
+ export interface MerchantOffer {
202
+ offer: Offer | null;
203
+ eligible: boolean;
204
+ reasonCode: OfferReasonCode | null;
205
+ reason: string | null;
206
+ coupon: string | null;
207
+ couponNote: string | null;
208
+ checked: OfferCheckSource[];
209
+ discounts: CheckoutDiscount[];
210
+ }
211
+ export interface CustomerReferral {
212
+ invitedBy: string | null;
213
+ invitedAt: string | null;
214
+ via: "link" | "discount_code" | null;
215
+ }
216
+ export interface CustomerAcrossPrograms {
217
+ externalId: string;
218
+ programs: CustomerInProgram[];
219
+ }
220
+ export interface CustomerInProgram {
221
+ programId: string;
222
+ programName: string;
223
+ test: boolean;
224
+ firstSeenAt: string | null;
225
+ referredAt: string | null;
226
+ via: "link" | "discount_code" | null;
227
+ invitedBy: {
228
+ kind: "referrer";
229
+ externalId: string;
230
+ test: boolean;
231
+ } | {
232
+ kind: "partner";
233
+ partnerId: string;
234
+ name: string;
235
+ } | {
236
+ kind: "former";
237
+ } | null;
238
+ }
239
+ export interface ReferrerView {
240
+ id: string;
241
+ programId: string;
242
+ externalId: string;
243
+ name: string | null;
244
+ code: string;
245
+ linkUrl: string;
246
+ status: ReferrerStatus;
247
+ erased: boolean;
248
+ createdAt: string;
249
+ clicks: number;
250
+ friends: number;
251
+ friendsPaid: number;
252
+ earnedMinor: number;
253
+ currency: string;
254
+ }
package/dist/types.js ADDED
@@ -0,0 +1,61 @@
1
+ export const SHARE_CHANNELS = ["native", "whatsapp", "x", "linkedin", "facebook", "messenger", "telegram", "sms", "email"];
2
+ export const SHARE_EVENT_CHANNELS = [...SHARE_CHANNELS, "copy", "qr"];
3
+ export const EMBED_THEMES = ["light", "dark", "auto"];
4
+ export const EMBED_LINK_MODES = ["boltclaw", "direct"];
5
+ export const EMBED_MODES = ["panel", "preview"];
6
+ export const EMBED_COPY_KEYS = {
7
+ headline: 120,
8
+ subline: 240,
9
+ step_1: 120,
10
+ step_2: 120,
11
+ step_3: 120,
12
+ copy_button: 30,
13
+ copied_label: 30,
14
+ share_button: 30,
15
+ email_button: 30,
16
+ email_title: 60,
17
+ terms_label: 40,
18
+ empty_title: 80,
19
+ empty_body: 240,
20
+ payout_title: 80,
21
+ payout_body: 240,
22
+ rules_title: 60,
23
+ history_title: 60,
24
+ expired_title: 80,
25
+ expired_body: 240,
26
+ };
27
+ export const EMBED_TOKEN_FORMAT = /^bcet_[A-Za-z0-9_-]{43}$/;
28
+ export const EMBED_TTL_MIN_SECONDS = 60;
29
+ export const EMBED_TTL_MAX_SECONDS = 86_400;
30
+ export const EMBED_TTL_DEFAULT_SECONDS = 3_600;
31
+ export const REASON_CODES = [
32
+ "awaiting_payment",
33
+ "on_hold_until",
34
+ "reward_ready",
35
+ "reward_paid",
36
+ "under_review",
37
+ "refunded",
38
+ "no_reward",
39
+ "referrer_not_approved",
40
+ "reward_expired",
41
+ "reward_not_eligible",
42
+ ];
43
+ export const HISTORY_STAGES = ["joined", "paid", "rewarded", "not_counted"];
44
+ export const PANEL_NOTICE_CODES = ["program_paused", "referrer_not_approved", "test_referrer"];
45
+ export const PAYOUT_METHODS_FOR_REFERRERS = ["paypal", "wise"];
46
+ export const OFFER_REASON_CODES = [
47
+ "unknown_code",
48
+ "program_paused",
49
+ "self_referral",
50
+ "already_referred",
51
+ "not_new",
52
+ "already_rewarded",
53
+ "paid_before",
54
+ "too_many_attempts",
55
+ ];
56
+ export const OFFER_CHECK_SOURCES = ["program", "stripe", "stripe_unavailable", "stripe_not_connected"];
57
+ export const OFFER_INTERVALS = ["month", "year", "one_time"];
58
+ export const OFFER_DISCOUNT_KINDS = ["percent", "amount", "free_period", "credit", "perk", "gift_card"];
59
+ export const WELCOME_STYLES = ["bar", "corner", "sheet"];
60
+ export const WELCOME_POSITIONS = ["top", "bottom"];
61
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AAIpI,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,cAAc,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;AAG/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAG/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAU,CAAC;AAGhE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAC;AAIzD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,GAAG;IACb,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,WAAW,EAAE,EAAE;IACf,YAAY,EAAE,EAAE;IAChB,YAAY,EAAE,EAAE;IAChB,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,EAAE;IACf,UAAU,EAAE,GAAG;IACf,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,GAAG;IAChB,WAAW,EAAE,EAAE;IACf,aAAa,EAAE,EAAE;IACjB,aAAa,EAAE,EAAE;IACjB,YAAY,EAAE,GAAG;CACT,CAAC;AAIX,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAE7D,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAE/C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,kBAAkB;IAClB,eAAe;IACf,cAAc;IACd,aAAa;IACb,cAAc;IACd,UAAU;IACV,WAAW;IACX,uBAAuB;IAEvB,gBAAgB;IAEhB,qBAAqB;CACb,CAAC;AAGX,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAU,CAAC;AAGrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,gBAAgB,EAAE,uBAAuB,EAAE,eAAe,CAAU,CAAC;AAGxG,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAU,CAAC;AA+FxE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,cAAc;IACd,gBAAgB;IAChB,eAAe;IACf,kBAAkB;IAClB,SAAS;IACT,kBAAkB;IAClB,aAAa;IAEb,mBAAmB;CACX,CAAC;AAIX,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE,sBAAsB,CAAU,CAAC;AAIhH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAGtE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAU,CAAC;AAGjH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAU,CAAC;AAGlE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAU,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface WebhookEvent {
2
+ event: string;
3
+ occurred_at: string;
4
+ test?: boolean;
5
+ [key: string]: unknown;
6
+ }
7
+ export type WebhookVerificationFailure = "missing_header" | "stale" | "bad_signature" | "bad_body";
8
+ export declare class WebhookVerificationError extends Error {
9
+ readonly reason: WebhookVerificationFailure;
10
+ constructor(reason: WebhookVerificationFailure);
11
+ }
12
+ export interface VerifyWebhookOptions {
13
+ toleranceSeconds?: number;
14
+ now?: Date | number;
15
+ }
16
+ export type HeaderSource = {
17
+ get(name: string): string | null;
18
+ } | Record<string, string | string[] | undefined>;
19
+ export declare const WEBHOOK_TOLERANCE_SECONDS = 300;
20
+ export declare function verifyWebhook(rawBody: string | Uint8Array | ArrayBuffer, headers: HeaderSource, secret: string, options?: VerifyWebhookOptions): Promise<WebhookEvent>;