connectbase-client 0.1.18 → 0.2.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
@@ -56,46 +56,6 @@ declare class HttpClient {
56
56
  delete<T>(url: string, config?: RequestConfig): Promise<T>;
57
57
  }
58
58
 
59
- interface SignUpRequest {
60
- email: string;
61
- password: string;
62
- name?: string;
63
- }
64
- interface SignUpResponse {
65
- access_token: string;
66
- refresh_token: string;
67
- user: UserInfo;
68
- }
69
- interface SignInRequest {
70
- email: string;
71
- password: string;
72
- }
73
- interface SignInResponse {
74
- access_token: string;
75
- refresh_token: string;
76
- user: UserInfo;
77
- }
78
- interface AnonymousSignUpResponse {
79
- access_token: string;
80
- refresh_token: string;
81
- anonymous_uid: string;
82
- }
83
- interface AnonymousSignInRequest {
84
- anonymous_uid?: string;
85
- }
86
- interface AnonymousSignInResponse {
87
- access_token: string;
88
- refresh_token: string;
89
- anonymous_uid?: string;
90
- }
91
- interface UserInfo {
92
- id: string;
93
- email: string;
94
- name?: string;
95
- email_verified: boolean;
96
- created_at: string;
97
- is_anonymous?: boolean;
98
- }
99
59
  /** 앱 멤버 게스트 가입 응답 */
