spaps-sdk 1.10.2 → 1.12.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,20 @@ 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.11.0] - 2026-06-08
14
+
15
+ ### Added
16
+
17
+ - Exported the canonical issue-report screenshot attachment constraints: `ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES`, `ISSUE_REPORT_ATTACHMENT_MAX_BYTES`, and `ISSUE_REPORT_ATTACHMENT_MAX_RETAINED`.
18
+ - Added SDK-side preflight validation to `issueReporting.uploadAttachment(file, options)`, rejecting unsupported MIME types and files larger than 10 MiB before opening the multipart request. SPAPS remains the authoritative backend validator.
19
+ - Documented the operator-gated automatic screenshot-capture handoff: React consumers should lazy-load capture through `spaps-issue-reporting-react@0.6.0`, pass captured files to SDK `uploadAttachment`, and keep publishing/deployment approval outside worker nodes. The local proof tarball for this SDK line was `/tmp/spaps-sdk-1.11.0.tgz`; `spaps-sdk@1.11.0` is now published on npm.
20
+
21
+ ## [1.10.2] - 2026-06-04
22
+
23
+ ### Added
24
+
11
25
  - Added `issueReporting.getAttachmentAccess(attachmentId)` as the canonical screenshot access helper while keeping `getAttachmentAccessUrl` as a backward-compatible alias.
12
26
 
13
27
  ## [1.10.1] - 2026-05-16
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
@@ -88,7 +88,7 @@ Relevant environment variables:
88
88
  | `appLinks` | Authenticated create and public resolve helpers for application-scoped short links |
89
89
  | `marketing` | Browser-safe attribution/experiment event emission and server-side experiment results |
90
90
  | `email` | Template lookup, preview, and send helpers |
91
- | `entitlements` | User and resource entitlement queries |
91
+ | `entitlements` | User/resource entitlement queries and browser-safe current-user project access reads |
92
92
  | `usage` | Secret-key usage authorization and immutable usage recording |
93
93
  | `skillEvals` | Paid blind skill-eval cases, review rooms, reviewer marks, insight inboxes, and controlled reveal |
94
94
  | `dayrate` | Availability, Stripe booking, x402 booking-hold, and checkout-status helpers |
@@ -97,6 +97,33 @@ Relevant environment variables:
97
97
 
98
98
  ## Common Patterns
99
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
+
100
127
  ### Typed Secure Messages
101
128
 
102
129
  ```ts
@@ -127,14 +154,34 @@ console.log(voiceToken.provider, voiceToken.model_id);
127
154
 
128
155
  ### Issue Reporting Screenshot Attachments
129
156
 
130
- Screenshots are uploaded as private pending hosted assets first. Create, update, or reply calls then send only attachment IDs; do not put raw image bytes, data URLs, or base64 payloads in issue notes or target metadata.
157
+ Use `spaps.issueReporting.uploadAttachment(file)` as the canonical screenshot
158
+ upload path. Consumers should not carry raw `POST /api/v1/issue-reports/attachments`
159
+ adapters when their installed `spaps-sdk` exposes this method.
160
+
161
+ Screenshots are uploaded as private pending hosted assets first. Create, update,
162
+ or reply calls then send only attachment IDs; do not put raw image bytes, data
163
+ URLs, or base64 payloads in issue notes or target metadata.
131
164
 
132
165
  ```ts
166
+ import {
167
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
168
+ ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
169
+ ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
170
+ } from "spaps-sdk";
171
+
133
172
  spaps.setAccessToken(accessToken);
134
173
 
135
174
  const file = new File([pngBytes], "protocol-save-failure.png", {
136
175
  type: "image/png",
137
176
  });
177
+
178
+ const supportedType = ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES.some(
179
+ (mimeType) => mimeType === file.type,
180
+ );
181
+ if (!supportedType || file.size > ISSUE_REPORT_ATTACHMENT_MAX_BYTES) {
182
+ throw new Error("Screenshot is not a supported SPAPS issue-report attachment");
183
+ }
184
+
138
185
  const attachment = await spaps.issueReporting.uploadAttachment(file);
139
186
 
