spaps-sdk 1.6.1 → 1.6.3
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/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/PERMISSIONS.md +390 -0
- package/README.md +133 -349
- package/dist/index.d.mts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +73 -0
- package/dist/index.mjs +73 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -1,444 +1,228 @@
|
|
|
1
|
-
|
|
2
|
-
id: spaps-typescript-sdk
|
|
3
|
-
title: spaps TypeScript SDK
|
|
4
|
-
category: sdk
|
|
5
|
-
tags:
|
|
6
|
-
- sdk
|
|
7
|
-
- typescript
|
|
8
|
-
- client
|
|
9
|
-
ai_summary: |
|
|
10
|
-
Reference for the spaps TypeScript SDK covering configuration, admin helpers,
|
|
11
|
-
and examples for interacting with authentication, payments, and permission
|
|
12
|
-
APIs from JavaScript or TypeScript applications.
|
|
13
|
-
last_updated: 2025-02-14
|
|
14
|
-
---
|
|
1
|
+
# spaps-sdk
|
|
15
2
|
|
|
16
|
-
|
|
3
|
+
TypeScript SDK for the Sweet Potato Authentication & Payment Service.
|
|
17
4
|
|
|
18
|
-
|
|
19
|
-
<img alt="node" src="https://img.shields.io/badge/node-%3E%3D14-brightgreen">
|
|
20
|
-
<img alt="types" src="https://img.shields.io/badge/types-TypeScript-blue">
|
|
5
|
+
## TL;DR
|
|
21
6
|
|
|
22
|
-
|
|
7
|
+
**The Problem**: SPAPS consumers need one client that can speak auth, payments, secure messaging, issue reporting, entitlements, and dayrate APIs without rebuilding request plumbing for every app.
|
|
23
8
|
|
|
24
|
-
|
|
9
|
+
**The Solution**: `spaps-sdk` exposes a typed `SPAPSClient` with source-backed namespaces for the major SPAPS surfaces and a small set of permission helpers for app code.
|
|
25
10
|
|
|
26
|
-
|
|
11
|
+
### Why Use `spaps-sdk`?
|
|
27
12
|
|
|
28
|
-
|
|
13
|
+
| Feature | What It Does |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Zero-config local mode | Point at `localhost` and the SDK automatically treats it as local mode |
|
|
16
|
+
| Typed namespaces | Use `auth`, `payments`, `sessions`, `secureMessages`, `issueReporting`, `email`, `entitlements`, `dayrate`, `cfo`, and `admin` from one client |
|
|
17
|
+
| Browser and server key support | Configure with `publishableKey`, `secretKey`, or the legacy `apiKey` field |
|
|
18
|
+
| Shared contracts | Re-exports many `spaps-types` definitions so apps can stay on one dependency surface |
|
|
29
19
|
|
|
30
|
-
|
|
31
|
-
import { SPAPSClient } from 'spaps-sdk';
|
|
20
|
+
## Metadata
|
|
32
21
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// Authenticate as admin
|
|
39
|
-
await spaps.signIn('admin@example.com', 'password');
|
|
40
|
-
|
|
41
|
-
// Admin API methods
|
|
42
|
-
await spaps.admin.createProduct({
|
|
43
|
-
name: 'Premium Plan',
|
|
44
|
-
category: 'subscription',
|
|
45
|
-
description: 'Advanced features'
|
|
46
|
-
});
|
|
22
|
+
- `package_name`: `spaps-sdk`
|
|
23
|
+
- `latest_version`: `1.6.2`
|
|
24
|
+
- `minimum_runtime`: `Node.js >=14.0.0`
|
|
25
|
+
- `api_base_url`: `https://api.sweetpotato.dev`
|
|
47
26
|
|
|
48
|
-
|
|
49
|
-
name: 'Premium Plan Pro'
|
|
50
|
-
});
|
|
27
|
+
## Installation
|
|
51
28
|
|
|
52
|
-
|
|
53
|
-
product_id: 'prod_123',
|
|
54
|
-
unit_amount: 2999,
|
|
55
|
-
currency: 'usd',
|
|
56
|
-
interval: 'month'
|
|
57
|
-
});
|
|
29
|
+
### npm
|
|
58
30
|
|
|
59
|
-
|
|
60
|
-
|
|
31
|
+
```bash
|
|
32
|
+
npm install spaps-sdk
|
|
61
33
|
```
|
|
62
34
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Built-in permission checking and role-based access control:
|
|
35
|
+
### pnpm
|
|
66
36
|
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Check admin status
|
|
71
|
-
const isAdmin = isAdminAccount('buildooor@gmail.com'); // true
|
|
72
|
-
|
|
73
|
-
// Check admin access with detailed result
|
|
74
|
-
const adminCheck = canAccessAdmin(user);
|
|
75
|
-
if (adminCheck.allowed) {
|
|
76
|
-
// Show admin UI
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Get user role
|
|
80
|
-
const role = getUserRole('user@example.com'); // 'user' | 'admin' | 'guest'
|
|
81
|
-
|
|
82
|
-
// Check if authenticated user is admin
|
|
83
|
-
if (spaps.isAdmin(currentUser)) {
|
|
84
|
-
// Show admin features
|
|
85
|
-
}
|
|
37
|
+
```bash
|
|
38
|
+
pnpm add spaps-sdk
|
|
86
39
|
```
|
|
87
40
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
## Installation
|
|
41
|
+
### yarn
|
|
91
42
|
|
|
92
43
|
```bash
|
|
93
|
-
npm install spaps-sdk
|
|
94
|
-
# or
|
|
95
44
|
yarn add spaps-sdk
|
|
96
|
-
# or
|
|
97
|
-
pnpm add spaps-sdk
|
|
98
45
|
```
|
|
99
46
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- ✅ **Node.js**: Fully supported (v14+) with automatic fetch polyfill
|
|
103
|
-
- ✅ **Browser**: Works in all modern browsers
|
|
104
|
-
- ✅ **TypeScript**: Full type definitions included
|
|
105
|
-
- ✅ **Next.js**: Server and client components supported
|
|
106
|
-
- ✅ **React Native**: Compatible with proper setup
|
|
107
|
-
|
|
108
|
-
The SDK automatically includes a `cross-fetch` polyfill for Node.js environments that don't have native fetch support.
|
|
109
|
-
|
|
110
|
-
## Quick Start
|
|
47
|
+
## Quick Example
|
|
111
48
|
|
|
112
|
-
```
|
|
49
|
+
```typescript
|
|
113
50
|
import { SPAPSClient } from 'spaps-sdk';
|
|
114
|
-
// or
|
|
115
|
-
const { SPAPSClient } = require('spaps-sdk');
|
|
116
51
|
|
|
117
|
-
// Auto-detects local mode - no API key needed for localhost!
|
|
118
52
|
const spaps = new SPAPSClient({
|
|
119
|
-
apiUrl: 'http://localhost:3301'
|
|
53
|
+
apiUrl: 'http://localhost:3301',
|
|
120
54
|
});
|
|
121
55
|
|
|
122
|
-
// Login
|
|
123
56
|
const { data } = await spaps.login('user@example.com', 'password');
|
|
124
57
|
console.log('User:', data.user);
|
|
125
58
|
|
|
126
|
-
// Check authentication
|
|
127
59
|
if (spaps.isAuthenticated()) {
|
|
128
|
-
const
|
|
129
|
-
console.log(
|
|
60
|
+
const me = await spaps.getUser();
|
|
61
|
+
console.log(me.data.email);
|
|
130
62
|
}
|
|
131
63
|
```
|
|
132
64
|
|
|
133
|
-
##
|
|
134
|
-
|
|
135
|
-
- If `apiUrl` is omitted or points to `localhost`/`127.0.0.1`, the SDK runs in local mode.
|
|
136
|
-
- Local mode integrates seamlessly with the `spaps` CLI (`npx spaps local`), defaulting to `http://localhost:3301`.
|
|
137
|
-
- No API key is required in local mode; tokens and data are managed locally for development.
|
|
138
|
-
|
|
139
|
-
You can check the mode at runtime:
|
|
140
|
-
|
|
141
|
-
```ts
|
|
142
|
-
spaps.isLocalMode(); // true | false
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Environment Variables
|
|
146
|
-
|
|
147
|
-
The SDK can read configuration from environment variables (useful in Next.js and Node):
|
|
148
|
-
|
|
149
|
-
- `SPAPS_API_URL` or `NEXT_PUBLIC_SPAPS_API_URL` — API base URL
|
|
150
|
-
- `SPAPS_API_KEY` — API key for production use
|
|
151
|
-
|
|
152
|
-
Example (Node):
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
export SPAPS_API_URL=https://api.sweetpotato.dev
|
|
156
|
-
export SPAPS_API_KEY=spaps_xxx
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Example (Next.js):
|
|
160
|
-
|
|
161
|
-
```env
|
|
162
|
-
NEXT_PUBLIC_SPAPS_API_URL=https://api.sweetpotato.dev
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Features
|
|
65
|
+
## Configuration
|
|
166
66
|
|
|
167
|
-
|
|
168
|
-
- **Auto-detects local mode** - No API key needed for localhost
|
|
169
|
-
- **Auto-refreshes tokens** - Handles expired tokens automatically
|
|
170
|
-
- **TypeScript support** - Full type definitions included
|
|
171
|
-
- **Crypto payments ready** - Create invoices, poll status, verify webhooks, trigger reconciliation
|
|
67
|
+
Constructor values win over environment variables.
|
|
172
68
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
69
|
+
| Option | Purpose |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `apiUrl` | Base API URL. Localhost enables local mode automatically. |
|
|
72
|
+
| `publishableKey` | Browser-safe key for client-side usage |
|
|
73
|
+
| `secretKey` | Server-side key for full access |
|
|
74
|
+
| `apiKey` | Deprecated legacy key field |
|
|
75
|
+
| `timeout` | Override request timeout |
|
|
178
76
|
|
|
179
|
-
|
|
180
|
-
await spaps.walletSignIn(walletAddress, signature, message, 'solana');
|
|
77
|
+
Relevant environment variables:
|
|
181
78
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
79
|
+
- `SPAPS_API_URL`
|
|
80
|
+
- `NEXT_PUBLIC_SPAPS_API_URL`
|
|
81
|
+
- `SPAPS_API_KEY`
|
|
82
|
+
- `NEXT_PUBLIC_SPAPS_API_KEY`
|
|
185
83
|
|
|
186
|
-
|
|
187
|
-
const user = await spaps.getUser();
|
|
188
|
-
```
|
|
84
|
+
## Client Surface
|
|
189
85
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
86
|
+
| Namespace | What It Covers |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `auth` | Password, wallet, magic-link, refresh, and logout flows |
|
|
89
|
+
| `payments` | Checkout sessions, products, prices, subscriptions, and crypto payment helpers |
|
|
90
|
+
| `sessions` | Current session lookup, validation, revocation, and session lifecycle helpers |
|
|
91
|
+
| `secureMessages` | Create and list secure messages |
|
|
92
|
+
| `issueReporting` | Status, history, create, edit, and reply issue-report flows |
|
|
93
|
+
| `email` | Template lookup, previews, and sends |
|
|
94
|
+
| `entitlements` | User and resource entitlement queries |
|
|
95
|
+
| `dayrate` | Availability and booking helpers |
|
|
96
|
+
| `admin` | Product and pricing admin helpers |
|
|
97
|
+
| `cfo` | CFO-specific endpoints |
|
|
201
98
|
|
|
202
|
-
|
|
203
|
-
const subscription = await spaps.getSubscription();
|
|
204
|
-
await spaps.cancelSubscription();
|
|
205
|
-
```
|
|
206
|
-
> `require_legal_consent` forces Stripe’s Terms/Privacy checkbox, and `legal_consent_text` (≤120 chars) customizes the copy. Text is sanitized and defaults to “I agree to the Terms of Service and Privacy Policy.” when omitted.
|
|
99
|
+
## Common Flows
|
|
207
100
|
|
|
208
|
-
###
|
|
209
|
-
```javascript
|
|
210
|
-
// Check balance
|
|
211
|
-
const balance = await spaps.getUsageBalance();
|
|
212
|
-
console.log(`Credits: ${balance.data.balance}`);
|
|
213
|
-
|
|
214
|
-
// Record usage
|
|
215
|
-
await spaps.recordUsage('api-call', 1);
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### ✉️ Secure Messaging
|
|
219
|
-
```javascript
|
|
220
|
-
// Create a secure message (content encrypted server-side when pii_enabled)
|
|
221
|
-
const message = await spaps.secureMessages.create({
|
|
222
|
-
patientId: '3d6f0a51-8d77-4b38-8248-2d1b2f1f6c7f',
|
|
223
|
-
practitionerId: 'a3d7f431-6c9d-4cbc-9f78-4e5b6a7c8d9e',
|
|
224
|
-
content: 'Patient is experiencing intermittent headaches.',
|
|
225
|
-
metadata: { urgency: 'high' }
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
// List secure messages for the current application
|
|
229
|
-
const messages = await spaps.secureMessages.list();
|
|
230
|
-
console.log(messages[0].content);
|
|
231
|
-
```
|
|
232
|
-
> Ensure your application has `settings.pii_enabled = true` so payloads are encrypted automatically.
|
|
101
|
+
### Typed Secure Messaging
|
|
233
102
|
|
|
234
103
|
```typescript
|
|
235
|
-
// Provide a strongly typed metadata shape for downstream usage
|
|
236
104
|
type SecureMessageMetadata = { urgency: 'low' | 'high'; tags?: string[] };
|
|
237
105
|
|
|
238
|
-
const spaps = new SPAPSClient<SecureMessageMetadata>({
|
|
106
|
+
const spaps = new SPAPSClient<SecureMessageMetadata>({
|
|
107
|
+
apiUrl: 'https://api.sweetpotato.dev',
|
|
108
|
+
secretKey: process.env.SPAPS_API_KEY,
|
|
109
|
+
});
|
|
239
110
|
|
|
240
111
|
await spaps.secureMessages.create({
|
|
241
112
|
patientId: '3d6f0a51-8d77-4b38-8248-2d1b2f1f6c7f',
|
|
242
113
|
practitionerId: 'a3d7f431-6c9d-4cbc-9f78-4e5b6a7c8d9e',
|
|
243
114
|
content: 'Follow up scheduled for next week.',
|
|
244
|
-
metadata: { urgency: 'low', tags: ['follow-up'] }
|
|
115
|
+
metadata: { urgency: 'low', tags: ['follow-up'] },
|
|
245
116
|
});
|
|
246
|
-
|
|
247
|
-
const typedMessages = await spaps.secureMessages.list();
|
|
248
|
-
typedMessages[0].metadata.urgency; // "low" | "high"
|
|
249
117
|
```
|
|
250
118
|
|
|
251
|
-
|
|
119
|
+
### Shared Issue Reporting
|
|
252
120
|
|
|
253
121
|
```typescript
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
122
|
+
spaps.setAccessToken('jwt-token');
|
|
123
|
+
|
|
124
|
+
const summary = await spaps.issueReporting.getStatus();
|
|
125
|
+
const history = await spaps.issueReporting.list({ status: 'open' });
|
|
126
|
+
|
|
127
|
+
if (!summary.has_open && history.total === 0) {
|
|
128
|
+
await spaps.issueReporting.create({
|
|
129
|
+
target: {
|
|
130
|
+
component_key: 'patient_protocol_widget',
|
|
131
|
+
component_label: 'Patient Protocol Widget',
|
|
132
|
+
page_url: '/patients/123/protocol',
|
|
133
|
+
metadata: { section: 'daily log' },
|
|
134
|
+
},
|
|
135
|
+
note: 'The save action silently fails after I edit today.',
|
|
136
|
+
reporter_role_hint: 'practitioner',
|
|
137
|
+
});
|
|
138
|
+
}
|
|
267
139
|
```
|
|
268
140
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
### Production Mode
|
|
272
|
-
```javascript
|
|
273
|
-
const spaps = new SPAPSClient({
|
|
274
|
-
apiUrl: 'https://api.sweetpotato.dev',
|
|
275
|
-
apiKey: 'spaps_your_api_key_here',
|
|
276
|
-
timeout: 10000 // Optional timeout in ms
|
|
277
|
-
});
|
|
278
|
-
```
|
|
141
|
+
### Permission Utilities
|
|
279
142
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const spaps = new SPAPSClient();
|
|
283
|
-
// Automatically uses http://localhost:3301 with no API key
|
|
284
|
-
```
|
|
143
|
+
```typescript
|
|
144
|
+
import { canAccessAdmin, getUserRole, isAdminAccount } from 'spaps-sdk';
|
|
285
145
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
SPAPS_API_URL=https://api.sweetpotato.dev
|
|
290
|
-
SPAPS_API_KEY=spaps_your_api_key_here
|
|
146
|
+
const role = getUserRole('user@example.com');
|
|
147
|
+
const adminCheck = canAccessAdmin({ id: 'user_123', email: 'buildooor@gmail.com' });
|
|
148
|
+
const isAdmin = isAdminAccount('buildooor@gmail.com');
|
|
291
149
|
|
|
292
|
-
|
|
293
|
-
NEXT_PUBLIC_SPAPS_API_URL=https://api.sweetpotato.dev
|
|
150
|
+
console.log(role, adminCheck.allowed, isAdmin);
|
|
294
151
|
```
|
|
295
152
|
|
|
296
|
-
|
|
153
|
+
### Helper Methods
|
|
297
154
|
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
spaps.isAuthenticated() // boolean
|
|
301
|
-
|
|
302
|
-
// Get current access token
|
|
303
|
-
spaps.getAccessToken() // string | undefined
|
|
155
|
+
```typescript
|
|
156
|
+
const spaps = new SPAPSClient({ apiUrl: 'http://localhost:3301' });
|
|
304
157
|
|
|
305
|
-
|
|
306
|
-
spaps.
|
|
158
|
+
spaps.isLocalMode();
|
|
159
|
+
spaps.isAuthenticated();
|
|
160
|
+
spaps.getAccessToken();
|
|
161
|
+
spaps.setAccessToken('token');
|
|
162
|
+
await spaps.health();
|
|
163
|
+
```
|
|
307
164
|
|
|
308
|
-
|
|
309
|
-
spaps.isLocalMode() // boolean
|
|
165
|
+
## Development
|
|
310
166
|
|
|
311
|
-
|
|
312
|
-
|
|
167
|
+
```bash
|
|
168
|
+
cd packages/sdk
|
|
169
|
+
npm ci
|
|
170
|
+
npm run build
|
|
171
|
+
npm run typecheck:readme
|
|
172
|
+
npm run test:readme
|
|
173
|
+
npm run test
|
|
313
174
|
```
|
|
314
175
|
|
|
315
|
-
##
|
|
176
|
+
## Troubleshooting
|
|
316
177
|
|
|
317
|
-
|
|
178
|
+
### `401 Unauthorized`
|
|
318
179
|
|
|
319
|
-
|
|
320
|
-
import { SPAPSClient, type User, type Session, type Role } from 'spaps-sdk';
|
|
321
|
-
```
|
|
180
|
+
Check the access token and key configuration for the environment you are targeting.
|
|
322
181
|
|
|
323
|
-
|
|
182
|
+
### Local mode is not activating
|
|
324
183
|
|
|
325
|
-
|
|
326
|
-
import type {
|
|
327
|
-
User,
|
|
328
|
-
Session,
|
|
329
|
-
Role,
|
|
330
|
-
Permission,
|
|
331
|
-
TokenPayload,
|
|
332
|
-
} from 'spaps-types';
|
|
333
|
-
```
|
|
184
|
+
Use a localhost URL such as `http://localhost:3301`, or call `spaps.isLocalMode()` to confirm how the SDK resolved the environment.
|
|
334
185
|
|
|
335
|
-
|
|
336
|
-
- `spaps-sdk` re-exports commonly used types for convenience.
|
|
337
|
-
- `spaps-types` is useful when building framework integrations, server middleware, or utilities that need to share types without depending on the SDK runtime.
|
|
186
|
+
### Browser app needs limited access
|
|
338
187
|
|
|
339
|
-
|
|
188
|
+
Use `publishableKey` instead of a server-side secret key.
|
|
340
189
|
|
|
341
|
-
|
|
342
|
-
```javascript
|
|
343
|
-
// ES6 Import
|
|
344
|
-
import { SPAPSClient } from 'spaps-sdk';
|
|
345
|
-
import SPAPSClient from 'spaps-sdk';
|
|
190
|
+
## Limitations
|
|
346
191
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
192
|
+
- The SDK wraps the current SPAPS surface; it is not an exhaustive code-generated client for every backend route.
|
|
193
|
+
- Some admin and entitlement flows still depend on upstream permissions and token context.
|
|
194
|
+
- The legacy `apiKey` constructor field still exists for compatibility, but new integrations should prefer the explicit key fields.
|
|
350
195
|
|
|
351
|
-
|
|
352
|
-
import { SPAPS } from 'spaps-sdk';
|
|
353
|
-
import { SweetPotatoSDK } from 'spaps-sdk';
|
|
354
|
-
```
|
|
196
|
+
## FAQ
|
|
355
197
|
|
|
356
|
-
|
|
198
|
+
### Does this work in browsers?
|
|
357
199
|
|
|
358
|
-
The
|
|
200
|
+
Yes. The package is designed for both browser and server-side usage.
|
|
359
201
|
|
|
360
|
-
###
|
|
202
|
+
### Does it include fetch polyfills?
|
|
361
203
|
|
|
362
|
-
|
|
363
|
-
// Create product (Admin required)
|
|
364
|
-
const product = await spaps.admin.createProduct({
|
|
365
|
-
name: 'Premium Plan',
|
|
366
|
-
category: 'subscription',
|
|
367
|
-
description: 'Advanced features for power users',
|
|
368
|
-
images: ['https://example.com/product-image.jpg'],
|
|
369
|
-
metadata: { feature_set: 'premium' },
|
|
370
|
-
active: true
|
|
371
|
-
});
|
|
204
|
+
Yes. It loads `cross-fetch/polyfill` when `fetch` is unavailable.
|
|
372
205
|
|
|
373
|
-
|
|
374
|
-
const updatedProduct = await spaps.admin.updateProduct('prod_123', {
|
|
375
|
-
name: 'Premium Plan Pro',
|
|
376
|
-
description: 'Updated features'
|
|
377
|
-
});
|
|
206
|
+
### Can I use it without TypeScript?
|
|
378
207
|
|
|
379
|
-
|
|
380
|
-
await spaps.admin.deleteProduct('prod_123');
|
|
208
|
+
Yes. The runtime works in JavaScript projects and ships bundled type declarations for TS users.
|
|
381
209
|
|
|
382
|
-
|
|
383
|
-
const { data } = await spaps.admin.getProducts();
|
|
384
|
-
if (data.adminMetadata) {
|
|
385
|
-
console.log('Total revenue:', data.adminMetadata.total_revenue);
|
|
386
|
-
}
|
|
387
|
-
```
|
|
210
|
+
### Does it re-export shared types?
|
|
388
211
|
|
|
389
|
-
|
|
212
|
+
Yes. Many `spaps-types` exports are re-exported for convenience.
|
|
390
213
|
|
|
391
|
-
|
|
392
|
-
// Create price (Admin required)
|
|
393
|
-
const price = await spaps.admin.createPrice({
|
|
394
|
-
product_id: 'prod_123',
|
|
395
|
-
unit_amount: 2999, // $29.99
|
|
396
|
-
currency: 'usd',
|
|
397
|
-
interval: 'month',
|
|
398
|
-
interval_count: 1,
|
|
399
|
-
nickname: 'Monthly Premium'
|
|
400
|
-
});
|
|
401
|
-
```
|
|
214
|
+
### How do I validate README-related examples?
|
|
402
215
|
|
|
403
|
-
|
|
216
|
+
Run:
|
|
404
217
|
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
console.log(`Synced ${syncResult.data.synced_count} products`);
|
|
218
|
+
```bash
|
|
219
|
+
npm run typecheck:readme
|
|
220
|
+
npm run test:readme
|
|
409
221
|
```
|
|
410
222
|
|
|
411
|
-
|
|
223
|
+
## About Contributions
|
|
412
224
|
|
|
413
|
-
|
|
414
|
-
// Check if current user can access admin features
|
|
415
|
-
const user = await spaps.getCurrentUser();
|
|
416
|
-
if (spaps.isAdmin(user)) {
|
|
417
|
-
// Show admin UI components
|
|
418
|
-
console.log('User has admin privileges');
|
|
419
|
-
} else {
|
|
420
|
-
// Show regular user UI
|
|
421
|
-
console.log('Regular user');
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
## Error Handling
|
|
426
|
-
|
|
427
|
-
```javascript
|
|
428
|
-
try {
|
|
429
|
-
await spaps.admin.createProduct(productData);
|
|
430
|
-
} catch (error) {
|
|
431
|
-
if (error.response?.status === 401) {
|
|
432
|
-
console.error('Authentication required');
|
|
433
|
-
} else if (error.response?.status === 403) {
|
|
434
|
-
console.error('Admin privileges required');
|
|
435
|
-
} else if (error.response?.status === 429) {
|
|
436
|
-
console.error('Rate limited');
|
|
437
|
-
} else {
|
|
438
|
-
console.error('Error:', error.message);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
```
|
|
225
|
+
*About Contributions:* Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via `gh` and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.
|
|
442
226
|
|
|
443
227
|
## License
|
|
444
228
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as spaps_types from 'spaps-types';
|
|
2
|
-
import { ResourceType, Entitlement, CreateProductRequest, Product, UpdateProductRequest, CreatePriceRequest, Price, ProductSyncResult, CryptoReconcileRequest, CreateSecureMessageRequest, SecureMessage, AuthResponse, User as User$1, CreateCryptoInvoiceRequest, CryptoInvoiceStatusSnapshot, CheckoutSession, DayrateAvailabilityResponse, DayrateBookingRequest, DayrateBookingResponse, DayrateMultiBookingRequest, DayrateMultiBookingResponse, Subscription, UsageBalance, VerifyCryptoWebhookSignatureOptions } from 'spaps-types';
|
|
3
|
-
export { AdminPermission, AdminRole, AdminUser, ApiResponse, AuthResponse, CheckoutSession, CreateCryptoInvoiceRequest, CreatePriceRequest, CreateProductRequest, CreateSecureMessageInput, CreateSecureMessageRequest, CryptoInvoice, CryptoInvoiceResponse, CryptoInvoiceStatusSnapshot, CryptoReconcileRequest, DayrateAvailabilityResponse, DayrateAvailableSlot, DayrateBookingRequest, DayrateBookingResponse, DayrateDayOfWeek, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayratePriceBreakdown, DayrateSlotType, Entitlement, Price, Product, ProductSyncResult, ResourceType, SecureMessage, SecureMessageOutput, Subscription, TokenPair, UpdateProductRequest, UsageBalance, User, UserProfile, UserRole, UserWallet, VerifyCryptoWebhookSignatureOptions, createSecureMessageRequestSchema, secureMessageMetadataSchema, secureMessageSchema } from 'spaps-types';
|
|
2
|
+
import { ResourceType, Entitlement, CreateProductRequest, Product, UpdateProductRequest, CreatePriceRequest, Price, ProductSyncResult, CryptoReconcileRequest, CreateSecureMessageRequest, SecureMessage, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, UpdateIssueReportRequest, ReplyIssueReportRequest, AuthResponse, User as User$1, CreateCryptoInvoiceRequest, CryptoInvoiceStatusSnapshot, CheckoutSession, DayrateAvailabilityResponse, DayrateBookingRequest, DayrateBookingResponse, DayrateMultiBookingRequest, DayrateMultiBookingResponse, Subscription, UsageBalance, VerifyCryptoWebhookSignatureOptions } from 'spaps-types';
|
|
3
|
+
export { AdminPermission, AdminRole, AdminUser, ApiResponse, AuthResponse, CheckoutSession, CreateCryptoInvoiceRequest, CreateIssueReportRequest, CreatePriceRequest, CreateProductRequest, CreateSecureMessageInput, CreateSecureMessageRequest, CryptoInvoice, CryptoInvoiceResponse, CryptoInvoiceStatusSnapshot, CryptoReconcileRequest, DayrateAvailabilityResponse, DayrateAvailableSlot, DayrateBookingRequest, DayrateBookingResponse, DayrateDayOfWeek, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayratePriceBreakdown, DayrateSlotType, Entitlement, IssueReport, IssueReportListResult, IssueReportStatus, IssueReportStatusResult, IssueReportTarget, LinkedIssueReportCase, Price, Product, ProductSyncResult, ReplyIssueReportRequest, ResourceType, SecureMessage, SecureMessageOutput, Subscription, TokenPair, UpdateIssueReportRequest, UpdateProductRequest, UsageBalance, User, UserProfile, UserRole, UserWallet, VerifyCryptoWebhookSignatureOptions, createSecureMessageRequestSchema, secureMessageMetadataSchema, secureMessageSchema } from 'spaps-types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Permission checking utilities for SPAPS SDK
|
|
@@ -344,6 +344,11 @@ interface EntitlementCheckResult {
|
|
|
344
344
|
/** The matching entitlement, if any */
|
|
345
345
|
entitlement?: Entitlement;
|
|
346
346
|
}
|
|
347
|
+
interface IssueReportListParams {
|
|
348
|
+
status?: IssueReportStatus;
|
|
349
|
+
limit?: number;
|
|
350
|
+
offset?: number;
|
|
351
|
+
}
|
|
347
352
|
|
|
348
353
|
declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Record<string, any>> {
|
|
349
354
|
private client;
|
|
@@ -429,6 +434,35 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
429
434
|
*/
|
|
430
435
|
listByResource: (resourceType: ResourceType, resourceId?: string) => Promise<Entitlement[]>;
|
|
431
436
|
};
|
|
437
|
+
/**
|
|
438
|
+
* Issue reporting namespace for authenticated end-user issue flows.
|
|
439
|
+
*/
|
|
440
|
+
issueReporting: {
|
|
441
|
+
/**
|
|
442
|
+
* Return canonical issue-report summary for the shared floating entrypoint.
|
|
443
|
+
*/
|
|
444
|
+
getStatus: () => Promise<IssueReportStatusResult>;
|
|
445
|
+
/**
|
|
446
|
+
* List the caller's issue reports inside the active application scope.
|
|
447
|
+
*/
|
|
448
|
+
list: (params?: IssueReportListParams) => Promise<IssueReportListResult>;
|
|
449
|
+
/**
|
|
450
|
+
* Hydrate one canonical issue report by ID.
|
|
451
|
+
*/
|
|
452
|
+
get: (issueReportId: string) => Promise<IssueReport>;
|
|
453
|
+
/**
|
|
454
|
+
* Create a new canonical issue report.
|
|
455
|
+
*/
|
|
456
|
+
create: (payload: CreateIssueReportRequest) => Promise<IssueReport>;
|
|
457
|
+
/**
|
|
458
|
+
* Update the note for an unresolved issue report.
|
|
459
|
+
*/
|
|
460
|
+
update: (issueReportId: string, payload: UpdateIssueReportRequest) => Promise<IssueReport>;
|
|
461
|
+
/**
|
|
462
|
+
* Reply to a resolved or ignored issue report and reopen the linked case.
|
|
463
|
+
*/
|
|
464
|
+
reply: (issueReportId: string, payload: ReplyIssueReportRequest) => Promise<IssueReport>;
|
|
465
|
+
};
|
|
432
466
|
constructor(config?: SPAPSConfig);
|
|
433
467
|
/** Raw API request helper that returns an ApiResponse-like shape */
|
|
434
468
|
request<T = any>(method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH', url: string, data?: any, requiresAuth?: boolean): Promise<{
|
|
@@ -895,4 +929,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
|
|
|
895
929
|
*/
|
|
896
930
|
declare function detectKeyType(key: string): ApiKeyType | null;
|
|
897
931
|
|
|
898
|
-
export { type AdminConfig, type ApiKeyType, type CheckoutLineItem, type CheckoutLineItemPriceData, type CreateCheckoutSessionPayload, DEFAULT_ADMIN_ACCOUNTS, type EmailSendOptions, type EmailSendResult, type EmailTemplate, type EmailTemplatePreview, type EntitlementCheckResult, type EntitlementListParams, type FeatureContext, type FeatureDefinition, FeatureEvaluator, type PermissionCheckResult, PermissionChecker, RoleHierarchy, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type TemplateVariable, TokenManager, WalletUtils, WebSocketAuthHelper, type WebSocketAuthHelperConfig, canAccessAdmin, createBrowserClient, createPermissionChecker, createServerClient, SPAPSClient as default, defaultPermissionChecker, detectKeyType, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount, verifyCryptoWebhookSignature };
|
|
932
|
+
export { type AdminConfig, type ApiKeyType, type CheckoutLineItem, type CheckoutLineItemPriceData, type CreateCheckoutSessionPayload, DEFAULT_ADMIN_ACCOUNTS, type EmailSendOptions, type EmailSendResult, type EmailTemplate, type EmailTemplatePreview, type EntitlementCheckResult, type EntitlementListParams, type FeatureContext, type FeatureDefinition, FeatureEvaluator, type IssueReportListParams, type PermissionCheckResult, PermissionChecker, RoleHierarchy, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type TemplateVariable, TokenManager, WalletUtils, WebSocketAuthHelper, type WebSocketAuthHelperConfig, canAccessAdmin, createBrowserClient, createPermissionChecker, createServerClient, SPAPSClient as default, defaultPermissionChecker, detectKeyType, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount, verifyCryptoWebhookSignature };
|