@heripo/research-radar 5.0.2 → 5.0.3

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/index.js CHANGED
@@ -678,42 +678,126 @@ const parseKhsDetail = async (html) => {
678
678
  };
679
679
  };
680
680
 
681
+ /**
682
+ * 크롤링 타겟과 API 요청 어댑터가 이 값을 함께 사용한다.
683
+ */
684
+ const KRAS_SITE_BASE_URL = 'https://www.kras.or.kr';
685
+ const isRecord = (value) => typeof value === 'object' && value !== null;
686
+ const isKrasApiPost = (value) => isRecord(value) &&
687
+ (typeof value.id === 'string' || typeof value.id === 'number') &&
688
+ typeof value.board_slug === 'string';
689
+ const parseJson = (html) => {
690
+ try {
691
+ return JSON.parse(html);
692
+ }
693
+ catch {
694
+ return undefined;
695
+ }
696
+ };
697
+ const getKrasPostDate = (post) => getDate((post.publish_date ?? post.created_at ?? '').slice(0, 10));
698
+ const toKrasListItem = (post) => {
699
+ const detailUrl = new URL(`/sub/${encodeURIComponent(post.board_slug)}/detail?id=${encodeURIComponent(String(post.id))}`, KRAS_SITE_BASE_URL);
700
+ return {
701
+ uniqId: String(post.id),
702
+ title: post.title?.trim() ?? '',
703
+ date: getKrasPostDate(post),
704
+ detailUrl: cleanUrl(detailUrl.href),
705
+ dateType: DateType.REGISTERED,
706
+ };
707
+ };
708
+ const parseKrasApiList = (html) => {
709
+ const data = parseJson(html);
710
+ if (!isRecord(data) || !Array.isArray(data.items)) {
711
+ return undefined;
712
+ }
713
+ return data.items.filter(isKrasApiPost).map(toKrasListItem);
714
+ };
715
+ const parseKrasApiDetail = (html) => {
716
+ const data = parseJson(html);
717
+ if (!isRecord(data) || !isKrasApiPost(data.item)) {
718
+ return undefined;
719
+ }
720
+ const item = data.item;
721
+ const content = cheerio.load(item.body ?? '')('body');
722
+ content.find('div.snsbox').remove();
723
+ return {
724
+ detailContent: new TurndownService().turndown(content.html() ?? ''),
725
+ hasAttachedFile: (item.attachments?.length ?? 0) > 0,
726
+ hasAttachedImage: content.find('img').length > 0,
727
+ };
728
+ };
729
+ /**
730
+ * 새 사이트는 게시글 상세 내용을 API로 렌더링한다.
731
+ * 기사 출처에는 공개 상세 URL을 유지하고, 크롤러가 해당 URL을 요청하면
732
+ * 상세 API 응답을 가져오도록 처리한다.
733
+ */
734
+ const createKrasFetch = (baseFetch = fetch) => async (input, init) => {
735
+ const requestUrl = typeof input === 'string'
736
+ ? input
737
+ : input instanceof URL
738
+ ? input.href
739
+ : input.url;
740
+ const url = new URL(requestUrl, KRAS_SITE_BASE_URL);
741
+ const isKrasDetailUrl = url.origin === new URL(KRAS_SITE_BASE_URL).origin &&
742
+ /^\/sub\/[^/]+\/detail$/.test(url.pathname) &&
743
+ url.searchParams.has('id');
744
+ if (isKrasDetailUrl) {
745
+ const id = encodeURIComponent(url.searchParams.get('id') ?? '');
746
+ return baseFetch(`${KRAS_SITE_BASE_URL}/api/boards/detail/${id}`, init);
747
+ }
748
+ return baseFetch(input, init);
749
+ };
681
750
  const parseKrasList = (html) => {
682
751
  const $ = cheerio.load(html);
683
752
  const posts = [];
684
- const baseUrl = 'https://www.kras.or.kr';
685
- $('table tbody tr').each((index, element) => {
686
- const columns = $(element).find('td');
687
- if (columns.length === 0) {
688
- return;
689
- }
690
- const titleElement = columns.eq(1).find('a');
691
- const relativeHref = titleElement.attr('href');
753
+ const apiPosts = parseKrasApiList(html);
754
+ if (apiPosts) {
755
+ return apiPosts;
756
+ }
757
+ $('.post-item').each((index, element) => {
758
+ const title = $(element).find('.col-title').text().trim();
759
+ const date = $(element).find('.col-date').text().trim();
760
+ const onclick = $(element).attr('onclick') ?? '';
761
+ const relativeHref = onclick.match(/location\.href\s*=\s*["']([^"']+)["']/)?.[1];
692
762
  if (!relativeHref) {
693
763
  return;
694
764
  }
695
- const fullUrl = new URL(relativeHref, baseUrl);
696
- const detailUrl = fullUrl.href;
697
- const uniqId = fullUrl.searchParams.get('uid') ?? undefined;
698
- const title = titleElement.text()?.trim() ?? '';
699
- const date = getDate(columns.eq(4).text().trim());
765
+ const fullUrl = new URL(relativeHref, KRAS_SITE_BASE_URL);
700
766
  posts.push({
701
- uniqId,
767
+ uniqId: fullUrl.searchParams.get('id') ?? undefined,
702
768
  title,
703
- date,
704
- detailUrl: cleanUrl(detailUrl),
769
+ date: getDate(date),
770
+ detailUrl: cleanUrl(fullUrl.href),
705
771
  dateType: DateType.REGISTERED,
706
772
  });
707
773
  });
708
774
  return posts;
709
775
  };
776
+ /**
777
+ * KRAS API를 통해 목록이 클라이언트에서 렌더링되는 게시판을 파싱한다.
778
+ */
779
+ const parseKrasListFromApi = async (_html, boardSlug, customFetch) => {
780
+ const response = await (customFetch ?? fetch)(`${KRAS_SITE_BASE_URL}/api/boards?board=${encodeURIComponent(boardSlug)}&page=1&limit=50`, {
781
+ headers: {
782
+ Accept: 'application/json',
783
+ },
784
+ });
785
+ if (!response.ok) {
786
+ throw new Error(`KRAS list API returned HTTP ${response.status}`);
787
+ }
788
+ return parseKrasList(await response.text());
789
+ };
710
790
  const parseKrasDetail = (html) => {
791
+ const apiDetail = parseKrasApiDetail(html);
792
+ if (apiDetail) {
793
+ return apiDetail;
794
+ }
711
795
  const $ = cheerio.load(html);
712
- const content = $('#vContent');
796
+ const content = $('.detail-body').first();
713
797
  content.find('div.snsbox').remove();
714
798
  return {
715
799
  detailContent: new TurndownService().turndown(content.html() ?? ''),
716
- hasAttachedFile: $('div.attach ul li').length > 0,
800
+ hasAttachedFile: $('.detail-attachments .attachment-item').length > 0,
717
801
  hasAttachedImage: content.find('img').length > 0,
718
802
  };
719
803
  };
@@ -1406,29 +1490,29 @@ function createCrawlingTargetGroups(customFetch) {
1406
1490
  {
1407
1491
  id: '한국고고학회_공지사항',
1408
1492
  name: '한국고고학회 공지사항',
1409
- url: 'https://www.kras.or.kr/?r=kras&m=bbs&bid=notice',
1410
- parseList: parseKrasList,
1493
+ url: `${KRAS_SITE_BASE_URL}/sub/notice`,
1494
+ parseList: (html) => parseKrasListFromApi(html, 'notice', customFetch),
1411
1495
  parseDetail: parseKrasDetail,
1412
1496
  },
1413
1497
  {
1414
1498
  id: '한국고고학회_학술대회및행사',
1415
1499
  name: '한국고고학회 학술대회 및 행사',
1416
- url: 'https://www.kras.or.kr/?r=kras&m=bbs&bid=sympo',
1417
- parseList: parseKrasList,
1500
+ url: `${KRAS_SITE_BASE_URL}/sub/symposium`,
1501
+ parseList: (html) => parseKrasListFromApi(html, 'symposium', customFetch),
1418
1502
  parseDetail: parseKrasDetail,
1419
1503
  },
1420
1504
  {
1421
1505
  id: '한국고고학회_신간안내_단행본',
1422
1506
  name: '한국고고학회 신간안내 - 단행본',
1423
- url: 'https://www.kras.or.kr/?c=61/101/105',
1424
- parseList: parseKrasList,
1507
+ url: `${KRAS_SITE_BASE_URL}/sub/books`,
1508
+ parseList: (html) => parseKrasListFromApi(html, 'books', customFetch),
1425
1509
  parseDetail: parseKrasDetail,
1426
1510
  },
1427
1511
  {
1428
1512
  id: '한국고고학회_현장소식',
1429
1513
  name: '한국고고학회 현장소식',
1430
- url: 'https://www.kras.or.kr/?c=61/73',
1431
- parseList: parseKrasList,
1514
+ url: `${KRAS_SITE_BASE_URL}/sub/field_news`,
1515
+ parseList: (html) => parseKrasListFromApi(html, 'field_news', customFetch),
1432
1516
  parseDetail: parseKrasDetail,
1433
1517
  },
1434
1518
  {
@@ -2572,8 +2656,8 @@ class CrawlingProvider {
2572
2656
  crawlingTargetGroups;
2573
2657
  constructor(articleRepository, customFetch) {
2574
2658
  this.articleRepository = articleRepository;
2575
- this.customFetch = customFetch;
2576
- this.crawlingTargetGroups = createCrawlingTargetGroups(customFetch);
2659
+ this.customFetch = createKrasFetch(customFetch ?? fetch);
2660
+ this.crawlingTargetGroups = createCrawlingTargetGroups(this.customFetch);
2577
2661
  }
2578
2662
  /**
2579
2663
  * Fetch existing articles by URLs to avoid duplicate crawling
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": "5.0.2",
5
+ "version": "5.0.3",
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.js",
8
8
  "types": "dist/index.d.ts",