@zonuexe/techbook-mcp 0.2.3 → 0.2.4

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 (135) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/README.md +39 -20
  3. package/dist/adapters/publishers/google-books.d.ts +4 -0
  4. package/dist/adapters/publishers/google-books.d.ts.map +1 -0
  5. package/dist/adapters/publishers/google-books.js +75 -0
  6. package/dist/adapters/publishers/google-books.js.map +1 -0
  7. package/dist/adapters/publishers/isbn-publisher-codes.d.ts +21 -0
  8. package/dist/adapters/publishers/isbn-publisher-codes.d.ts.map +1 -0
  9. package/dist/adapters/publishers/isbn-publisher-codes.js +49 -0
  10. package/dist/adapters/publishers/isbn-publisher-codes.js.map +1 -0
  11. package/dist/adapters/publishers/juse-p.d.ts +3 -0
  12. package/dist/adapters/publishers/juse-p.d.ts.map +1 -0
  13. package/dist/adapters/publishers/juse-p.js +110 -0
  14. package/dist/adapters/publishers/juse-p.js.map +1 -0
  15. package/dist/adapters/publishers/registry.d.ts.map +1 -1
  16. package/dist/adapters/publishers/registry.js +4 -0
  17. package/dist/adapters/publishers/registry.js.map +1 -1
  18. package/dist/application/get-book-by-isbn.d.ts +3 -2
  19. package/dist/application/get-book-by-isbn.d.ts.map +1 -1
  20. package/dist/application/get-book-by-isbn.js +22 -3
  21. package/dist/application/get-book-by-isbn.js.map +1 -1
  22. package/dist/config/credentials.d.ts +8 -0
  23. package/dist/config/credentials.d.ts.map +1 -0
  24. package/dist/config/credentials.js +32 -0
  25. package/dist/config/credentials.js.map +1 -0
  26. package/dist/main.js +15 -1
  27. package/dist/main.js.map +1 -1
  28. package/dist/setup.d.ts +2 -0
  29. package/dist/setup.d.ts.map +1 -0
  30. package/dist/setup.js +43 -0
  31. package/dist/setup.js.map +1 -0
  32. package/flake.lock +61 -0
  33. package/package.json +1 -1
  34. package/.claude/settings.local.json +0 -38
  35. package/.codex/skills/techbook-mcp-release-prep/SKILL.md +0 -105
  36. package/.github/workflows/test.yml +0 -72
  37. package/.oxlintrc.json +0 -12
  38. package/AGENTS.md +0 -100
  39. package/deno.json +0 -3
  40. package/src/adapters/cache/memory-cache.ts +0 -31
  41. package/src/adapters/cache/null-cache.ts +0 -8
  42. package/src/adapters/calil.ts +0 -57
  43. package/src/adapters/html/cheerio-parser.ts +0 -50
  44. package/src/adapters/http/fetch-client.ts +0 -47
  45. package/src/adapters/http/mock-client.ts +0 -77
  46. package/src/adapters/openbd.ts +0 -142
  47. package/src/adapters/publishers/base.ts +0 -279
  48. package/src/adapters/publishers/book-tech.ts +0 -117
  49. package/src/adapters/publishers/born-digital.ts +0 -143
  50. package/src/adapters/publishers/coronasha.ts +0 -139
  51. package/src/adapters/publishers/gihyo.ts +0 -120
  52. package/src/adapters/publishers/impress.ts +0 -103
  53. package/src/adapters/publishers/lambdanote.ts +0 -146
  54. package/src/adapters/publishers/manatee.ts +0 -113
  55. package/src/adapters/publishers/maruzen-publishing.ts +0 -129
  56. package/src/adapters/publishers/optronics.ts +0 -113
  57. package/src/adapters/publishers/oreilly-japan.ts +0 -133
  58. package/src/adapters/publishers/peaks.ts +0 -98
  59. package/src/adapters/publishers/personal-media.ts +0 -168
  60. package/src/adapters/publishers/registry.ts +0 -38
  61. package/src/adapters/publishers/rutles.ts +0 -149
  62. package/src/adapters/publishers/saiensu.ts +0 -136
  63. package/src/adapters/publishers/seshop.ts +0 -121
  64. package/src/adapters/publishers/tatsu-zine.ts +0 -142
  65. package/src/adapters/publishers/techbookfest.ts +0 -179
  66. package/src/application/get-book-by-isbn.ts +0 -50
  67. package/src/application/get-book-detail.ts +0 -40
  68. package/src/application/search-books.ts +0 -64
  69. package/src/domain/book.ts +0 -35
  70. package/src/domain/publisher.ts +0 -18
  71. package/src/main.ts +0 -14
  72. package/src/mcp/server.ts +0 -113
  73. package/src/mcp/tools.ts +0 -71
  74. package/src/ports/cache.ts +0 -5
  75. package/src/ports/html-parser.ts +0 -15
  76. package/src/ports/http.ts +0 -17
  77. package/tests/fixtures/book-tech-detail.html +0 -51
  78. package/tests/fixtures/book-tech-search.html +0 -91
  79. package/tests/fixtures/born-digital-detail.html +0 -62
  80. package/tests/fixtures/born-digital-search.html +0 -51
  81. package/tests/fixtures/calil-book.html +0 -987
  82. package/tests/fixtures/coronasha-detail.html +0 -41
  83. package/tests/fixtures/coronasha-search.html +0 -61
  84. package/tests/fixtures/gihyo-detail.html +0 -42
  85. package/tests/fixtures/gihyo-search.json +0 -54
  86. package/tests/fixtures/impress-detail-epub.html +0 -746
  87. package/tests/fixtures/impress-detail-social.html +0 -689
  88. package/tests/fixtures/lambdanote-search.html +0 -66
  89. package/tests/fixtures/manatee-detail.html +0 -53
  90. package/tests/fixtures/manatee-search.html +0 -59
  91. package/tests/fixtures/maruzen-detail.html +0 -51
  92. package/tests/fixtures/maruzen-search.html +0 -60
  93. package/tests/fixtures/openbd-response.json +0 -110
  94. package/tests/fixtures/optronics-detail.html +0 -30
  95. package/tests/fixtures/optronics-search.html +0 -75
  96. package/tests/fixtures/oreilly-detail.html +0 -52
  97. package/tests/fixtures/oreilly-ebook-list.html +0 -53
  98. package/tests/fixtures/peaks-detail.html +0 -39
  99. package/tests/fixtures/peaks-top.html +0 -50
  100. package/tests/fixtures/personal-media-detail.html +0 -32
  101. package/tests/fixtures/personal-media-search.html +0 -39
  102. package/tests/fixtures/rutles-detail.html +0 -32
  103. package/tests/fixtures/rutles-search.html +0 -62
  104. package/tests/fixtures/saiensu-detail.html +0 -41
  105. package/tests/fixtures/saiensu-search.html +0 -65
  106. package/tests/fixtures/seshop-detail.html +0 -45
  107. package/tests/fixtures/seshop-search.html +0 -58
  108. package/tests/fixtures/tatsu-zine-detail-free.html +0 -24
  109. package/tests/fixtures/tatsu-zine-search.html +0 -40
  110. package/tests/fixtures/techbookfest-search.json +0 -73
  111. package/tests/unit/adapters/base.test.ts +0 -441
  112. package/tests/unit/adapters/calil.test.ts +0 -69
  113. package/tests/unit/adapters/openbd.test.ts +0 -185
  114. package/tests/unit/adapters/publishers/book-tech.test.ts +0 -186
  115. package/tests/unit/adapters/publishers/born-digital.test.ts +0 -194
  116. package/tests/unit/adapters/publishers/coronasha.test.ts +0 -207
  117. package/tests/unit/adapters/publishers/gihyo.test.ts +0 -137
  118. package/tests/unit/adapters/publishers/impress.test.ts +0 -129
  119. package/tests/unit/adapters/publishers/lambdanote.test.ts +0 -85
  120. package/tests/unit/adapters/publishers/manatee.test.ts +0 -165
  121. package/tests/unit/adapters/publishers/maruzen-publishing.test.ts +0 -179
  122. package/tests/unit/adapters/publishers/optronics.test.ts +0 -208
  123. package/tests/unit/adapters/publishers/oreilly-japan.test.ts +0 -194
  124. package/tests/unit/adapters/publishers/peaks.test.ts +0 -177
  125. package/tests/unit/adapters/publishers/personal-media.test.ts +0 -199
  126. package/tests/unit/adapters/publishers/rutles.test.ts +0 -173
  127. package/tests/unit/adapters/publishers/saiensu.test.ts +0 -169
  128. package/tests/unit/adapters/publishers/seshop.test.ts +0 -174
  129. package/tests/unit/adapters/publishers/tatsu-zine.test.ts +0 -172
  130. package/tests/unit/adapters/publishers/techbookfest.test.ts +0 -94
  131. package/tests/unit/adapters/registry.test.ts +0 -37
  132. package/tests/unit/application/get-book-by-isbn.test.ts +0 -176
  133. package/tests/unit/application/get-book-detail.test.ts +0 -102
  134. package/tests/unit/application/search-books.test.ts +0 -137
  135. package/tsconfig.json +0 -17
