@sylphx/sdk 0.10.3 → 0.10.4

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/README.md CHANGED
@@ -66,6 +66,12 @@ export const config = {
66
66
 
67
67
  No manual `/api/auth/*` routes needed — the middleware handles everything.
68
68
 
69
+ Organization context is part of the same contract. Calling the mounted
70
+ `POST /auth/switch-org` route stores the active org in SDK-owned HttpOnly
71
+ cookies; subsequent refresh-token rotations restore the org-scoped access token
72
+ automatically. If a user belongs to exactly one organization, the middleware
73
+ auto-scopes the refreshed session without app-specific glue code.
74
+
69
75
  ---
70
76
 
71
77
  ### 3. Root Layout
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { SdkBillingPlan, SdkBillingSubscription, BillingCheckoutRequest, BillingCheckoutResponse, BillingPortalRequest, BillingPortalResponse, BillingBalanceResponse, BillingUsageResponse, SdkConsentType, UserConsent as UserConsent$1, AIModel as AIModel$1, GetModelsResponse, GetRateLimitResponse, GetUsageResponse, ReferralLeaderboardEntry, ReferralRewardDefaults as ReferralRewardDefaults$1, WebhookDelivery as WebhookDelivery$1, DeviceApproveRequest, DeviceApproveResponse, DeviceDenyRequest, DeviceDenyResponse, DeviceInitResponse, DeviceInitRequest, DevicePollResponse, LoginRequest as LoginRequest$1, LoginResponse as LoginResponse$1, UserFullProfile as UserFullProfile$1, LogoutInput, PlatformPasswordChangeRequest, PlatformPasswordChangeResponse, PlatformPasswordSetRequest, PlatformPasswordSetResponse, PlatformPasswordStatusResponse, RefreshTokenInput, RefreshTokenResult, PlatformSessionRenameRequest, PlatformSessionRenameResponse, PlatformSessionRevokeAllResponse, PlatformSessionRevokeRequest, PlatformSessionRevokeOtherResponse, PlatformSessionRevokeResponse, PlatformSessionsListResponse, AuthUserDeleteRequest, AuthUserDeleteResponse, AuthUserExportResponse, RegisterRequest as RegisterRequest$1, RegisterResponse as RegisterResponse$1, ResendEmailVerificationRequest as ResendEmailVerificationRequest$1, ResendEmailVerificationResponse as ResendEmailVerificationResponse$1, AuthTokensResponse, TwoFactorVerifyRequest as TwoFactorVerifyRequest$1, OAuthIntrospectResponse, PlatformAuditQueryRequest, PlatformAuditQueryResponse, PlatformRateLimitStatusRequest, PlatformRateLimitStatusResponse, PlatformRateLimitStrategiesListRequest, PlatformRateLimitStrategiesListResponse, PlatformRateLimitStrategyDeleteRequest, PlatformRateLimitStrategyDeleteResponse, PlatformRateLimitStrategyUpsertRequest, PlatformRateLimitStrategyUpsertResponse, File as File$1, UploadId, FileId, FileVersion, FileVersionId, CreateOrgInput as CreateOrgInput$1, InviteMemberInput as InviteMemberInput$1, OrgSdkRole, OrgInvitation, OrgMember, MembershipInfo, Organization, UpdateOrgInput as UpdateOrgInput$1, UserOrganizationMembership, UserOrganizationsResponse } from '@sylphx/contract';
1
+ import { SdkBillingPlan, SdkBillingSubscription, BillingCheckoutRequest, BillingCheckoutResponse, BillingPortalRequest, BillingPortalResponse, BillingBalanceResponse, BillingUsageResponse, SdkConsentType, UserConsent as UserConsent$1, AIModel as AIModel$1, GetModelsResponse, GetRateLimitResponse, GetUsageResponse, ReferralLeaderboardEntry, ReferralRewardDefaults as ReferralRewardDefaults$1, WebhookDelivery as WebhookDelivery$1, DeviceApproveRequest, DeviceApproveResponse, DeviceDenyRequest, DeviceDenyResponse, DeviceInitResponse, DeviceInitRequest, DevicePollResponse, LoginRequest as LoginRequest$1, LoginResponse as LoginResponse$1, UserFullProfile as UserFullProfile$1, LogoutInput, PlatformPasswordChangeRequest, PlatformPasswordChangeResponse, PlatformPasswordSetRequest, PlatformPasswordSetResponse, PlatformPasswordStatusResponse, RefreshTokenInput, RefreshTokenResult, PlatformSessionRenameRequest, PlatformSessionRenameResponse, PlatformSessionRevokeAllResponse, PlatformSessionRevokeRequest, PlatformSessionRevokeOtherResponse, PlatformSessionRevokeResponse, PlatformSessionsListResponse, AuthUserDeleteRequest, AuthUserDeleteResponse, AuthUserExportResponse, RegisterRequest as RegisterRequest$1, RegisterResponse as RegisterResponse$1, ResendEmailVerificationRequest as ResendEmailVerificationRequest$1, ResendEmailVerificationResponse as ResendEmailVerificationResponse$1, AuthTokensResponse, TwoFactorVerifyRequest as TwoFactorVerifyRequest$1, OAuthIntrospectResponse, PlatformAuditQueryRequest, PlatformAuditQueryResponse, PlatformRateLimitStatusRequest, PlatformRateLimitStatusResponse, PlatformRateLimitStrategiesListRequest, PlatformRateLimitStrategiesListResponse, PlatformRateLimitStrategyDeleteRequest, PlatformRateLimitStrategyDeleteResponse, PlatformRateLimitStrategyUpsertRequest, PlatformRateLimitStrategyUpsertResponse, File as File$1, UploadId, FileId, TakedownFileRequest, TakedownFileResult, FileVersion, FileVersionId, CreateOrgInput as CreateOrgInput$1, InviteMemberInput as InviteMemberInput$1, OrgSdkRole, OrgInvitation, OrgMember, MembershipInfo, Organization, UpdateOrgInput as UpdateOrgInput$1, UserOrganizationMembership, UserOrganizationsResponse } from '@sylphx/contract';
2
2
  export { BillingBalanceResponse as BalanceResponse, BillingCheckoutRequest as CheckoutRequest, BillingCheckoutResponse as CheckoutResponse, FileId, FileVersion, FileVersionId, FileVisibility, Organization, BillingPortalRequest as PortalRequest, BillingPortalResponse as PortalResponse, SignedUrlDisposition, File as StorageFile, UploadId, BillingUsageResponse as UsageResponse } from '@sylphx/contract';
3
3
 
4
4
  /**
@@ -1782,6 +1782,8 @@ interface AccessTokenPayload {
1782
1782
  email_verified: boolean;
1783
1783
  app_id: string;
1784
1784
  role?: string;
1785
+ /** Project session id when the token was minted from a BaaS auth session. */
1786
+ sid?: string;
1785
1787
  iat: number;
1786
1788
  exp: number;
1787
1789
  }
