spaps-sdk 1.12.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 CHANGED
@@ -8,6 +8,18 @@ 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
 
13
25
  ## [1.11.0] - 2026-06-08
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
- const me = await spaps.getUser();
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, me.data.email, issues.total);
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
@@ -231,6 +353,7 @@ publishing `spaps-sdk` or `spaps-issue-reporting-react` remains operator-gated.
231
353
  ### Application Short Links
232
354
 
233
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.
234
357
 
235
358
  ```ts
236
359
  const spaps = new SPAPSClient({
@@ -246,7 +369,7 @@ const link = await spaps.appLinks.create({
246
369
  metadata: { diagram_state: "pako:..." },
247
370
  });
248
371
 
249
- console.log(`/${link.app_slug}/${link.username}/${link.slug}`);
372
+ console.log(`/api/v1/app-links/${link.username}/${link.slug}`);
250
373
 
251
374
  await spaps.appLinks.update(link.username, link.slug, {
252
375
  metadata: { diagram_state: "pako:new-state" },
@@ -556,7 +679,7 @@ npm run test:readme
556
679
  ## Metadata
557
680
 
558
681
  - `package_name`: `spaps-sdk`
559
- - `latest_version`: `1.11.0`
682
+ - `latest_version`: `1.13.0`
560
683
  - `minimum_runtime`: `Node.js >=14.0.0`
561
684
  - `api_base_url`: `https://api.sweetpotato.dev`
562
685