140
187
  const issue = await spaps.issueReporting.create({
@@ -151,10 +198,35 @@ const issue = await spaps.issueReporting.create({
151
198
  });
152
199
 
153
200
  const access = await spaps.issueReporting.getAttachmentAccess(attachment.id);
154
- console.log(issue.id, access.expires_in_seconds);
201
+ console.log(issue.id, access.expires_in_seconds, ISSUE_REPORT_ATTACHMENT_MAX_RETAINED);
155
202
  ```
156
203
 
157
- SPAPS accepts PNG, JPEG, and WebP screenshots up to 10 MiB each, with at most 5 retained screenshots per report. The hosted object remains private; callers fetch a short-lived access URL after normal issue-reporting authorization succeeds. SPAPS does not redact screenshot contents, so host apps should warn users when a capture may include sensitive data.
204
+ The SDK rejects unsupported screenshot MIME types and files over 10 MiB before
205
+ opening the multipart request. SPAPS still performs authoritative validation,
206
+ stores the hosted object privately, and retains at most 5 screenshots per report
207
+ or reply. Callers fetch a short-lived access URL after normal issue-reporting
208
+ authorization succeeds. SPAPS does not redact screenshot contents, so host apps
209
+ should warn users when a capture may include sensitive data.
210
+
211
+ Browser capture is intentionally outside this SDK. The shared
212
+ `spaps-issue-reporting-react` automatic DOM capture contract is a React-package
213
+ concern: it should lazy-load `html2canvas` only after the host app opts in with
214
+ the React `screenshotCapture` config, convert the visible same-origin DOM result
215
+ to a PNG, JPEG, or WebP `Blob`/`File`, then pass that file to
216
+ `uploadAttachment`. Apps that do not opt in must not download `html2canvas`.
217
+ If capture or upload fails, submit the issue with metadata and any manual
218
+ attachments instead of blocking issue submission.
219
+
220
+ Version note: `uploadAttachment` was added in `spaps-sdk@1.10.1`, and
221
+ `getAttachmentAccess` became the canonical access helper in `spaps-sdk@1.10.2`.
222
+ The exported limit constants shown above are part of this source package line;
223
+ wait for the operator-approved npm release before removing local shims from
224
+ consumers pinned to older packages.
225
+
226
+ No new SDK method or backend screenshot endpoint is part of the automatic
227
+ capture contract unless the existing private attachment upload proves
228
+ insufficient. Worker nodes may validate with local packs or workspace links, but
229
+ publishing `spaps-sdk` or `spaps-issue-reporting-react` remains operator-gated.
158
230
 
159
231
  ### Application Short Links
160
232
 
@@ -484,7 +556,7 @@ npm run test:readme
484
556
  ## Metadata
485
557
 
486
558
  - `package_name`: `spaps-sdk`
487
- - `latest_version`: `1.10.1`
559
+ - `latest_version`: `1.11.0`
488
560
  - `minimum_runtime`: `Node.js >=14.0.0`
489
561
  - `api_base_url`: `https://api.sweetpotato.dev`
490
562
 
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, 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, Price, Product, ProductSyncResult, 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';
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
@@ -417,6 +417,22 @@ interface EntitlementCheckResult {
417
417
  /** The matching entitlement, if any */
418
418
  entitlement?: Entitlement;
419
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
+ }
420
436
  type SupportedIssueReportScope = Extract<IssueReportScope, 'mine'>;
421
437
  interface IssueReportListParams {
422
438
  status?: IssueReportStatus;
@@ -428,8 +444,16 @@ interface IssueReportStatusParams {
428
444
  scope?: SupportedIssueReportScope;
429
445
  }
430
446
  interface IssueReportAttachmentUploadOptions {
447
+ /**
448
+ * Optional filename to send in the multipart `file` part. File objects keep
449
+ * their own name when this is omitted.
450
+ */
431
451
  filename?: string;
432
452
  }
453
+ declare const ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES: readonly ["image/png", "image/jpeg", "image/webp"];
454
+ type IssueReportAttachmentMimeType = typeof ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES[number];
455
+ declare const ISSUE_REPORT_ATTACHMENT_MAX_BYTES: number;
456
+ declare const ISSUE_REPORT_ATTACHMENT_MAX_RETAINED = 5;
433
457
  declare class X402PaymentRequiredSDKError extends Error {
434
458
  readonly paymentRequiredHeader: string;
435
459
  readonly response: unknown;
@@ -698,6 +722,7 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
698
722
  private headerProvider?;
699
723
  private unwrapApiResponse;
700
724
  private skillEvalMutationConfig;
725
+ private requireCurrentUserIdFromAccessToken;
701
726
  private isAxiosResponse;
702
727
  private isResponseLikeWithData;
703
728
  private isApiResponse;
@@ -779,6 +804,20 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
779
804
  * @param resourceId - Optional specific resource ID.
780
805
  */
781
806
  listByResource: (resourceType: ResourceType, resourceId?: string) => Promise<Entitlement[]>;
807
+ /**
808
+ * List project grants for the authenticated user.
809
+ *
810
+ * Browser/publishable-key contexts are safe here because the server requires
811
+ * the JWT subject to match the path user id.
812
+ */
813
+ listCurrentUserProjects: (params?: CurrentUserProjectGrantListParams) => Promise<ListProjectGrantsResponse>;
814
+ /**
815
+ * Check whether the authenticated user has one project entitlement.
816
+ *
817
+ * The helper does not accept user/email overrides; publishable-key callers
818
+ * are scoped by the server to the JWT identity.
819
+ */
820
+ checkCurrentUserProjectAccess: (params: CurrentUserProjectAccessParams) => Promise<ProjectAccessCheckResponse>;
782
821
  };
783
822
  /**
784
823
  * Issue reporting namespace for authenticated end-user issue flows.
@@ -1478,4 +1517,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
1478
1517
  */
1479
1518
  declare function detectKeyType(key: string): ApiKeyType | null;
1480
1519
 
1481
- 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 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 };
1520
+ 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, ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES, ISSUE_REPORT_ATTACHMENT_MAX_BYTES, ISSUE_REPORT_ATTACHMENT_MAX_RETAINED, type ImportSkillEvalGovernanceOutcomeRequest, type IssueReportAttachmentMimeType, 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, 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, Price, Product, ProductSyncResult, 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';
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
@@ -417,6 +417,22 @@ interface EntitlementCheckResult {
417
417
  /** The matching entitlement, if any */
418
418
  entitlement?: Entitlement;
419
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
+ }
420
436
  type SupportedIssueReportScope = Extract<IssueReportScope, 'mine'>;
421
437
  interface IssueReportListParams {
422
438
  status?: IssueReportStatus;
@@ -428,8 +444,16 @@ interface IssueReportStatusParams {
428
444
  scope?: SupportedIssueReportScope;
429
445
  }
430
446
  interface IssueReportAttachmentUploadOptions {
447
+ /**
448
+ * Optional filename to send in the multipart `file` part. File objects keep
449
+ * their own name when this is omitted.
450
+ */
431
451
  filename?: string;
432
452
  }
453
+ declare const ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES: readonly ["image/png", "image/jpeg", "image/webp"];
454
+ type IssueReportAttachmentMimeType = typeof ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES[number];
455
+ declare const ISSUE_REPORT_ATTACHMENT_MAX_BYTES: number;
456
+ declare const ISSUE_REPORT_ATTACHMENT_MAX_RETAINED = 5;
433
457
  declare class X402PaymentRequiredSDKError extends Error {
434
458
  readonly paymentRequiredHeader: string;
435
459
  readonly response: unknown;
@@ -698,6 +722,7 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
698
722
  private headerProvider?;
699
723
  private unwrapApiResponse;
700
724
  private skillEvalMutationConfig;
725
+ private requireCurrentUserIdFromAccessToken;
701
726
  private isAxiosResponse;
702
727
  private isResponseLikeWithData;
703
728
  private isApiResponse;
@@ -779,6 +804,20 @@ declare class SPAPSClient<SecureMessageMetadata extends Record<string, any> = Re
779
804
  * @param resourceId - Optional specific resource ID.
780
805
  */
781
806
  listByResource: (resourceType: ResourceType, resourceId?: string) => Promise<Entitlement[]>;
807
+ /**
808
+ * List project grants for the authenticated user.
809
+ *
810
+ * Browser/publishable-key contexts are safe here because the server requires
811
+ * the JWT subject to match the path user id.
812
+ */
813
+ listCurrentUserProjects: (params?: CurrentUserProjectGrantListParams) => Promise<ListProjectGrantsResponse>;
814
+ /**
815
+ * Check whether the authenticated user has one project entitlement.
816
+ *
817
+ * The helper does not accept user/email overrides; publishable-key callers
818
+ * are scoped by the server to the JWT identity.
819
+ */
820
+ checkCurrentUserProjectAccess: (params: CurrentUserProjectAccessParams) => Promise<ProjectAccessCheckResponse>;
782
821
  };
783
822
  /**
784
823
  * Issue reporting namespace for authenticated end-user issue flows.
@@ -1478,4 +1517,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
1478
1517
  */
1479
1518
  declare function detectKeyType(key: string): ApiKeyType | null;
1480
1519
 
1481
- 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 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 };
1520
+ 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, ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES, ISSUE_REPORT_ATTACHMENT_MAX_BYTES, ISSUE_REPORT_ATTACHMENT_MAX_RETAINED, type ImportSkillEvalGovernanceOutcomeRequest, type IssueReportAttachmentMimeType, 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
@@ -196,6 +196,9 @@ var index_exports = {};
196
196
  __export(index_exports, {
197
197
  DEFAULT_ADMIN_ACCOUNTS: () => DEFAULT_ADMIN_ACCOUNTS,
198
198
  FeatureEvaluator: () => FeatureEvaluator,
199
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES: () => ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
200
+ ISSUE_REPORT_ATTACHMENT_MAX_BYTES: () => ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
201
+ ISSUE_REPORT_ATTACHMENT_MAX_RETAINED: () => ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
199
202
  PermissionChecker: () => PermissionChecker,
200
203
  RoleHierarchy: () => RoleHierarchy,
201
204
  SPAPS: () => SPAPSClient,
@@ -523,6 +526,27 @@ function appendSupportedIssueReportScope(q, scope) {
523
526
  }
524
527
  q.append("scope", scope);
525
528
  }
529
+ var ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES = [
530
+ "image/png",
531
+ "image/jpeg",
532
+ "image/webp"
533
+ ];
534
+ var ISSUE_REPORT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
535
+ var ISSUE_REPORT_ATTACHMENT_MAX_RETAINED = 5;
536
+ var ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPE_SET = new Set(
537
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES
538
+ );
539
+ function assertSupportedIssueReportAttachment(file) {
540
+ const mimeType = (file.type || "").trim().toLowerCase();
541
+ if (!ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPE_SET.has(mimeType)) {
542
+ throw new Error(
543
+ "SPAPS issue report attachments must be PNG, JPEG, or WebP screenshots"
544
+ );
545
+ }
546
+ if (file.size > ISSUE_REPORT_ATTACHMENT_MAX_BYTES) {
547
+ throw new Error("SPAPS issue report attachments must be 10 MiB or smaller");
548
+ }
549
+ }
526
550
  var X402PaymentRequiredSDKError = class extends Error {
527
551
  paymentRequiredHeader;
528
552
  response;
@@ -563,6 +587,17 @@ var SPAPSClient = class _SPAPSClient {
563
587
  }
564
588
  return { headers: { "If-Match": String(ifMatch) } };
565
589
  }
590
+ requireCurrentUserIdFromAccessToken() {
591
+ if (!this.accessToken) {
592
+ throw new Error("Authentication required. Please authenticate first.");
593
+ }
594
+ const payload = TokenManager.decodePayload(this.accessToken);
595
+ const userId = payload?.user_id ?? payload?.sub;
596
+ if (typeof userId !== "string" || userId.length === 0) {
597
+ throw new Error("Current user id not found in access token.");
598
+ }
599
+ return userId;
600
+ }
566
601
  isAxiosResponse(value) {
567
602
  if (!value || typeof value !== "object") {
568
603
  return false;
@@ -701,6 +736,46 @@ var SPAPSClient = class _SPAPSClient {
701
736
  return payload.entitlements;
702
737
  }
703
738
  return payload;
739
+ },
740
+ /**
741
+ * List project grants for the authenticated user.
742
+ *
743
+ * Browser/publishable-key contexts are safe here because the server requires
744
+ * the JWT subject to match the path user id.
745
+ */
746
+ listCurrentUserProjects: async (params) => {
747
+ const userId = this.requireCurrentUserIdFromAccessToken();
748
+ const q = new URLSearchParams();
749
+ if (params?.entitlementKey) q.append("entitlement_key", params.entitlementKey);
750
+ if (params?.limit !== void 0) q.append("limit", String(params.limit));
751
+ if (params?.offset !== void 0) q.append("offset", String(params.offset));
752
+ if (params?.cursor) q.append("cursor", params.cursor);
753
+ const qs = q.toString();
754
+ const res = await this.client.get(
755
+ `/api/project-grants/user/${encodeURIComponent(userId)}/projects${qs ? `?${qs}` : ""}`,
756
+ { headers: { Authorization: `Bearer ${this.accessToken}` } }
757
+ );
758
+ return this.unwrapApiResponse(res, "Failed to list current user project grants");
759
+ },
760
+ /**
761
+ * Check whether the authenticated user has one project entitlement.
762
+ *
763
+ * The helper does not accept user/email overrides; publishable-key callers
764
+ * are scoped by the server to the JWT identity.
765
+ */
766
+ checkCurrentUserProjectAccess: async (params) => {
767
+ if (!this.accessToken) {
768
+ throw new Error("Authentication required. Please authenticate first.");
769
+ }
770
+ const q = new URLSearchParams({
771
+ project_id: params.projectId,
772
+ entitlement_key: params.entitlementKey
773
+ });
774
+ const res = await this.client.get(
775
+ `/api/project-grants/check?${q.toString()}`,
776
+ { headers: { Authorization: `Bearer ${this.accessToken}` } }
777
+ );
778
+ return this.unwrapApiResponse(res, "Failed to check current user project access");
704
779
  }
705
780
  };
706
781
  /**
@@ -764,6 +839,7 @@ var SPAPSClient = class _SPAPSClient {
764
839
  if (typeof FormData === "undefined") {
765
840
  throw new Error("FormData is required to upload issue report attachments");
766
841
  }
842
+ assertSupportedIssueReportAttachment(file);
767
843
  const formData = new FormData();
768
844
  const fileWithOptionalName = file;
769
845
  const inferredFilename = typeof fileWithOptionalName.name === "string" ? fileWithOptionalName.name : void 0;
@@ -2370,6 +2446,9 @@ function detectKeyType(key) {
2370
2446
  0 && (module.exports = {
2371
2447
  DEFAULT_ADMIN_ACCOUNTS,
2372
2448
  FeatureEvaluator,
2449
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
2450
+ ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
2451
+ ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
2373
2452
  PermissionChecker,
2374
2453
  RoleHierarchy,
2375
2454
  SPAPS,
package/dist/index.mjs CHANGED
@@ -488,6 +488,27 @@ function appendSupportedIssueReportScope(q, scope) {
488
488
  }
489
489
  q.append("scope", scope);
490
490
  }
491
+ var ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES = [
492
+ "image/png",
493
+ "image/jpeg",
494
+ "image/webp"
495
+ ];
496
+ var ISSUE_REPORT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
497
+ var ISSUE_REPORT_ATTACHMENT_MAX_RETAINED = 5;
498
+ var ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPE_SET = new Set(
499
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES
500
+ );
501
+ function assertSupportedIssueReportAttachment(file) {
502
+ const mimeType = (file.type || "").trim().toLowerCase();
503
+ if (!ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPE_SET.has(mimeType)) {
504
+ throw new Error(
505
+ "SPAPS issue report attachments must be PNG, JPEG, or WebP screenshots"
506
+ );
507
+ }
508
+ if (file.size > ISSUE_REPORT_ATTACHMENT_MAX_BYTES) {
509
+ throw new Error("SPAPS issue report attachments must be 10 MiB or smaller");
510
+ }
511
+ }
491
512
  var X402PaymentRequiredSDKError = class extends Error {
492
513
  paymentRequiredHeader;
493
514
  response;
@@ -528,6 +549,17 @@ var SPAPSClient = class _SPAPSClient {
528
549
  }
529
550
  return { headers: { "If-Match": String(ifMatch) } };
530
551
  }
552
+ requireCurrentUserIdFromAccessToken() {
553
+ if (!this.accessToken) {
554
+ throw new Error("Authentication required. Please authenticate first.");
555
+ }
556
+ const payload = TokenManager.decodePayload(this.accessToken);
557
+ const userId = payload?.user_id ?? payload?.sub;
558
+ if (typeof userId !== "string" || userId.length === 0) {
559
+ throw new Error("Current user id not found in access token.");
560
+ }
561
+ return userId;
562
+ }
531
563
  isAxiosResponse(value) {
532
564
  if (!value || typeof value !== "object") {
533
565
  return false;
@@ -666,6 +698,46 @@ var SPAPSClient = class _SPAPSClient {
666
698
  return payload.entitlements;
667
699
  }
668
700
  return payload;
701
+ },
702
+ /**
703
+ * List project grants for the authenticated user.
704
+ *
705
+ * Browser/publishable-key contexts are safe here because the server requires
706
+ * the JWT subject to match the path user id.
707
+ */
708
+ listCurrentUserProjects: async (params) => {
709
+ const userId = this.requireCurrentUserIdFromAccessToken();
710
+ const q = new URLSearchParams();
711
+ if (params?.entitlementKey) q.append("entitlement_key", params.entitlementKey);
712
+ if (params?.limit !== void 0) q.append("limit", String(params.limit));
713
+ if (params?.offset !== void 0) q.append("offset", String(params.offset));
714
+ if (params?.cursor) q.append("cursor", params.cursor);
715
+ const qs = q.toString();
716
+ const res = await this.client.get(
717
+ `/api/project-grants/user/${encodeURIComponent(userId)}/projects${qs ? `?${qs}` : ""}`,
718
+ { headers: { Authorization: `Bearer ${this.accessToken}` } }
719
+ );
720
+ return this.unwrapApiResponse(res, "Failed to list current user project grants");
721
+ },
722
+ /**
723
+ * Check whether the authenticated user has one project entitlement.
724
+ *
725
+ * The helper does not accept user/email overrides; publishable-key callers
726
+ * are scoped by the server to the JWT identity.
727
+ */
728
+ checkCurrentUserProjectAccess: async (params) => {
729
+ if (!this.accessToken) {
730
+ throw new Error("Authentication required. Please authenticate first.");
731
+ }
732
+ const q = new URLSearchParams({
733
+ project_id: params.projectId,
734
+ entitlement_key: params.entitlementKey
735
+ });
736
+ const res = await this.client.get(
737
+ `/api/project-grants/check?${q.toString()}`,
738
+ { headers: { Authorization: `Bearer ${this.accessToken}` } }
739
+ );
740
+ return this.unwrapApiResponse(res, "Failed to check current user project access");
669
741
  }
670
742
  };
671
743
  /**
@@ -729,6 +801,7 @@ var SPAPSClient = class _SPAPSClient {
729
801
  if (typeof FormData === "undefined") {
730
802
  throw new Error("FormData is required to upload issue report attachments");
731
803
  }
804
+ assertSupportedIssueReportAttachment(file);
732
805
  const formData = new FormData();
733
806
  const fileWithOptionalName = file;
734
807
  const inferredFilename = typeof fileWithOptionalName.name === "string" ? fileWithOptionalName.name : void 0;
@@ -2334,6 +2407,9 @@ function detectKeyType(key) {
2334
2407
  export {
2335
2408
  DEFAULT_ADMIN_ACCOUNTS,
2336
2409
  FeatureEvaluator,
2410
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
2411
+ ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
2412
+ ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
2337
2413
  PermissionChecker,
2338
2414
  RoleHierarchy,
2339
2415
  SPAPSClient as SPAPS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spaps-sdk",
3
- "version": "1.10.2",
3
+ "version": "1.12.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.2"
54
+ "spaps-types": "^1.5.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/node": "^20.10.0",
@@ -81,4 +81,4 @@
81
81
  "engines": {
82
82
  "node": ">=14.0.0"
83
83
  }
84
- }
84
+ }