@@ -3769,6 +3771,7 @@ interface CopyFileOptions {
3769
3771
  visibility?: 'public' | 'private';
3770
3772
  metadata?: Record<string, unknown>;
3771
3773
  }
3774
+ type TakedownFileOptions = TakedownFileRequest;
3772
3775
  declare function uploadsCreate(config: SylphxConfig, blob: Blob | File, options: UploadCreateOptions): Promise<File$1>;
3773
3776
  declare function uploadsAbort(config: SylphxConfig, uploadId: UploadId | string): Promise<void>;
3774
3777
  interface ListPage {
@@ -3783,6 +3786,7 @@ declare function filesDelete(config: SylphxConfig, fileId: FileId | string): Pro
3783
3786
  id: FileId;
3784
3787
  isDeleted: true;
3785
3788
  }>;
3789
+ declare function filesTakedown(config: SylphxConfig, fileId: FileId | string, options: TakedownFileOptions): Promise<TakedownFileResult>;
3786
3790
  declare function filesRestore(config: SylphxConfig, fileId: FileId | string): Promise<File$1>;
3787
3791
  declare function filesSignedUrl(config: SylphxConfig, fileId: FileId | string, options?: SignedUrlOptions): Promise<{
3788
3792
  url: string;
@@ -3822,6 +3826,7 @@ declare const storage: {
3822
3826
  readonly list: typeof filesList;
3823
3827
  readonly get: typeof filesGet;
3824
3828
  readonly delete: typeof filesDelete;
3829
+ readonly takedown: typeof filesTakedown;
3825
3830
  readonly restore: typeof filesRestore;
3826
3831
  readonly signedUrl: typeof filesSignedUrl;
3827
3832
  readonly copy: typeof filesCopy;
@@ -3995,6 +4000,27 @@ interface PushNotification {
3995
4000
  icon?: string;
3996
4001
  url?: string;
3997
4002
  }
4003
+ interface PushDeliveryPlatformCounts {
4004
+ readonly web?: number;
4005
+ readonly ios?: number;
4006
+ readonly android?: number;
4007
+ }
4008
+ interface SendPushWireResult {
4009
+ readonly status?: 'delivered' | 'queued' | 'failed';
4010
+ readonly messageId?: string;
4011
+ readonly reason?: string;
4012
+ readonly sent?: number;
4013
+ readonly failed?: number;
4014
+ readonly platforms?: PushDeliveryPlatformCounts;
4015
+ readonly sentTo?: number;
4016
+ readonly expired?: number;
4017
+ }
4018
+ type SendPushResult = SendPushWireResult & {
4019
+ readonly sent: number;
4020
+ readonly failed: number;
4021
+ readonly sentTo: number;
4022
+ readonly expired: number;
4023
+ };
3998
4024
  /**
3999
4025
  * Register a push subscription
4000
4026
  *
@@ -4039,10 +4065,7 @@ declare function unregisterPush(config: SylphxConfig, endpoint: string): Promise
4039
4065
  * })
4040
4066
  * ```
4041
4067
  */
4042
- declare function sendPush(config: SylphxConfig, userId: string, notification: PushNotification): Promise<{
4043
- sentTo: number;
4044
- expired: number;
4045
- }>;
4068
+ declare function sendPush(config: SylphxConfig, userId: string, notification: PushNotification): Promise<SendPushResult>;
4046
4069
  /**
4047
4070
  * Get push notification preferences
4048
4071
  *
@@ -6696,7 +6719,7 @@ interface DatabaseConnectionInfo {
6696
6719
  /** Database name */
6697
6720
  databaseName: string;
6698
6721
  /** Database role/user name */
6699
- roleName: string | null;
6722
+ roleName: string;
6700
6723
  /** Database provisioning status */
6701
6724
  status: Exclude<DatabaseStatus, 'not_provisioned'>;
6702
6725
  }
@@ -6811,6 +6834,8 @@ interface KvSetRequest extends KvSetOptions {
6811
6834
  key: string;
6812
6835
  /** Value to store (any JSON-serializable value) */
6813
6836
  value: unknown;
6837
+ /** @deprecated Use `ex`. Kept for compatibility with early SDK adopters. */
6838
+ ttl?: number;
6814
6839
  }
6815
6840
  interface KvMsetRequest {
6816
6841
  /** Key-value pairs to set in a single atomic operation */
@@ -6886,12 +6911,14 @@ interface KvExpireRequest {
6886
6911
  seconds: number;
6887
6912
  }
6888
6913
  interface KvRateLimitRequest {
6889
- /** Rate limit identifier (e.g., userId, IP) */
6890
- identifier: string;
6914
+ /** Rate limit key (e.g., userId, IP) */
6915
+ key?: string;
6916
+ /** @deprecated Use `key`. Kept for compatibility with early SDK adopters. */
6917
+ identifier?: string;
6891
6918
  /** Maximum requests allowed in the window */
6892
6919
  limit: number;
6893
6920
  /** Window duration in seconds */
6894
- window: number;
6921
+ window: number | string;
6895
6922
  }
6896
6923
  /**
6897
6924
  * Set a key-value pair, with optional TTL and conditional flags.
@@ -7062,9 +7089,9 @@ declare function kvZrange(config: SylphxConfig, request: KvZrangeRequest): Promi
7062
7089
  * ```ts
7063
7090
  * // 10 requests per 60 seconds per user
7064
7091
  * const result = await kvRateLimit(config, {
7065
- * identifier: `user:${userId}`,
7092
+ * key: `user:${userId}`,
7066
7093
  * limit: 10,
7067
- * window: 60,
7094
+ * window: '60s',
7068
7095
  * })
7069
7096
  *
7070
7097
  * if (!result.success) {
@@ -7536,7 +7563,7 @@ interface SandboxOptions {
7536
7563
  createTimeoutMs?: number;
7537
7564
  /** Idle timeout in ms before auto-termination (default: 300_000 = 5 min) */
7538
7565
  idleTimeoutMs?: number;
7539
- /** Storage size in GiB (enables persistent PVC; default: disabled) */
7566
+ /** Scratch storage size in GiB at /data, scoped to the sandbox lifecycle. */
7540
7567
  storageGi?: number;
7541
7568
  /** CPU/memory resource spec */
7542
7569
  resources?: {
package/dist/index.mjs CHANGED
@@ -8138,6 +8138,7 @@ var PATHS = {
8138
8138
  uploadPart: (id, n) => `/storage/uploads/${encodeURIComponent(String(id))}/parts/${n}`,
8139
8139
  files: "/storage/files",
8140
8140
  file: (id) => `/storage/files/${encodeURIComponent(String(id))}`,
8141
+ fileTakedown: (id) => `/storage/files/${encodeURIComponent(String(id))}:takedown`,
8141
8142
  fileRestore: (id) => `/storage/files/${encodeURIComponent(String(id))}:restore`,
8142
8143
  fileSignedUrl: (id) => `/storage/files/${encodeURIComponent(String(id))}:signedUrl`,
8143
8144
  fileCopy: (id) => `/storage/files/${encodeURIComponent(String(id))}:copy`,
@@ -8462,6 +8463,12 @@ async function filesGet(config, fileId) {
8462
8463
  async function filesDelete(config, fileId) {
8463
8464
  return callApi(config, PATHS.file(fileId), { method: "DELETE" });
8464
8465
  }
8466
+ async function filesTakedown(config, fileId, options) {
8467
+ return callApi(config, PATHS.fileTakedown(fileId), {
8468
+ method: "POST",
8469
+ body: options
8470
+ });
8471
+ }
8465
8472
  async function filesRestore(config, fileId) {
8466
8473
  return callApi(config, PATHS.fileRestore(fileId), { method: "POST" });
8467
8474
  }
@@ -8506,6 +8513,7 @@ var storage = {
8506
8513
  list: filesList,
8507
8514
  get: filesGet,
8508
8515
  delete: filesDelete,
8516
+ takedown: filesTakedown,
8509
8517
  restore: filesRestore,
8510
8518
  signedUrl: filesSignedUrl,
8511
8519
  copy: filesCopy,
@@ -8668,6 +8676,16 @@ async function registerPushServiceWorker(swPath = "/sw.js") {
8668
8676
  }
8669
8677
 
8670
8678
  // src/notifications.ts
8679
+ function resolveSentCount(result) {
8680
+ if (result.sent !== void 0) return result.sent;
8681
+ if (result.sentTo !== void 0) return result.sentTo;
8682
+ return result.status === "delivered" ? 1 : 0;
8683
+ }
8684
+ function resolveFailedCount(result) {
8685
+ if (result.failed !== void 0) return result.failed;
8686
+ if (result.expired !== void 0) return result.expired;
8687
+ return result.status === "failed" ? 1 : 0;
8688
+ }
8671
8689
  async function registerPush(config, subscription) {
8672
8690
  await callApi(config, "/notifications/register", {
8673
8691
  method: "POST",
@@ -8688,10 +8706,19 @@ async function sendPush(config, userId, notification) {
8688
8706
  ...notification.icon !== void 0 && { icon: notification.icon },
8689
8707
  ...notification.url !== void 0 && { url: notification.url }
8690
8708
  };
8691
- return callApi(config, "/notifications/send", {
8709
+ const result = await callApi(config, "/notifications/send", {
8692
8710
  method: "POST",
8693
8711
  body
8694
8712
  });
8713
+ const sent = resolveSentCount(result);
8714
+ const failed = resolveFailedCount(result);
8715
+ return {
8716
+ ...result,
8717
+ sent,
8718
+ failed,
8719
+ sentTo: result.sentTo ?? sent,
8720
+ expired: result.expired ?? failed
8721
+ };
8695
8722
  }
8696
8723
  async function getPushPreferences(config) {
8697
8724
  return callApi(config, "/notifications/preferences", { method: "GET" });
@@ -9724,13 +9751,39 @@ function interpolatePath2(template, params) {
9724
9751
  }
9725
9752
  return path;
9726
9753
  }
9754
+ var KV_PATHS = {
9755
+ mset: "/kv/mset",
9756
+ mget: "/kv/mget",
9757
+ hset: "/kv/hset",
9758
+ hget: "/kv/hget",
9759
+ hgetall: "/kv/hgetall",
9760
+ lpush: "/kv/lpush",
9761
+ lrange: "/kv/lrange",
9762
+ zadd: "/kv/zadd",
9763
+ zrange: "/kv/zrange"
9764
+ };
9765
+ function toLegacyOkResult(result) {
9766
+ if (result.success !== void 0) return { ok: result.success };
9767
+ if (result.ok !== void 0) return { ok: result.ok };
9768
+ return { ok: false };
9769
+ }
9770
+ function resolveCreatedCount(result) {
9771
+ if (result.created !== void 0) return result.created;
9772
+ if (result.count !== void 0) return result.count;
9773
+ return 0;
9774
+ }
9727
9775
  async function kvSet(config, request) {
9728
- const body = request;
9776
+ const { ttl, ...rest } = request;
9777
+ const body = {
9778
+ ...rest,
9779
+ ...rest.ex === void 0 && ttl !== void 0 ? { ex: ttl } : {}
9780
+ };
9729
9781
  const endpoint = kvEndpoints.set;
9730
- return callApi(config, endpoint.path, {
9782
+ const result = await callApi(config, endpoint.path, {
9731
9783
  method: endpoint.method,
9732
9784
  body
9733
9785
  });
9786
+ return toLegacyOkResult(result);
9734
9787
  }
9735
9788
  async function kvGet(config, key) {
9736
9789
  const endpoint = kvEndpoints.get;
@@ -9756,10 +9809,11 @@ async function kvExists(config, key) {
9756
9809
  async function kvExpire(config, request) {
9757
9810
  const body = request;
9758
9811
  const endpoint = kvEndpoints.expire;
9759
- return callApi(config, endpoint.path, {
9812
+ const result = await callApi(config, endpoint.path, {
9760
9813
  method: endpoint.method,
9761
9814
  body
9762
9815
  });
9816
+ return toLegacyOkResult(result);
9763
9817
  }
9764
9818
  async function kvIncr(config, request) {
9765
9819
  const body = request;
@@ -9770,66 +9824,88 @@ async function kvIncr(config, request) {
9770
9824
  });
9771
9825
  }
9772
9826
  async function kvMset(config, request) {
9773
- return callApi(config, "/sdk/kv/mset", {
9827
+ const result = await callApi(config, KV_PATHS.mset, {
9774
9828
  method: "POST",
9775
9829
  body: request
9776
9830
  });
9831
+ return toLegacyOkResult(result);
9777
9832
  }
9778
9833
  async function kvMget(config, request) {
9779
- const result = await callApi(config, "/sdk/kv/mget", {
9780
- method: "POST",
9781
- body: request
9782
- });
9783
- return result.values;
9834
+ const result = await callApi(
9835
+ config,
9836
+ KV_PATHS.mget,
9837
+ {
9838
+ method: "POST",
9839
+ body: request
9840
+ }
9841
+ );
9842
+ const values = result.values;
9843
+ if (Array.isArray(values)) {
9844
+ return values;
9845
+ }
9846
+ return request.keys.map((key) => values[key] ?? null);
9784
9847
  }
9785
9848
  async function kvHset(config, request) {
9786
- return callApi(config, "/sdk/kv/hset", {
9849
+ const result = await callApi(config, KV_PATHS.hset, {
9787
9850
  method: "POST",
9788
9851
  body: request
9789
9852
  });
9853
+ return { count: resolveCreatedCount(result) };
9790
9854
  }
9791
9855
  async function kvHget(config, request) {
9792
- const result = await callApi(config, "/sdk/kv/hget", {
9856
+ const result = await callApi(config, KV_PATHS.hget, {
9793
9857
  method: "POST",
9794
9858
  body: request
9795
9859
  });
9796
9860
  return result.value;
9797
9861
  }
9798
9862
  async function kvHgetall(config, request) {
9799
- const result = await callApi(config, "/sdk/kv/hgetall", {
9863
+ const result = await callApi(config, KV_PATHS.hgetall, {
9800
9864
  method: "POST",
9801
9865
  body: request
9802
9866
  });
9803
- return result.value;
9867
+ if (result.fields !== void 0) return result.fields;
9868
+ if (result.value !== void 0) return result.value;
9869
+ return null;
9804
9870
  }
9805
9871
  async function kvLpush(config, request) {
9806
- return callApi(config, "/sdk/kv/lpush", {
9872
+ return callApi(config, KV_PATHS.lpush, {
9807
9873
  method: "POST",
9808
9874
  body: request
9809
9875
  });
9810
9876
  }
9811
9877
  async function kvLrange(config, request) {
9812
- const result = await callApi(config, "/sdk/kv/lrange", {
9878
+ const result = await callApi(config, KV_PATHS.lrange, {
9813
9879
  method: "POST",
9814
9880
  body: request
9815
9881
  });
9816
- return result.items;
9882
+ if (result.values !== void 0) return result.values;
9883
+ if (result.items !== void 0) return result.items;
9884
+ return [];
9817
9885
  }
9818
9886
  async function kvZadd(config, request) {
9819
- return callApi(config, "/sdk/kv/zadd", {
9887
+ return callApi(config, KV_PATHS.zadd, {
9820
9888
  method: "POST",
9821
9889
  body: request
9822
9890
  });
9823
9891
  }
9824
9892
  async function kvZrange(config, request) {
9825
- const result = await callApi(config, "/sdk/kv/zrange", {
9893
+ const result = await callApi(config, KV_PATHS.zrange, {
9826
9894
  method: "POST",
9827
9895
  body: request
9828
9896
  });
9829
9897
  return result.members;
9830
9898
  }
9831
9899
  async function kvRateLimit(config, request) {
9832
- const body = request;
9900
+ const key = request.key ?? request.identifier;
9901
+ if (!key) {
9902
+ throw new Error("kvRateLimit requires `key`");
9903
+ }
9904
+ const body = {
9905
+ key,
9906
+ limit: request.limit,
9907
+ window: typeof request.window === "number" ? `${request.window}s` : request.window
9908
+ };
9833
9909
  const endpoint = kvEndpoints.rateLimit;
9834
9910
  return callApi(config, endpoint.path, {
9835
9911
  method: endpoint.method,