package/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.4] - 2026-04-19
11
+
12
+ ### Added
13
+
14
+ - 日科技連出版社 (`juse-p`) アダプターを追加
15
+ - Google Books アダプター (`google-books`) を追加(APIキー未設定時は無効化)
16
+ - `techbook-mcp setup` コマンドを追加: Google Books API キーを対話入力し OS 固有の設定ディレクトリに保存
17
+ - Linux: `$XDG_CONFIG_HOME/techbook-mcp/credentials.json`
18
+ - macOS: `~/Library/Application Support/techbook-mcp/credentials.json`
19
+ - Windows: `%APPDATA%\techbook-mcp\credentials.json`
20
+ - ISBN出版者記号から出版社アダプターを特定するマッピング (`PUBLISHER_ISBN_CODES`) を追加(13出版社)
21
+ - `get_book_by_isbn` が openBD の storelink に加え、ISBN出版者記号からも対応アダプターを特定して出版社サイトから直接取得を試みるよう改善
22
+
10
23
  ## [0.2.3] - 2026-04-13
11
24
 
12
25
  ### Added
@@ -47,7 +60,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
47
60
 
48
61
  - テストを vitest から `node:test` + `node:assert` に移行(Node.js・Bun・Deno で共通実行可能に)
49
62
 
50
- [Unreleased]: https://github.com/zonuexe/techbook-mcp/compare/v0.2.3...HEAD
63
+ [Unreleased]: https://github.com/zonuexe/techbook-mcp/compare/v0.2.4...HEAD
64
+ [0.2.4]: https://github.com/zonuexe/techbook-mcp/compare/v0.2.3...v0.2.4
51
65
  [0.2.3]: https://github.com/zonuexe/techbook-mcp/compare/v0.2.2...v0.2.3
