paper-search-cli 0.1.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 (166) hide show
  1. package/.env.example +165 -0
  2. package/LICENSE +21 -0
  3. package/README-sc.md +642 -0
  4. package/README.md +642 -0
  5. package/dist/cli.d.ts +3 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +637 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/config/ConfigService.d.ts +26 -0
  10. package/dist/config/ConfigService.d.ts.map +1 -0
  11. package/dist/config/ConfigService.js +145 -0
  12. package/dist/config/ConfigService.js.map +1 -0
  13. package/dist/config/constants.d.ts +140 -0
  14. package/dist/config/constants.d.ts.map +1 -0
  15. package/dist/config/constants.js +93 -0
  16. package/dist/config/constants.js.map +1 -0
  17. package/dist/core/diagnostics.d.ts +43 -0
  18. package/dist/core/diagnostics.d.ts.map +1 -0
  19. package/dist/core/diagnostics.js +544 -0
  20. package/dist/core/diagnostics.js.map +1 -0
  21. package/dist/core/handleToolCall.d.ts +8 -0
  22. package/dist/core/handleToolCall.d.ts.map +1 -0
  23. package/dist/core/handleToolCall.js +440 -0
  24. package/dist/core/handleToolCall.js.map +1 -0
  25. package/dist/core/schemas.d.ts +454 -0
  26. package/dist/core/schemas.d.ts.map +1 -0
  27. package/dist/core/schemas.js +322 -0
  28. package/dist/core/schemas.js.map +1 -0
  29. package/dist/core/searchers.d.ts +45 -0
  30. package/dist/core/searchers.d.ts.map +1 -0
  31. package/dist/core/searchers.js +73 -0
  32. package/dist/core/searchers.js.map +1 -0
  33. package/dist/core/tools.d.ts +7 -0
  34. package/dist/core/tools.d.ts.map +1 -0
  35. package/dist/core/tools.js +640 -0
  36. package/dist/core/tools.js.map +1 -0
  37. package/dist/models/Paper.d.ts +64 -0
  38. package/dist/models/Paper.d.ts.map +1 -0
  39. package/dist/models/Paper.js +70 -0
  40. package/dist/models/Paper.js.map +1 -0
  41. package/dist/platforms/ArxivSearcher.d.ts +64 -0
  42. package/dist/platforms/ArxivSearcher.d.ts.map +1 -0
  43. package/dist/platforms/ArxivSearcher.js +531 -0
  44. package/dist/platforms/ArxivSearcher.js.map +1 -0
  45. package/dist/platforms/BioRxivSearcher.d.ts +47 -0
  46. package/dist/platforms/BioRxivSearcher.d.ts.map +1 -0
  47. package/dist/platforms/BioRxivSearcher.js +196 -0
  48. package/dist/platforms/BioRxivSearcher.js.map +1 -0
  49. package/dist/platforms/CORESearcher.d.ts +16 -0
  50. package/dist/platforms/CORESearcher.d.ts.map +1 -0
  51. package/dist/platforms/CORESearcher.js +148 -0
  52. package/dist/platforms/CORESearcher.js.map +1 -0
  53. package/dist/platforms/CrossrefSearcher.d.ts +34 -0
  54. package/dist/platforms/CrossrefSearcher.d.ts.map +1 -0
  55. package/dist/platforms/CrossrefSearcher.js +339 -0
  56. package/dist/platforms/CrossrefSearcher.js.map +1 -0
  57. package/dist/platforms/EuropePMCSearcher.d.ts +20 -0
  58. package/dist/platforms/EuropePMCSearcher.d.ts.map +1 -0
  59. package/dist/platforms/EuropePMCSearcher.js +173 -0
  60. package/dist/platforms/EuropePMCSearcher.js.map +1 -0
  61. package/dist/platforms/GoogleScholarSearcher.d.ts +77 -0
  62. package/dist/platforms/GoogleScholarSearcher.d.ts.map +1 -0
  63. package/dist/platforms/GoogleScholarSearcher.js +262 -0
  64. package/dist/platforms/GoogleScholarSearcher.js.map +1 -0
  65. package/dist/platforms/IACRSearcher.d.ts +51 -0
  66. package/dist/platforms/IACRSearcher.d.ts.map +1 -0
  67. package/dist/platforms/IACRSearcher.js +339 -0
  68. package/dist/platforms/IACRSearcher.js.map +1 -0
  69. package/dist/platforms/OpenAIRESearcher.d.ts +22 -0
  70. package/dist/platforms/OpenAIRESearcher.d.ts.map +1 -0
  71. package/dist/platforms/OpenAIRESearcher.js +223 -0
  72. package/dist/platforms/OpenAIRESearcher.js.map +1 -0
  73. package/dist/platforms/OpenAlexSearcher.d.ts +14 -0
  74. package/dist/platforms/OpenAlexSearcher.d.ts.map +1 -0
  75. package/dist/platforms/OpenAlexSearcher.js +114 -0
  76. package/dist/platforms/OpenAlexSearcher.js.map +1 -0
  77. package/dist/platforms/PMCSearcher.d.ts +20 -0
  78. package/dist/platforms/PMCSearcher.d.ts.map +1 -0
  79. package/dist/platforms/PMCSearcher.js +177 -0
  80. package/dist/platforms/PMCSearcher.js.map +1 -0
  81. package/dist/platforms/PaperSource.d.ts +143 -0
  82. package/dist/platforms/PaperSource.d.ts.map +1 -0
  83. package/dist/platforms/PaperSource.js +125 -0
  84. package/dist/platforms/PaperSource.js.map +1 -0
  85. package/dist/platforms/PubMedSearcher.d.ts +104 -0
  86. package/dist/platforms/PubMedSearcher.d.ts.map +1 -0
  87. package/dist/platforms/PubMedSearcher.js +422 -0
  88. package/dist/platforms/PubMedSearcher.js.map +1 -0
  89. package/dist/platforms/SciHubSearcher.d.ts +66 -0
  90. package/dist/platforms/SciHubSearcher.d.ts.map +1 -0
  91. package/dist/platforms/SciHubSearcher.js +398 -0
  92. package/dist/platforms/SciHubSearcher.js.map +1 -0
  93. package/dist/platforms/ScienceDirectSearcher.d.ts +42 -0
  94. package/dist/platforms/ScienceDirectSearcher.d.ts.map +1 -0
  95. package/dist/platforms/ScienceDirectSearcher.js +326 -0
  96. package/dist/platforms/ScienceDirectSearcher.js.map +1 -0
  97. package/dist/platforms/ScopusSearcher.d.ts +43 -0
  98. package/dist/platforms/ScopusSearcher.d.ts.map +1 -0
  99. package/dist/platforms/ScopusSearcher.js +364 -0
  100. package/dist/platforms/ScopusSearcher.js.map +1 -0
  101. package/dist/platforms/SemanticScholarSearcher.d.ts +96 -0
  102. package/dist/platforms/SemanticScholarSearcher.d.ts.map +1 -0
  103. package/dist/platforms/SemanticScholarSearcher.js +419 -0
  104. package/dist/platforms/SemanticScholarSearcher.js.map +1 -0
  105. package/dist/platforms/SpringerSearcher.d.ts +54 -0
  106. package/dist/platforms/SpringerSearcher.d.ts.map +1 -0
  107. package/dist/platforms/SpringerSearcher.js +407 -0
  108. package/dist/platforms/SpringerSearcher.js.map +1 -0
  109. package/dist/platforms/UnpaywallSearcher.d.ts +18 -0
  110. package/dist/platforms/UnpaywallSearcher.d.ts.map +1 -0
  111. package/dist/platforms/UnpaywallSearcher.js +115 -0
  112. package/dist/platforms/UnpaywallSearcher.js.map +1 -0
  113. package/dist/platforms/WebOfScienceSearcher.d.ts +111 -0
  114. package/dist/platforms/WebOfScienceSearcher.d.ts.map +1 -0
  115. package/dist/platforms/WebOfScienceSearcher.js +500 -0
  116. package/dist/platforms/WebOfScienceSearcher.js.map +1 -0
  117. package/dist/platforms/WileySearcher.d.ts +44 -0
  118. package/dist/platforms/WileySearcher.d.ts.map +1 -0
  119. package/dist/platforms/WileySearcher.js +148 -0
  120. package/dist/platforms/WileySearcher.js.map +1 -0
  121. package/dist/services/CitationService.d.ts +66 -0
  122. package/dist/services/CitationService.d.ts.map +1 -0
  123. package/dist/services/CitationService.js +237 -0
  124. package/dist/services/CitationService.js.map +1 -0
  125. package/dist/services/MultiSourceSearchService.d.ts +19 -0
  126. package/dist/services/MultiSourceSearchService.d.ts.map +1 -0
  127. package/dist/services/MultiSourceSearchService.js +96 -0
  128. package/dist/services/MultiSourceSearchService.js.map +1 -0
  129. package/dist/services/OpenAccessFallbackService.d.ts +20 -0
  130. package/dist/services/OpenAccessFallbackService.d.ts.map +1 -0
  131. package/dist/services/OpenAccessFallbackService.js +124 -0
  132. package/dist/services/OpenAccessFallbackService.js.map +1 -0
  133. package/dist/utils/ErrorHandler.d.ts +99 -0
  134. package/dist/utils/ErrorHandler.d.ts.map +1 -0
  135. package/dist/utils/ErrorHandler.js +266 -0
  136. package/dist/utils/ErrorHandler.js.map +1 -0
  137. package/dist/utils/Logger.d.ts +6 -0
  138. package/dist/utils/Logger.d.ts.map +1 -0
  139. package/dist/utils/Logger.js +26 -0
  140. package/dist/utils/Logger.js.map +1 -0
  141. package/dist/utils/PDFExtractor.d.ts +34 -0
  142. package/dist/utils/PDFExtractor.d.ts.map +1 -0
  143. package/dist/utils/PDFExtractor.js +130 -0
  144. package/dist/utils/PDFExtractor.js.map +1 -0
  145. package/dist/utils/PdfDownload.d.ts +7 -0
  146. package/dist/utils/PdfDownload.d.ts.map +1 -0
  147. package/dist/utils/PdfDownload.js +52 -0
  148. package/dist/utils/PdfDownload.js.map +1 -0
  149. package/dist/utils/QuotaManager.d.ts +32 -0
  150. package/dist/utils/QuotaManager.d.ts.map +1 -0
  151. package/dist/utils/QuotaManager.js +95 -0
  152. package/dist/utils/QuotaManager.js.map +1 -0
  153. package/dist/utils/RateLimiter.d.ts +50 -0
  154. package/dist/utils/RateLimiter.d.ts.map +1 -0
  155. package/dist/utils/RateLimiter.js +121 -0
  156. package/dist/utils/RateLimiter.js.map +1 -0
  157. package/dist/utils/RequestCache.d.ts +26 -0
  158. package/dist/utils/RequestCache.d.ts.map +1 -0
  159. package/dist/utils/RequestCache.js +66 -0
  160. package/dist/utils/RequestCache.js.map +1 -0
  161. package/dist/utils/SecurityUtils.d.ts +80 -0
  162. package/dist/utils/SecurityUtils.d.ts.map +1 -0
  163. package/dist/utils/SecurityUtils.js +357 -0
  164. package/dist/utils/SecurityUtils.js.map +1 -0
  165. package/package.json +111 -0
  166. package/skills/paper-search/SKILL.md +192 -0
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Scopus (Elsevier) Searcher
3
+ *
4
+ * Documentation: https://dev.elsevier.com/documentation/SCOPUSSearchAPI.wadl
5
+ * API Endpoints:
6
+ * - Search API: https://api.elsevier.com/content/search/scopus
7
+ * - Abstract API: https://api.elsevier.com/content/abstract/scopus_id/
8
+ *
9
+ * Required API Key: Yes (X-ELS-APIKey header or apikey parameter)
10
+ * Get API key from: https://dev.elsevier.com/apikey/manage
11
+ *
12
+ * Scopus is the largest abstract and citation database of peer-reviewed literature
13
+ */
14
+ import axios from 'axios';
15
+ import { PaperSource } from './PaperSource.js';
16
+ import { PaperFactory } from '../models/Paper.js';
17
+ import { RateLimiter } from '../utils/RateLimiter.js';
18
+ import { ErrorHandler } from '../utils/ErrorHandler.js';
19
+ import { QuotaManager } from '../utils/QuotaManager.js';
20
+ import { TIMEOUTS, USER_AGENT } from '../config/constants.js';
21
+ import { logDebug } from '../utils/Logger.js';
22
+ export class ScopusSearcher extends PaperSource {
23
+ client;
24
+ rateLimiter;
25
+ quotaManager;
26
+ searchApiKey;
27
+ elsevierApiKey;
28
+ constructor(apiKey, searchApiKey) {
29
+ super('scopus', 'https://api.elsevier.com', apiKey);
30
+ // Support two API keys: one for search, one for other operations
31
+ this.elsevierApiKey = apiKey || process.env.ELSEVIER_API_KEY;
32
+ this.searchApiKey = searchApiKey || process.env.SCOPUS_SEARCH_API_KEY || this.elsevierApiKey;
33
+ this.client = axios.create({
34
+ baseURL: 'https://api.elsevier.com',
35
+ timeout: TIMEOUTS.DEFAULT,
36
+ headers: {
37
+ 'Accept': 'application/json',
38
+ 'User-Agent': USER_AGENT,
39
+ ...(this.searchApiKey ? { 'X-ELS-APIKey': this.searchApiKey } : {})
40
+ }
41
+ });
42
+ // Scopus rate limits (same as Elsevier):
43
+ // - Without key: 20 requests per minute
44
+ // - With key: 10 requests per second (600 per minute)
45
+ const requestsPerSecond = this.searchApiKey ? 10 : 0.33;
46
+ this.rateLimiter = new RateLimiter({
47
+ requestsPerSecond,
48
+ burstCapacity: this.searchApiKey ? 20 : 5
49
+ });
50
+ this.quotaManager = QuotaManager.getInstance();
51
+ this.quotaManager.registerPlatform('scopus', {
52
+ dailyLimit: 5000,
53
+ envPrefix: 'SCOPUS'
54
+ });
55
+ }
56
+ async search(query, options = {}) {
57
+ const customOptions = options;
58
+ if (!this.apiKey) {
59
+ throw new Error('Scopus API key is required');
60
+ }
61
+ const maxResults = Math.min(options.maxResults || 10, 25); // Scopus max is 25 per request
62
+ const papers = [];
63
+ try {
64
+ // Build Scopus search query
65
+ let searchQuery = `TITLE-ABS-KEY(${query})`;
66
+ if (options.author) {
67
+ searchQuery += ` AND AUTHOR(${options.author})`;
68
+ }
69
+ if (options.journal) {
70
+ searchQuery += ` AND SRCTITLE(${options.journal})`;
71
+ }
72
+ if (customOptions.affiliation) {
73
+ searchQuery += ` AND AFFIL(${customOptions.affiliation})`;
74
+ }
75
+ if (customOptions.subject) {
76
+ searchQuery += ` AND SUBJAREA(${customOptions.subject})`;
77
+ }
78
+ if (options.year) {
79
+ if (options.year.includes('-')) {
80
+ const [startYear, endYear] = options.year.split('-');
81
+ searchQuery += ` AND PUBYEAR > ${parseInt(startYear) - 1}`;
82
+ if (endYear) {
83
+ searchQuery += ` AND PUBYEAR < ${parseInt(endYear) + 1}`;
84
+ }
85
+ }
86
+ else {
87
+ searchQuery += ` AND PUBYEAR = ${options.year}`;
88
+ }
89
+ }
90
+ if (customOptions.openAccess) {
91
+ searchQuery += ' AND OPENACCESS(1)';
92
+ }
93
+ if (customOptions.documentType) {
94
+ const docTypeMap = {
95
+ 'ar': 'Article',
96
+ 'cp': 'Conference Paper',
97
+ 're': 'Review',
98
+ 'bk': 'Book',
99
+ 'ch': 'Book Chapter'
100
+ };
101
+ searchQuery += ` AND DOCTYPE(${docTypeMap[customOptions.documentType]})`;
102
+ }
103
+ await this.rateLimiter.waitForPermission();
104
+ this.quotaManager.checkQuota('scopus');
105
+ const response = await ErrorHandler.retryWithBackoff(() => this.client.get('/content/search/scopus', {
106
+ params: this.buildSearchParams(searchQuery, maxResults)
107
+ }), { context: 'Scopus search' });
108
+ this.quotaManager.incrementUsage('scopus');
109
+ const entries = response.data['search-results']?.entry || [];
110
+ for (const entry of entries) {
111
+ const paper = await this.parseEntry(entry);
112
+ if (paper) {
113
+ papers.push(paper);
114
+ }
115
+ }
116
+ return papers;
117
+ }
118
+ catch (error) {
119
+ this.handleHttpError(error, 'search');
120
+ }
121
+ }
122
+ buildSearchParams(searchQuery, maxResults) {
123
+ return {
124
+ query: searchQuery,
125
+ count: maxResults,
126
+ start: 0,
127
+ field: [
128
+ 'dc:identifier',
129
+ 'eid',
130
+ 'dc:title',
131
+ 'dc:creator',
132
+ 'prism:publicationName',
133
+ 'prism:coverDate',
134
+ 'prism:doi',
135
+ 'prism:url',
136
+ 'prism:volume',
137
+ 'prism:issueIdentifier',
138
+ 'prism:pageRange',
139
+ 'citedby-count',
140
+ 'openaccess'
141
+ ].join(',')
142
+ };
143
+ }
144
+ async parseEntry(entry) {
145
+ try {
146
+ // Extract authors
147
+ let authors = '';
148
+ if (entry.author && entry.author.length > 0) {
149
+ authors = entry.author.map(a => a.authname).join(', ');
150
+ }
151
+ else if (entry['dc:creator']) {
152
+ authors = entry['dc:creator'];
153
+ }
154
+ // Extract affiliations
155
+ let affiliations = [];
156
+ if (entry.affiliation) {
157
+ affiliations = entry.affiliation.map(a => a.affilname);
158
+ }
159
+ // Build paper URL
160
+ const paperUrl = entry['prism:url'] ||
161
+ (entry['prism:doi'] ? `https://doi.org/${entry['prism:doi']}` : undefined);
162
+ // Extract keywords
163
+ const keywords = entry.authkeywords?.split(' | ') || [];
164
+ return PaperFactory.create({
165
+ paperId: entry.eid || entry['dc:identifier'] || '',
166
+ title: entry['dc:title'] || '',
167
+ authors: authors ? authors.split(', ') : [],
168
+ abstract: '', // Abstract not included in search results, need separate API call
169
+ doi: entry['prism:doi'],
170
+ publishedDate: entry['prism:coverDate'] ? new Date(entry['prism:coverDate']) : null,
171
+ url: paperUrl,
172
+ source: 'scopus',
173
+ journal: entry['prism:publicationName'],
174
+ volume: entry['prism:volume'],
175
+ issue: entry['prism:issueIdentifier'],
176
+ pages: entry['prism:pageRange'],
177
+ citationCount: entry['citedby-count'] ? parseInt(entry['citedby-count']) : undefined,
178
+ keywords: keywords,
179
+ extra: {
180
+ scopusId: entry['dc:identifier'],
181
+ eid: entry.eid,
182
+ affiliations: affiliations,
183
+ documentType: entry.subtypeDescription,
184
+ issn: entry['prism:issn'],
185
+ eIssn: entry['prism:eIssn'],
186
+ openAccess: entry.openaccess === '1' || entry.openaccessFlag === true
187
+ }
188
+ });
189
+ }
190
+ catch (error) {
191
+ logDebug('Error parsing Scopus entry:', error);
192
+ return null;
193
+ }
194
+ }
195
+ async getAbstract(scopusId) {
196
+ if (!this.apiKey) {
197
+ throw new Error('Scopus API key is required');
198
+ }
199
+ try {
200
+ await this.rateLimiter.waitForPermission();
201
+ const response = await ErrorHandler.retryWithBackoff(() => this.client.get(`/content/abstract/scopus_id/${scopusId}`, {
202
+ params: { view: 'FULL' }
203
+ }), { context: 'Scopus abstract' });
204
+ const coredata = response.data['abstracts-retrieval-response']?.coredata;
205
+ if (!coredata)
206
+ return null;
207
+ // Extract authors from detailed response
208
+ let authors = '';
209
+ const authorsData = response.data['abstracts-retrieval-response']?.authors;
210
+ if (authorsData && authorsData.author) {
211
+ authors = authorsData.author
212
+ .map(a => `${a['preferred-name']['ce:given-name']} ${a['preferred-name']['ce:surname']}`)
213
+ .join(', ');
214
+ }
215
+ else if (coredata['dc:creator']) {
216
+ authors = coredata['dc:creator'].map((c) => c.$).join(', ');
217
+ }
218
+ // Extract subjects/keywords
219
+ let keywords = [];
220
+ const subjectData = response.data['abstracts-retrieval-response']?.subject;
221
+ if (subjectData && subjectData.subject) {
222
+ keywords = subjectData.subject.map(s => s.$);
223
+ }
224
+ return PaperFactory.create({
225
+ paperId: scopusId,
226
+ title: coredata['dc:title'] || '',
227
+ authors: authors ? authors.split(', ') : [],
228
+ abstract: coredata['dc:description'] || '',
229
+ doi: coredata['prism:doi'],
230
+ publishedDate: coredata['prism:coverDate'] ? new Date(coredata['prism:coverDate']) : null,
231
+ url: coredata['prism:doi'] ? `https://doi.org/${coredata['prism:doi']}` : undefined,
232
+ source: 'scopus',
233
+ journal: coredata['prism:publicationName'],
234
+ volume: coredata['prism:volume'],
235
+ issue: coredata['prism:issueIdentifier'],
236
+ pages: coredata['prism:pageRange'],
237
+ citationCount: coredata['citedby-count'] ? parseInt(coredata['citedby-count']) : undefined,
238
+ keywords: keywords,
239
+ extra: {
240
+ scopusId: coredata['dc:identifier'],
241
+ eid: coredata.eid,
242
+ pubmedId: coredata['pubmed-id'],
243
+ issn: coredata['prism:issn']
244
+ }
245
+ });
246
+ }
247
+ catch (error) {
248
+ logDebug('Scopus abstract retrieval error:', error.message);
249
+ return null;
250
+ }
251
+ }
252
+ getCapabilities() {
253
+ return {
254
+ search: true,
255
+ download: false,
256
+ fullText: false,
257
+ citations: true,
258
+ requiresApiKey: true,
259
+ supportedOptions: ['maxResults', 'year', 'author', 'journal']
260
+ };
261
+ }
262
+ async downloadPdf(paperId, options = {}) {
263
+ throw new Error('PDF download requires institutional access for Scopus');
264
+ }
265
+ async readPaper(paperId, options = {}) {
266
+ const paper = await this.getAbstract(paperId);
267
+ if (!paper) {
268
+ throw new Error('Paper not found');
269
+ }
270
+ return paper.abstract || 'Abstract not available';
271
+ }
272
+ /**
273
+ * 获取参考文献的Scopus ID列表
274
+ */
275
+ async getReferenceIds(scopusId) {
276
+ if (!this.elsevierApiKey)
277
+ return [];
278
+ try {
279
+ await this.rateLimiter.waitForPermission();
280
+ const response = await ErrorHandler.retryWithBackoff(() => axios.get(`https://api.elsevier.com/content/abstract/scopus_id/${scopusId}`, {
281
+ params: { view: 'REF' },
282
+ headers: {
283
+ 'Accept': 'application/json',
284
+ 'X-ELS-APIKey': this.elsevierApiKey
285
+ }
286
+ }), { context: 'Scopus references' });
287
+ const refIds = [];
288
+ const coreData = response.data?.['abstracts-retrieval-response']?.item?.bibrecord;
289
+ const tail = coreData?.tail;
290
+ const bibliography = tail?.bibliography;
291
+ const references = bibliography?.reference || [];
292
+ for (const ref of references) {
293
+ const refInfo = ref?.['ref-info'];
294
+ const refScopusId = refInfo?.['refd-itemidlist']?.itemid?.['#text'];
295
+ if (refScopusId) {
296
+ refIds.push(refScopusId);
297
+ }
298
+ }
299
+ return refIds;
300
+ }
301
+ catch (error) {
302
+ logDebug(`Error getting reference IDs for Scopus ID ${scopusId}:`, error);
303
+ return [];
304
+ }
305
+ }
306
+ /**
307
+ * 获取引用文献的Scopus ID列表
308
+ */
309
+ async getCitationIds(scopusId) {
310
+ if (!this.elsevierApiKey)
311
+ return [];
312
+ try {
313
+ await this.rateLimiter.waitForPermission();
314
+ const response = await ErrorHandler.retryWithBackoff(() => axios.get('https://api.elsevier.com/content/abstract/citations', {
315
+ params: { scopus_id: scopusId },
316
+ headers: {
317
+ 'Accept': 'application/json',
318
+ 'X-ELS-APIKey': this.elsevierApiKey
319
+ }
320
+ }), { context: 'Scopus citations' });
321
+ const citIds = [];
322
+ const citationData = response.data?.['abstract-citations-response'];
323
+ const citeInfoMatrix = citationData?.citeInfoMatrix;
324
+ const citeInfo = citeInfoMatrix?.citeInfo || [];
325
+ for (const cite of citeInfo) {
326
+ const citeScopusId = cite?.['scopus-id'];
327
+ if (citeScopusId) {
328
+ citIds.push(citeScopusId);
329
+ }
330
+ }
331
+ return citIds;
332
+ }
333
+ catch (error) {
334
+ logDebug(`Error getting citation IDs for Scopus ID ${scopusId}:`, error);
335
+ return [];
336
+ }
337
+ }
338
+ /**
339
+ * 获取论文详情(包含references和citations ID列表)
340
+ */
341
+ async getPaperWithCitations(paperId) {
342
+ try {
343
+ const paper = await this.getAbstract(paperId);
344
+ if (!paper)
345
+ return null;
346
+ const scopusId = paper.extra?.scopusId?.replace('SCOPUS_ID:', '') || paperId;
347
+ const [refIds, citIds] = await Promise.all([
348
+ this.getReferenceIds(scopusId),
349
+ this.getCitationIds(scopusId)
350
+ ]);
351
+ paper.references = refIds;
352
+ paper.extra = {
353
+ ...paper.extra,
354
+ citationIds: citIds
355
+ };
356
+ return paper;
357
+ }
358
+ catch (error) {
359
+ logDebug('Error getting paper with citations:', error);
360
+ return null;
361
+ }
362
+ }
363
+ }
364
+ //# sourceMappingURL=ScopusSearcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScopusSearcher.js","sourceRoot":"","sources":["../../src/platforms/ScopusSearcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Semantic Scholar API集成模块
3
+ * 支持免费API和付费API密钥
4
+ */
5
+ import { Paper } from '../models/Paper.js';
6
+ import { PaperSource, SearchOptions, DownloadOptions, PlatformCapabilities } from './PaperSource.js';
7
+ interface SemanticSearchOptions extends SearchOptions {
8
+ /** 发表年份范围 */
9
+ year?: string;
10
+ /** 研究领域过滤 */
11
+ fieldsOfStudy?: string[];
12
+ }
13
+ interface SemanticSnippetSearchOptions {
14
+ query: string;
15
+ limit?: number;
16
+ year?: string;
17
+ fieldsOfStudy?: string[] | string;
18
+ paperIds?: string[] | string;
19
+ authors?: string[] | string;
20
+ venue?: string[] | string;
21
+ minCitationCount?: number;
22
+ publicationDateOrYear?: string;
23
+ fields?: string[] | string;
24
+ }
25
+ export interface SemanticSnippetResult {
26
+ score: number | null;
27
+ paper: {
28
+ corpusId: string;
29
+ title: string;
30
+ authors: string[];
31
+ openAccessInfo: Record<string, unknown>;
32
+ url: string;
33
+ };
34
+ snippet: {
35
+ text: string;
36
+ snippetKind: string;
37
+ section: string;
38
+ snippetOffset: Record<string, unknown>;
39
+ annotations: Record<string, unknown>;
40
+ };
41
+ text: string;
42
+ }
43
+ export declare class SemanticScholarSearcher extends PaperSource {
44
+ private readonly rateLimiter;
45
+ private readonly cache;
46
+ private readonly baseApiUrl;
47
+ constructor(apiKey?: string);
48
+ getCapabilities(): PlatformCapabilities;
49
+ /**
50
+ * 搜索Semantic Scholar论文
51
+ */
52
+ search(query: string, options?: SemanticSearchOptions): Promise<Paper[]>;
53
+ /**
54
+ * 获取论文详细信息
55
+ */
56
+ getPaperDetails(paperId: string): Promise<Paper | null>;
57
+ searchSnippets(options: SemanticSnippetSearchOptions): Promise<SemanticSnippetResult[]>;
58
+ /**
59
+ * 下载PDF文件
60
+ */
61
+ downloadPdf(paperId: string, options?: DownloadOptions): Promise<string>;
62
+ /**
63
+ * 读取论文全文内容
64
+ */
65
+ readPaper(paperId: string, options?: DownloadOptions): Promise<string>;
66
+ /**
67
+ * 根据DOI获取论文信息
68
+ */
69
+ getPaperByDoi(doi: string): Promise<Paper | null>;
70
+ /**
71
+ * 解析搜索响应
72
+ */
73
+ private parseSearchResponse;
74
+ /**
75
+ * 解析单个Semantic Scholar论文
76
+ */
77
+ private parseSemanticPaper;
78
+ private normalizePdfUrl;
79
+ private parseSnippet;
80
+ private listParam;
81
+ /**
82
+ * 获取速率限制器状态
83
+ */
84
+ getRateLimiterStatus(): {
85
+ availableTokens: number;
86
+ maxTokens: number;
87
+ requestsPerSecond: number;
88
+ pendingRequests: number;
89
+ };
90
+ /**
91
+ * 验证API密钥(如果提供)
92
+ */
93
+ validateApiKey(): Promise<boolean>;
94
+ }
95
+ export {};
96
+ //# sourceMappingURL=SemanticScholarSearcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticScholarSearcher.d.ts","sourceRoot":"","sources":["../../src/platforms/SemanticScholarSearcher.ts"],"names":[],"mappings":"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"}