100
60
  interface GuestMemberSignInResponse {
101
61
  member_id: string;
@@ -139,9 +99,7 @@ interface AuthSettingsResponse {
139
99
 
140
100
  declare class AuthAPI {
141
101
  private http;
142
- private anonymousLoginPromise;
143
102
  private guestMemberLoginPromise;
144
- private cachedAnonymousUIDKey;
145
103
  private cachedGuestMemberTokenKey;
146
104
  constructor(http: HttpClient);
147
105
  /**
@@ -162,56 +120,34 @@ declare class AuthAPI {
162
120
  */
163
121
  getAuthSettings(): Promise<AuthSettingsResponse>;
164
122
  /**
165
- * 현재 앱의 anonymous_uid 스토리지 키 생성
166
- * apiKey를 해시하여 앱별 고유 키 생성 (원본 apiKey 노출 방지)
167
- * 성능 최적화: 키를 캐싱하여 반복 해시 계산 방지
168
- */
169
- private getAnonymousUIDKey;
170
- /**
171
- * 회원가입
172
- */
173
- signUp(data: SignUpRequest): Promise<SignUpResponse>;
174
- /**
175
- * 로그인
176
- */
177
- signIn(data: SignInRequest): Promise<SignInResponse>;
178
- /**
179
- * 익명 로그인
180
- * 계정 없이 게스트로 앱을 사용할 수 있습니다.
181
- * 로컬 스토리지에 저장된 anonymous_uid가 있으면 기존 계정으로 재로그인을 시도합니다.
182
- * 동시 호출 시 중복 요청 방지 (race condition 방지)
183
- */
184
- signInAnonymously(): Promise<AnonymousSignInResponse>;
185
- /**
186
- * 실제 익명 로그인 실행 (내부 메서드)
187
- */
188
- private executeAnonymousLogin;
189
- /**
190
- * 저장된 anonymous_uid 조회
191
- */
192
- getStoredAnonymousUID(): string | null;
193
- /**
194
- * anonymous_uid 저장
195
- */
196
- private storeAnonymousUID;
197
- /**
198
- * 저장된 anonymous_uid 삭제
199
- */
200
- clearAnonymousUID(): void;
201
- /**
202
- * 로그아웃
203
- */
204
- signOut(): Promise<void>;
205
- /**
206
- * 현재 사용자 정보 조회
207
- * 토큰이 없거나 유효하지 않으면 자동으로 익명 계정을 생성합니다.
208
- * @param autoAnonymous - 자동 익명 로그인 활성화 (기본값: false, 명시적으로 활성화 필요)
123
+ * 멤버 회원가입 (아이디/비밀번호 기반)
124
+ * 앱에 새로운 멤버를 등록합니다.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const result = await client.auth.signUpMember({
129
+ * login_id: 'myuser123',
130
+ * password: 'password123',
131
+ * nickname: 'John'
132
+ * })
133
+ * console.log('가입 완료:', result.member_id)
134
+ * ```
209
135
  */
210
- getCurrentUser(autoAnonymous?: boolean): Promise<UserInfo>;
136
+ signUpMember(data: MemberSignUpRequest): Promise<MemberSignUpResponse>;
211
137
  /**
212
- * 이메일 인증 메일 재발송
138
+ * 멤버 로그인 (아이디/비밀번호 기반)
139
+ * 기존 멤버로 로그인합니다.
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const result = await client.auth.signInMember({
144
+ * login_id: 'myuser123',
145
+ * password: 'password123'
146
+ * })
147
+ * console.log('로그인 성공:', result.member_id)
148
+ * ```
213
149
  */
214
- resendVerificationEmail(): Promise<void>;
150
+ signInMember(data: MemberSignInRequest): Promise<MemberSignInResponse>;
215
151
  /**
216
152
  * 앱 멤버 게스트 가입
217
153
  * API Key로 인증된 앱에 게스트 멤버로 가입합니다.
@@ -221,65 +157,24 @@ declare class AuthAPI {
221
157
  *
222
158
  * @example
223
159
  * ```typescript
224
- * // 게스트로 가입하고 실시간 연결
225
160
  * const guest = await client.auth.signInAsGuestMember()
226
161
  * await client.realtime.connect({ accessToken: guest.access_token })
227
162
  * ```
228
163
  */
229
164
  signInAsGuestMember(): Promise<GuestMemberSignInResponse>;
230
165
  /**
231
- * 실제 게스트 멤버 로그인 실행 (내부 메서드)
166
+ * 로그아웃
232
167
  */
233
- private executeGuestMemberLogin;
168
+ signOut(): Promise<void>;
234
169
  /**
235
- * JWT 토큰 만료 여부 확인 (로컬 검증)
170
+ * 저장된 게스트 멤버 토큰 삭제
236
171
  */
172
+ clearGuestMemberTokens(): void;
173
+ private executeGuestMemberLogin;
237
174
  private isTokenExpired;
238
- /**
239
- * 현재 앱의 guest_member 토큰 스토리지 키 생성
240
- */
241
175
  private getGuestMemberTokenKey;
242
- /**
243
- * 저장된 게스트 멤버 토큰 조회
244
- */
245
176
  private getStoredGuestMemberTokens;
246
- /**
247
- * 게스트 멤버 토큰 저장
248
- */
249
177
  private storeGuestMemberTokens;
250
- /**
251
- * 저장된 게스트 멤버 토큰 삭제
252
- */
253
- clearGuestMemberTokens(): void;
254
- /**
255
- * 앱 멤버 회원가입 (이메일/ID 기반)
256
- * 앱에 새로운 멤버를 등록합니다.
257
- *
258
- * @example
259
- * ```typescript
260
- * const result = await client.auth.signUpMember({
261
- * login_id: 'user@example.com',
262
- * password: 'password123',
263
- * nickname: 'John'
264
- * })
265
- * console.log('가입 완료:', result.member_id)
266
- * ```
267
- */
268
- signUpMember(data: MemberSignUpRequest): Promise<MemberSignUpResponse>;
269
- /**
270
- * 앱 멤버 로그인 (이메일/ID 기반)
271
- * 기존 멤버로 로그인합니다.
272
- *
273
- * @example
274
- * ```typescript
275
- * const result = await client.auth.signInMember({
276
- * login_id: 'user@example.com',
277
- * password: 'password123'
278
- * })
279
- * console.log('로그인 성공:', result.member_id)
280
- * ```
281
- */
282
- signInMember(data: MemberSignInRequest): Promise<MemberSignInResponse>;
283
178
  }
284
179
 
285
180
  type DataType = 'string' | 'number' | 'boolean' | 'date' | 'object' | 'array';
@@ -3391,4 +3286,4 @@ declare class ConnectBase {
3391
3286
  updateConfig(config: Partial<ConnectBaseConfig>): void;
3392
3287
  }
3393
3288
 
3394
- export { type AnonymousSignInRequest, type AnonymousSignInResponse, type AnonymousSignUpResponse, ApiError, type ApiKeyItem, type AppStatsResponse, AuthError, type AuthSettingsResponse, type BillingCycle, type BillingKeyResponse, type BulkCreateResponse, type BulkError, type CancelPaymentRequest, type CancelPaymentResponse, type CancelSubscriptionRequest, type CategoryInfo, type Channel, type ChannelMembership, type ChargeWithBillingKeyRequest, type ChargeWithBillingKeyResponse, type ChatMessage, type ClientMessage, type ColumnSchema, type CommentListResponse, type ConfirmBillingKeyRequest, type ConfirmPaymentRequest, type ConfirmPaymentResponse, ConnectBase, type ConnectBaseConfig, type ConnectedData, type ConnectionState, type CreateApiKeyRequest, type CreateApiKeyResponse, type CreateChannelRequest, type CreateColumnRequest, type CreateDataRequest, type CreateFolderRequest, type CreateFolderResponse, type CreatePlaylistRequest, type CreateSubscriptionRequest, type CreateTableRequest, type DataItem, type DataType, type DeleteWhereResponse, type DeviceInfo, type EnabledProviderInfo, type EnabledProvidersResponse, type ErrorHandler, type ErrorMessage, type ErrorReport, type ErrorTrackerConfig, type ErrorType, type FetchApiKeysResponse, type FetchDataResponse, type FetchFilesResponse, type FileItem, GameAPI, type GameAction, type GameClientConfig, type GameConnectionState, type GameConnectionStatus, type GameDelta, type GameEventHandlers, type GamePlayer, GameRoom, type GameRoomConfig, type GameRoomInfo, GameRoomTransport, type GameServerMessage, type GameServerMessageType, type GameState, type GameTransportConfig, type GetAuthorizationURLResponse, type GuestMemberSignInResponse, type HistoryResponse, type ICEServer, type ICEServersResponse, type InitUploadResponse, type InvokeFunctionRequest, type InvokeFunctionResponse, type IssueBillingKeyRequest, type IssueBillingKeyResponse, type JoinRoomRequest, type JoinRoomResponse, type ListBillingKeysResponse, type ListSubscriptionPaymentsRequest, type ListSubscriptionPaymentsResponse, type ListSubscriptionsRequest, type ListSubscriptionsResponse, type MemberSignInRequest, type MemberSignInResponse, type MemberSignUpRequest, type MemberSignUpResponse, type MembershipTier, type MessageHandler, type MoveFileRequest, type OAuthCallbackResponse, type OAuthProvider, type PauseSubscriptionRequest, type PaymentDetail, type PaymentStatus, type PeerInfo, type PlayerEvent, type Playlist, type PlaylistItem, type PongMessage, type PreparePaymentRequest, type PreparePaymentResponse, type PushPlatform, type QualityProgress, type QueryOptions, type RealtimeConnectOptions, type RealtimeMessage, type RegisterDeviceRequest, type RenameFileRequest, type RenameFileResponse, type RoomInfo, type RoomStats, type RoomsResponse, type SendOptions, type ServerMessage, type Shorts, type ShortsListResponse, type SignInRequest, type SignInResponse, type SignUpRequest, type SignUpResponse, type SignalingMessage, type SignalingMessageType, type StateChange, type StateChangeHandler, type StreamDoneCallback, type StreamDoneData, type StreamErrorCallback, type StreamHandlers, type StreamMessage, type StreamOptions, type StreamSession, type StreamTokenCallback, type StreamURLResponse, type SubscribeOptions, type SubscribeTopicRequest, type SubscribedData, type Subscription, type SubscriptionPaymentResponse, type SubscriptionPaymentStatus, type SubscriptionResponse, type SubscriptionStatus, type SuperChat, type TableSchema, type TranscodeStatus, type TransportType, type UpdateApiKeyRequest, type UpdateApiKeyResponse, type UpdateBillingKeyRequest, type UpdateChannelRequest, type UpdateColumnRequest, type UpdateDataRequest, type UpdateSubscriptionRequest, type UpdateVideoRequest, type UploadFileResponse, type UploadOptions, type UploadProgress, type UserInfo, type VAPIDPublicKeyResponse, type Video, type VideoComment, type VideoListOptions, type VideoListResponse, VideoProcessingError, type VideoQuality, type VideoStatus, type VideoVisibility, type WaitOptions, type WatchHistoryItem, type WebPushSubscription, type WebRTCConnectOptions, type WebRTCConnectionState, type WebRTCMode, type WhereCondition, type WhereOperator, ConnectBase as default, isWebTransportSupported };
3289
+ export { ApiError, type ApiKeyItem, type AppStatsResponse, AuthError, type AuthSettingsResponse, type BillingCycle, type BillingKeyResponse, type BulkCreateResponse, type BulkError, type CancelPaymentRequest, type CancelPaymentResponse, type CancelSubscriptionRequest, type CategoryInfo, type Channel, type ChannelMembership, type ChargeWithBillingKeyRequest, type ChargeWithBillingKeyResponse, type ChatMessage, type ClientMessage, type ColumnSchema, type CommentListResponse, type ConfirmBillingKeyRequest, type ConfirmPaymentRequest, type ConfirmPaymentResponse, ConnectBase, type ConnectBaseConfig, type ConnectedData, type ConnectionState, type CreateApiKeyRequest, type CreateApiKeyResponse, type CreateChannelRequest, type CreateColumnRequest, type CreateDataRequest, type CreateFolderRequest, type CreateFolderResponse, type CreatePlaylistRequest, type CreateSubscriptionRequest, type CreateTableRequest, type DataItem, type DataType, type DeleteWhereResponse, type DeviceInfo, type EnabledProviderInfo, type EnabledProvidersResponse, type ErrorHandler, type ErrorMessage, type ErrorReport, type ErrorTrackerConfig, type ErrorType, type FetchApiKeysResponse, type FetchDataResponse, type FetchFilesResponse, type FileItem, GameAPI, type GameAction, type GameClientConfig, type GameConnectionState, type GameConnectionStatus, type GameDelta, type GameEventHandlers, type GamePlayer, GameRoom, type GameRoomConfig, type GameRoomInfo, GameRoomTransport, type GameServerMessage, type GameServerMessageType, type GameState, type GameTransportConfig, type GetAuthorizationURLResponse, type GuestMemberSignInResponse, type HistoryResponse, type ICEServer, type ICEServersResponse, type InitUploadResponse, type InvokeFunctionRequest, type InvokeFunctionResponse, type IssueBillingKeyRequest, type IssueBillingKeyResponse, type JoinRoomRequest, type JoinRoomResponse, type ListBillingKeysResponse, type ListSubscriptionPaymentsRequest, type ListSubscriptionPaymentsResponse, type ListSubscriptionsRequest, type ListSubscriptionsResponse, type MemberSignInRequest, type MemberSignInResponse, type MemberSignUpRequest, type MemberSignUpResponse, type MembershipTier, type MessageHandler, type MoveFileRequest, type OAuthCallbackResponse, type OAuthProvider, type PauseSubscriptionRequest, type PaymentDetail, type PaymentStatus, type PeerInfo, type PlayerEvent, type Playlist, type PlaylistItem, type PongMessage, type PreparePaymentRequest, type PreparePaymentResponse, type PushPlatform, type QualityProgress, type QueryOptions, type RealtimeConnectOptions, type RealtimeMessage, type RegisterDeviceRequest, type RenameFileRequest, type RenameFileResponse, type RoomInfo, type RoomStats, type RoomsResponse, type SendOptions, type ServerMessage, type Shorts, type ShortsListResponse, type SignalingMessage, type SignalingMessageType, type StateChange, type StateChangeHandler, type StreamDoneCallback, type StreamDoneData, type StreamErrorCallback, type StreamHandlers, type StreamMessage, type StreamOptions, type StreamSession, type StreamTokenCallback, type StreamURLResponse, type SubscribeOptions, type SubscribeTopicRequest, type SubscribedData, type Subscription, type SubscriptionPaymentResponse, type SubscriptionPaymentStatus, type SubscriptionResponse, type SubscriptionStatus, type SuperChat, type TableSchema, type TranscodeStatus, type TransportType, type UpdateApiKeyRequest, type UpdateApiKeyResponse, type UpdateBillingKeyRequest, type UpdateChannelRequest, type UpdateColumnRequest, type UpdateDataRequest, type UpdateSubscriptionRequest, type UpdateVideoRequest, type UploadFileResponse, type UploadOptions, type UploadProgress, type VAPIDPublicKeyResponse, type Video, type VideoComment, type VideoListOptions, type VideoListResponse, VideoProcessingError, type VideoQuality, type VideoStatus, type VideoVisibility, type WaitOptions, type WatchHistoryItem, type WebPushSubscription, type WebRTCConnectOptions, type WebRTCConnectionState, type WebRTCMode, type WhereCondition, type WhereOperator, ConnectBase as default, isWebTransportSupported };
package/dist/index.js CHANGED
@@ -225,8 +225,19 @@ var HttpClient = class {
225
225
  };
226
226
 
227
227
  // src/api/auth.ts
228
- var ANONYMOUS_UID_KEY_PREFIX = "cb_anon_";
229
228
  var GUEST_MEMBER_TOKEN_KEY_PREFIX = "cb_guest_";
229
+ function notifyVisitorTracker(memberId) {
230
+ if (typeof window === "undefined") return;
231
+ if (memberId) {
232
+ if (typeof window.__cbSetMember === "function") {
233
+ window.__cbSetMember(memberId);
234
+ }
235
+ } else {
236
+ if (typeof window.__cbClearMember === "function") {
237
+ window.__cbClearMember();
238
+ }
239
+ }
240
+ }
230
241
  function simpleHash(str) {
231
242
  let hash = 0;
232
243
  for (let i = 0; i < str.length; i++) {
@@ -239,9 +250,7 @@ function simpleHash(str) {
239
250
  var AuthAPI = class {
240
251
  constructor(http) {
241
252
  this.http = http;
242
- this.anonymousLoginPromise = null;
243
253
  this.guestMemberLoginPromise = null;
244
- this.cachedAnonymousUIDKey = null;
245
254
  this.cachedGuestMemberTokenKey = null;
246
255
  }
247
256
  /**
@@ -267,135 +276,52 @@ var AuthAPI = class {
267
276
  );
268
277
  }
269
278
  /**
270
- * 현재 앱의 anonymous_uid 스토리지 키 생성
271
- * apiKey를 해시하여 앱별 고유 키 생성 (원본 apiKey 노출 방지)
272
- * 성능 최적화: 키를 캐싱하여 반복 해시 계산 방지
273
- */
274
- getAnonymousUIDKey() {
275
- if (this.cachedAnonymousUIDKey) {
276
- return this.cachedAnonymousUIDKey;
277
- }
278
- const apiKey = this.http.getApiKey();
279
- if (!apiKey) {
280
- this.cachedAnonymousUIDKey = `${ANONYMOUS_UID_KEY_PREFIX}default`;
281
- } else {
282
- const keyHash = simpleHash(apiKey);
283
- this.cachedAnonymousUIDKey = `${ANONYMOUS_UID_KEY_PREFIX}${keyHash}`;
284
- }
285
- return this.cachedAnonymousUIDKey;
286
- }
287
- /**
288
- * 회원가입
279
+ * 멤버 회원가입 (아이디/비밀번호 기반)
280
+ * 앱에 새로운 멤버를 등록합니다.
281
+ *
282
+ * @example
283
+ * ```typescript
284
+ * const result = await client.auth.signUpMember({
285
+ * login_id: 'myuser123',
286
+ * password: 'password123',
287
+ * nickname: 'John'
288
+ * })
289
+ * console.log('가입 완료:', result.member_id)
290
+ * ```
289
291
  */
290
- async signUp(data) {
292
+ async signUpMember(data) {
291
293
  const response = await this.http.post(
292
- "/v1/auth/signup",
294
+ "/v1/public/app-members/signup",
293
295
  data,
294
296
  { skipAuth: true }
295
297
  );
296
298
  this.http.setTokens(response.access_token, response.refresh_token);
299
+ notifyVisitorTracker(response.member_id);
297
300
  return response;
298
301
  }
299
302
  /**
300
- * 로그인
303
+ * 앱 멤버 로그인 (아이디/비밀번호 기반)
304
+ * 기존 멤버로 로그인합니다.
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const result = await client.auth.signInMember({
309
+ * login_id: 'myuser123',
310
+ * password: 'password123'
311
+ * })
312
+ * console.log('로그인 성공:', result.member_id)
313
+ * ```
301
314
  */
302
- async signIn(data) {
315
+ async signInMember(data) {
303
316
  const response = await this.http.post(
304
- "/v1/auth/signin",
317
+ "/v1/public/app-members/signin",
305
318
  data,
306
319
  { skipAuth: true }
307
320
  );
308
321
  this.http.setTokens(response.access_token, response.refresh_token);
322
+ notifyVisitorTracker(response.member_id);
309
323
  return response;
310
324
  }
311
- /**
312
- * 익명 로그인
313
- * 계정 없이 게스트로 앱을 사용할 수 있습니다.
314
- * 로컬 스토리지에 저장된 anonymous_uid가 있으면 기존 계정으로 재로그인을 시도합니다.
315
- * 동시 호출 시 중복 요청 방지 (race condition 방지)
316
- */
317
- async signInAnonymously() {
318
- if (this.anonymousLoginPromise) {
319
- return this.anonymousLoginPromise;
320
- }
321
- this.anonymousLoginPromise = this.executeAnonymousLogin();
322
- try {
323
- return await this.anonymousLoginPromise;
324
- } finally {
325
- this.anonymousLoginPromise = null;
326
- }
327
- }
328
- /**
329
- * 실제 익명 로그인 실행 (내부 메서드)
330
- */
331
- async executeAnonymousLogin() {
332
- const storedAnonymousUID = this.getStoredAnonymousUID();
333
- const response = await this.http.post(
334
- "/v1/auth/signin/anonymous",
335
- storedAnonymousUID ? { anonymous_uid: storedAnonymousUID } : {},
336
- { skipAuth: true }
337
- );
338
- this.http.setTokens(response.access_token, response.refresh_token);
339
- if (response.anonymous_uid) {
340
- this.storeAnonymousUID(response.anonymous_uid);
341
- }
342
- return response;
343
- }
344
- /**
345
- * 저장된 anonymous_uid 조회
346
- */
347
- getStoredAnonymousUID() {
348
- if (typeof localStorage === "undefined") return null;
349
- return localStorage.getItem(this.getAnonymousUIDKey());
350
- }
351
- /**
352
- * anonymous_uid 저장
353
- */
354
- storeAnonymousUID(uid) {
355
- if (typeof localStorage === "undefined") return;
356
- localStorage.setItem(this.getAnonymousUIDKey(), uid);
357
- }
358
- /**
359
- * 저장된 anonymous_uid 삭제
360
- */
361
- clearAnonymousUID() {
362
- if (typeof localStorage === "undefined") return;
363
- localStorage.removeItem(this.getAnonymousUIDKey());
364
- }
365
- /**
366
- * 로그아웃
367
- */
368
- async signOut() {
369
- try {
370
- await this.http.post("/v1/auth/logout");
371
- } finally {
372
- this.http.clearTokens();
373
- }
374
- }
375
- /**
376
- * 현재 사용자 정보 조회
377
- * 토큰이 없거나 유효하지 않으면 자동으로 익명 계정을 생성합니다.
378
- * @param autoAnonymous - 자동 익명 로그인 활성화 (기본값: false, 명시적으로 활성화 필요)
379
- */
380
- async getCurrentUser(autoAnonymous = false) {
381
- try {
382
- return await this.http.get("/v1/auth");
383
- } catch (error) {
384
- const isAuthError = error instanceof ApiError && (error.statusCode === 401 || error.statusCode === 403) || error instanceof AuthError;
385
- if (autoAnonymous && isAuthError) {
386
- await this.signInAnonymously();
387
- const userInfo = await this.http.get("/v1/auth");
388
- return { ...userInfo, is_anonymous: true };
389
- }
390
- throw error;
391
- }
392
- }
393
- /**
394
- * 이메일 인증 메일 재발송
395
- */
396
- async resendVerificationEmail() {
397
- await this.http.post("/v1/auth/re-send-activate-email");
398
- }
399
325
  /**
400
326
  * 앱 멤버 게스트 가입
401
327
  * API Key로 인증된 앱에 게스트 멤버로 가입합니다.
@@ -405,7 +331,6 @@ var AuthAPI = class {
405
331
  *
406
332
  * @example
407
333
  * ```typescript
408
- * // 게스트로 가입하고 실시간 연결
409
334
  * const guest = await client.auth.signInAsGuestMember()
410
335
  * await client.realtime.connect({ accessToken: guest.access_token })
411
336
  * ```
@@ -422,8 +347,24 @@ var AuthAPI = class {
422
347
  }
423
348
  }
424
349
  /**
425
- * 실제 게스트 멤버 로그인 실행 (내부 메서드)
350
+ * 로그아웃
351
+ */
352
+ async signOut() {
353
+ try {
354
+ await this.http.post("/v1/auth/logout");
355
+ } finally {
356
+ this.http.clearTokens();
357
+ notifyVisitorTracker(null);
358
+ }
359
+ }
360
+ /**
361
+ * 저장된 게스트 멤버 토큰 삭제
426
362
  */
363
+ clearGuestMemberTokens() {
364
+ if (typeof localStorage === "undefined") return;
365
+ localStorage.removeItem(this.getGuestMemberTokenKey());
366
+ }
367
+ // ===== Private Methods =====
427
368
  async executeGuestMemberLogin() {
428
369
  const storedData = this.getStoredGuestMemberTokens();
429
370
  if (storedData) {
@@ -434,6 +375,7 @@ var AuthAPI = class {
434
375
  "/v1/public/app-members/me"
435
376
  );
436
377
  if (memberInfo.is_active) {
378
+ notifyVisitorTracker(memberInfo.member_id);
437
379
  return {
438
380
  member_id: memberInfo.member_id,
439
381
  access_token: storedData.accessToken,
@@ -454,6 +396,7 @@ var AuthAPI = class {
454
396
  );
455
397
  this.http.setTokens(refreshed.access_token, refreshed.refresh_token);
456
398
  this.storeGuestMemberTokens(refreshed.access_token, refreshed.refresh_token, storedData.memberId);
399
+ notifyVisitorTracker(storedData.memberId);
457
400
  return {
458
401
  member_id: storedData.memberId,
459
402
  access_token: refreshed.access_token,
@@ -473,11 +416,9 @@ var AuthAPI = class {
473
416
  );
474
417
  this.http.setTokens(response.access_token, response.refresh_token);
475
418
  this.storeGuestMemberTokens(response.access_token, response.refresh_token, response.member_id);
419
+ notifyVisitorTracker(response.member_id);
476
420
  return response;
477
421
  }
478
- /**
479
- * JWT 토큰 만료 여부 확인 (로컬 검증)
480
- */
481
422
  isTokenExpired(token) {
482
423
  try {
483
424
  const payload = JSON.parse(atob(token.split(".")[1]));
@@ -487,9 +428,6 @@ var AuthAPI = class {
487
428
  return true;
488
429
  }
489
430
  }
490
- /**
491
- * 현재 앱의 guest_member 토큰 스토리지 키 생성
492
- */
493
431
  getGuestMemberTokenKey() {
494
432
  if (this.cachedGuestMemberTokenKey) {
495
433
  return this.cachedGuestMemberTokenKey;
@@ -503,9 +441,6 @@ var AuthAPI = class {
503
441
  }
504
442
  return this.cachedGuestMemberTokenKey;
505
443
  }
506
- /**
507
- * 저장된 게스트 멤버 토큰 조회
508
- */
509
444
  getStoredGuestMemberTokens() {
510
445
  if (typeof localStorage === "undefined") return null;
511
446
  const stored = localStorage.getItem(this.getGuestMemberTokenKey());
@@ -516,65 +451,10 @@ var AuthAPI = class {
516
451
  return null;
517
452
  }
518
453
  }
519
- /**
520
- * 게스트 멤버 토큰 저장
521
- */
522
454
  storeGuestMemberTokens(accessToken, refreshToken, memberId) {
523
455
  if (typeof localStorage === "undefined") return;
524
456
  localStorage.setItem(this.getGuestMemberTokenKey(), JSON.stringify({ accessToken, refreshToken, memberId }));
525
457
  }
526
- /**
527
- * 저장된 게스트 멤버 토큰 삭제
528
- */
529
- clearGuestMemberTokens() {
530
- if (typeof localStorage === "undefined") return;
531
- localStorage.removeItem(this.getGuestMemberTokenKey());
532
- }
533
- /**
534
- * 앱 멤버 회원가입 (이메일/ID 기반)
535
- * 앱에 새로운 멤버를 등록합니다.
536
- *
537
- * @example
538
- * ```typescript
539
- * const result = await client.auth.signUpMember({
540
- * login_id: 'user@example.com',
541
- * password: 'password123',
542
- * nickname: 'John'
543
- * })
544
- * console.log('가입 완료:', result.member_id)
545
- * ```
546
- */
547
- async signUpMember(data) {
548
- const response = await this.http.post(
549
- "/v1/public/app-members/signup",
550
- data,
551
- { skipAuth: true }
552
- );
553
- this.http.setTokens(response.access_token, response.refresh_token);
554
- return response;
555
- }
556
- /**
557
- * 앱 멤버 로그인 (이메일/ID 기반)
558
- * 기존 멤버로 로그인합니다.
559
- *
560
- * @example
561
- * ```typescript
562
- * const result = await client.auth.signInMember({
563
- * login_id: 'user@example.com',
564
- * password: 'password123'
565
- * })
566
- * console.log('로그인 성공:', result.member_id)
567
- * ```
568
- */
569
- async signInMember(data) {
570
- const response = await this.http.post(
571
- "/v1/public/app-members/signin",
572
- data,
573
- { skipAuth: true }
574
- );
575
- this.http.setTokens(response.access_token, response.refresh_token);
576
- return response;
577
- }
578
458
  };
579
459
 
580
460
  // src/api/database.ts