spaps-sdk 0.1.0 → 1.0.2
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/.env.example +23 -0
- package/README.md +639 -103
- package/admin-utils.ts +243 -0
- package/dist/index.js +890 -134
- package/dist/index.mjs +880 -121
- package/package.json +34 -40
- package/dist/index.d.mts +0 -82
- package/dist/index.d.ts +0 -82
package/admin-utils.ts
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin utilities for Sweet Potato
|
|
3
|
+
* These are helper functions for admin operations that require JWT authentication
|
|
4
|
+
* NOT included in main SDK for security reasons
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface WhitelistEntry {
|
|
8
|
+
application_id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
tier: 'basic' | 'premium' | 'enterprise';
|
|
11
|
+
bypass_payment: boolean;
|
|
12
|
+
metadata?: Record<string, any>;
|
|
13
|
+
created_at?: string;
|
|
14
|
+
updated_at?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface WhitelistClient {
|
|
18
|
+
apiUrl: string;
|
|
19
|
+
apiKey: string;
|
|
20
|
+
adminToken: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a whitelist management client
|
|
25
|
+
* Requires admin JWT token from authentication
|
|
26
|
+
*/
|
|
27
|
+
export class WhitelistManager {
|
|
28
|
+
private headers: Record<string, string>;
|
|
29
|
+
|
|
30
|
+
constructor(private config: WhitelistClient) {
|
|
31
|
+
this.headers = {
|
|
32
|
+
'Authorization': `Bearer ${config.adminToken}`,
|
|
33
|
+
'X-API-Key': config.apiKey,
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Check if email is whitelisted
|
|
40
|
+
*/
|
|
41
|
+
async check(email: string): Promise<WhitelistEntry | null> {
|
|
42
|
+
const response = await fetch(
|
|
43
|
+
`${this.config.apiUrl}/api/v1/whitelist/check?email=${encodeURIComponent(email)}`,
|
|
44
|
+
{ headers: { 'X-API-Key': this.config.apiKey } }
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const result = await response.json() as any;
|
|
48
|
+
return result.data?.entry || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Add email to whitelist
|
|
53
|
+
*/
|
|
54
|
+
async add(
|
|
55
|
+
email: string,
|
|
56
|
+
tier: 'basic' | 'premium' | 'enterprise' = 'premium',
|
|
57
|
+
options?: {
|
|
58
|
+
bypass_payment?: boolean;
|
|
59
|
+
metadata?: Record<string, any>;
|
|
60
|
+
}
|
|
61
|
+
): Promise<WhitelistEntry> {
|
|
62
|
+
const response = await fetch(`${this.config.apiUrl}/api/v1/whitelist`, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: this.headers,
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
email,
|
|
67
|
+
tier,
|
|
68
|
+
bypass_payment: options?.bypass_payment ?? true,
|
|
69
|
+
metadata: options?.metadata
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const error = await response.json() as any;
|
|
75
|
+
throw new Error(error.error?.message || 'Failed to add to whitelist');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const result = await response.json() as any;
|
|
79
|
+
return result.data.entry;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Bulk add emails to whitelist
|
|
84
|
+
*/
|
|
85
|
+
async bulkAdd(
|
|
86
|
+
emails: Array<{
|
|
87
|
+
email: string;
|
|
88
|
+
tier?: 'basic' | 'premium' | 'enterprise';
|
|
89
|
+
metadata?: Record<string, any>;
|
|
90
|
+
}>
|
|
91
|
+
): Promise<{
|
|
92
|
+
successful: WhitelistEntry[];
|
|
93
|
+
failed: Array<{ email: string; error: string }>;
|
|
94
|
+
total: number;
|
|
95
|
+
}> {
|
|
96
|
+
const response = await fetch(`${this.config.apiUrl}/api/v1/whitelist/bulk`, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: this.headers,
|
|
99
|
+
body: JSON.stringify({ emails })
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const result = await response.json() as any;
|
|
103
|
+
return result.data;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* List whitelisted emails
|
|
108
|
+
*/
|
|
109
|
+
async list(options?: {
|
|
110
|
+
limit?: number;
|
|
111
|
+
offset?: number;
|
|
112
|
+
tier?: string;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
entries: WhitelistEntry[];
|
|
115
|
+
total: number;
|
|
116
|
+
}> {
|
|
117
|
+
const params = new URLSearchParams();
|
|
118
|
+
if (options?.limit) params.append('limit', options.limit.toString());
|
|
119
|
+
if (options?.offset) params.append('offset', options.offset.toString());
|
|
120
|
+
if (options?.tier) params.append('tier', options.tier);
|
|
121
|
+
|
|
122
|
+
const response = await fetch(
|
|
123
|
+
`${this.config.apiUrl}/api/v1/whitelist?${params}`,
|
|
124
|
+
{ headers: this.headers }
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
const result = await response.json() as any;
|
|
128
|
+
return result.data;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Update whitelist entry
|
|
133
|
+
*/
|
|
134
|
+
async update(
|
|
135
|
+
email: string,
|
|
136
|
+
updates: {
|
|
137
|
+
tier?: 'basic' | 'premium' | 'enterprise';
|
|
138
|
+
bypass_payment?: boolean;
|
|
139
|
+
metadata?: Record<string, any>;
|
|
140
|
+
}
|
|
141
|
+
): Promise<WhitelistEntry> {
|
|
142
|
+
const response = await fetch(
|
|
143
|
+
`${this.config.apiUrl}/api/v1/whitelist/${encodeURIComponent(email)}`,
|
|
144
|
+
{
|
|
145
|
+
method: 'PUT',
|
|
146
|
+
headers: this.headers,
|
|
147
|
+
body: JSON.stringify(updates)
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
const error = await response.json() as any;
|
|
153
|
+
throw new Error(error.error?.message || 'Failed to update whitelist');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const result = await response.json() as any;
|
|
157
|
+
return result.data.entry;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Remove email from whitelist
|
|
162
|
+
*/
|
|
163
|
+
async remove(email: string): Promise<void> {
|
|
164
|
+
const response = await fetch(
|
|
165
|
+
`${this.config.apiUrl}/api/v1/whitelist/${encodeURIComponent(email)}`,
|
|
166
|
+
{
|
|
167
|
+
method: 'DELETE',
|
|
168
|
+
headers: this.headers
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
if (!response.ok) {
|
|
173
|
+
const error = await response.json() as any;
|
|
174
|
+
throw new Error(error.error?.message || 'Failed to remove from whitelist');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Get whitelist statistics
|
|
180
|
+
*/
|
|
181
|
+
async getStats(): Promise<{
|
|
182
|
+
enabled: boolean;
|
|
183
|
+
total: number;
|
|
184
|
+
tierBreakdown: Array<{ tier: string; count: number }>;
|
|
185
|
+
}> {
|
|
186
|
+
const response = await fetch(
|
|
187
|
+
`${this.config.apiUrl}/api/v1/whitelist/stats`,
|
|
188
|
+
{ headers: this.headers }
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const result = await response.json() as any;
|
|
192
|
+
return result.data.stats;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Clear all whitelist entries (use with caution!)
|
|
197
|
+
*/
|
|
198
|
+
async clearAll(): Promise<number> {
|
|
199
|
+
const response = await fetch(
|
|
200
|
+
`${this.config.apiUrl}/api/v1/whitelist/all`,
|
|
201
|
+
{
|
|
202
|
+
method: 'DELETE',
|
|
203
|
+
headers: this.headers
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (!response.ok) {
|
|
208
|
+
const error = await response.json() as any;
|
|
209
|
+
throw new Error(error.error?.message || 'Failed to clear whitelist');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const result = await response.json() as any;
|
|
213
|
+
const match = result.data.message.match(/Cleared (\d+) entries/);
|
|
214
|
+
return match ? parseInt(match[1]) : 0;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Example usage:
|
|
220
|
+
*
|
|
221
|
+
* ```typescript
|
|
222
|
+
* import { SweetPotatoSDK } from '@sweet-potato/sdk';
|
|
223
|
+
* import { WhitelistManager } from '@sweet-potato/sdk/admin-utils';
|
|
224
|
+
*
|
|
225
|
+
* // First authenticate as admin
|
|
226
|
+
* const sdk = new SweetPotatoSDK({ apiUrl, apiKey });
|
|
227
|
+
* const auth = await sdk.auth.signInWithPassword({
|
|
228
|
+
* email: 'admin@example.com',
|
|
229
|
+
* password: 'admin_password'
|
|
230
|
+
* });
|
|
231
|
+
*
|
|
232
|
+
* // Create whitelist manager
|
|
233
|
+
* const whitelist = new WhitelistManager({
|
|
234
|
+
* apiUrl,
|
|
235
|
+
* apiKey,
|
|
236
|
+
* adminToken: auth.access_token
|
|
237
|
+
* });
|
|
238
|
+
*
|
|
239
|
+
* // Use whitelist operations
|
|
240
|
+
* await whitelist.add('vip@example.com', 'premium');
|
|
241
|
+
* const stats = await whitelist.getStats();
|
|
242
|
+
* ```
|
|
243
|
+
*/
|