spaps-sdk 1.11.0 → 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
@@ -10,6 +10,14 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
10
10
 
11
11
  - Added browser-safe `entitlements.listCurrentUserProjects()` and `entitlements.checkCurrentUserProjectAccess(...)` helpers for project grant reads.
12
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
+
13
21
  ## [1.10.2] - 2026-06-04
14
22
 
15
23
  ### Added
package/README.md CHANGED
@@ -154,14 +154,34 @@ console.log(voiceToken.provider, voiceToken.model_id);
154
154
 
155
155
  ### Issue Reporting Screenshot Attachments
156
156
 
157
- 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.
158
164
 
159
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
+
160
172
  spaps.setAccessToken(accessToken);
161
173
 
162
174
  const file = new File([pngBytes], "protocol-save-failure.png", {
163
175
  type: "image/png",
164
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
+
165
185
  const attachment = await spaps.issueReporting.uploadAttachment(file);
166
186
 
167
187
  const issue = await spaps.issueReporting.create({
@@ -178,10 +198,35 @@ const issue = await spaps.issueReporting.create({
178
198
  });
179
199
 
180
200
  const access = await spaps.issueReporting.getAttachmentAccess(attachment.id);
181
- console.log(issue.id, access.expires_in_seconds);
201
+ console.log(issue.id, access.expires_in_seconds, ISSUE_REPORT_ATTACHMENT_MAX_RETAINED);
182
202
  ```
183
203
 
184
- 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.
185
230
 
186
231
  ### Application Short Links
187
232
 
@@ -511,7 +556,7 @@ npm run test:readme
511
556
  ## Metadata
512
557
 
513
558
  - `package_name`: `spaps-sdk`
514
- - `latest_version`: `1.10.2`
559
+ - `latest_version`: `1.11.0`
515
560
  - `minimum_runtime`: `Node.js >=14.0.0`
516
561
  - `api_base_url`: `https://api.sweetpotato.dev`
517
562
 
package/dist/index.d.mts CHANGED
@@ -444,8 +444,16 @@ interface IssueReportStatusParams {
444
444
  scope?: SupportedIssueReportScope;
445
445
  }
446
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
+ */
447
451
  filename?: string;
448
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;
449
457
  declare class X402PaymentRequiredSDKError extends Error {
450
458
  readonly paymentRequiredHeader: string;
451
459
  readonly response: unknown;
@@ -1509,4 +1517,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
1509
1517
  */
1510
1518
  declare function detectKeyType(key: string): ApiKeyType | null;
1511
1519
 
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 };
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
@@ -444,8 +444,16 @@ interface IssueReportStatusParams {
444
444
  scope?: SupportedIssueReportScope;
445
445
  }
446
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
+ */
447
451
  filename?: string;
448
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;
449
457
  declare class X402PaymentRequiredSDKError extends Error {
450
458
  readonly paymentRequiredHeader: string;
451
459
  readonly response: unknown;
@@ -1509,4 +1517,4 @@ declare function createServerClient(secretKey: string, options?: Omit<SPAPSConfi
1509
1517
  */
1510
1518
  declare function detectKeyType(key: string): ApiKeyType | null;
1511
1519
 
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 };
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;
@@ -815,6 +839,7 @@ var SPAPSClient = class _SPAPSClient {
815
839
  if (typeof FormData === "undefined") {
816
840
  throw new Error("FormData is required to upload issue report attachments");
817
841
  }
842
+ assertSupportedIssueReportAttachment(file);
818
843
  const formData = new FormData();
819
844
  const fileWithOptionalName = file;
820
845
  const inferredFilename = typeof fileWithOptionalName.name === "string" ? fileWithOptionalName.name : void 0;
@@ -2421,6 +2446,9 @@ function detectKeyType(key) {
2421
2446
  0 && (module.exports = {
2422
2447
  DEFAULT_ADMIN_ACCOUNTS,
2423
2448
  FeatureEvaluator,
2449
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
2450
+ ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
2451
+ ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
2424
2452
  PermissionChecker,
2425
2453
  RoleHierarchy,
2426
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;
@@ -780,6 +801,7 @@ var SPAPSClient = class _SPAPSClient {
780
801
  if (typeof FormData === "undefined") {
781
802
  throw new Error("FormData is required to upload issue report attachments");
782
803
  }
804
+ assertSupportedIssueReportAttachment(file);
783
805
  const formData = new FormData();
784
806
  const fileWithOptionalName = file;
785
807
  const inferredFilename = typeof fileWithOptionalName.name === "string" ? fileWithOptionalName.name : void 0;
@@ -2385,6 +2407,9 @@ function detectKeyType(key) {
2385
2407
  export {
2386
2408
  DEFAULT_ADMIN_ACCOUNTS,
2387
2409
  FeatureEvaluator,
2410
+ ISSUE_REPORT_ATTACHMENT_ALLOWED_MIME_TYPES,
2411
+ ISSUE_REPORT_ATTACHMENT_MAX_BYTES,
2412
+ ISSUE_REPORT_ATTACHMENT_MAX_RETAINED,
2388
2413
  PermissionChecker,
2389
2414
  RoleHierarchy,
2390
2415
  SPAPSClient as SPAPS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spaps-sdk",
3
- "version": "1.11.0",
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",