spaps-sdk 1.10.1 → 1.11.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 +12 -0
- package/PERMISSIONS.md +22 -1
- package/README.md +67 -4
- package/dist/index.d.mts +178 -4
- package/dist/index.d.ts +178 -4
- package/dist/index.js +207 -3
- package/dist/index.mjs +207 -3
- package/package.json +2 -2
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 browser-safe `entitlements.listCurrentUserProjects()` and `entitlements.checkCurrentUserProjectAccess(...)` helpers for project grant reads.
|
|
12
|
+
|
|
13
|
+
## [1.10.2] - 2026-06-04
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Added `issueReporting.getAttachmentAccess(attachmentId)` as the canonical screenshot access helper while keeping `getAttachmentAccessUrl` as a backward-compatible alias.
|
|
18
|
+
|
|
19
|
+
## [1.10.1] - 2026-05-16
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
11
23
|
- Added issue-reporting screenshot attachment helpers for private upload, list, access URL, delete, and attach-by-ID create/update/reply flows.
|
|
12
24
|
|
|
13
25
|
## [1.10.0] - 2026-05-11
|
package/PERMISSIONS.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
Client-side permission checking and role management utilities for SPAPS applications.
|
|
4
4
|
|
|
5
|
+
## Browser-Safe Project Access
|
|
6
|
+
|
|
7
|
+
The SDK exposes read-only helpers for current-user project access:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
await spaps.entitlements.listCurrentUserProjects({
|
|
11
|
+
entitlementKey: 'pds.project.viewer'
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
await spaps.entitlements.checkCurrentUserProjectAccess({
|
|
15
|
+
projectId: 'project_123',
|
|
16
|
+
entitlementKey: 'pds.project.viewer'
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
These helpers are safe for publishable-key browser contexts because SPAPS
|
|
21
|
+
validates the JWT subject server-side. The SDK does not expose browser methods
|
|
22
|
+
for account membership invitation, project grant, project revoke, or account
|
|
23
|
+
capability mutation. Keep those operations in a trusted backend using a secret
|
|
24
|
+
key and admin access token.
|
|
25
|
+
|
|
5
26
|
## 🚀 Quick Start
|
|
6
27
|
|
|
7
28
|
```typescript
|
|
@@ -387,4 +408,4 @@ interface PermissionCheckResult {
|
|
|
387
408
|
4. **Role-based UI**: Show/hide features based on user permissions
|
|
388
409
|
5. **Custom admin management**: Use custom admin lists for multi-tenant apps
|
|
389
410
|
6. **Testing**: Test permission logic with various user states
|
|
390
|
-
7. **Type safety**: Use TypeScript interfaces for better development experience
|
|
411
|
+
7. **Type safety**: Use TypeScript interfaces for better development experience
|
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`, `email`, `entitlements`, `usage`, `skillEvals`, `dayrate`, `admin`, and `cfo` namespaces |
|
|
26
|
+
| One client for many SPAPS surfaces | `auth`, `payments`, `sessions`, `secureMessages`, `issueReporting`, `appLinks`, `marketing`, `email`, `entitlements`, `usage`, `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` |
|
|
@@ -86,8 +86,9 @@ Relevant environment variables:
|
|
|
86
86
|
| `secureMessages` | Secure-message create/list helpers |
|
|
87
87
|
| `issueReporting` | Status, history, create, update, reply, voice-token, and private screenshot attachment flows |
|
|
88
88
|
| `appLinks` | Authenticated create and public resolve helpers for application-scoped short links |
|
|
89
|
+
| `marketing` | Browser-safe attribution/experiment event emission and server-side experiment results |
|
|
89
90
|
| `email` | Template lookup, preview, and send helpers |
|
|
90
|
-
| `entitlements` | User
|
|
91
|
+
| `entitlements` | User/resource entitlement queries and browser-safe current-user project access reads |
|
|
91
92
|
| `usage` | Secret-key usage authorization and immutable usage recording |
|
|
92
93
|
| `skillEvals` | Paid blind skill-eval cases, review rooms, reviewer marks, insight inboxes, and controlled reveal |
|
|
93
94
|
| `dayrate` | Availability, Stripe booking, x402 booking-hold, and checkout-status helpers |
|
|
@@ -96,6 +97,33 @@ Relevant environment variables:
|
|
|
96
97
|
|
|
97
98
|
## Common Patterns
|
|
98
99
|
|
|
100
|
+
### Browser-Safe Project Access Reads
|
|
101
|
+
|
|
102
|
+
Use a publishable key and an authenticated user JWT in browser code. These
|
|
103
|
+
helpers only read project access for the current user; membership invitation,
|
|
104
|
+
project grant, project revoke, and account capability mutation remain
|
|
105
|
+
server-only operations.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const spaps = new SPAPSClient({
|
|
109
|
+
apiUrl: "https://api.example.test",
|
|
110
|
+
publishableKey: "spaps_pub_example",
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
spaps.setAccessToken(userAccessToken);
|
|
114
|
+
|
|
115
|
+
const projects = await spaps.entitlements.listCurrentUserProjects({
|
|
116
|
+
entitlementKey: "pds.project.viewer",
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const access = await spaps.entitlements.checkCurrentUserProjectAccess({
|
|
120
|
+
projectId: "project_123",
|
|
121
|
+
entitlementKey: "pds.project.viewer",
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
console.log(projects.count, access.has_access);
|
|
125
|
+
```
|
|
126
|
+
|
|
99
127
|
### Typed Secure Messages
|
|
100
128
|
|
|
101
129
|
```ts
|
|
@@ -149,7 +177,7 @@ const issue = await spaps.issueReporting.create({
|
|
|
149
177
|
attachment_ids: [attachment.id],
|
|
150
178
|
});
|
|
151
179
|
|
|
152
|
-
const access = await spaps.issueReporting.
|
|
180
|
+
const access = await spaps.issueReporting.getAttachmentAccess(attachment.id);
|
|
153
181
|
console.log(issue.id, access.expires_in_seconds);
|
|
154
182
|
```
|
|
155
183
|
|
|
@@ -174,6 +202,41 @@ const link = await spaps.appLinks.create({
|
|
|
174
202
|
});
|
|
175
203
|
|
|
176
204
|
console.log(`/${link.app_slug}/${link.username}/${link.slug}`);
|
|
205
|
+
|
|
206
|
+
await spaps.appLinks.update(link.username, link.slug, {
|
|
207
|
+
metadata: { diagram_state: "pako:new-state" },
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Marketing Events
|
|
212
|
+
|
|
213
|
+
Use `marketing.emit` in the browser with a publishable key for anonymous
|
|
214
|
+
attribution touches or experiment exposures. Use `marketing.getExperimentResults`
|
|
215
|
+
from a trusted server or agent with a secret key to read revenue-backed results
|
|
216
|
+
and the conservative stop signal.
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
const browserSpaps = new SPAPSClient({
|
|
220
|
+
apiUrl: "https://api.example.test",
|
|
221
|
+
publishableKey: "spaps_pub_example",
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
await browserSpaps.marketing.emit({
|
|
225
|
+
anon_id: "anon_01HY...",
|
|
226
|
+
event_type: "experiment_exposure",
|
|
227
|
+
experiment_id: "landing-hero-copy",
|
|
228
|
+
variant_id: "treatment",
|
|
229
|
+
dedupe_key: "landing-hero-copy:anon_01HY:treatment",
|
|
230
|
+
timestamp: new Date().toISOString(),
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const serverSpaps = new SPAPSClient({
|
|
234
|
+
apiUrl: "https://api.example.test",
|
|
235
|
+
secretKey: process.env.SPAPS_SECRET_KEY,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const results = await serverSpaps.marketing.getExperimentResults("landing-hero-copy");
|
|
239
|
+
console.log(results.decision.recommendation, results.decision.winner_variant_id);
|
|
177
240
|
```
|
|
178
241
|
|
|
179
242
|
### Server-Side Usage Control
|
|
@@ -448,7 +511,7 @@ npm run test:readme
|
|
|
448
511
|
## Metadata
|
|
449
512
|
|
|
450
513
|
- `package_name`: `spaps-sdk`
|
|
451
|
-
- `latest_version`: `1.10.
|
|
514
|
+
- `latest_version`: `1.10.2`
|
|
452
515
|
- `minimum_runtime`: `Node.js >=14.0.0`
|
|
453
516
|
- `api_base_url`: `https://api.sweetpotato.dev`
|
|
454
517
|
|
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, IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, IssueReportAttachmentOut, ListIssueReportAttachmentsResponse, IssueReportAttachmentAccessResponse, IssueReportingVoiceTokenResult, UpdateIssueReportRequest, ReplyIssueReportRequest, CreateAppLinkRequest, AppLink, AuthResponse, User as User$1, CreateCryptoInvoiceRequest, CryptoInvoiceStatusSnapshot, CheckoutSession, X402ResourceStatusResponse, X402ActionResponse, X402ReceiptResponse, X402ReceiptListResponse, X402HandoffVerification, DayrateAvailabilityResponse, DayrateBookingRequest, DayrateBookingResponse, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayrateX402BookingRequest, DayrateX402BookingResponse, DayrateCheckoutStatusResponse, UsageControlFeaturesResponse, UsageControlStatusRequest, UsageControlStatusResponse, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, Subscription, VerifyCryptoWebhookSignatureOptions } from 'spaps-types';
|
|
3
|
-
export { AdminPermission, AdminRole, AdminUser, ApiResponse, AppLink, AuthResponse, CheckoutSession, CreateAppLinkRequest, CreateCryptoInvoiceRequest, CreateIssueReportRequest, CreatePriceRequest, CreateProductRequest, CreateSecureMessageInput, CreateSecureMessageRequest, CryptoInvoice, CryptoInvoiceResponse, CryptoInvoiceStatusSnapshot, CryptoReconcileRequest, DayrateAvailabilityResponse, DayrateAvailableSlot, DayrateBookingRequest, DayrateBookingResponse, DayrateCheckoutStatus, DayrateCheckoutStatusBooking, DayrateCheckoutStatusResponse, DayrateDayOfWeek, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayratePriceBreakdown, DayrateSlotType, DayrateX402BookingRequest, DayrateX402BookingResponse, Entitlement, IssueReport, IssueReportAttachmentAccessResponse, IssueReportAttachmentOut, IssueReportListResult, IssueReportStatus, IssueReportStatusResult, IssueReportTarget, IssueReportingInputMode, IssueReportingVoiceProvider, IssueReportingVoiceTokenResult, LinkedIssueReportCase, ListIssueReportAttachmentsResponse, Price, Product, ProductSyncResult, ReplyIssueReportRequest, ResourceType, SecureMessage, SecureMessageOutput, Subscription, TokenPair, UpdateIssueReportRequest, UpdateProductRequest, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlDecision, UsageControlDimensions, UsageControlError, UsageControlErrorCode, UsageControlFeaturesResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, UsageControlLedgerEvent, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlRecordStatus, UsageControlStatusRequest, UsageControlStatusResponse, User, UserProfile, UserRole, UserWallet, VerifyCryptoWebhookSignatureOptions, X402ActionFreeResponse, X402ActionOutcome, X402ActionPendingResponse, X402ActionReplayedResponse, X402ActionResponse, X402ActionSettledResponse, X402ExecuteActionRequest, X402HandoffAuthorization, X402HandoffVerification, X402HandoffVerifyRequest, X402PaymentAccept, X402PaymentRequirement, X402ProjectionStatus, X402Receipt, X402ReceiptListResponse, X402ReceiptResponse, X402ReceiptStatus, X402Resource, X402ResourceStatus, X402ResourceStatusResponse, atomicToMoneyUnits, createSecureMessageRequestSchema, isX402PaymentRequired, isX402ResourceStatus, moneyUnitsToAtomic, roundHalfToPositiveInfinity, secureMessageMetadataSchema, secureMessageSchema, validatePositiveAmountAtomic } from 'spaps-types';
|
|
2
|
+
import { ResourceType, Entitlement, CreateProductRequest, Product, UpdateProductRequest, CreatePriceRequest, Price, ProductSyncResult, CryptoReconcileRequest, CreateSecureMessageRequest, SecureMessage, ListProjectGrantsResponse, ProjectAccessCheckResponse, IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, IssueReportAttachmentOut, ListIssueReportAttachmentsResponse, IssueReportAttachmentAccessResponse, IssueReportingVoiceTokenResult, UpdateIssueReportRequest, ReplyIssueReportRequest, ListIssueReportMessagesResponse, CreateReporterMessageRequest, IssueReportMessage, CreateOperatorMessageRequest, RetractOperatorMessageRequest, CreateAppLinkRequest, AppLink, UpdateAppLinkRequest, AuthResponse, User as User$1, CreateCryptoInvoiceRequest, CryptoInvoiceStatusSnapshot, CheckoutSession, X402ResourceStatusResponse, X402ActionResponse, X402ReceiptResponse, X402ReceiptListResponse, X402HandoffVerification, DayrateAvailabilityResponse, DayrateBookingRequest, DayrateBookingResponse, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayrateX402BookingRequest, DayrateX402BookingResponse, DayrateCheckoutStatusResponse, UsageControlFeaturesResponse, UsageControlStatusRequest, UsageControlStatusResponse, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, Subscription, VerifyCryptoWebhookSignatureOptions } from 'spaps-types';
|
|
3
|
+
export { AdminPermission, AdminRole, AdminUser, ApiResponse, AppLink, AuthResponse, CheckoutSession, CreateAppLinkRequest, CreateCryptoInvoiceRequest, CreateIssueReportRequest, CreateOperatorMessageRequest, CreatePriceRequest, CreateProductRequest, CreateReporterMessageRequest, CreateSecureMessageInput, CreateSecureMessageRequest, CryptoInvoice, CryptoInvoiceResponse, CryptoInvoiceStatusSnapshot, CryptoReconcileRequest, DayrateAvailabilityResponse, DayrateAvailableSlot, DayrateBookingRequest, DayrateBookingResponse, DayrateCheckoutStatus, DayrateCheckoutStatusBooking, DayrateCheckoutStatusResponse, DayrateDayOfWeek, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayratePriceBreakdown, DayrateSlotType, DayrateX402BookingRequest, DayrateX402BookingResponse, Entitlement, IssueReport, IssueReportAttachmentAccessResponse, IssueReportAttachmentOut, IssueReportListResult, IssueReportMessage, IssueReportStatus, IssueReportStatusResult, IssueReportTarget, IssueReportingInputMode, IssueReportingVoiceProvider, IssueReportingVoiceTokenResult, LinkedIssueReportCase, ListIssueReportAttachmentsResponse, ListIssueReportMessagesResponse, ListProjectGrantsResponse, Price, Product, ProductSyncResult, ProjectAccessCheckResponse, ProjectGrant, ProjectGrantStatus, ReplyIssueReportRequest, ResourceType, RetractOperatorMessageRequest, SecureMessage, SecureMessageOutput, Subscription, TokenPair, UpdateAppLinkRequest, UpdateIssueReportRequest, UpdateProductRequest, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlDecision, UsageControlDimensions, UsageControlError, UsageControlErrorCode, UsageControlFeaturesResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, UsageControlLedgerEvent, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlRecordStatus, UsageControlStatusRequest, UsageControlStatusResponse, User, UserProfile, UserRole, UserWallet, VerifyCryptoWebhookSignatureOptions, X402ActionFreeResponse, X402ActionOutcome, X402ActionPendingResponse, X402ActionReplayedResponse, X402ActionResponse, X402ActionSettledResponse, X402ExecuteActionRequest, X402HandoffAuthorization, X402HandoffVerification, X402HandoffVerifyRequest, X402PaymentAccept, X402PaymentRequirement, X402ProjectionStatus, X402Receipt, X402ReceiptListResponse, X402ReceiptResponse, X402ReceiptStatus, X402Resource, X402ResourceStatus, X402ResourceStatusResponse, atomicToMoneyUnits, createSecureMessageRequestSchema, isX402PaymentRequired, isX402ResourceStatus, moneyUnitsToAtomic, roundHalfToPositiveInfinity, secureMessageMetadataSchema, secureMessageSchema, validatePositiveAmountAtomic } from 'spaps-types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Permission checking utilities for SPAPS SDK
|
|
@@ -336,6 +336,73 @@ interface EmailTemplatePreview {
|
|
|
336
336
|
html: string;
|
|
337
337
|
text?: string;
|
|
338
338
|
}
|
|
339
|
+
type MarketingEventType = 'attribution_touch' | 'experiment_exposure';
|
|
340
|
+
type MarketingExperimentRecommendation = 'continue' | 'continue_srm_warning' | 'stop_for_winner';
|
|
341
|
+
type MarketingExperimentSrmStatus = 'pass' | 'warning' | 'not_applicable';
|
|
342
|
+
interface MarketingEventIngestRequest {
|
|
343
|
+
application_id?: string;
|
|
344
|
+
anon_id: string;
|
|
345
|
+
event_type: MarketingEventType;
|
|
346
|
+
experiment_id?: string | null;
|
|
347
|
+
variant_id?: string | null;
|
|
348
|
+
variant?: string | null;
|
|
349
|
+
metadata?: Record<string, unknown> | null;
|
|
350
|
+
dedupe_key?: string | null;
|
|
351
|
+
timestamp?: string | null;
|
|
352
|
+
observed_at?: string | null;
|
|
353
|
+
}
|
|
354
|
+
interface MarketingEventIngestResponse {
|
|
355
|
+
id: string;
|
|
356
|
+
application_id: string;
|
|
357
|
+
anon_id: string;
|
|
358
|
+
event_type: MarketingEventType;
|
|
359
|
+
experiment_id?: string | null;
|
|
360
|
+
variant?: string | null;
|
|
361
|
+
dedupe_key: string;
|
|
362
|
+
ts: string;
|
|
363
|
+
created_at: string;
|
|
364
|
+
}
|
|
365
|
+
interface MarketingExperimentVariantResult {
|
|
366
|
+
variant_id: string | null;
|
|
367
|
+
exposures: number;
|
|
368
|
+
conversions: number;
|
|
369
|
+
conversion_rate: number;
|
|
370
|
+
revenue: Record<string, number>;
|
|
371
|
+
}
|
|
372
|
+
interface MarketingExperimentMinSampleDecision {
|
|
373
|
+
met: boolean;
|
|
374
|
+
min_exposures_per_variant: number;
|
|
375
|
+
min_total_conversions: number;
|
|
376
|
+
observed_min_exposures: number;
|
|
377
|
+
observed_total_conversions: number;
|
|
378
|
+
}
|
|
379
|
+
interface MarketingExperimentSrmDecision {
|
|
380
|
+
status: MarketingExperimentSrmStatus;
|
|
381
|
+
expected_share?: number | null;
|
|
382
|
+
max_share_ratio?: number | null;
|
|
383
|
+
min_share_ratio?: number | null;
|
|
384
|
+
}
|
|
385
|
+
interface MarketingExperimentEffectDecision {
|
|
386
|
+
leader_variant_id?: string | null;
|
|
387
|
+
runner_up_variant_id?: string | null;
|
|
388
|
+
absolute_lift?: number | null;
|
|
389
|
+
relative_lift?: number | null;
|
|
390
|
+
}
|
|
391
|
+
interface MarketingExperimentDecision {
|
|
392
|
+
decisive: boolean;
|
|
393
|
+
recommendation: MarketingExperimentRecommendation;
|
|
394
|
+
winner_variant_id?: string | null;
|
|
395
|
+
reason_codes: string[];
|
|
396
|
+
min_sample: MarketingExperimentMinSampleDecision;
|
|
397
|
+
srm: MarketingExperimentSrmDecision;
|
|
398
|
+
effect: MarketingExperimentEffectDecision;
|
|
399
|
+
}
|
|
400
|
+
interface MarketingExperimentResultsResponse {
|
|
401
|
+
application_id: string;
|
|
402
|
+
experiment_id: string;
|
|
403
|
+
variants: MarketingExperimentVariantResult[];
|
|
404
|
+
decision: MarketingExperimentDecision;
|
|
405
|
+
}
|
|
339
406
|
interface EntitlementListParams {
|
|
340
407
|
/** Filter by entitlement key */
|
|
341
408
|
key?: string;
|
|
@@ -350,6 +417,22 @@ interface EntitlementCheckResult {
|
|
|
350
417
|
/** The matching entitlement, if any */
|
|
351
418
|
entitlement?: Entitlement;
|
|
352
419
|
}
|
|
420
|
+
interface CurrentUserProjectGrantListParams {
|
|
421
|
+
/** Filter to one project entitlement key, such as "pds.project.viewer" */
|
|
422
|
+
entitlementKey?: string;
|
|
423
|
+
/** Maximum number of project grants to return */
|
|
424
|
+
limit?: number;
|
|
425
|
+
/** Zero-based item offset */
|
|
426
|
+
offset?: number;
|
|
427
|
+
/** Opaque pagination cursor */
|
|
428
|
+
cursor?: string;
|
|
429
|
+
}
|
|
430
|
+
interface CurrentUserProjectAccessParams {
|
|
431
|
+
/** Project to check */
|
|
432
|
+
projectId: string;
|
|
433
|
+
/** Project entitlement key to check, such as "pds.project.viewer" */
|
|
434
|
+
entitlementKey: string;
|
|
435
|
+
}
|
|
353
436
|
type SupportedIssueReportScope = Extract<IssueReportScope, 'mine'>;
|
|
354
437
|
interface IssueReportListParams {
|
|
355
438
|
status?: IssueReportStatus;
|
|
@@ -631,6 +714,7 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
631
714
|
private headerProvider?;
|
|
632
715
|
private unwrapApiResponse;
|
|
633
716
|
private skillEvalMutationConfig;
|
|
717
|
+
private requireCurrentUserIdFromAccessToken;
|
|
634
718
|
private isAxiosResponse;
|
|
635
719
|
private isResponseLikeWithData;
|
|
636
720
|
private isApiResponse;
|
|
@@ -708,10 +792,24 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
708
792
|
* Note: For publishable key contexts, only `resource_type=user` is permitted.
|
|
709
793
|
* Non-user resource types will return a 403 error (enforced server-side).
|
|
710
794
|
*
|
|
711
|
-
* @param resourceType - The resource type (e.g. "user", "company", "org", "system").
|
|
795
|
+
* @param resourceType - The resource type (e.g. "user", "company", "org", "system", "project").
|
|
712
796
|
* @param resourceId - Optional specific resource ID.
|
|
713
797
|
*/
|
|
714
798
|
listByResource: (resourceType: ResourceType, resourceId?: string) => Promise<Entitlement[]>;
|
|
799
|
+
/**
|
|
800
|
+
* List project grants for the authenticated user.
|
|
801
|
+
*
|
|
802
|
+
* Browser/publishable-key contexts are safe here because the server requires
|
|
803
|
+
* the JWT subject to match the path user id.
|
|
804
|
+
*/
|
|
805
|
+
listCurrentUserProjects: (params?: CurrentUserProjectGrantListParams) => Promise<ListProjectGrantsResponse>;
|
|
806
|
+
/**
|
|
807
|
+
* Check whether the authenticated user has one project entitlement.
|
|
808
|
+
*
|
|
809
|
+
* The helper does not accept user/email overrides; publishable-key callers
|
|
810
|
+
* are scoped by the server to the JWT identity.
|
|
811
|
+
*/
|
|
812
|
+
checkCurrentUserProjectAccess: (params: CurrentUserProjectAccessParams) => Promise<ProjectAccessCheckResponse>;
|
|
715
813
|
};
|
|
716
814
|
/**
|
|
717
815
|
* Issue reporting namespace for authenticated end-user issue flows.
|
|
@@ -744,6 +842,12 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
744
842
|
/**
|
|
745
843
|
* Return a short-lived private attachment access URL.
|
|
746
844
|
*/
|
|
845
|
+
getAttachmentAccess: (attachmentId: string) => Promise<IssueReportAttachmentAccessResponse>;
|
|
846
|
+
/**
|
|
847
|
+
* Return a short-lived private attachment access URL.
|
|
848
|
+
*
|
|
849
|
+
* @deprecated Use getAttachmentAccess(attachmentId).
|
|
850
|
+
*/
|
|
747
851
|
getAttachmentAccessUrl: (attachmentId: string) => Promise<IssueReportAttachmentAccessResponse>;
|
|
748
852
|
/**
|
|
749
853
|
* Soft-delete one owned screenshot attachment.
|
|
@@ -761,6 +865,46 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
761
865
|
* Reply to a resolved or ignored issue report and reopen the linked case.
|
|
762
866
|
*/
|
|
763
867
|
reply: (issueReportId: string, payload: ReplyIssueReportRequest) => Promise<IssueReport>;
|
|
868
|
+
/**
|
|
869
|
+
* List the chronological, reporter-visible message thread for one owned
|
|
870
|
+
* issue report. Only active, reporter-visible rows are returned; retracted
|
|
871
|
+
* or superseded operator messages are excluded and raw audit payloads are
|
|
872
|
+
* never exposed. `needs_response` badges an open clarification request.
|
|
873
|
+
*/
|
|
874
|
+
listMessages: (issueReportId: string) => Promise<ListIssueReportMessagesResponse>;
|
|
875
|
+
/**
|
|
876
|
+
* Submit a reporter clarification response on one owned issue report. This
|
|
877
|
+
* does NOT reopen a closed case (use `reply` for that). Idempotent on
|
|
878
|
+
* `idempotency_key`: same key + same body returns the existing message,
|
|
879
|
+
* same key + different body returns 409 ISSUE_REPORT_MESSAGE_CONFLICT.
|
|
880
|
+
*/
|
|
881
|
+
submitMessage: (issueReportId: string, payload: CreateReporterMessageRequest) => Promise<IssueReportMessage>;
|
|
882
|
+
/**
|
|
883
|
+
* Triage-operator message commands. These require a secret key context and a
|
|
884
|
+
* triage role/capability; publishable browser contexts are rejected by the
|
|
885
|
+
* server. Provide the secret key as the SDK's API key.
|
|
886
|
+
*/
|
|
887
|
+
triage: {
|
|
888
|
+
/**
|
|
889
|
+
* List all projection rows for an app-scoped report (including corrected
|
|
890
|
+
* rows) for authorized triage operators.
|
|
891
|
+
*/
|
|
892
|
+
listMessages: (issueReportId: string) => Promise<ListIssueReportMessagesResponse>;
|
|
893
|
+
/**
|
|
894
|
+
* Post a clarification_request or final_response reporter-visible message
|
|
895
|
+
* as a triage operator. Idempotent on `idempotency_key`; a key reused with
|
|
896
|
+
* a different body returns 409. A final_response can drive a terminal
|
|
897
|
+
* lifecycle transition via `resolve_case`; the internal resolution_note is
|
|
898
|
+
* never auto-displayed to reporters.
|
|
899
|
+
*/
|
|
900
|
+
postMessage: (issueReportId: string, payload: CreateOperatorMessageRequest) => Promise<IssueReportMessage>;
|
|
901
|
+
/**
|
|
902
|
+
* Retract an operator-authored message. The body is retained; the row's
|
|
903
|
+
* state is marked `retracted`. Retracting an already-retracted message is
|
|
904
|
+
* a safe no-op.
|
|
905
|
+
*/
|
|
906
|
+
retractMessage: (issueReportId: string, messageId: string, payload?: RetractOperatorMessageRequest) => Promise<IssueReportMessage>;
|
|
907
|
+
};
|
|
764
908
|
};
|
|
765
909
|
/**
|
|
766
910
|
* Application-scoped short links for browser apps that need stable public URLs.
|
|
@@ -770,6 +914,10 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
770
914
|
* Create a short link owned by the authenticated user.
|
|
771
915
|
*/
|
|
772
916
|
create: (payload: CreateAppLinkRequest) => Promise<AppLink>;
|
|
917
|
+
/**
|
|
918
|
+
* Update a short link owned by the authenticated user.
|
|
919
|
+
*/
|
|
920
|
+
update: (username: string, slug: string, payload: UpdateAppLinkRequest) => Promise<AppLink>;
|
|
773
921
|
/**
|
|
774
922
|
* Resolve a public short link for the active application.
|
|
775
923
|
*/
|
|
@@ -777,6 +925,30 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
777
925
|
track?: boolean;
|
|
778
926
|
}) => Promise<AppLink>;
|
|
779
927
|
};
|
|
928
|
+
/**
|
|
929
|
+
* Marketing events and experiment results.
|
|
930
|
+
*
|
|
931
|
+
* Use a publishable key for browser-side event emission. Use a secret key
|
|
932
|
+
* from a trusted server or agent process when reading experiment results.
|
|
933
|
+
*/
|
|
934
|
+
marketing: {
|
|
935
|
+
/**
|
|
936
|
+
* Emit one anonymous attribution touch or experiment exposure.
|
|
937
|
+
*/
|
|
938
|
+
emit: (payload: MarketingEventIngestRequest) => Promise<MarketingEventIngestResponse>;
|
|
939
|
+
/**
|
|
940
|
+
* Alias for emit(), matching the backend ingest endpoint language.
|
|
941
|
+
*/
|
|
942
|
+
ingest: (payload: MarketingEventIngestRequest) => Promise<MarketingEventIngestResponse>;
|
|
943
|
+
/**
|
|
944
|
+
* Read per-variant experiment results and the conservative stop signal.
|
|
945
|
+
*/
|
|
946
|
+
getExperimentResults: (experimentId: string) => Promise<MarketingExperimentResultsResponse>;
|
|
947
|
+
/**
|
|
948
|
+
* Short alias for getExperimentResults().
|
|
949
|
+
*/
|
|
950
|
+
getResults: (experimentId: string) => Promise<MarketingExperimentResultsResponse>;
|
|
951
|
+
};
|
|
780
952
|
private static envVar;
|
|
781
953
|
constructor(config?: SPAPSConfig);
|
|
782
954
|
/** Raw API request helper that returns an ApiResponse-like shape */
|
|
@@ -1154,6 +1326,8 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
1154
1326
|
recordUsage(payload: UsageControlRecordRequest): Promise<UsageControlRecordResponse>;
|
|
1155
1327
|
getUsageStatus(query: UsageControlStatusRequest): Promise<UsageControlStatusResponse>;
|
|
1156
1328
|
listUsageHistory(query?: UsageControlHistoryRequest): Promise<UsageControlHistoryResponse>;
|
|
1329
|
+
emitMarketingEvent(payload: MarketingEventIngestRequest): Promise<MarketingEventIngestResponse>;
|
|
1330
|
+
getMarketingExperimentResults(experimentId: string): Promise<MarketingExperimentResultsResponse>;
|
|
1157
1331
|
private createSecureMessage;
|
|
1158
1332
|
private listSecureMessages;
|
|
1159
1333
|
/**
|
|
@@ -1335,4 +1509,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
|
|
|
1335
1509
|
*/
|
|
1336
1510
|
declare function detectKeyType(key: string): ApiKeyType | null;
|
|
1337
1511
|
|
|
1338
|
-
export { type AdminConfig, type ApiKeyType, type CheckoutLineItem, type CheckoutLineItemPriceData, type CreateCheckoutSessionPayload, type CreateSkillEvalCaseRequest, type CreateSkillEvalGovernanceSnapshotRequest, DEFAULT_ADMIN_ACCOUNTS, type EmailSendOptions, type EmailSendResult, type EmailTemplate, type EmailTemplatePreview, type EntitlementCheckResult, type EntitlementListParams, type FeatureContext, type FeatureDefinition, FeatureEvaluator, type HeaderProvider, type ImportSkillEvalGovernanceOutcomeRequest, type IssueReportAttachmentUploadOptions, type IssueReportListParams, type IssueReportStatusParams, type PermissionCheckResult, PermissionChecker, type RespondToSkillEvalReviewRequest, type RevealSkillEvalEvidenceRequest, RoleHierarchy, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type SPAPSEnvelope, type SkillEvalAccessMode, type SkillEvalActorAccess, type SkillEvalCandidateInput, type SkillEvalCandidateResponse, type SkillEvalCasePolicy, type SkillEvalCaseResponse, type SkillEvalConfidence, type SkillEvalCreateOptions, type SkillEvalDisclosurePolicy, type SkillEvalEligibilitySource, type SkillEvalGovernanceOutcomeResult, type SkillEvalGovernancePurpose, type SkillEvalGovernanceSnapshotResult, type SkillEvalInsight, type SkillEvalInsightsResponse, type SkillEvalModelEffort, type SkillEvalMutationOptions, type SkillEvalPosterResponse, type SkillEvalPosterResponseResult, type SkillEvalRevealField, type SkillEvalRevealResult, type SkillEvalReviewMarkInput, type SkillEvalReviewMarkKind, type SkillEvalReviewResponse, type SkillEvalReviewRoom, type SkillEvalReviewerEligibilityInput, type SkillEvalRewardEvent, type SubmitSkillEvalReviewRequest, type TemplateVariable, TokenManager, WalletUtils, WebSocketAuthHelper, type WebSocketAuthHelperConfig, type X402ExecuteActionOptions, X402PaymentRequiredSDKError, type X402ReceiptListParams, type X402VerifyHandoffOptions, canAccessAdmin, createBrowserClient, createPermissionChecker, createServerClient, SPAPSClient as default, defaultPermissionChecker, detectKeyType, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount, isEnvelope, isErrorEnvelope, isSuccessEnvelope, unwrapEnvelope, unwrapNestedData, verifyCryptoWebhookSignature };
|
|
1512
|
+
export { type AdminConfig, type ApiKeyType, type CheckoutLineItem, type CheckoutLineItemPriceData, type CreateCheckoutSessionPayload, type CreateSkillEvalCaseRequest, type CreateSkillEvalGovernanceSnapshotRequest, type CurrentUserProjectAccessParams, type CurrentUserProjectGrantListParams, DEFAULT_ADMIN_ACCOUNTS, type EmailSendOptions, type EmailSendResult, type EmailTemplate, type EmailTemplatePreview, type EntitlementCheckResult, type EntitlementListParams, type FeatureContext, type FeatureDefinition, FeatureEvaluator, type HeaderProvider, type ImportSkillEvalGovernanceOutcomeRequest, type IssueReportAttachmentUploadOptions, type IssueReportListParams, type IssueReportStatusParams, type MarketingEventIngestRequest, type MarketingEventIngestResponse, type MarketingEventType, type MarketingExperimentDecision, type MarketingExperimentEffectDecision, type MarketingExperimentMinSampleDecision, type MarketingExperimentRecommendation, type MarketingExperimentResultsResponse, type MarketingExperimentSrmDecision, type MarketingExperimentSrmStatus, type MarketingExperimentVariantResult, type PermissionCheckResult, PermissionChecker, type RespondToSkillEvalReviewRequest, type RevealSkillEvalEvidenceRequest, RoleHierarchy, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type SPAPSEnvelope, type SkillEvalAccessMode, type SkillEvalActorAccess, type SkillEvalCandidateInput, type SkillEvalCandidateResponse, type SkillEvalCasePolicy, type SkillEvalCaseResponse, type SkillEvalConfidence, type SkillEvalCreateOptions, type SkillEvalDisclosurePolicy, type SkillEvalEligibilitySource, type SkillEvalGovernanceOutcomeResult, type SkillEvalGovernancePurpose, type SkillEvalGovernanceSnapshotResult, type SkillEvalInsight, type SkillEvalInsightsResponse, type SkillEvalModelEffort, type SkillEvalMutationOptions, type SkillEvalPosterResponse, type SkillEvalPosterResponseResult, type SkillEvalRevealField, type SkillEvalRevealResult, type SkillEvalReviewMarkInput, type SkillEvalReviewMarkKind, type SkillEvalReviewResponse, type SkillEvalReviewRoom, type SkillEvalReviewerEligibilityInput, type SkillEvalRewardEvent, type SubmitSkillEvalReviewRequest, type TemplateVariable, TokenManager, WalletUtils, WebSocketAuthHelper, type WebSocketAuthHelperConfig, type X402ExecuteActionOptions, X402PaymentRequiredSDKError, type X402ReceiptListParams, type X402VerifyHandoffOptions, canAccessAdmin, createBrowserClient, createPermissionChecker, createServerClient, SPAPSClient as default, defaultPermissionChecker, detectKeyType, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount, isEnvelope, isErrorEnvelope, isSuccessEnvelope, unwrapEnvelope, unwrapNestedData, verifyCryptoWebhookSignature };
|
package/dist/index.d.ts
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, IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, IssueReportAttachmentOut, ListIssueReportAttachmentsResponse, IssueReportAttachmentAccessResponse, IssueReportingVoiceTokenResult, UpdateIssueReportRequest, ReplyIssueReportRequest, CreateAppLinkRequest, AppLink, AuthResponse, User as User$1, CreateCryptoInvoiceRequest, CryptoInvoiceStatusSnapshot, CheckoutSession, X402ResourceStatusResponse, X402ActionResponse, X402ReceiptResponse, X402ReceiptListResponse, X402HandoffVerification, DayrateAvailabilityResponse, DayrateBookingRequest, DayrateBookingResponse, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayrateX402BookingRequest, DayrateX402BookingResponse, DayrateCheckoutStatusResponse, UsageControlFeaturesResponse, UsageControlStatusRequest, UsageControlStatusResponse, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, Subscription, VerifyCryptoWebhookSignatureOptions } from 'spaps-types';
|
|
3
|
-
export { AdminPermission, AdminRole, AdminUser, ApiResponse, AppLink, AuthResponse, CheckoutSession, CreateAppLinkRequest, CreateCryptoInvoiceRequest, CreateIssueReportRequest, CreatePriceRequest, CreateProductRequest, CreateSecureMessageInput, CreateSecureMessageRequest, CryptoInvoice, CryptoInvoiceResponse, CryptoInvoiceStatusSnapshot, CryptoReconcileRequest, DayrateAvailabilityResponse, DayrateAvailableSlot, DayrateBookingRequest, DayrateBookingResponse, DayrateCheckoutStatus, DayrateCheckoutStatusBooking, DayrateCheckoutStatusResponse, DayrateDayOfWeek, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayratePriceBreakdown, DayrateSlotType, DayrateX402BookingRequest, DayrateX402BookingResponse, Entitlement, IssueReport, IssueReportAttachmentAccessResponse, IssueReportAttachmentOut, IssueReportListResult, IssueReportStatus, IssueReportStatusResult, IssueReportTarget, IssueReportingInputMode, IssueReportingVoiceProvider, IssueReportingVoiceTokenResult, LinkedIssueReportCase, ListIssueReportAttachmentsResponse, Price, Product, ProductSyncResult, ReplyIssueReportRequest, ResourceType, SecureMessage, SecureMessageOutput, Subscription, TokenPair, UpdateIssueReportRequest, UpdateProductRequest, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlDecision, UsageControlDimensions, UsageControlError, UsageControlErrorCode, UsageControlFeaturesResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, UsageControlLedgerEvent, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlRecordStatus, UsageControlStatusRequest, UsageControlStatusResponse, User, UserProfile, UserRole, UserWallet, VerifyCryptoWebhookSignatureOptions, X402ActionFreeResponse, X402ActionOutcome, X402ActionPendingResponse, X402ActionReplayedResponse, X402ActionResponse, X402ActionSettledResponse, X402ExecuteActionRequest, X402HandoffAuthorization, X402HandoffVerification, X402HandoffVerifyRequest, X402PaymentAccept, X402PaymentRequirement, X402ProjectionStatus, X402Receipt, X402ReceiptListResponse, X402ReceiptResponse, X402ReceiptStatus, X402Resource, X402ResourceStatus, X402ResourceStatusResponse, atomicToMoneyUnits, createSecureMessageRequestSchema, isX402PaymentRequired, isX402ResourceStatus, moneyUnitsToAtomic, roundHalfToPositiveInfinity, secureMessageMetadataSchema, secureMessageSchema, validatePositiveAmountAtomic } from 'spaps-types';
|
|
2
|
+
import { ResourceType, Entitlement, CreateProductRequest, Product, UpdateProductRequest, CreatePriceRequest, Price, ProductSyncResult, CryptoReconcileRequest, CreateSecureMessageRequest, SecureMessage, ListProjectGrantsResponse, ProjectAccessCheckResponse, IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, IssueReportAttachmentOut, ListIssueReportAttachmentsResponse, IssueReportAttachmentAccessResponse, IssueReportingVoiceTokenResult, UpdateIssueReportRequest, ReplyIssueReportRequest, ListIssueReportMessagesResponse, CreateReporterMessageRequest, IssueReportMessage, CreateOperatorMessageRequest, RetractOperatorMessageRequest, CreateAppLinkRequest, AppLink, UpdateAppLinkRequest, AuthResponse, User as User$1, CreateCryptoInvoiceRequest, CryptoInvoiceStatusSnapshot, CheckoutSession, X402ResourceStatusResponse, X402ActionResponse, X402ReceiptResponse, X402ReceiptListResponse, X402HandoffVerification, DayrateAvailabilityResponse, DayrateBookingRequest, DayrateBookingResponse, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayrateX402BookingRequest, DayrateX402BookingResponse, DayrateCheckoutStatusResponse, UsageControlFeaturesResponse, UsageControlStatusRequest, UsageControlStatusResponse, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, Subscription, VerifyCryptoWebhookSignatureOptions } from 'spaps-types';
|
|
3
|
+
export { AdminPermission, AdminRole, AdminUser, ApiResponse, AppLink, AuthResponse, CheckoutSession, CreateAppLinkRequest, CreateCryptoInvoiceRequest, CreateIssueReportRequest, CreateOperatorMessageRequest, CreatePriceRequest, CreateProductRequest, CreateReporterMessageRequest, CreateSecureMessageInput, CreateSecureMessageRequest, CryptoInvoice, CryptoInvoiceResponse, CryptoInvoiceStatusSnapshot, CryptoReconcileRequest, DayrateAvailabilityResponse, DayrateAvailableSlot, DayrateBookingRequest, DayrateBookingResponse, DayrateCheckoutStatus, DayrateCheckoutStatusBooking, DayrateCheckoutStatusResponse, DayrateDayOfWeek, DayrateMultiBookingRequest, DayrateMultiBookingResponse, DayratePriceBreakdown, DayrateSlotType, DayrateX402BookingRequest, DayrateX402BookingResponse, Entitlement, IssueReport, IssueReportAttachmentAccessResponse, IssueReportAttachmentOut, IssueReportListResult, IssueReportMessage, IssueReportStatus, IssueReportStatusResult, IssueReportTarget, IssueReportingInputMode, IssueReportingVoiceProvider, IssueReportingVoiceTokenResult, LinkedIssueReportCase, ListIssueReportAttachmentsResponse, ListIssueReportMessagesResponse, ListProjectGrantsResponse, Price, Product, ProductSyncResult, ProjectAccessCheckResponse, ProjectGrant, ProjectGrantStatus, ReplyIssueReportRequest, ResourceType, RetractOperatorMessageRequest, SecureMessage, SecureMessageOutput, Subscription, TokenPair, UpdateAppLinkRequest, UpdateIssueReportRequest, UpdateProductRequest, UsageControlAuthorizeRequest, UsageControlAuthorizeResponse, UsageControlDecision, UsageControlDimensions, UsageControlError, UsageControlErrorCode, UsageControlFeaturesResponse, UsageControlHistoryRequest, UsageControlHistoryResponse, UsageControlLedgerEvent, UsageControlRecordRequest, UsageControlRecordResponse, UsageControlRecordStatus, UsageControlStatusRequest, UsageControlStatusResponse, User, UserProfile, UserRole, UserWallet, VerifyCryptoWebhookSignatureOptions, X402ActionFreeResponse, X402ActionOutcome, X402ActionPendingResponse, X402ActionReplayedResponse, X402ActionResponse, X402ActionSettledResponse, X402ExecuteActionRequest, X402HandoffAuthorization, X402HandoffVerification, X402HandoffVerifyRequest, X402PaymentAccept, X402PaymentRequirement, X402ProjectionStatus, X402Receipt, X402ReceiptListResponse, X402ReceiptResponse, X402ReceiptStatus, X402Resource, X402ResourceStatus, X402ResourceStatusResponse, atomicToMoneyUnits, createSecureMessageRequestSchema, isX402PaymentRequired, isX402ResourceStatus, moneyUnitsToAtomic, roundHalfToPositiveInfinity, secureMessageMetadataSchema, secureMessageSchema, validatePositiveAmountAtomic } from 'spaps-types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Permission checking utilities for SPAPS SDK
|
|
@@ -336,6 +336,73 @@ interface EmailTemplatePreview {
|
|
|
336
336
|
html: string;
|
|
337
337
|
text?: string;
|
|
338
338
|
}
|
|
339
|
+
type MarketingEventType = 'attribution_touch' | 'experiment_exposure';
|
|
340
|
+
type MarketingExperimentRecommendation = 'continue' | 'continue_srm_warning' | 'stop_for_winner';
|
|
341
|
+
type MarketingExperimentSrmStatus = 'pass' | 'warning' | 'not_applicable';
|
|
342
|
+
interface MarketingEventIngestRequest {
|
|
343
|
+
application_id?: string;
|
|
344
|
+
anon_id: string;
|
|
345
|
+
event_type: MarketingEventType;
|
|
346
|
+
experiment_id?: string | null;
|
|
347
|
+
variant_id?: string | null;
|
|
348
|
+
variant?: string | null;
|
|
349
|
+
metadata?: Record<string, unknown> | null;
|
|
350
|
+
dedupe_key?: string | null;
|
|
351
|
+
timestamp?: string | null;
|
|
352
|
+
observed_at?: string | null;
|
|
353
|
+
}
|
|
354
|
+
interface MarketingEventIngestResponse {
|
|
355
|
+
id: string;
|
|
356
|
+
application_id: string;
|
|
357
|
+
anon_id: string;
|
|
358
|
+
event_type: MarketingEventType;
|
|
359
|
+
experiment_id?: string | null;
|
|
360
|
+
variant?: string | null;
|
|
361
|
+
dedupe_key: string;
|
|
362
|
+
ts: string;
|
|
363
|
+
created_at: string;
|
|
364
|
+
}
|
|
365
|
+
interface MarketingExperimentVariantResult {
|
|
366
|
+
variant_id: string | null;
|
|
367
|
+
exposures: number;
|
|
368
|
+
conversions: number;
|
|
369
|
+
conversion_rate: number;
|
|
370
|
+
revenue: Record<string, number>;
|
|
371
|
+
}
|
|
372
|
+
interface MarketingExperimentMinSampleDecision {
|
|
373
|
+
met: boolean;
|
|
374
|
+
min_exposures_per_variant: number;
|
|
375
|
+
min_total_conversions: number;
|
|
376
|
+
observed_min_exposures: number;
|
|
377
|
+
observed_total_conversions: number;
|
|
378
|
+
}
|
|
379
|
+
interface MarketingExperimentSrmDecision {
|
|
380
|
+
status: MarketingExperimentSrmStatus;
|
|
381
|
+
expected_share?: number | null;
|
|
382
|
+
max_share_ratio?: number | null;
|
|
383
|
+
min_share_ratio?: number | null;
|
|
384
|
+
}
|
|
385
|
+
interface MarketingExperimentEffectDecision {
|
|
386
|
+
leader_variant_id?: string | null;
|
|
387
|
+
runner_up_variant_id?: string | null;
|
|
388
|
+
absolute_lift?: number | null;
|
|
389
|
+
relative_lift?: number | null;
|
|
390
|
+
}
|
|
391
|
+
interface MarketingExperimentDecision {
|
|
392
|
+
decisive: boolean;
|
|
393
|
+
recommendation: MarketingExperimentRecommendation;
|
|
394
|
+
winner_variant_id?: string | null;
|
|
395
|
+
reason_codes: string[];
|
|
396
|
+
min_sample: MarketingExperimentMinSampleDecision;
|
|
397
|
+
srm: MarketingExperimentSrmDecision;
|
|
398
|
+
effect: MarketingExperimentEffectDecision;
|
|
399
|
+
}
|
|
400
|
+
interface MarketingExperimentResultsResponse {
|
|
401
|
+
application_id: string;
|
|
402
|
+
experiment_id: string;
|
|
403
|
+
variants: MarketingExperimentVariantResult[];
|
|
404
|
+
decision: MarketingExperimentDecision;
|
|
405
|
+
}
|
|
339
406
|
interface EntitlementListParams {
|
|
340
407
|
/** Filter by entitlement key */
|
|
341
408
|
key?: string;
|
|
@@ -350,6 +417,22 @@ interface EntitlementCheckResult {
|
|
|
350
417
|
/** The matching entitlement, if any */
|
|
351
418
|
entitlement?: Entitlement;
|
|
352
419
|
}
|
|
420
|
+
interface CurrentUserProjectGrantListParams {
|
|
421
|
+
/** Filter to one project entitlement key, such as "pds.project.viewer" */
|
|
422
|
+
entitlementKey?: string;
|
|
423
|
+
/** Maximum number of project grants to return */
|
|
424
|
+
limit?: number;
|
|
425
|
+
/** Zero-based item offset */
|
|
426
|
+
offset?: number;
|
|
427
|
+
/** Opaque pagination cursor */
|
|
428
|
+
cursor?: string;
|
|
429
|
+
}
|
|
430
|
+
interface CurrentUserProjectAccessParams {
|
|
431
|
+
/** Project to check */
|
|
432
|
+
projectId: string;
|
|
433
|
+
/** Project entitlement key to check, such as "pds.project.viewer" */
|
|
434
|
+
entitlementKey: string;
|
|
435
|
+
}
|
|
353
436
|
type SupportedIssueReportScope = Extract<IssueReportScope, 'mine'>;
|
|
354
437
|
interface IssueReportListParams {
|
|
355
438
|
status?: IssueReportStatus;
|
|
@@ -631,6 +714,7 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
631
714
|
private headerProvider?;
|
|
632
715
|
private unwrapApiResponse;
|
|
633
716
|
private skillEvalMutationConfig;
|
|
717
|
+
private requireCurrentUserIdFromAccessToken;
|
|
634
718
|
private isAxiosResponse;
|
|
635
719
|
private isResponseLikeWithData;
|
|
636
720
|
private isApiResponse;
|
|
@@ -708,10 +792,24 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
708
792
|
* Note: For publishable key contexts, only `resource_type=user` is permitted.
|
|
709
793
|
* Non-user resource types will return a 403 error (enforced server-side).
|
|
710
794
|
*
|
|
711
|
-
* @param resourceType - The resource type (e.g. "user", "company", "org", "system").
|
|
795
|
+
* @param resourceType - The resource type (e.g. "user", "company", "org", "system", "project").
|
|
712
796
|
* @param resourceId - Optional specific resource ID.
|
|
713
797
|
*/
|
|
714
798
|
listByResource: (resourceType: ResourceType, resourceId?: string) => Promise<Entitlement[]>;
|
|
799
|
+
/**
|
|
800
|
+
* List project grants for the authenticated user.
|
|
801
|
+
*
|
|
802
|
+
* Browser/publishable-key contexts are safe here because the server requires
|
|
803
|
+
* the JWT subject to match the path user id.
|
|
804
|
+
*/
|
|
805
|
+
listCurrentUserProjects: (params?: CurrentUserProjectGrantListParams) => Promise<ListProjectGrantsResponse>;
|
|
806
|
+
/**
|
|
807
|
+
* Check whether the authenticated user has one project entitlement.
|
|
808
|
+
*
|
|
809
|
+
* The helper does not accept user/email overrides; publishable-key callers
|
|
810
|
+
* are scoped by the server to the JWT identity.
|
|
811
|
+
*/
|
|
812
|
+
checkCurrentUserProjectAccess: (params: CurrentUserProjectAccessParams) => Promise<ProjectAccessCheckResponse>;
|
|
715
813
|
};
|
|
716
814
|
/**
|
|
717
815
|
* Issue reporting namespace for authenticated end-user issue flows.
|
|
@@ -744,6 +842,12 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
744
842
|
/**
|
|
745
843
|
* Return a short-lived private attachment access URL.
|
|
746
844
|
*/
|
|
845
|
+
getAttachmentAccess: (attachmentId: string) => Promise<IssueReportAttachmentAccessResponse>;
|
|
846
|
+
/**
|
|
847
|
+
* Return a short-lived private attachment access URL.
|
|
848
|
+
*
|
|
849
|
+
* @deprecated Use getAttachmentAccess(attachmentId).
|
|
850
|
+
*/
|
|
747
851
|
getAttachmentAccessUrl: (attachmentId: string) => Promise<IssueReportAttachmentAccessResponse>;
|
|
748
852
|
/**
|
|
749
853
|
* Soft-delete one owned screenshot attachment.
|
|
@@ -761,6 +865,46 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
761
865
|
* Reply to a resolved or ignored issue report and reopen the linked case.
|
|
762
866
|
*/
|
|
763
867
|
reply: (issueReportId: string, payload: ReplyIssueReportRequest) => Promise<IssueReport>;
|
|
868
|
+
/**
|
|
869
|
+
* List the chronological, reporter-visible message thread for one owned
|
|
870
|
+
* issue report. Only active, reporter-visible rows are returned; retracted
|
|
871
|
+
* or superseded operator messages are excluded and raw audit payloads are
|
|
872
|
+
* never exposed. `needs_response` badges an open clarification request.
|
|
873
|
+
*/
|
|
874
|
+
listMessages: (issueReportId: string) => Promise<ListIssueReportMessagesResponse>;
|
|
875
|
+
/**
|
|
876
|
+
* Submit a reporter clarification response on one owned issue report. This
|
|
877
|
+
* does NOT reopen a closed case (use `reply` for that). Idempotent on
|
|
878
|
+
* `idempotency_key`: same key + same body returns the existing message,
|
|
879
|
+
* same key + different body returns 409 ISSUE_REPORT_MESSAGE_CONFLICT.
|
|
880
|
+
*/
|
|
881
|
+
submitMessage: (issueReportId: string, payload: CreateReporterMessageRequest) => Promise<IssueReportMessage>;
|
|
882
|
+
/**
|
|
883
|
+
* Triage-operator message commands. These require a secret key context and a
|
|
884
|
+
* triage role/capability; publishable browser contexts are rejected by the
|
|
885
|
+
* server. Provide the secret key as the SDK's API key.
|
|
886
|
+
*/
|
|
887
|
+
triage: {
|
|
888
|
+
/**
|
|
889
|
+
* List all projection rows for an app-scoped report (including corrected
|
|
890
|
+
* rows) for authorized triage operators.
|
|
891
|
+
*/
|
|
892
|
+
listMessages: (issueReportId: string) => Promise<ListIssueReportMessagesResponse>;
|
|
893
|
+
/**
|
|
894
|
+
* Post a clarification_request or final_response reporter-visible message
|
|
895
|
+
* as a triage operator. Idempotent on `idempotency_key`; a key reused with
|
|
896
|
+
* a different body returns 409. A final_response can drive a terminal
|
|
897
|
+
* lifecycle transition via `resolve_case`; the internal resolution_note is
|
|
898
|
+
* never auto-displayed to reporters.
|
|
899
|
+
*/
|
|
900
|
+
postMessage: (issueReportId: string, payload: CreateOperatorMessageRequest) => Promise<IssueReportMessage>;
|
|
901
|
+
/**
|
|
902
|
+
* Retract an operator-authored message. The body is retained; the row's
|
|
903
|
+
* state is marked `retracted`. Retracting an already-retracted message is
|
|
904
|
+
* a safe no-op.
|
|
905
|
+
*/
|
|
906
|
+
retractMessage: (issueReportId: string, messageId: string, payload?: RetractOperatorMessageRequest) => Promise<IssueReportMessage>;
|
|
907
|
+
};
|
|
764
908
|
};
|
|
765
909
|
/**
|
|
766
910
|
* Application-scoped short links for browser apps that need stable public URLs.
|
|
@@ -770,6 +914,10 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
770
914
|
* Create a short link owned by the authenticated user.
|
|
771
915
|
*/
|
|
772
916
|
create: (payload: CreateAppLinkRequest) => Promise<AppLink>;
|
|
917
|
+
/**
|
|
918
|
+
* Update a short link owned by the authenticated user.
|
|
919
|
+
*/
|
|
920
|
+
update: (username: string, slug: string, payload: UpdateAppLinkRequest) => Promise<AppLink>;
|
|
773
921
|
/**
|
|
774
922
|
* Resolve a public short link for the active application.
|
|
775
923
|
*/
|
|
@@ -777,6 +925,30 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
777
925
|
track?: boolean;
|
|
778
926
|
}) => Promise<AppLink>;
|
|
779
927
|
};
|
|
928
|
+
/**
|
|
929
|
+
* Marketing events and experiment results.
|
|
930
|
+
*
|
|
931
|
+
* Use a publishable key for browser-side event emission. Use a secret key
|
|
932
|
+
* from a trusted server or agent process when reading experiment results.
|
|
933
|
+
*/
|
|
934
|
+
marketing: {
|
|
935
|
+
/**
|
|
936
|
+
* Emit one anonymous attribution touch or experiment exposure.
|
|
937
|
+
*/
|
|
938
|
+
emit: (payload: MarketingEventIngestRequest) => Promise<MarketingEventIngestResponse>;
|
|
939
|
+
/**
|
|
940
|
+
* Alias for emit(), matching the backend ingest endpoint language.
|
|
941
|
+
*/
|
|
942
|
+
ingest: (payload: MarketingEventIngestRequest) => Promise<MarketingEventIngestResponse>;
|
|
943
|
+
/**
|
|
944
|
+
* Read per-variant experiment results and the conservative stop signal.
|
|
945
|
+
*/
|
|
946
|
+
getExperimentResults: (experimentId: string) => Promise<MarketingExperimentResultsResponse>;
|
|
947
|
+
/**
|
|
948
|
+
* Short alias for getExperimentResults().
|
|
949
|
+
*/
|
|
950
|
+
getResults: (experimentId: string) => Promise<MarketingExperimentResultsResponse>;
|
|
951
|
+
};
|
|
780
952
|
private static envVar;
|
|
781
953
|
constructor(config?: SPAPSConfig);
|
|
782
954
|
/** Raw API request helper that returns an ApiResponse-like shape */
|
|
@@ -1154,6 +1326,8 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
|
|
|
1154
1326
|
recordUsage(payload: UsageControlRecordRequest): Promise<UsageControlRecordResponse>;
|
|
1155
1327
|
getUsageStatus(query: UsageControlStatusRequest): Promise<UsageControlStatusResponse>;
|
|
1156
1328
|
listUsageHistory(query?: UsageControlHistoryRequest): Promise<UsageControlHistoryResponse>;
|
|
1329
|
+
emitMarketingEvent(payload: MarketingEventIngestRequest): Promise<MarketingEventIngestResponse>;
|
|
1330
|
+
getMarketingExperimentResults(experimentId: string): Promise<MarketingExperimentResultsResponse>;
|
|
1157
1331
|
private createSecureMessage;
|
|
1158
1332
|
private listSecureMessages;
|
|
1159
1333
|
/**
|
|
@@ -1335,4 +1509,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
|
|
|
1335
1509
|
*/
|
|
1336
1510
|
declare function detectKeyType(key: string): ApiKeyType | null;
|
|
1337
1511
|
|
|
1338
|
-
export { type AdminConfig, type ApiKeyType, type CheckoutLineItem, type CheckoutLineItemPriceData, type CreateCheckoutSessionPayload, type CreateSkillEvalCaseRequest, type CreateSkillEvalGovernanceSnapshotRequest, DEFAULT_ADMIN_ACCOUNTS, type EmailSendOptions, type EmailSendResult, type EmailTemplate, type EmailTemplatePreview, type EntitlementCheckResult, type EntitlementListParams, type FeatureContext, type FeatureDefinition, FeatureEvaluator, type HeaderProvider, type ImportSkillEvalGovernanceOutcomeRequest, type IssueReportAttachmentUploadOptions, type IssueReportListParams, type IssueReportStatusParams, type PermissionCheckResult, PermissionChecker, type RespondToSkillEvalReviewRequest, type RevealSkillEvalEvidenceRequest, RoleHierarchy, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type SPAPSEnvelope, type SkillEvalAccessMode, type SkillEvalActorAccess, type SkillEvalCandidateInput, type SkillEvalCandidateResponse, type SkillEvalCasePolicy, type SkillEvalCaseResponse, type SkillEvalConfidence, type SkillEvalCreateOptions, type SkillEvalDisclosurePolicy, type SkillEvalEligibilitySource, type SkillEvalGovernanceOutcomeResult, type SkillEvalGovernancePurpose, type SkillEvalGovernanceSnapshotResult, type SkillEvalInsight, type SkillEvalInsightsResponse, type SkillEvalModelEffort, type SkillEvalMutationOptions, type SkillEvalPosterResponse, type SkillEvalPosterResponseResult, type SkillEvalRevealField, type SkillEvalRevealResult, type SkillEvalReviewMarkInput, type SkillEvalReviewMarkKind, type SkillEvalReviewResponse, type SkillEvalReviewRoom, type SkillEvalReviewerEligibilityInput, type SkillEvalRewardEvent, type SubmitSkillEvalReviewRequest, type TemplateVariable, TokenManager, WalletUtils, WebSocketAuthHelper, type WebSocketAuthHelperConfig, type X402ExecuteActionOptions, X402PaymentRequiredSDKError, type X402ReceiptListParams, type X402VerifyHandoffOptions, canAccessAdmin, createBrowserClient, createPermissionChecker, createServerClient, SPAPSClient as default, defaultPermissionChecker, detectKeyType, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount, isEnvelope, isErrorEnvelope, isSuccessEnvelope, unwrapEnvelope, unwrapNestedData, verifyCryptoWebhookSignature };
|
|
1512
|
+
export { type AdminConfig, type ApiKeyType, type CheckoutLineItem, type CheckoutLineItemPriceData, type CreateCheckoutSessionPayload, type CreateSkillEvalCaseRequest, type CreateSkillEvalGovernanceSnapshotRequest, type CurrentUserProjectAccessParams, type CurrentUserProjectGrantListParams, DEFAULT_ADMIN_ACCOUNTS, type EmailSendOptions, type EmailSendResult, type EmailTemplate, type EmailTemplatePreview, type EntitlementCheckResult, type EntitlementListParams, type FeatureContext, type FeatureDefinition, FeatureEvaluator, type HeaderProvider, type ImportSkillEvalGovernanceOutcomeRequest, type IssueReportAttachmentUploadOptions, type IssueReportListParams, type IssueReportStatusParams, type MarketingEventIngestRequest, type MarketingEventIngestResponse, type MarketingEventType, type MarketingExperimentDecision, type MarketingExperimentEffectDecision, type MarketingExperimentMinSampleDecision, type MarketingExperimentRecommendation, type MarketingExperimentResultsResponse, type MarketingExperimentSrmDecision, type MarketingExperimentSrmStatus, type MarketingExperimentVariantResult, type PermissionCheckResult, PermissionChecker, type RespondToSkillEvalReviewRequest, type RevealSkillEvalEvidenceRequest, RoleHierarchy, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type SPAPSEnvelope, type SkillEvalAccessMode, type SkillEvalActorAccess, type SkillEvalCandidateInput, type SkillEvalCandidateResponse, type SkillEvalCasePolicy, type SkillEvalCaseResponse, type SkillEvalConfidence, type SkillEvalCreateOptions, type SkillEvalDisclosurePolicy, type SkillEvalEligibilitySource, type SkillEvalGovernanceOutcomeResult, type SkillEvalGovernancePurpose, type SkillEvalGovernanceSnapshotResult, type SkillEvalInsight, type SkillEvalInsightsResponse, type SkillEvalModelEffort, type SkillEvalMutationOptions, type SkillEvalPosterResponse, type SkillEvalPosterResponseResult, type SkillEvalRevealField, type SkillEvalRevealResult, type SkillEvalReviewMarkInput, type SkillEvalReviewMarkKind, type SkillEvalReviewResponse, type SkillEvalReviewRoom, type SkillEvalReviewerEligibilityInput, type SkillEvalRewardEvent, type SubmitSkillEvalReviewRequest, type TemplateVariable, TokenManager, WalletUtils, WebSocketAuthHelper, type WebSocketAuthHelperConfig, type X402ExecuteActionOptions, X402PaymentRequiredSDKError, type X402ReceiptListParams, type X402VerifyHandoffOptions, canAccessAdmin, createBrowserClient, createPermissionChecker, createServerClient, SPAPSClient as default, defaultPermissionChecker, detectKeyType, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount, isEnvelope, isErrorEnvelope, isSuccessEnvelope, unwrapEnvelope, unwrapNestedData, verifyCryptoWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -563,6 +563,17 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
563
563
|
}
|
|
564
564
|
return { headers: { "If-Match": String(ifMatch) } };
|
|
565
565
|
}
|
|
566
|
+
requireCurrentUserIdFromAccessToken() {
|
|
567
|
+
if (!this.accessToken) {
|
|
568
|
+
throw new Error("Authentication required. Please authenticate first.");
|
|
569
|
+
}
|
|
570
|
+
const payload = TokenManager.decodePayload(this.accessToken);
|
|
571
|
+
const userId = payload?.user_id ?? payload?.sub;
|
|
572
|
+
if (typeof userId !== "string" || userId.length === 0) {
|
|
573
|
+
throw new Error("Current user id not found in access token.");
|
|
574
|
+
}
|
|
575
|
+
return userId;
|
|
576
|
+
}
|
|
566
577
|
isAxiosResponse(value) {
|
|
567
578
|
if (!value || typeof value !== "object") {
|
|
568
579
|
return false;
|
|
@@ -672,7 +683,7 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
672
683
|
* @param userId - Optional user ID override (secret key contexts only).
|
|
673
684
|
*/
|
|
674
685
|
check: async (key, userId) => {
|
|
675
|
-
const q = new URLSearchParams({ key });
|
|
686
|
+
const q = new URLSearchParams({ entitlement_key: key });
|
|
676
687
|
if (userId) q.append("user_id", userId);
|
|
677
688
|
const res = await this.client.get(
|
|
678
689
|
`/api/entitlements/check?${q.toString()}`,
|
|
@@ -686,7 +697,7 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
686
697
|
* Note: For publishable key contexts, only `resource_type=user` is permitted.
|
|
687
698
|
* Non-user resource types will return a 403 error (enforced server-side).
|
|
688
699
|
*
|
|
689
|
-
* @param resourceType - The resource type (e.g. "user", "company", "org", "system").
|
|
700
|
+
* @param resourceType - The resource type (e.g. "user", "company", "org", "system", "project").
|
|
690
701
|
* @param resourceId - Optional specific resource ID.
|
|
691
702
|
*/
|
|
692
703
|
listByResource: async (resourceType, resourceId) => {
|
|
@@ -701,6 +712,46 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
701
712
|
return payload.entitlements;
|
|
702
713
|
}
|
|
703
714
|
return payload;
|
|
715
|
+
},
|
|
716
|
+
/**
|
|
717
|
+
* List project grants for the authenticated user.
|
|
718
|
+
*
|
|
719
|
+
* Browser/publishable-key contexts are safe here because the server requires
|
|
720
|
+
* the JWT subject to match the path user id.
|
|
721
|
+
*/
|
|
722
|
+
listCurrentUserProjects: async (params) => {
|
|
723
|
+
const userId = this.requireCurrentUserIdFromAccessToken();
|
|
724
|
+
const q = new URLSearchParams();
|
|
725
|
+
if (params?.entitlementKey) q.append("entitlement_key", params.entitlementKey);
|
|
726
|
+
if (params?.limit !== void 0) q.append("limit", String(params.limit));
|
|
727
|
+
if (params?.offset !== void 0) q.append("offset", String(params.offset));
|
|
728
|
+
if (params?.cursor) q.append("cursor", params.cursor);
|
|
729
|
+
const qs = q.toString();
|
|
730
|
+
const res = await this.client.get(
|
|
731
|
+
`/api/project-grants/user/${encodeURIComponent(userId)}/projects${qs ? `?${qs}` : ""}`,
|
|
732
|
+
{ headers: { Authorization: `Bearer ${this.accessToken}` } }
|
|
733
|
+
);
|
|
734
|
+
return this.unwrapApiResponse(res, "Failed to list current user project grants");
|
|
735
|
+
},
|
|
736
|
+
/**
|
|
737
|
+
* Check whether the authenticated user has one project entitlement.
|
|
738
|
+
*
|
|
739
|
+
* The helper does not accept user/email overrides; publishable-key callers
|
|
740
|
+
* are scoped by the server to the JWT identity.
|
|
741
|
+
*/
|
|
742
|
+
checkCurrentUserProjectAccess: async (params) => {
|
|
743
|
+
if (!this.accessToken) {
|
|
744
|
+
throw new Error("Authentication required. Please authenticate first.");
|
|
745
|
+
}
|
|
746
|
+
const q = new URLSearchParams({
|
|
747
|
+
project_id: params.projectId,
|
|
748
|
+
entitlement_key: params.entitlementKey
|
|
749
|
+
});
|
|
750
|
+
const res = await this.client.get(
|
|
751
|
+
`/api/project-grants/check?${q.toString()}`,
|
|
752
|
+
{ headers: { Authorization: `Bearer ${this.accessToken}` } }
|
|
753
|
+
);
|
|
754
|
+
return this.unwrapApiResponse(res, "Failed to check current user project access");
|
|
704
755
|
}
|
|
705
756
|
};
|
|
706
757
|
/**
|
|
@@ -793,7 +844,7 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
793
844
|
/**
|
|
794
845
|
* Return a short-lived private attachment access URL.
|
|
795
846
|
*/
|
|
796
|
-
|
|
847
|
+
getAttachmentAccess: async (attachmentId) => {
|
|
797
848
|
const res = await this.client.get(
|
|
798
849
|
`/api/v1/issue-reports/attachments/${encodeURIComponent(attachmentId)}/access`,
|
|
799
850
|
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
@@ -803,6 +854,14 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
803
854
|
"Failed to get issue report attachment access URL"
|
|
804
855
|
);
|
|
805
856
|
},
|
|
857
|
+
/**
|
|
858
|
+
* Return a short-lived private attachment access URL.
|
|
859
|
+
*
|
|
860
|
+
* @deprecated Use getAttachmentAccess(attachmentId).
|
|
861
|
+
*/
|
|
862
|
+
getAttachmentAccessUrl: async (attachmentId) => {
|
|
863
|
+
return this.issueReporting.getAttachmentAccess(attachmentId);
|
|
864
|
+
},
|
|
806
865
|
/**
|
|
807
866
|
* Soft-delete one owned screenshot attachment.
|
|
808
867
|
*/
|
|
@@ -844,6 +903,82 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
844
903
|
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
845
904
|
);
|
|
846
905
|
return this.unwrapApiResponse(res, "Failed to reply to issue report");
|
|
906
|
+
},
|
|
907
|
+
/**
|
|
908
|
+
* List the chronological, reporter-visible message thread for one owned
|
|
909
|
+
* issue report. Only active, reporter-visible rows are returned; retracted
|
|
910
|
+
* or superseded operator messages are excluded and raw audit payloads are
|
|
911
|
+
* never exposed. `needs_response` badges an open clarification request.
|
|
912
|
+
*/
|
|
913
|
+
listMessages: async (issueReportId) => {
|
|
914
|
+
const res = await this.client.get(
|
|
915
|
+
`/api/v1/issue-reports/${issueReportId}/messages`,
|
|
916
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
917
|
+
);
|
|
918
|
+
return this.unwrapApiResponse(res, "Failed to list issue report messages");
|
|
919
|
+
},
|
|
920
|
+
/**
|
|
921
|
+
* Submit a reporter clarification response on one owned issue report. This
|
|
922
|
+
* does NOT reopen a closed case (use `reply` for that). Idempotent on
|
|
923
|
+
* `idempotency_key`: same key + same body returns the existing message,
|
|
924
|
+
* same key + different body returns 409 ISSUE_REPORT_MESSAGE_CONFLICT.
|
|
925
|
+
*/
|
|
926
|
+
submitMessage: async (issueReportId, payload) => {
|
|
927
|
+
const res = await this.client.post(
|
|
928
|
+
`/api/v1/issue-reports/${issueReportId}/messages`,
|
|
929
|
+
payload,
|
|
930
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
931
|
+
);
|
|
932
|
+
return this.unwrapApiResponse(res, "Failed to submit issue report message");
|
|
933
|
+
},
|
|
934
|
+
/**
|
|
935
|
+
* Triage-operator message commands. These require a secret key context and a
|
|
936
|
+
* triage role/capability; publishable browser contexts are rejected by the
|
|
937
|
+
* server. Provide the secret key as the SDK's API key.
|
|
938
|
+
*/
|
|
939
|
+
triage: {
|
|
940
|
+
/**
|
|
941
|
+
* List all projection rows for an app-scoped report (including corrected
|
|
942
|
+
* rows) for authorized triage operators.
|
|
943
|
+
*/
|
|
944
|
+
listMessages: async (issueReportId) => {
|
|
945
|
+
const res = await this.client.get(
|
|
946
|
+
`/api/v1/issue-reports/triage/${issueReportId}/messages`,
|
|
947
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
948
|
+
);
|
|
949
|
+
return this.unwrapApiResponse(
|
|
950
|
+
res,
|
|
951
|
+
"Failed to list triage issue report messages"
|
|
952
|
+
);
|
|
953
|
+
},
|
|
954
|
+
/**
|
|
955
|
+
* Post a clarification_request or final_response reporter-visible message
|
|
956
|
+
* as a triage operator. Idempotent on `idempotency_key`; a key reused with
|
|
957
|
+
* a different body returns 409. A final_response can drive a terminal
|
|
958
|
+
* lifecycle transition via `resolve_case`; the internal resolution_note is
|
|
959
|
+
* never auto-displayed to reporters.
|
|
960
|
+
*/
|
|
961
|
+
postMessage: async (issueReportId, payload) => {
|
|
962
|
+
const res = await this.client.post(
|
|
963
|
+
`/api/v1/issue-reports/triage/${issueReportId}/messages`,
|
|
964
|
+
payload,
|
|
965
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
966
|
+
);
|
|
967
|
+
return this.unwrapApiResponse(res, "Failed to post triage issue report message");
|
|
968
|
+
},
|
|
969
|
+
/**
|
|
970
|
+
* Retract an operator-authored message. The body is retained; the row's
|
|
971
|
+
* state is marked `retracted`. Retracting an already-retracted message is
|
|
972
|
+
* a safe no-op.
|
|
973
|
+
*/
|
|
974
|
+
retractMessage: async (issueReportId, messageId, payload = {}) => {
|
|
975
|
+
const res = await this.client.post(
|
|
976
|
+
`/api/v1/issue-reports/triage/${issueReportId}/messages/${messageId}/retract`,
|
|
977
|
+
payload,
|
|
978
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
979
|
+
);
|
|
980
|
+
return this.unwrapApiResponse(res, "Failed to retract triage issue report message");
|
|
981
|
+
}
|
|
847
982
|
}
|
|
848
983
|
};
|
|
849
984
|
/**
|
|
@@ -861,6 +996,17 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
861
996
|
);
|
|
862
997
|
return this.unwrapApiResponse(res, "Failed to create app link");
|
|
863
998
|
},
|
|
999
|
+
/**
|
|
1000
|
+
* Update a short link owned by the authenticated user.
|
|
1001
|
+
*/
|
|
1002
|
+
update: async (username, slug, payload) => {
|
|
1003
|
+
const res = await this.client.patch(
|
|
1004
|
+
`/api/v1/app-links/${encodeURIComponent(username)}/${encodeURIComponent(slug)}`,
|
|
1005
|
+
payload,
|
|
1006
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
1007
|
+
);
|
|
1008
|
+
return this.unwrapApiResponse(res, "Failed to update app link");
|
|
1009
|
+
},
|
|
864
1010
|
/**
|
|
865
1011
|
* Resolve a public short link for the active application.
|
|
866
1012
|
*/
|
|
@@ -875,6 +1021,58 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
875
1021
|
return this.unwrapApiResponse(res, "Failed to get app link");
|
|
876
1022
|
}
|
|
877
1023
|
};
|
|
1024
|
+
/**
|
|
1025
|
+
* Marketing events and experiment results.
|
|
1026
|
+
*
|
|
1027
|
+
* Use a publishable key for browser-side event emission. Use a secret key
|
|
1028
|
+
* from a trusted server or agent process when reading experiment results.
|
|
1029
|
+
*/
|
|
1030
|
+
marketing = {
|
|
1031
|
+
/**
|
|
1032
|
+
* Emit one anonymous attribution touch or experiment exposure.
|
|
1033
|
+
*/
|
|
1034
|
+
emit: async (payload) => {
|
|
1035
|
+
if (payload.event_type === "experiment_exposure") {
|
|
1036
|
+
if (!payload.experiment_id?.trim()) {
|
|
1037
|
+
throw new Error("experiment_id is required for experiment_exposure events");
|
|
1038
|
+
}
|
|
1039
|
+
const variant = payload.variant_id ?? payload.variant;
|
|
1040
|
+
if (!variant?.trim()) {
|
|
1041
|
+
throw new Error("variant_id or variant is required for experiment_exposure events");
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
const res = await this.client.post("/api/marketing-events/ingest", payload);
|
|
1045
|
+
return this.unwrapApiResponse(
|
|
1046
|
+
res,
|
|
1047
|
+
"Failed to emit marketing event"
|
|
1048
|
+
);
|
|
1049
|
+
},
|
|
1050
|
+
/**
|
|
1051
|
+
* Alias for emit(), matching the backend ingest endpoint language.
|
|
1052
|
+
*/
|
|
1053
|
+
ingest: async (payload) => {
|
|
1054
|
+
return this.marketing.emit(payload);
|
|
1055
|
+
},
|
|
1056
|
+
/**
|
|
1057
|
+
* Read per-variant experiment results and the conservative stop signal.
|
|
1058
|
+
*/
|
|
1059
|
+
getExperimentResults: async (experimentId) => {
|
|
1060
|
+
const encodedExperimentId = encodeURIComponent(experimentId);
|
|
1061
|
+
const res = await this.client.get(
|
|
1062
|
+
`/api/marketing/experiments/${encodedExperimentId}/results`
|
|
1063
|
+
);
|
|
1064
|
+
return this.unwrapApiResponse(
|
|
1065
|
+
res,
|
|
1066
|
+
"Failed to get marketing experiment results"
|
|
1067
|
+
);
|
|
1068
|
+
},
|
|
1069
|
+
/**
|
|
1070
|
+
* Short alias for getExperimentResults().
|
|
1071
|
+
*/
|
|
1072
|
+
getResults: async (experimentId) => {
|
|
1073
|
+
return this.marketing.getExperimentResults(experimentId);
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
878
1076
|
static envVar(name) {
|
|
879
1077
|
if (typeof process !== "undefined" && process.env) {
|
|
880
1078
|
return process.env[name];
|
|
@@ -1763,6 +1961,12 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
1763
1961
|
async listUsageHistory(query = {}) {
|
|
1764
1962
|
return this.usage.listHistory(query);
|
|
1765
1963
|
}
|
|
1964
|
+
async emitMarketingEvent(payload) {
|
|
1965
|
+
return this.marketing.emit(payload);
|
|
1966
|
+
}
|
|
1967
|
+
async getMarketingExperimentResults(experimentId) {
|
|
1968
|
+
return this.marketing.getExperimentResults(experimentId);
|
|
1969
|
+
}
|
|
1766
1970
|
// Secure Messaging Methods
|
|
1767
1971
|
async createSecureMessage(payload) {
|
|
1768
1972
|
const response = await this.client.post("/api/secure-messages", payload);
|
package/dist/index.mjs
CHANGED
|
@@ -528,6 +528,17 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
528
528
|
}
|
|
529
529
|
return { headers: { "If-Match": String(ifMatch) } };
|
|
530
530
|
}
|
|
531
|
+
requireCurrentUserIdFromAccessToken() {
|
|
532
|
+
if (!this.accessToken) {
|
|
533
|
+
throw new Error("Authentication required. Please authenticate first.");
|
|
534
|
+
}
|
|
535
|
+
const payload = TokenManager.decodePayload(this.accessToken);
|
|
536
|
+
const userId = payload?.user_id ?? payload?.sub;
|
|
537
|
+
if (typeof userId !== "string" || userId.length === 0) {
|
|
538
|
+
throw new Error("Current user id not found in access token.");
|
|
539
|
+
}
|
|
540
|
+
return userId;
|
|
541
|
+
}
|
|
531
542
|
isAxiosResponse(value) {
|
|
532
543
|
if (!value || typeof value !== "object") {
|
|
533
544
|
return false;
|
|
@@ -637,7 +648,7 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
637
648
|
* @param userId - Optional user ID override (secret key contexts only).
|
|
638
649
|
*/
|
|
639
650
|
check: async (key, userId) => {
|
|
640
|
-
const q = new URLSearchParams({ key });
|
|
651
|
+
const q = new URLSearchParams({ entitlement_key: key });
|
|
641
652
|
if (userId) q.append("user_id", userId);
|
|
642
653
|
const res = await this.client.get(
|
|
643
654
|
`/api/entitlements/check?${q.toString()}`,
|
|
@@ -651,7 +662,7 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
651
662
|
* Note: For publishable key contexts, only `resource_type=user` is permitted.
|
|
652
663
|
* Non-user resource types will return a 403 error (enforced server-side).
|
|
653
664
|
*
|
|
654
|
-
* @param resourceType - The resource type (e.g. "user", "company", "org", "system").
|
|
665
|
+
* @param resourceType - The resource type (e.g. "user", "company", "org", "system", "project").
|
|
655
666
|
* @param resourceId - Optional specific resource ID.
|
|
656
667
|
*/
|
|
657
668
|
listByResource: async (resourceType, resourceId) => {
|
|
@@ -666,6 +677,46 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
666
677
|
return payload.entitlements;
|
|
667
678
|
}
|
|
668
679
|
return payload;
|
|
680
|
+
},
|
|
681
|
+
/**
|
|
682
|
+
* List project grants for the authenticated user.
|
|
683
|
+
*
|
|
684
|
+
* Browser/publishable-key contexts are safe here because the server requires
|
|
685
|
+
* the JWT subject to match the path user id.
|
|
686
|
+
*/
|
|
687
|
+
listCurrentUserProjects: async (params) => {
|
|
688
|
+
const userId = this.requireCurrentUserIdFromAccessToken();
|
|
689
|
+
const q = new URLSearchParams();
|
|
690
|
+
if (params?.entitlementKey) q.append("entitlement_key", params.entitlementKey);
|
|
691
|
+
if (params?.limit !== void 0) q.append("limit", String(params.limit));
|
|
692
|
+
if (params?.offset !== void 0) q.append("offset", String(params.offset));
|
|
693
|
+
if (params?.cursor) q.append("cursor", params.cursor);
|
|
694
|
+
const qs = q.toString();
|
|
695
|
+
const res = await this.client.get(
|
|
696
|
+
`/api/project-grants/user/${encodeURIComponent(userId)}/projects${qs ? `?${qs}` : ""}`,
|
|
697
|
+
{ headers: { Authorization: `Bearer ${this.accessToken}` } }
|
|
698
|
+
);
|
|
699
|
+
return this.unwrapApiResponse(res, "Failed to list current user project grants");
|
|
700
|
+
},
|
|
701
|
+
/**
|
|
702
|
+
* Check whether the authenticated user has one project entitlement.
|
|
703
|
+
*
|
|
704
|
+
* The helper does not accept user/email overrides; publishable-key callers
|
|
705
|
+
* are scoped by the server to the JWT identity.
|
|
706
|
+
*/
|
|
707
|
+
checkCurrentUserProjectAccess: async (params) => {
|
|
708
|
+
if (!this.accessToken) {
|
|
709
|
+
throw new Error("Authentication required. Please authenticate first.");
|
|
710
|
+
}
|
|
711
|
+
const q = new URLSearchParams({
|
|
712
|
+
project_id: params.projectId,
|
|
713
|
+
entitlement_key: params.entitlementKey
|
|
714
|
+
});
|
|
715
|
+
const res = await this.client.get(
|
|
716
|
+
`/api/project-grants/check?${q.toString()}`,
|
|
717
|
+
{ headers: { Authorization: `Bearer ${this.accessToken}` } }
|
|
718
|
+
);
|
|
719
|
+
return this.unwrapApiResponse(res, "Failed to check current user project access");
|
|
669
720
|
}
|
|
670
721
|
};
|
|
671
722
|
/**
|
|
@@ -758,7 +809,7 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
758
809
|
/**
|
|
759
810
|
* Return a short-lived private attachment access URL.
|
|
760
811
|
*/
|
|
761
|
-
|
|
812
|
+
getAttachmentAccess: async (attachmentId) => {
|
|
762
813
|
const res = await this.client.get(
|
|
763
814
|
`/api/v1/issue-reports/attachments/${encodeURIComponent(attachmentId)}/access`,
|
|
764
815
|
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
@@ -768,6 +819,14 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
768
819
|
"Failed to get issue report attachment access URL"
|
|
769
820
|
);
|
|
770
821
|
},
|
|
822
|
+
/**
|
|
823
|
+
* Return a short-lived private attachment access URL.
|
|
824
|
+
*
|
|
825
|
+
* @deprecated Use getAttachmentAccess(attachmentId).
|
|
826
|
+
*/
|
|
827
|
+
getAttachmentAccessUrl: async (attachmentId) => {
|
|
828
|
+
return this.issueReporting.getAttachmentAccess(attachmentId);
|
|
829
|
+
},
|
|
771
830
|
/**
|
|
772
831
|
* Soft-delete one owned screenshot attachment.
|
|
773
832
|
*/
|
|
@@ -809,6 +868,82 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
809
868
|
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
810
869
|
);
|
|
811
870
|
return this.unwrapApiResponse(res, "Failed to reply to issue report");
|
|
871
|
+
},
|
|
872
|
+
/**
|
|
873
|
+
* List the chronological, reporter-visible message thread for one owned
|
|
874
|
+
* issue report. Only active, reporter-visible rows are returned; retracted
|
|
875
|
+
* or superseded operator messages are excluded and raw audit payloads are
|
|
876
|
+
* never exposed. `needs_response` badges an open clarification request.
|
|
877
|
+
*/
|
|
878
|
+
listMessages: async (issueReportId) => {
|
|
879
|
+
const res = await this.client.get(
|
|
880
|
+
`/api/v1/issue-reports/${issueReportId}/messages`,
|
|
881
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
882
|
+
);
|
|
883
|
+
return this.unwrapApiResponse(res, "Failed to list issue report messages");
|
|
884
|
+
},
|
|
885
|
+
/**
|
|
886
|
+
* Submit a reporter clarification response on one owned issue report. This
|
|
887
|
+
* does NOT reopen a closed case (use `reply` for that). Idempotent on
|
|
888
|
+
* `idempotency_key`: same key + same body returns the existing message,
|
|
889
|
+
* same key + different body returns 409 ISSUE_REPORT_MESSAGE_CONFLICT.
|
|
890
|
+
*/
|
|
891
|
+
submitMessage: async (issueReportId, payload) => {
|
|
892
|
+
const res = await this.client.post(
|
|
893
|
+
`/api/v1/issue-reports/${issueReportId}/messages`,
|
|
894
|
+
payload,
|
|
895
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
896
|
+
);
|
|
897
|
+
return this.unwrapApiResponse(res, "Failed to submit issue report message");
|
|
898
|
+
},
|
|
899
|
+
/**
|
|
900
|
+
* Triage-operator message commands. These require a secret key context and a
|
|
901
|
+
* triage role/capability; publishable browser contexts are rejected by the
|
|
902
|
+
* server. Provide the secret key as the SDK's API key.
|
|
903
|
+
*/
|
|
904
|
+
triage: {
|
|
905
|
+
/**
|
|
906
|
+
* List all projection rows for an app-scoped report (including corrected
|
|
907
|
+
* rows) for authorized triage operators.
|
|
908
|
+
*/
|
|
909
|
+
listMessages: async (issueReportId) => {
|
|
910
|
+
const res = await this.client.get(
|
|
911
|
+
`/api/v1/issue-reports/triage/${issueReportId}/messages`,
|
|
912
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
913
|
+
);
|
|
914
|
+
return this.unwrapApiResponse(
|
|
915
|
+
res,
|
|
916
|
+
"Failed to list triage issue report messages"
|
|
917
|
+
);
|
|
918
|
+
},
|
|
919
|
+
/**
|
|
920
|
+
* Post a clarification_request or final_response reporter-visible message
|
|
921
|
+
* as a triage operator. Idempotent on `idempotency_key`; a key reused with
|
|
922
|
+
* a different body returns 409. A final_response can drive a terminal
|
|
923
|
+
* lifecycle transition via `resolve_case`; the internal resolution_note is
|
|
924
|
+
* never auto-displayed to reporters.
|
|
925
|
+
*/
|
|
926
|
+
postMessage: async (issueReportId, payload) => {
|
|
927
|
+
const res = await this.client.post(
|
|
928
|
+
`/api/v1/issue-reports/triage/${issueReportId}/messages`,
|
|
929
|
+
payload,
|
|
930
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
931
|
+
);
|
|
932
|
+
return this.unwrapApiResponse(res, "Failed to post triage issue report message");
|
|
933
|
+
},
|
|
934
|
+
/**
|
|
935
|
+
* Retract an operator-authored message. The body is retained; the row's
|
|
936
|
+
* state is marked `retracted`. Retracting an already-retracted message is
|
|
937
|
+
* a safe no-op.
|
|
938
|
+
*/
|
|
939
|
+
retractMessage: async (issueReportId, messageId, payload = {}) => {
|
|
940
|
+
const res = await this.client.post(
|
|
941
|
+
`/api/v1/issue-reports/triage/${issueReportId}/messages/${messageId}/retract`,
|
|
942
|
+
payload,
|
|
943
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
944
|
+
);
|
|
945
|
+
return this.unwrapApiResponse(res, "Failed to retract triage issue report message");
|
|
946
|
+
}
|
|
812
947
|
}
|
|
813
948
|
};
|
|
814
949
|
/**
|
|
@@ -826,6 +961,17 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
826
961
|
);
|
|
827
962
|
return this.unwrapApiResponse(res, "Failed to create app link");
|
|
828
963
|
},
|
|
964
|
+
/**
|
|
965
|
+
* Update a short link owned by the authenticated user.
|
|
966
|
+
*/
|
|
967
|
+
update: async (username, slug, payload) => {
|
|
968
|
+
const res = await this.client.patch(
|
|
969
|
+
`/api/v1/app-links/${encodeURIComponent(username)}/${encodeURIComponent(slug)}`,
|
|
970
|
+
payload,
|
|
971
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
972
|
+
);
|
|
973
|
+
return this.unwrapApiResponse(res, "Failed to update app link");
|
|
974
|
+
},
|
|
829
975
|
/**
|
|
830
976
|
* Resolve a public short link for the active application.
|
|
831
977
|
*/
|
|
@@ -840,6 +986,58 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
840
986
|
return this.unwrapApiResponse(res, "Failed to get app link");
|
|
841
987
|
}
|
|
842
988
|
};
|
|
989
|
+
/**
|
|
990
|
+
* Marketing events and experiment results.
|
|
991
|
+
*
|
|
992
|
+
* Use a publishable key for browser-side event emission. Use a secret key
|
|
993
|
+
* from a trusted server or agent process when reading experiment results.
|
|
994
|
+
*/
|
|
995
|
+
marketing = {
|
|
996
|
+
/**
|
|
997
|
+
* Emit one anonymous attribution touch or experiment exposure.
|
|
998
|
+
*/
|
|
999
|
+
emit: async (payload) => {
|
|
1000
|
+
if (payload.event_type === "experiment_exposure") {
|
|
1001
|
+
if (!payload.experiment_id?.trim()) {
|
|
1002
|
+
throw new Error("experiment_id is required for experiment_exposure events");
|
|
1003
|
+
}
|
|
1004
|
+
const variant = payload.variant_id ?? payload.variant;
|
|
1005
|
+
if (!variant?.trim()) {
|
|
1006
|
+
throw new Error("variant_id or variant is required for experiment_exposure events");
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
const res = await this.client.post("/api/marketing-events/ingest", payload);
|
|
1010
|
+
return this.unwrapApiResponse(
|
|
1011
|
+
res,
|
|
1012
|
+
"Failed to emit marketing event"
|
|
1013
|
+
);
|
|
1014
|
+
},
|
|
1015
|
+
/**
|
|
1016
|
+
* Alias for emit(), matching the backend ingest endpoint language.
|
|
1017
|
+
*/
|
|
1018
|
+
ingest: async (payload) => {
|
|
1019
|
+
return this.marketing.emit(payload);
|
|
1020
|
+
},
|
|
1021
|
+
/**
|
|
1022
|
+
* Read per-variant experiment results and the conservative stop signal.
|
|
1023
|
+
*/
|
|
1024
|
+
getExperimentResults: async (experimentId) => {
|
|
1025
|
+
const encodedExperimentId = encodeURIComponent(experimentId);
|
|
1026
|
+
const res = await this.client.get(
|
|
1027
|
+
`/api/marketing/experiments/${encodedExperimentId}/results`
|
|
1028
|
+
);
|
|
1029
|
+
return this.unwrapApiResponse(
|
|
1030
|
+
res,
|
|
1031
|
+
"Failed to get marketing experiment results"
|
|
1032
|
+
);
|
|
1033
|
+
},
|
|
1034
|
+
/**
|
|
1035
|
+
* Short alias for getExperimentResults().
|
|
1036
|
+
*/
|
|
1037
|
+
getResults: async (experimentId) => {
|
|
1038
|
+
return this.marketing.getExperimentResults(experimentId);
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
843
1041
|
static envVar(name) {
|
|
844
1042
|
if (typeof process !== "undefined" && process.env) {
|
|
845
1043
|
return process.env[name];
|
|
@@ -1728,6 +1926,12 @@ var SPAPSClient = class _SPAPSClient {
|
|
|
1728
1926
|
async listUsageHistory(query = {}) {
|
|
1729
1927
|
return this.usage.listHistory(query);
|
|
1730
1928
|
}
|
|
1929
|
+
async emitMarketingEvent(payload) {
|
|
1930
|
+
return this.marketing.emit(payload);
|
|
1931
|
+
}
|
|
1932
|
+
async getMarketingExperimentResults(experimentId) {
|
|
1933
|
+
return this.marketing.getExperimentResults(experimentId);
|
|
1934
|
+
}
|
|
1731
1935
|
// Secure Messaging Methods
|
|
1732
1936
|
async createSecureMessage(payload) {
|
|
1733
1937
|
const response = await this.client.post("/api/secure-messages", payload);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spaps-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Sweet Potato Authentication & Payment Service SDK - Zero-config client with built-in permission checking, role-based access control, and dayrate scheduling",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"axios": "^1.15.1",
|
|
53
53
|
"cross-fetch": "^4.0.0",
|
|
54
|
-
"spaps-types": "^1.4.
|
|
54
|
+
"spaps-types": "^1.4.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/node": "^20.10.0",
|