@ph-cms/client-sdk 0.1.47 → 0.1.50
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 +72 -4
- 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 +16 -16
- package/dist/modules/auth.d.ts +47 -0
- package/dist/modules/auth.js +25 -0
- package/dist/types.d.ts +1 -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
|
|
|
@@ -68,6 +68,9 @@ import type {
|
|
|
68
68
|
|
|
69
69
|
// Channel
|
|
70
70
|
ChannelDto,
|
|
71
|
+
ChannelContentCountsQuery,
|
|
72
|
+
ChannelContentCountsResponse,
|
|
73
|
+
ChannelPublicContentSummaryResponse,
|
|
71
74
|
CheckHierarchyQuery,
|
|
72
75
|
|
|
73
76
|
// Content
|
|
@@ -167,8 +170,41 @@ SDK의 인증 시스템은 세 개의 레이어로 구성됩니다:
|
|
|
167
170
|
| `loginWithFirebase()` | `POST /api/auth/firebase/exchange` | `setTokens()` → `refreshUser()` |
|
|
168
171
|
| `register()` (method: 'email') | `POST /api/auth/register` | `setTokens()` → `refreshUser()` |
|
|
169
172
|
| `register()` (method: 'firebase') | `POST /api/auth/register` (provider: firebase:password) | `setTokens()` → `refreshUser()` |
|
|
173
|
+
| `checkEmail()` | `GET /api/auth/check-email` | 중복 여부 확인용 |
|
|
170
174
|
| `logout()` | `POST /api/auth/logout` | `provider.logout()` → `refreshUser()` (상태 초기화) |
|
|
171
175
|
|
|
176
|
+
### Email Duplicate Check
|
|
177
|
+
|
|
178
|
+
회원가입 전에 이메일 중복 여부와 소속 채널을 확인할 수 있습니다.
|
|
179
|
+
|
|
180
|
+
`useAuth()`에서 바로 사용할 수 있습니다.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
const { checkEmail, checkEmailStatus } = useAuth();
|
|
184
|
+
|
|
185
|
+
const result = await checkEmail('user@example.com');
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
{
|
|
190
|
+
email: 'user@example.com',
|
|
191
|
+
exists: true,
|
|
192
|
+
channels: [
|
|
193
|
+
{
|
|
194
|
+
channelUid: 'ch_xxx',
|
|
195
|
+
channelName: 'Seoul Channel',
|
|
196
|
+
channelSlug: 'seoul-channel',
|
|
197
|
+
relationType: 'member',
|
|
198
|
+
memberRole: 'manager'
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- `exists: false` 이면 `channels` 는 빈 배열입니다.
|
|
205
|
+
- `relationType` 은 `owner` 또는 `member` 입니다.
|
|
206
|
+
- `memberRole` 은 채널 멤버인 경우에만 값이 있으며, 소유자인 경우 `null` 입니다.
|
|
207
|
+
|
|
172
208
|
### Authentication Lifecycle
|
|
173
209
|
|
|
174
210
|
#### 1. 초기 마운트 (비인증 상태)
|
|
@@ -354,7 +390,9 @@ const client = new PHCMSClient({
|
|
|
354
390
|
|
|
355
391
|
### `FirebaseAuthProvider`
|
|
356
392
|
|
|
357
|
-
Firebase Authentication과 연동합니다. PH-CMS
|
|
393
|
+
Firebase Authentication과 연동합니다. PH-CMS access/refresh 토큰을 관리하며,
|
|
394
|
+
`getToken()`은 PH-CMS access token만 반환합니다. PH-CMS 토큰이 없거나 만료되어 갱신에 실패하면 `null`을 반환합니다.
|
|
395
|
+
Firebase ID 토큰이 필요하면 별도로 `getIdToken()`을 호출합니다.
|
|
358
396
|
|
|
359
397
|
```ts
|
|
360
398
|
import { FirebaseAuthProvider, PHCMSClient } from '@ph-cms/client-sdk';
|
|
@@ -384,7 +422,13 @@ const client = new PHCMSClient({
|
|
|
384
422
|
|
|
385
423
|
1. PH-CMS access token이 유효하면 → 그대로 반환
|
|
386
424
|
2. 만료 임박이면 → `tryRefresh()` 시도 → 성공하면 새 토큰 반환
|
|
387
|
-
3. PH-CMS
|
|
425
|
+
3. PH-CMS access token이 없거나 갱신 실패 → `null` 반환
|
|
426
|
+
|
|
427
|
+
Firebase ID token이 필요한 경우:
|
|
428
|
+
|
|
429
|
+
```ts
|
|
430
|
+
const firebaseIdToken = await authProvider.getIdToken();
|
|
431
|
+
```
|
|
388
432
|
|
|
389
433
|
### `AuthProvider` Interface
|
|
390
434
|
|
|
@@ -503,6 +547,7 @@ function AuthComponent() {
|
|
|
503
547
|
login, // (data: LoginRequest) => Promise<AuthResponse>
|
|
504
548
|
loginWithFirebase, // (data: FirebaseExchangeRequest) => Promise<AuthResponse>
|
|
505
549
|
register, // (data: RegisterInput) => Promise<AuthResponse> ← method: 'email' | 'firebase'
|
|
550
|
+
checkEmail, // (email: string) => Promise<CheckEmailResponse>
|
|
506
551
|
loginAnonymous, // (data?: AnonymousLoginRequest) => Promise<AuthResponse>
|
|
507
552
|
upgradeAnonymous, // (data: { email, password, display_name?, username?, phone_number? }) => Promise<UserDto>
|
|
508
553
|
logout, // () => Promise<void>
|
|
@@ -511,6 +556,7 @@ function AuthComponent() {
|
|
|
511
556
|
loginStatus,
|
|
512
557
|
loginWithFirebaseStatus,
|
|
513
558
|
registerStatus,
|
|
559
|
+
checkEmailStatus,
|
|
514
560
|
loginAnonymousStatus,
|
|
515
561
|
upgradeAnonymousStatus,
|
|
516
562
|
logoutStatus,
|
|
@@ -1011,6 +1057,17 @@ const detail = await client.content.get('content-uid');
|
|
|
1011
1057
|
|
|
1012
1058
|
// 채널 정보 조회
|
|
1013
1059
|
const channel = await client.channel.getBySlug('my-channel-slug');
|
|
1060
|
+
|
|
1061
|
+
// 채널 관리용 콘텐츠 요약 조회
|
|
1062
|
+
// includeDeleted는 true만 허용됩니다.
|
|
1063
|
+
const counts = await client.channel.getManageContentCounts('my-channel-uid', {
|
|
1064
|
+
includeDeleted: true,
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
// 채널 요약 조회
|
|
1068
|
+
const summary = await client.channel.getContentSummary('my-channel-uid');
|
|
1069
|
+
console.log(summary.totalPublishedCount);
|
|
1070
|
+
console.log(summary.counts);
|
|
1014
1071
|
```
|
|
1015
1072
|
|
|
1016
1073
|
### 4. 약관 동의
|
|
@@ -1841,10 +1898,19 @@ const result = await content.list({ channelUid: 'my-channel' });
|
|
|
1841
1898
|
예시:
|
|
1842
1899
|
|
|
1843
1900
|
```ts
|
|
1844
|
-
await client.content.list({
|
|
1901
|
+
await client.content.list({
|
|
1902
|
+
withParent: true,
|
|
1903
|
+
withDetail: true,
|
|
1904
|
+
page: 1,
|
|
1905
|
+
limit: 20,
|
|
1906
|
+
periodAt: '2026-06-10T00:00:00Z',
|
|
1907
|
+
});
|
|
1845
1908
|
await client.content.get('cnt_123', { withParent: true, withDetail: true });
|
|
1846
1909
|
```
|
|
1847
1910
|
|
|
1911
|
+
`periodAt`은 `startAt` / `endAt`로 저장된 콘텐츠 기간을 기준으로 목록을 필터링할 때 사용합니다.
|
|
1912
|
+
예를 들어 `periodAt: '2026-06-10T00:00:00Z'`를 전달하면 해당 시점에 유효한 콘텐츠만 조회됩니다.
|
|
1913
|
+
|
|
1848
1914
|
### `ChannelModule` (`client.channel`)
|
|
1849
1915
|
|
|
1850
1916
|
| 메서드 | 설명 |
|
|
@@ -1853,6 +1919,8 @@ await client.content.get('cnt_123', { withParent: true, withDetail: true });
|
|
|
1853
1919
|
| `getBySlug(slug: string)` | 슬러그로 채널 상세 조회 |
|
|
1854
1920
|
| `update(uid: string, data: any)` | 채널 정보 수정 |
|
|
1855
1921
|
| `checkHierarchy(params: CheckHierarchyQuery)` | 하이어라키 규칙 체크 |
|
|
1922
|
+
| `getManageContentCounts(uid: string, params?: ChannelContentCountsQuery)` | 채널 관리자용 콘텐츠 요약 조회 → `ChannelContentCountsResponse` (`includeDeleted`는 `true`만 허용) |
|
|
1923
|
+
| `getContentSummary(uid: string)` | 채널 공개 콘텐츠 요약 조회 → `ChannelPublicContentSummaryResponse` |
|
|
1856
1924
|
|
|
1857
1925
|
### `TermsModule` (`client.terms`)
|
|
1858
1926
|
|
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
|
@@ -60,24 +60,24 @@ export declare const useUser: () => {
|
|
|
60
60
|
/**
|
|
61
61
|
* Hook to fetch a user's public profile.
|
|
62
62
|
*/
|
|
63
|
-
export declare const useUserProfile: (uid: string) => import("@tanstack/react-query").UseQueryResult<{
|
|
63
|
+
export declare const useUserProfile: (uid: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
64
64
|
uid: string;
|
|
65
65
|
username: string | null;
|
|
66
66
|
display_name: string;
|
|
67
67
|
avatar_url: string | null;
|
|
68
68
|
follower_count: number;
|
|
69
69
|
profile_data: Record<string, any>;
|
|
70
|
-
}
|
|
70
|
+
}>, Error>;
|
|
71
71
|
/**
|
|
72
72
|
* Hook to fetch follow status for a target user.
|
|
73
73
|
*/
|
|
74
|
-
export declare const useFollowStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
74
|
+
export declare const useFollowStatus: (uid: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
75
75
|
is_following: boolean;
|
|
76
|
-
}
|
|
76
|
+
}>, Error>;
|
|
77
77
|
/**
|
|
78
78
|
* Hook to fetch followers of a target user.
|
|
79
79
|
*/
|
|
80
|
-
export declare const useFollowers: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
80
|
+
export declare const useFollowers: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
81
81
|
items: {
|
|
82
82
|
uid: string;
|
|
83
83
|
username: string | null;
|
|
@@ -90,11 +90,11 @@ export declare const useFollowers: (uid: string, params?: Partial<ListUserFollow
|
|
|
90
90
|
page: number;
|
|
91
91
|
limit: number;
|
|
92
92
|
totalPages: number;
|
|
93
|
-
}
|
|
93
|
+
}>, Error>;
|
|
94
94
|
/**
|
|
95
95
|
* Hook to fetch followings of a target user.
|
|
96
96
|
*/
|
|
97
|
-
export declare const useFollowings: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<{
|
|
97
|
+
export declare const useFollowings: (uid: string, params?: Partial<ListUserFollowQuery>, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
98
98
|
items: {
|
|
99
99
|
uid: string;
|
|
100
100
|
username: string | null;
|
|
@@ -107,7 +107,7 @@ export declare const useFollowings: (uid: string, params?: Partial<ListUserFollo
|
|
|
107
107
|
page: number;
|
|
108
108
|
limit: number;
|
|
109
109
|
totalPages: number;
|
|
110
|
-
}
|
|
110
|
+
}>, Error>;
|
|
111
111
|
/**
|
|
112
112
|
* Hook to update a user's profile.
|
|
113
113
|
* Typically used by a user to update their own profile.
|
|
@@ -167,7 +167,7 @@ export declare const useUnfollowUser: () => import("@tanstack/react-query").UseM
|
|
|
167
167
|
/**
|
|
168
168
|
* Hook to fetch contents liked by a specific user.
|
|
169
169
|
*/
|
|
170
|
-
export declare const useLikedContents: (uid: string, params?: Partial<ListLikedContentQuery>) => import("@tanstack/react-query").UseQueryResult<{
|
|
170
|
+
export declare const useLikedContents: (uid: string, params?: Partial<ListLikedContentQuery>) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
171
171
|
number: number;
|
|
172
172
|
totalPages: number;
|
|
173
173
|
content: import("@ph-cms/api-contract").ContentDto[];
|
|
@@ -176,18 +176,18 @@ export declare const useLikedContents: (uid: string, params?: Partial<ListLikedC
|
|
|
176
176
|
first: boolean;
|
|
177
177
|
last: boolean;
|
|
178
178
|
empty: boolean;
|
|
179
|
-
}
|
|
179
|
+
}>, Error>;
|
|
180
180
|
/**
|
|
181
181
|
* Hook to fetch statistics of liked contents by type for a specific user.
|
|
182
182
|
*/
|
|
183
|
-
export declare const useLikedStats: (uid: string) => import("@tanstack/react-query").UseQueryResult<{
|
|
183
|
+
export declare const useLikedStats: (uid: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
184
184
|
type: string;
|
|
185
185
|
count: number;
|
|
186
|
-
}[]
|
|
186
|
+
}[]>, Error>;
|
|
187
187
|
/**
|
|
188
188
|
* List terms required/available for the current channel.
|
|
189
189
|
*/
|
|
190
|
-
export declare const useChannelTerms: () => import("@tanstack/react-query").UseQueryResult<{
|
|
190
|
+
export declare const useChannelTerms: () => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
191
191
|
code: string;
|
|
192
192
|
type: "text" | "url";
|
|
193
193
|
id: number;
|
|
@@ -197,7 +197,7 @@ export declare const useChannelTerms: () => import("@tanstack/react-query").UseQ
|
|
|
197
197
|
isActive: boolean;
|
|
198
198
|
createdAt: string;
|
|
199
199
|
isRequired?: boolean | undefined;
|
|
200
|
-
}[]
|
|
200
|
+
}[]>, Error>;
|
|
201
201
|
/**
|
|
202
202
|
* Submit term agreements for the current user.
|
|
203
203
|
*/
|
|
@@ -228,7 +228,7 @@ export declare const useUnblockUser: () => import("@tanstack/react-query").UseMu
|
|
|
228
228
|
export declare const useBlockedUsers: (uid: string, params?: {
|
|
229
229
|
page?: number;
|
|
230
230
|
limit?: number;
|
|
231
|
-
}) => import("@tanstack/react-query").UseQueryResult<{
|
|
231
|
+
}) => import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
232
232
|
items: {
|
|
233
233
|
uid: string;
|
|
234
234
|
username: string | null;
|
|
@@ -241,7 +241,7 @@ export declare const useBlockedUsers: (uid: string, params?: {
|
|
|
241
241
|
page: number;
|
|
242
242
|
limit: number;
|
|
243
243
|
totalPages: number;
|
|
244
|
-
}
|
|
244
|
+
}>, Error>;
|
|
245
245
|
/**
|
|
246
246
|
* Hook to suspend a user (Global Ban).
|
|
247
247
|
* Admin only.
|
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 없이 이메일/비밀번호를 전송하고,
|
package/dist/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type { UserDto, UserProfileDto, FollowStatusResponse, FollowUserResponse,
|
|
|
9
9
|
export type { ChannelContentCountDto, ChannelContentCountsQuery, ChannelContentCountsResponse, ChannelDto, ChannelPublicContentSummaryResponse, 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';
|
|
12
|
-
export type { PermissionPolicySetDto } from '@ph-cms/api-contract';
|
|
12
|
+
export type { ChannelContentRolePolicy, PermissionAction, PermissionPolicyDocument, PermissionPolicySetDto, PermissionRule, } from '@ph-cms/api-contract';
|
|
13
13
|
export type { TermDto } from '@ph-cms/api-contract';
|
|
14
14
|
export type { GeoJSON } from '@ph-cms/api-contract';
|
|
15
15
|
export type { MediaUploadTicketBatchRequest, MediaUploadTicketBatchResponse, MediaUploadTicketRequest, MediaUploadTicketResponse } 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.50",
|
|
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.28",
|
|
34
34
|
"@tanstack/react-query": "^5.0.0",
|
|
35
35
|
"axios": "^1.6.0",
|
|
36
36
|
"zod": "^3.22.4"
|