meteoswiss-mcp 2.3.1 → 3.0.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.
Files changed (68) hide show
  1. package/README.md +5 -1
  2. package/dist/data/meteoswiss-content-data.js +103 -57
  3. package/dist/data/meteoswiss-content-data.js.map +1 -1
  4. package/dist/data/meteoswiss-search-data.js +66 -55
  5. package/dist/data/meteoswiss-search-data.js.map +1 -1
  6. package/dist/data/meteoswiss-web-components.js +5 -0
  7. package/dist/data/meteoswiss-web-components.js.map +1 -1
  8. package/dist/data/ogd-climate-data.js +28 -8
  9. package/dist/data/ogd-climate-data.js.map +1 -1
  10. package/dist/data/ogd-current-weather.js +71 -16
  11. package/dist/data/ogd-current-weather.js.map +1 -1
  12. package/dist/data/ogd-data-store.js +102 -2
  13. package/dist/data/ogd-data-store.js.map +1 -1
  14. package/dist/data/ogd-local-forecast.js +230 -60
  15. package/dist/data/ogd-local-forecast.js.map +1 -1
  16. package/dist/data/ogd-nbcn-stations.js +18 -2
  17. package/dist/data/ogd-nbcn-stations.js.map +1 -1
  18. package/dist/data/ogd-pollen-data.js +39 -3
  19. package/dist/data/ogd-pollen-data.js.map +1 -1
  20. package/dist/data/ogd-smn-stations.js +25 -22
  21. package/dist/data/ogd-smn-stations.js.map +1 -1
  22. package/dist/data/ogd-stac-client.js +12 -7
  23. package/dist/data/ogd-stac-client.js.map +1 -1
  24. package/dist/data/ogd-station-resolver.js +2 -23
  25. package/dist/data/ogd-station-resolver.js.map +1 -1
  26. package/dist/schemas/meteoswiss-fetch.js +31 -4
  27. package/dist/schemas/meteoswiss-fetch.js.map +1 -1
  28. package/dist/schemas/meteoswiss-search.js +24 -9
  29. package/dist/schemas/meteoswiss-search.js.map +1 -1
  30. package/dist/schemas/ogd-climate-data.js +56 -1
  31. package/dist/schemas/ogd-climate-data.js.map +1 -1
  32. package/dist/schemas/ogd-current-weather.js +59 -1
  33. package/dist/schemas/ogd-current-weather.js.map +1 -1
  34. package/dist/schemas/ogd-local-forecast.js +73 -1
  35. package/dist/schemas/ogd-local-forecast.js.map +1 -1
  36. package/dist/schemas/ogd-pollen-data.js +39 -0
  37. package/dist/schemas/ogd-pollen-data.js.map +1 -1
  38. package/dist/schemas/ogd-station-list.js +21 -1
  39. package/dist/schemas/ogd-station-list.js.map +1 -1
  40. package/dist/server.js +112 -29
  41. package/dist/server.js.map +1 -1
  42. package/dist/support/environment-validation.js +18 -0
  43. package/dist/support/environment-validation.js.map +1 -1
  44. package/dist/support/geocode.js +23 -5
  45. package/dist/support/geocode.js.map +1 -1
  46. package/dist/support/http-cache.js +24 -36
  47. package/dist/support/http-cache.js.map +1 -1
  48. package/dist/support/http-communication.js +137 -33
  49. package/dist/support/http-communication.js.map +1 -1
  50. package/dist/support/name-matcher.js +28 -0
  51. package/dist/support/name-matcher.js.map +1 -1
  52. package/dist/support/ogd-csv-parser.js +7 -2
  53. package/dist/support/ogd-csv-parser.js.map +1 -1
  54. package/dist/support/ogd-timestamp.js +37 -0
  55. package/dist/support/ogd-timestamp.js.map +1 -0
  56. package/dist/support/round-measurements.js +86 -0
  57. package/dist/support/round-measurements.js.map +1 -0
  58. package/dist/support/weather-icons.js +12 -3
  59. package/dist/support/weather-icons.js.map +1 -1
  60. package/dist/tools/meteoswiss-fetch.js +1 -1
  61. package/dist/tools/meteoswiss-fetch.js.map +1 -1
  62. package/dist/transports/streamable-http.js +47 -19
  63. package/dist/transports/streamable-http.js.map +1 -1
  64. package/package.json +11 -7
  65. package/src/views/homepage/overview.md +5 -1
  66. package/src/views/homepage/tools.md +20 -3
  67. package/dist/support/validation-errors.js +0 -38
  68. package/dist/support/validation-errors.js.map +0 -1
