@cyanheads/openalex-mcp-server 0.7.16 → 0.9.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.
- package/AGENTS.md +48 -33
- package/CLAUDE.md +48 -33
- package/Dockerfile +98 -33
- package/README.md +23 -16
- package/changelog/0.8.x/0.8.0.md +38 -0
- package/changelog/0.9.x/0.9.0.md +48 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/prompts/definitions/literature-review.prompt.js +1 -1
- package/dist/mcp-server/prompts/definitions/research-landscape.prompt.js +1 -1
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.d.ts +28 -3
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.js +57 -10
- package/dist/mcp-server/tools/definitions/analyze-trends.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/citation-graph.tool.d.ts +62 -5
- package/dist/mcp-server/tools/definitions/citation-graph.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/citation-graph.tool.js +100 -52
- package/dist/mcp-server/tools/definitions/citation-graph.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/describe-fields.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/describe-fields.tool.js +34 -4
- package/dist/mcp-server/tools/definitions/describe-fields.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/resolve-name.tool.d.ts +38 -2
- package/dist/mcp-server/tools/definitions/resolve-name.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/resolve-name.tool.js +176 -41
- package/dist/mcp-server/tools/definitions/resolve-name.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts +75 -4
- package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-entities.tool.js +169 -73
- package/dist/mcp-server/tools/definitions/search-entities.tool.js.map +1 -1
- package/dist/mcp-server/tools/render-budget.d.ts +4 -2
- package/dist/mcp-server/tools/render-budget.d.ts.map +1 -1
- package/dist/mcp-server/tools/render-budget.js +4 -2
- package/dist/mcp-server/tools/render-budget.js.map +1 -1
- package/dist/mcp-server/tools/render-entity-record.d.ts +12 -1
- package/dist/mcp-server/tools/render-entity-record.d.ts.map +1 -1
- package/dist/mcp-server/tools/render-entity-record.js +23 -8
- package/dist/mcp-server/tools/render-entity-record.js.map +1 -1
- package/dist/mcp-server/tools/response-budget.d.ts +160 -0
- package/dist/mcp-server/tools/response-budget.d.ts.map +1 -0
- package/dist/mcp-server/tools/response-budget.js +489 -0
- package/dist/mcp-server/tools/response-budget.js.map +1 -0
- package/dist/services/openalex/budget.d.ts +3 -1
- package/dist/services/openalex/budget.d.ts.map +1 -1
- package/dist/services/openalex/budget.js +3 -1
- package/dist/services/openalex/budget.js.map +1 -1
- package/dist/services/openalex/field-catalog.json +50 -1
- package/dist/services/openalex/filter-values.d.ts +46 -0
- package/dist/services/openalex/filter-values.d.ts.map +1 -0
- package/dist/services/openalex/filter-values.js +294 -0
- package/dist/services/openalex/filter-values.js.map +1 -0
- package/dist/services/openalex/iso-codes.json +1565 -0
- package/dist/services/openalex/openalex-service.d.ts +181 -16
- package/dist/services/openalex/openalex-service.d.ts.map +1 -1
- package/dist/services/openalex/openalex-service.js +593 -141
- package/dist/services/openalex/openalex-service.js.map +1 -1
- package/dist/services/openalex/provider-text.d.ts +13 -5
- package/dist/services/openalex/provider-text.d.ts.map +1 -1
- package/dist/services/openalex/provider-text.js +799 -51
- package/dist/services/openalex/provider-text.js.map +1 -1
- package/dist/services/openalex/types.d.ts +1 -1
- package/dist/services/openalex/types.js +1 -1
- package/package.json +16 -13
- package/server.json +10 -24
|
@@ -4,6 +4,38 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { type AnalyzeParams, type AnalyzeResult, type AutocompleteParams, type AutocompleteRecord, type AutocompleteResult, type EntityRecord, type EntityType, type SearchParams, type SearchResult } from './types.js';
|
|
7
|
+
/** One upstream filter clause: the canonical key and the value it constrains. */
|
|
8
|
+
type FilterClause = [key: string, value: string];
|
|
9
|
+
/**
|
|
10
|
+
* Build an OpenAlex filter string from ordered key-value clauses.
|
|
11
|
+
* Input: [["cited_by_count", ">100"], ["is_oa", "true"]]
|
|
12
|
+
* Output: "cited_by_count:>100,is_oa:true"
|
|
13
|
+
*
|
|
14
|
+
* Clauses, not a record: OpenAlex ANDs a repeated key (`publication_year:2020,publication_year:2024`
|
|
15
|
+
* matches works in both years, which is nothing), and two caller filters can resolve to one
|
|
16
|
+
* canonical key. A record would hold only the last of them.
|
|
17
|
+
*
|
|
18
|
+
* Comma handling (commas collide with OpenAlex's filter clause separator):
|
|
19
|
+
* - Free-text search keys (`title.search`, `abstract.search.exact`, `semantic.search`, …) and
|
|
20
|
+
* keys matched as whole text (`raw_affiliation_strings`, `display_name`, `geo.city`, …): the
|
|
21
|
+
* value goes out double-quoted as `quotedCommaValue()` writes it, so the comma stays part of the
|
|
22
|
+
* phrase. The quoted value is sent as written, `+` included.
|
|
23
|
+
* - All other keys: throw a pre-flight validation error — OpenAlex OR-lists use `|`, not commas.
|
|
24
|
+
*
|
|
25
|
+
* Every other value goes out as `upstreamFilterValue()` writes it: country and `language` values
|
|
26
|
+
* converted to the codes OpenAlex stores (a country segment that cannot be a code throws
|
|
27
|
+
* `invalid_country_code`), a multi-word value on a key matched as whole text (`geo.city`,
|
|
28
|
+
* `awards.funder_display_name`, …) double-quoted so OpenAlex reads it as one phrase, and the AND
|
|
29
|
+
* operator — a `+`, or a space on a key where words mean AND — sent as the AND it spells. A value
|
|
30
|
+
* that puts that operator beside a `|` throws `mixed_and_or_in_filter_value`, since OpenAlex drops
|
|
31
|
+
* every `|` alternative that ANDs more than one value; a value sent double-quoted that carries a
|
|
32
|
+
* `"` of its own throws `quote_in_filter_value`. Every throw runs before any request.
|
|
33
|
+
* `autocomplete()` sends its filters without `translateFilters()`, so the conversion lives here
|
|
34
|
+
* rather than there.
|
|
35
|
+
*
|
|
36
|
+
* Exported for the timing suite, which runs it on caller-sized keys and values.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildFilterString(filters: FilterClause[]): string;
|
|
7
39
|
/**
|
|
8
40
|
* Recovery for a PMCID that reached OpenAlex and came back with nothing. OpenAlex indexes no
|
|
9
41
|
* PMCIDs — `has_pmcid:true` matches zero works and a work's `ids` object never carries the key —
|
|
@@ -12,6 +44,11 @@ import { type AnalyzeParams, type AnalyzeResult, type AutocompleteParams, type A
|
|
|
12
44
|
* mapping here and the `openalex_resolve_name` miss notice so both say the same thing.
|
|
13
45
|
*/
|
|
14
46
|
export declare const PMCID_NOT_INDEXED_HINT = "OpenAlex indexes no PMCIDs, so a PMCID resolves nothing however it is written. Convert it to a PMID or DOI \u2014 the NCBI ID Converter (https://www.ncbi.nlm.nih.gov/pmc/tools/idconv/) does this \u2014 and retry with that identifier.";
|
|
47
|
+
/**
|
|
48
|
+
* The filter clause that matches a funder by its bare DOI, or undefined for a value that clause
|
|
49
|
+
* would read as more than one literal DOI — it could only match some other funder, or every one.
|
|
50
|
+
*/
|
|
51
|
+
export declare function funderDoiFilter(doi: string): string | undefined;
|
|
15
52
|
/**
|
|
16
53
|
* Detect ID format and return the API path segment.
|
|
17
54
|
* "10.1038/nature12373" → "doi:10.1038/nature12373"
|
|
@@ -25,18 +62,51 @@ export declare const PMCID_NOT_INDEXED_HINT = "OpenAlex indexes no PMCIDs, so a
|
|
|
25
62
|
* "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1234567/" → "pmcid:PMC1234567"
|
|
26
63
|
* "https://pubmed.ncbi.nlm.nih.gov/21491125" → "pmid:21491125"
|
|
27
64
|
* "PMID:21491125" → "pmid:21491125"
|
|
28
|
-
* "https://openalex.org/
|
|
65
|
+
* "https://openalex.org/works/W2741809807" → "W2741809807"
|
|
66
|
+
* "https://api.openalex.org/keywords/groundwater" → "groundwater"
|
|
29
67
|
* "W2741809807" → "W2741809807"
|
|
30
68
|
*/
|
|
31
69
|
export declare function normalizeId(id: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* The by-ID request path for `id`: `/<entityType>/<id>`, with every character a URL parse would
|
|
72
|
+
* read as structure percent-encoded so it stays part of the ID. OpenAlex decodes them back, so a
|
|
73
|
+
* DOI that holds a `#` or `?` reaches the record it names instead of a truncated one.
|
|
74
|
+
*
|
|
75
|
+
* A `.` or `..` segment, plain or percent-encoded, is refused before any request, since encoding
|
|
76
|
+
* cannot keep it inside the path. `/` is left as written, since DOIs carry it, and an encoded
|
|
77
|
+
* `%2F` is one segment to both the parse and OpenAlex. The refusal quotes `callerId`, the
|
|
78
|
+
* identifier as the caller wrote it, rather than the normalized `id` (`doi:…` for a DOI URL).
|
|
79
|
+
*/
|
|
80
|
+
export declare function byIdPath(entityType: EntityType, id: string, callerId?: string): string;
|
|
32
81
|
/** An identifier the deterministic by-ID path can resolve, with the scheme it was read as. */
|
|
33
82
|
export interface ResolvedIdentifier {
|
|
34
|
-
|
|
83
|
+
/** The entity types to look the identifier up as, in the order their records are returned. */
|
|
84
|
+
entityTypes: readonly EntityType[];
|
|
35
85
|
/** The value in the form the OpenAlex path segment expects (`doi:10.1038/…`, `W2741809807`). */
|
|
36
86
|
id: string;
|
|
87
|
+
/**
|
|
88
|
+
* Set on a bare native-ID shape, which short names share — keyword `p53` reads as publisher
|
|
89
|
+
* `P53`, and `F1`, `S1`, and `A1` are keywords too — so a lookup that finds no record is no
|
|
90
|
+
* sign the caller meant an ID, and the query is worth searching as a name next. A URL form
|
|
91
|
+
* names its record outright and never carries it.
|
|
92
|
+
*/
|
|
93
|
+
mayBeName?: true;
|
|
37
94
|
/** Identifier scheme, for caller-facing messages: `doi`, `orcid`, `openalex`, … */
|
|
38
95
|
scheme: string;
|
|
39
96
|
}
|
|
97
|
+
/** What `resolveIdentifier()` found. */
|
|
98
|
+
export interface IdentifierResolution extends AutocompleteResult {
|
|
99
|
+
/** Entity types whose lookup failed upstream while another type returned a record. */
|
|
100
|
+
failedEntityTypes?: EntityType[];
|
|
101
|
+
/**
|
|
102
|
+
* Set when every lookup found nothing and the query ran as a name search instead: `results`
|
|
103
|
+
* then hold that search's matches. `failedReason` names the upstream failure that stopped the
|
|
104
|
+
* search, with `results` empty.
|
|
105
|
+
*/
|
|
106
|
+
nameFallback?: {
|
|
107
|
+
failedReason?: string;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
40
110
|
/**
|
|
41
111
|
* Classify a query as an identifier, or return `undefined` for a name.
|
|
42
112
|
*
|
|
@@ -45,12 +115,17 @@ export interface ResolvedIdentifier {
|
|
|
45
115
|
* it produced. Names never survive that: a name with a colon in it yields a prefix that is in no
|
|
46
116
|
* scheme table, and anything else fails the native-ID pattern.
|
|
47
117
|
*
|
|
48
|
-
* Keywords are the exception, and are read from the
|
|
49
|
-
* `normalizeId()`
|
|
50
|
-
* form is the only keyword spelling that identifies itself — a bare slug is
|
|
51
|
-
* from any other name, and autocomplete is the right answer for it.
|
|
118
|
+
* Keywords are the exception, and are read from the URL before it is reduced: their IDs are
|
|
119
|
+
* slugs, so `normalizeId()` turns the URL into a bare word that no longer names an entity type.
|
|
120
|
+
* The URL form is the only keyword spelling that identifies itself — a bare slug is
|
|
121
|
+
* indistinguishable from any other name, and autocomplete is the right answer for it.
|
|
122
|
+
*
|
|
123
|
+
* `requested` (the caller's `entity_type`) narrows an identifier only among the types it can
|
|
124
|
+
* address: a ROR to one of institutions, funders, and publishers, and a Funder Registry DOI to
|
|
125
|
+
* works. Any other type leaves the identifier's own types in place — except `keywords`, under
|
|
126
|
+
* which a bare native-ID shape is a name: keyword IDs are slugs, and `P53` is a keyword.
|
|
52
127
|
*/
|
|
53
|
-
export declare function inferIdentifier(query: string): ResolvedIdentifier | undefined;
|
|
128
|
+
export declare function inferIdentifier(query: string, requested?: EntityType): ResolvedIdentifier | undefined;
|
|
54
129
|
/**
|
|
55
130
|
* Shape a singleton entity record like an autocomplete match, so both resolution paths of
|
|
56
131
|
* `openalex_resolve_name` return one result type. `entity_type` is singularized to match what
|
|
@@ -58,6 +133,28 @@ export declare function inferIdentifier(query: string): ResolvedIdentifier | und
|
|
|
58
133
|
* a work has no works of its own, which is the same thing autocomplete reports.
|
|
59
134
|
*/
|
|
60
135
|
export declare function toAutocompleteRecord(entityType: EntityType, record: EntityRecord): AutocompleteRecord;
|
|
136
|
+
/**
|
|
137
|
+
* The works `select` field the server derives rather than projects: each authorship's author as
|
|
138
|
+
* `{id, display_name, orcid}`, from the `authorships` it requests in its place. Not an upstream
|
|
139
|
+
* field, so it is never forwarded, and neither the default projection nor `*` includes it.
|
|
140
|
+
*/
|
|
141
|
+
export declare const AUTHOR_LIST_FIELD = "author_list";
|
|
142
|
+
/**
|
|
143
|
+
* The record key one caller-supplied `select` name lands under: `author_list` keeps its own
|
|
144
|
+
* name; any other name lands under the upstream field it projects (`authors` → `authorships`).
|
|
145
|
+
* Exported so a tool can find the array a one-field projection returns.
|
|
146
|
+
*/
|
|
147
|
+
export declare function selectRecordKey(entityType: SearchParams['entityType'], field: string): string;
|
|
148
|
+
/**
|
|
149
|
+
* Detect a value the `id:` filter would carry — OpenAlex IDs, bare or in any URL spelling
|
|
150
|
+
* `parseOpenAlexUrl()` reads, optionally pipe-joined for OR semantics. When matched, `id` is
|
|
151
|
+
* rewritten to `openalex` (the canonical filter key) and the value is forwarded as written:
|
|
152
|
+
* upstream accepts every one of those spellings, and the space around a `|`. Stricter than any
|
|
153
|
+
* value so a future generic upstream `id:` filter wouldn't be shadowed — only values that read
|
|
154
|
+
* as OpenAlex IDs get redirected. Exported for the timing suite, which runs it on caller-sized
|
|
155
|
+
* values.
|
|
156
|
+
*/
|
|
157
|
+
export declare function isOpenAlexFilterValue(value: string): boolean;
|
|
61
158
|
/**
|
|
62
159
|
* Rewrite one caller-supplied filter key to the upstream OpenAlex name, before the
|
|
63
160
|
* value-dependent `id` rewrite. Exported so the citation-graph tool can check a caller's key
|
|
@@ -68,21 +165,61 @@ export declare function toAutocompleteRecord(entityType: EntityType, record: Ent
|
|
|
68
165
|
* typos no map can preempt.
|
|
69
166
|
*/
|
|
70
167
|
export declare function translateFilterKey(entityType: SearchParams['entityType'], key: string): string;
|
|
168
|
+
/**
|
|
169
|
+
* The `filter` parameter a search or group_by over `filters` sends: keys translated, then each
|
|
170
|
+
* clause built by `buildFilterString()`, whose pre-flight throws (`comma_in_filter_value`,
|
|
171
|
+
* `invalid_country_code`, `mixed_and_or_in_filter_value`, `quote_in_filter_value`) it shares.
|
|
172
|
+
* Exported so a tool that spends a request before its search — the citation graph's seed lookup —
|
|
173
|
+
* can run those checks first and fail without one.
|
|
174
|
+
*/
|
|
175
|
+
export declare function buildSearchFilter(entityType: SearchParams['entityType'], filters: Record<string, string>): string;
|
|
176
|
+
/**
|
|
177
|
+
* Recovery for every `upstream_unavailable` failure of a semantic search — a relabelled embedding
|
|
178
|
+
* failure, the 503 OpenAlex sends when the embedding timed out, or any other outage — since a
|
|
179
|
+
* keyword search does not depend on the embedding service and can answer while it is down.
|
|
180
|
+
*/
|
|
181
|
+
export declare const SEMANTIC_UNAVAILABLE_HINT = "OpenAlex semantic search is failing upstream. Retry in a minute, or rerun with search_mode \"keyword\", which does not depend on it.";
|
|
182
|
+
/**
|
|
183
|
+
* Recovery for a spent daily budget on a server that sends no API key. It runs on the smaller
|
|
184
|
+
* anonymous budget, so a key is the one fix besides waiting. A keyed server's budget is already
|
|
185
|
+
* the larger one, and a caller of a shared endpoint cannot set the server's environment, so that
|
|
186
|
+
* case keeps the key-neutral recovery each tool's contract declares.
|
|
187
|
+
*/
|
|
188
|
+
export declare const BUDGET_EXHAUSTED_KEYLESS_HINT = "This server's daily OpenAlex budget is spent and refills at midnight UTC \u2014 retrying before then will not succeed. The server sends no OpenAlex API key, so it runs on the smaller anonymous budget; setting OPENALEX_API_KEY to a free key (https://openalex.org/settings/api) raises it.";
|
|
189
|
+
/**
|
|
190
|
+
* The server's own message for a plan-gated filter, naming the filter when the upstream message
|
|
191
|
+
* opens with it. The name is read as a field-name run only, so caller text the upstream clause
|
|
192
|
+
* echoes cannot carry markdown or a line break into the message.
|
|
193
|
+
*/
|
|
194
|
+
export declare function planGatedFilterMessage(upstreamMessage: string | undefined): string;
|
|
71
195
|
declare class OpenAlexService {
|
|
72
196
|
private readonly baseUrl;
|
|
73
197
|
private readonly apiKey;
|
|
74
198
|
private readonly mailto;
|
|
75
199
|
constructor();
|
|
76
|
-
/**
|
|
200
|
+
/**
|
|
201
|
+
* Execute an HTTP request against the OpenAlex API with retry on transient failures. With
|
|
202
|
+
* `deadlineMs`, every attempt and backoff settles within that many milliseconds, after which
|
|
203
|
+
* the request fails as a `Timeout`.
|
|
204
|
+
*/
|
|
77
205
|
private request;
|
|
78
206
|
private throwNormalizedRequestError;
|
|
79
207
|
private parseResponse;
|
|
80
208
|
/** Search/filter/sort entities, or retrieve a single entity by ID. */
|
|
81
209
|
search(params: SearchParams, ctx: Context): Promise<SearchResult>;
|
|
210
|
+
/**
|
|
211
|
+
* Look a funder up by its Crossref Funder Registry DOI. OpenAlex's `/funders/doi:` path
|
|
212
|
+
* resolves nothing, so this is a one-result list request on the `ids.doi` filter, which OpenAlex
|
|
213
|
+
* bills like any list request. A value the filter would read as more than one literal DOI fails
|
|
214
|
+
* as not found without a request (see `funderDoiFilter`).
|
|
215
|
+
*/
|
|
216
|
+
private funderByDoi;
|
|
82
217
|
/** Group-by aggregation. */
|
|
83
218
|
analyze(params: AnalyzeParams, ctx: Context): Promise<AnalyzeResult>;
|
|
84
219
|
/**
|
|
85
|
-
* Resolve an identifier to the
|
|
220
|
+
* Resolve an identifier to the entities it addresses, shaped as autocomplete matches — one
|
|
221
|
+
* lookup per entity type in `identifier.entityTypes`, run in parallel, with the records found
|
|
222
|
+
* returned in that order.
|
|
86
223
|
*
|
|
87
224
|
* Autocomplete matches on `display_name` and the external-ID URL, so whether an identifier
|
|
88
225
|
* resolves through it depends on scheme, bare-vs-URL form, and entity type — a bare ORCID or
|
|
@@ -93,22 +230,50 @@ declare class OpenAlexService {
|
|
|
93
230
|
* A miss returns no results rather than throwing. Autocomplete answers an unmatched query with
|
|
94
231
|
* an empty list, and routing identifiers through here is meant to make them behave *more* like
|
|
95
232
|
* the front door, not to hand one class of query a hard failure the rest never sees.
|
|
233
|
+
*
|
|
234
|
+
* A lookup that fails for any other reason drops only its own type, named in
|
|
235
|
+
* `failedEntityTypes`, while another type returned a record. With no record to return, or once
|
|
236
|
+
* the caller has cancelled, the failure is thrown instead — an empty or partial answer there
|
|
237
|
+
* would claim records do not exist when the lookup for them never finished.
|
|
238
|
+
*
|
|
239
|
+
* `nameSearch` is the autocomplete to run when every lookup finds nothing — for a query that
|
|
240
|
+
* may be a name rather than an ID (`ResolvedIdentifier.mayBeName`). It runs only on that miss,
|
|
241
|
+
* so an ID that resolves still costs its one request, and only within what is left of
|
|
242
|
+
* `NAME_FALLBACK_DEADLINE_MS` from the start of this call (see `nameSearchAfterMiss`).
|
|
243
|
+
*
|
|
244
|
+
* `query` is the text `identifier` was read from, as the caller wrote it. The lookups are sent
|
|
245
|
+
* that spelling, which `search()` normalizes back to `identifier.id`, so a lookup that refuses
|
|
246
|
+
* the identifier quotes what the caller sent.
|
|
247
|
+
*/
|
|
248
|
+
resolveIdentifier(identifier: ResolvedIdentifier, ctx: Context, nameSearch?: AutocompleteParams, query?: string): Promise<IdentifierResolution>;
|
|
249
|
+
/**
|
|
250
|
+
* The name search an identifier lookup falls back to after finding nothing, bounded by the
|
|
251
|
+
* `remainingMs` the lookup left of the call's deadline. It is a best-effort second reading of
|
|
252
|
+
* the query, so a transient upstream failure — a timeout, the deadline running out, an outage,
|
|
253
|
+
* a burst throttle — comes back as `nameFallback.failedReason` for the caller to see, beside
|
|
254
|
+
* the lookup's own true miss. A caller cancellation, a request upstream rejected, a spent
|
|
255
|
+
* budget, and anything unclassified are thrown: none of them is cured by calling again, and an
|
|
256
|
+
* answer in their place would hide the error the caller needs to act on.
|
|
257
|
+
*/
|
|
258
|
+
private nameSearchAfterMiss;
|
|
259
|
+
/**
|
|
260
|
+
* Autocomplete name resolution. `deadlineMs` bounds the whole request, retries included (see
|
|
261
|
+
* `request`).
|
|
96
262
|
*/
|
|
97
|
-
|
|
98
|
-
/** Autocomplete name resolution. */
|
|
99
|
-
autocomplete(params: AutocompleteParams, ctx: Context): Promise<AutocompleteResult>;
|
|
263
|
+
autocomplete(params: AutocompleteParams, ctx: Context, deadlineMs?: number): Promise<AutocompleteResult>;
|
|
100
264
|
}
|
|
101
265
|
export declare function initOpenAlexService(): void;
|
|
102
266
|
export declare function getOpenAlexService(): OpenAlexService;
|
|
267
|
+
type FieldCatalog = Record<EntityType, {
|
|
268
|
+
filter: string[];
|
|
269
|
+
select: string[];
|
|
270
|
+
}>;
|
|
103
271
|
/**
|
|
104
272
|
* Return the typed field catalog keyed by entity type → context → field list.
|
|
105
273
|
* Only `filter` and `select` arrays are stored. `group_by` resolves to the `filter` key here;
|
|
106
274
|
* the describe-fields handler then prunes the fields group_by cannot target (raw dates,
|
|
107
275
|
* `*.search` operators, `from_*`/`to_*` range modifiers, and a per-type set from a live sweep).
|
|
108
276
|
*/
|
|
109
|
-
export declare function getFieldCatalog():
|
|
110
|
-
filter: string[];
|
|
111
|
-
select: string[];
|
|
112
|
-
}>;
|
|
277
|
+
export declare function getFieldCatalog(): FieldCatalog;
|
|
113
278
|
export {};
|
|
114
279
|
//# sourceMappingURL=openalex-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openalex-service.d.ts","sourceRoot":"","sources":["../../../src/services/openalex/openalex-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"openalex-service.d.ts","sourceRoot":"","sources":["../../../src/services/openalex/openalex-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AA6BtD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAGvB,KAAK,YAAY,EACjB,KAAK,UAAU,EAEf,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAoBpB,iFAAiF;AACjF,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAcjE;AA6BD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,8OACgM,CAAC;AAqFpO;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAiF9C;AAwED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,MAAM,CAUlF;AAED,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,8FAA8F;IAC9F,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IACnC,gGAAgG;IAChG,EAAE,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wCAAwC;AACxC,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,UAAU,EAAE,CAAC;IACjC;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,UAAU,GACrB,kBAAkB,GAAG,SAAS,CAyBhC;AA8LD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,YAAY,GACnB,kBAAkB,CAUpB;AASD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAmG/C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI7F;AAqCD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9F;AA4BD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,EACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAER;AAkSD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,yIACgG,CAAC;AA6BvI;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,mSACmP,CAAC;AAe9R;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKlF;AAiJD,cAAM,eAAe;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,cAKC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAsDf,OAAO,CAAC,2BAA2B;IA2InC,OAAO,CAAC,aAAa;IAqCrB,sEAAsE;IAChE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAqGtE;IAED;;;;;OAKG;YACW,WAAW;IA2BzB,4BAA4B;IACtB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CA2DzE;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,iBAAiB,CACrB,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,OAAO,EACZ,UAAU,CAAC,EAAE,kBAAkB,EAC/B,KAAK,GAAE,MAAsB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAuC/B;IAED;;;;;;;;OAQG;YACW,mBAAmB;IAyBjC;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,kBAAkB,EAC1B,GAAG,EAAE,OAAO,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAsB7B;CACF;AAID,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAIpD;AAED,KAAK,YAAY,GAAG,MAAM,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAY/E;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAE9C"}
|