openalex-research-mcp 0.4.0 → 0.4.1

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.
package/QUICKSTART.md CHANGED
@@ -69,36 +69,52 @@ Which countries are leading research in renewable energy?
69
69
 
70
70
  ## Available Tools
71
71
 
72
- The server provides 18 specialized tools:
73
-
74
- **Literature Search:**
75
- - `search_works` - Advanced search for papers
76
- - `get_work` - Get detailed paper information
77
- - `get_related_works` - Find similar papers
78
- - `search_by_topic` - Explore specific research domains
79
- - `autocomplete_search` - Fast typeahead search
72
+ The server provides 31 specialized tools:
73
+
74
+ **Literature Search & Discovery:**
75
+ - `search_works` - Advanced search with Boolean operators, venue/institution filters
76
+ - `get_work` - Get complete metadata for a specific work
77
+ - `get_related_works` - Find similar papers based on citations and topics
78
+ - `search_by_topic` - Explore literature in specific research domains
79
+ - `autocomplete_search` - Fast typeahead search for all entity types
80
+
81
+ **Credibility-Gated Search (Journal & Conference Presets):**
82
+ - `list_journal_presets` - List all available journal/conference and institution group presets
83
+ - `search_in_journal_list` - Search within a named preset (UTD24, FT50, AJG tiers, etc.)
84
+ - `search_works_in_venue` - Search within a specific venue by name, ISSN, or ID
85
+ - `get_top_venues_for_field` - Discover top journals/conferences ranked by h-index
86
+ - `check_venue_quality` - Inspect h-index, impact, and indexing status of any venue
80
87
 
81
88
  **Citation Analysis:**
82
- - `get_work_citations` - Who cites this paper
83
- - `get_work_references` - What this paper cites
84
- - `get_citation_network` - Complete citation graph
85
- - `get_top_cited_works` - Most influential papers
86
-
87
- **Author & Institutions:**
88
- - `search_authors` - Find researchers
89
- - `get_author_works` - Author's publications
90
- - `get_author_collaborators` - Co-authorship networks
91
- - `search_institutions` - Find universities/organizations
92
-
93
- **Research Trends:**
94
- - `analyze_topic_trends` - Track research evolution
95
- - `compare_research_areas` - Compare different fields
96
- - `get_trending_topics` - Discover emerging areas
97
- - `analyze_geographic_distribution` - Global research mapping
89
+ - `get_work_citations` - Forward citation analysis (who cites this work)
90
+ - `get_work_references` - Backward citation analysis (what this work cites)
91
+ - `get_citation_network` - Build citation networks (forward + backward)
92
+ - `get_top_cited_works` - Find the most influential papers in a field
93
+
94
+ **Author & Institution Analysis:**
95
+ - `search_authors` - Find researchers with h-index and citation metrics
96
+ - `search_authors_by_expertise` - Find experts in a topic ranked by h-index
97
+ - `get_author_profile` - Full profile: h-index, i10-index, top works, recent works
98
+ - `get_author_works` - Analyze an author's publication history
99
+ - `get_author_collaborators` - Map co-authorship networks
100
+ - `search_institutions` - Find academic institutions
101
+
102
+ **High-Value Citation Finding:**
103
+ - `find_review_articles` - Find review papers and meta-analyses
104
+ - `find_seminal_papers` - Find foundational "must-cite" papers
105
+ - `find_open_access_version` - Find freely available versions of papers
106
+ - `batch_resolve_references` - Validate up to 20 DOIs/IDs at once
107
+
108
+ **Research Landscape & Trends:**
109
+ - `analyze_topic_trends` - Track research evolution over time
110
+ - `compare_research_areas` - Compare activity across different fields
111
+ - `get_trending_topics` - Discover emerging research areas
112
+ - `analyze_geographic_distribution` - Map global research activity
98
113
 
99
114
  **Entity Lookup:**
