Public Source Viewer
비나래아카이브 개발자 포털
실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.
src/services/blog-tag.service.ts
공개 가능
1
import fs from 'fs';
2
import path from 'path';
3
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
4
import { Post } from '../types/models';
5
6
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
7
const defaultBlogTags = ['맛집', '여행'];
8
9
export const normalizeBlogTag = (value: unknown): string => {
10
return String(value || '')
11
.replace(/[#,\n\r\t]/g, ' ')
12
.replace(/\s+/g, ' ')
13
.trim()
14
.slice(0, 20);
15
};
16
17
export const normalizeBlogTags = (value: unknown): string[] => {
18
const tags = Array.isArray(value) ? value : typeof value === 'string' ? [value] : [];
19
return Array.from(new Set(tags.map(normalizeBlogTag).filter(Boolean))).slice(0, 8);
20
};
21
22
const sortTags = (tags: string[]): string[] => {
23
return Array.from(new Set(tags.map(normalizeBlogTag).filter(Boolean))).sort((a, b) => a.localeCompare(b, 'ko'));
24
};
25
26
export const readBlogTags = (): string[] => {
27
try {
28
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
29
return defaultBlogTags;
30
}
31
32
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
33
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
34
const savedTags = Array.isArray(parsed) ? parsed : parsed?.tags;
35
return sortTags(normalizeBlogTags(savedTags));
36
} catch {
37
return defaultBlogTags;
38
}
39
};
40
41
export const writeBlogTags = (tags: string[]): void => {
42
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
43
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
44
};
45
46
export const addBlogTag = (tag: unknown): string[] => {
47
const normalizedTag = normalizeBlogTag(tag);
48
const nextTags = sortTags([...readBlogTags(), normalizedTag]);
49
writeBlogTags(nextTags);
50
return nextTags;
51
};
52
53
export const deleteBlogTag = (tag: unknown): string[] => {
54
const normalizedTag = normalizeBlogTag(tag);
55
if (!normalizedTag) {
56
return readBlogTags();
57
}
58
59
const nextTags = readBlogTags().filter(savedTag => savedTag !== normalizedTag);
60
writeBlogTags(nextTags);
61
return nextTags;
62
};
63
64
export const removeBlogTagFromPosts = (tag: unknown): void => {
65
const normalizedTag = normalizeBlogTag(tag);
66
67
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
68
return;
69
}
70
71
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
72
73
files.forEach(file => {
74
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
75
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
76
let changed = false;
77
78
const nextPosts = posts.map(post => {
79
const tags = normalizeBlogTags(post.tags);
80
const nextTags = tags.filter(postTag => postTag !== normalizedTag);
81
82
if (nextTags.length !== tags.length) {
83
changed = true;
84
return { ...post, tags: nextTags };
85
}
86
87
return post;
88
});
89
90
if (changed) {
91
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
92
}
93
});
94
};
95
96
export const getAvailableBlogTags = (posts: Post[] = []): string[] => {
97
const postTags = posts.flatMap(post => normalizeBlogTags(post.tags));
98
return sortTags([...readBlogTags(), ...postTags]);
99
};
100