@heripo/research-radar 2.1.0 → 2.3.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.
@@ -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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { UrlString, ParsedTarget, CrawlingTargetGroup, CrawlingTarget, UnscoredArticle, ArticleForUpdateByAnalysis, ArticleForGenerateContent, Newsletter, AppLogger, EmailService, EmailMessage, DateService as DateService$1, IsoDateString, TaskService as TaskService$1, AnalysisProvider as AnalysisProvider$1, ContentGenerateProvider as ContentGenerateProvider$1, HtmlTemplate, CrawlingProvider as CrawlingProvider$1 } from '@llm-newsletter-kit/core';
1
+ import { UrlString, ParsedTarget, CrawlingTargetGroup, CrawlingTarget, UnscoredArticle, ArticleForUpdateByAnalysis, ArticleForGenerateContent, Newsletter, AppLogger, EmailService, EmailMessage, DateService as DateService$1, IsoDateString, TaskService as TaskService$1, AnalysisProvider as AnalysisProvider$1, ContentGenerateProvider as ContentGenerateProvider$1, HtmlTemplate, CrawlingProvider as CrawlingProvider$1, GenerateNewsletterConfig } from '@llm-newsletter-kit/core';
2
2
  import { OpenAIProvider } from '@ai-sdk/openai';
3
3
  import { GoogleGenerativeAIProvider } from '@ai-sdk/google';
4
4
 
@@ -64,6 +64,68 @@ interface TagRepository {
64
64
  */
65
65
  findAllTags(): Promise<string[]>;
66
66
  }
67
+ /**
68
+ * Base template options shared by all newsletter variants.
69
+ */
70
+ interface BaseNewsletterTemplateOptions {
71
+ /**
72
+ * Markdown content for KRAS news section.
73
+ * Converted to HTML and injected into the newsletter template.
74
+ */
75
+ krasNewsMarkdown?: string;
76
+ /**
77
+ * Markdown content for heripo lab news section.
78
+ * Converted to HTML and injected into the newsletter template.
79
+ */
80
+ heripolabNewsMarkdown?: string;
81
+ /**
82
+ * Display date string for the newsletter header (e.g. "2026년 2월 12일").
83
+ * Injected from DateService.getDisplayDateString() at generation time.
84
+ */
85
+ displayDate?: string;
86
+ }
87
+ /**
88
+ * Template options for the default (heripo) newsletter variant.
89
+ */
90
+ interface DefaultNewsletterTemplateOptions extends BaseNewsletterTemplateOptions {
91
+ isKrasNewsletter?: false;
92
+ }
93
+ /**
94
+ * Template options for the KRAS (Korean Archaeological Society) newsletter variant.
95
+ *
96
+ * When isKrasNewsletter is true, additional KRAS-specific options become available:
97
+ * - titleContext: Context string to prioritize in newsletter title generation
98
+ */
99
+ interface KrasNewsletterTemplateOptions extends BaseNewsletterTemplateOptions {
100
+ isKrasNewsletter: true;
101
+ /**
102
+ * Context string to prioritize when generating the newsletter title.
103
+ * Only available in KRAS mode. When provided, the LLM will consider this value
104
+ * as the top priority along with the generated newsletter content for title creation.
105
+ * An empty string is treated as undefined (no context).
106
+ */
107
+ titleContext?: string;
108
+ }
109
+ /**
110
+ * Template customization options for newsletter HTML generation.
111
+ *
112
+ * Uses a discriminated union on `isKrasNewsletter`:
113
+ * - When `isKrasNewsletter` is `true`: KRAS-specific options (titleContext) are available.
114
+ * - When `isKrasNewsletter` is `false` or omitted: Only base options are available.
115
+ */
116
+ type NewsletterTemplateOptions = DefaultNewsletterTemplateOptions | KrasNewsletterTemplateOptions;
117
+ /**
118
+ * Options for generating the welcome email HTML.
119
+ *
120
+ * When `isKrasNewsletter` is `true`, KRAS-specific branding and content are applied.
121
+ * When `isKrasNewsletter` is `false` or omitted, standard heripo branding is used.
122
+ */
123
+ interface WelcomeTemplateOptions {
124
+ /** When true, apply KRAS (Korean Archaeological Society) branding */
125
+ isKrasNewsletter?: boolean;
126
+ /** Site base URL for constructing links (default: 'https://heripo.com') */
127
+ siteUrl?: string;
128
+ }
67
129
  /**
68
130
  * Repository interface for newsletter management
69
131
  */
@@ -135,6 +197,10 @@ interface NewsletterGeneratorDependencies {
135
197
  * @example "2025-02-12"
136
198
  */
137
199
  publishDate?: string;
200
+ /** Newsletter template customization options (optional) */
201
+ templateOptions?: NewsletterTemplateOptions;
202
+ /** Custom fetch function for crawling (e.g., proxy-based fetch). Optional. */
203
+ customFetch?: typeof fetch;
138
204
  }
139
205
  /**
140
206
  * Newsletter generation execution function
@@ -156,6 +222,30 @@ interface NewsletterGeneratorDependencies {
156
222
  */
157
223
  declare function generateNewsletter(dependencies: NewsletterGeneratorDependencies): Promise<string | number | null>;
158
224
 
