All files / src/aggregator/generator slug.ts

100% Statements 5/5
100% Branches 2/2
100% Functions 3/3
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68                                                              42x                         10x         8x                             6x 6x    
// SPDX-FileCopyrightText: 2024-2026 Hack23 AB
// SPDX-License-Identifier: Apache-2.0
 
/**
 * @module Aggregator/Generator/Slug
 * @description Slug + default-description helpers used by the article
 * generator. Thin re-exports of the canonical slug helpers in
 * `aggregator/slug/index.js`, plus the strict default-description
 * extractor used when neither the manifest nor the article-metadata
 * resolver supplies a description.
 */
 
import { extractStrongProseLine } from '../article-metadata.js';
import {
  buildArticleSlug as _buildArticleSlug,
  sanitizeRunSuffix as _sanitizeRunSuffix,
} from '../slug/index.js';
 
/**
 * Build the article slug `YYYY-MM-DD-<article-type>[-<runSuffix>]`.
 *
 * Thin re-export of the canonical implementation in
 * `aggregator/slug/index.js` preserved here for back-compat with the
 * existing test suite.
 *
 * @param date - ISO date string (`YYYY-MM-DD`)
 * @param articleType - Article-type slug (e.g. `breaking`)
 * @param runSuffix - Optional collision-suffix (e.g. `run191`)
 * @returns Combined slug used as the file-stem for every language variant
 */
export function buildArticleSlug(date: string, articleType: string, runSuffix?: string): string {
  return _buildArticleSlug(date, articleType, runSuffix);
}
 
/**
 * Turn an arbitrary run-id string into a short, filename-safe suffix.
 *
 * Thin re-export of the canonical implementation in
 * `aggregator/slug/index.js`.
 *
 * @param runId - Raw run identifier from the manifest (or directory name)
 * @returns Sanitised suffix usable in a filename
 */
export function sanitizeRunSuffix(runId: string): string {
  return _sanitizeRunSuffix(runId);
}
 
/** Description used when no prose paragraph qualifies. */
const FALLBACK_DESCRIPTION =
  'EU Parliament intelligence summary derived from committed analysis artifacts.';
 
/**
 * Extract a short description from the first prose paragraph of the
 * aggregated Markdown — used as the default `<meta name="description">`.
 * Uses the stricter `extractStrongProseLine` filter from
 * `article-metadata.ts` so mermaid `%%{init}` blocks, `title …` directives,
 * emoji-banner metadata rows, and `Analysis Date:` / `Run:` / `Window:`
 * style banners no longer leak into `<meta description>`. Kept as an
 * exported thin wrapper for back-compat with the existing test suite.
 *
 * @param markdown - Aggregated Markdown document
 * @returns Plain-text description, truncated to ≤300 characters
 */
export function extractDefaultDescription(markdown: string): string {
  const strong = extractStrongProseLine(markdown);
  return strong.length > 0 ? strong : FALLBACK_DESCRIPTION;
}