memi-board 0.11.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composables/useMemiBoardPosts.d.ts +18 -2
- package/dist/composables/useMemiBoardSettings.d.ts +5 -1
- package/dist/composables/useMemiBoardUsers.d.ts +9 -1
- package/dist/composables/useMemiBoardViews.d.ts +11 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +665 -539
- package/dist/index.js.map +1 -1
- package/dist/module.mjs +4 -0
- package/dist/module.mjs.map +1 -1
- package/dist/runtime/components/CategorySettings.vue +108 -12
- package/dist/runtime/components/CommentForm.vue +26 -5
- package/dist/runtime/components/CommentItem.vue +1 -0
- package/dist/runtime/components/CommentList.vue +2 -1
- package/dist/runtime/components/CommentThread.vue +2 -1
- package/dist/runtime/components/Detail.vue +25 -6
- package/dist/runtime/components/Editor.vue +36 -11
- package/dist/runtime/components/Footer.vue +1 -1
- package/dist/runtime/components/List.vue +85 -5
- package/dist/runtime/components/ListDefault.vue +81 -24
- package/dist/runtime/components/ListDense.vue +112 -0
- package/dist/runtime/components/ListImage.vue +35 -22
- package/dist/runtime/components/ListVideo.vue +31 -15
- package/dist/runtime/components/ListViewSwitch.vue +30 -0
- package/dist/runtime/components/OptionCards.vue +30 -0
- package/dist/runtime/components/Settings.vue +86 -11
- package/dist/runtime/components/Users.vue +1 -1
- package/dist/types.d.ts +28 -1
- package/dist/utils/postPreview.d.ts +8 -0
- package/docs/firestore.rules.example +85 -16
- package/package.json +1 -1
|
@@ -21,6 +21,19 @@ export interface UpdatePostInput {
|
|
|
21
21
|
category?: string;
|
|
22
22
|
attachments?: Attachment[];
|
|
23
23
|
}
|
|
24
|
+
/** getPostBySlug 결과 — not-found 와 permission-denied 를 UI 에서 구분한다. */
|
|
25
|
+
export type GetPostBySlugResult = {
|
|
26
|
+
status: 'ok';
|
|
27
|
+
post: PostDetail;
|
|
28
|
+
} | {
|
|
29
|
+
status: 'not-found';
|
|
30
|
+
} | {
|
|
31
|
+
status: 'permission-denied';
|
|
32
|
+
} | {
|
|
33
|
+
status: 'error';
|
|
34
|
+
message: string;
|
|
35
|
+
};
|
|
36
|
+
export declare function isFirestorePermissionDenied(error: unknown): boolean;
|
|
24
37
|
/** 목록 조회는 posts/{id} 메타만 읽고, 본문(body/main)은 상세 조회 시에만 읽는다. */
|
|
25
38
|
export declare function useMemiBoardPosts(): {
|
|
26
39
|
createPostId: () => string;
|
|
@@ -29,13 +42,15 @@ export declare function useMemiBoardPosts(): {
|
|
|
29
42
|
cursor?: QueryDocumentSnapshot<DocumentData>;
|
|
30
43
|
/** 지정 시 해당 카테고리 글만 (boardSettings 의 category id) */
|
|
31
44
|
category?: string;
|
|
45
|
+
/** true 면 listed==true 만 (비권한 목록). staff 전체 보기는 false */
|
|
46
|
+
publicOnly?: boolean;
|
|
32
47
|
}) => Promise<{
|
|
33
48
|
posts: PostModel[];
|
|
34
49
|
cursor: QueryDocumentSnapshot<DocumentData> | undefined;
|
|
35
50
|
hasMore: boolean;
|
|
36
51
|
}>;
|
|
37
52
|
getPost: (id: string) => Promise<PostDetail | null>;
|
|
38
|
-
getPostBySlug: (category: string, slug: string) => Promise<
|
|
53
|
+
getPostBySlug: (category: string, slug: string) => Promise<GetPostBySlugResult>;
|
|
39
54
|
getAdjacentPosts: (current: PostModel) => Promise<{
|
|
40
55
|
previous: PostModel | null;
|
|
41
56
|
next: PostModel | null;
|
|
@@ -54,7 +69,8 @@ export declare function useMemiBoardPosts(): {
|
|
|
54
69
|
* 이 정도 트래픽 폭이면 실사용에서 발생 가능성이 낮아 별도 보정 로직은 두지 않았다.
|
|
55
70
|
*/
|
|
56
71
|
export declare function useMemiBoardPostList(category?: string | Ref<string | undefined>, options?: {
|
|
57
|
-
pageSize?: number;
|
|
72
|
+
pageSize?: number; /** staff 등 숨김 글 포함 시 false. 기본 true */
|
|
73
|
+
publicOnly?: boolean | Ref<boolean>;
|
|
58
74
|
}): {
|
|
59
75
|
posts: import('vue').ComputedRef<PostModel[]>;
|
|
60
76
|
postsPending: Ref<boolean, boolean>;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { BoardCategory } from '../types';
|
|
1
|
+
import { BoardCategory, BoardVisibility } from '../types';
|
|
2
2
|
/** 필요할 때 호스트가 명시적으로 사용할 수 있는 예시 카테고리. 자동 적용하지 않는다. */
|
|
3
3
|
export declare const DEFAULT_CATEGORIES: BoardCategory[];
|
|
4
4
|
/** 게시판 카테고리 — `{prefix}Settings/config/categories/{categoryId}` 개별 문서. */
|
|
5
5
|
export declare function useMemiBoardSettings(): {
|
|
6
6
|
categories: import('vue').ComputedRef<BoardCategory[]>;
|
|
7
|
+
publicCategories: import('vue').ComputedRef<BoardCategory[]>;
|
|
7
8
|
categoryLabel: (id: string | undefined) => string | undefined;
|
|
9
|
+
categoryDescription: (id: string | undefined) => string | undefined;
|
|
10
|
+
categoryVisibility: (id: string | undefined) => BoardVisibility;
|
|
11
|
+
isCategoryHidden: (id: string | undefined) => boolean;
|
|
8
12
|
settingsPending: import('vue').Ref<boolean, boolean>;
|
|
9
13
|
ensureSettings: () => Promise<void>;
|
|
10
14
|
addCategory: (label: string) => Promise<string>;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
import { MaybeRefOrGetter } from 'vue';
|
|
1
2
|
import { BoardUserModel, BoardUserRole } from '../types';
|
|
2
3
|
export declare const BOARD_USER_ROLES: Array<{
|
|
3
4
|
value: BoardUserRole;
|
|
4
5
|
label: string;
|
|
5
6
|
description: string;
|
|
6
7
|
}>;
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* 전체 사용자 목록은 관리자만 읽을 수 있다(rules). enabled가 false인 동안은
|
|
10
|
+
* 쿼리 자체를 시작하지 않는다 — 그냥 호출만 하면 권한 확인 전에 구독이 걸려서
|
|
11
|
+
* 관리자가 아니거나 아직 role을 확인 중일 때 permission-denied로 화면이 죽는다.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useMemiBoardUsers(options?: {
|
|
14
|
+
enabled?: MaybeRefOrGetter<boolean>;
|
|
15
|
+
}): {
|
|
8
16
|
users: import('vuefire')._RefFirestore<import('vuefire').VueFirestoreQueryData<BoardUserModel>>;
|
|
9
17
|
usersPending: import('vue').Ref<boolean, boolean>;
|
|
10
18
|
updateUserRole: (uid: string, role: BoardUserRole) => Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 게시글 조회수.
|
|
3
|
+
*
|
|
4
|
+
* - 로그인 불필요: rules 가 viewCount +1 만 허용하면 익명도 증가 가능.
|
|
5
|
+
* - 신뢰 수준은 likeCount/commentCount 와 같은 클라이언트 편의 카운터.
|
|
6
|
+
* - 같은 브라우저·세션에서 같은 글을 반복 열어 폭증하지 않도록 sessionStorage 로 1회만 기록.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMemiBoardViews(): {
|
|
9
|
+
recordView: (postId: string) => Promise<void>;
|
|
10
|
+
hasRecordedView: (postId: string) => boolean;
|
|
11
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ export { configureMemiBoard, useMemiBoardConfig } from './config';
|
|
|
3
3
|
export type { MemiBoardConfig, MemiBoardAuthOptions, MemiBoardModerationOptions } from './config';
|
|
4
4
|
export { useMemiBoardAuth } from './composables/useMemiBoardAuth';
|
|
5
5
|
export { useMemiBoardPosts, useMemiBoardPostList, useMemiBoardPost } from './composables/useMemiBoardPosts';
|
|
6
|
-
export type { CreatePostInput, UpdatePostInput } from './composables/useMemiBoardPosts';
|
|
6
|
+
export type { CreatePostInput, UpdatePostInput, GetPostBySlugResult } from './composables/useMemiBoardPosts';
|
|
7
|
+
export { isFirestorePermissionDenied } from './composables/useMemiBoardPosts';
|
|
7
8
|
export { COMMENT_BODY_MAX_LENGTH, useMemiBoardComments, useMemiBoardReplies } from './composables/useMemiBoardComments';
|
|
8
9
|
export type { AddCommentInput, AddReplyInput } from './composables/useMemiBoardComments';
|
|
9
10
|
export { useMemiBoardLikes } from './composables/useMemiBoardLikes';
|
|
11
|
+
export { useMemiBoardViews } from './composables/useMemiBoardViews';
|
|
10
12
|
export { useMemiBoardModeration } from './composables/useMemiBoardModeration';
|
|
11
13
|
export { useMemiBoardStorage } from './composables/useMemiBoardStorage';
|
|
12
14
|
export { useMemiBoardSettings, DEFAULT_CATEGORIES } from './composables/useMemiBoardSettings';
|
|
@@ -16,9 +18,10 @@ export type { VersionHistoryEntry } from './data/versionHistory';
|
|
|
16
18
|
export { formatDate, formatFullDate, formatRelativeDate, formatTimestampDetails } from './utils/formatDate';
|
|
17
19
|
export { slugify } from './utils/slugify';
|
|
18
20
|
export { DEFAULT_BLOCK_BAN_THRESHOLD, DEFAULT_BLOCK_BAN_DECAY_MS, effectiveModerationBlockCount, isModerationWriteRestricted, moderationWriteRestrictedUntilMs, formatRestrictedUntilLabel, } from './utils/moderation-strike';
|
|
19
|
-
export type { Attachment, EditorImageEntry, ModerationStatus, PostModel, PostDetail, CommentModel, BoardUserRole, BoardUserModel, BoardCategory, BoardListView, BoardWriteRole, BoardSettingsModel, ModerationResult, } from './types';
|
|
21
|
+
export type { Attachment, EditorImageEntry, ModerationStatus, PostModel, PostDetail, CommentModel, BoardUserRole, BoardUserModel, BoardCategory, BoardListView, BoardWriteRole, BoardVisibility, BoardSettingsModel, ModerationResult, } from './types';
|
|
20
22
|
export { compressImage } from './utils/compressImage';
|
|
21
23
|
export { extractEditorImageUrls } from './utils/extractEditorImageUrls';
|
|
22
24
|
export { renderMarkdownToHtml } from './utils/renderMarkdown';
|
|
25
|
+
export { buildPostPreview, youtubeId, videoListCoverUrl } from './utils/postPreview';
|
|
23
26
|
export { storagePathFromDownloadUrl, postNamespaceFromStoragePath } from './utils/storagePath';
|
|
24
27
|
export { EDITOR_IMAGE_MAX_BYTES, EDITOR_IMAGE_SOURCE_MAX_BYTES } from './composables/useMemiBoardStorage';
|