100
- - `get_entity` - Get any OpenAlex entity
101
- - `search_sources` - Find journals/venues
115
+ - `get_entity` - Get any OpenAlex entity (works, authors, sources, etc.)
116
+ - `search_sources` - Find journals/conferences sorted by h-index
117
+ - `health_check` - Verify server and API connectivity
102
118
 
103
119
  ## Tips
104
120
 
package/README.md CHANGED
@@ -441,7 +441,28 @@ MIT
441
441
 
442
442
  ## Contributing
443
443
 
444
- Contributions are welcome! Please feel free to submit issues or pull requests.
444
+ Contributions are welcome! Here's how to get involved:
445
+
446
+ ### Reporting bugs
447
+
448
+ - Search [existing issues](https://github.com/oksure/openalex-research-mcp/issues) before opening a new one.
449
+ - Include a clear description of what you expected vs. what happened.
450
+ - If the bug involves an API call, paste the relevant curl command or error message so it can be reproduced quickly (see the [OpenAlex API docs](https://docs.openalex.org) for reference).
451
+
452
+ ### Requesting features
453
+
454
+ - Open an issue with the `enhancement` label.
455
+ - Describe the use case and, if possible, sketch the desired tool name, input parameters, and example output.
456
+
457
+ ### Submitting pull requests
458
+
459
+ 1. **Fork** the repo and create a branch from `master` (e.g. `fix/my-bug` or `feat/my-feature`).
460
+ 2. **Make your changes** following the patterns in [CLAUDE.md](CLAUDE.md) (two-layer architecture, `summarizeWork` for list results, `getFullWorkDetails` for single-work lookups, etc.).
461
+ 3. **Add tests** — run `npm test` (vitest) to make sure all 26+ existing tests still pass, and add new tests in `tests/` for any new behaviour.
462
+ 4. **Build** with `npm run build` to confirm there are no TypeScript errors.
463
+ 5. **Open a PR** against `master` with a clear description of the problem and fix, including any curl-level reproduction steps for API-related bugs.
464
+
465
+ > **Note on API quirks:** Before adding new filter logic, check the "OpenAlex API Quirks & Common Bugs" section in [CLAUDE.md](CLAUDE.md) — several non-obvious behaviours (date filters, sort suffixes, DOI encoding) are documented there.
445
466
 
446
467
  ## Resources
447
468
 
package/build/config.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export declare function debug(...args: unknown[]): void;
1
2
  export declare const CONFIG: {
2
3
  API: {
3
4
  BASE_URL: string;
@@ -8,6 +9,7 @@ export declare const CONFIG: {
8
9
  };
9
10
  RETRY: {
10
11
  MAX_RETRIES: number;
12
+ MAX_429_RETRIES: number;
11
13
  INITIAL_DELAY_MS: number;
12
14
  MAX_DELAY_MS: number;
13
15
  BACKOFF_FACTOR: number;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BlB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,wBAAgB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAE9C;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BlB,CAAC"}
package/build/config.js CHANGED
@@ -1,3 +1,9 @@
1
+ // Debug logging gated on OPENALEX_DEBUG env var (stderr is safe for MCP stdio servers)
2
+ const DEBUG_ENABLED = process.env.OPENALEX_DEBUG === '1' || process.env.OPENALEX_DEBUG === 'true';
3
+ export function debug(...args) {
4
+ if (DEBUG_ENABLED)
5
+ console.error('[openalex]', ...args);
6
+ }
1
7
  export const CONFIG = {
2
8
  API: {
3
9
  BASE_URL: 'https://api.openalex.org',
@@ -8,6 +14,7 @@ export const CONFIG = {
8
14
  },
9
15
  RETRY: {
10
16
  MAX_RETRIES: 3,
17
+ MAX_429_RETRIES: 3,
11
18
  INITIAL_DELAY_MS: 1000,
12
19
  MAX_DELAY_MS: 10000,
13
20
  BACKOFF_FACTOR: 2,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,GAAG,EAAE;QACH,QAAQ,EAAE,0BAA0B;QACpC,OAAO,EAAE,KAAK;QACd,UAAU,EAAE;YACV,mBAAmB,EAAE,EAAE;YACvB,gBAAgB,EAAE,MAAM;SACzB;QACD,KAAK,EAAE;YACL,WAAW,EAAE,CAAC;YACd,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,CAAC;SAClB;KACF;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;QACnC,QAAQ,EAAE,IAAI;KACf;IACD,GAAG,EAAE;QACH,iBAAiB,EAAE,EAAE;QACrB,aAAa,EAAE,GAAG;QAClB,sBAAsB,EAAE,CAAC;QACzB,mBAAmB,EAAE,GAAG;QACxB,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,CAAC;QACb,6BAA6B,EAAE,EAAE;KAClC;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;AAClG,MAAM,UAAU,KAAK,CAAC,GAAG,IAAe;IACtC,IAAI,aAAa;QAAE,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,GAAG,EAAE;QACH,QAAQ,EAAE,0BAA0B;QACpC,OAAO,EAAE,KAAK;QACd,UAAU,EAAE;YACV,mBAAmB,EAAE,EAAE;YACvB,gBAAgB,EAAE,MAAM;SACzB;QACD,KAAK,EAAE;YACL,WAAW,EAAE,CAAC;YACd,eAAe,EAAE,CAAC;YAClB,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,CAAC;SAClB;KACF;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;QACnC,QAAQ,EAAE,IAAI;KACf;IACD,GAAG,EAAE;QACH,iBAAiB,EAAE,EAAE;QACrB,aAAa,EAAE,GAAG;QAClB,sBAAsB,EAAE,CAAC;QACzB,mBAAmB,EAAE,GAAG;QACxB,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,CAAC;QACb,6BAA6B,EAAE,EAAE;KAClC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { FilterOptions } from './openalex-client.js';
2
+ export declare function buildFilter(params: any): FilterOptions;
3
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,CAwDtD"}
@@ -0,0 +1,61 @@
1
+ // buildFilter — maps MCP tool parameters to OpenAlex API filter format.
2
+ // Exported so it can be unit-tested directly.
3
+ import { INSTITUTION_GROUPS } from './presets.js';
4
+ import { debug } from './config.js';
5
+ export function buildFilter(params) {
6
+ const filter = {};
7
+ // Handle publication year range (all tools now use from_year/to_year)
8
+ const fromYear = params.from_year || params.from_publication_year;
9
+ const toYear = params.to_year || params.to_publication_year;
10
+ if (fromYear && toYear) {
11
+ filter['publication_year'] = `${fromYear}-${toYear}`;
12
+ }
13
+ else if (fromYear) {
14
+ filter['publication_year'] = `>${fromYear - 1}`;
15
+ }
16
+ else if (toYear) {
17
+ filter['publication_year'] = `<${toYear + 1}`;
18
+ }
19
+ if (params.cited_by_count) {
20
+ filter['cited_by_count'] = params.cited_by_count;
21
+ }
22
+ if (params.is_oa !== undefined) {
23
+ filter['is_oa'] = params.is_oa;
24
+ }
25
+ if (params.type) {
26
+ filter['type'] = params.type;
27
+ }
28
+ if (params.works_count) {
29
+ filter['works_count'] = params.works_count;
30
+ }
31
+ if (params.country_code) {
32
+ filter['country_code'] = params.country_code;
33
+ }
34
+ if (params.institution) {
35
+ filter['institutions.display_name'] = params.institution;
36
+ }
37
+ if (params.institution_group) {
38
+ const group = INSTITUTION_GROUPS[params.institution_group];
39
+ if (group) {
40
+ filter['authorships.institutions.display_name'] = group.institutions.join('|');
41
+ }
42
+ }
43
+ else if (params.author_institution) {
44
+ filter['authorships.institutions.display_name'] = params.author_institution;
45
+ }
46
+ if (params.source_id) {
47
+ filter['primary_location.source.id'] = params.source_id;
48
+ }
49
+ if (params.source_name) {
50
+ filter['primary_location.source.display_name.search'] = params.source_name;
51
+ }
52
+ if (params.source_issn) {
53
+ filter['primary_location.source.issn'] = params.source_issn;
54
+ }
55
+ if (params.min_citations !== undefined && params.min_citations > 0) {
56
+ filter['cited_by_count'] = `>${params.min_citations - 1}`;
57
+ }
58
+ debug('buildFilter result:', JSON.stringify(filter));
59
+ return filter;
60
+ }
61
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ export declare function reconstructAbstract(invertedIndex: any): string;
2
+ export declare function summarizeWork(work: any): {
3
+ id: any;
4
+ doi: any;
5
+ title: any;
6
+ publication_year: any;
7
+ publication_date: any;
8
+ cited_by_count: any;
9
+ type: any;
10
+ authors: any;
11
+ authors_truncated: boolean;
12
+ primary_topic: {
13
+ display_name: any;
14
+ field: any;
15
+ subfield: any;
16
+ } | null;
17
+ open_access: {
18
+ is_oa: any;
19
+ oa_status: any;
20
+ oa_url: any;
21
+ };
22
+ landing_page_url: any;
23
+ pdf_url: any;
24
+ source: any;
25
+ source_id: any;
26
+ source_issn_l: any;
27
+ source_type: any;
28
+ fwci: any;
29
+ abstract: string | null;
30
+ };
31
+ export declare function summarizeAuthor(author: any): {
32
+ id: any;
33
+ name: any;
34
+ orcid: any;
35
+ works_count: any;
36
+ cited_by_count: any;
37
+ h_index: any;
38
+ i10_index: any;
39
+ two_year_mean_citedness: any;
40
+ last_known_institutions: any;
41
+ top_topics: any;
42
+ };
43
+ export declare function summarizeSource(source: any): {
44
+ id: any;
45
+ display_name: any;
46
+ issn_l: any;
47
+ issn: any;
48
+ type: any;
49
+ h_index: any;
50
+ two_year_mean_citedness: any;
51
+ works_count: any;
52
+ cited_by_count: any;
53
+ is_oa: any;
54
+ is_in_doaj: any;
55
+ homepage_url: any;
56
+ host_organization: any;
57
+ topics: any;
58
+ };
59
+ export declare function summarizeWorksList(response: any): {
60
+ meta: {
61
+ count: any;
62
+ page: any;
63
+ per_page: any;
64
+ };
65
+ results: any;
66
+ };
67
+ export declare function getFullWorkDetails(work: any): {
68
+ id: any;
69
+ doi: any;
70
+ title: any;
71
+ publication_year: any;
72
+ publication_date: any;
73
+ cited_by_count: any;
74
+ type: any;
75
+ authors: any;
76
+ primary_topic: {
77
+ id: any;
78
+ display_name: any;
79
+ score: any;
80
+ field: any;
81
+ subfield: any;
82
+ domain: any;
83
+ } | null;
84
+ topics: any;
85
+ open_access: {
86
+ is_oa: any;
87
+ oa_status: any;
88
+ oa_url: any;
89
+ any_repository_has_fulltext: any;
90
+ };
91
+ landing_page_url: any;
92
+ pdf_url: any;
93
+ primary_location: {
94
+ is_oa: any;
95
+ landing_page_url: any;
96
+ pdf_url: any;
97
+ source: {
98
+ id: any;
99
+ display_name: any;
100
+ issn_l: any;
101
+ issn: any;
102
+ type: any;
103
+ host_organization: any;
104
+ } | null;
105
+ license: any;
106
+ version: any;
107
+ } | null;
108
+ abstract: string | null;
109
+ biblio: any;
110
+ referenced_works_count: any;
111
+ cited_by_percentile_year: any;
112
+ fwci: any;
113
+ keywords: any;
114
+ grants: any;
115
+ referenced_works: any;
116
+ related_works: any;
117
+ };
118
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,GAAG,GAAG,MAAM,CAa9D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCtC;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG;;;;;;;;;;;EAoB1C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;EAiB1C;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,GAAG;;;;;;;EAS/C;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgF3C"}
@@ -0,0 +1,180 @@
1
+ // Response formatting helpers — pure functions for summarizing OpenAlex API responses.
2
+ // Two-tier strategy: summarized results for list operations, full details for single-work lookups.
3
+ export function reconstructAbstract(invertedIndex) {
4
+ const words = {};
5
+ for (const [word, positions] of Object.entries(invertedIndex)) {
6
+ if (Array.isArray(positions)) {
7
+ positions.forEach((pos) => {
8
+ words[pos] = word;
9
+ });
10
+ }
11
+ }
12
+ const sortedPositions = Object.keys(words).map(Number).sort((a, b) => a - b);
13
+ return sortedPositions.map(pos => words[pos]).join(' ');
14
+ }
15
+ export function summarizeWork(work) {
16
+ return {
17
+ id: work.id,
18
+ doi: work.doi,
19
+ title: work.title || work.display_name,
20
+ publication_year: work.publication_year,
21
+ publication_date: work.publication_date,
22
+ cited_by_count: work.cited_by_count,
23
+ type: work.type,
24
+ authors: work.authorships?.slice(0, 5).map((a) => ({
25
+ name: a.author?.display_name,
26
+ institutions: a.institutions?.slice(0, 2).map((i) => i.display_name)
27
+ })) || [],
28
+ authors_truncated: work.authorships?.length > 5,
29
+ primary_topic: work.primary_topic ? {
30
+ display_name: work.primary_topic.display_name,
31
+ field: work.primary_topic.field?.display_name,
32
+ subfield: work.primary_topic.subfield?.display_name
33
+ } : null,
34
+ open_access: {
35
+ is_oa: work.open_access?.is_oa,
36
+ oa_status: work.open_access?.oa_status,
37
+ oa_url: work.open_access?.oa_url
38
+ },
39
+ landing_page_url: work.primary_location?.landing_page_url,
40
+ pdf_url: work.best_oa_location?.pdf_url,
41
+ source: work.primary_location?.source?.display_name,
42
+ source_id: work.primary_location?.source?.id,
43
+ source_issn_l: work.primary_location?.source?.issn_l,
44
+ source_type: work.primary_location?.source?.type,
45
+ fwci: work.fwci ?? null,
46
+ abstract: work.abstract_inverted_index ?
47
+ reconstructAbstract(work.abstract_inverted_index).substring(0, 600) : null
48
+ };
49
+ }
50
+ export function summarizeAuthor(author) {
51
+ return {
52
+ id: author.id,
53
+ name: author.display_name,
54
+ orcid: author.orcid,
55
+ works_count: author.works_count,
56
+ cited_by_count: author.cited_by_count,
57
+ h_index: author.summary_stats?.h_index ?? null,
58
+ i10_index: author.summary_stats?.i10_index ?? null,
59
+ two_year_mean_citedness: author.summary_stats?.['2yr_mean_citedness'] ?? null,
60
+ last_known_institutions: author.last_known_institutions?.slice(0, 2).map((i) => ({
61
+ display_name: i.display_name,
62
+ country_code: i.country_code,
63
+ type: i.type
64
+ })) || [],
65
+ top_topics: author.topics?.slice(0, 4).map((t) => ({
66
+ name: t.display_name,
67
+ count: t.count
68
+ })) || []
69
+ };
70
+ }
71
+ export function summarizeSource(source) {
72
+ return {
73
+ id: source.id,
74
+ display_name: source.display_name,
75
+ issn_l: source.issn_l,
76
+ issn: source.issn,
77
+ type: source.type,
78
+ h_index: source.summary_stats?.h_index ?? null,
79
+ two_year_mean_citedness: source.summary_stats?.['2yr_mean_citedness'] ?? null,
80
+ works_count: source.works_count,
81
+ cited_by_count: source.cited_by_count,
82
+ is_oa: source.is_oa,
83
+ is_in_doaj: source.is_in_doaj,
84
+ homepage_url: source.homepage_url,
85
+ host_organization: source.host_organization_name,
86
+ topics: source.topics?.slice(0, 4).map((t) => t.display_name) || []
87
+ };
88
+ }
89
+ export function summarizeWorksList(response) {
90
+ return {
91
+ meta: {
92
+ count: response.meta?.count,
93
+ page: response.meta?.page,
94
+ per_page: response.meta?.per_page
95
+ },
96
+ results: response.results?.map(summarizeWork) || []
97
+ };
98
+ }
99
+ export function getFullWorkDetails(work) {
100
+ return {
101
+ id: work.id,
102
+ doi: work.doi,
103
+ title: work.title || work.display_name,
104
+ publication_year: work.publication_year,
105
+ publication_date: work.publication_date,
106
+ cited_by_count: work.cited_by_count,
107
+ type: work.type,
108
+ authors: work.authorships?.map((a, index) => ({
109
+ position: index === 0 ? 'first' : index === work.authorships.length - 1 ? 'last' : 'middle',
110
+ author_position: a.author_position,
111
+ name: a.author?.display_name,
112
+ id: a.author?.id,
113
+ orcid: a.author?.orcid,
114
+ institutions: a.institutions?.map((i) => ({
115
+ id: i.id,
116
+ display_name: i.display_name,
117
+ ror: i.ror,
118
+ country_code: i.country_code,
119
+ type: i.type
120
+ })) || [],
121
+ countries: a.countries || [],
122
+ is_corresponding: a.is_corresponding,
123
+ raw_affiliation_strings: a.raw_affiliation_strings || []
124
+ })) || [],
125
+ primary_topic: work.primary_topic ? {
126
+ id: work.primary_topic.id,
127
+ display_name: work.primary_topic.display_name,
128
+ score: work.primary_topic.score,
129
+ field: work.primary_topic.field?.display_name,
130
+ subfield: work.primary_topic.subfield?.display_name,
131
+ domain: work.primary_topic.domain?.display_name
132
+ } : null,
133
+ topics: work.topics?.slice(0, 5).map((t) => ({
134
+ id: t.id,
135
+ display_name: t.display_name,
136
+ score: t.score
137
+ })) || [],
138
+ open_access: {
139
+ is_oa: work.open_access?.is_oa,
140
+ oa_status: work.open_access?.oa_status,
141
+ oa_url: work.open_access?.oa_url,
142
+ any_repository_has_fulltext: work.open_access?.any_repository_has_fulltext
143
+ },
144
+ landing_page_url: work.primary_location?.landing_page_url,
145
+ pdf_url: work.best_oa_location?.pdf_url,
146
+ primary_location: work.primary_location ? {
147
+ is_oa: work.primary_location.is_oa,
148
+ landing_page_url: work.primary_location.landing_page_url,
149
+ pdf_url: work.primary_location.pdf_url,
150
+ source: work.primary_location.source ? {
151
+ id: work.primary_location.source.id,
152
+ display_name: work.primary_location.source.display_name,
153
+ issn_l: work.primary_location.source.issn_l,
154
+ issn: work.primary_location.source.issn,
155
+ type: work.primary_location.source.type,
156
+ host_organization: work.primary_location.source.host_organization_name
157
+ } : null,
158
+ license: work.primary_location.license,
159
+ version: work.primary_location.version
160
+ } : null,
161
+ abstract: work.abstract_inverted_index ?
162
+ reconstructAbstract(work.abstract_inverted_index) : null,
163
+ biblio: work.biblio,
164
+ referenced_works_count: work.referenced_works_count,
165
+ cited_by_percentile_year: work.cited_by_percentile_year,
166
+ fwci: work.fwci,
167
+ keywords: work.keywords?.slice(0, 10).map((k) => ({
168
+ keyword: k.keyword || k.display_name,
169
+ score: k.score
170
+ })) || [],
171
+ grants: work.grants?.slice(0, 5).map((g) => ({
172
+ funder: g.funder,
173
+ funder_display_name: g.funder_display_name,
174
+ award_id: g.award_id
175
+ })) || [],
176
+ referenced_works: work.referenced_works || [],
177
+ related_works: work.related_works || []
178
+ };
179
+ }
180
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"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"}