package/README.md CHANGED
@@ -7,12 +7,15 @@
7
7
 
8
8
  MCP server for MeteoSwiss weather data — powered by [MeteoSwiss Open Data](https://opendatadocs.meteoswiss.ch/), the same data behind the MeteoSwiss app and website.
9
9
 
10
+ This package is the *server* half of the repo's [skill vs. MCP case study](../../docs/skill-vs-mcp.md) — the same data is also available as a no-infrastructure [agent skill](../meteoswiss-skills/).
11
+
10
12
  **[meteoswiss-mcp.ars.is](https://meteoswiss-mcp.ars.is/)** — try it now, no setup needed.
11
13
 
12
14
  - **Multi-day forecasts** for ~6000 Swiss locations (postal codes, stations, place names)
13
- - **Real-time measurements** from ~160 automatic weather stations, updated every 10 minutes
15
+ - **Real-time measurements** from ~300 stations (~160 full weather + ~140 precipitation-only), updated every 10 minutes
14
16
  - **Station discovery** by name, canton, or GPS coordinates
15
17
  - **Pollen monitoring** from ~15 stations across Switzerland
18
+ - **Climate series** from the National Basic Climatic Network (NBCN), going back decades
16
19
  - **MeteoSwiss website** search and content retrieval
17
20
 
18
21
  ## Use the Hosted Service
@@ -65,6 +68,7 @@ Go to **Settings** → **Integrations** → **Add MCP Server** → paste `https:
65
68
  | `meteoswissCurrentWeather` | Real-time measurements from automatic weather stations (temperature, wind, humidity, pressure) |
66
69
  | `meteoswissStations` | Search and browse the MeteoSwiss station network by name, canton, or coordinates |
67
70
  | `meteoswissPollenData` | Current pollen concentration data from monitoring stations |
71
+ | `meteoswissClimateData` | NBCN climate series — temperature, precipitation, sunshine, and climate indicators going back decades |
68
72
  | `search` | Search MeteoSwiss website content (DE, FR, IT, EN) |
69
73
  | `fetch` | Fetch full content from MeteoSwiss pages in markdown, text, or HTML |
70
74
 
@@ -16,6 +16,14 @@ const TEST_FIXTURES_ROOT = existsSync(TEST_FIXTURES_DEV_PATH)
16
16
  ? TEST_FIXTURES_DEV_PATH
17
17
  : TEST_FIXTURES_PROD_PATH;
18
18
  const USE_TEST_FIXTURES = process.env.USE_TEST_FIXTURES === 'true';
19
+ /**
20
+ * Hard cap on HTML size before parsing. `new JSDOM(html)` is synchronous and
21
+ * blocks the single-threaded event loop for the full parse; an unbounded input
22
+ * from a large upstream page therefore stalls every other session. The largest
23
+ * real MeteoSwiss page is well under 500 KB, so 5 MB leaves generous headroom
24
+ * while preventing a pathological multi-MB block. Must stay ≤ MAX_RESPONSE_BYTES.
25
+ */
26
+ const MAX_HTML_BYTES = 5_000_000;
19
27
  // Allowed MeteoSwiss domains
20
28
  const ALLOWED_DOMAINS = [
21
29
  'www.meteoschweiz.admin.ch',
@@ -27,6 +35,36 @@ const ALLOWED_DOMAINS = [
27
35
  'meteosvizzera.admin.ch',
28
36
  'meteoswiss.admin.ch',
29
37
  ];
38
+ /**
39
+ * Assert that a URL targets an allowed MeteoSwiss domain over https on the
40
+ * default port. Run on the initial fetch URL and re-run on every redirect hop
41
+ * (so an upstream open redirect cannot escape the allowlist — SEC-4), and pins
42
+ * the scheme to https and the port to default (SEC-8).
43
+ *
44
+ * `URL.hostname` is used for the host check, which is robust against userinfo
45
+ * (`@`), case, punycode/IDN, and bare-path (`//evil.com`) escapes.
46
+ *
47
+ * @param rawUrl - The URL to validate
48
+ * @throws {Error} If the URL is malformed, non-https, non-default-port, or off-allowlist
49
+ */
50
+ export function assertAllowedContentUrl(rawUrl) {
51
+ let parsedUrl;
52
+ try {
53
+ parsedUrl = new URL(rawUrl);
54
+ }
55
+ catch (error) {
56
+ throw new Error(`Invalid URL: ${rawUrl}`, { cause: error });
57
+ }
58
+ if (parsedUrl.protocol !== 'https:') {
59
+ throw new Error(`Invalid scheme: ${parsedUrl.protocol} for ${rawUrl}. Only https is allowed.`);
60
+ }
61
+ if (parsedUrl.port !== '') {
62
+ throw new Error(`Invalid port: ${parsedUrl.port} for ${rawUrl}. Only the default https port is allowed.`);
63
+ }
64
+ if (!ALLOWED_DOMAINS.includes(parsedUrl.hostname)) {
65
+ throw new Error(`Invalid domain: ${parsedUrl.hostname}. Only MeteoSwiss domains are allowed.`);
66
+ }
67
+ }
30
68
  // Initialize Turndown for HTML to Markdown conversion
31
69
  const turndownService = new TurndownService({
32
70
  headingStyle: 'atx',
@@ -35,77 +73,78 @@ const turndownService = new TurndownService({
35
73
  });
36
74
  // Add GFM plugin for better markdown support (tables, strikethrough, task lists)
37
75
  turndownService.use(gfm);
76
+ // ContentResponse now lives in ../schemas/meteoswiss-fetch.ts as a Zod schema
77
+ // (ContentResponseSchema) so the fetch tool can declare it as its MCP outputSchema.
78
+ // Field naming follows the ChatGPT Deep Research MCP contract: `id`, `title`,
79
+ // `text`, `url`, `metadata`. Prior to v2.4.0 this response also included a
80
+ // `content` field duplicating `text` byte-for-byte; it was removed as a
81
+ // token-cost fix (issue #110, BUG-2) — `text` is canonical.
38
82
  /**
39
- * Fetch MeteoSwiss content by ID
83
+ * Fetch MeteoSwiss content by ID.
84
+ *
85
+ * The `id` parameter is a full MeteoSwiss page URL returned by the search tool.
40
86
  *
41
87
  * @param params Fetch parameters
42
88
  * @returns Content response
43
89
  */
44
90
  export async function fetchMeteoSwissContent(params) {
45
- const { url, format = 'markdown', includeMetadata = true } = params;
91
+ const { id, format = 'markdown', includeMetadata = true } = params;
46
92
  debugData('fetchMeteoSwissContent called with params: %o', {
47
- url,
93
+ id,
48
94
  format,
49
95
  includeMetadata,
50
96
  });
51
97
  if (USE_TEST_FIXTURES) {
52
98
  debugData('Using test fixtures for content fetch');
53
- return fetchFromTestFixtures(url, format, includeMetadata);
99
+ return fetchFromTestFixtures(id, format, includeMetadata);
54
100
  }
55
101
  debugData('Using live API for content fetch');
56
- return fetchFromWeb(url, format, includeMetadata);
102
+ return fetchFromWeb(id, format, includeMetadata);
57
103
  }
58
104
  /**
59
- * Fetch content from the web
105
+ * Fetch content from the web.
106
+ *
107
+ * @param id The page id — a full URL or a path returned by the search tool.
60
108
  */
61
- async function fetchFromWeb(url, format, includeMetadata) {
109
+ async function fetchFromWeb(id, format, includeMetadata) {
62
110
  // Normalise to full URL (accept full URLs; prepend base for bare paths for backward compat)
63
- const fullUrl = url.startsWith('http')
64
- ? url
65
- : `https://www.meteoswiss.admin.ch${url.startsWith('/') ? url : '/' + url}`;
111
+ const fullUrl = id.startsWith('http')
112
+ ? id
113
+ : `https://www.meteoswiss.admin.ch${id.startsWith('/') ? id : '/' + id}`;
66
114
  debugData('Fetching content from URL: %s', fullUrl);
67
- // Validate the URL is from an allowed MeteoSwiss domain
68
- try {
69
- const parsedUrl = new URL(fullUrl);
70
- if (!ALLOWED_DOMAINS.includes(parsedUrl.hostname)) {
71
- throw new Error(`Invalid domain: ${parsedUrl.hostname}. Only MeteoSwiss domains are allowed.`);
72
- }
73
- }
74
- catch (error) {
75
- if (error instanceof TypeError) {
76
- throw new Error(`Invalid URL: ${fullUrl}`, { cause: error });
77
- }
78
- throw error;
79
- }
115
+ // Validate scheme, port, and domain up front (thrown directly to the caller).
116
+ assertAllowedContentUrl(fullUrl);
80
117
  try {
81
118
  debugData('Making HTTP request to fetch content');
82
- const html = await fetchHtml(fullUrl);
119
+ // Re-validate every redirect hop so an upstream open redirect cannot escape
120
+ // the allowlist.
121
+ const html = await fetchHtml(fullUrl, { validateUrl: assertAllowedContentUrl });
83
122
  debugData('Content fetched successfully, size: %d bytes', html.length);
84
- // Add timeout protection for HTML processing
85
- const processingTimeout = new Promise((_, reject) => {
86
- setTimeout(() => reject(new Error('HTML processing timeout after 10 seconds')), 10000);
87
- });
88
- const contentProcessing = processHtmlContent(html, fullUrl, format, includeMetadata);
89
- return await Promise.race([contentProcessing, processingTimeout]);
123
+ // processHtmlContent is synchronous; a Promise.race timeout around it was
124
+ // dead code (the parse completes before the race is evaluated). The parse is
125
+ // bounded instead by MAX_HTML_BYTES inside processHtmlContent.
126
+ return processHtmlContent(html, fullUrl, format, includeMetadata);
90
127
  }
91
128
  catch (error) {
92
129
  debugData('Content fetch error: %o', error);
93
130
  if (error instanceof HttpRequestError && error.statusCode === 404) {
94
- throw new Error(`Content not found: ${url}. Use the search tool to discover valid page URLs.`, { cause: error });
131
+ throw new Error(`Content not found: ${id}. Use the search tool to discover valid page URLs.`, { cause: error });
95
132
  }
96
133
  throw new Error(`Failed to fetch content: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
97
134
  }
98
135
  }
99
136
  /**
100
- * Fetch content from test fixtures
137
+ * Fetch content from test fixtures.
138
+ *
139
+ * @param id The page id — a full URL or a path returned by the search tool.
101
140
  */
102
- async function fetchFromTestFixtures(url, format, includeMetadata) {
103
- debugData('Looking for test fixture for URL: %s', url);
141
+ async function fetchFromTestFixtures(id, format, includeMetadata) {
142
+ debugData('Looking for test fixture for id: %s', id);
104
143
  // Extract language from URL if it's a full URL
105
144
  let detectedLang = 'de';
106
- let urlPath = url;
107
- if (url.startsWith('http')) {
108
- const parsed = new URL(url);
145
+ let urlPath = id;
146
+ if (id.startsWith('http')) {
147
+ const parsed = new URL(id);
109
148
  urlPath = parsed.pathname;
110
149
  // Detect language from domain
111
150
  if (parsed.hostname.includes('meteoschweiz')) {
@@ -132,28 +171,30 @@ async function fetchFromTestFixtures(url, format, includeMetadata) {
132
171
  if (existsSync(fixtureFile)) {
133
172
  debugData('Loading test fixture from: %s', fixtureFile);
134
173
  const html = await fs.readFile(fixtureFile, 'utf-8');
135
- const fullUrl = url.startsWith('http') ? url : `https://www.meteoswiss.admin.ch${url}`;
174
+ const fullUrl = id.startsWith('http') ? id : `https://www.meteoswiss.admin.ch${id}`;
136
175
  return processHtmlContent(html, fullUrl, format, includeMetadata);
137
176
  }
138
177
  }
139
- debugData('No test fixture found for URL: %s', url);
140
- throw new Error(`Content not found: ${url}`);
178
+ debugData('No test fixture found for id: %s', id);
179
+ throw new Error(`Content not found: ${id}`);
141
180
  }
142
181
  /**
143
182
  * Process HTML content and convert to requested format
144
183
  */
145
184
  function processHtmlContent(html, url, format, includeMetadata) {
146
185
  debugData('Processing HTML content, format: %s, includeMetadata: %s, size: %d bytes', format, includeMetadata, html.length);
147
- // Warn if HTML is very large
148
- if (html.length > 500000) {
149
- debugData('WARNING: Large HTML document (%d bytes), processing may be slow', html.length);
186
+ // Reject oversized input before the synchronous (event-loop-blocking) parse.
187
+ if (html.length > MAX_HTML_BYTES) {
188
+ throw new Error(`HTML document too large to process: ${html.length} characters exceeds ${MAX_HTML_BYTES} cap`);
150
189
  }
151
190
  const dom = new JSDOM(html);
152
191
  const document = dom.window.document;
153
192
  // Expand MeteoSwiss web components into standard HTML before extraction
154
193
  expandWebComponents(document);
155
- // Extract main content
156
- const mainContent = extractMainContent(document);
194
+ // Extract main content element (parsed once; the text path reuses this DOM
195
+ // node's textContent rather than instantiating a second JSDOM).
196
+ const mainElement = extractMainContent(document);
197
+ const mainHtml = mainElement?.innerHTML ?? '';
157
198
  // Extract title - try multiple selectors
158
199
  const title = document.querySelector('h1')?.textContent?.trim() ||
159
200
  document.querySelector('mch-title[level="1"]')?.textContent?.trim() ||
@@ -175,14 +216,14 @@ function processHtmlContent(html, url, format, includeMetadata) {
175
216
  let content;
176
217
  switch (format) {
177
218
  case 'markdown':
178
- content = turndownService.turndown(mainContent);
219
+ content = turndownService.turndown(mainHtml);
179
220
  // Prepend title as H1 if we have one and it's not already in the content
180
221
  if (title && title !== 'Untitled' && !content.includes(`# ${title}`)) {
181
222
  content = `# ${title}\n\n${content}`;
182
223
  }
183
224
  break;
184
225
  case 'text':
185
- content = extractTextContent(mainContent);
226
+ content = cleanTextContent(mainElement?.textContent ?? '');
186
227
  // Prepend title for text format too
187
228
  if (title && title !== 'Untitled') {
188
229
  content = `${title}\n\n${content}`;
@@ -195,13 +236,19 @@ function processHtmlContent(html, url, format, includeMetadata) {
195
236
  return {
196
237
  id: url,
197
238
  title,
198
- content,
239
+ text: content,
199
240
  format,
241
+ url,
200
242
  metadata,
201
243
  };
202
244
  }
203
245
  /**
204
- * Extract main content from the page
246
+ * Extract the main content element from the page.
247
+ *
248
+ * Returns the DOM element (not serialized HTML) so callers can derive both
249
+ * `innerHTML` (markdown path) and `textContent` (text path) from a single parse.
250
+ *
251
+ * @returns The main-content element, or `null` if the document has no body
205
252
  */
206
253
  function extractMainContent(document) {
207
254
  // Remove screenreader titles in all languages
@@ -264,7 +311,7 @@ function extractMainContent(document) {
264
311
  for (const selector of selectors) {
265
312
  const element = document.querySelector(selector);
266
313
  if (element) {
267
- return element.innerHTML;
314
+ return element;
268
315
  }
269
316
  }
270
317
  // Fallback to body content
@@ -273,17 +320,16 @@ function extractMainContent(document) {
273
320
  // Remove navigation, header, footer, scripts, styles
274
321
  const toRemove = body.querySelectorAll('nav, header, footer, script, style, noscript');
275
322
  toRemove.forEach((el) => el.remove());
276
- return body.innerHTML;
323
+ return body;
277
324
  }
278
- return '';
325
+ return null;
279
326
  }
280
327
  /**
281
- * Extract text content from HTML
328
+ * Normalize extracted plain text: trim each line and drop blank lines.
329
+ * Operates on already-extracted `textContent` — no HTML parsing (a second
330
+ * JSDOM instantiation here previously doubled the parse cost for text format).
282
331
  */
283
- function extractTextContent(html) {
284
- const tempDom = new JSDOM(html);
285
- const text = tempDom.window.document.body.textContent || '';
286
- // Clean up whitespace
332
+ function cleanTextContent(text) {
287
333
  return text
288
334
  .split('\n')
289
335
  .map((line) => line.trim())
@@ -1 +1 @@
1
- {"version":3,"file":"meteoswiss-content-data.js","sourceRoot":"","sources":["../../src/data/meteoswiss-content-data.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"meteoswiss-content-data.js","sourceRoot":"","sources":["../../src/data/meteoswiss-content-data.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,33 @@ import fs from 'node:fs/promises';
2
2
  import { existsSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
+ import { z } from 'zod';
5
6
  import { fetchJson, HttpRequestError } from '../support/http-communication.js';
6
7
  import { debugData } from '../support/logging.js';
8
+ // Solr response schemas. Validated (not just cast) so a valid-JSON error payload
9
+ // or a shape change throws instead of silently degrading to "0 results" (FUN-9).
10
+ const SolrDocumentSchema = z.object({
11
+ path: z.string().optional(),
12
+ id: z.string().optional(),
13
+ title: z.string().optional(),
14
+ lead: z.string().optional(),
15
+ description: z.string().optional(),
16
+ pageType: z.string().optional(),
17
+ modificationDate: z.string().optional(),
18
+ publicationDate: z.string().optional(),
19
+ content: z.string().optional(),
20
+ });
21
+ const SolrResponseSchema = z.object({
22
+ response: z.object({
23
+ numFound: z.number().optional(),
24
+ // Required array — an error envelope lacking it fails validation and throws.
25
+ docs: z.array(SolrDocumentSchema),
26
+ }),
27
+ });
28
+ /** Parse and validate a raw Solr response, throwing on shape mismatch. */
29
+ function parseSolrResponse(raw) {
30
+ return SolrResponseSchema.parse(raw);
31
+ }
7
32
  // Language to domain mapping for MeteoSwiss
8
33
  const LANGUAGE_DOMAIN_MAP = {
9
34
  de: 'https://www.meteoschweiz.admin.ch',
@@ -21,6 +46,14 @@ const TEST_FIXTURES_ROOT = existsSync(TEST_FIXTURES_DEV_PATH)
21
46
  ? TEST_FIXTURES_DEV_PATH
22
47
  : TEST_FIXTURES_PROD_PATH;
23
48
  const USE_TEST_FIXTURES = process.env.USE_TEST_FIXTURES === 'true';
49
+ /**
50
+ * The upstream MeteoSwiss Solr search API ignores the `rows` parameter and
51
+ * always returns exactly 10 documents per request (verified against the live
52
+ * API: `rows=3` and `rows=30` both return 10 of N results). We mirror that
53
+ * fixed page size exactly rather than expose a `pageSize` knob that upstream
54
+ * doesn't honor — see GitHub issue #110, DECISION-1.
55
+ */
56
+ const UPSTREAM_PAGE_SIZE = 10;
24
57
  /**
25
58
  * Search MeteoSwiss content
26
59
  *
@@ -28,26 +61,25 @@ const USE_TEST_FIXTURES = process.env.USE_TEST_FIXTURES === 'true';
28
61
  * @returns Search results
29
62
  */
30
63
  export async function searchMeteoSwissContent(params) {
31
- const { query, language = 'de', contentType, page = 1, pageSize = 12, sort = 'relevance', } = params;
64
+ const { query, language = 'de', contentType, page = 1, sort = 'relevance' } = params;
32
65
  debugData('searchMeteoSwissContent called with params: %o', {
33
66
  query,
34
67
  language,
35
68
  contentType,
36
69
  page,
37
- pageSize,
38
70
  sort,
39
71
  });
40
72
  if (USE_TEST_FIXTURES) {
41
73
  debugData('Using test fixtures for search');
42
- return searchFromTestFixtures(query, language, contentType, page, pageSize, sort);
74
+ return searchFromTestFixtures(query, language, contentType, page, sort);
43
75
  }
44
76
  debugData('Using live API for search');
45
- return searchFromApi(query, language, contentType, page, pageSize, sort);
77
+ return searchFromApi(query, language, contentType, page, sort);
46
78
  }
47
79
  /**
48
80
  * Search from the live API
49
81
  */
50
- async function searchFromApi(query, language, contentType, page = 1, pageSize = 12, sort = 'relevance') {
82
+ async function searchFromApi(query, language, contentType, page = 1, sort = 'relevance') {
51
83
  const tenant = 'mchweb';
52
84
  const pageGroup = 'project';
53
85
  const languageCode = `public-${language}`;
@@ -62,8 +94,11 @@ async function searchFromApi(query, language, contentType, page = 1, pageSize =
62
94
  url.searchParams.append('fullText', processedQuery);
63
95
  url.searchParams.append('tenant', tenant);
64
96
  url.searchParams.append('pageGroup', pageGroup);
65
- url.searchParams.append('rows', String(pageSize));
66
- url.searchParams.append('start', String((page - 1) * pageSize));
97
+ // Upstream ignores `rows` and always returns UPSTREAM_PAGE_SIZE docs, but it
98
+ // does honor `start` so the offset must be computed from the fixed page
99
+ // size, not a requested one, for `page` navigation to be consistent.
100
+ url.searchParams.append('rows', String(UPSTREAM_PAGE_SIZE));
101
+ url.searchParams.append('start', String((page - 1) * UPSTREAM_PAGE_SIZE));
67
102
  // Always set content type, defaulting to 'content' to exclude application pages
68
103
  // Only allow specific content types that are relevant
69
104
  const allowedContentTypes = ['content', 'press-release', 'blog-article', 'publication'];
@@ -84,7 +119,7 @@ async function searchFromApi(query, language, contentType, page = 1, pageSize =
84
119
  url.searchParams.append('sort', sortValue);
85
120
  try {
86
121
  debugData('Searching MeteoSwiss API: %s', url.toString());
87
- const response = await fetchJson(url.toString());
122
+ const response = parseSolrResponse(await fetchJson(url.toString()));
88
123
  debugData('API response received: %d documents found', response.response?.numFound || 0);
89
124
  // Transform the Solr response to our format
90
125
  const results = response.response?.docs?.map((doc) => ({
@@ -102,7 +137,9 @@ async function searchFromApi(query, language, contentType, page = 1, pageSize =
102
137
  return {
103
138
  totalResults: response.response?.numFound || 0,
104
139
  page,
105
- pageSize,
140
+ // Report what upstream actually delivered, not a requested value it
141
+ // ignores — see UPSTREAM_PAGE_SIZE comment above.
142
+ pageSize: results.length,
106
143
  results,
107
144
  };
108
145
  }
@@ -117,12 +154,16 @@ async function searchFromApi(query, language, contentType, page = 1, pageSize =
117
154
  /**
118
155
  * Search from test fixtures
119
156
  */
120
- async function searchFromTestFixtures(query, language, contentType, page = 1, pageSize = 12, sort = 'relevance') {
157
+ async function searchFromTestFixtures(query, language, contentType, page = 1, sort = 'relevance') {
121
158
  // Get the base domain for this language
122
159
  const baseDomain = LANGUAGE_DOMAIN_MAP[language] || LANGUAGE_DOMAIN_MAP.de;
123
- // Replace spaces with hyphens for fixture filename, consistent with how we name fixture files
160
+ // Slugify the query into a fixture filename. Diacritics are stripped (NFD +
161
+ // combining-mark removal) so "météo" resolves to `meteo-results.json` by exact
162
+ // match instead of relying on the removed first-file fallback (TEST-2).
124
163
  const fixtureFile = path.join(TEST_FIXTURES_ROOT, language, `${query
125
164
  .toLowerCase()
165
+ .normalize('NFD')
166
+ .replace(/[\u0300-\u036f]/g, '')
126
167
  .replace(/\s+/g, '-')
127
168
  .replace(/[^a-z0-9-]/g, '-')}-results.json`);
128
169
  debugData('Looking for test fixture: %s', fixtureFile);
@@ -130,7 +171,7 @@ async function searchFromTestFixtures(query, language, contentType, page = 1, pa
130
171
  if (existsSync(fixtureFile)) {
131
172
  debugData('Loading test fixture from: %s', fixtureFile);
132
173
  const data = await fs.readFile(fixtureFile, 'utf-8');
133
- const response = JSON.parse(data);
174
+ const response = parseSolrResponse(JSON.parse(data));
134
175
  // Transform fixture data to our format
135
176
  const results = response.response?.docs?.map((doc) => ({
136
177
  id: doc.path ? `${baseDomain}${doc.path}` : doc.id || '',
@@ -158,57 +199,27 @@ async function searchFromTestFixtures(query, language, contentType, page = 1, pa
158
199
  return dateA - dateB;
159
200
  });
160
201
  }
161
- // Apply pagination
162
- const startIndex = (page - 1) * pageSize;
163
- const paginatedResults = results.slice(startIndex, startIndex + pageSize);
202
+ // Mirror the live API's fixed upstream page size (see UPSTREAM_PAGE_SIZE).
203
+ const startIndex = (page - 1) * UPSTREAM_PAGE_SIZE;
204
+ const paginatedResults = results.slice(startIndex, startIndex + UPSTREAM_PAGE_SIZE);
164
205
  return {
165
206
  totalResults: response.response?.numFound || 0,
166
207
  page,
167
- pageSize,
208
+ pageSize: paginatedResults.length,
168
209
  results: paginatedResults,
169
210
  };
170
211
  }
171
- // Try to find any fixture file for the language
172
- const langDir = path.join(TEST_FIXTURES_ROOT, language);
173
- if (existsSync(langDir)) {
174
- const files = await fs.readdir(langDir);
175
- if (files.length > 0 && files[0]) {
176
- const firstFile = files[0];
177
- const data = await fs.readFile(path.join(langDir, firstFile), 'utf-8');
178
- const response = JSON.parse(data);
179
- // Filter results by query in fixtures
180
- const allDocs = response.response?.docs || [];
181
- const filteredDocs = allDocs.filter((doc) => doc.title?.toLowerCase().includes(query.toLowerCase()) ||
182
- doc.lead?.toLowerCase().includes(query.toLowerCase()) ||
183
- doc.content?.toLowerCase().includes(query.toLowerCase()));
184
- const baseDomain = LANGUAGE_DOMAIN_MAP[language] || LANGUAGE_DOMAIN_MAP.de;
185
- const results = filteredDocs.map((doc) => ({
186
- id: doc.path ? `${baseDomain}${doc.path}` : doc.id || '',
187
- title: doc.title || 'Untitled',
188
- url: doc.path ? `${baseDomain}${doc.path}` : '',
189
- description: doc.lead || doc.description || '',
190
- contentType: doc.pageType || 'content',
191
- lastModified: doc.modificationDate || doc.publicationDate,
192
- path: doc.path,
193
- lead: doc.lead,
194
- publicationDate: doc.publicationDate,
195
- }));
196
- // Apply pagination
197
- const startIndex = (page - 1) * pageSize;
198
- const paginatedResults = results.slice(startIndex, startIndex + pageSize);
199
- return {
200
- totalResults: results.length,
201
- page,
202
- pageSize,
203
- results: paginatedResults,
204
- };
205
- }
206
- }
207
- // Return empty results if no fixtures found
212
+ // No exact fixture: return empty (a genuine "no match", the same shape the
213
+ // live API gives for an unmatched query). The previous behaviour — read the
214
+ // first file in the language directory and substring-filter it — could return
215
+ // "whatever sorts first" for a missing/renamed fixture, silently masking the
216
+ // gap with unrelated results (TEST-2). Diacritic-insensitive slugging above
217
+ // means real fixtures (e.g. "météo" → meteo) resolve by exact match instead.
218
+ debugData('No exact search fixture for query "%s" (%s) — returning empty results', query, language);
208
219
  return {
209
220
  totalResults: 0,
210
- page: 1,
211
- pageSize: 12,
221
+ page,
222
+ pageSize: 0,
212
223
  results: [],
213
224
  };
214
225
  }
@@ -1 +1 @@
1
- {"version":3,"file":"meteoswiss-search-data.js","sourceRoot":"","sources":["../../src/data/meteoswiss-search-data.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"meteoswiss-search-data.js","sourceRoot":"","sources":["../../src/data/meteoswiss-search-data.ts"],"names":[],"mappings":"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"}
@@ -188,6 +188,11 @@ function removeNonContentElements(document) {
188
188
  'mch-breadcrumb',
189
189
  'mch-skiplinks',
190
190
  'mch-go-to-top',
191
+ // Decorative icons (chevrons, arrows, social icons). Each wraps a nested
192
+ // <wb-icon><svg><title>{name}</title>...</svg></wb-icon> whose <title>
193
+ // text (e.g. "chevron-small-right") is otherwise picked up as visible
194
+ // page text by Turndown/textContent extraction (issue #110, BUG-6).
195
+ 'mch-icon',
191
196
  ];
192
197
  for (const selector of selectorsToRemove) {
193
198
  document.querySelectorAll(selector).forEach((el) => el.remove());