spaps-sdk 1.0.2 → 1.1.1
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/README.md +213 -602
- package/dist/index.d.mts +302 -0
- package/dist/index.d.ts +302 -0
- package/dist/index.js +382 -854
- package/dist/index.mjs +379 -840
- package/package.json +52 -33
- package/.env.example +0 -23
- package/admin-utils.ts +0 -243
package/package.json
CHANGED
|
@@ -1,56 +1,75 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spaps-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"
|
|
5
|
-
"type": "git",
|
|
6
|
-
"url": "https://github.com/sweet-potato/spaps-sdk"
|
|
7
|
-
},
|
|
8
|
-
"homepage": "https://github.com/sweet-potato/spaps-sdk#readme",
|
|
9
|
-
"bugs": {
|
|
10
|
-
"url": "https://github.com/sweet-potato/spaps-sdk/issues"
|
|
11
|
-
},
|
|
12
|
-
"description": "Sweet Potato Authentication & Payment Service SDK",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "Sweet Potato Authentication & Payment Service SDK - Zero-config client with built-in permission checking and role-based access control",
|
|
13
5
|
"main": "dist/index.js",
|
|
14
|
-
"module": "dist/index.mjs",
|
|
15
6
|
"types": "dist/index.d.ts",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./client": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"require": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
22
19
|
"scripts": {
|
|
23
|
-
"build": "tsup index.ts --format cjs,esm --clean",
|
|
24
|
-
"dev": "tsup index.ts --format cjs,esm --dts --watch",
|
|
25
|
-
"
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
21
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
+
"test": "echo \"No tests yet\"",
|
|
23
|
+
"smoke-test": "npm run build && node smoke-test.js",
|
|
24
|
+
"prepublishOnly": "npm run build && npm run smoke-test"
|
|
26
25
|
},
|
|
27
26
|
"keywords": [
|
|
28
27
|
"authentication",
|
|
29
28
|
"payments",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
29
|
+
"stripe",
|
|
30
|
+
"spaps",
|
|
31
|
+
"sdk",
|
|
32
|
+
"client",
|
|
33
|
+
"sweet-potato",
|
|
34
|
+
"wallet-auth"
|
|
34
35
|
],
|
|
35
|
-
"author": "
|
|
36
|
+
"author": "buildooor",
|
|
36
37
|
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/buildooor/sweet-potato",
|
|
41
|
+
"directory": "packages/sdk"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/buildooor/sweet-potato/tree/main/packages/sdk",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/buildooor/sweet-potato/issues"
|
|
46
|
+
},
|
|
37
47
|
"dependencies": {
|
|
38
|
-
"axios": "^1.
|
|
48
|
+
"axios": "^1.6.0",
|
|
49
|
+
"cross-fetch": "^4.0.0"
|
|
39
50
|
},
|
|
40
51
|
"devDependencies": {
|
|
41
|
-
"
|
|
52
|
+
"@types/node": "^20.10.0",
|
|
53
|
+
"tsup": "^8.0.1",
|
|
42
54
|
"typescript": "^5.3.2"
|
|
43
55
|
},
|
|
44
56
|
"peerDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"ethers": "^6.9.0"
|
|
57
|
+
"typescript": ">=4.5.0"
|
|
47
58
|
},
|
|
48
59
|
"peerDependenciesMeta": {
|
|
49
|
-
"
|
|
50
|
-
"optional": true
|
|
51
|
-
},
|
|
52
|
-
"ethers": {
|
|
60
|
+
"typescript": {
|
|
53
61
|
"optional": true
|
|
54
62
|
}
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"dist",
|
|
66
|
+
"README.md"
|
|
67
|
+
],
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public",
|
|
70
|
+
"registry": "https://registry.npmjs.org/"
|
|
71
|
+
},
|
|
72
|
+
"engines": {
|
|
73
|
+
"node": ">=14.0.0"
|
|
55
74
|
}
|
|
56
75
|
}
|
package/.env.example
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Sweet Potato SDK Environment Variables
|
|
2
|
-
|
|
3
|
-
# API Configuration (REQUIRED)
|
|
4
|
-
# For development, use localhost
|
|
5
|
-
SPAPS_API_URL=http://localhost:3456
|
|
6
|
-
# For production (when available)
|
|
7
|
-
# SPAPS_API_URL=https://api.sweetpotato.dev
|
|
8
|
-
|
|
9
|
-
# Your API Key (REQUIRED)
|
|
10
|
-
# Get from https://dashboard.sweetpotato.dev (production)
|
|
11
|
-
# Or use 'test_key_local_dev_only' for local development
|
|
12
|
-
SPAPS_API_KEY=test_key_local_dev_only
|
|
13
|
-
|
|
14
|
-
# Optional: Stripe Keys (for server-side operations only)
|
|
15
|
-
# STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
|
|
16
|
-
# STRIPE_SECRET_KEY=sk_test_xxxxx
|
|
17
|
-
|
|
18
|
-
# Optional: Webhook Secret (for receiving webhooks)
|
|
19
|
-
# WEBHOOK_SECRET=whsec_xxxxx
|
|
20
|
-
|
|
21
|
-
# Optional: Admin Credentials (NEVER expose to clients)
|
|
22
|
-
# ADMIN_EMAIL=admin@example.com
|
|
23
|
-
# ADMIN_PASSWORD=secure_password_here
|
package/admin-utils.ts
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
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
|
-
*/
|