@ph-cms/client-sdk 0.1.44 → 0.1.46

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
@@ -1,4 +1,4 @@
1
- # @ph-cms/client-sdk 0.1.44
1
+ # @ph-cms/client-sdk 0.1.45
2
2
 
3
3
  PH-CMS 클라이언트 SDK — 브라우저 및 React 애플리케이션을 위한 통합 클라이언트.
4
4
 
@@ -60,6 +60,8 @@ import type {
60
60
  BlockUserRequest,
61
61
  BlockUserResponse,
62
62
  BlockedUserDto,
63
+ FollowStatusResponse,
64
+ FollowUserResponse,
63
65
  PagedBlockedUserListResponse,
64
66
  SuspendUserRequest,
65
67
  SuspendUserResponse,
@@ -832,7 +834,7 @@ function UserLikedContents({ userUid }) {
832
834
 
833
835
  ### Public Profile (`useUserProfile`)
834
836
 
835
- 다른 사용자의 공개 프로필(이름, 아바타, 자기소개 등)을 조회할 때 사용하는 훅입니다.
837
+ 다른 사용자의 공개 프로필(이름, 아바타, 자기소개, 팔로워 수 등)을 조회할 때 사용하는 훅입니다.
836
838
 
837
839
  ```tsx
838
840
  import { useUserProfile } from '@ph-cms/client-sdk';
@@ -847,10 +849,69 @@ function UserProfileCard({ userId }) {
847
849
  <div>
848
850
  <img src={profile.avatar_url} alt={profile.display_name} />
849
851
  <h3>{profile.display_name} (@{profile.username})</h3>
852
+ <p>followers: {profile.follower_count}</p>
850
853
  <p>{profile.profile_data?.bio}</p>
851
854
  </div>
852
855
  );
853
856
  }
857
+ ```
858
+
859
+ ### Follow Status / Follow / Unfollow
860
+
861
+ 특정 사용자에 대한 팔로우 상태를 조회하고, 팔로우/언팔로우할 수 있습니다.
862
+
863
+ ```tsx
864
+ import {
865
+ useFollowStatus,
866
+ useFollowUser,
867
+ useUnfollowUser,
868
+ } from '@ph-cms/client-sdk';
869
+
870
+ function FollowButton({ userUid }: { userUid: string }) {
871
+ const { data: status, isLoading } = useFollowStatus(userUid);
872
+ const { mutate: followUser, isPending: isFollowingPending } = useFollowUser();
873
+ const { mutate: unfollowUser, isPending: isUnfollowingPending } = useUnfollowUser();
874
+
875
+ if (isLoading) return <button disabled>Loading...</button>;
876
+
877
+ const isFollowing = status?.is_following ?? false;
878
+ const isPending = isFollowingPending || isUnfollowingPending;
879
+
880
+ return (
881
+ <button
882
+ disabled={isPending}
883
+ onClick={() => {
884
+ if (isFollowing) unfollowUser(userUid);
885
+ else followUser(userUid);
886
+ }}
887
+ >
888
+ {isFollowing ? '언팔로우' : '팔로우'}
889
+ </button>
890
+ );
891
+ }
892
+ ```
893
+
894
+ ### Followers / Followings List
895
+
896
+ 특정 사용자의 팔로워 목록/팔로잉 목록을 페이지네이션으로 조회할 수 있습니다.
897
+
898
+ ```tsx
899
+ import { useFollowers, useFollowings } from '@ph-cms/client-sdk';
900
+
901
+ function FollowLists({ userUid }: { userUid: string }) {
902
+ const { data: followers, isLoading: isFollowersLoading } = useFollowers(userUid, { page: 1, limit: 20 });
903
+ const { data: followings, isLoading: isFollowingsLoading } = useFollowings(userUid, { page: 1, limit: 20 });
904
+
905
+ if (isFollowersLoading || isFollowingsLoading) return <div>Loading...</div>;
906
+
907
+ return (
908
+ <div>
909
+ <p>followers: {followers?.total ?? 0}</p>
910
+ <p>followings: {followings?.total ?? 0}</p>
911
+ </div>
912
+ );
913
+ }
914
+ ```
854
915
 
855
916
  ### `useLikedStats` (Liked Statistics)
856
917
 
@@ -1250,6 +1311,49 @@ const blockedUsers = await client.user.getBlockedUsers('my-user-uid', { page: 1,
1250
1311
  const { data: blockedList } = useBlockedUsers('my-user-uid', { page: 1 });
1251
1312
  ```
1252
1313
 
1314
+ ## User Follow (사용자 팔로우)
1315
+
1316
+ 특정 사용자를 팔로우하거나 언팔로우할 수 있습니다. (인증 필수)
1317
+
1318
+ ```ts
1319
+ // 1. 팔로우 상태 조회
1320
+ const followStatus = await client.user.getFollowStatus('target-user-uid');
1321
+ // => { is_following: false }
1322
+
1323
+ // React Hook 사용
1324
+ const { data: status } = useFollowStatus('target-user-uid');
1325
+
1326
+ // 2. 사용자 팔로우
1327
+ const followResult = await client.user.follow('target-user-uid');
1328
+ // => { success: true, message: 'User followed', is_following: true }
1329
+
1330
+ // React Hook 사용
1331
+ const { mutate: followUser } = useFollowUser();
1332
+ followUser('target-user-uid');
1333
+
1334
+ // 3. 사용자 언팔로우
1335
+ const unfollowResult = await client.user.unfollow('target-user-uid');
1336
+ // => { success: true, message: 'User unfollowed', is_following: false }
1337
+
1338
+ // React Hook 사용
1339
+ const { mutate: unfollowUser } = useUnfollowUser();
1340
+ unfollowUser('target-user-uid');
1341
+
1342
+ // 4. 사용자 팔로워 목록 조회 (Public)
1343
+ const followers = await client.user.getFollowers('target-user-uid', { page: 1, limit: 20 });
1344
+ // => PagedUserProfileListResponse
1345
+
1346
+ // React Hook 사용
1347
+ const { data: followerList } = useFollowers('target-user-uid', { page: 1, limit: 20 });
1348
+
1349
+ // 5. 사용자 팔로잉 목록 조회 (Public)
1350
+ const followings = await client.user.getFollowings('target-user-uid', { page: 1, limit: 20 });
1351
+ // => PagedUserProfileListResponse
1352
+
1353
+ // React Hook 사용
1354
+ const { data: followingList } = useFollowings('target-user-uid', { page: 1, limit: 20 });
1355
+ ```
1356
+
1253
1357
  ## Global Ban (글로벌 밴 - 관리자 전용)
1254
1358
 
1255
1359
  특정 사용자의 활동을 전역적으로 정지시키거나 해제할 수 있습니다. (관리자 권한 필수)
@@ -1687,6 +1791,11 @@ const result = await content.list({ channelUid: 'my-channel' });
1687
1791
  | 메서드 | 설명 |
1688
1792
  |---|---|
1689
1793
  | `getProfile(uid: string)` | 유저의 공개 프로필 정보 조회 → `UserProfileDto` |
1794
+ | `getFollowStatus(uid: string)` | 현재 로그인 사용자의 대상 유저 팔로우 상태 조회 → `FollowStatusResponse` |
1795
+ | `follow(uid: string)` | 특정 사용자 팔로우 → `FollowUserResponse` |
1796
+ | `unfollow(uid: string)` | 특정 사용자 언팔로우 → `FollowUserResponse` |
1797
+ | `getFollowers(uid: string, params?: { page?: number; limit?: number })` | 특정 사용자의 팔로워 목록 조회 → `PagedUserProfileListResponse` |
1798
+ | `getFollowings(uid: string, params?: { page?: number; limit?: number })` | 특정 사용자의 팔로잉 목록 조회 → `PagedUserProfileListResponse` |
1690
1799
  | `updateProfile(uid: string, data: UpdateUserProfileRequest)` | 유저의 프로필 정보 업데이트 → `UserDto` |
1691
1800
  | `getLikedContents(uid: string, params?: Partial<ListLikedContentQuery>)` | 사용자가 좋아요 누른 콘텐츠 목록 조회 → `PagedContentListResponse` |
1692
1801
  | `getLikedStats(uid: string)` | 사용자가 좋아요 누른 콘텐츠 타입별 통계 조회 → `LikedStatsByTypeResponse` |
@@ -23,6 +23,7 @@ export declare const useAuth: () => {
23
23
  username: string | null;
24
24
  display_name: string;
25
25
  avatar_url: string | null;
26
+ follower_count: number;
26
27
  phone_number: string | null;
27
28
  email_verified_at: string | null;
28
29
  phone_verified_at: string | null;
@@ -59,6 +60,7 @@ export declare const useAuth: () => {
59
60
  username: string | null;
60
61
  display_name: string;
61
62
  avatar_url: string | null;
63
+ follower_count: number;
62
64
  phone_number: string | null;
63
65
  email_verified_at: string | null;
64
66
  phone_verified_at: string | null;
@@ -98,6 +100,7 @@ export declare const useAuth: () => {
98
100
  username: string | null;
99
101
  display_name: string;
100
102
  avatar_url: string | null;
103
+ follower_count: number;
101
104
  phone_number: string | null;
102
105
  email_verified_at: string | null;
103
106
  phone_verified_at: string | null;
@@ -137,6 +140,7 @@ export declare const useAuth: () => {
137
140
  username: string | null;
138
141
  display_name: string;
139
142
  avatar_url: string | null;
143
+ follower_count: number;
140
144
  phone_number: string | null;
141
145
  email_verified_at: string | null;
142
146
  phone_verified_at: string | null;
@@ -173,6 +177,7 @@ export declare const useAuth: () => {
173
177
  username: string | null;
174
178
  display_name: string;
175
179
  avatar_url: string | null;
180
+ follower_count: number;
176
181
  phone_number: string | null;
177
182
  email_verified_at: string | null;
178
183
  phone_verified_at: string | null;
@@ -209,6 +214,7 @@ export declare const useAuth: () => {
209
214
  username: string | null;
210
215
  display_name: string;
211
216
  avatar_url: string | null;
217
+ follower_count: number;
212
218
  phone_number: string | null;
213
219
  email_verified_at: string | null;
214
220
  phone_verified_at: string | null;
@@ -251,6 +257,7 @@ export declare const useAuth: () => {
251
257
  username: string | null;
252
258
  display_name: string;
253
259
  avatar_url: string | null;
260
+ follower_count: number;
254
261
  phone_number: string | null;
255
262
  email_verified_at: string | null;
256
263
  phone_verified_at: string | null;
@@ -290,6 +297,7 @@ export declare const useAuth: () => {
290
297
  username: string | null;
291
298
  display_name: string;
292
299
  avatar_url: string | null;
300
+ follower_count: number;
293
301
  phone_number: string | null;
294
302
  email_verified_at: string | null;
295
303
  phone_verified_at: string | null;
@@ -329,6 +337,7 @@ export declare const useAuth: () => {
329
337
  username: string | null;
330
338
  display_name: string;
331
339
  avatar_url: string | null;
340
+ follower_count: number;
332
341
  phone_number: string | null;
333
342
  email_verified_at: string | null;
334
343
  phone_verified_at: string | null;
@@ -365,6 +374,7 @@ export declare const useAuth: () => {
365
374
  username: string | null;
366
375
  display_name: string;
367
376
  avatar_url: string | null;
377
+ follower_count: number;
368
378
  phone_number: string | null;
369
379
  email_verified_at: string | null;
370
380
  phone_verified_at: string | null;
@@ -401,6 +411,7 @@ export declare const useAuth: () => {
401
411
  username: string | null;
402
412
  display_name: string;
403
413
  avatar_url: string | null;
414
+ follower_count: number;
404
415
  phone_number: string | null;
405
416
  email_verified_at: string | null;
406
417
  phone_verified_at: string | null;
@@ -443,6 +454,7 @@ export declare const useLogin: () => import("@tanstack/react-query").UseMutation
443
454
  username: string | null;
444
455
  display_name: string;
445
456
  avatar_url: string | null;
457
+ follower_count: number;
446
458
  phone_number: string | null;
447
459
  email_verified_at: string | null;
448
460
  phone_verified_at: string | null;
@@ -483,6 +495,7 @@ export declare const useLoginAnonymous: () => import("@tanstack/react-query").Us
483
495
  username: string | null;
484
496
  display_name: string;
485
497
  avatar_url: string | null;
498
+ follower_count: number;
486
499
  phone_number: string | null;
487
500
  email_verified_at: string | null;
488
501
  phone_verified_at: string | null;
@@ -519,6 +532,7 @@ export declare const useUpgradeAnonymous: () => import("@tanstack/react-query").
519
532
  username: string | null;
520
533
  display_name: string;
521
534
  avatar_url: string | null;
535
+ follower_count: number;
522
536
  phone_number: string | null;
523
537
  email_verified_at: string | null;
524
538
  phone_verified_at: string | null;
@@ -1,8 +1,21 @@
1
- import { ListLikedContentQuery, UpdateUserProfileRequest, BlockUserRequest, SuspendUserRequest } from '@ph-cms/api-contract';
1
+ import { ListLikedContentQuery, ListUserFollowQuery, UpdateUserProfileRequest, BlockUserRequest, SuspendUserRequest } from '@ph-cms/api-contract';
2
2
  export declare const termsKeys: {
3
3
  all: readonly ["terms"];
4
4
  lists: () => readonly ["terms", "list"];
5
5
  };
6
+ export declare const userKeys: {
7
+ all: readonly ["users"];
8
+ profile: (uid: string) => readonly ["users", "profile", string];
9
+ followStatus: (uid: string) => readonly ["users", "follow-status", string];
10
+ followers: (uid: string, params: Partial<ListUserFollowQuery>) => readonly ["users", "followers", string, Partial<{
11
+ page: number;
12
+ limit: number;
13
+ }>];
14
+ followings: (uid: string, params: Partial<ListUserFollowQuery>) => readonly ["users", "followings", string, Partial<{
15
+ page: number;
16
+ limit: number;
17
+ }>];
18
+ };
6
19
  /**
7
20
  * Access the current user profile and status.
8
21
  */
@@ -14,6 +27,7 @@ export declare const useUser: () => {
14
27
  username: string | null;
15
28
  display_name: string;
16
29
  avatar_url: string | null;
30
+ follower_count: number;
17
31
  phone_number: string | null;
18
32
  email_verified_at: string | null;
19
33
  phone_verified_at: string | null;
@@ -51,8 +65,49 @@ export declare const useUserProfile: (uid: string) => import("@tanstack/react-qu
51
65
  username: string | null;
52
66
  display_name: string;
53
67
  avatar_url: string | null;
68
+ follower_count: number;
54
69
  profile_data: Record<string, any>;
55
70
  }, Error>;
71
+ /**
72
+ * Hook to fetch follow status for a target user.
73
+ */
74
+ export declare const useFollowStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
75
+ is_following: boolean;
76
+ }, Error>;
77
+ /**
78
+ * Hook to fetch followers of a target user.
79
+ */
80
+ export declare const useFollowers: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
81
+ items: {
82
+ uid: string;
83
+ username: string | null;
84
+ display_name: string;
85
+ avatar_url: string | null;
86
+ follower_count: number;
87
+ profile_data: Record<string, any>;
88
+ }[];
89
+ total: number;
90
+ page: number;
91
+ limit: number;
92
+ totalPages: number;
93
+ }, Error>;
94
+ /**
95
+ * Hook to fetch followings of a target user.
96
+ */
97
+ export declare const useFollowings: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
98
+ items: {
99
+ uid: string;
100
+ username: string | null;
101
+ display_name: string;
102
+ avatar_url: string | null;
103
+ follower_count: number;
104
+ profile_data: Record<string, any>;
105
+ }[];
106
+ total: number;
107
+ page: number;
108
+ limit: number;
109
+ totalPages: number;
110
+ }, Error>;
56
111
  /**
57
112
  * Hook to update a user's profile.
58
113
  * Typically used by a user to update their own profile.
@@ -64,6 +119,7 @@ export declare const useUpdateProfile: () => import("@tanstack/react-query").Use
64
119
  username: string | null;
65
120
  display_name: string;
66
121
  avatar_url: string | null;
122
+ follower_count: number;
67
123
  phone_number: string | null;
68
124
  email_verified_at: string | null;
69
125
  phone_verified_at: string | null;
@@ -92,6 +148,22 @@ export declare const useUpdateProfile: () => import("@tanstack/react-query").Use
92
148
  uid: string;
93
149
  data: UpdateUserProfileRequest | Record<string, any>;
94
150
  }, unknown>;
151
+ /**
152
+ * Hook to follow a user.
153
+ */
154
+ export declare const useFollowUser: () => import("@tanstack/react-query").UseMutationResult<{
155
+ message: string;
156
+ is_following: boolean;
157
+ success: boolean;
158
+ }, Error, string, unknown>;
159
+ /**
160
+ * Hook to unfollow a user.
161
+ */
162
+ export declare const useUnfollowUser: () => import("@tanstack/react-query").UseMutationResult<{
163
+ message: string;
164
+ is_following: boolean;
165
+ success: boolean;
166
+ }, Error, string, unknown>;
95
167
  /**
96
168
  * Hook to fetch contents liked by a specific user.
97
169
  */
@@ -1,12 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useUnsuspendUser = exports.useSuspendUser = exports.useBlockedUsers = exports.useUnblockUser = exports.useBlockUser = exports.useAgreeTerms = exports.useChannelTerms = exports.useLikedStats = exports.useLikedContents = exports.useUpdateProfile = exports.useUserProfile = exports.useUser = exports.termsKeys = void 0;
3
+ exports.useUnsuspendUser = exports.useSuspendUser = exports.useBlockedUsers = exports.useUnblockUser = exports.useBlockUser = exports.useAgreeTerms = exports.useChannelTerms = exports.useLikedStats = exports.useLikedContents = exports.useUnfollowUser = exports.useFollowUser = exports.useUpdateProfile = exports.useFollowings = exports.useFollowers = exports.useFollowStatus = exports.useUserProfile = exports.useUser = exports.userKeys = exports.termsKeys = void 0;
4
4
  const react_query_1 = require("@tanstack/react-query");
5
5
  const context_1 = require("../context");
6
6
  exports.termsKeys = {
7
7
  all: ['terms'],
8
8
  lists: () => [...exports.termsKeys.all, 'list'],
9
9
  };
10
+ exports.userKeys = {
11
+ all: ['users'],
12
+ profile: (uid) => [...exports.userKeys.all, 'profile', uid],
13
+ followStatus: (uid) => [...exports.userKeys.all, 'follow-status', uid],
14
+ followers: (uid, params) => [...exports.userKeys.all, 'followers', uid, params],
15
+ followings: (uid, params) => [...exports.userKeys.all, 'followings', uid, params],
16
+ };
10
17
  /**
11
18
  * Access the current user profile and status.
12
19
  */
@@ -21,12 +28,48 @@ exports.useUser = useUser;
21
28
  const useUserProfile = (uid) => {
22
29
  const client = (0, context_1.usePHCMS)();
23
30
  return (0, react_query_1.useQuery)({
24
- queryKey: ['user-profile', uid],
31
+ queryKey: exports.userKeys.profile(uid),
25
32
  queryFn: () => client.user.getProfile(uid),
26
33
  enabled: !!uid,
27
34
  });
28
35
  };
29
36
  exports.useUserProfile = useUserProfile;
37
+ /**
38
+ * Hook to fetch follow status for a target user.
39
+ */
40
+ const useFollowStatus = (uid, enabled = true) => {
41
+ const client = (0, context_1.usePHCMS)();
42
+ return (0, react_query_1.useQuery)({
43
+ queryKey: exports.userKeys.followStatus(uid),
44
+ queryFn: () => client.user.getFollowStatus(uid),
45
+ enabled: !!uid && enabled,
46
+ });
47
+ };
48
+ exports.useFollowStatus = useFollowStatus;
49
+ /**
50
+ * Hook to fetch followers of a target user.
51
+ */
52
+ const useFollowers = (uid, params = {}, enabled = true) => {
53
+ const client = (0, context_1.usePHCMS)();
54
+ return (0, react_query_1.useQuery)({
55
+ queryKey: exports.userKeys.followers(uid, params),
56
+ queryFn: () => client.user.getFollowers(uid, params),
57
+ enabled: !!uid && enabled,
58
+ });
59
+ };
60
+ exports.useFollowers = useFollowers;
61
+ /**
62
+ * Hook to fetch followings of a target user.
63
+ */
64
+ const useFollowings = (uid, params = {}, enabled = true) => {
65
+ const client = (0, context_1.usePHCMS)();
66
+ return (0, react_query_1.useQuery)({
67
+ queryKey: exports.userKeys.followings(uid, params),
68
+ queryFn: () => client.user.getFollowings(uid, params),
69
+ enabled: !!uid && enabled,
70
+ });
71
+ };
72
+ exports.useFollowings = useFollowings;
30
73
  /**
31
74
  * Hook to update a user's profile.
32
75
  * Typically used by a user to update their own profile.
@@ -43,6 +86,36 @@ const useUpdateProfile = () => {
43
86
  });
44
87
  };
45
88
  exports.useUpdateProfile = useUpdateProfile;
89
+ /**
90
+ * Hook to follow a user.
91
+ */
92
+ const useFollowUser = () => {
93
+ const client = (0, context_1.usePHCMS)();
94
+ const queryClient = (0, react_query_1.useQueryClient)();
95
+ return (0, react_query_1.useMutation)({
96
+ mutationFn: (uid) => client.user.follow(uid),
97
+ onSuccess: (_data, uid) => {
98
+ queryClient.invalidateQueries({ queryKey: exports.userKeys.followStatus(uid) });
99
+ queryClient.invalidateQueries({ queryKey: exports.userKeys.profile(uid) });
100
+ },
101
+ });
102
+ };
103
+ exports.useFollowUser = useFollowUser;
104
+ /**
105
+ * Hook to unfollow a user.
106
+ */
107
+ const useUnfollowUser = () => {
108
+ const client = (0, context_1.usePHCMS)();
109
+ const queryClient = (0, react_query_1.useQueryClient)();
110
+ return (0, react_query_1.useMutation)({
111
+ mutationFn: (uid) => client.user.unfollow(uid),
112
+ onSuccess: (_data, uid) => {
113
+ queryClient.invalidateQueries({ queryKey: exports.userKeys.followStatus(uid) });
114
+ queryClient.invalidateQueries({ queryKey: exports.userKeys.profile(uid) });
115
+ },
116
+ });
117
+ };
118
+ exports.useUnfollowUser = useUnfollowUser;
46
119
  /**
47
120
  * Hook to fetch contents liked by a specific user.
48
121
  */
@@ -1,4 +1,4 @@
1
- import { LikedStatsByTypeResponse, ListLikedContentQuery, PagedContentListResponse, UpdateUserProfileRequest, UserDto, UserProfileDto, BlockUserRequest, BlockUserResponse, PagedBlockedUserListResponse, SuspendUserRequest, SuspendUserResponse } from "@ph-cms/api-contract";
1
+ import { LikedStatsByTypeResponse, ListLikedContentQuery, ListUserFollowQuery, PagedContentListResponse, PagedUserProfileListResponse, UpdateUserProfileRequest, UserDto, UserProfileDto, FollowStatusResponse, FollowUserResponse, BlockUserRequest, BlockUserResponse, PagedBlockedUserListResponse, SuspendUserRequest, SuspendUserResponse } from "@ph-cms/api-contract";
2
2
  import { AxiosInstance } from "axios";
3
3
  export declare class UserModule {
4
4
  private client;
@@ -10,6 +10,38 @@ export declare class UserModule {
10
10
  * @param uid - The UID of the user.
11
11
  */
12
12
  getProfile(uid: string): Promise<UserProfileDto>;
13
+ /**
14
+ * Retrieves whether the current authenticated user follows the target user.
15
+ *
16
+ * @param uid - The UID of the target user.
17
+ */
18
+ getFollowStatus(uid: string): Promise<FollowStatusResponse>;
19
+ /**
20
+ * Follows a user.
21
+ *
22
+ * @param uid - The UID of the target user.
23
+ */
24
+ follow(uid: string): Promise<FollowUserResponse>;
25
+ /**
26
+ * Unfollows a user.
27
+ *
28
+ * @param uid - The UID of the target user.
29
+ */
30
+ unfollow(uid: string): Promise<FollowUserResponse>;
31
+ /**
32
+ * Retrieves followers of a user.
33
+ *
34
+ * @param uid - The UID of the target user.
35
+ * @param params - Paging parameters.
36
+ */
37
+ getFollowers(uid: string, params?: Partial<ListUserFollowQuery>): Promise<PagedUserProfileListResponse>;
38
+ /**
39
+ * Retrieves followings of a user.
40
+ *
41
+ * @param uid - The UID of the target user.
42
+ * @param params - Paging parameters.
43
+ */
44
+ getFollowings(uid: string, params?: Partial<ListUserFollowQuery>): Promise<PagedUserProfileListResponse>;
13
45
  /**
14
46
  * Updates a user's profile.
15
47
  *
@@ -16,6 +16,66 @@ class UserModule {
16
16
  async getProfile(uid) {
17
17
  return this.client.get(`${this.prefix}/users/${uid}/profile`);
18
18
  }
19
+ /**
20
+ * Retrieves whether the current authenticated user follows the target user.
21
+ *
22
+ * @param uid - The UID of the target user.
23
+ */
24
+ async getFollowStatus(uid) {
25
+ if (!uid)
26
+ throw new errors_1.ValidationError("UID is required", []);
27
+ return this.client.get(`${this.prefix}/users/${uid}/follow-status`);
28
+ }
29
+ /**
30
+ * Follows a user.
31
+ *
32
+ * @param uid - The UID of the target user.
33
+ */
34
+ async follow(uid) {
35
+ if (!uid)
36
+ throw new errors_1.ValidationError("UID is required", []);
37
+ return this.client.post(`${this.prefix}/users/${uid}/follow`);
38
+ }
39
+ /**
40
+ * Unfollows a user.
41
+ *
42
+ * @param uid - The UID of the target user.
43
+ */
44
+ async unfollow(uid) {
45
+ if (!uid)
46
+ throw new errors_1.ValidationError("UID is required", []);
47
+ return this.client.delete(`${this.prefix}/users/${uid}/follow`);
48
+ }
49
+ /**
50
+ * Retrieves followers of a user.
51
+ *
52
+ * @param uid - The UID of the target user.
53
+ * @param params - Paging parameters.
54
+ */
55
+ async getFollowers(uid, params = {}) {
56
+ if (!uid)
57
+ throw new errors_1.ValidationError("UID is required", []);
58
+ const validation = api_contract_1.ListUserFollowQuerySchema.safeParse(params);
59
+ if (!validation.success) {
60
+ throw new errors_1.ValidationError("Invalid followers list params", validation.error.errors);
61
+ }
62
+ return this.client.get(`${this.prefix}/users/${uid}/followers`, { params: validation.data });
63
+ }
64
+ /**
65
+ * Retrieves followings of a user.
66
+ *
67
+ * @param uid - The UID of the target user.
68
+ * @param params - Paging parameters.
69
+ */
70
+ async getFollowings(uid, params = {}) {
71
+ if (!uid)
72
+ throw new errors_1.ValidationError("UID is required", []);
73
+ const validation = api_contract_1.ListUserFollowQuerySchema.safeParse(params);
74
+ if (!validation.success) {
75
+ throw new errors_1.ValidationError("Invalid followings list params", validation.error.errors);
76
+ }
77
+ return this.client.get(`${this.prefix}/users/${uid}/followings`, { params: validation.data });
78
+ }
19
79
  /**
20
80
  * Updates a user's profile.
21
81
  *
package/dist/types.d.ts CHANGED
@@ -5,7 +5,7 @@ export type { AuthStatus, PHCMSContextType, PHCMSProviderProps } from './context
5
5
  export type { FirebaseAuthSyncProps, UseFirebaseAuthSyncOptions, UseFirebaseAuthSyncReturn } from './hooks/useFirebaseAuthSync';
6
6
  export type { StampAvailability, CheckStampAvailabilityParams } from './hooks/useStampTour';
7
7
  export type { AnonymousLoginRequest, AuthResponse, FirebaseExchangeRequest, FirebaseRegisterRequest, LoginRequest, RefreshTokenRequest, RegisterRequest, } from '@ph-cms/api-contract';
8
- export type { UserDto, UserProfileDto } from '@ph-cms/api-contract';
8
+ export type { UserDto, UserProfileDto, FollowStatusResponse, FollowUserResponse, ListUserFollowQuery, PagedUserProfileListResponse, } from '@ph-cms/api-contract';
9
9
  export type { ChannelDto, CheckHierarchyQuery } from '@ph-cms/api-contract';
10
10
  export type { ContentDto, ContentStatDto, ContentMediaDto, ContentStatus, CreateContentRequest, ListContentQuery, PagedContentListResponse, UpdateContentRequest, } from '@ph-cms/api-contract';
11
11
  export type { HierarchySetDto } from '@ph-cms/api-contract';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ph-cms/client-sdk",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "Unified PH-CMS Client SDK (React + Core)",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "LICENSE"
31
31
  ],
32
32
  "dependencies": {
33
- "@ph-cms/api-contract": "^0.1.21",
33
+ "@ph-cms/api-contract": "^0.1.23",
34
34
  "@tanstack/react-query": "^5.0.0",
35
35
  "axios": "^1.6.0",
36
36
  "zod": "^3.22.4"