@fre4x/hn 1.0.30 → 1.0.42

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 (3) hide show
  1. package/README.md +10 -1
  2. package/dist/index.js +24 -17
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -23,6 +23,14 @@ Hacker News is where technologists think out loud. This server taps that stream
23
23
 
24
24
  All tools return paginated Markdown or JSON. Token limit enforced at ~3,000 tokens per response.
25
25
 
26
+ ## Mock Mode
27
+
28
+ Run without any API key (returns fixture data of identical shape):
29
+
30
+ ```bash
31
+ MOCK=true npx @fre4x/hn
32
+ ```
33
+
26
34
  ## Deploy
27
35
 
28
36
  ```json
@@ -41,7 +49,8 @@ All tools return paginated Markdown or JSON. Token limit enforced at ~3,000 toke
41
49
  ```bash
42
50
  npm install
43
51
  npm run dev # tsx, no build
44
- npm run build # compile → dist/
52
+ npm run build # esbuild → dist/
53
+ npm test # vitest unit tests
45
54
  ```
46
55
 
47
56
  ## License
package/dist/index.js CHANGED
@@ -3498,7 +3498,7 @@ var require_schemes = __commonJS({
3498
3498
  serialize: httpSerialize
3499
3499
  }
3500
3500
  );
3501
- var https2 = (
3501
+ var https3 = (
3502
3502
  /** @type {SchemeHandler} */
3503
3503
  {
3504
3504
  scheme: "https",
@@ -3547,7 +3547,7 @@ var require_schemes = __commonJS({
3547
3547
  /** @type {Record<SchemeName, SchemeHandler>} */
3548
3548
  {
3549
3549
  http: http3,
3550
- https: https2,
3550
+ https: https3,
3551
3551
  ws,
3552
3552
  wss,
3553
3553
  urn,
@@ -16763,7 +16763,7 @@ var require_form_data = __commonJS({
16763
16763
  var util4 = __require("util");
16764
16764
  var path = __require("path");
16765
16765
  var http3 = __require("http");
16766
- var https2 = __require("https");
16766
+ var https3 = __require("https");
16767
16767
  var parseUrl = __require("url").parse;
16768
16768
  var fs = __require("fs");
16769
16769
  var Stream = __require("stream").Stream;
@@ -17032,7 +17032,7 @@ var require_form_data = __commonJS({
17032
17032
  }
17033
17033
  options.headers = this.getHeaders(params.headers);
17034
17034
  if (options.protocol === "https:") {
17035
- request = https2.request(options);
17035
+ request = https3.request(options);
17036
17036
  } else {
17037
17037
  request = http3.request(options);
17038
17038
  }
@@ -17945,7 +17945,7 @@ var require_follow_redirects = __commonJS({
17945
17945
  var url3 = __require("url");
17946
17946
  var URL2 = url3.URL;
17947
17947
  var http3 = __require("http");
17948
- var https2 = __require("https");
17948
+ var https3 = __require("https");
17949
17949
  var Writable = __require("stream").Writable;
17950
17950
  var assert2 = __require("assert");
17951
17951
  var debug = require_debug();
@@ -18430,7 +18430,7 @@ var require_follow_redirects = __commonJS({
18430
18430
  function isURL(value) {
18431
18431
  return URL2 && value instanceof URL2;
18432
18432
  }
18433
- module.exports = wrap({ http: http3, https: https2 });
18433
+ module.exports = wrap({ http: http3, https: https3 });
18434
18434
  module.exports.wrap = wrap;
18435
18435
  }
18436
18436
  });
@@ -41725,6 +41725,9 @@ var StdioServerTransport = class {
41725
41725
  }
41726
41726
  };
41727
41727
 
41728
+ // src/api.ts
41729
+ import https2 from "node:https";
41730
+
41728
41731
  // ../node_modules/axios/lib/helpers/bind.js
41729
41732
  function bind(fn, thisArg) {
41730
41733
  return function wrap() {
@@ -45504,6 +45507,10 @@ var {
45504
45507
 
45505
45508
  // src/api.ts
45506
45509
  var BASE_URL = "https://hacker-news.firebaseio.com/v0";
45510
+ var httpClient = axios_default.create({
45511
+ baseURL: BASE_URL,
45512
+ httpsAgent: new https2.Agent({ keepAlive: true })
45513
+ });
45507
45514
  var HNApiClient = class {
45508
45515
  cache = /* @__PURE__ */ new Map();
45509
45516
  CACHE_TTL_MS = 60 * 1e3;
@@ -45518,42 +45525,42 @@ var HNApiClient = class {
45518
45525
  if (cached2 && Date.now() - cached2.timestamp < this.CACHE_TTL_MS) {
45519
45526
  return cached2.data;
45520
45527
  }
45521
- const response = await axios_default.get(url3);
45528
+ const response = await httpClient.get(`${url3}.json`);
45522
45529
  this.cache.set(url3, { data: response.data, timestamp: Date.now() });
45523
45530
  return response.data;
45524
45531
  }
45525
45532
  async getItem(id) {
45526
- const response = await axios_default.get(`${BASE_URL}/item/${id}.json`);
45533
+ const response = await httpClient.get(`/item/${id}.json`);
45527
45534
  return response.data;
45528
45535
  }
45529
45536
  async getUser(id) {
45530
- const response = await axios_default.get(`${BASE_URL}/user/${id}.json`);
45537
+ const response = await httpClient.get(`/user/${id}.json`);
45531
45538
  return response.data;
45532
45539
  }
45533
45540
  async getMaxItem() {
45534
- const response = await axios_default.get(`${BASE_URL}/maxitem.json`);
45541
+ const response = await httpClient.get(`/maxitem.json`);
45535
45542
  return response.data;
45536
45543
  }
45537
45544
  async getTopStories() {
45538
- return this.fetchWithCache(`${BASE_URL}/topstories.json`);
45545
+ return this.fetchWithCache(`/topstories`);
45539
45546
  }
45540
45547
  async getNewStories() {
45541
- return this.fetchWithCache(`${BASE_URL}/newstories.json`);
45548
+ return this.fetchWithCache(`/newstories`);
45542
45549
  }
45543
45550
  async getBestStories() {
45544
- return this.fetchWithCache(`${BASE_URL}/beststories.json`);
45551
+ return this.fetchWithCache(`/beststories`);
45545
45552
  }
45546
45553
  async getAskStories() {
45547
- return this.fetchWithCache(`${BASE_URL}/askstories.json`);
45554
+ return this.fetchWithCache(`/askstories`);
45548
45555
  }
45549
45556
  async getShowStories() {
45550
- return this.fetchWithCache(`${BASE_URL}/showstories.json`);
45557
+ return this.fetchWithCache(`/showstories`);
45551
45558
  }
45552
45559
  async getJobStories() {
45553
- return this.fetchWithCache(`${BASE_URL}/jobstories.json`);
45560
+ return this.fetchWithCache(`/jobstories`);
45554
45561
  }
45555
45562
  async getUpdates() {
45556
- const response = await axios_default.get(`${BASE_URL}/updates.json`);
45563
+ const response = await httpClient.get(`/updates.json`);
45557
45564
  return response.data;
45558
45565
  }
45559
45566
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fre4x/hn",
3
- "version": "1.0.30",
3
+ "version": "1.0.42",
4
4
  "description": "A Hacker News MCP server for LLMs.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,8 +11,8 @@
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "npx esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\"",
15
- "typecheck": "NODE_OPTIONS='--max-old-space-size=4096' tsc --noEmit",
14
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && npx esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\"",
15
+ "typecheck": "cross-env NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
16
16
  "start": "node dist/index.js",
17
17
  "dev": "tsx src/index.ts",
18
18
  "watch": "tsc -w",