connectbase-client 3.46.0 → 3.48.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/dist/index.d.ts CHANGED
@@ -173,13 +173,20 @@ declare class HttpClient {
173
173
  * 한 번 settle 되면 그 결과(메모리 적재 또는 미로그인)가 항상 반영되어 있다.
174
174
  */
175
175
  private bootRestorePromise;
176
+ private bootRestoreAlwaysAwait;
176
177
  constructor(config: HttpClientConfig);
177
178
  /**
178
179
  * 페이지 진입 시 fire-and-forget 으로 시작된 cookie 복구 promise 를 SDK 가 등록한다.
179
180
  * 같은 promise 가 `prepareHeaders` 에서 await 되어, 첫 인증 호출이 cookie 복구
180
181
  * 완료 후 발화한다.
182
+ *
183
+ * options.alwaysAwait=true 면 세션 힌트가 없어도 첫 인증 호출이 이 promise 를
184
+ * 기다린다 — OAuth 리다이렉트 콜백처럼 "이 부트 promise 가 곧 세션을 만든다"는 것이
185
+ * 확실한 흐름용 (일반 cookie 복구는 힌트 기반 fast-path 적용).
181
186
  */
182
- setBootRestorePromise(p: Promise<boolean>): void;
187
+ setBootRestorePromise(p: Promise<boolean>, options?: {
188
+ alwaysAwait?: boolean;
189
+ }): void;
183
190
  /** 최근 호출 ring buffer 스냅샷 (시간순). */
184
191
  getRecentCalls(): RecentApiCall[];
185
192
  /** 최근 호출 buffer clear (테스트/프라이버시 처리). */
@@ -188,6 +195,10 @@ declare class HttpClient {
188
195
  updateConfig(config: Partial<HttpClientConfig>): void;
189
196
  setTokens(accessToken: string, refreshToken: string): void;
190
197
  clearTokens(): void;
198
+ private buildSessionHintKey;
199
+ private markSessionHint;
200
+ private clearSessionHint;
201
+ private hasSessionHint;
191
202
  /**
192
203
  * OAuth redirect callback 직후 호출되어 HttpOnly cookie 를 부트스트랩한다.
193
204
  *
@@ -1174,7 +1185,12 @@ interface UpdateDataRequest {
1174
1185
  interface FetchDataResponse {
1175
1186
  /** 조회된 문서 배열 */
1176
1187
  data: DataItem[];
1177
- /** 총 매칭 문서 수 */
1188
+ /**
1189
+ * 총 매칭 문서 수.
1190
+ *
1191
+ * `count: false` 로 조회한 경우: 마지막 페이지(반환 건수 < limit)면 서버가 정확한
1192
+ * 총계를 파생해 돌려주고, 아니면 `-1` (미상) 이 반환됩니다.
1193
+ */
1178
1194
  total_count: number;
1179
1195
  }
1180
1196
  interface QueryOptions {
@@ -1187,6 +1203,14 @@ interface QueryOptions {
1187
1203
  select?: string[];
1188
1204
  /** 제외할 필드 목록 - 지정된 필드를 제외하고 반환 */
1189
1205
  exclude?: string[];
1206
+ /**
1207
+ * `false` 면 `total_count` 계산(서버측 COUNT 쿼리)을 생략합니다.
1208
+ *
1209
+ * 필터가 붙은 COUNT 는 본 조회와 같은 비용의 스캔을 한 번 더 도는 것이므로,
1210
+ * 총계가 필요 없는 목록/무한스크롤 조회는 `count: false` 로 눈에 띄게 빨라집니다.
1211
+ * 생략 시 기본값은 `true` (기존 동작 유지).
1212
+ */
1213
+ count?: boolean;
1190
1214
  }
1191
1215
  type WhereCondition = {
1192
1216
  /** OR 조건: 배열 내 조건들 중 하나 이상 만족 */
@@ -4015,7 +4039,7 @@ declare class OAuthAPI {
4015
4039
  } | null>;
4016
4040
  }
4017
4041
 
4018
- type PaymentProvider = "toss" | "stripe" | "payapp";
4042
+ type PaymentProvider = "toss" | "stripe" | "payapp" | "paypal";
4019
4043
  type PaymentStatus = "pending" | "ready" | "in_progress" | "done" | "canceled" | "partial_canceled" | "aborted" | "expired" | "failed";
4020
4044
  interface PreparePaymentRequest {
4021
4045
  amount: number;
@@ -4040,6 +4064,8 @@ interface PreparePaymentResponse {
4040
4064
  stripe_publishable_key?: string;
4041
4065
  payapp_pay_url?: string;
4042
4066
  payapp_mul_no?: string;
4067
+ paypal_approve_url?: string;
4068
+ paypal_order_id?: string;
4043
4069
  }
4044
4070
  interface CreateCheckoutSessionRequest {
4045
4071
  amount: number;
@@ -4065,6 +4091,7 @@ interface ConfirmPaymentRequest {
4065
4091
  order_id: string;
4066
4092
  amount: number;
4067
4093
  stripe_payment_intent_id?: string;
4094
+ paypal_order_id?: string;
4068
4095
  }
4069
4096
  interface ConfirmPaymentResponse {
4070
4097
  payment_id: string;
@@ -4110,6 +4137,40 @@ interface PaymentDetail {
4110
4137
  created_at: string;
4111
4138
  updated_at: string;
4112
4139
  }
4140
+ /** `cb.payment.list` 필터 옵션. 모두 선택. 백엔드 `ListPaymentsRequest` 쿼리에 매핑. */
4141
+ interface ListPaymentsOptions {
4142
+ /** pending | done | canceled | failed */
4143
+ status?: string;
4144
+ /** ISO8601(RFC3339) 시작일 필터. */
4145
+ startDate?: string;
4146
+ /** ISO8601(RFC3339) 종료일 필터. */
4147
+ endDate?: string;
4148
+ /** 기본 50. */
4149
+ limit?: number;
4150
+ offset?: number;
4151
+ }
4152
+ /** 결제 목록 항목. 백엔드 `PaymentListItem` 매핑. */
4153
+ interface PaymentListItem {
4154
+ payment_id: string;
4155
+ order_id: string;
4156
+ order_name: string;
4157
+ amount: number;
4158
+ status: PaymentStatus;
4159
+ method?: string;
4160
+ /** toss | stripe 등 */
4161
+ payment_provider: string;
4162
+ customer_name?: string;
4163
+ customer_email?: string;
4164
+ approved_at?: string;
4165
+ created_at: string;
4166
+ }
4167
+ /** `cb.payment.list` 반환값. 백엔드 `ListPaymentsResponse` 매핑. */
4168
+ interface PaymentListResult {
4169
+ payments: PaymentListItem[];
4170
+ total: number;
4171
+ limit: number;
4172
+ offset: number;
4173
+ }
4113
4174
 
4114
4175
  declare class PaymentAPI {
4115
4176
  private http;
@@ -4251,6 +4312,20 @@ declare class PaymentAPI {
4251
4312
  * ```
4252
4313
  */
4253
4314
  getByOrderId(orderId: string): Promise<PaymentDetail>;
4315
+ /**
4316
+ * 앱의 결제 내역 목록을 조회한다 (필터/페이지네이션 지원).
4317
+ *
4318
+ * 서버사이드 전용 — service_role(ctx.cbAdmin, management_scopes=["payment:read"]) 또는 콘솔 JWT
4319
+ * 인증이 필요하다. 재무 데이터이므로 Public Key(cb_pk_) 단독 브라우저 SDK 인스턴스로는 호출할 수
4320
+ * 없다. (다른 payment 메서드와 달리 /v1/public 이 아니라 앱 스코프 dual-auth 라우트를 쓴다.)
4321
+ *
4322
+ * @example
4323
+ * ```typescript
4324
+ * // 함수(service_role, management_scopes: ["payment:read"]) 안에서
4325
+ * const { payments, total } = await ctx.cbAdmin.payment.list(ctx.appId, { status: 'done', limit: 20 })
4326
+ * ```
4327
+ */
4328
+ list(appId: string, options?: ListPaymentsOptions): Promise<PaymentListResult>;
4254
4329
  }
4255
4330
 
4256
4331
  interface IssueBillingKeyRequest {
@@ -4358,9 +4433,11 @@ interface SubscriptionResponse {
4358
4433
  /** 구독 ID (문자열) */
4359
4434
  subscription_id: string;
4360
4435
  /** 결제 프로바이더 */
4361
- provider?: 'toss' | 'stripe' | 'payapp';
4436
+ provider?: 'toss' | 'stripe' | 'payapp' | 'paypal';
4362
4437
  /** payapp: 카드등록+1회차 결제창 URL. 이 URL로 사용자를 redirect 시킨다 (위젯 불필요) */
4363
4438
  payapp_pay_url?: string;
4439
+ /** paypal: 구독 승인+결제수단 등록 URL. 이 URL로 사용자를 redirect 시킨다 (위젯 불필요) */
4440
+ paypal_approve_url?: string;
4364
4441
  /** 플랜 이름 */
4365
4442
  plan_name: string;
4366
4443
  /** 플랜 설명 */
@@ -4864,6 +4941,29 @@ interface SendPushResult {
4864
4941
  status: string;
4865
4942
  error_message?: string;
4866
4943
  }
4944
+ /**
4945
+ * 푸시 통계. 백엔드 `dto.PushStatsResponse` 와 1:1 매핑. `cb.push.getStats` 반환값.
4946
+ * open_rate / click_rate 는 % 단위. 서버사이드(ctx.cbAdmin) 전용 — Public Key 단독 SDK 는 호출 불가.
4947
+ */
4948
+ interface PushStatsResult {
4949
+ total_devices: number;
4950
+ active_devices: number;
4951
+ ios_devices: number;
4952
+ android_devices: number;
4953
+ web_devices: number;
4954
+ total_messages: number;
4955
+ sent_messages: number;
4956
+ failed_messages: number;
4957
+ pending_messages: number;
4958
+ total_topics: number;
4959
+ total_sent: number;
4960
+ total_opened: number;
4961
+ total_clicked: number;
4962
+ /** 열람율 (%) */
4963
+ open_rate: number;
4964
+ /** 클릭율 (%) */
4965
+ click_rate: number;
4966
+ }
4867
4967
  /**
4868
4968
  * 푸시 알림 API
4869
4969
  *
@@ -5054,6 +5154,21 @@ declare class PushAPI {
5054
5154
  * ```
5055
5155
  */
5056
5156
  sendToTopic(appId: string, topicName: string, payload: SendToTopicPayload): Promise<SendPushResult>;
5157
+ /**
5158
+ * 앱의 푸시 통계(도달/오픈율/클릭율, 디바이스/메시지/토픽 수)를 조회한다.
5159
+ *
5160
+ * 서버사이드 전용 — service_role(ctx.cbAdmin, management_scopes=["push:read"]) 또는 콘솔 JWT
5161
+ * 인증이 필요하다. sendToMembers/sendToTopic 과 동일한 위임 가드 — cb_pk_ 단독(브라우저) SDK
5162
+ * 인스턴스는 차단하고, 위임 Bearer(ctx.cbAdmin) 인스턴스는 허용한다.
5163
+ *
5164
+ * @example
5165
+ * ```typescript
5166
+ * // 함수(service_role, management_scopes: ["push:read"]) 안에서
5167
+ * const stats = await ctx.cbAdmin.push.getStats(ctx.appId)
5168
+ * console.log(stats.open_rate, stats.click_rate)
5169
+ * ```
5170
+ */
5171
+ getStats(appId: string): Promise<PushStatsResult>;
5057
5172
  /**
5058
5173
  * 브라우저 고유 ID 생성 (localStorage에 저장)
5059
5174
  */
@@ -5068,6 +5183,108 @@ declare class PushAPI {
5068
5183
  private getOSInfo;
5069
5184
  }
5070
5185
 
5186
+ /** 역할 목록 항목. 백엔드 `fetchRoleItem` 매핑. */
5187
+ interface RoleListItem {
5188
+ id: string;
5189
+ role_title: string;
5190
+ role_description: string;
5191
+ create_time: string;
5192
+ permission_count: number;
5193
+ user_count: number;
5194
+ }
5195
+ /** `cb.roles.list` 반환값. 백엔드 `FetchRolesResponse` 매핑. */
5196
+ interface RoleList {
5197
+ total_count: number;
5198
+ role_list: RoleListItem[];
5199
+ }
5200
+ /** 역할이 가진 권한 항목. */
5201
+ interface RolePermissionItem {
5202
+ id: number;
5203
+ name: string;
5204
+ category: string;
5205
+ description: string;
5206
+ }
5207
+ /** 역할에 할당된 사용자 항목. */
5208
+ interface RoleUserItem {
5209
+ id: string;
5210
+ nickname: string;
5211
+ email: string | null;
5212
+ assign_time: string;
5213
+ }
5214
+ /** `cb.roles.get` 반환값. 백엔드 `FetchRoleDetailResponse` 매핑. */
5215
+ interface RoleDetail {
5216
+ role_name: string;
5217
+ role_description: string;
5218
+ create_time: string;
5219
+ permission_item: RolePermissionItem[];
5220
+ user_item: RoleUserItem[];
5221
+ }
5222
+ /** `cb.roles.create` 페이로드. */
5223
+ interface CreateRolePayload {
5224
+ title: string;
5225
+ description: string;
5226
+ /** 생성과 동시에 부여할 권한 ID 목록 (선택). 없으면 빈 역할로 생성. */
5227
+ permissionIds?: number[];
5228
+ }
5229
+ /** `cb.roles.create` 반환값. */
5230
+ interface CreateRoleResult {
5231
+ id: string;
5232
+ role_title: string;
5233
+ role_description: string;
5234
+ }
5235
+ /**
5236
+ * `cb.roles.update` 페이로드. 백엔드 EditRole 은 **전체 동기화(replace)** 라 모든 필드가 필수다 —
5237
+ * permissionIds / userIds 는 "이 역할이 가질 전체"를 의미하며, 전달값으로 완전히 대체된다.
5238
+ * 사용자만 바꾸고 나머지를 보존하려면 `assign` 을 쓰거나 `get` 으로 현재 값을 읽어 합쳐라.
5239
+ */
5240
+ interface UpdateRolePayload {
5241
+ title: string;
5242
+ description: string;
5243
+ /** 이 역할이 가질 권한 ID 전체 (동기화). */
5244
+ permissionIds: number[];
5245
+ /** 이 역할을 가질 사용자 ID 전체 (동기화). */
5246
+ userIds: string[];
5247
+ }
5248
+ /**
5249
+ * 앱 역할(RBAC) 관리 API — 서버사이드 전용.
5250
+ *
5251
+ * service_role 함수(ctx.cbAdmin) 또는 콘솔 JWT 인증이 필요하며, Public Key(cb_pk_) 단독 브라우저
5252
+ * SDK 인스턴스로는 호출할 수 없다. service_role 함수에서 쓰려면 management_scopes 가 필요하다 —
5253
+ * 조회(list/get)는 `role:read`, 변경(create/update/assign/delete)은 `role:manage`.
5254
+ *
5255
+ * @example
5256
+ * ```typescript
5257
+ * // 함수(service_role, management_scopes: ["role:read","role:manage"]) 안에서
5258
+ * const roles = await ctx.cbAdmin.roles.list(ctx.appId)
5259
+ * const { id } = await ctx.cbAdmin.roles.create(ctx.appId, { title: '읽기전용 운영자', description: '조회만' })
5260
+ * await ctx.cbAdmin.roles.assign(ctx.appId, id, ['user-uuid-1', 'user-uuid-2'])
5261
+ * ```
5262
+ */
5263
+ declare class RolesAPI {
5264
+ private http;
5265
+ constructor(http: HttpClient);
5266
+ private ensureServerAuth;
5267
+ /** 앱의 역할 목록을 조회한다. (management_scope: `role:read`) */
5268
+ list(appId: string): Promise<RoleList>;
5269
+ /** 역할 상세(권한/할당 사용자 포함)를 조회한다. (management_scope: `role:read`) */
5270
+ get(appId: string, roleId: string): Promise<RoleDetail>;
5271
+ /** 역할을 생성한다. (management_scope: `role:manage`) */
5272
+ create(appId: string, payload: CreateRolePayload): Promise<CreateRoleResult>;
5273
+ /**
5274
+ * 역할을 수정한다 — **전체 동기화(replace)**. permissionIds / userIds 는 전달값으로 대체된다.
5275
+ * (management_scope: `role:manage`)
5276
+ */
5277
+ update(appId: string, roleId: string, payload: UpdateRolePayload): Promise<void>;
5278
+ /**
5279
+ * 역할에 사용자를 할당한다 (제목/설명/권한 보존). EditRole 이 전체 동기화라, 현재 상세를 읽어
5280
+ * 나머지 필드를 유지한 채 사용자 목록만 교체해 PUT 한다. userIds 는 "이 역할을 가질 사용자
5281
+ * 전체"다 (추가가 아니라 동기화). (management_scope: `role:manage`)
5282
+ */
5283
+ assign(appId: string, roleId: string, userIds: string[]): Promise<void>;
5284
+ /** 역할을 삭제한다. (management_scope: `role:manage`) */
5285
+ delete(appId: string, roleId: string): Promise<void>;
5286
+ }
5287
+
5071
5288
  interface Video {
5072
5289
  id: string;
5073
5290
  channel_id: string;
@@ -8993,6 +9210,11 @@ declare class ConnectBase {
8993
9210
  * 푸시 알림 API
8994
9211
  */
8995
9212
  readonly push: PushAPI;
9213
+ /**
9214
+ * 앱 역할(RBAC) 관리 API — 서버사이드 전용(ctx.cbAdmin / 콘솔 JWT).
9215
+ * service_role 함수에서는 management_scopes(role:read / role:manage)가 필요하다.
9216
+ */
9217
+ readonly roles: RolesAPI;
8996
9218
  /**
8997
9219
  * 비디오 API (동영상 업로드/스트리밍)
8998
9220
  */
@@ -9082,4 +9304,4 @@ declare class ConnectBase {
9082
9304
  updateConfig(config: Partial<ConnectBaseConfig>): void;
9083
9305
  }
9084
9306
 
9085
- export { AIAPI, type AIChatRequest, type AIChatResponse, type AIChatStreamCallbacks, type AIChatStreamOptions, type AIMessage, type AISource, type AIStreamChunk, type AITool, type AIToolCall, type AIToolEvent, AUTH_MEMBER_ID_TOKEN, type AckMessagesRequest, type AdMobDailyReport, type AdMobReportResponse, type AdMobReportSummary, type AdReportResponse, type AdReportSummary, type AdmobConnectionInfo, AdsAPI, type AdsenseConnectionInfo, type AgenticSearchProgress, type AggregateResult, type AggregateStage, type AnalyticsConfig, type AnalyticsEvent, ApiError, type ApiErrorDetail, type AppStatsResponse, type ArchivePolicy, type AtomicOperator, type AtomicOperatorType, AuthError, type AuthSettingsResponse, type BackupInfo, type BatchOperation, type BatchOperationResult, type BatchSetPageMetaRequest, type BatchWriteResult, type BillingCycle, type BillingKeyResponse, type BiometricInfo, type BiometricResult, type BulkCreateResponse, type BulkError, type CPUInfo, type CancelPaymentRequest, type CancelPaymentResponse, type CancelSubscriptionRequest, type CategoryInfo, type Channel, type ChannelMembership, type ChannelStats, type ChargeWithBillingKeyRequest, type ChargeWithBillingKeyResponse, type ChatMessage, type ClientMessage, type ColumnSchema, type CommentListResponse, type CompleteUploadRequest, type CompleteUploadResponse, type ConfirmBillingKeyRequest, type ConfirmPaymentRequest, type ConfirmPaymentResponse, ConnectBase, type ConnectBaseConfig, type ConnectedData, type ConnectionState, type ConsentOptions, type ConsumeMessagesResponse, type ConsumeOptions, type CopyTableRequest, type CopyTableResponse, type CreateBackupRequest, type CreateChannelRequest, type CreateCheckoutSessionRequest, type CreateCheckoutSessionResponse, type CreateColumnRequest, type CreateDataRequest, type CreateDocumentRequest, type CreateFolderRequest, type CreateFolderResponse, type CreateGeoIndexRequest, type CreateIndexRequest, type CreateLobbyRequest, type CreatePlaylistRequest, type CreatePublicKeyRequest, type CreatePublicKeyResponse, type CreateRelationRequest, type CreateRoomResult, type CreateSearchIndexRequest, type CreateSecurityRuleRequest, type CreateSubscriptionRequest, type CreateTableRequest, type CreateTriggerRequest, type CreateVideoStorageRequest, type DailyReport, type DataItem, type DataType, type DatabaseChange, type DatabaseChangeMessage, type DatabaseChangeType, type DatabaseRealtimeConnectOptions, type DatabaseRealtimeFilter, type DatabaseRealtimeHandlers, type DatabaseRealtimeSubscription, type DatabaseSnapshot, type DatabaseSnapshotMessage, type DatabaseSubscribeOptions, type DeleteWhereResponse, type DeviceInfo, type DocumentResponse, type EnabledProviderInfo, type EnabledProvidersResponse, EndpointAPI, type EndpointCallInit, type ErrorHandler, type ErrorMessage, type ErrorReport, type ErrorTrackerConfig, type ErrorType, type ExportDataRequest, type ExportDataResponse, type FetchDataResponse, type FetchFilesResponse, type FetchPublicKeysResponse, type FileItem, type FileStats, GameAPI, type GameAction, type GameClientConfig, type GameConfig, GameConfigAPI, type GameConfigPatch, type GameConnectionState, type GameConnectionStatus, type GameDelta, GameError, type GameErrorCode, type GameEventHandlers, type GamePlayer, GameRoom, type GameRoomConfig, type GameRoomInfo, GameRoomTransport, type GameServerMessage, type GameServerMessageType, type GameState, type GameTransportConfig, type GenerateUploadURLByPathRequest, type GenerateUploadURLRequest, type GenerateUploadURLResponse, type GeoBoundingBox, type GeoIndex, type GeoNear, type GeoPoint, type GeoPolygon, type GeoQuery, type GeoResponse, type GeoResult, type GetAuthorizationURLResponse, type GetFileByPathResponse, type GoogleConnectionStatus, type HistoryResponse, type ICEServer, type ICEServersResponse, type ImageResult, type ImportDataRequest, type ImportDataResponse, type IndexAnalysis, type IndexRecommendation, type InitUploadResponse, type InvokeFunctionRequest, type InvokeFunctionResponse, type IssueBillingKeyRequest, type IssueBillingKeyResponse, type JoinQueueRequest, type JoinRoomRequest, type JoinRoomResponse, type KnowledgeSearchRequest, type KnowledgeSearchResponse, type KnowledgeSearchResult, type LeaderboardEntry, type LeaderboardListResponse, type LeaderboardScoreEntry, type LifecyclePolicy, type ListBillingKeysResponse, type ListDocumentsResponse, type ListPageMetasOptions, type ListPageMetasResponse, type ListSubscriptionPaymentsRequest, type ListSubscriptionPaymentsResponse, type ListSubscriptionsRequest, type ListSubscriptionsResponse, type LobbyInfo, type LobbyInvite, type LobbyMember, type LobbyVisibility, type MatchResult, type MatchmakingTicket, type MatchqueueListResponse, type MatchqueueTicket, type MemberInfoResponse, type MemberSignInRequest, type MemberSignInResponse, type MemberSignUpRequest, type MemberSignUpResponse, type MembershipTier, type MemoryInfo, type MessageHandler, type MigrateDataRequest, type MigrateDataResponse, type MoveFileRequest, type NackMessageRequest, NativeAPI, type OAuthCallbackResponse, type OAuthProvider, type OpenDialogOptions, type OpenDialogResult, type PageMetaResponse, type PartyInfo, type PartyInvite, type PartyMember, type PauseSubscriptionRequest, type PaymentDetail, type PaymentProvider, type PaymentStatus, type PeerInfo, type Platform, type PlayerEvent, type PlayerStats, type Playlist, type PlaylistItem, type PollUntilOptions, type PongMessage, type PopulateOption, type Position, type PreparePaymentRequest, type PreparePaymentResponse, type PresenceChangeHandler, type PresenceInfo, type PresenceSetOptions, type PresenceStatus, type PresenceStatusResult, type PublicKeyItem, type PublishBatchRequest, type PublishBatchResponse, type PublishMessageRequest, type PublishMessageResponse, type PushPlatform, type QualityProgress, type QueryOptions, type QueueInfoResponse, type QueueMessage, type ReadReceiptHandler, type ReadReceiptInfo, type RealtimeConnectOptions, type RealtimeMessage, type RegisterDeviceRequest, type RelationType, type RenameFileRequest, type RenameFileResponse, type ReplayHighlight, type ReplayInfo, type ReplayPlayerInfo, type RestoreBackupRequest, type RestoreBackupResponse, type RetentionPolicy, type RoomInfo, type RoomStaleMessage, type RoomSummary, type RoomsResponse, type SaveDialogOptions, type SaveDialogResult, type ScriptDetailResponse, type ScriptListResponse, type ScriptMeta, type ScriptVersion, type ScriptVersionListResponse, type SearchIndex, type SearchOptions, type SearchResponse, type SearchResult, type SecurityRule, type SendOptions, type SendSuperChatOptions, type SendSuperChatResponse, type ServerMessage, SessionManager, type SetPageMetaRequest, type Shorts, type ShortsListResponse, type SignalingMessage, type SignalingMessageType, type SlowQueryInfo, type SpectatorInfo, type SpectatorPlayerState, type SpectatorState, type SpeechRecognizeOptions, type SpeechResult, type StateChange, type StateChangeHandler, type StorageUploadOptions, type StreamContentPart, type StreamDoneCallback, type StreamDoneData, type StreamErrorCallback, type StreamHandlers, type StreamImageURLPart, type StreamMessage, type StreamOptions, type StreamSession, type StreamTextPart, type StreamTokenCallback, type StreamToolCallCallback, type StreamToolResultCallback, type StreamURLResponse, type SubscribeOptions, type SubscribeTopicRequest, type SubscribedData, type Subscription, type SubscriptionPaymentResponse, type SubscriptionPaymentStatus, type SubscriptionResponse, type SubscriptionStatus, type SuperChat, type SuperChatType, type SystemInfo, type TTLConfig, type TableAccessLevel, type TableColumnDef, type TableIndex, type TableRelation, type TableSchema, type TableSchemaDefinition, type TokenPersistence, type TransactionRead, type TransactionResult, type TransactionWrite, type TransactionWriteResult, type TranscodeStatus, type TransportType, type Trigger, type TriggerEvent, type TriggerHandlerType, type TypingChangeHandler, type TypingInfo, type UpdateBillingKeyRequest, type UpdateChannelRequest, type UpdateColumnRequest, type UpdateCustomDataRequest, type UpdateCustomDataResponse, type UpdateDataRequest, type UpdateDocumentRequest, type UpdateLobbyRequest, type UpdatePublicKeyRequest, type UpdatePublicKeyResponse, type UpdateSecurityRuleRequest, type UpdateSubscriptionRequest, type UpdateTriggerRequest, type UpdateVideoRequest, type UpdateVideoStorageRequest, type UploadByPathOptions, type UploadFileResponse, type UploadOptions, type UploadProgress, type VAPIDPublicKeyResponse, type ValidateResponse, type ValidationSchema, type ValidationSchemaField, type ValidationStateTransitions, type Video, type VideoComment, type VideoCompleteUploadResponse, type VideoListOptions, type VideoListResponse, VideoProcessingError, type VideoQuality, type VideoStatus, type VideoStorage, type VideoStorageListResponse, type VideoVisibility, type VoiceChannel, type VoiceMember, type WaitOptions, type WatchHistoryItem, type WebPushSubscription, type WebRTCConnectOptions, type WebRTCConnectionState, type WebRTCMode, type WhereCondition, type WhereOperator, ConnectBase as default, detectInAppBrowser, escapeToExternalBrowser, isWebTransportSupported, toCreateRoomWire };
9307
+ export { AIAPI, type AIChatRequest, type AIChatResponse, type AIChatStreamCallbacks, type AIChatStreamOptions, type AIMessage, type AISource, type AIStreamChunk, type AITool, type AIToolCall, type AIToolEvent, AUTH_MEMBER_ID_TOKEN, type AckMessagesRequest, type AdMobDailyReport, type AdMobReportResponse, type AdMobReportSummary, type AdReportResponse, type AdReportSummary, type AdmobConnectionInfo, AdsAPI, type AdsenseConnectionInfo, type AgenticSearchProgress, type AggregateResult, type AggregateStage, type AnalyticsConfig, type AnalyticsEvent, ApiError, type ApiErrorDetail, type AppStatsResponse, type ArchivePolicy, type AtomicOperator, type AtomicOperatorType, AuthError, type AuthSettingsResponse, type BackupInfo, type BatchOperation, type BatchOperationResult, type BatchSetPageMetaRequest, type BatchWriteResult, type BillingCycle, type BillingKeyResponse, type BiometricInfo, type BiometricResult, type BulkCreateResponse, type BulkError, type CPUInfo, type CancelPaymentRequest, type CancelPaymentResponse, type CancelSubscriptionRequest, type CategoryInfo, type Channel, type ChannelMembership, type ChannelStats, type ChargeWithBillingKeyRequest, type ChargeWithBillingKeyResponse, type ChatMessage, type ClientMessage, type ColumnSchema, type CommentListResponse, type CompleteUploadRequest, type CompleteUploadResponse, type ConfirmBillingKeyRequest, type ConfirmPaymentRequest, type ConfirmPaymentResponse, ConnectBase, type ConnectBaseConfig, type ConnectedData, type ConnectionState, type ConsentOptions, type ConsumeMessagesResponse, type ConsumeOptions, type CopyTableRequest, type CopyTableResponse, type CreateBackupRequest, type CreateChannelRequest, type CreateCheckoutSessionRequest, type CreateCheckoutSessionResponse, type CreateColumnRequest, type CreateDataRequest, type CreateDocumentRequest, type CreateFolderRequest, type CreateFolderResponse, type CreateGeoIndexRequest, type CreateIndexRequest, type CreateLobbyRequest, type CreatePlaylistRequest, type CreatePublicKeyRequest, type CreatePublicKeyResponse, type CreateRelationRequest, type CreateRolePayload, type CreateRoleResult, type CreateRoomResult, type CreateSearchIndexRequest, type CreateSecurityRuleRequest, type CreateSubscriptionRequest, type CreateTableRequest, type CreateTriggerRequest, type CreateVideoStorageRequest, type DailyReport, type DataItem, type DataType, type DatabaseChange, type DatabaseChangeMessage, type DatabaseChangeType, type DatabaseRealtimeConnectOptions, type DatabaseRealtimeFilter, type DatabaseRealtimeHandlers, type DatabaseRealtimeSubscription, type DatabaseSnapshot, type DatabaseSnapshotMessage, type DatabaseSubscribeOptions, type DeleteWhereResponse, type DeviceInfo, type DocumentResponse, type EnabledProviderInfo, type EnabledProvidersResponse, EndpointAPI, type EndpointCallInit, type ErrorHandler, type ErrorMessage, type ErrorReport, type ErrorTrackerConfig, type ErrorType, type ExportDataRequest, type ExportDataResponse, type FetchDataResponse, type FetchFilesResponse, type FetchPublicKeysResponse, type FileItem, type FileStats, GameAPI, type GameAction, type GameClientConfig, type GameConfig, GameConfigAPI, type GameConfigPatch, type GameConnectionState, type GameConnectionStatus, type GameDelta, GameError, type GameErrorCode, type GameEventHandlers, type GamePlayer, GameRoom, type GameRoomConfig, type GameRoomInfo, GameRoomTransport, type GameServerMessage, type GameServerMessageType, type GameState, type GameTransportConfig, type GenerateUploadURLByPathRequest, type GenerateUploadURLRequest, type GenerateUploadURLResponse, type GeoBoundingBox, type GeoIndex, type GeoNear, type GeoPoint, type GeoPolygon, type GeoQuery, type GeoResponse, type GeoResult, type GetAuthorizationURLResponse, type GetFileByPathResponse, type GoogleConnectionStatus, type HistoryResponse, type ICEServer, type ICEServersResponse, type ImageResult, type ImportDataRequest, type ImportDataResponse, type IndexAnalysis, type IndexRecommendation, type InitUploadResponse, type InvokeFunctionRequest, type InvokeFunctionResponse, type IssueBillingKeyRequest, type IssueBillingKeyResponse, type JoinQueueRequest, type JoinRoomRequest, type JoinRoomResponse, type KnowledgeSearchRequest, type KnowledgeSearchResponse, type KnowledgeSearchResult, type LeaderboardEntry, type LeaderboardListResponse, type LeaderboardScoreEntry, type LifecyclePolicy, type ListBillingKeysResponse, type ListDocumentsResponse, type ListPageMetasOptions, type ListPageMetasResponse, type ListPaymentsOptions, type ListSubscriptionPaymentsRequest, type ListSubscriptionPaymentsResponse, type ListSubscriptionsRequest, type ListSubscriptionsResponse, type LobbyInfo, type LobbyInvite, type LobbyMember, type LobbyVisibility, type MatchResult, type MatchmakingTicket, type MatchqueueListResponse, type MatchqueueTicket, type MemberInfoResponse, type MemberSignInRequest, type MemberSignInResponse, type MemberSignUpRequest, type MemberSignUpResponse, type MembershipTier, type MemoryInfo, type MessageHandler, type MigrateDataRequest, type MigrateDataResponse, type MoveFileRequest, type NackMessageRequest, NativeAPI, type OAuthCallbackResponse, type OAuthProvider, type OpenDialogOptions, type OpenDialogResult, type PageMetaResponse, type PartyInfo, type PartyInvite, type PartyMember, type PauseSubscriptionRequest, type PaymentDetail, type PaymentListItem, type PaymentListResult, type PaymentProvider, type PaymentStatus, type PeerInfo, type Platform, type PlayerEvent, type PlayerStats, type Playlist, type PlaylistItem, type PollUntilOptions, type PongMessage, type PopulateOption, type Position, type PreparePaymentRequest, type PreparePaymentResponse, type PresenceChangeHandler, type PresenceInfo, type PresenceSetOptions, type PresenceStatus, type PresenceStatusResult, type PublicKeyItem, type PublishBatchRequest, type PublishBatchResponse, type PublishMessageRequest, type PublishMessageResponse, type PushPlatform, type PushStatsResult, type QualityProgress, type QueryOptions, type QueueInfoResponse, type QueueMessage, type ReadReceiptHandler, type ReadReceiptInfo, type RealtimeConnectOptions, type RealtimeMessage, type RegisterDeviceRequest, type RelationType, type RenameFileRequest, type RenameFileResponse, type ReplayHighlight, type ReplayInfo, type ReplayPlayerInfo, type RestoreBackupRequest, type RestoreBackupResponse, type RetentionPolicy, type RoleDetail, type RoleList, type RoleListItem, type RolePermissionItem, type RoleUserItem, RolesAPI, type RoomInfo, type RoomStaleMessage, type RoomSummary, type RoomsResponse, type SaveDialogOptions, type SaveDialogResult, type ScriptDetailResponse, type ScriptListResponse, type ScriptMeta, type ScriptVersion, type ScriptVersionListResponse, type SearchIndex, type SearchOptions, type SearchResponse, type SearchResult, type SecurityRule, type SendOptions, type SendSuperChatOptions, type SendSuperChatResponse, type ServerMessage, SessionManager, type SetPageMetaRequest, type Shorts, type ShortsListResponse, type SignalingMessage, type SignalingMessageType, type SlowQueryInfo, type SpectatorInfo, type SpectatorPlayerState, type SpectatorState, type SpeechRecognizeOptions, type SpeechResult, type StateChange, type StateChangeHandler, type StorageUploadOptions, type StreamContentPart, type StreamDoneCallback, type StreamDoneData, type StreamErrorCallback, type StreamHandlers, type StreamImageURLPart, type StreamMessage, type StreamOptions, type StreamSession, type StreamTextPart, type StreamTokenCallback, type StreamToolCallCallback, type StreamToolResultCallback, type StreamURLResponse, type SubscribeOptions, type SubscribeTopicRequest, type SubscribedData, type Subscription, type SubscriptionPaymentResponse, type SubscriptionPaymentStatus, type SubscriptionResponse, type SubscriptionStatus, type SuperChat, type SuperChatType, type SystemInfo, type TTLConfig, type TableAccessLevel, type TableColumnDef, type TableIndex, type TableRelation, type TableSchema, type TableSchemaDefinition, type TokenPersistence, type TransactionRead, type TransactionResult, type TransactionWrite, type TransactionWriteResult, type TranscodeStatus, type TransportType, type Trigger, type TriggerEvent, type TriggerHandlerType, type TypingChangeHandler, type TypingInfo, type UpdateBillingKeyRequest, type UpdateChannelRequest, type UpdateColumnRequest, type UpdateCustomDataRequest, type UpdateCustomDataResponse, type UpdateDataRequest, type UpdateDocumentRequest, type UpdateLobbyRequest, type UpdatePublicKeyRequest, type UpdatePublicKeyResponse, type UpdateRolePayload, type UpdateSecurityRuleRequest, type UpdateSubscriptionRequest, type UpdateTriggerRequest, type UpdateVideoRequest, type UpdateVideoStorageRequest, type UploadByPathOptions, type UploadFileResponse, type UploadOptions, type UploadProgress, type VAPIDPublicKeyResponse, type ValidateResponse, type ValidationSchema, type ValidationSchemaField, type ValidationStateTransitions, type Video, type VideoComment, type VideoCompleteUploadResponse, type VideoListOptions, type VideoListResponse, VideoProcessingError, type VideoQuality, type VideoStatus, type VideoStorage, type VideoStorageListResponse, type VideoVisibility, type VoiceChannel, type VoiceMember, type WaitOptions, type WatchHistoryItem, type WebPushSubscription, type WebRTCConnectOptions, type WebRTCConnectionState, type WebRTCMode, type WhereCondition, type WhereOperator, ConnectBase as default, detectInAppBrowser, escapeToExternalBrowser, isWebTransportSupported, toCreateRoomWire };
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  GameRoom: () => GameRoom,
34
34
  GameRoomTransport: () => GameRoomTransport,
35
35
  NativeAPI: () => NativeAPI,
36
+ RolesAPI: () => RolesAPI,
36
37
  SessionManager: () => SessionManager,
37
38
  VideoProcessingError: () => VideoProcessingError,
38
39
  default: () => index_default,
@@ -184,6 +185,9 @@ var HttpClient = class {
184
185
  * 한 번 settle 되면 그 결과(메모리 적재 또는 미로그인)가 항상 반영되어 있다.
185
186
  */
186
187
  this.bootRestorePromise = null;
188
+ // OAuth 콜백 부트스트랩처럼 세션 힌트 유무와 무관하게 첫 인증 호출이 반드시 기다려야
189
+ // 하는 boot promise 인지 여부 (setBootRestorePromise 의 alwaysAwait 옵션).
190
+ this.bootRestoreAlwaysAwait = false;
187
191
  this.config = { ...config };
188
192
  this.storageKey = this.buildStorageKey();
189
193
  this.warnIfUnsafePersistence();
@@ -193,9 +197,14 @@ var HttpClient = class {
193
197
  * 페이지 진입 시 fire-and-forget 으로 시작된 cookie 복구 promise 를 SDK 가 등록한다.
194
198
  * 같은 promise 가 `prepareHeaders` 에서 await 되어, 첫 인증 호출이 cookie 복구
195
199
  * 완료 후 발화한다.
200
+ *
201
+ * options.alwaysAwait=true 면 세션 힌트가 없어도 첫 인증 호출이 이 promise 를
202
+ * 기다린다 — OAuth 리다이렉트 콜백처럼 "이 부트 promise 가 곧 세션을 만든다"는 것이
203
+ * 확실한 흐름용 (일반 cookie 복구는 힌트 기반 fast-path 적용).
196
204
  */
197
- setBootRestorePromise(p) {
205
+ setBootRestorePromise(p, options) {
198
206
  this.bootRestorePromise = p.catch(() => false);
207
+ this.bootRestoreAlwaysAwait = options?.alwaysAwait === true;
199
208
  }
200
209
  /** 최근 호출 ring buffer 스냅샷 (시간순). */
201
210
  getRecentCalls() {
@@ -224,11 +233,49 @@ var HttpClient = class {
224
233
  this.config.accessToken = accessToken;
225
234
  this.config.refreshToken = refreshToken;
226
235
  this.persistTokens();
236
+ this.markSessionHint();
227
237
  }
228
238
  clearTokens() {
229
239
  this.config.accessToken = void 0;
230
240
  this.config.refreshToken = void 0;
231
241
  this.removePersistedTokens();
242
+ this.clearSessionHint();
243
+ }
244
+ // ===== 세션 힌트 =====
245
+ //
246
+ // "이 origin 에서 이 앱으로 로그인한 적이 있다"는 boolean 마커 (토큰 아님 — 민감정보 없음).
247
+ // 부트 시 cookie 복구(`/v1/auth/re-issue`)를 첫 인증 호출이 기다릴지 판단하는 데 쓴다:
248
+ // - 힌트 있음 → 기존과 동일하게 대기 (로그인 세션의 첫 호출이 익명으로 나가는 것 방지).
249
+ // - 힌트 없음 → 대기 생략. 익명 방문자(공개 사이트 첫 방문 대부분)의 첫 조회가
250
+ // re-issue 왕복만큼 빨라진다. 복구 자체는 백그라운드로 계속 진행되므로, 드물게
251
+ // 힌트가 지워졌지만 cookie 세션이 살아있는 경우도 이후 호출부터 자동 회복된다.
252
+ //
253
+ // 세션을 만드는 모든 흐름(로그인/OAuth 콜백/토큰 refresh)이 setTokens 를 경유하므로
254
+ // 그곳에서 마킹하고, clearTokens(로그아웃)에서 지운다.
255
+ buildSessionHintKey() {
256
+ return `${this.buildStorageKey()}:has_session`;
257
+ }
258
+ markSessionHint() {
259
+ if (typeof window === "undefined") return;
260
+ try {
261
+ localStorage.setItem(this.buildSessionHintKey(), "1");
262
+ } catch {
263
+ }
264
+ }
265
+ clearSessionHint() {
266
+ if (typeof window === "undefined") return;
267
+ try {
268
+ localStorage.removeItem(this.buildSessionHintKey());
269
+ } catch {
270
+ }
271
+ }
272
+ hasSessionHint() {
273
+ if (typeof window === "undefined") return false;
274
+ try {
275
+ return localStorage.getItem(this.buildSessionHintKey()) === "1";
276
+ } catch {
277
+ return true;
278
+ }
232
279
  }
233
280
  /**
234
281
  * OAuth redirect callback 직후 호출되어 HttpOnly cookie 를 부트스트랩한다.
@@ -557,7 +604,7 @@ var HttpClient = class {
557
604
  if (credential) {
558
605
  headers.set("X-Public-Key", credential);
559
606
  }
560
- if (!config?.skipAuth && !this.config.accessToken && this.config.publicKey && typeof window !== "undefined" && this.bootRestorePromise) {
607
+ if (!config?.skipAuth && !this.config.accessToken && this.config.publicKey && typeof window !== "undefined" && this.bootRestorePromise && (this.bootRestoreAlwaysAwait || this.hasSessionHint())) {
561
608
  try {
562
609
  await this.bootRestorePromise;
563
610
  } catch {
@@ -1267,6 +1314,7 @@ var DatabaseAPI = class {
1267
1314
  const params = new URLSearchParams();
1268
1315
  if (options?.limit) params.append("limit", options.limit.toString());
1269
1316
  if (options?.offset) params.append("offset", options.offset.toString());
1317
+ if (options?.count === false) params.append("count", "false");
1270
1318
  const queryString = params.toString();
1271
1319
  const url = queryString ? `${prefix}/tables/${tableId}/data?${queryString}` : `${prefix}/tables/${tableId}/data`;
1272
1320
  return this.http.get(url);
@@ -1285,7 +1333,8 @@ var DatabaseAPI = class {
1285
1333
  limit: options.limit,
1286
1334
  offset: options.offset,
1287
1335
  select: options.select,
1288
- exclude: options.exclude
1336
+ exclude: options.exclude,
1337
+ count: options.count
1289
1338
  }
1290
1339
  );
1291
1340
  }
@@ -1449,7 +1498,8 @@ var DatabaseAPI = class {
1449
1498
  offset: options.offset,
1450
1499
  select: options.select,
1451
1500
  exclude: options.exclude,
1452
- populate: options.populate
1501
+ populate: options.populate,
1502
+ count: options.count
1453
1503
  }
1454
1504
  );
1455
1505
  }
@@ -5448,6 +5498,38 @@ var PaymentAPI = class {
5448
5498
  const prefix = this.getPublicPrefix();
5449
5499
  return this.http.get(`${prefix}/payments/orders/${orderId}`);
5450
5500
  }
5501
+ /**
5502
+ * 앱의 결제 내역 목록을 조회한다 (필터/페이지네이션 지원).
5503
+ *
5504
+ * 서버사이드 전용 — service_role(ctx.cbAdmin, management_scopes=["payment:read"]) 또는 콘솔 JWT
5505
+ * 인증이 필요하다. 재무 데이터이므로 Public Key(cb_pk_) 단독 브라우저 SDK 인스턴스로는 호출할 수
5506
+ * 없다. (다른 payment 메서드와 달리 /v1/public 이 아니라 앱 스코프 dual-auth 라우트를 쓴다.)
5507
+ *
5508
+ * @example
5509
+ * ```typescript
5510
+ * // 함수(service_role, management_scopes: ["payment:read"]) 안에서
5511
+ * const { payments, total } = await ctx.cbAdmin.payment.list(ctx.appId, { status: 'done', limit: 20 })
5512
+ * ```
5513
+ */
5514
+ async list(appId, options) {
5515
+ if (this.http.hasPublicKey() && !this.http.hasJWT()) {
5516
+ throw new Error(
5517
+ 'cb.payment.list() \uB294 \uCF58\uC194 JWT \uB610\uB294 service_role(ctx.cbAdmin, management_scopes: ["payment:read"]) \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. Public Key(cb_pk_) \uB2E8\uB3C5 SDK \uC778\uC2A4\uD134\uC2A4\uB85C\uB294 \uD638\uCD9C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 Functions \uD658\uACBD\uC5D0\uC11C \uC0AC\uC6A9\uD558\uC138\uC694.'
5518
+ );
5519
+ }
5520
+ const params = new URLSearchParams();
5521
+ if (options?.status) params.set("status", options.status);
5522
+ if (options?.startDate) params.set("start_date", options.startDate);
5523
+ if (options?.endDate) params.set("end_date", options.endDate);
5524
+ if (options?.limit !== void 0)
5525
+ params.set("limit", String(options.limit));
5526
+ if (options?.offset !== void 0)
5527
+ params.set("offset", String(options.offset));
5528
+ const qs = params.toString();
5529
+ return this.http.get(
5530
+ `/v1/apps/${appId}/payments${qs ? `?${qs}` : ""}`
5531
+ );
5532
+ }
5451
5533
  };
5452
5534
 
5453
5535
  // src/api/subscription.ts
@@ -6049,6 +6131,28 @@ var PushAPI = class {
6049
6131
  };
6050
6132
  return this.http.post(`/v1/apps/${appId}/push/send-to-topic`, body);
6051
6133
  }
6134
+ /**
6135
+ * 앱의 푸시 통계(도달/오픈율/클릭율, 디바이스/메시지/토픽 수)를 조회한다.
6136
+ *
6137
+ * 서버사이드 전용 — service_role(ctx.cbAdmin, management_scopes=["push:read"]) 또는 콘솔 JWT
6138
+ * 인증이 필요하다. sendToMembers/sendToTopic 과 동일한 위임 가드 — cb_pk_ 단독(브라우저) SDK
6139
+ * 인스턴스는 차단하고, 위임 Bearer(ctx.cbAdmin) 인스턴스는 허용한다.
6140
+ *
6141
+ * @example
6142
+ * ```typescript
6143
+ * // 함수(service_role, management_scopes: ["push:read"]) 안에서
6144
+ * const stats = await ctx.cbAdmin.push.getStats(ctx.appId)
6145
+ * console.log(stats.open_rate, stats.click_rate)
6146
+ * ```
6147
+ */
6148
+ async getStats(appId) {
6149
+ if (this.http.hasPublicKey() && !this.http.hasJWT()) {
6150
+ throw new Error(
6151
+ 'cb.push.getStats() \uB294 \uCF58\uC194 JWT \uB610\uB294 service_role(ctx.cbAdmin, management_scopes: ["push:read"]) \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. Public Key(cb_pk_) \uB2E8\uB3C5 SDK \uC778\uC2A4\uD134\uC2A4\uB85C\uB294 \uD638\uCD9C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 Functions \uD658\uACBD\uC5D0\uC11C \uC0AC\uC6A9\uD558\uC138\uC694.'
6152
+ );
6153
+ }
6154
+ return this.http.get(`/v1/apps/${appId}/push/stats`);
6155
+ }
6052
6156
  // ============ Helper Methods ============
6053
6157
  /**
6054
6158
  * 브라우저 고유 ID 생성 (localStorage에 저장)
@@ -6109,6 +6213,72 @@ var PushAPI = class {
6109
6213
  }
6110
6214
  };
6111
6215
 
6216
+ // src/api/roles.ts
6217
+ var RolesAPI = class {
6218
+ constructor(http) {
6219
+ this.http = http;
6220
+ }
6221
+ ensureServerAuth(method) {
6222
+ if (this.http.hasPublicKey() && !this.http.hasJWT()) {
6223
+ throw new Error(
6224
+ `cb.roles.${method}() \uB294 \uCF58\uC194 JWT \uB610\uB294 service_role(ctx.cbAdmin, management_scopes: ["role:read" | "role:manage"]) \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. Public Key(cb_pk_) \uB2E8\uB3C5 SDK \uC778\uC2A4\uD134\uC2A4\uB85C\uB294 \uD638\uCD9C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 Functions \uD658\uACBD\uC5D0\uC11C \uC0AC\uC6A9\uD558\uC138\uC694.`
6225
+ );
6226
+ }
6227
+ }
6228
+ /** 앱의 역할 목록을 조회한다. (management_scope: `role:read`) */
6229
+ async list(appId) {
6230
+ this.ensureServerAuth("list");
6231
+ return this.http.get(`/v1/apps/${appId}/app-roles`);
6232
+ }
6233
+ /** 역할 상세(권한/할당 사용자 포함)를 조회한다. (management_scope: `role:read`) */
6234
+ async get(appId, roleId) {
6235
+ this.ensureServerAuth("get");
6236
+ return this.http.get(`/v1/apps/${appId}/app-roles/${roleId}`);
6237
+ }
6238
+ /** 역할을 생성한다. (management_scope: `role:manage`) */
6239
+ async create(appId, payload) {
6240
+ this.ensureServerAuth("create");
6241
+ return this.http.post(`/v1/apps/${appId}/app-roles`, {
6242
+ role_title: payload.title,
6243
+ role_description: payload.description,
6244
+ selected_permission_ids: payload.permissionIds ?? []
6245
+ });
6246
+ }
6247
+ /**
6248
+ * 역할을 수정한다 — **전체 동기화(replace)**. permissionIds / userIds 는 전달값으로 대체된다.
6249
+ * (management_scope: `role:manage`)
6250
+ */
6251
+ async update(appId, roleId, payload) {
6252
+ this.ensureServerAuth("update");
6253
+ await this.http.put(`/v1/apps/${appId}/app-roles/${roleId}`, {
6254
+ role_title: payload.title,
6255
+ role_description: payload.description,
6256
+ selected_permission_ids: payload.permissionIds,
6257
+ selected_user_ids: payload.userIds
6258
+ });
6259
+ }
6260
+ /**
6261
+ * 역할에 사용자를 할당한다 (제목/설명/권한 보존). EditRole 이 전체 동기화라, 현재 상세를 읽어
6262
+ * 나머지 필드를 유지한 채 사용자 목록만 교체해 PUT 한다. userIds 는 "이 역할을 가질 사용자
6263
+ * 전체"다 (추가가 아니라 동기화). (management_scope: `role:manage`)
6264
+ */
6265
+ async assign(appId, roleId, userIds) {
6266
+ this.ensureServerAuth("assign");
6267
+ const detail = await this.http.get(`/v1/apps/${appId}/app-roles/${roleId}`);
6268
+ await this.http.put(`/v1/apps/${appId}/app-roles/${roleId}`, {
6269
+ role_title: detail.role_name,
6270
+ role_description: detail.role_description,
6271
+ selected_permission_ids: detail.permission_item.map((p) => p.id),
6272
+ selected_user_ids: userIds
6273
+ });
6274
+ }
6275
+ /** 역할을 삭제한다. (management_scope: `role:manage`) */
6276
+ async delete(appId, roleId) {
6277
+ this.ensureServerAuth("delete");
6278
+ await this.http.delete(`/v1/apps/${appId}/app-roles/${roleId}`);
6279
+ }
6280
+ };
6281
+
6112
6282
  // src/api/video.ts
6113
6283
  var DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024;
6114
6284
  var VideoProcessingError = class extends Error {
@@ -11197,6 +11367,7 @@ var ConnectBase = class {
11197
11367
  this.payment = new PaymentAPI(this.http);
11198
11368
  this.subscription = new SubscriptionAPI(this.http);
11199
11369
  this.push = new PushAPI(this.http);
11370
+ this.roles = new RolesAPI(this.http);
11200
11371
  this.video = new VideoAPI(this.http, config.videoUrl || env("CB_VIDEO_URL") || DEFAULT_VIDEO_URL);
11201
11372
  this.game = new GameAPI(this.http, config.gameUrl || env("CB_GAME_URL") || DEFAULT_GAME_URL, config.appId);
11202
11373
  this.ads = new AdsAPI(this.http);
@@ -11211,7 +11382,7 @@ var ConnectBase = class {
11211
11382
  const shouldAutoRestore = config.autoRestoreSession ?? true;
11212
11383
  if (shouldAutoRestore && typeof window !== "undefined") {
11213
11384
  if (this.isOAuthRedirectCallbackUrl()) {
11214
- this.http.setBootRestorePromise(this.oauth.consumeRedirectCallbackOnBoot());
11385
+ this.http.setBootRestorePromise(this.oauth.consumeRedirectCallbackOnBoot(), { alwaysAwait: true });
11215
11386
  } else if (!this.isOAuthCallbackUrl()) {
11216
11387
  this.http.setBootRestorePromise(this.http.tryRestoreSessionFromCookie());
11217
11388
  }
@@ -11292,6 +11463,7 @@ var index_default = ConnectBase;
11292
11463
  GameRoom,
11293
11464
  GameRoomTransport,
11294
11465
  NativeAPI,
11466
+ RolesAPI,
11295
11467
  SessionManager,
11296
11468
  VideoProcessingError,
11297
11469
  detectInAppBrowser,