@inflexa-ai/harness 0.30.2 → 0.31.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/dist/contracts/target-dossier.d.ts +61 -61
- package/dist/execution/run-synthesis.js +7 -2
- package/dist/lib/zod-issues.d.ts +8 -0
- package/dist/lib/zod-issues.js +13 -0
- package/dist/literature/sources/semantic-scholar.d.ts +34 -0
- package/dist/literature/sources/semantic-scholar.js +15 -4
- package/dist/sandbox/cpu-files.d.ts +37 -0
- package/dist/sandbox/cpu-files.js +55 -0
- package/dist/sandbox/docker-client.d.ts +15 -0
- package/dist/sandbox/docker-client.js +100 -11
- package/dist/sandbox/k8s-client.d.ts +5 -0
- package/dist/sandbox/k8s-client.js +128 -19
- package/dist/sandbox/thread-env.d.ts +29 -0
- package/dist/sandbox/thread-env.js +49 -0
- package/dist/state/data-profile.d.ts +35 -0
- package/dist/state/data-profile.js +56 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -1
- package/dist/tasks/data-profile.d.ts +16 -1
- package/dist/tasks/data-profile.js +31 -10
- package/dist/tools/bio/chembl.js +4 -3
- package/dist/tools/bio/drug-gene-interactions.d.ts +2 -14
- package/dist/tools/bio/drug-gene-interactions.js +10 -18
- package/dist/tools/bio/gene-disease-evidence.d.ts +3 -1
- package/dist/tools/bio/gene-disease-evidence.js +12 -9
- package/dist/tools/bio/keys.js +1 -0
- package/dist/tools/bio/lookup-annotation.d.ts +43 -0
- package/dist/tools/bio/lookup-annotation.js +19 -4
- package/dist/tools/bio/pubchem.js +5 -3
- package/dist/tools/bio/search-clinical-trials.js +5 -4
- package/dist/tools/bio/search-geo-datasets.d.ts +39 -9
- package/dist/tools/bio/search-geo-datasets.js +38 -20
- package/dist/tools/lib/api-utils.d.ts +27 -2
- package/dist/tools/lib/api-utils.js +43 -3
- package/dist/tools/lib/bgee-client.d.ts +16 -0
- package/dist/tools/lib/bgee-client.js +16 -5
- package/dist/tools/lib/cbioportal-client.d.ts +20 -0
- package/dist/tools/lib/cbioportal-client.js +16 -8
- package/dist/tools/lib/chembl-client.d.ts +105 -3
- package/dist/tools/lib/chembl-client.js +196 -84
- package/dist/tools/lib/clinical-benchmarks-client.d.ts +5 -0
- package/dist/tools/lib/clinical-benchmarks-client.js +5 -0
- package/dist/tools/lib/clinical-trials-client.d.ts +131 -2
- package/dist/tools/lib/clinical-trials-client.js +32 -6
- package/dist/tools/lib/clinvar-client.d.ts +35 -0
- package/dist/tools/lib/clinvar-client.js +34 -28
- package/dist/tools/lib/ctx-ops.d.ts +106 -35
- package/dist/tools/lib/ctx-ops.js +135 -69
- package/dist/tools/lib/dgidb-client.d.ts +73 -0
- package/dist/tools/lib/dgidb-client.js +25 -13
- package/dist/tools/lib/disgenet-client.d.ts +117 -24
- package/dist/tools/lib/disgenet-client.js +127 -34
- package/dist/tools/lib/disgenet-config.d.ts +1 -1
- package/dist/tools/lib/disgenet-config.js +5 -3
- package/dist/tools/lib/drugbank-client.d.ts +57 -58
- package/dist/tools/lib/drugbank-client.js +69 -64
- package/dist/tools/lib/drugbank-config.d.ts +6 -1
- package/dist/tools/lib/drugbank-config.js +6 -1
- package/dist/tools/lib/ema-client.d.ts +53 -0
- package/dist/tools/lib/ema-client.js +19 -7
- package/dist/tools/lib/ensembl-client.d.ts +4 -0
- package/dist/tools/lib/ensembl-client.js +4 -0
- package/dist/tools/lib/gwas-catalog-client.d.ts +64 -1
- package/dist/tools/lib/gwas-catalog-client.js +21 -6
- package/dist/tools/lib/identifier-resolver.d.ts +17 -1
- package/dist/tools/lib/identifier-resolver.js +13 -4
- package/dist/tools/lib/impc-client.d.ts +4 -0
- package/dist/tools/lib/impc-client.js +4 -0
- package/dist/tools/lib/iuphar-client.d.ts +10 -5
- package/dist/tools/lib/iuphar-client.js +49 -13
- package/dist/tools/lib/monarch-client.d.ts +4 -0
- package/dist/tools/lib/monarch-client.js +4 -0
- package/dist/tools/lib/openfda-client.d.ts +34 -0
- package/dist/tools/lib/openfda-client.js +22 -8
- package/dist/tools/lib/opentargets-client.d.ts +99 -4
- package/dist/tools/lib/opentargets-client.js +97 -37
- package/dist/tools/lib/pathway-client.d.ts +45 -0
- package/dist/tools/lib/pathway-client.js +88 -8
- package/dist/tools/lib/pharmgkb-client.d.ts +35 -1
- package/dist/tools/lib/pharmgkb-client.js +22 -6
- package/dist/tools/lib/pharmgkb-config.d.ts +8 -1
- package/dist/tools/lib/pharmgkb-config.js +8 -1
- package/dist/tools/lib/pubchem-client.d.ts +22 -0
- package/dist/tools/lib/pubchem-client.js +36 -33
- package/dist/tools/lib/pubchem-ops.d.ts +85 -5
- package/dist/tools/lib/pubchem-ops.js +96 -68
- package/dist/tools/lib/pubmed-client.d.ts +4 -0
- package/dist/tools/lib/pubmed-client.js +4 -0
- package/dist/tools/lib/string-client.d.ts +52 -0
- package/dist/tools/lib/string-client.js +12 -7
- package/dist/tools/lib/uniprot-client.d.ts +4 -0
- package/dist/tools/lib/uniprot-client.js +4 -0
- package/dist/tools/research/context7-docs.d.ts +23 -0
- package/dist/tools/research/context7-docs.js +49 -9
- package/dist/tools/research/search-github-repos.d.ts +4 -0
- package/dist/tools/research/search-github-repos.js +4 -0
- package/dist/workflows/execute-target-assessment.js +4 -4
- package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +2 -1
- package/dist/workflows/target-assessment/assemblers/orchestrator.js +3 -3
- package/dist/workflows/target-assessment/collectors/index.d.ts +8 -2
- package/dist/workflows/target-assessment/collectors/index.js +37 -10
- package/dist/workflows/target-assessment/fanout/index.d.ts +2 -1
- package/dist/workflows/target-assessment/fanout/index.js +2 -2
- package/dist/workflows/target-assessment/lib/safety-corroboration.js +2 -2
- package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +3 -2
- package/dist/workflows/target-assessment/lib/target-identity-filter.js +16 -5
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +61 -60
- package/dist/workflows/target-assessment/phase4-assemble.js +2 -2
- package/dist/workflows/target-assessment/schemas.d.ts +2 -8
- package/dist/workflows/target-assessment/schemas.js +8 -2
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +1 -4
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -4
- package/package.json +1 -1
- package/dist/agents/sandbox/__fixtures__/deps.d.ts +0 -23
- package/dist/agents/sandbox/__fixtures__/deps.js +0 -102
- package/dist/citations/__fixtures__/resolver.d.ts +0 -3
- package/dist/citations/__fixtures__/resolver.js +0 -9
- package/dist/loop/__fixtures__/scripted-provider.d.ts +0 -31
- package/dist/loop/__fixtures__/scripted-provider.js +0 -81
- package/dist/providers/__fixtures__/session.d.ts +0 -17
- package/dist/providers/__fixtures__/session.js +0 -20
- package/dist/tools/__fixtures__/tool-context.d.ts +0 -13
- package/dist/tools/__fixtures__/tool-context.js +0 -22
|
@@ -10,20 +10,32 @@
|
|
|
10
10
|
* panels never list a sibling receptor-complex as a developable hit.
|
|
11
11
|
*/
|
|
12
12
|
import { z } from "zod";
|
|
13
|
-
import {
|
|
13
|
+
import { createNoopLogger } from "../../lib/console-logger.js";
|
|
14
|
+
import { apiFetchValidated, describeApiError, isUnexpectedApiError } from "./api-utils.js";
|
|
14
15
|
import { IUPHAR_BASE, IUPHAR_HEADERS as HEADERS } from "./iuphar-config.js";
|
|
15
|
-
// Validated at the fetch boundary. GtoPdb
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
16
|
+
// Validated at the fetch boundary. GtoPdb serves the target record in three
|
|
17
|
+
// wire shapes under this one schema, and the key set differs per shape:
|
|
18
|
+
//
|
|
19
|
+
// Shape A — the `/targets?…` list and `/targets/{id}/complexes`. It OMITS
|
|
20
|
+
// `complexIds`, and `type` is lower snake case (`gpcr`,
|
|
21
|
+
// `catalytic_receptor`, and `""` for an accessory protein).
|
|
22
|
+
// Shape B — `/targets/{id}/subunits`. It carries `complexIds` as a populated
|
|
23
|
+
// number array, and `type` is CamelCase (`GPCR`, `AccessoryProtein`).
|
|
24
|
+
// Shape C — `/targets/{id}`. Same key set as shape B, plus about 27 flat
|
|
25
|
+
// cross-reference keys, but `type` is the shape A casing again.
|
|
26
|
+
//
|
|
27
|
+
// Thus `complexIds` is optional, and its one read site in
|
|
28
|
+
// `getFamilyHeterodimers` guards the omission. `familyIds` stays required,
|
|
29
|
+
// because every shape sends it and an accessory protein sends `[]`. A missing
|
|
30
|
+
// `familyIds` surfaces as `invalid_response` rather than as a runtime
|
|
31
|
+
// TypeError.
|
|
32
|
+
export const IupharTargetSchema = z.object({
|
|
21
33
|
targetId: z.number(),
|
|
22
34
|
name: z.string(),
|
|
23
35
|
type: z.string().nullable().optional(),
|
|
24
36
|
familyIds: z.array(z.number()),
|
|
25
37
|
subunitIds: z.array(z.number()).optional(),
|
|
26
|
-
complexIds: z.array(z.number()),
|
|
38
|
+
complexIds: z.array(z.number()).optional(),
|
|
27
39
|
subunitType: z.string().optional(),
|
|
28
40
|
});
|
|
29
41
|
const UNIPROT_ACCESSION_RE = /^[A-Z][0-9][A-Z0-9]{3}[0-9]$/;
|
|
@@ -93,7 +105,11 @@ export async function getSubunits(complexId) {
|
|
|
93
105
|
*/
|
|
94
106
|
export async function getFamilyHeterodimers(uniprotOrGeneSymbol) {
|
|
95
107
|
const target = await resolveTarget(uniprotOrGeneSymbol);
|
|
96
|
-
|
|
108
|
+
// `resolveTarget` gives a shape A record, which omits `complexIds`. An
|
|
109
|
+
// omission thus says nothing about the complexes of the target, and only a
|
|
110
|
+
// present and empty array proves that there is none. `?.length === 0` is
|
|
111
|
+
// false for the omission, thus the `/complexes` call below answers for it.
|
|
112
|
+
if (!target || target.complexIds?.length === 0)
|
|
97
113
|
return [];
|
|
98
114
|
const url = `${IUPHAR_BASE}/targets/${target.targetId}/complexes`;
|
|
99
115
|
const res = await apiFetchValidated(url, z.array(IupharTargetSchema), { headers: HEADERS });
|
|
@@ -112,6 +128,12 @@ export async function getFamilyHeterodimers(uniprotOrGeneSymbol) {
|
|
|
112
128
|
const complex = batch[j];
|
|
113
129
|
const subunits = subunitLists[j];
|
|
114
130
|
const cleanedSubunits = subunits.map((s) => ({ ...s, name: stripHtml(s.name) }));
|
|
131
|
+
// Only a shape B row reaches this filter, because `getSubunits`
|
|
132
|
+
// calls `/targets/{id}/subunits`. Shape B is the one shape that
|
|
133
|
+
// names the kind of a target as `AccessoryProtein`, and the
|
|
134
|
+
// lower-case compare matches that CamelCase form. Shape A and shape
|
|
135
|
+
// C send `""` for the same target, thus the same filter over a list
|
|
136
|
+
// row or a single-target row would match nothing.
|
|
115
137
|
const accessories = cleanedSubunits.filter((s) => (s.type ?? "").toLowerCase() === "accessoryprotein");
|
|
116
138
|
results.push({
|
|
117
139
|
complex: { ...complex, name: stripHtml(complex.name) },
|
|
@@ -143,7 +165,7 @@ export async function getAccessoryProteinNames(uniprotOrGeneSymbol) {
|
|
|
143
165
|
}
|
|
144
166
|
// getFamilySiblingUniprots iterates `targetIds` without a guard, so it stays
|
|
145
167
|
// required; the other fields are not read, so they may be absent.
|
|
146
|
-
const IupharFamilySchema = z.object({
|
|
168
|
+
export const IupharFamilySchema = z.object({
|
|
147
169
|
familyId: z.number().optional(),
|
|
148
170
|
name: z.string().optional(),
|
|
149
171
|
targetIds: z.array(z.number()),
|
|
@@ -158,9 +180,15 @@ export async function getFamily(familyId) {
|
|
|
158
180
|
return null;
|
|
159
181
|
throw new Error(describeApiError(res.error));
|
|
160
182
|
}
|
|
183
|
+
// GtoPdb answers an unknown family with HTTP 200 and the sentinel record
|
|
184
|
+
// `{familyId: -1, targetIds: []}`, never with a 404. Thus the sentinel is
|
|
185
|
+
// the one signal that the family does not exist, and the `notFound` branch
|
|
186
|
+
// above cannot report it.
|
|
187
|
+
if (res.value.familyId === -1)
|
|
188
|
+
return null;
|
|
161
189
|
return res.value;
|
|
162
190
|
}
|
|
163
|
-
const IupharDatabaseLinkSchema = z.object({
|
|
191
|
+
export const IupharDatabaseLinkSchema = z.object({
|
|
164
192
|
accession: z.string().optional(),
|
|
165
193
|
database: z.string().optional(),
|
|
166
194
|
species: z.string().optional(),
|
|
@@ -193,7 +221,8 @@ export async function getTargetHumanUniprots(targetId) {
|
|
|
193
221
|
* CALCRL accession; the AMY1/2/3 complexes are excluded because they are
|
|
194
222
|
* heterodimers, not separate primary proteins.
|
|
195
223
|
*/
|
|
196
|
-
export async function getFamilySiblingUniprots(uniprotOrGeneSymbol) {
|
|
224
|
+
export async function getFamilySiblingUniprots(uniprotOrGeneSymbol, logger) {
|
|
225
|
+
const log = (logger ?? createNoopLogger()).named("iuphar-client.family-siblings").with({ query: uniprotOrGeneSymbol });
|
|
197
226
|
const self = await resolveTarget(uniprotOrGeneSymbol);
|
|
198
227
|
if (!self)
|
|
199
228
|
return [];
|
|
@@ -221,8 +250,15 @@ export async function getFamilySiblingUniprots(uniprotOrGeneSymbol) {
|
|
|
221
250
|
const uniprotLists = await Promise.all(batch.map(async (tid) => {
|
|
222
251
|
const url = `${IUPHAR_BASE}/targets/${tid}`;
|
|
223
252
|
const res = await apiFetchValidated(url, IupharTargetSchema, { headers: HEADERS });
|
|
224
|
-
if (res.isErr())
|
|
253
|
+
if (res.isErr()) {
|
|
254
|
+
// A sibling that GtoPdb does not serve is a normal miss, and the
|
|
255
|
+
// loop drops it. But a contract break drops every sibling in the
|
|
256
|
+
// same way, thus an unexpected cause reaches the Logger first.
|
|
257
|
+
if (isUnexpectedApiError(res.error)) {
|
|
258
|
+
log.error("sibling target dropped from the result", { targetId: tid, cause: describeApiError(res.error) });
|
|
259
|
+
}
|
|
225
260
|
return [];
|
|
261
|
+
}
|
|
226
262
|
const t = res.value;
|
|
227
263
|
if (t.subunitIds && t.subunitIds.length > 0)
|
|
228
264
|
return [];
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
* rather than by matching prose.
|
|
12
12
|
*
|
|
13
13
|
* The API is keyless and public.
|
|
14
|
+
*
|
|
15
|
+
* Absence policy: the OpenAPI document of Monarch declares an absent value as
|
|
16
|
+
* `anyOf` with `null`, thus the API sends an explicit `null`. A maybe-absent
|
|
17
|
+
* field carries `.nullish()` exactly.
|
|
14
18
|
*/
|
|
15
19
|
/** A curated human phenotype attributed to variation in the gene. */
|
|
16
20
|
export interface MonarchPhenotypeAssociation {
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
* rather than by matching prose.
|
|
12
12
|
*
|
|
13
13
|
* The API is keyless and public.
|
|
14
|
+
*
|
|
15
|
+
* Absence policy: the OpenAPI document of Monarch declares an absent value as
|
|
16
|
+
* `anyOf` with `null`, thus the API sends an explicit `null`. A maybe-absent
|
|
17
|
+
* field carries `.nullish()` exactly.
|
|
14
18
|
*/
|
|
15
19
|
import { z } from "zod";
|
|
16
20
|
import { apiFetchValidated, describeApiError, isUnexpectedApiError } from "./api-utils.js";
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Used by §2.6.2 (FAERS summary) and §2.6.6 (class precedent — drugs-in-class
|
|
5
5
|
* AEs).
|
|
6
|
+
*
|
|
7
|
+
* Absence policy: openFDA omits the key of an absent value, and the `openfda`
|
|
8
|
+
* object can arrive as `{}`. Thus a maybe-absent field carries `.optional()`,
|
|
9
|
+
* not `.nullable()`.
|
|
6
10
|
*/
|
|
11
|
+
import { z } from "zod";
|
|
7
12
|
export interface AdverseEventCount {
|
|
8
13
|
reaction: string;
|
|
9
14
|
count: number;
|
|
@@ -42,6 +47,35 @@ export declare function getFaersByDrug(drugName: string, options?: {
|
|
|
42
47
|
* and §2.6.8 risk summary.
|
|
43
48
|
*/
|
|
44
49
|
export declare function getFaersSeriousness(drugName: string): Promise<SeriousnessProfile | null>;
|
|
50
|
+
export declare const OpenFdaLabelResponseSchema: z.ZodObject<{
|
|
51
|
+
results: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodObject<{
|
|
52
|
+
set_id: z.ZodOptional<z.ZodUnknown>;
|
|
53
|
+
openfda: z.ZodOptional<z.ZodObject<{
|
|
54
|
+
application_number: z.ZodOptional<z.ZodUnknown>;
|
|
55
|
+
brand_name: z.ZodOptional<z.ZodUnknown>;
|
|
56
|
+
generic_name: z.ZodOptional<z.ZodUnknown>;
|
|
57
|
+
}, z.core.$strip>>;
|
|
58
|
+
effective_time: z.ZodOptional<z.ZodUnknown>;
|
|
59
|
+
boxed_warning: z.ZodOptional<z.ZodUnknown>;
|
|
60
|
+
warnings_and_cautions: z.ZodOptional<z.ZodUnknown>;
|
|
61
|
+
warnings: z.ZodOptional<z.ZodUnknown>;
|
|
62
|
+
spl_medguide: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
63
|
+
patient_medication_information: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
64
|
+
}, z.core.$strip>, z.ZodTransform<DrugLabelAction, {
|
|
65
|
+
set_id?: unknown;
|
|
66
|
+
openfda?: {
|
|
67
|
+
application_number?: unknown;
|
|
68
|
+
brand_name?: unknown;
|
|
69
|
+
generic_name?: unknown;
|
|
70
|
+
} | undefined;
|
|
71
|
+
effective_time?: unknown;
|
|
72
|
+
boxed_warning?: unknown;
|
|
73
|
+
warnings_and_cautions?: unknown;
|
|
74
|
+
warnings?: unknown;
|
|
75
|
+
spl_medguide?: string[] | undefined;
|
|
76
|
+
patient_medication_information?: string[] | undefined;
|
|
77
|
+
}>>>>;
|
|
78
|
+
}, z.core.$strip>;
|
|
45
79
|
/**
|
|
46
80
|
* Fetch FDA Structured Product Label entries by drug name. The name matches
|
|
47
81
|
* the generic name or the brand name, thus a caller that holds only a brand
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Used by §2.6.2 (FAERS summary) and §2.6.6 (class precedent — drugs-in-class
|
|
5
5
|
* AEs).
|
|
6
|
+
*
|
|
7
|
+
* Absence policy: openFDA omits the key of an absent value, and the `openfda`
|
|
8
|
+
* object can arrive as `{}`. Thus a maybe-absent field carries `.optional()`,
|
|
9
|
+
* not `.nullable()`.
|
|
6
10
|
*/
|
|
7
11
|
import { z } from "zod";
|
|
8
12
|
import { apiFetchValidated, describeApiError } from "./api-utils.js";
|
|
@@ -22,7 +26,13 @@ const OpenFdaLabelMetaSchema = z.object({
|
|
|
22
26
|
brand_name: z.unknown().optional(),
|
|
23
27
|
generic_name: z.unknown().optional(),
|
|
24
28
|
});
|
|
25
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* A single openFDA structured-product-label record (raw wire shape).
|
|
31
|
+
*
|
|
32
|
+
* `spl_medguide` and `patient_medication_information` are the two label sections
|
|
33
|
+
* that carry the patient-facing safety documents. The field reference of the
|
|
34
|
+
* provider types both as an array of string.
|
|
35
|
+
*/
|
|
26
36
|
const OpenFdaLabelSchema = z.object({
|
|
27
37
|
set_id: z.unknown().optional(),
|
|
28
38
|
openfda: OpenFdaLabelMetaSchema.optional(),
|
|
@@ -30,9 +40,8 @@ const OpenFdaLabelSchema = z.object({
|
|
|
30
40
|
boxed_warning: z.unknown().optional(),
|
|
31
41
|
warnings_and_cautions: z.unknown().optional(),
|
|
32
42
|
warnings: z.unknown().optional(),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
medication_guide: z.unknown().optional(),
|
|
43
|
+
spl_medguide: z.array(z.string()).optional(),
|
|
44
|
+
patient_medication_information: z.array(z.string()).optional(),
|
|
36
45
|
});
|
|
37
46
|
/**
|
|
38
47
|
* Escape a value for embedding inside a double-quoted openFDA (Lucene) phrase.
|
|
@@ -166,8 +175,12 @@ function buildLabelSourceUrl(label) {
|
|
|
166
175
|
}
|
|
167
176
|
function mapLabel(raw) {
|
|
168
177
|
const openfda = raw?.openfda ?? {};
|
|
169
|
-
|
|
170
|
-
|
|
178
|
+
// The label reference carries no REMS field, thus the signal is the word
|
|
179
|
+
// itself in one of the three sections that a REMS program writes to. The
|
|
180
|
+
// presence of a medication guide alone is not the signal: many labels with no
|
|
181
|
+
// REMS carry one, and a presence test would report a REMS that does not exist.
|
|
182
|
+
const remsTextCandidates = [raw?.boxed_warning, raw?.spl_medguide, raw?.patient_medication_information];
|
|
183
|
+
const hasRems = remsTextCandidates.some((v) => joinSection(v)?.toLowerCase().includes("rems") ?? false);
|
|
171
184
|
return {
|
|
172
185
|
applicationNumber: firstString(openfda.application_number),
|
|
173
186
|
brandName: firstString(openfda.brand_name),
|
|
@@ -181,8 +194,9 @@ function mapLabel(raw) {
|
|
|
181
194
|
}
|
|
182
195
|
// The label endpoint's records are mapped to `DrugLabelAction` rows by
|
|
183
196
|
// `mapLabel` — a context-free normalize folded into the schema so ONE schema
|
|
184
|
-
// validates the raw wire AND emits the output rows.
|
|
185
|
-
|
|
197
|
+
// validates the raw wire AND emits the output rows. It is exported so that the
|
|
198
|
+
// golden-fixture table drives it.
|
|
199
|
+
export const OpenFdaLabelResponseSchema = z.object({
|
|
186
200
|
results: z.array(OpenFdaLabelSchema.transform(mapLabel)).optional(),
|
|
187
201
|
});
|
|
188
202
|
/**
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* Pure async client functions for the Open Targets Platform GraphQL API.
|
|
3
3
|
*
|
|
4
4
|
* Used directly by target-assessment workflow steps and by tool wrappers.
|
|
5
|
+
*
|
|
6
|
+
* Absence policy: the nullability of the GraphQL SDL encodes an absent value.
|
|
7
|
+
* Open Targets answers each requested field with a key and an explicit `null`,
|
|
8
|
+
* thus the SDL gives each modifier and `.optional()` is wrong.
|
|
5
9
|
*/
|
|
10
|
+
import { z } from "zod";
|
|
6
11
|
export interface Association {
|
|
7
12
|
diseaseId: string;
|
|
8
13
|
diseaseName: string;
|
|
@@ -50,6 +55,13 @@ export interface BaselineExpressionEntry {
|
|
|
50
55
|
tissueId: string;
|
|
51
56
|
tissueLabel: string;
|
|
52
57
|
organSystem: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* The Open Targets datasource of the row, for example `gtex`,
|
|
60
|
+
* `tabula_sapiens` or `DICE`. One target carries rows of more than one
|
|
61
|
+
* datasource, and each datasource has its own unit and its own resolution.
|
|
62
|
+
* Thus a consumer that compares two entries must first compare this value.
|
|
63
|
+
*/
|
|
64
|
+
datasourceId: string;
|
|
53
65
|
rna: {
|
|
54
66
|
value: number;
|
|
55
67
|
unit: string;
|
|
@@ -58,6 +70,82 @@ export interface BaselineExpressionEntry {
|
|
|
58
70
|
level: number | null;
|
|
59
71
|
} | null;
|
|
60
72
|
}
|
|
73
|
+
export declare const TargetAssociationsDataSchema: z.ZodObject<{
|
|
74
|
+
target: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
75
|
+
id: z.ZodString;
|
|
76
|
+
approvedSymbol: z.ZodString;
|
|
77
|
+
approvedName: z.ZodString;
|
|
78
|
+
tractability: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
79
|
+
label: z.ZodOptional<z.ZodString>;
|
|
80
|
+
modality: z.ZodOptional<z.ZodString>;
|
|
81
|
+
value: z.ZodOptional<z.ZodBoolean>;
|
|
82
|
+
}, z.core.$strip>>>>;
|
|
83
|
+
}, z.core.$strip>>>;
|
|
84
|
+
associations: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
85
|
+
associatedDiseases: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
rows: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
87
|
+
disease: z.ZodObject<{
|
|
88
|
+
id: z.ZodString;
|
|
89
|
+
name: z.ZodString;
|
|
90
|
+
}, z.core.$strip>;
|
|
91
|
+
score: z.ZodNumber;
|
|
92
|
+
datatypeScores: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
93
|
+
id: z.ZodOptional<z.ZodString>;
|
|
94
|
+
score: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
}, z.core.$strip>>>>;
|
|
96
|
+
}, z.core.$strip>>>>;
|
|
97
|
+
}, z.core.$strip>>;
|
|
98
|
+
}, z.core.$strip>>>;
|
|
99
|
+
}, z.core.$strip>;
|
|
100
|
+
export declare const TargetSafetyDataSchema: z.ZodObject<{
|
|
101
|
+
target: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
102
|
+
id: z.ZodOptional<z.ZodString>;
|
|
103
|
+
approvedSymbol: z.ZodString;
|
|
104
|
+
safetyLiabilities: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
105
|
+
event: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
106
|
+
biosamples: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
107
|
+
tissueLabel: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
108
|
+
}, z.core.$strip>>>>;
|
|
109
|
+
effects: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
110
|
+
direction: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
111
|
+
}, z.core.$strip>>>>;
|
|
112
|
+
datasource: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
113
|
+
}, z.core.$strip>>>>;
|
|
114
|
+
}, z.core.$strip>>>;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
/**
|
|
117
|
+
* `Target.baselineExpression`, per the SDL.
|
|
118
|
+
*
|
|
119
|
+
* The modifiers come from the SDL and from nothing else: `BaselineExpression!`
|
|
120
|
+
* and its `count`, `rows`, `unit`, `datasourceId` and `targetId` are non-null,
|
|
121
|
+
* the five quantile fields are `Float` and thus nullable, and each biosample
|
|
122
|
+
* link is a nullable `Biosample`.
|
|
123
|
+
*/
|
|
124
|
+
export declare const TargetExpressionDataSchema: z.ZodObject<{
|
|
125
|
+
target: z.ZodNullable<z.ZodObject<{
|
|
126
|
+
baselineExpression: z.ZodObject<{
|
|
127
|
+
count: z.ZodNumber;
|
|
128
|
+
rows: z.ZodArray<z.ZodObject<{
|
|
129
|
+
unit: z.ZodString;
|
|
130
|
+
median: z.ZodNullable<z.ZodNumber>;
|
|
131
|
+
q1: z.ZodNullable<z.ZodNumber>;
|
|
132
|
+
q3: z.ZodNullable<z.ZodNumber>;
|
|
133
|
+
min: z.ZodNullable<z.ZodNumber>;
|
|
134
|
+
max: z.ZodNullable<z.ZodNumber>;
|
|
135
|
+
datasourceId: z.ZodString;
|
|
136
|
+
targetId: z.ZodString;
|
|
137
|
+
tissueBiosample: z.ZodNullable<z.ZodObject<{
|
|
138
|
+
biosampleId: z.ZodString;
|
|
139
|
+
biosampleName: z.ZodString;
|
|
140
|
+
}, z.core.$strip>>;
|
|
141
|
+
tissueBiosampleParent: z.ZodNullable<z.ZodObject<{
|
|
142
|
+
biosampleId: z.ZodString;
|
|
143
|
+
biosampleName: z.ZodString;
|
|
144
|
+
}, z.core.$strip>>;
|
|
145
|
+
}, z.core.$strip>>;
|
|
146
|
+
}, z.core.$strip>;
|
|
147
|
+
}, z.core.$strip>>;
|
|
148
|
+
}, z.core.$strip>;
|
|
61
149
|
/** Fetch target info, tractability, and disease associations for an Ensembl gene id. */
|
|
62
150
|
export declare function searchTargetAssociations(ensemblId: string, limit?: number): Promise<TargetInfo | null>;
|
|
63
151
|
/** Fetch target associations for a disease (EFO id). */
|
|
@@ -77,8 +165,15 @@ export declare function getTargetSafetyLiabilities(ensemblId: string): Promise<{
|
|
|
77
165
|
safetyLiabilities: SafetyLiability[];
|
|
78
166
|
} | null>;
|
|
79
167
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
168
|
+
* Map one `baselineExpression` page onto the baseline-expression entries.
|
|
169
|
+
*
|
|
170
|
+
* The function is pure, thus the golden-fixture table exercises it against a
|
|
171
|
+
* stored payload.
|
|
172
|
+
*/
|
|
173
|
+
export declare function mapBaselineExpression(data: z.infer<typeof TargetExpressionDataSchema>): BaselineExpressionEntry[];
|
|
174
|
+
/**
|
|
175
|
+
* Fetch baseline RNA expression across tissues. Open Targets gives one row for
|
|
176
|
+
* each tissue and datasource, with the parent biosample as the organ system —
|
|
177
|
+
* used by §2.7 (Off-Tissue Risk) and §3.9 (Normal Tissue Expression).
|
|
83
178
|
*/
|
|
84
|
-
export declare function getBaselineExpression(ensemblId: string): Promise<BaselineExpressionEntry[]>;
|
|
179
|
+
export declare function getBaselineExpression(ensemblId: string, limit?: number): Promise<BaselineExpressionEntry[]>;
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* Pure async client functions for the Open Targets Platform GraphQL API.
|
|
3
3
|
*
|
|
4
4
|
* Used directly by target-assessment workflow steps and by tool wrappers.
|
|
5
|
+
*
|
|
6
|
+
* Absence policy: the nullability of the GraphQL SDL encodes an absent value.
|
|
7
|
+
* Open Targets answers each requested field with a key and an explicit `null`,
|
|
8
|
+
* thus the SDL gives each modifier and `.optional()` is wrong.
|
|
5
9
|
*/
|
|
6
10
|
import { z } from "zod";
|
|
7
11
|
import { apiFetchValidated, describeApiError } from "./api-utils.js";
|
|
@@ -79,22 +83,36 @@ const SAFETY_QUERY = `
|
|
|
79
83
|
}
|
|
80
84
|
`;
|
|
81
85
|
const EXPRESSION_QUERY = `
|
|
82
|
-
query
|
|
86
|
+
query TargetBaselineExpression($ensemblId: String!, $size: Int!) {
|
|
83
87
|
target(ensemblId: $ensemblId) {
|
|
84
88
|
id
|
|
85
89
|
approvedSymbol
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
baselineExpression(page: { size: $size, index: 0 }) {
|
|
91
|
+
count
|
|
92
|
+
rows {
|
|
93
|
+
unit
|
|
94
|
+
median
|
|
95
|
+
q1
|
|
96
|
+
q3
|
|
97
|
+
min
|
|
98
|
+
max
|
|
99
|
+
datasourceId
|
|
100
|
+
targetId
|
|
101
|
+
tissueBiosample { biosampleId biosampleName }
|
|
102
|
+
tissueBiosampleParent { biosampleId biosampleName }
|
|
91
103
|
}
|
|
92
|
-
rna { value unit }
|
|
93
|
-
protein { level }
|
|
94
104
|
}
|
|
95
105
|
}
|
|
96
106
|
}
|
|
97
107
|
`;
|
|
108
|
+
/**
|
|
109
|
+
* The page size of one `baselineExpression` request.
|
|
110
|
+
*
|
|
111
|
+
* `Pagination.size` caps at 3000 in the SDL, and one target carries more than
|
|
112
|
+
* 1400 rows. Thus a smaller page drops tissues, and it gives no signal that it
|
|
113
|
+
* dropped them.
|
|
114
|
+
*/
|
|
115
|
+
const BASELINE_EXPRESSION_PAGE_SIZE = 3000;
|
|
98
116
|
// Open Targets GraphQL `data` payload schemas, validated at the fetch boundary.
|
|
99
117
|
// Fields the mapping code reads behind a guard (optional chaining, `?? default`,
|
|
100
118
|
// `Array.isArray`) are `.nullable().optional()`; fields read directly — a missing
|
|
@@ -104,7 +122,7 @@ const EXPRESSION_QUERY = `
|
|
|
104
122
|
// that resolves empty — an unknown/retired id yields `{"target": null}`, which a
|
|
105
123
|
// bare `.optional()` rejects, turning a clean "not found" into a thrown error.
|
|
106
124
|
const DatatypeScoreSchema = z.object({ id: z.string().optional(), score: z.number().optional() });
|
|
107
|
-
const TargetAssociationsDataSchema = z.object({
|
|
125
|
+
export const TargetAssociationsDataSchema = z.object({
|
|
108
126
|
target: z
|
|
109
127
|
.object({
|
|
110
128
|
id: z.string(),
|
|
@@ -175,7 +193,7 @@ const DiseaseSearchDataSchema = z.object({
|
|
|
175
193
|
.nullable()
|
|
176
194
|
.optional(),
|
|
177
195
|
});
|
|
178
|
-
const TargetSafetyDataSchema = z.object({
|
|
196
|
+
export const TargetSafetyDataSchema = z.object({
|
|
179
197
|
target: z
|
|
180
198
|
.object({
|
|
181
199
|
id: z.string().optional(),
|
|
@@ -199,35 +217,57 @@ const TargetSafetyDataSchema = z.object({
|
|
|
199
217
|
.nullable()
|
|
200
218
|
.optional(),
|
|
201
219
|
});
|
|
202
|
-
|
|
220
|
+
/** `Biosample`, as `BaselineExpressionRow` embeds it. Both leaf fields are non-null in the SDL. */
|
|
221
|
+
const BiosampleSchema = z.object({ biosampleId: z.string(), biosampleName: z.string() });
|
|
222
|
+
/**
|
|
223
|
+
* `Target.baselineExpression`, per the SDL.
|
|
224
|
+
*
|
|
225
|
+
* The modifiers come from the SDL and from nothing else: `BaselineExpression!`
|
|
226
|
+
* and its `count`, `rows`, `unit`, `datasourceId` and `targetId` are non-null,
|
|
227
|
+
* the five quantile fields are `Float` and thus nullable, and each biosample
|
|
228
|
+
* link is a nullable `Biosample`.
|
|
229
|
+
*/
|
|
230
|
+
export const TargetExpressionDataSchema = z.object({
|
|
203
231
|
target: z
|
|
204
232
|
.object({
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
233
|
+
baselineExpression: z.object({
|
|
234
|
+
count: z.number(),
|
|
235
|
+
rows: z.array(z.object({
|
|
236
|
+
unit: z.string(),
|
|
237
|
+
median: z.number().nullable(),
|
|
238
|
+
q1: z.number().nullable(),
|
|
239
|
+
q3: z.number().nullable(),
|
|
240
|
+
min: z.number().nullable(),
|
|
241
|
+
max: z.number().nullable(),
|
|
242
|
+
datasourceId: z.string(),
|
|
243
|
+
targetId: z.string(),
|
|
244
|
+
tissueBiosample: BiosampleSchema.nullable(),
|
|
245
|
+
tissueBiosampleParent: BiosampleSchema.nullable(),
|
|
246
|
+
})),
|
|
247
|
+
}),
|
|
213
248
|
})
|
|
214
|
-
.nullable()
|
|
215
|
-
.optional(),
|
|
249
|
+
.nullable(),
|
|
216
250
|
});
|
|
217
251
|
function extractDatatype(datatypeScores, id) {
|
|
218
252
|
const match = datatypeScores.find((d) => d.id === id);
|
|
219
253
|
return match?.score ?? null;
|
|
220
254
|
}
|
|
221
255
|
async function gqlFetch(query, variables, schema) {
|
|
222
|
-
const res = await apiFetchValidated(OT_GRAPHQL, z.object({ data: schema.optional() }), {
|
|
256
|
+
const res = await apiFetchValidated(OT_GRAPHQL, z.object({ data: schema.optional(), errors: z.array(z.object({ message: z.string().optional() })).optional() }), {
|
|
223
257
|
method: "POST",
|
|
224
258
|
headers: OT_HEADERS,
|
|
225
259
|
body: JSON.stringify({ query, variables }),
|
|
226
260
|
});
|
|
227
261
|
if (res.isErr())
|
|
228
262
|
throw new Error(describeApiError(res.error));
|
|
229
|
-
if (!res.value.data)
|
|
230
|
-
|
|
263
|
+
if (!res.value.data) {
|
|
264
|
+
// A GraphQL server answers HTTP 200 with an `errors` array and no `data`
|
|
265
|
+
// key when the document itself is invalid, for example when it names a
|
|
266
|
+
// retired field. Without the first message the caller sees only "no
|
|
267
|
+
// data", which names no cause and points at no field.
|
|
268
|
+
const firstError = res.value.errors?.[0]?.message;
|
|
269
|
+
throw new Error(firstError ? `Open Targets returned no data: ${firstError}` : "Open Targets returned no data");
|
|
270
|
+
}
|
|
231
271
|
return res.value.data;
|
|
232
272
|
}
|
|
233
273
|
/** Fetch target info, tractability, and disease associations for an Ensembl gene id. */
|
|
@@ -318,18 +358,38 @@ export async function getTargetSafetyLiabilities(ensemblId) {
|
|
|
318
358
|
return { targetSymbol: target.approvedSymbol, safetyLiabilities };
|
|
319
359
|
}
|
|
320
360
|
/**
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
361
|
+
* Map one `baselineExpression` page onto the baseline-expression entries.
|
|
362
|
+
*
|
|
363
|
+
* The function is pure, thus the golden-fixture table exercises it against a
|
|
364
|
+
* stored payload.
|
|
365
|
+
*/
|
|
366
|
+
export function mapBaselineExpression(data) {
|
|
367
|
+
const entries = [];
|
|
368
|
+
for (const row of data.target?.baselineExpression.rows ?? []) {
|
|
369
|
+
// A row with no tissue biosample measures a cell type alone, thus it
|
|
370
|
+
// carries no tissue identity and it cannot become a tissue entry.
|
|
371
|
+
const tissue = row.tissueBiosample;
|
|
372
|
+
if (!tissue)
|
|
373
|
+
continue;
|
|
374
|
+
entries.push({
|
|
375
|
+
tissueId: tissue.biosampleId,
|
|
376
|
+
tissueLabel: tissue.biosampleName,
|
|
377
|
+
organSystem: row.tissueBiosampleParent?.biosampleName ?? null,
|
|
378
|
+
datasourceId: row.datasourceId,
|
|
379
|
+
rna: row.median === null ? null : { value: row.median, unit: row.unit },
|
|
380
|
+
// The `baselineExpression` surface carries no protein measurement,
|
|
381
|
+
// thus the protein level of an entry is always absent.
|
|
382
|
+
protein: null,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
return entries;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Fetch baseline RNA expression across tissues. Open Targets gives one row for
|
|
389
|
+
* each tissue and datasource, with the parent biosample as the organ system —
|
|
390
|
+
* used by §2.7 (Off-Tissue Risk) and §3.9 (Normal Tissue Expression).
|
|
324
391
|
*/
|
|
325
|
-
export async function getBaselineExpression(ensemblId) {
|
|
326
|
-
const data = await gqlFetch(EXPRESSION_QUERY, { ensemblId }, TargetExpressionDataSchema);
|
|
327
|
-
|
|
328
|
-
return expressions.map((e) => ({
|
|
329
|
-
tissueId: e.tissue.id,
|
|
330
|
-
tissueLabel: e.tissue.label,
|
|
331
|
-
organSystem: Array.isArray(e.tissue.organs) && e.tissue.organs.length > 0 ? e.tissue.organs[0] : null,
|
|
332
|
-
rna: e.rna && typeof e.rna.value === "number" ? { value: e.rna.value, unit: e.rna.unit ?? "TPM" } : null,
|
|
333
|
-
protein: e.protein ? { level: typeof e.protein.level === "number" ? e.protein.level : null } : null,
|
|
334
|
-
}));
|
|
392
|
+
export async function getBaselineExpression(ensemblId, limit = BASELINE_EXPRESSION_PAGE_SIZE) {
|
|
393
|
+
const data = await gqlFetch(EXPRESSION_QUERY, { ensemblId, size: limit }, TargetExpressionDataSchema);
|
|
394
|
+
return mapBaselineExpression(data);
|
|
335
395
|
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* Pure async client functions for biological pathway lookups via KEGG and Reactome.
|
|
3
3
|
*
|
|
4
4
|
* Used by §3.7 (Pathway Context).
|
|
5
|
+
*
|
|
6
|
+
* Absence policy: Reactome omits the key of an absent value, thus a maybe-absent
|
|
7
|
+
* field carries `.optional()`. KEGG serves plain text, not JSON, thus it has no
|
|
8
|
+
* key to omit.
|
|
5
9
|
*/
|
|
10
|
+
import { z } from "zod";
|
|
6
11
|
export declare function stripHtmlAndCollapseWs(s: string): string;
|
|
7
12
|
export type PathwaySource = "kegg" | "reactome";
|
|
8
13
|
export interface Pathway {
|
|
@@ -14,6 +19,25 @@ export interface Pathway {
|
|
|
14
19
|
entity_uniprots?: string[];
|
|
15
20
|
url?: string;
|
|
16
21
|
}
|
|
22
|
+
export declare const ReactomeSearchResponseSchema: z.ZodObject<{
|
|
23
|
+
results: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
24
|
+
entries: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
25
|
+
stId: z.ZodOptional<z.ZodString>;
|
|
26
|
+
name: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strip>>>;
|
|
28
|
+
}, z.core.$strip>>>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
/** Participant list — `searchReactome` reads `displayName` per participant. */
|
|
31
|
+
export declare const ReactomeParticipantsSchema: z.ZodArray<z.ZodObject<{
|
|
32
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
33
|
+
}, z.core.$strip>>;
|
|
34
|
+
/** Participant list — `getPathwayMemberships` reads `refEntities` per participant. */
|
|
35
|
+
export declare const ReactomeParticipantEntitiesSchema: z.ZodArray<z.ZodObject<{
|
|
36
|
+
refEntities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
37
|
+
schemaClass: z.ZodOptional<z.ZodString>;
|
|
38
|
+
identifier: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, z.core.$strip>>>;
|
|
40
|
+
}, z.core.$strip>>;
|
|
17
41
|
export interface PathwaySearchOptions {
|
|
18
42
|
source?: "kegg" | "reactome" | "both";
|
|
19
43
|
organism?: string;
|
|
@@ -21,6 +45,27 @@ export interface PathwaySearchOptions {
|
|
|
21
45
|
maxResults?: number;
|
|
22
46
|
}
|
|
23
47
|
export declare function searchKegg(query: string, organism: string, maxResults: number, includeGenes: boolean): Promise<Pathway[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Read the KEGG gene identifier of a symbol, for example `hsa:7157` for `TP53`.
|
|
50
|
+
*
|
|
51
|
+
* `find/{organism}/{symbol}` searches the gene names of one organism, and it
|
|
52
|
+
* ranks a partial name match above an exact one. A query for `TP53` puts
|
|
53
|
+
* `TP53BP2` first. Thus the caller matches the symbol against the alias list of
|
|
54
|
+
* each row, and it never takes the first row.
|
|
55
|
+
*/
|
|
56
|
+
export declare function selectKeggGeneId(rows: string[][], symbol: string): string | null;
|
|
57
|
+
/** The pathway identifiers of a `link/pathway/{geneId}` answer, without the `path:` prefix. */
|
|
58
|
+
export declare function parseKeggPathwayLinks(rows: string[][]): string[];
|
|
59
|
+
/**
|
|
60
|
+
* The pathways that hold one gene, from KEGG.
|
|
61
|
+
*
|
|
62
|
+
* `find/pathway/{query}` matches a pathway NAME only, thus a gene symbol gives
|
|
63
|
+
* an empty body there. The membership path is a gene resolution, then
|
|
64
|
+
* `link/pathway/{geneId}`, then one `list/pathway/{organism}` call for the
|
|
65
|
+
* names. The one list call costs about 22 kB and names every pathway of the
|
|
66
|
+
* organism, thus it replaces one `get/{id}` call for each membership.
|
|
67
|
+
*/
|
|
68
|
+
export declare function keggPathwaysForGene(geneSymbol: string, organism: string, maxResults: number): Promise<Pathway[]>;
|
|
24
69
|
export declare function searchReactome(query: string, species: string, maxResults: number, includeGenes: boolean): Promise<Pathway[]>;
|
|
25
70
|
export declare function searchPathways(query: string, options?: PathwaySearchOptions): Promise<Pathway[]>;
|
|
26
71
|
/**
|