@molgenis/vip-report-template 7.1.3 → 8.0.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/.gitattributes +3 -1
- package/README.md +13 -0
- package/eslint.config.mjs +6 -1
- package/package.json +6 -5
- package/scripts/validateConfig/README.txt +5 -0
- package/scripts/validateConfig/compileValidator.ts +17 -0
- package/scripts/validateConfig/createSchema.ts +6 -0
- package/scripts/validateConfig/schema.ts +370 -0
- package/src/App.tsx +2 -1
- package/src/components/DatasetDropdown.tsx +1 -1
- package/src/components/GenomeBrowser.tsx +14 -4
- package/src/components/RecordsTable.tsx +23 -6
- package/src/components/VariantConsequenceContainer.tsx +9 -2
- package/src/components/VariantInfoTable.tsx +1 -1
- package/src/components/VariantsContainer.tsx +47 -9
- package/src/components/VariantsContainerHeader.tsx +1 -8
- package/src/components/field/composed/FieldGenotype.tsx +1 -1
- package/src/components/field/composed/FieldGenotypeStr.tsx +18 -10
- package/src/components/field/composed/FieldGnomAd.tsx +1 -1
- package/src/components/field/composed/FieldInheritanceModes.tsx +1 -4
- package/src/components/field/composed/FieldVkgl.tsx +1 -1
- package/src/components/field/typed/FieldCategorical.tsx +1 -1
- package/src/components/field/typed/FieldCharacter.tsx +1 -1
- package/src/components/field/typed/FieldFlag.tsx +1 -1
- package/src/components/field/typed/FieldFloat.tsx +1 -1
- package/src/components/field/typed/FieldInteger.tsx +1 -1
- package/src/components/field/typed/FieldString.tsx +1 -1
- package/src/components/filter/Filter.tsx +1 -0
- package/src/components/filter/composed/FilterAllelicImbalance.tsx +1 -0
- package/src/components/filter/composed/FilterComposed.tsx +7 -0
- package/src/components/filter/composed/FilterDeNovo.tsx +1 -0
- package/src/components/filter/composed/FilterHpo.tsx +1 -0
- package/src/components/filter/composed/FilterInheritance.tsx +1 -0
- package/src/components/filter/composed/FilterLocus.tsx +17 -3
- package/src/components/filter/composed/FilterPick.tsx +30 -0
- package/src/components/filter/composed/FilterVipC.tsx +1 -0
- package/src/components/filter/composed/FilterVipCS.tsx +1 -0
- package/src/components/filter/fixed/FilterFixed.tsx +7 -0
- package/src/components/filter/typed/FilterCategorical.tsx +18 -1
- package/src/components/filter/typed/FilterFlag.tsx +2 -0
- package/src/components/filter/typed/FilterInterval.tsx +29 -1
- package/src/components/filter/typed/FilterString.tsx +8 -1
- package/src/components/filter/typed/FilterTyped.tsx +1 -0
- package/src/components/form/ButtonApply.tsx +6 -2
- package/src/mocks/GRCh38/README.txt +15 -0
- package/src/mocks/GRCh38/decisionTree.json +201 -0
- package/src/mocks/GRCh38/family.ped +6 -0
- package/src/mocks/GRCh38/field_metadata.json +36 -11
- package/src/mocks/GRCh38/sample1.ped +1 -0
- package/src/mocks/GRCh38/static.ts +36 -148
- package/src/mocks/GRCh38/str.ped +1 -0
- package/src/mocks/GRCh38/vcf/family.db.blob +0 -0
- package/src/mocks/GRCh38/vcf/family.vcf +312 -0
- package/src/mocks/GRCh38/vcf/fixPaths.sql +7 -0
- package/src/mocks/GRCh38/vcf/no_vep.db.blob +0 -0
- package/src/mocks/GRCh38/vcf/{no_vep.vcf.blob → no_vep.vcf} +1 -1
- package/src/mocks/GRCh38/vcf/samples_0.db.blob +0 -0
- package/src/mocks/GRCh38/vcf/samples_1.db.blob +0 -0
- package/src/mocks/GRCh38/vcf/samples_100.db.blob +0 -0
- package/src/mocks/GRCh38/vcf/{samples_100.vcf.blob → samples_100.vcf} +6 -6
- package/src/mocks/GRCh38/vcf/str.db.blob +0 -0
- package/src/mocks/GRCh38/vcf/{str.vcf.blob → str.vcf} +17 -17
- package/src/mocks/MockApiClient.ts +60 -226
- package/src/mocks/config_cram.json +4 -0
- package/src/mocks/config_default_values.json +722 -0
- package/src/mocks/config_vcf.json +15 -1
- package/src/mocks/sql-wasm.wasm.blob +0 -0
- package/src/types/config.d.ts +9 -5
- package/src/types/configCells.d.ts +1 -0
- package/src/types/configFilter.d.ts +1 -0
- package/src/types/configFilterComposed.d.ts +3 -0
- package/src/utils/api.ts +21 -49
- package/src/utils/config/configCellsComposed.ts +1 -1
- package/src/utils/config/configCellsField.ts +2 -0
- package/src/utils/config/configFiltersComposed.ts +7 -0
- package/src/utils/config/configFiltersField.ts +3 -2
- package/src/utils/config/configFiltersFixed.ts +7 -0
- package/src/utils/config/configValidator.precompiled.ts +83402 -0
- package/src/utils/config/configValidator.ts +3 -368
- package/src/utils/csq.ts +5 -10
- package/src/utils/decisionTree.ts +8 -9
- package/src/utils/query/query.ts +3 -2
- package/src/utils/query/queryFilter.ts +2 -3
- package/src/utils/query/queryFilterComposed.ts +12 -12
- package/src/utils/query/queryFilterField.ts +14 -7
- package/src/utils/query/queryFilterFixed.ts +5 -5
- package/src/utils/query/querySample.ts +15 -4
- package/src/utils/query/selector.ts +5 -20
- package/src/utils/query/sort.ts +4 -4
- package/src/utils/vcf.ts +20 -11
- package/src/views/Help.tsx +2 -2
- package/src/views/SampleVariant.tsx +4 -1
- package/src/views/Samples.tsx +10 -3
- package/src/views/data/data.tsx +2 -2
- package/tests/utils/config/configFiltersComposed.test.ts +2 -0
- package/tests/utils/config/configFiltersField.test.ts +4 -2
- package/tests/utils/config/configFiltersFixed.test.ts +23 -6
- package/tests/utils/query/query.test.ts +34 -6
- package/tests/utils/query/queryFilter.test.ts +4 -31
- package/tests/utils/query/queryFilterComposed.test.ts +13 -13
- package/tests/utils/query/queryFilterField.test.ts +5 -5
- package/tests/utils/query/queryFilterFixed.test.ts +5 -5
- package/tests/utils/query/querySample.test.ts +50 -10
- package/tests/utils/query/sort.test.ts +1 -1
- package/tests/utils/vcf.test.ts +1 -0
- package/vite.config.mts +2 -1
- package/src/mocks/GRCh37/alignment.cram.blob +0 -0
- package/src/mocks/GRCh37/alignment.cram.crai.blob +0 -0
- package/src/mocks/GRCh37/decisionTree.json +0 -355
- package/src/mocks/GRCh37/fasta/1-10042288-10042788.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/1-152520538-152521038.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/1-16375333-16375833.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/1-16376162-16376662.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/1-17348965-17349469.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/1-17348969-17349469.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/1-17354844-17355344.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/10-126091249-126091749.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/11-134013975-134014475.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/13-77569878-77570378.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/14-105167610-105168110.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/14-89307588-89308088.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/14-89309945-89310445.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/14-89336157-89336657.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/17-29555814-29556314.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/17-29585172-29585672.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/17-29663629-29664129.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/17-29675976-29676476.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/17-29683733-29684233.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/19-11215896-11216396.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/19-11223801-11224301.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/19-17449149-17449649.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/19-17451747-17452247.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/2-47635417-47635917.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/20-62326742-62327242.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/22-50627343-50627843.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/22-50721296-50721796.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/4-106320044-106320544.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/7-42017061-42017561.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/7-42064707-42065207.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/8-145140250-145140750.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/8-61764893-61765393.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/9-107546383-107546883.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/9-107584614-107585114.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/MT-15076-15576.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/X-48932771-48933271.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/fasta/Y-2655391-2655891.fasta.gz.blob +0 -0
- package/src/mocks/GRCh37/field_metadata.json +0 -794
- package/src/mocks/GRCh37/genes.gff.gz.blob +0 -0
- package/src/mocks/GRCh37/sampleTree.json +0 -143
- package/src/mocks/GRCh37/static.ts +0 -189
- package/src/mocks/GRCh37/vcf/family.vcf.blob +0 -134
- package/src/mocks/GRCh38/vcf/family.vcf.blob +0 -272
- package/src/mocks/static.ts +0 -1636
- /package/src/mocks/GRCh38/vcf/{samples_0.vcf.blob → samples_0.vcf} +0 -0
- /package/src/mocks/GRCh38/vcf/{samples_1.vcf.blob → samples_1.vcf} +0 -0
|
@@ -1,374 +1,9 @@
|
|
|
1
|
-
import Ajv, { JTDSchemaType } from "ajv/dist/jtd";
|
|
2
1
|
import { Json } from "@molgenis/vip-report-api";
|
|
3
2
|
import { ConfigValidationError } from "../error.ts";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
ConfigJsonField,
|
|
7
|
-
ConfigJsonFilter,
|
|
8
|
-
ConfigJsonRecordsPerPageOption,
|
|
9
|
-
ConfigJsonSort,
|
|
10
|
-
ConfigJsonSortOrder,
|
|
11
|
-
ConfigJsonVariant,
|
|
12
|
-
ConfigJsonVariantConsequence,
|
|
13
|
-
ConfigJsonVariants,
|
|
14
|
-
ConfigJsonVip,
|
|
15
|
-
ConfigJsonVipParams,
|
|
16
|
-
ConfigJsonVipParamsCram,
|
|
17
|
-
ConfigJsonVipParamsVcf,
|
|
18
|
-
} from "../../types/config";
|
|
3
|
+
import { ConfigJson } from "../../types/config";
|
|
4
|
+
import validate from "./configValidator.precompiled.ts";
|
|
19
5
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// allow additional properties so we can extend config in vip without updating vip-report-template
|
|
23
|
-
const schemaConfigJsonVipParamsVcf: JTDSchemaType<ConfigJsonVipParamsVcf> = {
|
|
24
|
-
properties: {
|
|
25
|
-
filter: {
|
|
26
|
-
properties: { classes: { type: "string" }, consequences: { type: "boolean" } },
|
|
27
|
-
additionalProperties: true,
|
|
28
|
-
},
|
|
29
|
-
filter_samples: {
|
|
30
|
-
properties: { classes: { type: "string" } },
|
|
31
|
-
additionalProperties: true,
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
additionalProperties: true,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// allow additional properties so we can extend config in vip without updating vip-report-template
|
|
38
|
-
const schemaConfigJsonVipParamsCram: JTDSchemaType<ConfigJsonVipParamsCram> = {
|
|
39
|
-
properties: {
|
|
40
|
-
call_snv: { type: "boolean" },
|
|
41
|
-
call_str: { type: "boolean" },
|
|
42
|
-
call_sv: { type: "boolean" },
|
|
43
|
-
call_cnv: { type: "boolean" },
|
|
44
|
-
},
|
|
45
|
-
additionalProperties: true,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// allow additional properties so we can extend config in vip without updating vip-report-template
|
|
49
|
-
const schemaConfigJsonVipParams: JTDSchemaType<ConfigJsonVipParams> = {
|
|
50
|
-
properties: {
|
|
51
|
-
vcf: schemaConfigJsonVipParamsVcf,
|
|
52
|
-
},
|
|
53
|
-
optionalProperties: {
|
|
54
|
-
cram: schemaConfigJsonVipParamsCram,
|
|
55
|
-
},
|
|
56
|
-
additionalProperties: true,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const schemaConfigJsonVip: JTDSchemaType<ConfigJsonVip> = {
|
|
60
|
-
properties: {
|
|
61
|
-
filter_field: {
|
|
62
|
-
properties: { type: { enum: ["genotype"] }, name: { type: "string" } },
|
|
63
|
-
optionalProperties: { label: { type: "string" }, description: { type: "string" } },
|
|
64
|
-
},
|
|
65
|
-
params: schemaConfigJsonVipParams,
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const schemaConfigJsonField: JTDSchemaType<ConfigJsonField> = {
|
|
70
|
-
discriminator: "type",
|
|
71
|
-
mapping: {
|
|
72
|
-
fixed: {
|
|
73
|
-
properties: {
|
|
74
|
-
name: { enum: ["chrom", "pos", "id", "ref", "alt", "qual", "filter"] },
|
|
75
|
-
},
|
|
76
|
-
optionalProperties: {
|
|
77
|
-
label: { type: "string" },
|
|
78
|
-
description: { type: "string" },
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
info: {
|
|
82
|
-
properties: {
|
|
83
|
-
name: { type: "string" },
|
|
84
|
-
},
|
|
85
|
-
optionalProperties: {
|
|
86
|
-
label: { type: "string" },
|
|
87
|
-
description: { type: "string" },
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
format: {
|
|
91
|
-
properties: {
|
|
92
|
-
name: { type: "string" },
|
|
93
|
-
},
|
|
94
|
-
optionalProperties: {
|
|
95
|
-
label: { type: "string" },
|
|
96
|
-
description: { type: "string" },
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
genotype: {
|
|
100
|
-
properties: {
|
|
101
|
-
name: { type: "string" },
|
|
102
|
-
},
|
|
103
|
-
optionalProperties: {
|
|
104
|
-
label: { type: "string" },
|
|
105
|
-
description: { type: "string" },
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
composed: {
|
|
109
|
-
properties: {
|
|
110
|
-
name: {
|
|
111
|
-
enum: [
|
|
112
|
-
"clinVar",
|
|
113
|
-
"gene",
|
|
114
|
-
"genotype",
|
|
115
|
-
"genotype_maternal",
|
|
116
|
-
"genotype_paternal",
|
|
117
|
-
"gnomAdAf",
|
|
118
|
-
"hpo",
|
|
119
|
-
"inheritancePattern",
|
|
120
|
-
"locus",
|
|
121
|
-
"vipC",
|
|
122
|
-
"vipCS",
|
|
123
|
-
"vkgl",
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
optionalProperties: {
|
|
128
|
-
label: { type: "string" },
|
|
129
|
-
description: { type: "string" },
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
group: {
|
|
133
|
-
// TODO deduplicate code, see mappings listed above
|
|
134
|
-
properties: {
|
|
135
|
-
fields: {
|
|
136
|
-
elements: {
|
|
137
|
-
discriminator: "type",
|
|
138
|
-
mapping: {
|
|
139
|
-
fixed: {
|
|
140
|
-
properties: {
|
|
141
|
-
name: { enum: ["chrom", "pos", "id", "ref", "alt", "qual", "filter"] },
|
|
142
|
-
},
|
|
143
|
-
optionalProperties: {
|
|
144
|
-
label: { type: "string" },
|
|
145
|
-
description: { type: "string" },
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
info: {
|
|
149
|
-
properties: {
|
|
150
|
-
name: { type: "string" },
|
|
151
|
-
},
|
|
152
|
-
optionalProperties: {
|
|
153
|
-
label: { type: "string" },
|
|
154
|
-
description: { type: "string" },
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
format: {
|
|
158
|
-
properties: {
|
|
159
|
-
name: { type: "string" },
|
|
160
|
-
},
|
|
161
|
-
optionalProperties: {
|
|
162
|
-
label: { type: "string" },
|
|
163
|
-
description: { type: "string" },
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
genotype: {
|
|
167
|
-
properties: {
|
|
168
|
-
name: { type: "string" },
|
|
169
|
-
},
|
|
170
|
-
optionalProperties: {
|
|
171
|
-
label: { type: "string" },
|
|
172
|
-
description: { type: "string" },
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
composed: {
|
|
176
|
-
properties: {
|
|
177
|
-
name: {
|
|
178
|
-
enum: [
|
|
179
|
-
"clinVar",
|
|
180
|
-
"gene",
|
|
181
|
-
"genotype",
|
|
182
|
-
"gnomAdAf",
|
|
183
|
-
"hpo",
|
|
184
|
-
"inheritancePattern",
|
|
185
|
-
"locus",
|
|
186
|
-
"ref",
|
|
187
|
-
"vipC",
|
|
188
|
-
"vipCS",
|
|
189
|
-
"vkgl",
|
|
190
|
-
],
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
optionalProperties: {
|
|
194
|
-
label: { type: "string" },
|
|
195
|
-
description: { type: "string" },
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const schemaConfigJsonFilter: JTDSchemaType<ConfigJsonFilter> = {
|
|
207
|
-
discriminator: "type",
|
|
208
|
-
mapping: {
|
|
209
|
-
fixed: {
|
|
210
|
-
properties: {
|
|
211
|
-
name: { enum: ["chrom", "pos", "id", "ref", "alt", "qual", "filter"] },
|
|
212
|
-
},
|
|
213
|
-
optionalProperties: {
|
|
214
|
-
label: { type: "string" },
|
|
215
|
-
description: { type: "string" },
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
info: {
|
|
219
|
-
properties: {
|
|
220
|
-
name: { type: "string" },
|
|
221
|
-
},
|
|
222
|
-
optionalProperties: {
|
|
223
|
-
label: { type: "string" },
|
|
224
|
-
description: { type: "string" },
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
format: {
|
|
228
|
-
properties: {
|
|
229
|
-
name: { type: "string" },
|
|
230
|
-
},
|
|
231
|
-
optionalProperties: {
|
|
232
|
-
label: { type: "string" },
|
|
233
|
-
description: { type: "string" },
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
genotype: {
|
|
237
|
-
properties: {
|
|
238
|
-
name: { type: "string" },
|
|
239
|
-
},
|
|
240
|
-
optionalProperties: {
|
|
241
|
-
label: { type: "string" },
|
|
242
|
-
description: { type: "string" },
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
composed: {
|
|
246
|
-
properties: {
|
|
247
|
-
name: {
|
|
248
|
-
enum: ["allelicImbalance", "deNovo", "hpo", "inheritanceMatch", "locus", "vipC", "vipCS"],
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
optionalProperties: {
|
|
252
|
-
label: { type: "string" },
|
|
253
|
-
description: { type: "string" },
|
|
254
|
-
},
|
|
255
|
-
},
|
|
256
|
-
},
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const schemaConfigJsonSortOrder: JTDSchemaType<ConfigJsonSortOrder> = {
|
|
260
|
-
properties: {
|
|
261
|
-
direction: { enum: ["asc", "desc"] },
|
|
262
|
-
field: schemaConfigJsonField,
|
|
263
|
-
},
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
const schemaConfigJsonSort: JTDSchemaType<ConfigJsonSort> = {
|
|
267
|
-
properties: {
|
|
268
|
-
selected: { type: "boolean" },
|
|
269
|
-
orders: {
|
|
270
|
-
elements: schemaConfigJsonSortOrder,
|
|
271
|
-
},
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
const schemaConfigJsonRecordsPerPageOption: JTDSchemaType<ConfigJsonRecordsPerPageOption> = {
|
|
276
|
-
properties: {
|
|
277
|
-
number: { type: "uint16" },
|
|
278
|
-
},
|
|
279
|
-
optionalProperties: {
|
|
280
|
-
selected: { type: "boolean" },
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const schemaConfigJsonVariants: JTDSchemaType<ConfigJsonVariants> = {
|
|
285
|
-
properties: {
|
|
286
|
-
cells: {
|
|
287
|
-
optionalProperties: {
|
|
288
|
-
all: { elements: schemaConfigJsonField },
|
|
289
|
-
snv: { elements: schemaConfigJsonField },
|
|
290
|
-
str: { elements: schemaConfigJsonField },
|
|
291
|
-
sv: { elements: schemaConfigJsonField },
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
},
|
|
295
|
-
optionalProperties: {
|
|
296
|
-
filters: {
|
|
297
|
-
optionalProperties: {
|
|
298
|
-
all: { elements: schemaConfigJsonFilter },
|
|
299
|
-
snv: { elements: schemaConfigJsonFilter },
|
|
300
|
-
str: { elements: schemaConfigJsonFilter },
|
|
301
|
-
sv: { elements: schemaConfigJsonFilter },
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
sorts: {
|
|
305
|
-
optionalProperties: {
|
|
306
|
-
all: { elements: schemaConfigJsonSort },
|
|
307
|
-
snv: { elements: schemaConfigJsonSort },
|
|
308
|
-
str: { elements: schemaConfigJsonSort },
|
|
309
|
-
sv: { elements: schemaConfigJsonSort },
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
recordsPerPage: {
|
|
313
|
-
optionalProperties: {
|
|
314
|
-
all: { elements: schemaConfigJsonRecordsPerPageOption },
|
|
315
|
-
snv: { elements: schemaConfigJsonRecordsPerPageOption },
|
|
316
|
-
str: { elements: schemaConfigJsonRecordsPerPageOption },
|
|
317
|
-
sv: { elements: schemaConfigJsonRecordsPerPageOption },
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
const schemaConfigJsonVariant: JTDSchemaType<ConfigJsonVariant> = {
|
|
324
|
-
properties: {
|
|
325
|
-
cells: {
|
|
326
|
-
optionalProperties: {
|
|
327
|
-
all: { elements: schemaConfigJsonField },
|
|
328
|
-
snv: { elements: schemaConfigJsonField },
|
|
329
|
-
str: { elements: schemaConfigJsonField },
|
|
330
|
-
sv: { elements: schemaConfigJsonField },
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
optionalProperties: {
|
|
335
|
-
sample_cells: {
|
|
336
|
-
optionalProperties: {
|
|
337
|
-
all: { elements: schemaConfigJsonField },
|
|
338
|
-
snv: { elements: schemaConfigJsonField },
|
|
339
|
-
str: { elements: schemaConfigJsonField },
|
|
340
|
-
sv: { elements: schemaConfigJsonField },
|
|
341
|
-
},
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
const schemaConfigJsonVariantConsequence: JTDSchemaType<ConfigJsonVariantConsequence> = {
|
|
347
|
-
optionalProperties: {
|
|
348
|
-
sample_cells: {
|
|
349
|
-
optionalProperties: {
|
|
350
|
-
all: { elements: schemaConfigJsonField },
|
|
351
|
-
snv: { elements: schemaConfigJsonField },
|
|
352
|
-
str: { elements: schemaConfigJsonField },
|
|
353
|
-
sv: { elements: schemaConfigJsonField },
|
|
354
|
-
},
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
const schema: JTDSchemaType<ConfigJson> = {
|
|
360
|
-
properties: {
|
|
361
|
-
vip: schemaConfigJsonVip,
|
|
362
|
-
sample_variants: schemaConfigJsonVariants,
|
|
363
|
-
variants: schemaConfigJsonVariants,
|
|
364
|
-
sample_variant: schemaConfigJsonVariant,
|
|
365
|
-
variant: schemaConfigJsonVariant,
|
|
366
|
-
sample_variant_consequence: schemaConfigJsonVariantConsequence,
|
|
367
|
-
variant_consequence: schemaConfigJsonVariantConsequence,
|
|
368
|
-
},
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
const validate = ajv.compile(schema);
|
|
6
|
+
//se /scripts/validateConfig for instructions to update the schema
|
|
372
7
|
|
|
373
8
|
export function validateConfig(json: Json): ConfigJson {
|
|
374
9
|
const valid = validate(json);
|
package/src/utils/csq.ts
CHANGED
|
@@ -94,20 +94,15 @@ export function compareCsq(
|
|
|
94
94
|
return compareCsqValue(aValue, bValue, direction);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export function compareCsqDefault(
|
|
98
|
-
aValue: Value[],
|
|
99
|
-
bValue: Value[],
|
|
100
|
-
pickIndex: number,
|
|
101
|
-
consequenceIndex: number,
|
|
102
|
-
): number {
|
|
97
|
+
export function compareCsqDefault(aValue: object, bValue: object, pickIndex: number, consequenceIndex: number): number {
|
|
103
98
|
if (pickIndex !== -1) {
|
|
104
|
-
if (aValue[
|
|
105
|
-
if (bValue[
|
|
99
|
+
if (aValue["PICK"] === 1) return bValue["PICK"] === null ? -1 : 0;
|
|
100
|
+
if (bValue["PICK"] === 1) return 1;
|
|
106
101
|
}
|
|
107
102
|
|
|
108
103
|
if (consequenceIndex !== -1) {
|
|
109
|
-
const aIndex = getMostSevereConsequenceIndex(aValue[
|
|
110
|
-
const bIndex = getMostSevereConsequenceIndex(bValue[
|
|
104
|
+
const aIndex = getMostSevereConsequenceIndex(aValue["Consequence"] as string[]);
|
|
105
|
+
const bIndex = getMostSevereConsequenceIndex(bValue["Consequence"] as string[]);
|
|
111
106
|
return aIndex - bIndex;
|
|
112
107
|
} else {
|
|
113
108
|
return 0;
|
|
@@ -29,17 +29,16 @@ export function getSampleTreePath(
|
|
|
29
29
|
variant: Item<VcfRecord>,
|
|
30
30
|
csqId: number,
|
|
31
31
|
): DecisionTreePath {
|
|
32
|
-
let decisionTreePath: DecisionTreePath;
|
|
33
32
|
const fieldMetadata = getSampleField(metadata, "VIPP_S");
|
|
34
33
|
if (fieldMetadata) {
|
|
35
34
|
const value = getSampleValue(sample, variant, -1, fieldMetadata); // TODO replace with getSampleNestedValue once VIPP_S metadata is nested
|
|
36
|
-
if (value
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
if (value !== undefined) {
|
|
36
|
+
if (!Array.isArray(value)) throw new RuntimeError();
|
|
37
|
+
const valueArray = value as string[];
|
|
38
|
+
if (valueArray.length > csqId) {
|
|
39
|
+
return valueArray[csqId]!.split("&") as DecisionTreePath;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
43
42
|
}
|
|
44
|
-
return
|
|
43
|
+
return [];
|
|
45
44
|
}
|
package/src/utils/query/query.ts
CHANGED
|
@@ -3,13 +3,14 @@ import { FilterValueMap } from "../../types/configFilter";
|
|
|
3
3
|
import { VariantType } from "../variantType.ts";
|
|
4
4
|
|
|
5
5
|
import { Config } from "../../types/config";
|
|
6
|
-
import { SampleContainer } from "../api.ts";
|
|
6
|
+
import { MetadataContainer, SampleContainer } from "../api.ts";
|
|
7
7
|
import { createQueryFilters } from "./queryFilter.ts";
|
|
8
8
|
import { createQueryVariantType } from "./queryVariantType.ts";
|
|
9
9
|
import { createQuerySample } from "./querySample.ts";
|
|
10
10
|
|
|
11
11
|
export function createQuery(
|
|
12
12
|
config: Config,
|
|
13
|
+
meta: MetadataContainer,
|
|
13
14
|
variantType: VariantType,
|
|
14
15
|
sample: SampleContainer | null,
|
|
15
16
|
filterValues: FilterValueMap,
|
|
@@ -22,7 +23,7 @@ export function createQuery(
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
if (sample !== null) {
|
|
25
|
-
const querySample = createQuerySample(config.vip, sample);
|
|
26
|
+
const querySample = createQuerySample(config.vip, sample, meta);
|
|
26
27
|
if (querySample !== null) {
|
|
27
28
|
queryParts.push(querySample);
|
|
28
29
|
}
|
|
@@ -63,7 +63,6 @@ export function createQueryFilterString(
|
|
|
63
63
|
selector: Selector,
|
|
64
64
|
filterValue: FilterValueString,
|
|
65
65
|
multiValue: boolean,
|
|
66
|
-
nestedValue: boolean,
|
|
67
66
|
): Query {
|
|
68
67
|
// null values
|
|
69
68
|
// multi=false --> value=null
|
|
@@ -74,7 +73,7 @@ export function createQueryFilterString(
|
|
|
74
73
|
if (filterValues.length > 0) {
|
|
75
74
|
queryParts.push({
|
|
76
75
|
selector,
|
|
77
|
-
operator:
|
|
76
|
+
operator: "in",
|
|
78
77
|
args: filterValues,
|
|
79
78
|
});
|
|
80
79
|
}
|
|
@@ -82,7 +81,7 @@ export function createQueryFilterString(
|
|
|
82
81
|
if (multiValue && filterValues.findIndex((value) => value === null) !== -1) {
|
|
83
82
|
queryParts.push({
|
|
84
83
|
selector,
|
|
85
|
-
operator:
|
|
84
|
+
operator: "==",
|
|
86
85
|
args: multiValue ? [] : null,
|
|
87
86
|
});
|
|
88
87
|
}
|
|
@@ -68,7 +68,7 @@ function createQueryFilterHpo(filter: ConfigFilterHpo, filterValue: FilterValueH
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function createQueryFilterLocus(filterValue: FilterValueLocus): Query {
|
|
71
|
-
const queryParts: Query[] = [createQueryFilterString(["c"], [filterValue.chromosome], false
|
|
71
|
+
const queryParts: Query[] = [createQueryFilterString(["c"], [filterValue.chromosome], false)];
|
|
72
72
|
|
|
73
73
|
if (filterValue.start !== undefined || filterValue.end !== undefined) {
|
|
74
74
|
const posQuery = createQueryFilterClosedInterval(["p"], { left: filterValue.start, right: filterValue.end });
|
|
@@ -83,8 +83,8 @@ function createQueryFilterAllelicImbalance(
|
|
|
83
83
|
filterValue: FilterValueAllelicImbalance,
|
|
84
84
|
): Query {
|
|
85
85
|
const viabSelector = createSelectorSample(filter.sample, filter.viabField);
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
//GT_type is a technical field specific for the database, so no metadata present
|
|
87
|
+
const gtTypeSelector = ["s", filter.sample.item.id, "GT_type"];
|
|
88
88
|
const queryParts: Query[] = [];
|
|
89
89
|
if (filterValue.includes("true")) {
|
|
90
90
|
const queryPartsTrue: Query[] = [];
|
|
@@ -93,8 +93,8 @@ function createQueryFilterAllelicImbalance(
|
|
|
93
93
|
[
|
|
94
94
|
{
|
|
95
95
|
operator: "in",
|
|
96
|
-
selector:
|
|
97
|
-
args: ["
|
|
96
|
+
selector: gtTypeSelector,
|
|
97
|
+
args: ["HOM_ALT", "HOM_REF"],
|
|
98
98
|
},
|
|
99
99
|
createQueryFilterClosedInterval(viabSelector, { left: 0.02, right: 0.98 }),
|
|
100
100
|
],
|
|
@@ -106,8 +106,8 @@ function createQueryFilterAllelicImbalance(
|
|
|
106
106
|
[
|
|
107
107
|
{
|
|
108
108
|
operator: "==",
|
|
109
|
-
selector:
|
|
110
|
-
args: "
|
|
109
|
+
selector: gtTypeSelector,
|
|
110
|
+
args: "HET",
|
|
111
111
|
},
|
|
112
112
|
createQueryFilterClosedIntervalOutside(viabSelector, { left: 0.2, right: 0.8 }),
|
|
113
113
|
],
|
|
@@ -123,8 +123,8 @@ function createQueryFilterAllelicImbalance(
|
|
|
123
123
|
[
|
|
124
124
|
{
|
|
125
125
|
operator: "in",
|
|
126
|
-
selector:
|
|
127
|
-
args: ["
|
|
126
|
+
selector: gtTypeSelector,
|
|
127
|
+
args: ["HOM_ALT", "HOM_REF"],
|
|
128
128
|
},
|
|
129
129
|
createQueryFilterClosedIntervalOutside(viabSelector, { left: 0.02, right: 0.98 }),
|
|
130
130
|
],
|
|
@@ -136,8 +136,8 @@ function createQueryFilterAllelicImbalance(
|
|
|
136
136
|
[
|
|
137
137
|
{
|
|
138
138
|
operator: "==",
|
|
139
|
-
selector:
|
|
140
|
-
args: "
|
|
139
|
+
selector: gtTypeSelector,
|
|
140
|
+
args: "HET",
|
|
141
141
|
},
|
|
142
142
|
createQueryFilterClosedInterval(viabSelector, { left: 0.2, right: 0.8 }),
|
|
143
143
|
],
|
|
@@ -231,7 +231,7 @@ function createQueryFilterDeNovo(filter: ConfigFilterDeNovo, filterValue: Filter
|
|
|
231
231
|
});
|
|
232
232
|
queryParts.push(createQueryComposed(queryPartsUndefined, "or"));
|
|
233
233
|
}
|
|
234
|
-
return createQueryComposed(queryParts, "
|
|
234
|
+
return createQueryComposed(queryParts, "or");
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
function createQueryFilterVipC(filter: ConfigFilterVipC, filterValue: FilterValueVipC): Query {
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
ConfigFilterFormat,
|
|
6
6
|
FilterValue,
|
|
7
7
|
FilterValueCategorical,
|
|
8
|
+
FilterValueFlag,
|
|
8
9
|
FilterValueInterval,
|
|
9
10
|
FilterValueString,
|
|
10
11
|
} from "../../types/configFilter";
|
|
@@ -30,7 +31,7 @@ export function createQueryFilterField(filter: ConfigFilterField, filterValue: F
|
|
|
30
31
|
query = createQueryFilterClosedInterval(selector, filterValue as FilterValueInterval);
|
|
31
32
|
break;
|
|
32
33
|
case "FLAG":
|
|
33
|
-
query = createQueryFilterFlag();
|
|
34
|
+
query = createQueryFilterFlag(selector, field, filterValue as FilterValueCategorical);
|
|
34
35
|
break;
|
|
35
36
|
default:
|
|
36
37
|
throw new UnexpectedEnumValueException(field.type);
|
|
@@ -60,16 +61,22 @@ export function createQueryFilterFieldCategorical(
|
|
|
60
61
|
filterValue: FilterValueCategorical,
|
|
61
62
|
): Query {
|
|
62
63
|
const multiValue = field.number.count !== 1;
|
|
63
|
-
|
|
64
|
-
return createQueryFilterString(selector, filterValue, multiValue, nestedValue);
|
|
64
|
+
return createQueryFilterString(selector, filterValue, multiValue);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function createQueryFilterFlag(): Query {
|
|
68
|
-
|
|
67
|
+
function createQueryFilterFlag(selector: Selector, field: FieldMetadata, filterValue: FilterValueFlag): Query {
|
|
68
|
+
const values: string[] = [];
|
|
69
|
+
for (const value of filterValue) {
|
|
70
|
+
if (value === "true") {
|
|
71
|
+
values.push("1");
|
|
72
|
+
} else if (value === "false") {
|
|
73
|
+
values.push("__null");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return createQueryFilterFieldCategorical(selector, field, values);
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
function createQueryFilterFieldString(selector: Selector, field: FieldMetadata, filterValue: FilterValueString): Query {
|
|
72
80
|
const multiValue = field.number.count !== 1;
|
|
73
|
-
|
|
74
|
-
return createQueryFilterString(selector, filterValue, multiValue, nestedValue);
|
|
81
|
+
return createQueryFilterString(selector, filterValue, multiValue);
|
|
75
82
|
}
|
|
@@ -17,25 +17,25 @@ export function createQueryFilterFixed(filter: ConfigFilterFixed, filterValue: F
|
|
|
17
17
|
let query: Query;
|
|
18
18
|
switch (filter.id) {
|
|
19
19
|
case "fixed/chrom":
|
|
20
|
-
query = createQueryFilterString(["c"], filterValue as FilterValueChrom, false
|
|
20
|
+
query = createQueryFilterString(["c"], filterValue as FilterValueChrom, false);
|
|
21
21
|
break;
|
|
22
22
|
case "fixed/pos":
|
|
23
23
|
query = createQueryFilterClosedInterval(["p"], filterValue as FilterValuePos);
|
|
24
24
|
break;
|
|
25
25
|
case "fixed/id":
|
|
26
|
-
query = createQueryFilterString(["i"], filterValue as FilterValueId, true
|
|
26
|
+
query = createQueryFilterString(["i"], filterValue as FilterValueId, true);
|
|
27
27
|
break;
|
|
28
28
|
case "fixed/ref":
|
|
29
|
-
query = createQueryFilterString(["r"], filterValue as FilterValueRef, false
|
|
29
|
+
query = createQueryFilterString(["r"], filterValue as FilterValueRef, false);
|
|
30
30
|
break;
|
|
31
31
|
case "fixed/alt":
|
|
32
|
-
query = createQueryFilterString(["a"], filterValue as FilterValueAlt, true
|
|
32
|
+
query = createQueryFilterString(["a"], filterValue as FilterValueAlt, true);
|
|
33
33
|
break;
|
|
34
34
|
case "fixed/qual":
|
|
35
35
|
query = createQueryFilterClosedInterval(["q"], filterValue as FilterValueQual);
|
|
36
36
|
break;
|
|
37
37
|
case "fixed/filter":
|
|
38
|
-
query = createQueryFilterString(["f"], filterValue as FilterValueFilter, true
|
|
38
|
+
query = createQueryFilterString(["f"], filterValue as FilterValueFilter, true);
|
|
39
39
|
break;
|
|
40
40
|
default:
|
|
41
41
|
throw new UnexpectedEnumValueException(filter.id);
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { Query } from "@molgenis/vip-report-api";
|
|
2
|
-
import { SampleContainer } from "../api.ts";
|
|
2
|
+
import { MetadataContainer, SampleContainer } from "../api.ts";
|
|
3
3
|
import { createSelectorSample } from "./selector.ts";
|
|
4
4
|
import { ConfigVip } from "../../types/config";
|
|
5
5
|
import { FilterValueCategorical } from "../../types/configFilter";
|
|
6
6
|
import { createQueryFilterFieldCategorical } from "./queryFilterField.ts";
|
|
7
|
+
import { createQueryComposed } from "./query.ts";
|
|
7
8
|
|
|
8
|
-
export function createQuerySample(config: ConfigVip, sample: SampleContainer): Query | null {
|
|
9
|
+
export function createQuerySample(config: ConfigVip, sample: SampleContainer, meta: MetadataContainer): Query | null {
|
|
9
10
|
const filterField = config.filter_field;
|
|
10
11
|
if (filterField === null) return null;
|
|
11
12
|
|
|
12
13
|
const filterValues = getFilterValues(config);
|
|
13
|
-
const
|
|
14
|
-
|
|
14
|
+
const filterSelector = createSelectorSample(sample, filterField);
|
|
15
|
+
const classFilter = createQueryFilterFieldCategorical(filterSelector, filterField, filterValues);
|
|
16
|
+
const filters = [classFilter];
|
|
17
|
+
if (meta.records.format.GT !== undefined) {
|
|
18
|
+
const gtFilter = {
|
|
19
|
+
selector: ["s", sample.item.id, "GT_type"],
|
|
20
|
+
operator: "!in",
|
|
21
|
+
args: ["HOM_REF", "NO_CALL", "UNAVAILABLE"],
|
|
22
|
+
} as Query;
|
|
23
|
+
filters.push(gtFilter);
|
|
24
|
+
}
|
|
25
|
+
return createQueryComposed(filters, "and");
|
|
15
26
|
}
|
|
16
27
|
|
|
17
28
|
function getFilterValues(config: ConfigVip): FilterValueCategorical {
|