52
66
  [0.2.2]: https://github.com/zonuexe/techbook-mcp/compare/v0.2.1...v0.2.2
53
67
  [0.2.1]: https://github.com/zonuexe/techbook-mcp/compare/v0.2.0...v0.2.1
package/README.md CHANGED
@@ -60,26 +60,45 @@ Claude が `get_book_detail` ツールで著者・価格・ISBN・購入可能
60
60
 
61
61
  Claude が `list_publishers` ツールを呼び出し、出版社名と ID の一覧を返します。
62
62
 
63
- ## 対応出版社
64
-
65
- | 出版社 | ID |
66
- |--------|-----|
67
- | BOOK TECH | `book-tech` |
68
- | ボーンデジタル | `born-digital` |
69
- | コロナ社 | `coronasha` |
70
- | 技術評論社 | `gihyo` |
71
- | ラムダノート | `lambdanote` |
72
- | マナティ(マイナビ出版直販) | `manatee` |
73
- | 丸善出版 | `maruzen-publishing` |
74
- | オプトロニクス社 | `optronics` |
75
- | オライリー・ジャパン | `oreilly-japan` |
76
- | PEAKS | `peaks` |
77
- | パーソナルメディア | `personal-media` |
78
- | ラトルズ | `rutles` |
79
- | サイエンス社 | `saiensu` |
80
- | SEshop(翔泳社) | `seshop` |
81
- | 達人出版会 | `tatsu-zine` |
82
- | 技術書典オンラインマーケット | `techbookfest` |
63
+ ## 対応ソース
64
+
65
+ ### 出版社・書店
66
+
67
+ `publisher` パラメータに ID を指定すると、その出版社のみを検索できます。
68
+
69
+ | 出版社・書店 | ID | ISBN出版者記号 | 取得方式 |
70
+ |---|---|---|---|
71
+ | BOOK TECH | `book-tech` | — | HTML scraping |
72
+ | ボーンデジタル | `born-digital` | `86246` | HTML scraping (EUC-JP) |
73
+ | コロナ社 | `coronasha` | `339` | HTML scraping |
74
+ | 技術評論社 | `gihyo` | `297` | JSON API |
75
+ | インプレスブックス | `impress-books` | `8443` | HTML scraping |
76
+ | 日科技連出版社 | `juse-p` | `8171` | HTML scraping |
77
+ | ラムダノート | `lambdanote` | `908686` | HTML scraping (Shopify) |
78
+ | マナティ(マイナビ出版直販) | `manatee` | `8399` | HTML scraping |
79
+ | 丸善出版 | `maruzen-publishing` | `621` | HTML scraping |
80
+ | オプトロニクス社 | `optronics` | `902312` | HTML scraping |
81
+ | オライリー・ジャパン | `oreilly-japan` | `8144` | HTML scraping (ローカルフィルタ) |
82
+ | PEAKS | `peaks` | — | HTML scraping (ローカルフィルタ) |
83
+ | パーソナルメディア | `personal-media` | `89362` | HTML scraping (ローカルフィルタ) |
84
+ | ラトルズ | `rutles` | `89977` | HTML scraping (EUC-JP) |
85
+ | サイエンス社 | `saiensu` | `7819` | HTML scraping |
86
+ | SEshop(翔泳社) | `seshop` | `7981` | HTML scraping |
87
+ | 達人出版会 | `tatsu-zine` | — | HTML scraping |
88
+ | 技術書典オンラインマーケット | `techbookfest` | — | GraphQL API |
89
+
90
+ ISBN出版者記号(`978-4-XXXXX-...` の `XXXXX` 部分)が登録されている出版社は、ISBNだけで直接検索できます。
91
+ 「—」は電子書籍専業・同人誌マーケット等でISBN出版者記号を持たないソースです。
92
+
93
+ ### 外部 API・データソース
94
+
95
+ | サービス | ID | 用途 | 備考 |
96
+ |---|---|---|---|
97
+ | Google Books | `google-books` | 横断検索 | APIキー必須(`techbook-mcp setup` で設定) |
98
+ | [openBD](https://openbd.jp/) | — | ISBN検索のバックボーン | 自動使用・設定不要 |
99
+ | [カーリル](https://calil.jp/) | — | openBDにない書籍のフォールバック | 自動使用・設定不要 |
100
+
101
+ **openBD** は `get_book_by_isbn` ツールで常に参照される書誌情報データベースです。ISBN で書籍を検索すると、まず openBD から書誌情報・出版社ストアリンクを取得し、対応する出版社アダプターがあればそのサイトから詳細情報を補完します。openBD にない書籍(絶版・廃業出版社など)はカーリルにフォールバックします。
83
102
 
84
103
  ## MCPツール
85
104
 
@@ -0,0 +1,4 @@
1
+ import type { PublisherAdapter } from "../../domain/publisher.js";
2
+ export declare function makeGoogleBooksAdapter(apiKey?: string): PublisherAdapter;
3
+ export declare const googleBooksAdapter: PublisherAdapter;
4
+ //# sourceMappingURL=google-books.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-books.d.ts","sourceRoot":"","sources":["../../../src/adapters/publishers/google-books.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,2BAA2B,CAAC;AA8DjF,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,gBAAgB,CA4CxE;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAA2C,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { fetchText } from "./base.js";
2
+ const API_BASE = "https://www.googleapis.com/books/v1";
3
+ const INFO_BASE = "https://books.google.com";
4
+ function toHttps(url) {
5
+ return url.replace(/^http:\/\//, "https://");
6
+ }
7
+ function parsePublishedDate(raw) {
8
+ const parts = raw.split("-");
9
+ if (parts.length >= 3)
10
+ return raw.slice(0, 10);
11
+ if (parts.length === 2)
12
+ return `${parts[0]}-${parts[1]}-01`;
13
+ return `${parts[0]}-01-01`;
14
+ }
15
+ function volumeToBookRecord(vol) {
16
+ const info = vol.volumeInfo;
17
+ const isbn13 = info.industryIdentifiers?.find(id => id.type === "ISBN_13")?.identifier;
18
+ const price = vol.saleInfo?.listPrice?.currencyCode === "JPY"
19
+ ? Math.round(vol.saleInfo.listPrice.amount)
20
+ : undefined;
21
+ const url = toHttps(info.infoLink ?? `${INFO_BASE}/books?id=${vol.id}`);
22
+ return {
23
+ title: info.title,
24
+ authors: info.authors ?? [],
25
+ publisher: info.publisher ?? "",
26
+ publishedAt: info.publishedDate ? parsePublishedDate(info.publishedDate) : undefined,
27
+ isbn: isbn13,
28
+ url,
29
+ price,
30
+ coverImageUrl: info.imageLinks?.thumbnail ? toHttps(info.imageLinks.thumbnail) : undefined,
31
+ description: info.description,
32
+ };
33
+ }
34
+ export function makeGoogleBooksAdapter(apiKey) {
35
+ // env アクセスはメソッド呼び出し時に遅延評価する。
36
+ // モジュールロード時に読むと Deno が --allow-env なしで権限エラーになる。
37
+ const resolveKey = () => apiKey ?? process.env.GOOGLE_BOOKS_API_KEY ?? "";
38
+ return {
39
+ id: "google-books",
40
+ name: "Google Books",
41
+ baseUrl: INFO_BASE,
42
+ async search(query, deps) {
43
+ const key = resolveKey();
44
+ if (!key)
45
+ return [];
46
+ const word = [query.title, query.author].filter(Boolean).join(" ");
47
+ if (!word)
48
+ return [];
49
+ const limit = Math.min(query.limit ?? 10, 40);
50
+ const params = new URLSearchParams({
51
+ q: word,
52
+ langRestrict: "ja",
53
+ maxResults: String(limit),
54
+ key,
55
+ });
56
+ const text = await fetchText(`${API_BASE}/volumes?${params}`, deps);
57
+ const data = JSON.parse(text);
58
+ return (data.items ?? []).map(volumeToBookRecord);
59
+ },
60
+ async getDetail(url, deps) {
61
+ const key = resolveKey();
62
+ if (!key)
63
+ throw new Error("GOOGLE_BOOKS_API_KEY が設定されていません");
64
+ const idMatch = url.match(/[?&]id=([^&]+)/);
65
+ if (!idMatch)
66
+ throw new Error(`URLからボリュームIDを取得できません: ${url}`);
67
+ const volumeId = idMatch[1];
68
+ const text = await fetchText(`${API_BASE}/volumes/${volumeId}?key=${key}`, deps);
69
+ const vol = JSON.parse(text);
70
+ return volumeToBookRecord(vol);
71
+ },
72
+ };
73
+ }
74
+ export const googleBooksAdapter = makeGoogleBooksAdapter();
75
+ //# sourceMappingURL=google-books.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-books.js","sourceRoot":"","sources":["../../../src/adapters/publishers/google-books.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 日本のISBN出版者記号 (978-4-XXXXX-...) とアダプターIDの対応表。
3
+ *
4
+ * ISBN出版者記号は978-4-(グループ識別子)に続くXXXXXの部分。
5
+ * 桁数はJPOの範囲規定(3桁: 200-699、4桁: 7000-8499、
6
+ * 5桁: 85000-89999、6桁: 900000-949999)による。
7
+ *
8
+ * 出典: JPO登録出版者照会 https://isbn.jpo.or.jp/index.php/fix__ref_pub/
9
+ * および各出版社公式サイト・版元ドットコムにて確認済み(2026-04-19)。
10
+ *
11
+ * 電子書籍専業(達人出版会・PEAKS)や
12
+ * 書店プラットフォーム(BOOK TECH・技術書典)はISBN出版者記号なし。
13
+ */
14
+ /** アダプターIDとISBN出版者記号の対応。複数記号を持つ出版社は配列で列挙。 */
15
+ export declare const PUBLISHER_ISBN_CODES: ReadonlyMap<string, readonly string[]>;
16
+ /**
17
+ * ISBN-13に対応するアダプターIDを返す。
18
+ * 例: "9784297128152" → "gihyo"
19
+ */
20
+ export declare function findAdapterIdByIsbn(isbn13: string): string | undefined;
21
+ //# sourceMappingURL=isbn-publisher-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isbn-publisher-codes.d.ts","sourceRoot":"","sources":["../../../src/adapters/publishers/isbn-publisher-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAetE,CAAC;AAEH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYtE"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 日本のISBN出版者記号 (978-4-XXXXX-...) とアダプターIDの対応表。
3
+ *
4
+ * ISBN出版者記号は978-4-(グループ識別子)に続くXXXXXの部分。
5
+ * 桁数はJPOの範囲規定(3桁: 200-699、4桁: 7000-8499、
6
+ * 5桁: 85000-89999、6桁: 900000-949999)による。
7
+ *
8
+ * 出典: JPO登録出版者照会 https://isbn.jpo.or.jp/index.php/fix__ref_pub/
9
+ * および各出版社公式サイト・版元ドットコムにて確認済み(2026-04-19)。
10
+ *
11
+ * 電子書籍専業(達人出版会・PEAKS)や
12
+ * 書店プラットフォーム(BOOK TECH・技術書典)はISBN出版者記号なし。
13
+ */
14
+ /** アダプターIDとISBN出版者記号の対応。複数記号を持つ出版社は配列で列挙。 */
15
+ export const PUBLISHER_ISBN_CODES = new Map([
16
+ ["coronasha", ["339"]],
17
+ ["maruzen-publishing", ["621"]],
18
+ ["gihyo", ["297"]],
19
+ ["saiensu", ["7819"]],
20
+ ["seshop", ["7981"]],
21
+ ["oreilly-japan", ["8144"]],
22
+ ["juse-p", ["8171"]],
23
+ ["impress-books", ["8443"]],
24
+ ["born-digital", ["86246"]],
25
+ ["personal-media", ["89362"]],
26
+ ["rutles", ["89977"]],
27
+ ["manatee", ["8399"]],
28
+ ["lambdanote", ["908686"]],
29
+ ["optronics", ["902312"]],
30
+ ]);
31
+ /**
32
+ * ISBN-13に対応するアダプターIDを返す。
33
+ * 例: "9784297128152" → "gihyo"
34
+ */
35
+ export function findAdapterIdByIsbn(isbn13) {
36
+ const raw = isbn13.replace(/-/g, "");
37
+ if (!raw.startsWith("9784"))
38
+ return undefined;
39
+ // 9784 の次から始まる出版者記号候補を長さ順(長い方優先)でチェック
40
+ for (const [adapterId, codes] of PUBLISHER_ISBN_CODES) {
41
+ for (const code of codes) {
42
+ if (raw.startsWith(`9784${code}`)) {
43
+ return adapterId;
44
+ }
45
+ }
46
+ }
47
+ return undefined;
48
+ }
49
+ //# sourceMappingURL=isbn-publisher-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isbn-publisher-codes.js","sourceRoot":"","sources":["../../../src/adapters/publishers/isbn-publisher-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,oBAAoB,GAA2C,IAAI,GAAG,CAAC;IAClF,CAAC,WAAW,EAAU,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,oBAAoB,EAAC,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,OAAO,EAAc,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,SAAS,EAAY,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,QAAQ,EAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,eAAe,EAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,QAAQ,EAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,eAAe,EAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,cAAc,EAAO,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC,gBAAgB,EAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC,QAAQ,EAAa,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC,SAAS,EAAY,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,YAAY,EAAS,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC,WAAW,EAAU,CAAC,QAAQ,CAAC,CAAC;CAClC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,sCAAsC;IACtC,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,oBAAoB,EAAE,CAAC;QACtD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;gBAClC,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PublisherAdapter } from "../../domain/publisher.js";
2
+ export declare const jusePAdapter: PublisherAdapter;
3
+ //# sourceMappingURL=juse-p.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"juse-p.d.ts","sourceRoot":"","sources":["../../../src/adapters/publishers/juse-p.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,2BAA2B,CAAC;AAmCjF,eAAO,MAAM,YAAY,EAAE,gBAyF1B,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { fetchText, parseJapanesePrice, resolveUrl } from "./base.js";
2
+ const BASE_URL = "https://www.juse-p.co.jp";
3
+ const SEARCH_URL = `${BASE_URL}/products`;
4
+ /**
5
+ * "武藤佳恭[監修]、和田尚之[著]" → ["武藤佳恭", "和田尚之"]
6
+ * 著者テキストから役割語([著][監修]等)を除去して名前リストを返す。
7
+ */
8
+ function parseAuthors(text) {
9
+ return text.split(/[、,]/)
10
+ .map(s => s.replace(/\[.*?\]/g, "").trim())
11
+ .filter(Boolean);
12
+ }
13
+ /** "ISBN978-4-8171-9818-1" → "9784817198181" */
14
+ function parseIsbn(text) {
15
+ const m = text.match(/[\d-]{13,}/);
16
+ return m ? m[0].replace(/-/g, "") : undefined;
17
+ }
18
+ /**
19
+ * h2.c-ttl-02 のテキストから書籍名とサブタイトルを取り出す。
20
+ * 【カテゴリラベル】は除外する。
21
+ * 例: "【コレクション】\n\tPython入門\n\t機械学習の基礎" → ["Python入門", "機械学習の基礎"]
22
+ */
23
+ function parseTitleParts(text) {
24
+ return text
25
+ .split(/\n/)
26
+ .map(s => s.trim())
27
+ .filter(s => s && !/^【.*】$/.test(s));
28
+ }
29
+ export const jusePAdapter = {
30
+ id: "juse-p",
31
+ name: "日科技連出版社",
32
+ baseUrl: BASE_URL,
33
+ async search(query, deps) {
34
+ const keyword = [query.title, query.author].filter(Boolean).join(" ");
35
+ if (!keyword)
36
+ return [];
37
+ const url = `${SEARCH_URL}?k=${encodeURIComponent(keyword)}`;
38
+ const html = await fetchText(url, deps);
39
+ const doc = deps.parser.parse(html);
40
+ const results = [];
41
+ const limit = query.limit ?? 10;
42
+ for (const item of doc.select(".product-col")) {
43
+ const linkEl = item.find("div.title h4 a")[0];
44
+ const href = linkEl?.attr("href");
45
+ if (!href)
46
+ continue;
47
+ const title = linkEl.text().trim();
48
+ if (!title)
49
+ continue;
50
+ const bookUrl = resolveUrl(BASE_URL, href);
51
+ const imgEl = item.find("div.image img")[0];
52
+ const coverSrc = imgEl?.attr("src");
53
+ const coverImageUrl = coverSrc ? resolveUrl(BASE_URL, coverSrc) : undefined;
54
+ results.push({
55
+ title,
56
+ authors: [],
57
+ publisher: "日科技連出版社",
58
+ url: bookUrl,
59
+ coverImageUrl,
60
+ ebookStores: [],
61
+ });
62
+ if (results.length >= limit)
63
+ break;
64
+ }
65
+ return results;
66
+ },
67
+ async getDetail(url, deps) {
68
+ const html = await fetchText(url, deps);
69
+ const doc = deps.parser.parse(html);
70
+ // h2.c-ttl-02 に【カテゴリ】・書籍名・サブタイトルが <br> 区切りで入る
71
+ const h2 = doc.selectOne("h2.c-ttl-02");
72
+ const titleParts = parseTitleParts(h2?.text() ?? "");
73
+ const title = titleParts.join(" ");
74
+ // .product-details ul li をパターンで分類
75
+ const lis = doc.select(".product-details ul li");
76
+ let authors = [];
77
+ let price;
78
+ let isbn;
79
+ for (const li of lis) {
80
+ const text = li.text();
81
+ if (/^定価/.test(text)) {
82
+ price = parseJapanesePrice(text);
83
+ }
84
+ else if (/^ISBN/.test(text)) {
85
+ isbn = parseIsbn(text);
86
+ }
87
+ else if (/^[A-Z][0-9]//.test(text) || /在庫|品切/.test(text)) {
88
+ // 判型・ページ数 または 在庫状況 → スキップ
89
+ }
90
+ else if (authors.length === 0) {
91
+ authors = parseAuthors(text);
92
+ }
93
+ }
94
+ const imgEl = doc.selectOne(".images-block img");
95
+ const coverSrc = imgEl?.attr("src");
96
+ const coverImageUrl = coverSrc ? resolveUrl(BASE_URL, coverSrc) : undefined;
97
+ return {
98
+ title,
99
+ authors,
100
+ publisher: "日科技連出版社",
101
+ url,
102
+ isbn,
103
+ price,
104
+ coverImageUrl,
105
+ // Amazon・楽天等のリンクは紙書籍向けのため電子書籍ストアとして扱わない
106
+ ebookStores: [],
107
+ };
108
+ },
109
+ };
110
+ //# sourceMappingURL=juse-p.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"juse-p.js","sourceRoot":"","sources":["../../../src/adapters/publishers/juse-p.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/publishers/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAmBlE,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAkBzD,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/publishers/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAqBlE,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAoBzD,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { bookTechAdapter } from "./book-tech.js";
2
+ import { googleBooksAdapter } from "./google-books.js";
2
3
  import { bornDigitalAdapter } from "./born-digital.js";
3
4
  import { coronashaAdapter } from "./coronasha.js";
4
5
  import { gihyoAdapter } from "./gihyo.js";
5
6
  import { impressBooksAdapter } from "./impress.js";
7
+ import { jusePAdapter } from "./juse-p.js";
6
8
  import { lambdanoteAdapter } from "./lambdanote.js";
7
9
  import { manateeAdapter } from "./manatee.js";
8
10
  import { maruzenPublishingAdapter } from "./maruzen-publishing.js";
@@ -21,6 +23,7 @@ export const DEFAULT_PUBLISHERS = [
21
23
  coronashaAdapter,
22
24
  gihyoAdapter,
23
25
  impressBooksAdapter,
26
+ jusePAdapter,
24
27
  lambdanoteAdapter,
25
28
  manateeAdapter,
26
29
  maruzenPublishingAdapter,
@@ -33,5 +36,6 @@ export const DEFAULT_PUBLISHERS = [
33
36
  seshopAdapter,
34
37
  tatsuZineAdapter,
35
38
  techbookfestAdapter,
39
+ googleBooksAdapter,
36
40
  ];
37
41
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/adapters/publishers/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,MAAM,kBAAkB,GAAgC;IAC7D,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,wBAAwB;IACxB,gBAAgB;IAChB,mBAAmB;IACnB,YAAY;IACZ,oBAAoB;IACpB,aAAa;IACb,cAAc;IACd,aAAa;IACb,gBAAgB;IAChB,mBAAmB;CACpB,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/adapters/publishers/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,MAAM,kBAAkB,GAAgC;IAC7D,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,mBAAmB;IACnB,YAAY;IACZ,iBAAiB;IACjB,cAAc;IACd,wBAAwB;IACxB,gBAAgB;IAChB,mBAAmB;IACnB,YAAY;IACZ,oBAAoB;IACpB,aAAa;IACb,cAAc;IACd,aAAa;IACb,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;CACnB,CAAC"}
@@ -5,8 +5,9 @@ import type { PublisherAdapter, PublisherDeps } from "../domain/publisher.js";
5
5
  *
6
6
  * 1. openBD で書誌情報と出版社ストアリンクを取得する
7
7
  * 2. ストアリンクが既知アダプターと一致する場合は出版社サイトから詳細取得を試みる
8
- * 3. 取得できない場合は openBD データをそのまま返す
9
- * 4. openBD にも存在しない場合はカーリルから書誌情報を取得する(廃業出版社など)
8
+ * 3. ISBN出版者記号から対応アダプターを特定し、出版社サイトで検索して詳細取得を試みる
9
+ * 4. 取得できない場合は openBD データをそのまま返す
10
+ * 5. openBD にも存在しない場合はカーリルから書誌情報を取得する(廃業出版社など)
10
11
  */
11
12
  export declare function getBookByIsbn(isbn: string, publishers: readonly PublisherAdapter[], deps: PublisherDeps): Promise<BookRecord>;
12
13
  //# sourceMappingURL=get-book-by-isbn.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-book-by-isbn.d.ts","sourceRoot":"","sources":["../../src/application/get-book-by-isbn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK9E;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,SAAS,gBAAgB,EAAE,EACvC,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,UAAU,CAAC,CA+BrB"}
1
+ {"version":3,"file":"get-book-by-isbn.d.ts","sourceRoot":"","sources":["../../src/application/get-book-by-isbn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAM9E;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,SAAS,gBAAgB,EAAE,EACvC,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,UAAU,CAAC,CA+CrB"}
@@ -1,13 +1,15 @@
1
1
  import { checkRobotsTxt } from "../adapters/publishers/base.js";
2
2
  import { fetchOpenBDBooks, openBDEntryToBookRecord } from "../adapters/openbd.js";
3
3
  import { fetchCalilBook } from "../adapters/calil.js";
4
+ import { findAdapterIdByIsbn } from "../adapters/publishers/isbn-publisher-codes.js";
4
5
  /**
5
6
  * ISBNから書籍情報を取得する。
6
7
  *
7
8
  * 1. openBD で書誌情報と出版社ストアリンクを取得する
8
9
  * 2. ストアリンクが既知アダプターと一致する場合は出版社サイトから詳細取得を試みる
9
- * 3. 取得できない場合は openBD データをそのまま返す
10
- * 4. openBD にも存在しない場合はカーリルから書誌情報を取得する(廃業出版社など)
10
+ * 3. ISBN出版者記号から対応アダプターを特定し、出版社サイトで検索して詳細取得を試みる
11
+ * 4. 取得できない場合は openBD データをそのまま返す
12
+ * 5. openBD にも存在しない場合はカーリルから書誌情報を取得する(廃業出版社など)
11
13
  */
12
14
  export async function getBookByIsbn(isbn, publishers, deps) {
13
15
  const normalizedIsbn = isbn.replace(/-/g, "");
@@ -32,11 +34,28 @@ export async function getBookByIsbn(isbn, publishers, deps) {
32
34
  return await publisher.getDetail(storelink, deps);
33
35
  }
34
36
  catch {
35
- // 出版社サイトからの取得失敗は無視して openBD データで返す
37
+ // 出版社サイトからの取得失敗は無視して次のフォールバックへ
36
38
  }
37
39
  }
38
40
  }
39
41
  }
42
+ // ISBN出版者記号から対応アダプターを特定し、出版社サイトで検索する
43
+ const adapterId = findAdapterIdByIsbn(normalizedIsbn);
44
+ if (adapterId) {
45
+ const publisher = publishers.find(p => p.id === adapterId);
46
+ if (publisher) {
47
+ try {
48
+ const results = await publisher.search({ title: normalizedIsbn, limit: 5 }, deps);
49
+ const matched = results.find(r => r.isbn && r.isbn.replace(/-/g, "") === normalizedIsbn)
50
+ ?? results[0];
51
+ if (matched)
52
+ return matched;
53
+ }
54
+ catch {
55
+ // 出版社サイトからの取得失敗は無視して openBD データで返す
56
+ }
57
+ }
58
+ }
40
59
  return openBDEntryToBookRecord(entry);
41
60
  }
42
61
  //# sourceMappingURL=get-book-by-isbn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-book-by-isbn.js","sourceRoot":"","sources":["../../src/application/get-book-by-isbn.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,UAAuC,EACvC,IAAmB;IAEnB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,2CAA2C;QAC3C,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,iDAAiD;IACjD,mBAAmB;IACnB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACxE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACH,OAAO,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACpD,CAAC;gBAAC,MAAM,CAAC;oBACP,mCAAmC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"get-book-by-isbn.js","sourceRoot":"","sources":["../../src/application/get-book-by-isbn.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AAErF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,UAAuC,EACvC,IAAmB;IAEnB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,2CAA2C;QAC3C,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,iDAAiD;IACjD,mBAAmB;IACnB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACxE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACH,OAAO,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACpD,CAAC;gBAAC,MAAM,CAAC;oBACP,+BAA+B;gBACjC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,MAAM,SAAS,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;IACtD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAClF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,cAAc,CAAC;uBACnF,OAAO,CAAC,CAAC,CAAC,CAAC;gBAChB,IAAI,OAAO;oBAAE,OAAO,OAAO,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface Credentials {
2
+ googleBooksApiKey?: string;
3
+ }
4
+ export declare function getConfigDir(): string;
5
+ export declare function getCredentialsPath(): string;
6
+ export declare function loadCredentials(): Promise<Credentials>;
7
+ export declare function saveCredentials(creds: Credentials): Promise<void>;
8
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/config/credentials.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,YAAY,IAAI,MAAM,CAUrC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CAO5D;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE"}
@@ -0,0 +1,32 @@
1
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ export function getConfigDir() {
5
+ const { platform, env } = process;
6
+ if (platform === "win32") {
7
+ return join(env["APPDATA"] ?? join(homedir(), "AppData", "Roaming"), "techbook-mcp");
8
+ }
9
+ if (platform === "darwin") {
10
+ return join(homedir(), "Library", "Application Support", "techbook-mcp");
11
+ }
12
+ // Linux / others: XDG Base Directory
13
+ return join(env["XDG_CONFIG_HOME"] ?? join(homedir(), ".config"), "techbook-mcp");
14
+ }
15
+ export function getCredentialsPath() {
16
+ return join(getConfigDir(), "credentials.json");
17
+ }
18
+ export async function loadCredentials() {
19
+ try {
20
+ const text = await readFile(getCredentialsPath(), "utf-8");
21
+ return JSON.parse(text);
22
+ }
23
+ catch {
24
+ return {};
25
+ }
26
+ }
27
+ export async function saveCredentials(creds) {
28
+ const configDir = getConfigDir();
29
+ await mkdir(configDir, { recursive: true });
30
+ await writeFile(getCredentialsPath(), JSON.stringify(creds, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
31
+ }
32
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/config/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMlC,MAAM,UAAU,YAAY;IAC1B,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAClC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,cAAc,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,cAAc,CAAC,CAAC;IAC3E,CAAC;IACD,qCAAqC;IACrC,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,cAAc,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAkB;IACtD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,SAAS,CAAC,kBAAkB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACnH,CAAC"}
package/dist/main.js CHANGED
@@ -1,13 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import { startServer } from "./mcp/server.js";
3
3
  import { DEFAULT_PUBLISHERS } from "./adapters/publishers/registry.js";
4
+ import { makeGoogleBooksAdapter } from "./adapters/publishers/google-books.js";
4
5
  import { FetchHttpClient } from "./adapters/http/fetch-client.js";
5
6
  import { CheerioHtmlParser } from "./adapters/html/cheerio-parser.js";
6
7
  import { MemoryCacheStore } from "./adapters/cache/memory-cache.js";
8
+ import { loadCredentials } from "./config/credentials.js";
9
+ import { runSetup } from "./setup.js";
10
+ const subcommand = process.argv[2];
11
+ if (subcommand === "setup") {
12
+ await runSetup();
13
+ process.exit(0);
14
+ }
15
+ const credentials = await loadCredentials();
16
+ const googleBooksApiKey = process.env["GOOGLE_BOOKS_API_KEY"] ?? credentials.googleBooksApiKey ?? "";
17
+ const publishers = [
18
+ ...DEFAULT_PUBLISHERS.filter(p => p.id !== "google-books"),
19
+ makeGoogleBooksAdapter(googleBooksApiKey),
20
+ ];
7
21
  const deps = {
8
22
  http: new FetchHttpClient(),
9
23
  parser: new CheerioHtmlParser(),
10
24
  cache: new MemoryCacheStore(),
11
25
  };
12
- await startServer(DEFAULT_PUBLISHERS, deps);
26
+ await startServer(publishers, deps);
13
27
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEpE,MAAM,IAAI,GAAG;IACX,IAAI,EAAE,IAAI,eAAe,EAAE;IAC3B,MAAM,EAAE,IAAI,iBAAiB,EAAE;IAC/B,KAAK,EAAE,IAAI,gBAAgB,EAAE;CAC9B,CAAC;AAEF,MAAM,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;IAC3B,MAAM,QAAQ,EAAE,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;AAC5C,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,WAAW,CAAC,iBAAiB,IAAI,EAAE,CAAC;AAErG,MAAM,UAAU,GAAG;IACjB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC;IAC1D,sBAAsB,CAAC,iBAAiB,CAAC;CAC1C,CAAC;AAEF,MAAM,IAAI,GAAG;IACX,IAAI,EAAE,IAAI,eAAe,EAAE;IAC3B,MAAM,EAAE,IAAI,iBAAiB,EAAE;IAC/B,KAAK,EAAE,IAAI,gBAAgB,EAAE;CAC9B,CAAC;AAEF,MAAM,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runSetup(): Promise<void>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAoBA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAgC9C"}