@ph-cms/client-sdk 0.1.49 → 0.1.51
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 +123 -5
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/core.d.ts +1 -0
- package/dist/core.js +1 -0
- package/dist/hooks/useAuth.d.ts +22 -0
- package/dist/hooks/useAuth.js +5 -0
- package/dist/hooks/useContent.d.ts +8 -5
- package/dist/hooks/useMedia.d.ts +2 -2
- package/dist/hooks/usePlace.d.ts +2 -2
- package/dist/hooks/useStampTour.d.ts +4 -4
- package/dist/hooks/useUser.d.ts +28 -16
- package/dist/hooks/useUser.js +15 -1
- package/dist/hooks/useUserGroup.d.ts +122 -0
- package/dist/hooks/useUserGroup.js +126 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/modules/auth.d.ts +47 -0
- package/dist/modules/auth.js +25 -0
- package/dist/modules/user-group.d.ts +15 -0
- package/dist/modules/user-group.js +66 -0
- package/dist/modules/user.d.ts +10 -0
- package/dist/modules/user.js +25 -0
- package/dist/types.d.ts +8 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @ph-cms/client-sdk 0.1.
|
|
1
|
+
# @ph-cms/client-sdk 0.1.51
|
|
2
2
|
|
|
3
3
|
PH-CMS 클라이언트 SDK — 브라우저 및 React 애플리케이션을 위한 통합 클라이언트.
|
|
4
4
|
|
|
@@ -106,9 +106,22 @@ import type {
|
|
|
106
106
|
// Common
|
|
107
107
|
PagedResponse,
|
|
108
108
|
UserProfileDto,
|
|
109
|
+
UserSearchResultDto,
|
|
109
110
|
IntegratedPlace,
|
|
110
111
|
PlaceSearchQuery,
|
|
111
112
|
PlaceSearchResponse,
|
|
113
|
+
|
|
114
|
+
// User Group
|
|
115
|
+
UserGroupDto,
|
|
116
|
+
UserGroupMembershipDto,
|
|
117
|
+
UserGroupInviteDto,
|
|
118
|
+
UserGroupInviteStatus,
|
|
119
|
+
ListUserGroupQuery,
|
|
120
|
+
GetMyUserGroupMembershipResponse,
|
|
121
|
+
PagedMyGroupInviteListResponse,
|
|
122
|
+
JoinUserGroupResponse,
|
|
123
|
+
LeaveUserGroupResponse,
|
|
124
|
+
RespondInviteResponse,
|
|
112
125
|
} from '@ph-cms/client-sdk';
|
|
113
126
|
```
|
|
114
127
|
|
|
@@ -170,8 +183,41 @@ SDK의 인증 시스템은 세 개의 레이어로 구성됩니다:
|
|
|
170
183
|
| `loginWithFirebase()` | `POST /api/auth/firebase/exchange` | `setTokens()` → `refreshUser()` |
|
|
171
184
|
| `register()` (method: 'email') | `POST /api/auth/register` | `setTokens()` → `refreshUser()` |
|
|
172
185
|
| `register()` (method: 'firebase') | `POST /api/auth/register` (provider: firebase:password) | `setTokens()` → `refreshUser()` |
|
|
186
|
+
| `checkEmail()` | `GET /api/auth/check-email` | 중복 여부 확인용 |
|
|
173
187
|
| `logout()` | `POST /api/auth/logout` | `provider.logout()` → `refreshUser()` (상태 초기화) |
|
|
174
188
|
|
|
189
|
+
### Email Duplicate Check
|
|
190
|
+
|
|
191
|
+
회원가입 전에 이메일 중복 여부와 소속 채널을 확인할 수 있습니다.
|
|
192
|
+
|
|
193
|
+
`useAuth()`에서 바로 사용할 수 있습니다.
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
const { checkEmail, checkEmailStatus } = useAuth();
|
|
197
|
+
|
|
198
|
+
const result = await checkEmail('user@example.com');
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
{
|
|
203
|
+
email: 'user@example.com',
|
|
204
|
+
exists: true,
|
|
205
|
+
channels: [
|
|
206
|
+
{
|
|
207
|
+
channelUid: 'ch_xxx',
|
|
208
|
+
channelName: 'Seoul Channel',
|
|
209
|
+
channelSlug: 'seoul-channel',
|
|
210
|
+
relationType: 'member',
|
|
211
|
+
memberRole: 'manager'
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
- `exists: false` 이면 `channels` 는 빈 배열입니다.
|
|
218
|
+
- `relationType` 은 `owner` 또는 `member` 입니다.
|
|
219
|
+
- `memberRole` 은 채널 멤버인 경우에만 값이 있으며, 소유자인 경우 `null` 입니다.
|
|
220
|
+
|
|
175
221
|
### Authentication Lifecycle
|
|
176
222
|
|
|
177
223
|
#### 1. 초기 마운트 (비인증 상태)
|
|
@@ -357,7 +403,9 @@ const client = new PHCMSClient({
|
|
|
357
403
|
|
|
358
404
|
### `FirebaseAuthProvider`
|
|
359
405
|
|
|
360
|
-
Firebase Authentication과 연동합니다. PH-CMS
|
|
406
|
+
Firebase Authentication과 연동합니다. PH-CMS access/refresh 토큰을 관리하며,
|
|
407
|
+
`getToken()`은 PH-CMS access token만 반환합니다. PH-CMS 토큰이 없거나 만료되어 갱신에 실패하면 `null`을 반환합니다.
|
|
408
|
+
Firebase ID 토큰이 필요하면 별도로 `getIdToken()`을 호출합니다.
|
|
361
409
|
|
|
362
410
|
```ts
|
|
363
411
|
import { FirebaseAuthProvider, PHCMSClient } from '@ph-cms/client-sdk';
|
|
@@ -387,7 +435,13 @@ const client = new PHCMSClient({
|
|
|
387
435
|
|
|
388
436
|
1. PH-CMS access token이 유효하면 → 그대로 반환
|
|
389
437
|
2. 만료 임박이면 → `tryRefresh()` 시도 → 성공하면 새 토큰 반환
|
|
390
|
-
3. PH-CMS
|
|
438
|
+
3. PH-CMS access token이 없거나 갱신 실패 → `null` 반환
|
|
439
|
+
|
|
440
|
+
Firebase ID token이 필요한 경우:
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
const firebaseIdToken = await authProvider.getIdToken();
|
|
444
|
+
```
|
|
391
445
|
|
|
392
446
|
### `AuthProvider` Interface
|
|
393
447
|
|
|
@@ -506,6 +560,7 @@ function AuthComponent() {
|
|
|
506
560
|
login, // (data: LoginRequest) => Promise<AuthResponse>
|
|
507
561
|
loginWithFirebase, // (data: FirebaseExchangeRequest) => Promise<AuthResponse>
|
|
508
562
|
register, // (data: RegisterInput) => Promise<AuthResponse> ← method: 'email' | 'firebase'
|
|
563
|
+
checkEmail, // (email: string) => Promise<CheckEmailResponse>
|
|
509
564
|
loginAnonymous, // (data?: AnonymousLoginRequest) => Promise<AuthResponse>
|
|
510
565
|
upgradeAnonymous, // (data: { email, password, display_name?, username?, phone_number? }) => Promise<UserDto>
|
|
511
566
|
logout, // () => Promise<void>
|
|
@@ -514,6 +569,7 @@ function AuthComponent() {
|
|
|
514
569
|
loginStatus,
|
|
515
570
|
loginWithFirebaseStatus,
|
|
516
571
|
registerStatus,
|
|
572
|
+
checkEmailStatus,
|
|
517
573
|
loginAnonymousStatus,
|
|
518
574
|
upgradeAnonymousStatus,
|
|
519
575
|
logoutStatus,
|
|
@@ -1794,7 +1850,7 @@ const result = await content.list({ channelUid: 'my-channel' });
|
|
|
1794
1850
|
| 카테고리 | export 항목 |
|
|
1795
1851
|
|---|---|
|
|
1796
1852
|
| 클라이언트 | `PHCMSClient` |
|
|
1797
|
-
| 모듈 | `ContentModule`, `AuthModule`, `UserModule`, `ChannelModule`, `MediaModule`, `TermsModule` |
|
|
1853
|
+
| 모듈 | `ContentModule`, `AuthModule`, `UserModule`, `ChannelModule`, `MediaModule`, `TermsModule`, `UserGroupModule` |
|
|
1798
1854
|
| Auth 프로바이더 | `BaseAuthProvider`, `LocalAuthProvider`, `JwtUtils` |
|
|
1799
1855
|
| 타입/에러 | `PHCMSClientError`, 각종 DTO/Request 타입 |
|
|
1800
1856
|
|
|
@@ -1805,6 +1861,7 @@ const result = await content.list({ channelUid: 'my-channel' });
|
|
|
1805
1861
|
| 메서드 | 설명 |
|
|
1806
1862
|
|---|---|
|
|
1807
1863
|
| `getProfile(uid: string)` | 유저의 공개 프로필 정보 조회 → `UserProfileDto` |
|
|
1864
|
+
| `search(query, params?)` | 이름/아이디/이메일 키워드로 사용자 검색 → `UserSearchResultDto[]` |
|
|
1808
1865
|
| `getFollowStatus(uid: string)` | 현재 로그인 사용자의 대상 유저 팔로우 상태 조회 → `FollowStatusResponse` |
|
|
1809
1866
|
| `follow(uid: string)` | 특정 사용자 팔로우 → `FollowUserResponse` |
|
|
1810
1867
|
| `unfollow(uid: string)` | 특정 사용자 언팔로우 → `FollowUserResponse` |
|
|
@@ -1819,6 +1876,18 @@ const result = await content.list({ channelUid: 'my-channel' });
|
|
|
1819
1876
|
| `suspend(uid: string, data?: SuspendUserRequest)` | 유저 활동 정지 (글로벌 밴) → `SuspendUserResponse` |
|
|
1820
1877
|
| `unsuspend(uid: string)` | 유저 활동 정지 해제 → `SuspendUserResponse` |
|
|
1821
1878
|
|
|
1879
|
+
예시:
|
|
1880
|
+
|
|
1881
|
+
```ts
|
|
1882
|
+
const users = await client.user.search('hong', { limit: 10 });
|
|
1883
|
+
```
|
|
1884
|
+
|
|
1885
|
+
React hook 예시:
|
|
1886
|
+
|
|
1887
|
+
```ts
|
|
1888
|
+
const { data: users } = useUserSearch('hong', { limit: 10 });
|
|
1889
|
+
```
|
|
1890
|
+
|
|
1822
1891
|
### `AuthModule` (`client.auth`)
|
|
1823
1892
|
|
|
1824
1893
|
| 메서드 | 설명 |
|
|
@@ -1855,10 +1924,19 @@ const result = await content.list({ channelUid: 'my-channel' });
|
|
|
1855
1924
|
예시:
|
|
1856
1925
|
|
|
1857
1926
|
```ts
|
|
1858
|
-
await client.content.list({
|
|
1927
|
+
await client.content.list({
|
|
1928
|
+
withParent: true,
|
|
1929
|
+
withDetail: true,
|
|
1930
|
+
page: 1,
|
|
1931
|
+
limit: 20,
|
|
1932
|
+
periodAt: '2026-06-10T00:00:00Z',
|
|
1933
|
+
});
|
|
1859
1934
|
await client.content.get('cnt_123', { withParent: true, withDetail: true });
|
|
1860
1935
|
```
|
|
1861
1936
|
|
|
1937
|
+
`periodAt`은 `startAt` / `endAt`로 저장된 콘텐츠 기간을 기준으로 목록을 필터링할 때 사용합니다.
|
|
1938
|
+
예를 들어 `periodAt: '2026-06-10T00:00:00Z'`를 전달하면 해당 시점에 유효한 콘텐츠만 조회됩니다.
|
|
1939
|
+
|
|
1862
1940
|
### `ChannelModule` (`client.channel`)
|
|
1863
1941
|
|
|
1864
1942
|
| 메서드 | 설명 |
|
|
@@ -1878,6 +1956,46 @@ await client.content.get('cnt_123', { withParent: true, withDetail: true });
|
|
|
1878
1956
|
| `agree(data: { termCodes: string[]; channelUid?: string })` | 약관 동의 제출 |
|
|
1879
1957
|
| `listByChannel(channelUid: string)` | 채널별 약관 목록 조회 |
|
|
1880
1958
|
|
|
1959
|
+
### `UserGroupModule` (`client.userGroup`)
|
|
1960
|
+
|
|
1961
|
+
| 메서드 | 설명 |
|
|
1962
|
+
|---|---|
|
|
1963
|
+
| `listByBaseContent(baseContentUid, params?)` | 기준 콘텐츠에 연결된 공개 그룹 목록 조회 → `PagedUserGroupListResponse` |
|
|
1964
|
+
| `getMyMembership(baseContentUid, groupUid)` | 현재 사용자의 특정 그룹 가입 여부 조회 → `GetMyUserGroupMembershipResponse` |
|
|
1965
|
+
| `join(baseContentUid, groupUid)` | 그룹 self join → `JoinUserGroupResponse` |
|
|
1966
|
+
| `leave(baseContentUid, groupUid)` | 그룹 탈퇴 → `LeaveUserGroupResponse` |
|
|
1967
|
+
| `listMine(params?)` | 현재 사용자가 가입한 그룹 목록 조회 → `PagedMyUserGroupMembershipListResponse` |
|
|
1968
|
+
| `listMyInvites(params?)` | 현재 사용자의 그룹 초대 목록 조회 → `PagedMyGroupInviteListResponse` |
|
|
1969
|
+
| `acceptInvite(inviteUid)` | 그룹 초대 수락 → `RespondInviteResponse` |
|
|
1970
|
+
| `declineInvite(inviteUid)` | 그룹 초대 거절 → `RespondInviteResponse` |
|
|
1971
|
+
|
|
1972
|
+
예시:
|
|
1973
|
+
|
|
1974
|
+
```ts
|
|
1975
|
+
const groups = await client.userGroup.listByBaseContent(baseContentUid, {
|
|
1976
|
+
limit: 20,
|
|
1977
|
+
offset: 0,
|
|
1978
|
+
});
|
|
1979
|
+
|
|
1980
|
+
const joined = await client.userGroup.join(baseContentUid, groupUid);
|
|
1981
|
+
|
|
1982
|
+
const invites = await client.userGroup.listMyInvites({ limit: 20, offset: 0 });
|
|
1983
|
+
|
|
1984
|
+
await client.userGroup.acceptInvite('invite_123');
|
|
1985
|
+
await client.userGroup.declineInvite('invite_123');
|
|
1986
|
+
```
|
|
1987
|
+
|
|
1988
|
+
React hook 예시:
|
|
1989
|
+
|
|
1990
|
+
```ts
|
|
1991
|
+
const { data: myInvites } = useMyUserGroupInvites({ limit: 20 });
|
|
1992
|
+
const acceptInvite = useAcceptUserGroupInvite();
|
|
1993
|
+
const declineInvite = useDeclineUserGroupInvite();
|
|
1994
|
+
|
|
1995
|
+
await acceptInvite.mutateAsync({ inviteUid: 'inv_123' });
|
|
1996
|
+
await declineInvite.mutateAsync({ inviteUid: 'inv_123' });
|
|
1997
|
+
```
|
|
1998
|
+
|
|
1881
1999
|
### JWT Utilities
|
|
1882
2000
|
|
|
1883
2001
|
클라이언트에서 토큰 상태를 확인할 수 있는 유틸리티입니다 (서명 검증은 하지 않음).
|
package/dist/client.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ContentModule } from './modules/content';
|
|
|
6
6
|
import { MediaModule } from './modules/media';
|
|
7
7
|
import { PlaceModule } from './modules/place';
|
|
8
8
|
import { TermsModule } from './modules/terms';
|
|
9
|
+
import { UserGroupModule } from './modules/user-group';
|
|
9
10
|
import { UserModule } from './modules/user';
|
|
10
11
|
export interface PHCMSClientConfig {
|
|
11
12
|
baseURL: string;
|
|
@@ -28,6 +29,7 @@ export declare class PHCMSClient {
|
|
|
28
29
|
readonly media: MediaModule;
|
|
29
30
|
readonly place: PlaceModule;
|
|
30
31
|
readonly user: UserModule;
|
|
32
|
+
readonly userGroup: UserGroupModule;
|
|
31
33
|
/**
|
|
32
34
|
* Whether a token refresh is currently in flight (used by the 401
|
|
33
35
|
* interceptor to de-duplicate concurrent refresh attempts).
|
package/dist/client.js
CHANGED
|
@@ -13,6 +13,7 @@ const content_1 = require("./modules/content");
|
|
|
13
13
|
const media_1 = require("./modules/media");
|
|
14
14
|
const place_1 = require("./modules/place");
|
|
15
15
|
const terms_1 = require("./modules/terms");
|
|
16
|
+
const user_group_1 = require("./modules/user-group");
|
|
16
17
|
const user_1 = require("./modules/user");
|
|
17
18
|
class PHCMSClient {
|
|
18
19
|
/** Exposes the auth provider so UI layers can check token state synchronously. */
|
|
@@ -71,6 +72,7 @@ class PHCMSClient {
|
|
|
71
72
|
this.media = new media_1.MediaModule(this.axiosInstance, normalizedApiPrefix);
|
|
72
73
|
this.place = new place_1.PlaceModule(this.axiosInstance, normalizedApiPrefix);
|
|
73
74
|
this.user = new user_1.UserModule(this.axiosInstance, normalizedApiPrefix);
|
|
75
|
+
this.userGroup = new user_group_1.UserGroupModule(this.axiosInstance, normalizedApiPrefix);
|
|
74
76
|
// Wire the refresh function into the auth provider so it can
|
|
75
77
|
// proactively refresh tokens inside `getToken()` without needing
|
|
76
78
|
// a direct reference to the AuthModule / axios instance.
|
package/dist/core.d.ts
CHANGED
package/dist/core.js
CHANGED
|
@@ -29,5 +29,6 @@ __exportStar(require("./modules/content"), exports);
|
|
|
29
29
|
__exportStar(require("./modules/media"), exports);
|
|
30
30
|
__exportStar(require("./modules/place"), exports);
|
|
31
31
|
__exportStar(require("./modules/terms"), exports);
|
|
32
|
+
__exportStar(require("./modules/user-group"), exports);
|
|
32
33
|
__exportStar(require("./modules/user"), exports);
|
|
33
34
|
__exportStar(require("./types"), exports);
|
package/dist/hooks/useAuth.d.ts
CHANGED
|
@@ -168,6 +168,17 @@ export declare const useAuth: () => {
|
|
|
168
168
|
};
|
|
169
169
|
accessToken: string;
|
|
170
170
|
}, Error, RegisterInput, unknown>;
|
|
171
|
+
checkEmail: import("@tanstack/react-query").UseMutateAsyncFunction<{
|
|
172
|
+
email: string;
|
|
173
|
+
exists: boolean;
|
|
174
|
+
channels: {
|
|
175
|
+
channelUid: string;
|
|
176
|
+
channelName: string;
|
|
177
|
+
channelSlug: string;
|
|
178
|
+
relationType: "owner" | "member";
|
|
179
|
+
memberRole: string | null;
|
|
180
|
+
}[];
|
|
181
|
+
}, Error, string, unknown>;
|
|
171
182
|
loginAnonymous: import("@tanstack/react-query").UseMutateAsyncFunction<{
|
|
172
183
|
refreshToken: string;
|
|
173
184
|
user: {
|
|
@@ -365,6 +376,17 @@ export declare const useAuth: () => {
|
|
|
365
376
|
};
|
|
366
377
|
accessToken: string;
|
|
367
378
|
}, Error, RegisterInput, unknown>;
|
|
379
|
+
checkEmailStatus: import("@tanstack/react-query").UseMutationResult<{
|
|
380
|
+
email: string;
|
|
381
|
+
exists: boolean;
|
|
382
|
+
channels: {
|
|
383
|
+
channelUid: string;
|
|
384
|
+
channelName: string;
|
|
385
|
+
channelSlug: string;
|
|
386
|
+
relationType: "owner" | "member";
|
|
387
|
+
memberRole: string | null;
|
|
388
|
+
}[];
|
|
389
|
+
}, Error, string, unknown>;
|
|
368
390
|
loginAnonymousStatus: import("@tanstack/react-query").UseMutationResult<{
|
|
369
391
|
refreshToken: string;
|
|
370
392
|
user: {
|
package/dist/hooks/useAuth.js
CHANGED
|
@@ -46,6 +46,9 @@ const useAuth = () => {
|
|
|
46
46
|
await refreshUser();
|
|
47
47
|
},
|
|
48
48
|
});
|
|
49
|
+
const checkEmailMutation = (0, react_query_1.useMutation)({
|
|
50
|
+
mutationFn: (email) => client.auth.checkEmail(email),
|
|
51
|
+
});
|
|
49
52
|
const loginAnonymousMutation = (0, react_query_1.useMutation)({
|
|
50
53
|
mutationFn: (data) => client.auth.loginAnonymous({
|
|
51
54
|
channelUid: data?.channelUid || channelUid,
|
|
@@ -75,6 +78,7 @@ const useAuth = () => {
|
|
|
75
78
|
login: loginMutation.mutateAsync,
|
|
76
79
|
loginWithFirebase: loginWithFirebaseMutation.mutateAsync,
|
|
77
80
|
register: registerMutation.mutateAsync,
|
|
81
|
+
checkEmail: checkEmailMutation.mutateAsync,
|
|
78
82
|
loginAnonymous: loginAnonymousMutation.mutateAsync,
|
|
79
83
|
upgradeAnonymous: upgradeAnonymousMutation.mutateAsync,
|
|
80
84
|
logout: logoutMutation.mutateAsync,
|
|
@@ -83,6 +87,7 @@ const useAuth = () => {
|
|
|
83
87
|
loginStatus: loginMutation,
|
|
84
88
|
loginWithFirebaseStatus: loginWithFirebaseMutation,
|
|
85
89
|
registerStatus: registerMutation,
|
|
90
|
+
checkEmailStatus: checkEmailMutation,
|
|
86
91
|
loginAnonymousStatus: loginAnonymousMutation,
|
|
87
92
|
upgradeAnonymousStatus: upgradeAnonymousMutation,
|
|
88
93
|
logoutStatus: logoutMutation,
|
|
@@ -17,6 +17,7 @@ export declare const contentKeys: {
|
|
|
17
17
|
uids?: string[] | undefined;
|
|
18
18
|
rootUid?: string | undefined;
|
|
19
19
|
keyword?: string | undefined;
|
|
20
|
+
periodAt?: string | undefined;
|
|
20
21
|
orderBy?: "title" | "created_at" | "updated_at" | "published_at" | "view_count" | "like_count" | undefined;
|
|
21
22
|
orderDir?: "asc" | "desc" | undefined;
|
|
22
23
|
includeDeleted?: boolean | undefined;
|
|
@@ -33,7 +34,7 @@ export declare const contentKeys: {
|
|
|
33
34
|
likes: () => readonly ["contents", "like"];
|
|
34
35
|
like: (uid: string) => readonly ["contents", "like", string];
|
|
35
36
|
};
|
|
36
|
-
export declare const useContentList: (params: ListContentQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
37
|
+
export declare const useContentList: (params: ListContentQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
37
38
|
number: number;
|
|
38
39
|
totalPages: number;
|
|
39
40
|
content: ContentDto[];
|
|
@@ -42,11 +43,11 @@ export declare const useContentList: (params: ListContentQuery, enabled?: boolea
|
|
|
42
43
|
first: boolean;
|
|
43
44
|
last: boolean;
|
|
44
45
|
empty: boolean;
|
|
45
|
-
}
|
|
46
|
+
}>, Error>;
|
|
46
47
|
export declare const useContentDetail: (uid: string, params?: {
|
|
47
48
|
withParent?: boolean;
|
|
48
49
|
withDetail?: boolean;
|
|
49
|
-
}) => import("@tanstack/react-query").UseQueryResult<ContentDto
|
|
50
|
+
}) => import("@tanstack/react-query").UseQueryResult<NoInfer<ContentDto>, Error>;
|
|
50
51
|
export declare const useIncrementView: () => import("@tanstack/react-query").UseMutationResult<void, Error, string, {
|
|
51
52
|
previousDetail: ContentDto | undefined;
|
|
52
53
|
uid: string;
|
|
@@ -74,10 +75,12 @@ export declare const useCreateContent: () => import("@tanstack/react-query").Use
|
|
|
74
75
|
parentUid?: string | undefined;
|
|
75
76
|
sortOrder?: number | undefined;
|
|
76
77
|
mediaAttachments?: string[] | undefined;
|
|
78
|
+
startAt?: string | null | undefined;
|
|
79
|
+
endAt?: string | null | undefined;
|
|
77
80
|
}, unknown>;
|
|
78
|
-
export declare const useLikeStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
81
|
+
export declare const useLikeStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
79
82
|
liked: boolean;
|
|
80
|
-
}
|
|
83
|
+
}>, Error>;
|
|
81
84
|
export declare const useToggleLike: () => import("@tanstack/react-query").UseMutationResult<{
|
|
82
85
|
liked: boolean;
|
|
83
86
|
likeCount: number;
|
package/dist/hooks/useMedia.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export declare const useUploadToS3: () => import("@tanstack/react-query").UseMut
|
|
|
18
18
|
url: string;
|
|
19
19
|
file: File | Blob;
|
|
20
20
|
}, unknown>;
|
|
21
|
-
export declare const useMediaDetail: (uid: string) => import("@tanstack/react-query").UseQueryResult<{
|
|
21
|
+
export declare const useMediaDetail: (uid: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
22
22
|
type: "image" | "video" | "audio" | "document" | "file";
|
|
23
23
|
url: string;
|
|
24
24
|
uid: string;
|
|
@@ -29,4 +29,4 @@ export declare const useMediaDetail: (uid: string) => import("@tanstack/react-qu
|
|
|
29
29
|
width?: number | undefined;
|
|
30
30
|
height?: number | undefined;
|
|
31
31
|
description?: string | null | undefined;
|
|
32
|
-
}
|
|
32
|
+
}>, Error>;
|
package/dist/hooks/usePlace.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare const placeKeys: {
|
|
|
7
7
|
lng?: number | undefined;
|
|
8
8
|
}];
|
|
9
9
|
};
|
|
10
|
-
export declare const usePlaceSearch: (params: PlaceSearchQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
10
|
+
export declare const usePlaceSearch: (params: PlaceSearchQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
11
11
|
items: {
|
|
12
12
|
id: string;
|
|
13
13
|
provider: "google" | "naver";
|
|
@@ -35,4 +35,4 @@ export declare const usePlaceSearch: (params: PlaceSearchQuery, enabled?: boolea
|
|
|
35
35
|
}[];
|
|
36
36
|
}[];
|
|
37
37
|
keyword: string;
|
|
38
|
-
}
|
|
38
|
+
}>, Error>;
|
|
@@ -38,7 +38,7 @@ export declare const useStamp: () => import("@tanstack/react-query").UseMutation
|
|
|
38
38
|
markerUid: string;
|
|
39
39
|
data?: CollectStampRequest;
|
|
40
40
|
}, unknown>;
|
|
41
|
-
export declare const useStampStatus: (tourUid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
41
|
+
export declare const useStampStatus: (tourUid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
42
42
|
total_markers: number;
|
|
43
43
|
collected_markers: number;
|
|
44
44
|
is_completed: boolean;
|
|
@@ -46,8 +46,8 @@ export declare const useStampStatus: (tourUid: string, enabled?: boolean) => imp
|
|
|
46
46
|
marker_uid: string;
|
|
47
47
|
collected_at: string;
|
|
48
48
|
}[];
|
|
49
|
-
}
|
|
50
|
-
export declare const useTourStats: (tourUid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
49
|
+
}>, Error>;
|
|
50
|
+
export declare const useTourStats: (tourUid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
51
51
|
total_markers: number;
|
|
52
52
|
tour_uid: string;
|
|
53
53
|
tour_title: string;
|
|
@@ -60,7 +60,7 @@ export declare const useTourStats: (tourUid: string, enabled?: boolean) => impor
|
|
|
60
60
|
marker_title: string;
|
|
61
61
|
stamp_count: number;
|
|
62
62
|
}[];
|
|
63
|
-
}
|
|
63
|
+
}>, Error>;
|
|
64
64
|
export interface StampAvailability {
|
|
65
65
|
currentLocation?: {
|
|
66
66
|
latitude: number;
|
package/dist/hooks/useUser.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ListLikedContentQuery, ListUserFollowQuery, UpdateUserProfileRequest, BlockUserRequest, SuspendUserRequest } from '@ph-cms/api-contract';
|
|
2
|
+
import { UserSearchResultDto } from '../types';
|
|
2
3
|
export declare const termsKeys: {
|
|
3
4
|
all: readonly ["terms"];
|
|
4
5
|
lists: () => readonly ["terms", "list"];
|
|
@@ -15,6 +16,11 @@ export declare const userKeys: {
|
|
|
15
16
|
page: number;
|
|
16
17
|
limit: number;
|
|
17
18
|
}>];
|
|
19
|
+
search: (query: string, params: {
|
|
20
|
+
limit?: number;
|
|
21
|
+
}) => readonly ["users", "search", string, {
|
|
22
|
+
limit?: number;
|
|
23
|
+
}];
|
|
18
24
|
};
|
|
19
25
|
/**
|
|
20
26
|
* Access the current user profile and status.
|
|
@@ -60,24 +66,24 @@ export declare const useUser: () => {
|
|
|
60
66
|
/**
|
|
61
67
|
* Hook to fetch a user's public profile.
|
|
62
68
|
*/
|
|
63
|
-
export declare const useUserProfile: (uid: string) => import("@tanstack/react-query").UseQueryResult<{
|
|
69
|
+
export declare const useUserProfile: (uid: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
64
70
|
uid: string;
|
|
65
71
|
username: string | null;
|
|
66
72
|
display_name: string;
|
|
67
73
|
avatar_url: string | null;
|
|
68
74
|
follower_count: number;
|
|
69
75
|
profile_data: Record<string, any>;
|
|
70
|
-
}
|
|
76
|
+
}>, Error>;
|
|
71
77
|
/**
|
|
72
78
|
* Hook to fetch follow status for a target user.
|
|
73
79
|
*/
|
|
74
|
-
export declare const useFollowStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
80
|
+
export declare const useFollowStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
75
81
|
is_following: boolean;
|
|
76
|
-
}
|
|
82
|
+
}>, Error>;
|
|
77
83
|
/**
|
|
78
84
|
* Hook to fetch followers of a target user.
|
|
79
85
|
*/
|
|
80
|
-
export declare const useFollowers: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
86
|
+
export declare const useFollowers: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
81
87
|
items: {
|
|
82
88
|
uid: string;
|
|
83
89
|
username: string | null;
|
|
@@ -90,11 +96,11 @@ export declare const useFollowers: (uid: string, params?: Partial<ListUserFollow
|
|
|
90
96
|
page: number;
|
|
91
97
|
limit: number;
|
|
92
98
|
totalPages: number;
|
|
93
|
-
}
|
|
99
|
+
}>, Error>;
|
|
94
100
|
/**
|
|
95
101
|
* Hook to fetch followings of a target user.
|
|
96
102
|
*/
|
|
97
|
-
export declare const useFollowings: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
103
|
+
export declare const useFollowings: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
98
104
|
items: {
|
|
99
105
|
uid: string;
|
|
100
106
|
username: string | null;
|
|
@@ -107,7 +113,13 @@ export declare const useFollowings: (uid: string, params?: Partial<ListUserFollo
|
|
|
107
113
|
page: number;
|
|
108
114
|
limit: number;
|
|
109
115
|
totalPages: number;
|
|
110
|
-
}
|
|
116
|
+
}>, Error>;
|
|
117
|
+
/**
|
|
118
|
+
* Hook to search users by keyword.
|
|
119
|
+
*/
|
|
120
|
+
export declare const useUserSearch: (query: string, params?: {
|
|
121
|
+
limit?: number;
|
|
122
|
+
}, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<UserSearchResultDto[]>, Error>;
|
|
111
123
|
/**
|
|
112
124
|
* Hook to update a user's profile.
|
|
113
125
|
* Typically used by a user to update their own profile.
|
|
@@ -167,7 +179,7 @@ export declare const useUnfollowUser: () => import("@tanstack/react-query").UseM
|
|
|
167
179
|
/**
|
|
168
180
|
* Hook to fetch contents liked by a specific user.
|
|
169
181
|
*/
|
|
170
|
-
export declare const useLikedContents: (uid: string, params?: Partial<ListLikedContentQuery>) => import("@tanstack/react-query").UseQueryResult<{
|
|
182
|
+
export declare const useLikedContents: (uid: string, params?: Partial<ListLikedContentQuery>) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
171
183
|
number: number;
|
|
172
184
|
totalPages: number;
|
|
173
185
|
content: import("@ph-cms/api-contract").ContentDto[];
|
|
@@ -176,18 +188,18 @@ export declare const useLikedContents: (uid: string, params?: Partial<ListLikedC
|
|
|
176
188
|
first: boolean;
|
|
177
189
|
last: boolean;
|
|
178
190
|
empty: boolean;
|
|
179
|
-
}
|
|
191
|
+
}>, Error>;
|
|
180
192
|
/**
|
|
181
193
|
* Hook to fetch statistics of liked contents by type for a specific user.
|
|
182
194
|
*/
|
|
183
|
-
export declare const useLikedStats: (uid: string) => import("@tanstack/react-query").UseQueryResult<{
|
|
195
|
+
export declare const useLikedStats: (uid: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
184
196
|
type: string;
|
|
185
197
|
count: number;
|
|
186
|
-
}[]
|
|
198
|
+
}[]>, Error>;
|
|
187
199
|
/**
|
|
188
200
|
* List terms required/available for the current channel.
|
|
189
201
|
*/
|
|
190
|
-
export declare const useChannelTerms: () => import("@tanstack/react-query").UseQueryResult<{
|
|
202
|
+
export declare const useChannelTerms: () => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
191
203
|
code: string;
|
|
192
204
|
type: "text" | "url";
|
|
193
205
|
id: number;
|
|
@@ -197,7 +209,7 @@ export declare const useChannelTerms: () => import("@tanstack/react-query").UseQ
|
|
|
197
209
|
isActive: boolean;
|
|
198
210
|
createdAt: string;
|
|
199
211
|
isRequired?: boolean | undefined;
|
|
200
|
-
}[]
|
|
212
|
+
}[]>, Error>;
|
|
201
213
|
/**
|
|
202
214
|
* Submit term agreements for the current user.
|
|
203
215
|
*/
|
|
@@ -228,7 +240,7 @@ export declare const useUnblockUser: () => import("@tanstack/react-query").UseMu
|
|
|
228
240
|
export declare const useBlockedUsers: (uid: string, params?: {
|
|
229
241
|
page?: number;
|
|
230
242
|
limit?: number;
|
|
231
|
-
}) => import("@tanstack/react-query").UseQueryResult<{
|
|
243
|
+
}) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
232
244
|
items: {
|
|
233
245
|
uid: string;
|
|
234
246
|
username: string | null;
|
|
@@ -241,7 +253,7 @@ export declare const useBlockedUsers: (uid: string, params?: {
|
|
|
241
253
|
page: number;
|
|
242
254
|
limit: number;
|
|
243
255
|
totalPages: number;
|
|
244
|
-
}
|
|
256
|
+
}>, Error>;
|
|
245
257
|
/**
|
|
246
258
|
* Hook to suspend a user (Global Ban).
|
|
247
259
|
* Admin only.
|
package/dist/hooks/useUser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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.useUnfollowUser = exports.useFollowUser = exports.useUpdateProfile = exports.useFollowings = exports.useFollowers = exports.useFollowStatus = exports.useUserProfile = exports.useUser = exports.userKeys = 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.useUserSearch = 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 = {
|
|
@@ -13,6 +13,7 @@ exports.userKeys = {
|
|
|
13
13
|
followStatus: (uid) => [...exports.userKeys.all, 'follow-status', uid],
|
|
14
14
|
followers: (uid, params) => [...exports.userKeys.all, 'followers', uid, params],
|
|
15
15
|
followings: (uid, params) => [...exports.userKeys.all, 'followings', uid, params],
|
|
16
|
+
search: (query, params) => [...exports.userKeys.all, 'search', query, params],
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
19
|
* Access the current user profile and status.
|
|
@@ -70,6 +71,19 @@ const useFollowings = (uid, params = {}, enabled = true) => {
|
|
|
70
71
|
});
|
|
71
72
|
};
|
|
72
73
|
exports.useFollowings = useFollowings;
|
|
74
|
+
/**
|
|
75
|
+
* Hook to search users by keyword.
|
|
76
|
+
*/
|
|
77
|
+
const useUserSearch = (query, params = {}, enabled = true) => {
|
|
78
|
+
const client = (0, context_1.usePHCMS)();
|
|
79
|
+
const normalizedQuery = query.trim();
|
|
80
|
+
return (0, react_query_1.useQuery)({
|
|
81
|
+
queryKey: exports.userKeys.search(normalizedQuery, params),
|
|
82
|
+
queryFn: () => client.user.search(normalizedQuery, params),
|
|
83
|
+
enabled: !!normalizedQuery && enabled,
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
exports.useUserSearch = useUserSearch;
|
|
73
87
|
/**
|
|
74
88
|
* Hook to update a user's profile.
|
|
75
89
|
* Typically used by a user to update their own profile.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ListUserGroupQuery } from "@ph-cms/api-contract";
|
|
2
|
+
export declare const userGroupKeys: {
|
|
3
|
+
all: readonly ["user-groups"];
|
|
4
|
+
publicLists: () => readonly ["user-groups", "public", "list"];
|
|
5
|
+
publicListPrefix: (baseContentUid: string) => readonly ["user-groups", "public", "list", string];
|
|
6
|
+
publicList: (baseContentUid: string, params?: ListUserGroupQuery) => readonly ["user-groups", "public", "list", string, {
|
|
7
|
+
limit?: number | undefined;
|
|
8
|
+
offset?: number | undefined;
|
|
9
|
+
}];
|
|
10
|
+
myMembership: (baseContentUid: string, groupUid: string) => readonly ["user-groups", "me", string, string];
|
|
11
|
+
myGroups: (params?: ListUserGroupQuery) => readonly ["user-groups", "my-groups", {
|
|
12
|
+
limit?: number | undefined;
|
|
13
|
+
offset?: number | undefined;
|
|
14
|
+
}];
|
|
15
|
+
myInvites: (params?: ListUserGroupQuery) => readonly ["user-groups", "my-invites", {
|
|
16
|
+
limit?: number | undefined;
|
|
17
|
+
offset?: number | undefined;
|
|
18
|
+
}];
|
|
19
|
+
};
|
|
20
|
+
export declare const useBaseContentUserGroups: (baseContentUid: string, params?: ListUserGroupQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
21
|
+
items: {
|
|
22
|
+
isActive: boolean;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
uid: string;
|
|
25
|
+
channelUid: string;
|
|
26
|
+
name: string;
|
|
27
|
+
description: string | null;
|
|
28
|
+
baseContentUid: string;
|
|
29
|
+
groupCode: string;
|
|
30
|
+
joinMode: "open" | "invite_only" | "approval";
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
joined?: boolean | undefined;
|
|
33
|
+
}[];
|
|
34
|
+
total: number;
|
|
35
|
+
page: number;
|
|
36
|
+
limit: number;
|
|
37
|
+
totalPages: number;
|
|
38
|
+
}>, Error>;
|
|
39
|
+
export declare const useMyUserGroupMembership: (baseContentUid: string, groupUid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
40
|
+
isJoined: boolean;
|
|
41
|
+
membership: {
|
|
42
|
+
baseContentUid: string;
|
|
43
|
+
groupCode: string;
|
|
44
|
+
membershipUid: string;
|
|
45
|
+
groupUid: string;
|
|
46
|
+
groupName: string;
|
|
47
|
+
baseContentType: string;
|
|
48
|
+
baseContentTitle: string;
|
|
49
|
+
baseContentImage: string | null;
|
|
50
|
+
baseContentSlug: string | null;
|
|
51
|
+
joinedAt: string;
|
|
52
|
+
} | null;
|
|
53
|
+
}>, Error>;
|
|
54
|
+
export declare const useMyUserGroups: (params?: ListUserGroupQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
55
|
+
items: {
|
|
56
|
+
baseContentUid: string;
|
|
57
|
+
groupCode: string;
|
|
58
|
+
membershipUid: string;
|
|
59
|
+
groupUid: string;
|
|
60
|
+
groupName: string;
|
|
61
|
+
baseContentType: string;
|
|
62
|
+
baseContentTitle: string;
|
|
63
|
+
baseContentImage: string | null;
|
|
64
|
+
baseContentSlug: string | null;
|
|
65
|
+
joinedAt: string;
|
|
66
|
+
}[];
|
|
67
|
+
total: number;
|
|
68
|
+
page: number;
|
|
69
|
+
limit: number;
|
|
70
|
+
totalPages: number;
|
|
71
|
+
}>, Error>;
|
|
72
|
+
export declare const useMyUserGroupInvites: (params?: ListUserGroupQuery, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
73
|
+
items: {
|
|
74
|
+
status: "pending" | "accepted" | "declined";
|
|
75
|
+
createdAt: string;
|
|
76
|
+
uid: string;
|
|
77
|
+
baseContentUid: string;
|
|
78
|
+
groupCode: string;
|
|
79
|
+
updatedAt: string;
|
|
80
|
+
groupUid: string;
|
|
81
|
+
groupName: string;
|
|
82
|
+
inviterUid: string;
|
|
83
|
+
}[];
|
|
84
|
+
total: number;
|
|
85
|
+
page: number;
|
|
86
|
+
limit: number;
|
|
87
|
+
totalPages: number;
|
|
88
|
+
}>, Error>;
|
|
89
|
+
export declare const useJoinUserGroup: () => import("@tanstack/react-query").UseMutationResult<{
|
|
90
|
+
joined: boolean;
|
|
91
|
+
membership: {
|
|
92
|
+
baseContentUid: string;
|
|
93
|
+
groupCode: string;
|
|
94
|
+
membershipUid: string;
|
|
95
|
+
groupUid: string;
|
|
96
|
+
groupName: string;
|
|
97
|
+
baseContentType: string;
|
|
98
|
+
baseContentTitle: string;
|
|
99
|
+
baseContentImage: string | null;
|
|
100
|
+
baseContentSlug: string | null;
|
|
101
|
+
joinedAt: string;
|
|
102
|
+
};
|
|
103
|
+
}, Error, {
|
|
104
|
+
baseContentUid: string;
|
|
105
|
+
groupUid: string;
|
|
106
|
+
}, unknown>;
|
|
107
|
+
export declare const useLeaveUserGroup: () => import("@tanstack/react-query").UseMutationResult<{
|
|
108
|
+
left: boolean;
|
|
109
|
+
}, Error, {
|
|
110
|
+
baseContentUid: string;
|
|
111
|
+
groupUid: string;
|
|
112
|
+
}, unknown>;
|
|
113
|
+
export declare const useAcceptUserGroupInvite: () => import("@tanstack/react-query").UseMutationResult<{
|
|
114
|
+
success: boolean;
|
|
115
|
+
}, Error, {
|
|
116
|
+
inviteUid: string;
|
|
117
|
+
}, unknown>;
|
|
118
|
+
export declare const useDeclineUserGroupInvite: () => import("@tanstack/react-query").UseMutationResult<{
|
|
119
|
+
success: boolean;
|
|
120
|
+
}, Error, {
|
|
121
|
+
inviteUid: string;
|
|
122
|
+
}, unknown>;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDeclineUserGroupInvite = exports.useAcceptUserGroupInvite = exports.useLeaveUserGroup = exports.useJoinUserGroup = exports.useMyUserGroupInvites = exports.useMyUserGroups = exports.useMyUserGroupMembership = exports.useBaseContentUserGroups = exports.userGroupKeys = void 0;
|
|
4
|
+
const react_query_1 = require("@tanstack/react-query");
|
|
5
|
+
const context_1 = require("../context");
|
|
6
|
+
exports.userGroupKeys = {
|
|
7
|
+
all: ["user-groups"],
|
|
8
|
+
publicLists: () => [...exports.userGroupKeys.all, "public", "list"],
|
|
9
|
+
publicListPrefix: (baseContentUid) => [...exports.userGroupKeys.publicLists(), baseContentUid],
|
|
10
|
+
publicList: (baseContentUid, params = {}) => [...exports.userGroupKeys.publicLists(), baseContentUid, params],
|
|
11
|
+
myMembership: (baseContentUid, groupUid) => [...exports.userGroupKeys.all, "me", baseContentUid, groupUid],
|
|
12
|
+
myGroups: (params = {}) => [...exports.userGroupKeys.all, "my-groups", params],
|
|
13
|
+
myInvites: (params = {}) => [...exports.userGroupKeys.all, "my-invites", params],
|
|
14
|
+
};
|
|
15
|
+
const useBaseContentUserGroups = (baseContentUid, params = {}, enabled = true) => {
|
|
16
|
+
const client = (0, context_1.usePHCMS)();
|
|
17
|
+
return (0, react_query_1.useQuery)({
|
|
18
|
+
queryKey: exports.userGroupKeys.publicList(baseContentUid, params),
|
|
19
|
+
queryFn: () => client.userGroup.listByBaseContent(baseContentUid, params),
|
|
20
|
+
enabled: !!baseContentUid && enabled,
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
exports.useBaseContentUserGroups = useBaseContentUserGroups;
|
|
24
|
+
const useMyUserGroupMembership = (baseContentUid, groupUid, enabled = true) => {
|
|
25
|
+
const client = (0, context_1.usePHCMS)();
|
|
26
|
+
return (0, react_query_1.useQuery)({
|
|
27
|
+
queryKey: exports.userGroupKeys.myMembership(baseContentUid, groupUid),
|
|
28
|
+
queryFn: () => client.userGroup.getMyMembership(baseContentUid, groupUid),
|
|
29
|
+
enabled: !!baseContentUid && !!groupUid && enabled,
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
exports.useMyUserGroupMembership = useMyUserGroupMembership;
|
|
33
|
+
const useMyUserGroups = (params = {}, enabled = true) => {
|
|
34
|
+
const client = (0, context_1.usePHCMS)();
|
|
35
|
+
return (0, react_query_1.useQuery)({
|
|
36
|
+
queryKey: exports.userGroupKeys.myGroups(params),
|
|
37
|
+
queryFn: () => client.userGroup.listMine(params),
|
|
38
|
+
enabled,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
exports.useMyUserGroups = useMyUserGroups;
|
|
42
|
+
const useMyUserGroupInvites = (params = {}, enabled = true) => {
|
|
43
|
+
const client = (0, context_1.usePHCMS)();
|
|
44
|
+
return (0, react_query_1.useQuery)({
|
|
45
|
+
queryKey: exports.userGroupKeys.myInvites(params),
|
|
46
|
+
queryFn: () => client.userGroup.listMyInvites(params),
|
|
47
|
+
enabled,
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
exports.useMyUserGroupInvites = useMyUserGroupInvites;
|
|
51
|
+
const useJoinUserGroup = () => {
|
|
52
|
+
const client = (0, context_1.usePHCMS)();
|
|
53
|
+
const queryClient = (0, react_query_1.useQueryClient)();
|
|
54
|
+
return (0, react_query_1.useMutation)({
|
|
55
|
+
mutationFn: ({ baseContentUid, groupUid }) => client.userGroup.join(baseContentUid, groupUid),
|
|
56
|
+
onSuccess: (_data, variables) => {
|
|
57
|
+
queryClient.invalidateQueries({
|
|
58
|
+
queryKey: exports.userGroupKeys.publicListPrefix(variables.baseContentUid),
|
|
59
|
+
});
|
|
60
|
+
queryClient.invalidateQueries({
|
|
61
|
+
queryKey: exports.userGroupKeys.myMembership(variables.baseContentUid, variables.groupUid),
|
|
62
|
+
});
|
|
63
|
+
queryClient.invalidateQueries({
|
|
64
|
+
queryKey: [...exports.userGroupKeys.all, "my-groups"],
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
exports.useJoinUserGroup = useJoinUserGroup;
|
|
70
|
+
const useLeaveUserGroup = () => {
|
|
71
|
+
const client = (0, context_1.usePHCMS)();
|
|
72
|
+
const queryClient = (0, react_query_1.useQueryClient)();
|
|
73
|
+
return (0, react_query_1.useMutation)({
|
|
74
|
+
mutationFn: ({ baseContentUid, groupUid }) => client.userGroup.leave(baseContentUid, groupUid),
|
|
75
|
+
onSuccess: (_data, variables) => {
|
|
76
|
+
queryClient.invalidateQueries({
|
|
77
|
+
queryKey: exports.userGroupKeys.publicListPrefix(variables.baseContentUid),
|
|
78
|
+
});
|
|
79
|
+
queryClient.invalidateQueries({
|
|
80
|
+
queryKey: exports.userGroupKeys.myMembership(variables.baseContentUid, variables.groupUid),
|
|
81
|
+
});
|
|
82
|
+
queryClient.invalidateQueries({
|
|
83
|
+
queryKey: [...exports.userGroupKeys.all, "my-groups"],
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
exports.useLeaveUserGroup = useLeaveUserGroup;
|
|
89
|
+
const useAcceptUserGroupInvite = () => {
|
|
90
|
+
const client = (0, context_1.usePHCMS)();
|
|
91
|
+
const queryClient = (0, react_query_1.useQueryClient)();
|
|
92
|
+
return (0, react_query_1.useMutation)({
|
|
93
|
+
mutationFn: ({ inviteUid }) => client.userGroup.acceptInvite(inviteUid),
|
|
94
|
+
onSuccess: () => {
|
|
95
|
+
queryClient.invalidateQueries({
|
|
96
|
+
queryKey: [...exports.userGroupKeys.all, "my-invites"],
|
|
97
|
+
});
|
|
98
|
+
queryClient.invalidateQueries({
|
|
99
|
+
queryKey: [...exports.userGroupKeys.all, "my-groups"],
|
|
100
|
+
});
|
|
101
|
+
queryClient.invalidateQueries({
|
|
102
|
+
queryKey: [...exports.userGroupKeys.all, "public", "list"],
|
|
103
|
+
});
|
|
104
|
+
queryClient.invalidateQueries({
|
|
105
|
+
queryKey: [...exports.userGroupKeys.all, "me"],
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
exports.useAcceptUserGroupInvite = useAcceptUserGroupInvite;
|
|
111
|
+
const useDeclineUserGroupInvite = () => {
|
|
112
|
+
const client = (0, context_1.usePHCMS)();
|
|
113
|
+
const queryClient = (0, react_query_1.useQueryClient)();
|
|
114
|
+
return (0, react_query_1.useMutation)({
|
|
115
|
+
mutationFn: ({ inviteUid }) => client.userGroup.declineInvite(inviteUid),
|
|
116
|
+
onSuccess: () => {
|
|
117
|
+
queryClient.invalidateQueries({
|
|
118
|
+
queryKey: [...exports.userGroupKeys.all, "my-invites"],
|
|
119
|
+
});
|
|
120
|
+
queryClient.invalidateQueries({
|
|
121
|
+
queryKey: [...exports.userGroupKeys.all, "me"],
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
exports.useDeclineUserGroupInvite = useDeclineUserGroupInvite;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from './modules/content';
|
|
|
12
12
|
export * from './modules/media';
|
|
13
13
|
export * from './modules/place';
|
|
14
14
|
export * from './modules/terms';
|
|
15
|
+
export * from './modules/user-group';
|
|
15
16
|
export * from './modules/user';
|
|
16
17
|
export * from './context';
|
|
17
18
|
export * from './hooks/useAuth';
|
|
@@ -20,5 +21,6 @@ export * from './hooks/useStampTour';
|
|
|
20
21
|
export * from './hooks/useFirebaseAuthSync';
|
|
21
22
|
export * from './hooks/useMedia';
|
|
22
23
|
export * from './hooks/usePlace';
|
|
24
|
+
export * from './hooks/useUserGroup';
|
|
23
25
|
export * from './hooks/useUser';
|
|
24
26
|
export * from './types';
|
package/dist/index.js
CHANGED
|
@@ -28,6 +28,7 @@ __exportStar(require("./modules/content"), exports);
|
|
|
28
28
|
__exportStar(require("./modules/media"), exports);
|
|
29
29
|
__exportStar(require("./modules/place"), exports);
|
|
30
30
|
__exportStar(require("./modules/terms"), exports);
|
|
31
|
+
__exportStar(require("./modules/user-group"), exports);
|
|
31
32
|
__exportStar(require("./modules/user"), exports);
|
|
32
33
|
__exportStar(require("./context"), exports);
|
|
33
34
|
__exportStar(require("./hooks/useAuth"), exports);
|
|
@@ -36,5 +37,6 @@ __exportStar(require("./hooks/useStampTour"), exports);
|
|
|
36
37
|
__exportStar(require("./hooks/useFirebaseAuthSync"), exports);
|
|
37
38
|
__exportStar(require("./hooks/useMedia"), exports);
|
|
38
39
|
__exportStar(require("./hooks/usePlace"), exports);
|
|
40
|
+
__exportStar(require("./hooks/useUserGroup"), exports);
|
|
39
41
|
__exportStar(require("./hooks/useUser"), exports);
|
|
40
42
|
__exportStar(require("./types"), exports);
|
package/dist/modules/auth.d.ts
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
import { AnonymousLoginRequest, AuthResponse, FirebaseExchangeRequest, FirebaseRegisterRequest, LoginRequest, RegisterRequest, UserDto } from "@ph-cms/api-contract";
|
|
2
2
|
import { AxiosInstance } from "axios";
|
|
3
3
|
import { AuthProvider } from "../auth/interfaces";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
declare const CheckEmailResponseSchema: z.ZodObject<{
|
|
6
|
+
email: z.ZodString;
|
|
7
|
+
exists: z.ZodBoolean;
|
|
8
|
+
channels: z.ZodArray<z.ZodObject<{
|
|
9
|
+
channelUid: z.ZodString;
|
|
10
|
+
channelName: z.ZodString;
|
|
11
|
+
channelSlug: z.ZodString;
|
|
12
|
+
relationType: z.ZodEnum<["owner", "member"]>;
|
|
13
|
+
memberRole: z.ZodNullable<z.ZodString>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
channelUid: string;
|
|
16
|
+
channelName: string;
|
|
17
|
+
channelSlug: string;
|
|
18
|
+
relationType: "owner" | "member";
|
|
19
|
+
memberRole: string | null;
|
|
20
|
+
}, {
|
|
21
|
+
channelUid: string;
|
|
22
|
+
channelName: string;
|
|
23
|
+
channelSlug: string;
|
|
24
|
+
relationType: "owner" | "member";
|
|
25
|
+
memberRole: string | null;
|
|
26
|
+
}>, "many">;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
email: string;
|
|
29
|
+
exists: boolean;
|
|
30
|
+
channels: {
|
|
31
|
+
channelUid: string;
|
|
32
|
+
channelName: string;
|
|
33
|
+
channelSlug: string;
|
|
34
|
+
relationType: "owner" | "member";
|
|
35
|
+
memberRole: string | null;
|
|
36
|
+
}[];
|
|
37
|
+
}, {
|
|
38
|
+
email: string;
|
|
39
|
+
exists: boolean;
|
|
40
|
+
channels: {
|
|
41
|
+
channelUid: string;
|
|
42
|
+
channelName: string;
|
|
43
|
+
channelSlug: string;
|
|
44
|
+
relationType: "owner" | "member";
|
|
45
|
+
memberRole: string | null;
|
|
46
|
+
}[];
|
|
47
|
+
}>;
|
|
48
|
+
type CheckEmailResponse = z.infer<typeof CheckEmailResponseSchema>;
|
|
49
|
+
export type { CheckEmailResponse };
|
|
4
50
|
export declare class AuthModule {
|
|
5
51
|
private client;
|
|
6
52
|
private provider?;
|
|
@@ -15,6 +61,7 @@ export declare class AuthModule {
|
|
|
15
61
|
*/
|
|
16
62
|
loginWithFirebase(data: FirebaseExchangeRequest): Promise<AuthResponse>;
|
|
17
63
|
register(data: RegisterRequest): Promise<AuthResponse>;
|
|
64
|
+
checkEmail(email: string): Promise<CheckEmailResponse>;
|
|
18
65
|
/**
|
|
19
66
|
* 서버 사이드 Firebase 회원가입.
|
|
20
67
|
* 클라이언트는 idToken 없이 이메일/비밀번호를 전송하고,
|
package/dist/modules/auth.js
CHANGED
|
@@ -3,6 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AuthModule = void 0;
|
|
4
4
|
const api_contract_1 = require("@ph-cms/api-contract");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const CheckEmailQuerySchema = zod_1.z.object({
|
|
8
|
+
email: zod_1.z.string().email(),
|
|
9
|
+
});
|
|
10
|
+
const EmailChannelAssociationSchema = zod_1.z.object({
|
|
11
|
+
channelUid: zod_1.z.string(),
|
|
12
|
+
channelName: zod_1.z.string(),
|
|
13
|
+
channelSlug: zod_1.z.string(),
|
|
14
|
+
relationType: zod_1.z.enum(["owner", "member"]),
|
|
15
|
+
memberRole: zod_1.z.string().nullable(),
|
|
16
|
+
});
|
|
17
|
+
const CheckEmailResponseSchema = zod_1.z.object({
|
|
18
|
+
email: zod_1.z.string().email(),
|
|
19
|
+
exists: zod_1.z.boolean(),
|
|
20
|
+
channels: zod_1.z.array(EmailChannelAssociationSchema),
|
|
21
|
+
});
|
|
6
22
|
class AuthModule {
|
|
7
23
|
constructor(client, provider, prefix = '/api') {
|
|
8
24
|
this.client = client;
|
|
@@ -48,6 +64,15 @@ class AuthModule {
|
|
|
48
64
|
}
|
|
49
65
|
return response;
|
|
50
66
|
}
|
|
67
|
+
async checkEmail(email) {
|
|
68
|
+
const validation = CheckEmailQuerySchema.safeParse({ email });
|
|
69
|
+
if (!validation.success) {
|
|
70
|
+
throw new errors_1.ValidationError("Invalid email", validation.error.errors);
|
|
71
|
+
}
|
|
72
|
+
return this.client.get(`${this.prefix}/auth/check-email`, {
|
|
73
|
+
params: validation.data,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
51
76
|
/**
|
|
52
77
|
* 서버 사이드 Firebase 회원가입.
|
|
53
78
|
* 클라이언트는 idToken 없이 이메일/비밀번호를 전송하고,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { GetMyUserGroupMembershipResponse, JoinUserGroupResponse, LeaveUserGroupResponse, ListUserGroupQuery, PagedMyGroupInviteListResponse, PagedMyUserGroupMembershipListResponse, PagedUserGroupListResponse, RespondInviteResponse } from "@ph-cms/api-contract";
|
|
2
|
+
import { AxiosInstance } from "axios";
|
|
3
|
+
export declare class UserGroupModule {
|
|
4
|
+
private client;
|
|
5
|
+
private prefix;
|
|
6
|
+
constructor(client: AxiosInstance, prefix?: string);
|
|
7
|
+
listByBaseContent(baseContentUid: string, params?: ListUserGroupQuery): Promise<PagedUserGroupListResponse>;
|
|
8
|
+
getMyMembership(baseContentUid: string, groupUid: string): Promise<GetMyUserGroupMembershipResponse>;
|
|
9
|
+
join(baseContentUid: string, groupUid: string): Promise<JoinUserGroupResponse>;
|
|
10
|
+
leave(baseContentUid: string, groupUid: string): Promise<LeaveUserGroupResponse>;
|
|
11
|
+
listMine(params?: ListUserGroupQuery): Promise<PagedMyUserGroupMembershipListResponse>;
|
|
12
|
+
listMyInvites(params?: ListUserGroupQuery): Promise<PagedMyGroupInviteListResponse>;
|
|
13
|
+
acceptInvite(inviteUid: string): Promise<RespondInviteResponse>;
|
|
14
|
+
declineInvite(inviteUid: string): Promise<RespondInviteResponse>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserGroupModule = void 0;
|
|
4
|
+
const api_contract_1 = require("@ph-cms/api-contract");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
class UserGroupModule {
|
|
7
|
+
constructor(client, prefix = "/api") {
|
|
8
|
+
this.client = client;
|
|
9
|
+
this.prefix = prefix;
|
|
10
|
+
}
|
|
11
|
+
async listByBaseContent(baseContentUid, params = {}) {
|
|
12
|
+
if (!baseContentUid)
|
|
13
|
+
throw new errors_1.ValidationError("Base content UID is required", []);
|
|
14
|
+
const validation = api_contract_1.ListUserGroupQuerySchema.safeParse(params);
|
|
15
|
+
if (!validation.success) {
|
|
16
|
+
throw new errors_1.ValidationError("Invalid user group list params", validation.error.errors);
|
|
17
|
+
}
|
|
18
|
+
return this.client.get(`${this.prefix}/contents/${baseContentUid}/user-groups`, { params: validation.data });
|
|
19
|
+
}
|
|
20
|
+
async getMyMembership(baseContentUid, groupUid) {
|
|
21
|
+
if (!baseContentUid)
|
|
22
|
+
throw new errors_1.ValidationError("Base content UID is required", []);
|
|
23
|
+
if (!groupUid)
|
|
24
|
+
throw new errors_1.ValidationError("Group UID is required", []);
|
|
25
|
+
return this.client.get(`${this.prefix}/contents/${baseContentUid}/user-groups/${groupUid}/me`);
|
|
26
|
+
}
|
|
27
|
+
async join(baseContentUid, groupUid) {
|
|
28
|
+
if (!baseContentUid)
|
|
29
|
+
throw new errors_1.ValidationError("Base content UID is required", []);
|
|
30
|
+
if (!groupUid)
|
|
31
|
+
throw new errors_1.ValidationError("Group UID is required", []);
|
|
32
|
+
return this.client.post(`${this.prefix}/contents/${baseContentUid}/user-groups/${groupUid}/join`);
|
|
33
|
+
}
|
|
34
|
+
async leave(baseContentUid, groupUid) {
|
|
35
|
+
if (!baseContentUid)
|
|
36
|
+
throw new errors_1.ValidationError("Base content UID is required", []);
|
|
37
|
+
if (!groupUid)
|
|
38
|
+
throw new errors_1.ValidationError("Group UID is required", []);
|
|
39
|
+
return this.client.delete(`${this.prefix}/contents/${baseContentUid}/user-groups/${groupUid}/join`);
|
|
40
|
+
}
|
|
41
|
+
async listMine(params = {}) {
|
|
42
|
+
const validation = api_contract_1.ListUserGroupQuerySchema.safeParse(params);
|
|
43
|
+
if (!validation.success) {
|
|
44
|
+
throw new errors_1.ValidationError("Invalid my user group list params", validation.error.errors);
|
|
45
|
+
}
|
|
46
|
+
return this.client.get(`${this.prefix}/me/user-groups`, { params: validation.data });
|
|
47
|
+
}
|
|
48
|
+
async listMyInvites(params = {}) {
|
|
49
|
+
const validation = api_contract_1.ListUserGroupQuerySchema.safeParse(params);
|
|
50
|
+
if (!validation.success) {
|
|
51
|
+
throw new errors_1.ValidationError("Invalid my user group invite list params", validation.error.errors);
|
|
52
|
+
}
|
|
53
|
+
return this.client.get(`${this.prefix}/me/group-invites`, { params: validation.data });
|
|
54
|
+
}
|
|
55
|
+
async acceptInvite(inviteUid) {
|
|
56
|
+
if (!inviteUid)
|
|
57
|
+
throw new errors_1.ValidationError("Invite UID is required", []);
|
|
58
|
+
return this.client.post(`${this.prefix}/me/group-invites/${inviteUid}/accept`);
|
|
59
|
+
}
|
|
60
|
+
async declineInvite(inviteUid) {
|
|
61
|
+
if (!inviteUid)
|
|
62
|
+
throw new errors_1.ValidationError("Invite UID is required", []);
|
|
63
|
+
return this.client.post(`${this.prefix}/me/group-invites/${inviteUid}/decline`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.UserGroupModule = UserGroupModule;
|
package/dist/modules/user.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
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
|
+
import { UserSearchResultDto } from "../types";
|
|
3
4
|
export declare class UserModule {
|
|
4
5
|
private client;
|
|
5
6
|
private prefix;
|
|
@@ -42,6 +43,15 @@ export declare class UserModule {
|
|
|
42
43
|
* @param params - Paging parameters.
|
|
43
44
|
*/
|
|
44
45
|
getFollowings(uid: string, params?: Partial<ListUserFollowQuery>): Promise<PagedUserProfileListResponse>;
|
|
46
|
+
/**
|
|
47
|
+
* Searches users by name, username, or email keyword.
|
|
48
|
+
*
|
|
49
|
+
* @param query - Search keyword.
|
|
50
|
+
* @param params - Optional search limits.
|
|
51
|
+
*/
|
|
52
|
+
search(query: string, params?: {
|
|
53
|
+
limit?: number;
|
|
54
|
+
}): Promise<UserSearchResultDto[]>;
|
|
45
55
|
/**
|
|
46
56
|
* Updates a user's profile.
|
|
47
57
|
*
|
package/dist/modules/user.js
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UserModule = void 0;
|
|
4
4
|
const api_contract_1 = require("@ph-cms/api-contract");
|
|
5
|
+
const zod_1 = require("zod");
|
|
5
6
|
const errors_1 = require("../errors");
|
|
7
|
+
const UserSearchQuerySchema = zod_1.z.object({
|
|
8
|
+
limit: zod_1.z.coerce.number().int().min(1).max(10).optional(),
|
|
9
|
+
});
|
|
6
10
|
class UserModule {
|
|
7
11
|
constructor(client, prefix = '/api') {
|
|
8
12
|
this.client = client;
|
|
@@ -76,6 +80,27 @@ class UserModule {
|
|
|
76
80
|
}
|
|
77
81
|
return this.client.get(`${this.prefix}/users/${uid}/followings`, { params: validation.data });
|
|
78
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Searches users by name, username, or email keyword.
|
|
85
|
+
*
|
|
86
|
+
* @param query - Search keyword.
|
|
87
|
+
* @param params - Optional search limits.
|
|
88
|
+
*/
|
|
89
|
+
async search(query, params = {}) {
|
|
90
|
+
const keyword = query.trim();
|
|
91
|
+
if (!keyword)
|
|
92
|
+
throw new errors_1.ValidationError("Query is required", []);
|
|
93
|
+
const validation = UserSearchQuerySchema.safeParse(params);
|
|
94
|
+
if (!validation.success) {
|
|
95
|
+
throw new errors_1.ValidationError("Invalid user search params", validation.error.errors);
|
|
96
|
+
}
|
|
97
|
+
return this.client.get(`${this.prefix}/users/search`, {
|
|
98
|
+
params: {
|
|
99
|
+
q: keyword,
|
|
100
|
+
...validation.data,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
79
104
|
/**
|
|
80
105
|
* Updates a user's profile.
|
|
81
106
|
*
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ export type { AuthProvider } from './auth/interfaces';
|
|
|
2
2
|
export type { JwtPayload } from './auth/jwt-utils';
|
|
3
3
|
export type { PHCMSClientConfig } from './client';
|
|
4
4
|
export type { AuthStatus, PHCMSContextType, PHCMSProviderProps } from './context';
|
|
5
|
+
export type UserSearchResultDto = {
|
|
6
|
+
uid: string;
|
|
7
|
+
username: string | null;
|
|
8
|
+
display_name: string;
|
|
9
|
+
avatar_url: string | null;
|
|
10
|
+
};
|
|
5
11
|
export type { FirebaseAuthSyncProps, UseFirebaseAuthSyncOptions, UseFirebaseAuthSyncReturn } from './hooks/useFirebaseAuthSync';
|
|
6
12
|
export type { StampAvailability, CheckStampAvailabilityParams } from './hooks/useStampTour';
|
|
7
13
|
export type { AnonymousLoginRequest, AuthResponse, FirebaseExchangeRequest, FirebaseRegisterRequest, LoginRequest, RefreshTokenRequest, RegisterRequest, } from '@ph-cms/api-contract';
|
|
@@ -9,9 +15,10 @@ export type { UserDto, UserProfileDto, FollowStatusResponse, FollowUserResponse,
|
|
|
9
15
|
export type { ChannelContentCountDto, ChannelContentCountsQuery, ChannelContentCountsResponse, ChannelDto, ChannelPublicContentSummaryResponse, CheckHierarchyQuery, } from '@ph-cms/api-contract';
|
|
10
16
|
export type { ContentDto, ContentStatDto, ContentMediaDto, ContentStatus, CreateContentRequest, ListContentQuery, PagedContentListResponse, UpdateContentRequest, } from '@ph-cms/api-contract';
|
|
11
17
|
export type { HierarchySetDto } from '@ph-cms/api-contract';
|
|
12
|
-
export type { PermissionPolicySetDto } from '@ph-cms/api-contract';
|
|
18
|
+
export type { ChannelContentRolePolicy, PermissionAction, PermissionPolicyDocument, PermissionPolicySetDto, PermissionRule, } from '@ph-cms/api-contract';
|
|
13
19
|
export type { TermDto } from '@ph-cms/api-contract';
|
|
14
20
|
export type { GeoJSON } from '@ph-cms/api-contract';
|
|
15
21
|
export type { MediaUploadTicketBatchRequest, MediaUploadTicketBatchResponse, MediaUploadTicketRequest, MediaUploadTicketResponse } from '@ph-cms/api-contract';
|
|
16
22
|
export type { IntegratedPlace, PlaceSearchQuery, PlaceSearchResponse, } from '@ph-cms/api-contract';
|
|
23
|
+
export type { GetMyUserGroupMembershipResponse, JoinUserGroupResponse, LeaveUserGroupResponse, ListUserGroupQuery, PagedMyGroupInviteListResponse, PagedMyUserGroupMembershipListResponse, PagedUserGroupListResponse, RespondInviteResponse, UserGroupDto, UserGroupJoinMode, UserGroupInviteDto, UserGroupInviteStatus, UserGroupMembershipDto, } from '@ph-cms/api-contract';
|
|
17
24
|
export type { PagedResponse } 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.
|
|
3
|
+
"version": "0.1.51",
|
|
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": "
|
|
33
|
+
"@ph-cms/api-contract": "0.1.29",
|
|
34
34
|
"@tanstack/react-query": "^5.0.0",
|
|
35
35
|
"axios": "^1.6.0",
|
|
36
36
|
"zod": "^3.22.4"
|