225
+ /**
226
+ * Generates a welcome email HTML string with CSS inlined via juice.
227
+ *
228
+ * API is designed to match the original heripo-web `generateWelcomeHTML(id, name)` usage,
229
+ * with an optional third parameter for KRAS mode and site URL override.
230
+ *
231
+ * @param id - Subscriber ID (used for unsubscribe links in default mode)
232
+ * @param name - Subscriber display name
233
+ * @param options - Optional configuration for KRAS mode and site URL
234
+ * @returns Complete HTML string with CSS inlined (ready to send as email)
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * // Default heripo branding (same as original heripo-web usage):
239
+ * const html = generateWelcomeHTML('subscriber-123', '홍길동');
240
+ *
241
+ * // KRAS mode:
242
+ * const krasHtml = generateWelcomeHTML('subscriber-123', '홍길동', {
243
+ * isKrasNewsletter: true,
244
+ * });
245
+ * ```
246
+ */
247
+ declare function generateWelcomeHTML(id: string, name: string, options?: WelcomeTemplateOptions): string;
248
+
159
249
  /**
160
250
  * Date service implementation
161
251
  * - Provides current date and display date strings
@@ -258,11 +348,13 @@ declare class ContentGenerateProvider implements ContentGenerateProvider$1 {
258
348
  private readonly newsletterRepository;
259
349
  private _issueOrder;
260
350
  model: ReturnType<GoogleGenerativeAIProvider>;
261
- constructor(google: GoogleGenerativeAIProvider, articleRepository: ArticleRepository, newsletterRepository: NewsletterRepository);
351
+ /** HTML template with markers for title and content injection */
352
+ htmlTemplate: HtmlTemplate;
353
+ /** Newsletter brand name (defaults to config, can be overridden via constructor) */
354
+ newsletterBrandName: string;
355
+ constructor(google: GoogleGenerativeAIProvider, articleRepository: ArticleRepository, newsletterRepository: NewsletterRepository, templateOptions?: NewsletterTemplateOptions, brandName?: string);
262
356
  /** LLM temperature setting for content generation */
263
357
  temperature: number;
264
- /** Newsletter brand name */
265
- newsletterBrandName: string;
266
358
  /** Subscribe page URL */
267
359
  subscribePageUrl: UrlString;
268
360
  /** Publication criteria (minimum article count, priority score threshold) */
@@ -284,8 +376,6 @@ declare class ContentGenerateProvider implements ContentGenerateProvider$1 {
284
376
  * @returns Articles eligible for inclusion in the newsletter
285
377
  */
286
378
  fetchArticleCandidates(): Promise<ArticleForGenerateContent[]>;
287
- /** HTML template with markers for title and content injection */
288
- htmlTemplate: HtmlTemplate;
289
379
  /**
290
380
  * Save generated newsletter to the repository
291
381
  * @param input - Newsletter data and used articles
@@ -309,9 +399,11 @@ declare class CrawlingProvider implements CrawlingProvider$1 {
309
399
  private readonly articleRepository;
310
400
  /** Maximum number of concurrent crawling operations */
311
401
  maxConcurrency: number;
312
- constructor(articleRepository: ArticleRepository);
402
+ /** Optional custom fetch function (e.g., proxy-based fetch) */
403
+ customFetch?: typeof fetch;
313
404
  /** Crawling target groups configuration */
314
405
  crawlingTargetGroups: CrawlingTargetGroup[];
406
+ constructor(articleRepository: ArticleRepository, customFetch?: typeof fetch);
315
407
  /**
316
408
  * Fetch existing articles by URLs to avoid duplicate crawling
317
409
  * @param articleUrls - URLs to check
@@ -331,26 +423,31 @@ declare class CrawlingProvider implements CrawlingProvider$1 {
331
423
  }): Promise<number>;
332
424
  }
333
425
 
334
- declare const crawlingTargetGroups: CrawlingTargetGroup[];
426
+ declare function createCrawlingTargetGroups(customFetch?: typeof fetch): CrawlingTargetGroup[];
335
427
 
336
428
  /**
337
- * Newsletter content configuration
429
+ * Content options type extracted from core GenerateNewsletterConfig
338
430
  */
339
- declare const contentOptions: {
340
- outputLanguage: string;
341
- expertField: string[];
342
- };
431
+ type ContentOptions = GenerateNewsletterConfig<any>['contentOptions'];
343
432
  /**
344
- * Newsletter brand configuration
433
+ * Newsletter brand configuration type
345
434
  */
346
- declare const newsletterConfig: {
435
+ interface NewsletterConfig {
347
436
  brandName: string;
348
437
  subscribePageUrl: string;
349
438
  publicationCriteria: {
350
439
  minimumArticleCountForIssue: number;
351
440
  priorityArticleScoreThreshold: number;
352
441
  };
353
- };
442
+ }
443
+ /**
444
+ * Newsletter content configuration
445
+ */
446
+ declare const contentOptions: ContentOptions;
447
+ /**
448
+ * Newsletter brand configuration
449
+ */
450
+ declare const newsletterConfig: NewsletterConfig;
354
451
  /**
355
452
  * LLM configuration
356
453
  */
@@ -362,5 +459,5 @@ declare const llmConfig: {
362
459
  };
363
460
  };
364
461
 
365
- export { AnalysisProvider, ContentGenerateProvider, CrawlingProvider, DateService, TaskService, contentOptions, crawlingTargetGroups, generateNewsletter, llmConfig, newsletterConfig };
366
- export type { ArticleRepository, NewsletterGeneratorDependencies, NewsletterRepository, PreviewNewsletterOptions, TagRepository, TaskRepository };
462
+ export { AnalysisProvider, ContentGenerateProvider, CrawlingProvider, DateService, TaskService, contentOptions, createCrawlingTargetGroups, generateNewsletter, generateWelcomeHTML, llmConfig, newsletterConfig };
463
+ export type { ArticleRepository, ContentOptions, NewsletterConfig, NewsletterGeneratorDependencies, NewsletterRepository, NewsletterTemplateOptions, PreviewNewsletterOptions, TagRepository, TaskRepository, WelcomeTemplateOptions };