@heripo/research-radar 1.1.0 → 1.2.1
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/NOTICE +1 -1
- package/README.md +27 -12
- package/dist/index.cjs +160 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +160 -3
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
package/NOTICE
CHANGED
|
@@ -48,7 +48,7 @@ Example implementations are welcome to use this code, but should establish
|
|
|
48
48
|
their own brand identity.
|
|
49
49
|
|
|
50
50
|
For permission to use the "heripo" trademark, contact the project maintainer
|
|
51
|
-
via GitHub: https://github.com/
|
|
51
|
+
via GitHub: https://github.com/heripo-lab/heripo-research-radar/issues
|
|
52
52
|
|
|
53
53
|
===============================================================================
|
|
54
54
|
|
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# heripo Research Radar
|
|
2
2
|
|
|
3
3
|
English | [한국어](./README-ko.md)
|
|
4
4
|
|
|
5
|
-
[](https://github.com/heripo-lab/heripo-research-radar/actions/workflows/ci.yml)
|
|
6
6
|
[
|
|
7
7
|

|
|
8
8
|
](https://www.npmjs.com/package/@heripo/research-radar)
|
|
9
|
-

|
|
10
10
|

|
|
11
11
|
|
|
12
12
|
[Code of Conduct](./CODE_OF_CONDUCT.md) • [Security Policy](./SECURITY.md) • [Contributing](./CONTRIBUTING.md)
|
|
13
13
|
|
|
14
14
|
## What is this?
|
|
15
15
|
|
|
16
|
-
An AI-powered newsletter service for Korean cultural heritage. Built on [`@llm-newsletter-kit/core`](https://github.com/
|
|
16
|
+
An AI-powered newsletter service for Korean cultural heritage. Built on [`@llm-newsletter-kit/core`](https://github.com/heripo-lab/llm-newsletter-kit-core), it's both a production service ([live at heripo.com](https://heripo.com/research-radar/subscribe)) and a reference implementation showing how to build automated newsletters with LLMs.
|
|
17
17
|
|
|
18
18
|
**Production metrics**:
|
|
19
19
|
- **Cost**: $0.2-1 USD per issue
|
|
@@ -23,11 +23,11 @@ An AI-powered newsletter service for Korean cultural heritage. Built on [`@llm-n
|
|
|
23
23
|
**Technical highlights**:
|
|
24
24
|
- Type-safe TypeScript with strict interfaces
|
|
25
25
|
- Provider pattern for swapping components (Crawling/Analysis/Content/Email)
|
|
26
|
-
-
|
|
26
|
+
- 66 crawling targets across heritage agencies, museums, academic societies
|
|
27
27
|
- LLM-driven analysis (GPT-5 models)
|
|
28
28
|
- Built-in retries, chain options, preview emails
|
|
29
29
|
|
|
30
|
-
**Links**: [Live service](https://heripo.com/research-radar/subscribe) • [Newsletter example](https://heripo.com/research-radar-newsletter-example.html) • [Core engine](https://github.com/
|
|
30
|
+
**Links**: [Live service](https://heripo.com/research-radar/subscribe) • [Newsletter example](https://heripo.com/research-radar-newsletter-example.html) • [Core engine](https://github.com/heripo-lab/llm-newsletter-kit-core)
|
|
31
31
|
|
|
32
32
|
## Background
|
|
33
33
|
|
|
@@ -54,11 +54,11 @@ We recommend adding this notice to your newsletter template footer or service do
|
|
|
54
54
|
For academic publications:
|
|
55
55
|
|
|
56
56
|
```bibtex
|
|
57
|
-
@software{
|
|
57
|
+
@software{heripo research radar,
|
|
58
58
|
author = {Kim, Hongyeon},
|
|
59
|
-
title = {
|
|
59
|
+
title = {heripo research radar},
|
|
60
60
|
year = {2025},
|
|
61
|
-
url = {https://github.com/
|
|
61
|
+
url = {https://github.com/heripo-lab/heripo-research-radar},
|
|
62
62
|
note = {Apache License 2.0}
|
|
63
63
|
}
|
|
64
64
|
```
|
|
@@ -125,13 +125,13 @@ const newsletterId = await generateNewsletter({
|
|
|
125
125
|
3. **Generation**: Create newsletter from top-scoring articles
|
|
126
126
|
4. **Save**: Store and optionally send preview email
|
|
127
127
|
|
|
128
|
-
Uses the **Provider-Service pattern** from `@llm-newsletter-kit/core`. See [core docs](https://github.com/
|
|
128
|
+
Uses the **Provider-Service pattern** from `@llm-newsletter-kit/core`. See [core docs](https://github.com/heripo-lab/llm-newsletter-kit-core#architecture--flow) for flow diagrams.
|
|
129
129
|
|
|
130
130
|
## Components
|
|
131
131
|
|
|
132
132
|
**Config** (`src/config/`): Brand, language, LLM settings
|
|
133
133
|
|
|
134
|
-
**Targets** (`src/config/crawling-targets.ts`):
|
|
134
|
+
**Targets** (`src/config/crawling-targets.ts`): 66 sources (News 52, Business 4, Employment 10)
|
|
135
135
|
|
|
136
136
|
**Parsers** (`src/parsers/`): Custom extractors per organization
|
|
137
137
|
|
|
@@ -152,6 +152,21 @@ npm run typecheck # TypeScript type-check
|
|
|
152
152
|
npm run format # Prettier formatting
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
+
### Crawler Debugger
|
|
156
|
+
|
|
157
|
+
A web-based tool for testing crawling parsers during development. Built with Express.js and vanilla HTML/CSS/JS to minimize dependencies.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm run dev:crawler # Start at http://localhost:3333
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Features**:
|
|
164
|
+
- Test `parseList()` and `parseDetail()` parsers via web UI
|
|
165
|
+
- View raw HTML source for debugging
|
|
166
|
+
- Copy parsed results as JSON
|
|
167
|
+
- 5-minute response cache (with skip/clear options)
|
|
168
|
+
- Timing info for fetch and parse operations
|
|
169
|
+
|
|
155
170
|
## 🤝 Contributing
|
|
156
171
|
|
|
157
172
|
You can use this project in two ways:
|
|
@@ -212,5 +227,5 @@ Code-based automation delivers **superior output quality** through advanced AI t
|
|
|
212
227
|
|
|
213
228
|
## Related Projects
|
|
214
229
|
|
|
215
|
-
- [`@llm-newsletter-kit/core`](https://github.com/
|
|
230
|
+
- [`@llm-newsletter-kit/core`](https://github.com/heripo-lab/llm-newsletter-kit-core) — Domain-agnostic newsletter engine
|
|
216
231
|
- [Archaeological Informatization Using LLMs](https://poc.heripo.com) — Academic research (Korean)
|
package/dist/index.cjs
CHANGED
|
@@ -970,6 +970,135 @@ function getUniqIdFromNrichMajorEvent(element) {
|
|
|
970
970
|
return ((element.attr('onclick') ?? '').match(/fnViewPage\('(.*)'\)/)?.[1] ?? '');
|
|
971
971
|
}
|
|
972
972
|
|
|
973
|
+
const LIST_API_URL = 'http://www.yngogo.or.kr/module/ntt/unity/selectNttListAjax.ink';
|
|
974
|
+
const DETAIL_API_URL = 'http://www.yngogo.or.kr/module/ntt/unity/selectNttDetailAjax.ink';
|
|
975
|
+
const BASE_URL = 'http://www.yngogo.or.kr';
|
|
976
|
+
// User-Agent list used by real browsers
|
|
977
|
+
const USER_AGENTS = [
|
|
978
|
+
// Windows - Chrome, Edge, Firefox
|
|
979
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
|
|
980
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
|
|
981
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0',
|
|
982
|
+
// macOS - Chrome, Safari, Firefox
|
|
983
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
|
|
984
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15',
|
|
985
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0',
|
|
986
|
+
// Linux - Chrome, Firefox
|
|
987
|
+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
|
|
988
|
+
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0',
|
|
989
|
+
// Additional common combinations
|
|
990
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
|
991
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
|
|
992
|
+
];
|
|
993
|
+
// Pick a random User-Agent
|
|
994
|
+
const getRandomUserAgent = () => USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
|
|
995
|
+
/**
|
|
996
|
+
* Parse list page from 영남고고학회 (Yeongnam Archaeological Society)
|
|
997
|
+
* Uses internal API since the table is rendered via CSR
|
|
998
|
+
* @see https://www.yngogo.or.kr
|
|
999
|
+
*/
|
|
1000
|
+
const parseYngogoList = async (_html, menuSeq, bbsSeq, sitecntntsSeq) => {
|
|
1001
|
+
// Fetch from internal API (CSR workaround)
|
|
1002
|
+
const response = await fetch(LIST_API_URL, {
|
|
1003
|
+
method: 'POST',
|
|
1004
|
+
headers: {
|
|
1005
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
1006
|
+
'User-Agent': getRandomUserAgent(),
|
|
1007
|
+
},
|
|
1008
|
+
body: new URLSearchParams({
|
|
1009
|
+
siteSeq: '32000001030',
|
|
1010
|
+
bbsSeq,
|
|
1011
|
+
pageIndex: '1',
|
|
1012
|
+
menuSeq,
|
|
1013
|
+
pageMode: 'B',
|
|
1014
|
+
sitecntntsSeq,
|
|
1015
|
+
tabTyCode: 'dataManage',
|
|
1016
|
+
mngrAt: 'N',
|
|
1017
|
+
searchCondition: '',
|
|
1018
|
+
searchKeyword: '',
|
|
1019
|
+
nttSeq: '',
|
|
1020
|
+
}),
|
|
1021
|
+
});
|
|
1022
|
+
const html = await response.text();
|
|
1023
|
+
const $ = cheerio__namespace.load(html);
|
|
1024
|
+
const posts = [];
|
|
1025
|
+
$('.basic-table01 tr').each((_index, element) => {
|
|
1026
|
+
const columns = $(element).find('td');
|
|
1027
|
+
if (columns.length === 0) {
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
const titleElement = columns.eq(1).find('a');
|
|
1031
|
+
const uniqId = getUniqId(titleElement);
|
|
1032
|
+
const detailUrl = `${BASE_URL}/subList/${menuSeq}?pmode=detail&nttSeq=${uniqId}&bbsSeq=${bbsSeq}&sitecntntsSeq=${sitecntntsSeq}`;
|
|
1033
|
+
const title = titleElement.text()?.trim() ?? '';
|
|
1034
|
+
const date = getDate(columns.eq(3).text().trim());
|
|
1035
|
+
posts.push({
|
|
1036
|
+
uniqId,
|
|
1037
|
+
title,
|
|
1038
|
+
date,
|
|
1039
|
+
detailUrl: cleanUrl(detailUrl),
|
|
1040
|
+
dateType: core.DateType.REGISTERED,
|
|
1041
|
+
});
|
|
1042
|
+
});
|
|
1043
|
+
return posts;
|
|
1044
|
+
};
|
|
1045
|
+
/**
|
|
1046
|
+
* Parse detail page from 영남고고학회 (Yeongnam Archaeological Society)
|
|
1047
|
+
* Uses internal API since the detail page is rendered via CSR
|
|
1048
|
+
*/
|
|
1049
|
+
const parseYngogoDetail = async (_html, menuSeq, bbsSeq, nttSeq, sitecntntsSeq) => {
|
|
1050
|
+
// Fetch from internal API (CSR workaround)
|
|
1051
|
+
const response = await fetch(DETAIL_API_URL, {
|
|
1052
|
+
method: 'POST',
|
|
1053
|
+
headers: {
|
|
1054
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
1055
|
+
'User-Agent': getRandomUserAgent(),
|
|
1056
|
+
},
|
|
1057
|
+
body: new URLSearchParams({
|
|
1058
|
+
siteSeq: '32000001030',
|
|
1059
|
+
bbsSeq,
|
|
1060
|
+
nttSeq,
|
|
1061
|
+
pageIndex: '1',
|
|
1062
|
+
ordrSe: 'D',
|
|
1063
|
+
searchCnd: 'frstRegistPnttm',
|
|
1064
|
+
checkNttSeq: '',
|
|
1065
|
+
menuSeq,
|
|
1066
|
+
mngrAt: 'N',
|
|
1067
|
+
parntsNttSeq: '',
|
|
1068
|
+
secretAt: '',
|
|
1069
|
+
searchAt: '',
|
|
1070
|
+
sitecntntsSeq,
|
|
1071
|
+
cmntUseAt: 'N',
|
|
1072
|
+
atchFilePosblAt: 'Y',
|
|
1073
|
+
atchFilePosblCo: '3',
|
|
1074
|
+
listCount: '10',
|
|
1075
|
+
searchCondition: '1',
|
|
1076
|
+
searchKeyword: '',
|
|
1077
|
+
}),
|
|
1078
|
+
});
|
|
1079
|
+
const html = await response.text();
|
|
1080
|
+
const $ = cheerio__namespace.load(html);
|
|
1081
|
+
const content = $('.conM_txt');
|
|
1082
|
+
return {
|
|
1083
|
+
detailContent: new TurndownService().turndown(content.html() ?? ''),
|
|
1084
|
+
hasAttachedFile: $('#atchFile_div').length > 0,
|
|
1085
|
+
hasAttachedImage: content.find('img').length > 0,
|
|
1086
|
+
};
|
|
1087
|
+
};
|
|
1088
|
+
function getUniqId(element) {
|
|
1089
|
+
// fnView('1005200642', 'admin', '', '',''); - extract first param
|
|
1090
|
+
return (element.attr('onclick') ?? '').match(/fnView\('([^']*)'/)?.[1] ?? '';
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Extract nttSeq from CSR page HTML
|
|
1094
|
+
* The URL query parameter is embedded in the page script
|
|
1095
|
+
*/
|
|
1096
|
+
function extractNttSeq(html) {
|
|
1097
|
+
// Pattern: nttSeq=1005200644 or nttSeq='1005200644'
|
|
1098
|
+
const match = html.match(/nttSeq[=:]['"]?(\d+)/);
|
|
1099
|
+
return match?.[1] ?? '';
|
|
1100
|
+
}
|
|
1101
|
+
|
|
973
1102
|
const crawlingTargetGroups = [
|
|
974
1103
|
{
|
|
975
1104
|
id: 'news',
|
|
@@ -1200,6 +1329,27 @@ const crawlingTargetGroups = [
|
|
|
1200
1329
|
parseList: parseHsasList,
|
|
1201
1330
|
parseDetail: parseHsasDetail,
|
|
1202
1331
|
},
|
|
1332
|
+
{
|
|
1333
|
+
id: '영남고고학회_공지사항',
|
|
1334
|
+
name: '영남고고학회 공지사항',
|
|
1335
|
+
url: 'http://www.yngogo.or.kr/subList/32000001120',
|
|
1336
|
+
parseList: (html) => parseYngogoList(html, '32000001120', '32000001157', '32000001711'),
|
|
1337
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001120', '32000001157', extractNttSeq(html), '32000001711'),
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
id: '영남고고학회_학계소식',
|
|
1341
|
+
name: '영남고고학회 학계소식',
|
|
1342
|
+
url: 'http://www.yngogo.or.kr/subList/32000001133',
|
|
1343
|
+
parseList: (html) => parseYngogoList(html, '32000001133', '32000001161', '32000001715'),
|
|
1344
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001133', '32000001161', extractNttSeq(html), '32000001715'),
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
id: '영남고고학회_현장소식',
|
|
1348
|
+
name: '영남고고학회 현장소식',
|
|
1349
|
+
url: 'http://www.yngogo.or.kr/subList/32000001135',
|
|
1350
|
+
parseList: (html) => parseYngogoList(html, '32000001135', '32000001163', '32000001717'),
|
|
1351
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001135', '32000001163', extractNttSeq(html), '32000001717'),
|
|
1352
|
+
},
|
|
1203
1353
|
{
|
|
1204
1354
|
id: '국립중앙박물관_알림',
|
|
1205
1355
|
name: '국립중앙박물관 알림',
|
|
@@ -1385,6 +1535,13 @@ const crawlingTargetGroups = [
|
|
|
1385
1535
|
parseList: parseKaahList,
|
|
1386
1536
|
parseDetail: parseKaahDetail,
|
|
1387
1537
|
},
|
|
1538
|
+
{
|
|
1539
|
+
id: '영남고고학회_채용공고',
|
|
1540
|
+
name: '영남고고학회 채용공고',
|
|
1541
|
+
url: 'http://www.yngogo.or.kr/subList/32000001136',
|
|
1542
|
+
parseList: (html) => parseYngogoList(html, '32000001136', '32000001164', '32000001718'),
|
|
1543
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001136', '32000001164', extractNttSeq(html), '32000001718'),
|
|
1544
|
+
},
|
|
1388
1545
|
{
|
|
1389
1546
|
id: '국립중앙박물관_채용안내',
|
|
1390
1547
|
name: '국립중앙박물관 채용 안내',
|
|
@@ -2027,7 +2184,7 @@ const createNewsletterHtmlTemplate = (targets) => `<!DOCTYPE html>
|
|
|
2027
2184
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">이 뉴스레터는 heripo의 선공개 버전으로 플랫폼의 일부 기능 중 하나입니다.</p>
|
|
2028
2185
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">2026년 중 플랫폼 출시를 목표로 개발 중이며, 핵심 로직 또한 오픈소스 프로젝트로 공개할 예정입니다.</p>
|
|
2029
2186
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">플랫폼 프로토타입 출시 시 구독자분들께 우선 안내해 드리겠습니다.</p>
|
|
2030
|
-
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">뉴스레터 소스 추가를 원하시거나 기타 궁금한 점이 있다면 <a href="https://github.com/
|
|
2187
|
+
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">뉴스레터 소스 추가를 원하시거나 기타 궁금한 점이 있다면 <a href="https://github.com/heripo-lab/heripo-research-radar/issues" target="_blank">GitHub 이슈</a>를 통해 요청해 주세요.</p>
|
|
2031
2188
|
<hr style="border: 0; border-top: 2px solid #D2691E; margin: 32px 0;">
|
|
2032
2189
|
<h2 style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px; font-weight: bold; line-height: 1.3; color: #D2691E; margin: 0 0 16px 0; letter-spacing: -0.2px; border-left: 5px solid #D2691E; padding-left: 12px; background: none;">⚠️ 중요 안내</h2>
|
|
2033
2190
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">본 뉴스레터는 국가유산청 공지사항, 관련 기관 입찰 정보 등 특정 웹 게시판의 모든 신규 소식을 빠짐없이 수집하여 제공합니다. 수집된 모든 정보는 정확한 크롤링 로직에 기반하므로 원본과 일치하여 신뢰할 수 있습니다.</p>
|
|
@@ -2041,8 +2198,8 @@ const createNewsletterHtmlTemplate = (targets) => `<!DOCTYPE html>
|
|
|
2041
2198
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 10px 0;" class="footer-text">이 메일은 heripo.com에서 리서치 레이더를 구독하신 분들에게 발송됩니다.<br>
|
|
2042
2199
|
더 이상 이메일을 받고 싶지 않으시면 <a href="{{{RESEND_UNSUBSCRIBE_URL}}}" target="_blank" style="-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; font-weight: bold; transition: color 0.2s; color: #888888; text-decoration: underline;" class="footer-link">여기에서 수신 거부</a>하세요.</p>
|
|
2043
2200
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.5; color: #999999; margin: 0;" class="footer-text">
|
|
2044
|
-
Powered by <a href="https://github.com/
|
|
2045
|
-
<a href="https://github.com/
|
|
2201
|
+
Powered by <a href="https://github.com/heripo-lab/llm-newsletter-kit-core" target="_blank" style="-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; transition: color 0.2s; color: #999999; text-decoration: underline;" class="footer-link">LLM Newsletter Kit</a> ·
|
|
2202
|
+
<a href="https://github.com/heripo-lab/heripo-research-radar" target="_blank" style="-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; transition: color 0.2s; color: #999999; text-decoration: underline;" class="footer-link">View Source</a>
|
|
2046
2203
|
</p>
|
|
2047
2204
|
</td>
|
|
2048
2205
|
</tr>
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.js
CHANGED
|
@@ -949,6 +949,135 @@ function getUniqIdFromNrichMajorEvent(element) {
|
|
|
949
949
|
return ((element.attr('onclick') ?? '').match(/fnViewPage\('(.*)'\)/)?.[1] ?? '');
|
|
950
950
|
}
|
|
951
951
|
|
|
952
|
+
const LIST_API_URL = 'http://www.yngogo.or.kr/module/ntt/unity/selectNttListAjax.ink';
|
|
953
|
+
const DETAIL_API_URL = 'http://www.yngogo.or.kr/module/ntt/unity/selectNttDetailAjax.ink';
|
|
954
|
+
const BASE_URL = 'http://www.yngogo.or.kr';
|
|
955
|
+
// User-Agent list used by real browsers
|
|
956
|
+
const USER_AGENTS = [
|
|
957
|
+
// Windows - Chrome, Edge, Firefox
|
|
958
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
|
|
959
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
|
|
960
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0',
|
|
961
|
+
// macOS - Chrome, Safari, Firefox
|
|
962
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
|
|
963
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15',
|
|
964
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0',
|
|
965
|
+
// Linux - Chrome, Firefox
|
|
966
|
+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
|
|
967
|
+
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0',
|
|
968
|
+
// Additional common combinations
|
|
969
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
|
970
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
|
|
971
|
+
];
|
|
972
|
+
// Pick a random User-Agent
|
|
973
|
+
const getRandomUserAgent = () => USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
|
|
974
|
+
/**
|
|
975
|
+
* Parse list page from 영남고고학회 (Yeongnam Archaeological Society)
|
|
976
|
+
* Uses internal API since the table is rendered via CSR
|
|
977
|
+
* @see https://www.yngogo.or.kr
|
|
978
|
+
*/
|
|
979
|
+
const parseYngogoList = async (_html, menuSeq, bbsSeq, sitecntntsSeq) => {
|
|
980
|
+
// Fetch from internal API (CSR workaround)
|
|
981
|
+
const response = await fetch(LIST_API_URL, {
|
|
982
|
+
method: 'POST',
|
|
983
|
+
headers: {
|
|
984
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
985
|
+
'User-Agent': getRandomUserAgent(),
|
|
986
|
+
},
|
|
987
|
+
body: new URLSearchParams({
|
|
988
|
+
siteSeq: '32000001030',
|
|
989
|
+
bbsSeq,
|
|
990
|
+
pageIndex: '1',
|
|
991
|
+
menuSeq,
|
|
992
|
+
pageMode: 'B',
|
|
993
|
+
sitecntntsSeq,
|
|
994
|
+
tabTyCode: 'dataManage',
|
|
995
|
+
mngrAt: 'N',
|
|
996
|
+
searchCondition: '',
|
|
997
|
+
searchKeyword: '',
|
|
998
|
+
nttSeq: '',
|
|
999
|
+
}),
|
|
1000
|
+
});
|
|
1001
|
+
const html = await response.text();
|
|
1002
|
+
const $ = cheerio.load(html);
|
|
1003
|
+
const posts = [];
|
|
1004
|
+
$('.basic-table01 tr').each((_index, element) => {
|
|
1005
|
+
const columns = $(element).find('td');
|
|
1006
|
+
if (columns.length === 0) {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
const titleElement = columns.eq(1).find('a');
|
|
1010
|
+
const uniqId = getUniqId(titleElement);
|
|
1011
|
+
const detailUrl = `${BASE_URL}/subList/${menuSeq}?pmode=detail&nttSeq=${uniqId}&bbsSeq=${bbsSeq}&sitecntntsSeq=${sitecntntsSeq}`;
|
|
1012
|
+
const title = titleElement.text()?.trim() ?? '';
|
|
1013
|
+
const date = getDate(columns.eq(3).text().trim());
|
|
1014
|
+
posts.push({
|
|
1015
|
+
uniqId,
|
|
1016
|
+
title,
|
|
1017
|
+
date,
|
|
1018
|
+
detailUrl: cleanUrl(detailUrl),
|
|
1019
|
+
dateType: DateType.REGISTERED,
|
|
1020
|
+
});
|
|
1021
|
+
});
|
|
1022
|
+
return posts;
|
|
1023
|
+
};
|
|
1024
|
+
/**
|
|
1025
|
+
* Parse detail page from 영남고고학회 (Yeongnam Archaeological Society)
|
|
1026
|
+
* Uses internal API since the detail page is rendered via CSR
|
|
1027
|
+
*/
|
|
1028
|
+
const parseYngogoDetail = async (_html, menuSeq, bbsSeq, nttSeq, sitecntntsSeq) => {
|
|
1029
|
+
// Fetch from internal API (CSR workaround)
|
|
1030
|
+
const response = await fetch(DETAIL_API_URL, {
|
|
1031
|
+
method: 'POST',
|
|
1032
|
+
headers: {
|
|
1033
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
1034
|
+
'User-Agent': getRandomUserAgent(),
|
|
1035
|
+
},
|
|
1036
|
+
body: new URLSearchParams({
|
|
1037
|
+
siteSeq: '32000001030',
|
|
1038
|
+
bbsSeq,
|
|
1039
|
+
nttSeq,
|
|
1040
|
+
pageIndex: '1',
|
|
1041
|
+
ordrSe: 'D',
|
|
1042
|
+
searchCnd: 'frstRegistPnttm',
|
|
1043
|
+
checkNttSeq: '',
|
|
1044
|
+
menuSeq,
|
|
1045
|
+
mngrAt: 'N',
|
|
1046
|
+
parntsNttSeq: '',
|
|
1047
|
+
secretAt: '',
|
|
1048
|
+
searchAt: '',
|
|
1049
|
+
sitecntntsSeq,
|
|
1050
|
+
cmntUseAt: 'N',
|
|
1051
|
+
atchFilePosblAt: 'Y',
|
|
1052
|
+
atchFilePosblCo: '3',
|
|
1053
|
+
listCount: '10',
|
|
1054
|
+
searchCondition: '1',
|
|
1055
|
+
searchKeyword: '',
|
|
1056
|
+
}),
|
|
1057
|
+
});
|
|
1058
|
+
const html = await response.text();
|
|
1059
|
+
const $ = cheerio.load(html);
|
|
1060
|
+
const content = $('.conM_txt');
|
|
1061
|
+
return {
|
|
1062
|
+
detailContent: new TurndownService().turndown(content.html() ?? ''),
|
|
1063
|
+
hasAttachedFile: $('#atchFile_div').length > 0,
|
|
1064
|
+
hasAttachedImage: content.find('img').length > 0,
|
|
1065
|
+
};
|
|
1066
|
+
};
|
|
1067
|
+
function getUniqId(element) {
|
|
1068
|
+
// fnView('1005200642', 'admin', '', '',''); - extract first param
|
|
1069
|
+
return (element.attr('onclick') ?? '').match(/fnView\('([^']*)'/)?.[1] ?? '';
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Extract nttSeq from CSR page HTML
|
|
1073
|
+
* The URL query parameter is embedded in the page script
|
|
1074
|
+
*/
|
|
1075
|
+
function extractNttSeq(html) {
|
|
1076
|
+
// Pattern: nttSeq=1005200644 or nttSeq='1005200644'
|
|
1077
|
+
const match = html.match(/nttSeq[=:]['"]?(\d+)/);
|
|
1078
|
+
return match?.[1] ?? '';
|
|
1079
|
+
}
|
|
1080
|
+
|
|
952
1081
|
const crawlingTargetGroups = [
|
|
953
1082
|
{
|
|
954
1083
|
id: 'news',
|
|
@@ -1179,6 +1308,27 @@ const crawlingTargetGroups = [
|
|
|
1179
1308
|
parseList: parseHsasList,
|
|
1180
1309
|
parseDetail: parseHsasDetail,
|
|
1181
1310
|
},
|
|
1311
|
+
{
|
|
1312
|
+
id: '영남고고학회_공지사항',
|
|
1313
|
+
name: '영남고고학회 공지사항',
|
|
1314
|
+
url: 'http://www.yngogo.or.kr/subList/32000001120',
|
|
1315
|
+
parseList: (html) => parseYngogoList(html, '32000001120', '32000001157', '32000001711'),
|
|
1316
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001120', '32000001157', extractNttSeq(html), '32000001711'),
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
id: '영남고고학회_학계소식',
|
|
1320
|
+
name: '영남고고학회 학계소식',
|
|
1321
|
+
url: 'http://www.yngogo.or.kr/subList/32000001133',
|
|
1322
|
+
parseList: (html) => parseYngogoList(html, '32000001133', '32000001161', '32000001715'),
|
|
1323
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001133', '32000001161', extractNttSeq(html), '32000001715'),
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
id: '영남고고학회_현장소식',
|
|
1327
|
+
name: '영남고고학회 현장소식',
|
|
1328
|
+
url: 'http://www.yngogo.or.kr/subList/32000001135',
|
|
1329
|
+
parseList: (html) => parseYngogoList(html, '32000001135', '32000001163', '32000001717'),
|
|
1330
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001135', '32000001163', extractNttSeq(html), '32000001717'),
|
|
1331
|
+
},
|
|
1182
1332
|
{
|
|
1183
1333
|
id: '국립중앙박물관_알림',
|
|
1184
1334
|
name: '국립중앙박물관 알림',
|
|
@@ -1364,6 +1514,13 @@ const crawlingTargetGroups = [
|
|
|
1364
1514
|
parseList: parseKaahList,
|
|
1365
1515
|
parseDetail: parseKaahDetail,
|
|
1366
1516
|
},
|
|
1517
|
+
{
|
|
1518
|
+
id: '영남고고학회_채용공고',
|
|
1519
|
+
name: '영남고고학회 채용공고',
|
|
1520
|
+
url: 'http://www.yngogo.or.kr/subList/32000001136',
|
|
1521
|
+
parseList: (html) => parseYngogoList(html, '32000001136', '32000001164', '32000001718'),
|
|
1522
|
+
parseDetail: (html) => parseYngogoDetail(html, '32000001136', '32000001164', extractNttSeq(html), '32000001718'),
|
|
1523
|
+
},
|
|
1367
1524
|
{
|
|
1368
1525
|
id: '국립중앙박물관_채용안내',
|
|
1369
1526
|
name: '국립중앙박물관 채용 안내',
|
|
@@ -2006,7 +2163,7 @@ const createNewsletterHtmlTemplate = (targets) => `<!DOCTYPE html>
|
|
|
2006
2163
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">이 뉴스레터는 heripo의 선공개 버전으로 플랫폼의 일부 기능 중 하나입니다.</p>
|
|
2007
2164
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">2026년 중 플랫폼 출시를 목표로 개발 중이며, 핵심 로직 또한 오픈소스 프로젝트로 공개할 예정입니다.</p>
|
|
2008
2165
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">플랫폼 프로토타입 출시 시 구독자분들께 우선 안내해 드리겠습니다.</p>
|
|
2009
|
-
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">뉴스레터 소스 추가를 원하시거나 기타 궁금한 점이 있다면 <a href="https://github.com/
|
|
2166
|
+
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">뉴스레터 소스 추가를 원하시거나 기타 궁금한 점이 있다면 <a href="https://github.com/heripo-lab/heripo-research-radar/issues" target="_blank">GitHub 이슈</a>를 통해 요청해 주세요.</p>
|
|
2010
2167
|
<hr style="border: 0; border-top: 2px solid #D2691E; margin: 32px 0;">
|
|
2011
2168
|
<h2 style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px; font-weight: bold; line-height: 1.3; color: #D2691E; margin: 0 0 16px 0; letter-spacing: -0.2px; border-left: 5px solid #D2691E; padding-left: 12px; background: none;">⚠️ 중요 안내</h2>
|
|
2012
2169
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 18px 0;">본 뉴스레터는 국가유산청 공지사항, 관련 기관 입찰 정보 등 특정 웹 게시판의 모든 신규 소식을 빠짐없이 수집하여 제공합니다. 수집된 모든 정보는 정확한 크롤링 로직에 기반하므로 원본과 일치하여 신뢰할 수 있습니다.</p>
|
|
@@ -2020,8 +2177,8 @@ const createNewsletterHtmlTemplate = (targets) => `<!DOCTYPE html>
|
|
|
2020
2177
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.7; color: #444444; margin: 0 0 10px 0;" class="footer-text">이 메일은 heripo.com에서 리서치 레이더를 구독하신 분들에게 발송됩니다.<br>
|
|
2021
2178
|
더 이상 이메일을 받고 싶지 않으시면 <a href="{{{RESEND_UNSUBSCRIBE_URL}}}" target="_blank" style="-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; font-weight: bold; transition: color 0.2s; color: #888888; text-decoration: underline;" class="footer-link">여기에서 수신 거부</a>하세요.</p>
|
|
2022
2179
|
<p style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.5; color: #999999; margin: 0;" class="footer-text">
|
|
2023
|
-
Powered by <a href="https://github.com/
|
|
2024
|
-
<a href="https://github.com/
|
|
2180
|
+
Powered by <a href="https://github.com/heripo-lab/llm-newsletter-kit-core" target="_blank" style="-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; transition: color 0.2s; color: #999999; text-decoration: underline;" class="footer-link">LLM Newsletter Kit</a> ·
|
|
2181
|
+
<a href="https://github.com/heripo-lab/heripo-research-radar" target="_blank" style="-webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; transition: color 0.2s; color: #999999; text-decoration: underline;" class="footer-link">View Source</a>
|
|
2025
2182
|
</p>
|
|
2026
2183
|
</td>
|
|
2027
2184
|
</tr>
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@heripo/research-radar",
|
|
3
3
|
"private": false,
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "1.1
|
|
5
|
+
"version": "1.2.1",
|
|
6
6
|
"description": "AI-driven intelligence for Korean cultural heritage. This package serves as both a ready-to-use newsletter service and a practical implementation example for the LLM-Newsletter-Kit.",
|
|
7
7
|
"main": "dist/index.cjs",
|
|
8
8
|
"module": "dist/index.js",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"lint:fix": "eslint --fix ./src",
|
|
37
37
|
"lint:ci": "eslint --quiet ./src",
|
|
38
38
|
"typecheck": "tsc --noEmit",
|
|
39
|
-
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md,mdx}\""
|
|
39
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md,mdx}\"",
|
|
40
|
+
"dev:crawler": "tsx watch dev-tools/crawler-debugger/server.ts"
|
|
40
41
|
},
|
|
41
42
|
"author": "kimhongyeon",
|
|
42
43
|
"license": "Apache-2.0",
|
|
@@ -52,24 +53,27 @@
|
|
|
52
53
|
"@eslint/js": "^9.39.2",
|
|
53
54
|
"@llm-newsletter-kit/core": "^1.1.0",
|
|
54
55
|
"@trivago/prettier-plugin-sort-imports": "^6.0.1",
|
|
56
|
+
"@types/express": "^5.0.6",
|
|
55
57
|
"@types/node": "^25.0.3",
|
|
56
58
|
"@types/turndown": "^5.0.6",
|
|
57
59
|
"eslint": "^9.39.2",
|
|
58
60
|
"eslint-plugin-unused-imports": "^4.3.0",
|
|
61
|
+
"express": "^5.2.1",
|
|
59
62
|
"prettier": "^3.7.4",
|
|
60
63
|
"rimraf": "^6.1.2",
|
|
61
64
|
"rollup": "^4.55.1",
|
|
62
65
|
"rollup-plugin-dts": "^6.3.0",
|
|
63
66
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
67
|
+
"tsx": "^4.21.0",
|
|
64
68
|
"typescript": "^5.9.3",
|
|
65
69
|
"typescript-eslint": "^8.52.0"
|
|
66
70
|
},
|
|
67
71
|
"repository": {
|
|
68
72
|
"type": "git",
|
|
69
|
-
"url": "https://github.com/
|
|
73
|
+
"url": "https://github.com/heripo-lab/heripo-research-radar"
|
|
70
74
|
},
|
|
71
75
|
"bugs": {
|
|
72
|
-
"url": "https://github.com/
|
|
76
|
+
"url": "https://github.com/heripo-lab/heripo-research-radar/issues"
|
|
73
77
|
},
|
|
74
78
|
"homepage": "https://heripo.com",
|
|
75
79
|
"keywords": [
|