spaps-sdk 1.11.0 → 1.13.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.
- package/CHANGELOG.md +20 -0
- package/README.md +177 -9
- package/dist/index.d.mts +808 -35
- package/dist/index.d.ts +808 -35
- package/dist/index.js +617 -29
- package/dist/index.mjs +613 -29
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,8 +8,28 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
|
8
8
|
|
|
9
9
|
### Added
|
|
10
10
|
|
|
11
|
+
- Added `whitelist`, `users`, and `supportTelemetry` namespaces so the TypeScript SDK matches consumer-facing Python client domain coverage.
|
|
12
|
+
|
|
13
|
+
## [1.13.0] - 2026-06-13
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Added `auth.oidc`, `auth.webauthn`, `auth.mfa`, and `auth.sms` helpers for the backend login-method families, with MFA-required challenge results preserved as typed responses.
|
|
18
|
+
|
|
19
|
+
## [1.12.0] - 2026-06-12
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
11
23
|
- Added browser-safe `entitlements.listCurrentUserProjects()` and `entitlements.checkCurrentUserProjectAccess(...)` helpers for project grant reads.
|
|
12
24
|
|
|
25
|
+
## [1.11.0] - 2026-06-08
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Exported the canonical issue-report screenshot attachment constraints: `ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES`, `ISSUE_REPORT_ATTACHMENT_MAX_BYTES`, and `ISSUE_REPORT_ATTACHMENT_MAX_RETAINED`.
|
|
30
|
+
- Added SDK-side preflight validation to `issueReporting.uploadAttachment(file, options)`, rejecting unsupported MIME types and files larger than 10 MiB before opening the multipart request. SPAPS remains the authoritative backend validator.
|
|
31
|
+
- Documented the operator-gated automatic screenshot-capture handoff: React consumers should lazy-load capture through `spaps-issue-reporting-react@0.6.0`, pass captured files to SDK `uploadAttachment`, and keep publishing/deployment approval outside worker nodes. The local proof tarball for this SDK line was `/tmp/spaps-sdk-1.11.0.tgz`; `spaps-sdk@1.11.0` is now published on npm.
|
|
32
|
+
|
|
13
33
|
## [1.10.2] - 2026-06-04
|
|
14
34
|
|
|
15
35
|
### Added
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ This package targets `Node.js >=14`.
|
|
|
23
23
|
|
|
24
24
|
| Need | Package gives you |
|
|
25
25
|
| --- | --- |
|
|
26
|
-
| One client for many SPAPS surfaces | `auth`, `payments`, `sessions`, `secureMessages`, `issueReporting`, `appLinks`, `marketing`, `email`, `entitlements`, `usage`, `skillEvals`, `dayrate`, `admin`, and `cfo` namespaces |
|
|
26
|
+
| One client for many SPAPS surfaces | `auth`, `payments`, `sessions`, `secureMessages`, `issueReporting`, `appLinks`, `whitelist`, `users`, `supportTelemetry`, `marketing`, `email`, `entitlements`, `usage`, `access`, `graph`, `contract`, `skillEvals`, `dayrate`, `admin`, and `cfo` namespaces |
|
|
27
27
|
| Local development without extra config | Localhost URLs automatically enable local mode |
|
|
28
28
|
| Browser and server usage | `publishableKey`, `secretKey`, or legacy `apiKey` support |
|
|
29
29
|
| Shared contracts | Re-exports a large slice of `spaps-types` |
|
|
@@ -43,14 +43,16 @@ const auth = await spaps.auth.signInWithPassword({
|
|
|
43
43
|
password: "correct-horse-battery-staple",
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
// Accounts with activated TOTP receive an MFA challenge from /api/auth/login;
|
|
47
|
+
// complete /api/auth/mfa/verify before using token-backed helpers.
|
|
48
|
+
const session = await spaps.getSessionContext();
|
|
47
49
|
const issues = await spaps.issueReporting.list({
|
|
48
50
|
status: "open",
|
|
49
51
|
scope: "mine",
|
|
50
52
|
limit: 20,
|
|
51
53
|
});
|
|
52
54
|
|
|
53
|
-
console.log(auth.user.id,
|
|
55
|
+
console.log(auth.user.id, session.user.email, session.entitlements.length, issues.total);
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
Issue-reporting reads are user-scoped in the stock SPAPS API. The SDK accepts `scope: "mine"`
|
|
@@ -80,16 +82,22 @@ Relevant environment variables:
|
|
|
80
82
|
|
|
81
83
|
| Namespace | Covers |
|
|
82
84
|
| --- | --- |
|
|
83
|
-
| `auth` | Password, wallet, magic-link, refresh, logout, and password-management flows |
|
|
85
|
+
| `auth` | Password, wallet, OIDC, WebAuthn, MFA, SMS, magic-link, refresh, logout, and password-management flows |
|
|
84
86
|
| `payments` | Checkout sessions, products, prices, subscriptions, and crypto helpers |
|
|
85
87
|
| `sessions` | Session lookup, validation, and lifecycle helpers |
|
|
86
88
|
| `secureMessages` | Secure-message create/list helpers |
|
|
87
89
|
| `issueReporting` | Status, history, create, update, reply, voice-token, and private screenshot attachment flows |
|
|
88
90
|
| `appLinks` | Authenticated create and public resolve helpers for application-scoped short links |
|
|
91
|
+
| `whitelist` | Email whitelist checks and admin mutations |
|
|
92
|
+
| `users` | Batch user/email lookups and app membership administration |
|
|
93
|
+
| `supportTelemetry` | Trusted-service support event ingest and case inspection |
|
|
89
94
|
| `marketing` | Browser-safe attribution/experiment event emission and server-side experiment results |
|
|
90
95
|
| `email` | Template lookup, preview, and send helpers |
|
|
91
96
|
| `entitlements` | User/resource entitlement queries and browser-safe current-user project access reads |
|
|
92
97
|
| `usage` | Secret-key usage authorization and immutable usage recording |
|
|
98
|
+
| `access` | Agent-oriented access decisions, action preparation, and persisted decision traces |
|
|
99
|
+
| `graph` | Secret-key capability graph node, path, impact, explain, and refresh helpers |
|
|
100
|
+
| `contract` | Machine-readable capability graph contract discovery |
|
|
93
101
|
| `skillEvals` | Paid blind skill-eval cases, review rooms, reviewer marks, insight inboxes, and controlled reveal |
|
|
94
102
|
| `dayrate` | Availability, Stripe booking, x402 booking-hold, and checkout-status helpers |
|
|
95
103
|
| `admin` | Product and pricing admin helpers |
|
|
@@ -97,6 +105,68 @@ Relevant environment variables:
|
|
|
97
105
|
|
|
98
106
|
## Common Patterns
|
|
99
107
|
|
|
108
|
+
### Agent Access Decisions
|
|
109
|
+
|
|
110
|
+
`access.check` returns a typed decision even when access is denied. Treat
|
|
111
|
+
`allowed: false` as a normal outcome and use `next_actions` to route the user
|
|
112
|
+
or agent to the next step.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const spaps = new SPAPSClient({
|
|
116
|
+
apiUrl: "https://api.example.test",
|
|
117
|
+
secretKey: process.env.SPAPS_API_KEY,
|
|
118
|
+
});
|
|
119
|
+
spaps.setAccessToken(process.env.SPAPS_ADMIN_ACCESS_TOKEN!);
|
|
120
|
+
|
|
121
|
+
const decision = await spaps.access.check({
|
|
122
|
+
actor: { actor_type: "user", actor_ref: "user_123" },
|
|
123
|
+
action: "checkout.create",
|
|
124
|
+
resource: { resource_type: "product", resource_ref: "dayrate" },
|
|
125
|
+
controls: { entitlement_key: "bookme_paid" },
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
if (!decision.allowed) {
|
|
129
|
+
console.log(decision.outcome, decision.next_actions);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const prepared = await spaps.access.prepareAction({
|
|
133
|
+
access: {
|
|
134
|
+
actor: { actor_ref: "admin_123" },
|
|
135
|
+
action: "admin.delete_user",
|
|
136
|
+
resource: { resource_type: "user", resource_ref: "user_123" },
|
|
137
|
+
},
|
|
138
|
+
include_command_templates: true,
|
|
139
|
+
environment: "production",
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
console.log(prepared.status, prepared.execution.operator_gate_required);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`operator-gated` is descriptive compatibility input when supplied by a client;
|
|
146
|
+
it does not authorize mutation command templates. The server returns mutation
|
|
147
|
+
command templates only for a non-publishable key plus an authenticated
|
|
148
|
+
admin/operator user context. Publishable callers cannot self-attest the gate.
|
|
149
|
+
|
|
150
|
+
Use the graph and contract namespaces from trusted server code:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const contract = await spaps.contract.get();
|
|
154
|
+
const refresh = await spaps.graph.refresh("local-refresh");
|
|
155
|
+
const nodes = await spaps.graph.listNodes({ node_type: "x402_resource", q: "dayrate" });
|
|
156
|
+
const explanation = await spaps.access.explain(decision.decision_trace_id);
|
|
157
|
+
|
|
158
|
+
console.log(contract.version, refresh.status, refresh.diagnostics.phase2_gate?.recommendation);
|
|
159
|
+
console.log(nodes.projection?.projection_status, explanation.graph_node_keys);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`contract.get()` also returns `graph_node_types`, `graph_edge_types`,
|
|
163
|
+
`graph_source_domains`, and `source_domain_notes` so agents can discover
|
|
164
|
+
stable graph vocabulary such as `wallet`, `api_key`, `role`, and `approver`.
|
|
165
|
+
|
|
166
|
+
Capability API failures throw `SPAPSSDKError`. The error preserves `code`,
|
|
167
|
+
`status`/`statusCode`, `requestId`/`request_id`, `details`, `diagnostics`, and
|
|
168
|
+
`remediations`, including fields returned by the server error envelope.
|
|
169
|
+
|
|
100
170
|
### Browser-Safe Project Access Reads
|
|
101
171
|
|
|
102
172
|
Use a publishable key and an authenticated user JWT in browser code. These
|
|
@@ -124,6 +194,58 @@ const access = await spaps.entitlements.checkCurrentUserProjectAccess({
|
|
|
124
194
|
console.log(projects.count, access.has_access);
|
|
125
195
|
```
|
|
126
196
|
|
|
197
|
+
### Modern Auth Methods
|
|
198
|
+
|
|
199
|
+
Login methods that may require MFA return either token data or an MFA challenge
|
|
200
|
+
with `mfa_required: true`. Complete the challenge with `auth.mfa.verify()`
|
|
201
|
+
before calling token-backed helpers.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
const methods = await spaps.auth.getMethods();
|
|
205
|
+
console.log(methods.methods.filter((item) => item.enabled).map((item) => item.method));
|
|
206
|
+
|
|
207
|
+
const login = await spaps.auth.signInWithPassword({
|
|
208
|
+
email: "user@example.com",
|
|
209
|
+
password: "correct-horse-battery-staple",
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if ("mfa_required" in login) {
|
|
213
|
+
const verified = await spaps.auth.mfa.verify({
|
|
214
|
+
challenge_id: login.challenge_id,
|
|
215
|
+
challenge: login.challenge,
|
|
216
|
+
code: "123456",
|
|
217
|
+
});
|
|
218
|
+
console.log(verified.user.id);
|
|
219
|
+
} else {
|
|
220
|
+
console.log(login.user.id);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
OIDC, WebAuthn, and SMS helpers mirror the backend route families without
|
|
225
|
+
reimplementing browser or provider SDKs:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
const oidc = await spaps.auth.oidc.getNonce();
|
|
229
|
+
await spaps.auth.oidc.signIn({
|
|
230
|
+
provider: "google",
|
|
231
|
+
id_token: providerIdToken,
|
|
232
|
+
challenge_id: oidc.challenge_id,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const createOptions = await spaps.auth.webauthn.registerOptions();
|
|
236
|
+
await spaps.auth.webauthn.registerVerify({
|
|
237
|
+
challenge_id: createOptions.challenge_id,
|
|
238
|
+
credential: serializedPublicKeyCredential,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const sms = await spaps.auth.sms.request({ phone_number: "+15555550100" });
|
|
242
|
+
await spaps.auth.sms.verify({
|
|
243
|
+
phone_number: "+15555550100",
|
|
244
|
+
challenge_id: sms.challenge_id,
|
|
245
|
+
code: "123456",
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
127
249
|
### Typed Secure Messages
|
|
128
250
|
|
|
129
251
|
```ts
|
|
@@ -154,14 +276,34 @@ console.log(voiceToken.provider, voiceToken.model_id);
|
|
|
154
276
|
|
|
155
277
|
### Issue Reporting Screenshot Attachments
|
|
156
278
|
|
|
157
|
-
|
|
279
|
+
Use `spaps.issueReporting.uploadAttachment(file)` as the canonical screenshot
|
|
280
|
+
upload path. Consumers should not carry raw `POST /api/v1/issue-reports/attachments`
|
|
281
|
+
adapters when their installed `spaps-sdk` exposes this method.
|
|
282
|
+
|
|
283
|
+
Screenshots are uploaded as private pending hosted assets first. Create, update,
|
|
284
|
+
or reply calls then send only attachment IDs; do not put raw image bytes, data
|
|
285
|
+
URLs, or base64 payloads in issue notes or target metadata.
|
|
158
286
|
|
|
159
287
|
```ts
|
|
288
|
+
import {
|
|
289
|
+
ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
|
|
290
|
+
ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
|
|
291
|
+
ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
|
|
292
|
+
} from "spaps-sdk";
|
|
293
|
+
|
|
160
294
|
spaps.setAccessToken(accessToken);
|
|
161
295
|
|
|
162
296
|
const file = new File([pngBytes], "protocol-save-failure.png", {
|
|
163
297
|
type: "image/png",
|
|
164
298
|
});
|
|
299
|
+
|
|
300
|
+
const supportedType = ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES.some(
|
|
301
|
+
(mimeType) => mimeType === file.type,
|
|
302
|
+
);
|
|
303
|
+
if (!supportedType || file.size > ISSUE_REPORT_ATTACHMENT_MAX_BYTES) {
|
|
304
|
+
throw new Error("Screenshot is not a supported SPAPS issue-report attachment");
|
|
305
|
+
}
|
|
306
|
+
|
|
165
307
|
const attachment = await spaps.issueReporting.uploadAttachment(file);
|
|
166
308
|
|
|
167
309
|
const issue = await spaps.issueReporting.create({
|
|
@@ -178,14 +320,40 @@ const issue = await spaps.issueReporting.create({
|
|
|
178
320
|
});
|
|
179
321
|
|
|
180
322
|
const access = await spaps.issueReporting.getAttachmentAccess(attachment.id);
|
|
181
|
-
console.log(issue.id, access.expires_in_seconds);
|
|
323
|
+
console.log(issue.id, access.expires_in_seconds, ISSUE_REPORT_ATTACHMENT_MAX_RETAINED);
|
|
182
324
|
```
|
|
183
325
|
|
|
184
|
-
|
|
326
|
+
The SDK rejects unsupported screenshot MIME types and files over 10 MiB before
|
|
327
|
+
opening the multipart request. SPAPS still performs authoritative validation,
|
|
328
|
+
stores the hosted object privately, and retains at most 5 screenshots per report
|
|
329
|
+
or reply. Callers fetch a short-lived access URL after normal issue-reporting
|
|
330
|
+
authorization succeeds. SPAPS does not redact screenshot contents, so host apps
|
|
331
|
+
should warn users when a capture may include sensitive data.
|
|
332
|
+
|
|
333
|
+
Browser capture is intentionally outside this SDK. The shared
|
|
334
|
+
`spaps-issue-reporting-react` automatic DOM capture contract is a React-package
|
|
335
|
+
concern: it should lazy-load `html2canvas` only after the host app opts in with
|
|
336
|
+
the React `screenshotCapture` config, convert the visible same-origin DOM result
|
|
337
|
+
to a PNG, JPEG, or WebP `Blob`/`File`, then pass that file to
|
|
338
|
+
`uploadAttachment`. Apps that do not opt in must not download `html2canvas`.
|
|
339
|
+
If capture or upload fails, submit the issue with metadata and any manual
|
|
340
|
+
attachments instead of blocking issue submission.
|
|
341
|
+
|
|
342
|
+
Version note: `uploadAttachment` was added in `spaps-sdk@1.10.1`, and
|
|
343
|
+
`getAttachmentAccess` became the canonical access helper in `spaps-sdk@1.10.2`.
|
|
344
|
+
The exported limit constants shown above are part of this source package line;
|
|
345
|
+
wait for the operator-approved npm release before removing local shims from
|
|
346
|
+
consumers pinned to older packages.
|
|
347
|
+
|
|
348
|
+
No new SDK method or backend screenshot endpoint is part of the automatic
|
|
349
|
+
capture contract unless the existing private attachment upload proves
|
|
350
|
+
insufficient. Worker nodes may validate with local packs or workspace links, but
|
|
351
|
+
publishing `spaps-sdk` or `spaps-issue-reporting-react` remains operator-gated.
|
|
185
352
|
|
|
186
353
|
### Application Short Links
|
|
187
354
|
|
|
188
355
|
Use `appLinks` when a browser app needs a stable public URL for large local state, such as compressed diagram state.
|
|
356
|
+
Treat `link.username` as an opaque public owner segment returned by SPAPS.
|
|
189
357
|
|
|
190
358
|
```ts
|
|
191
359
|
const spaps = new SPAPSClient({
|
|
@@ -201,7 +369,7 @@ const link = await spaps.appLinks.create({
|
|
|
201
369
|
metadata: { diagram_state: "pako:..." },
|
|
202
370
|
});
|
|
203
371
|
|
|
204
|
-
console.log(
|
|
372
|
+
console.log(`/api/v1/app-links/${link.username}/${link.slug}`);
|
|
205
373
|
|
|
206
374
|
await spaps.appLinks.update(link.username, link.slug, {
|
|
207
375
|
metadata: { diagram_state: "pako:new-state" },
|
|
@@ -511,7 +679,7 @@ npm run test:readme
|
|
|
511
679
|
## Metadata
|
|
512
680
|
|
|
513
681
|
- `package_name`: `spaps-sdk`
|
|
514
|
-
- `latest_version`: `1.
|
|
682
|
+
- `latest_version`: `1.13.0`
|
|
515
683
|
- `minimum_runtime`: `Node.js >=14.0.0`
|
|
516
684
|
- `api_base_url`: `https://api.sweetpotato.dev`
|
|
517
685
|
|