From d9bfe61d5af28b8983bd8fc25b8ba712c184ac56 Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Tue, 30 Jan 2024 08:26:01 +0100 Subject: [PATCH] feat: adding api/variantValidator (#38) --- .../__snapshots__/client.spec.ts.snap | 436 +++++++++++++++ .../__snapshots__/types.spec.ts.snap | 524 ++++++++++++++++++ src/api/variantValidator/client.spec.ts | 54 ++ src/api/variantValidator/client.ts | 36 ++ .../fixture.maneResponse.BRCA1.json | 416 ++++++++++++++ .../fixture.maneResponse.telomeric.json | 75 +++ src/api/variantValidator/index.ts | 2 + src/api/variantValidator/types.spec.ts | 41 ++ src/api/variantValidator/types.ts | 503 +++++++++++++++++ 9 files changed, 2087 insertions(+) create mode 100644 src/api/variantValidator/__snapshots__/client.spec.ts.snap create mode 100644 src/api/variantValidator/__snapshots__/types.spec.ts.snap create mode 100644 src/api/variantValidator/client.spec.ts create mode 100644 src/api/variantValidator/client.ts create mode 100644 src/api/variantValidator/fixture.maneResponse.BRCA1.json create mode 100644 src/api/variantValidator/fixture.maneResponse.telomeric.json create mode 100644 src/api/variantValidator/index.ts create mode 100644 src/api/variantValidator/types.spec.ts create mode 100644 src/api/variantValidator/types.ts diff --git a/src/api/variantValidator/__snapshots__/client.spec.ts.snap b/src/api/variantValidator/__snapshots__/client.spec.ts.snap new file mode 100644 index 0000000..b063299 --- /dev/null +++ b/src/api/variantValidator/__snapshots__/client.spec.ts.snap @@ -0,0 +1,436 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`VariantValidator > throws in case of fetching problems 1`] = ` +{ + "NM_001195610.1:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false, + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": false, + "variant": "2", + }, + "gene_ids": { + "ccds_ids": [ + "CCDS4550", + ], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": [ + "605755", + ], + "ucsc_id": "uc003ndx.4", + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_001195610.1):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_001182539.1:p.?", + "tlr": "NP_001182539.1:p.?", + }, + "hgvs_refseqgene_variant": "", + "hgvs_transcript_variant": "NM_001195610.1:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_001182539.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_001195610.1", + }, + "refseqgene_context_intronic_sequence": "", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 2, mRNA", + "validation_warnings": [ + "A more recent version of the selected reference sequence NM_001195610.1 is available (NM_001195610.2): NM_001195610.2:c.349-2A>G MUST be fully validated prior to use in reports: select_variants=NM_001195610.2:c.349-2A>G", + ], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "3i", + "start_exon": "3i", + }, + "NC_000006.12": { + "end_exon": "3i", + "start_exon": "3i", + }, + }, + }, + "NM_001195610.2:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false, + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": false, + "variant": "2", + }, + "gene_ids": { + "ccds_ids": [ + "CCDS4550", + ], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": [ + "605755", + ], + "ucsc_id": "uc003ndx.4", + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_001195610.2):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_001182539.1:p.?", + "tlr": "NP_001182539.1:p.?", + }, + "hgvs_refseqgene_variant": "", + "hgvs_transcript_variant": "NM_001195610.2:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_001182539.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_001195610.2", + }, + "refseqgene_context_intronic_sequence": "", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 2, mRNA", + "validation_warnings": [], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "3i", + "start_exon": "3i", + }, + "NC_000006.12": { + "end_exon": "3i", + "start_exon": "3i", + }, + }, + }, + "NM_016356.4:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false, + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": false, + "variant": "1", + }, + "gene_ids": { + "ccds_ids": [ + "CCDS4550", + ], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": [ + "605755", + ], + "ucsc_id": "uc003ndx.4", + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_016356.4):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_057440.2:p.?", + "tlr": "NP_057440.2:p.?", + }, + "hgvs_refseqgene_variant": "NG_012829.1:g.61007A>G", + "hgvs_transcript_variant": "NM_016356.4:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_057440.2", + "refseqgene": "https://www.ncbi.nlm.nih.gov/nuccore/NG_012829.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_016356.4", + }, + "refseqgene_context_intronic_sequence": "NG_012829.1(NM_016356.4):c.349-2A>G", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 1, mRNA", + "validation_warnings": [ + "A more recent version of the selected reference sequence NM_016356.4 is available (NM_016356.5): NM_016356.5:c.349-2A>G MUST be fully validated prior to use in reports: select_variants=NM_016356.5:c.349-2A>G", + ], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "2i", + "start_exon": "2i", + }, + "NC_000006.12": { + "end_exon": "2i", + "start_exon": "2i", + }, + "NG_012829.1": { + "end_exon": "2i", + "start_exon": "2i", + }, + }, + }, + "NM_016356.5:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": "MANE", + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": true, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": true, + "variant": "1", + }, + "gene_ids": { + "ccds_ids": [ + "CCDS4550", + ], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": [ + "605755", + ], + "ucsc_id": "uc003ndx.4", + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_016356.5):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_057440.2:p.?", + "tlr": "NP_057440.2:p.?", + }, + "hgvs_refseqgene_variant": "NG_012829.2:g.86247A>G", + "hgvs_transcript_variant": "NM_016356.5:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_057440.2", + "refseqgene": "https://www.ncbi.nlm.nih.gov/nuccore/NG_012829.2", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_016356.5", + }, + "refseqgene_context_intronic_sequence": "NG_012829.2(NM_016356.5):c.349-2A>G", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 1, mRNA", + "validation_warnings": [], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "2i", + "start_exon": "2i", + }, + "NC_000006.12": { + "end_exon": "2i", + "start_exon": "2i", + }, + "NG_012829.2": { + "end_exon": "2i", + "start_exon": "2i", + }, + }, + }, + "flag": "gene_variant", + "metadata": { + "variantvalidator_hgvs_version": "2.2.0", + "variantvalidator_version": "2.2.1.dev492+g032aa70", + "vvdb_version": "vvdb_2023_8", + "vvseqrepo_db": "VV_SR_2023_05/master", + "vvta_version": "vvta_2023_05", + }, +} +`; diff --git a/src/api/variantValidator/__snapshots__/types.spec.ts.snap b/src/api/variantValidator/__snapshots__/types.spec.ts.snap new file mode 100644 index 0000000..5efb8df --- /dev/null +++ b/src/api/variantValidator/__snapshots__/types.spec.ts.snap @@ -0,0 +1,524 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Response.fromJson > handles telomeric variant correctly 1`] = ` +{ + "entries": [ + { + "annotations": { + "chromosome": "6", + "dbXref": { + "ccds": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false, + }, + "ensemblSelect": false, + "manePlusClinicalTranscript": undefined, + "maneSelect": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseqSelect": false, + "variant": "2", + }, + "geneIds": { + "ccdIds": undefined, + "ensemblGeneId": "ENSG00000146038", + "entrezGeneId": "51473", + "hgncId": "HGNC:18141", + "omimId": [ + "605755", + ], + "ucscId": "uc003ndx.4", + }, + "geneSymbol": "DCDC2", + "genomeContextIntronicSequence": "NC_000006.11(NM_001195610.1):c.349-2A>G", + "hgvsLrgTranscriptVariant": "", + "hgvsLrgVariant": "", + "hgvsPredictedProteinConsequence": { + "lrgSlr": "", + "lrgTlr": "", + "slr": "NP_001182539.1:p.?", + "tlr": "NP_001182539.1:p.?", + }, + "hgvsRefseqgeneVariant": "", + "hgvsTranscriptVariant": "NM_001195610.1:c.349-2A>G", + "primaryAssemblyLoci": { + "grch37": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "referenceSequenceRecords": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_001182539.1", + "refseqgene": undefined, + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_001195610.1", + }, + "refseqgeneContextIntronicSequence": "", + "rnaVariantDescriptions": null, + "selectedAssembly": "hg19", + "submittedVariant": "6-24302274-T-C", + "transcriptVariant": undefined, + "validationWarnings": [ + "A more recent version of the selected reference sequence NM_001195610.1 is available (NM_001195610.2): NM_001195610.2:c.349-2A>G MUST be fully validated prior to use in reports: select_variants=NM_001195610.2:c.349-2A>G", + ], + "variantExonicPositions": { + "NC_000006.11": { + "endExon": "3i", + "startExon": "3i", + }, + "NC_000006.12": { + "endExon": "3i", + "startExon": "3i", + }, + }, + }, + { + "annotations": { + "chromosome": "6", + "dbXref": { + "ccds": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false, + }, + "ensemblSelect": false, + "manePlusClinicalTranscript": undefined, + "maneSelect": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseqSelect": false, + "variant": "2", + }, + "geneIds": { + "ccdIds": undefined, + "ensemblGeneId": "ENSG00000146038", + "entrezGeneId": "51473", + "hgncId": "HGNC:18141", + "omimId": [ + "605755", + ], + "ucscId": "uc003ndx.4", + }, + "geneSymbol": "DCDC2", + "genomeContextIntronicSequence": "NC_000006.11(NM_001195610.2):c.349-2A>G", + "hgvsLrgTranscriptVariant": "", + "hgvsLrgVariant": "", + "hgvsPredictedProteinConsequence": { + "lrgSlr": "", + "lrgTlr": "", + "slr": "NP_001182539.1:p.?", + "tlr": "NP_001182539.1:p.?", + }, + "hgvsRefseqgeneVariant": "", + "hgvsTranscriptVariant": "NM_001195610.2:c.349-2A>G", + "primaryAssemblyLoci": { + "grch37": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "referenceSequenceRecords": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_001182539.1", + "refseqgene": undefined, + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_001195610.2", + }, + "refseqgeneContextIntronicSequence": "", + "rnaVariantDescriptions": null, + "selectedAssembly": "hg19", + "submittedVariant": "6-24302274-T-C", + "transcriptVariant": undefined, + "validationWarnings": [], + "variantExonicPositions": { + "NC_000006.11": { + "endExon": "3i", + "startExon": "3i", + }, + "NC_000006.12": { + "endExon": "3i", + "startExon": "3i", + }, + }, + }, + { + "annotations": { + "chromosome": "6", + "dbXref": { + "ccds": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false, + }, + "ensemblSelect": false, + "manePlusClinicalTranscript": undefined, + "maneSelect": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseqSelect": false, + "variant": "1", + }, + "geneIds": { + "ccdIds": undefined, + "ensemblGeneId": "ENSG00000146038", + "entrezGeneId": "51473", + "hgncId": "HGNC:18141", + "omimId": [ + "605755", + ], + "ucscId": "uc003ndx.4", + }, + "geneSymbol": "DCDC2", + "genomeContextIntronicSequence": "NC_000006.11(NM_016356.4):c.349-2A>G", + "hgvsLrgTranscriptVariant": "", + "hgvsLrgVariant": "", + "hgvsPredictedProteinConsequence": { + "lrgSlr": "", + "lrgTlr": "", + "slr": "NP_057440.2:p.?", + "tlr": "NP_057440.2:p.?", + }, + "hgvsRefseqgeneVariant": "NG_012829.1:g.61007A>G", + "hgvsTranscriptVariant": "NM_016356.4:c.349-2A>G", + "primaryAssemblyLoci": { + "grch37": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "referenceSequenceRecords": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_057440.2", + "refseqgene": "https://www.ncbi.nlm.nih.gov/nuccore/NG_012829.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_016356.4", + }, + "refseqgeneContextIntronicSequence": "NG_012829.1(NM_016356.4):c.349-2A>G", + "rnaVariantDescriptions": null, + "selectedAssembly": "hg19", + "submittedVariant": "6-24302274-T-C", + "transcriptVariant": undefined, + "validationWarnings": [ + "A more recent version of the selected reference sequence NM_016356.4 is available (NM_016356.5): NM_016356.5:c.349-2A>G MUST be fully validated prior to use in reports: select_variants=NM_016356.5:c.349-2A>G", + ], + "variantExonicPositions": { + "NC_000006.11": { + "endExon": "2i", + "startExon": "2i", + }, + "NC_000006.12": { + "endExon": "2i", + "startExon": "2i", + }, + "NG_012829.1": { + "endExon": "2i", + "startExon": "2i", + }, + }, + }, + { + "annotations": { + "chromosome": "6", + "dbXref": { + "ccds": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": "MANE", + }, + "ensemblSelect": false, + "manePlusClinicalTranscript": undefined, + "maneSelect": true, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseqSelect": true, + "variant": "1", + }, + "geneIds": { + "ccdIds": undefined, + "ensemblGeneId": "ENSG00000146038", + "entrezGeneId": "51473", + "hgncId": "HGNC:18141", + "omimId": [ + "605755", + ], + "ucscId": "uc003ndx.4", + }, + "geneSymbol": "DCDC2", + "genomeContextIntronicSequence": "NC_000006.11(NM_016356.5):c.349-2A>G", + "hgvsLrgTranscriptVariant": "", + "hgvsLrgVariant": "", + "hgvsPredictedProteinConsequence": { + "lrgSlr": "", + "lrgTlr": "", + "slr": "NP_057440.2:p.?", + "tlr": "NP_057440.2:p.?", + }, + "hgvsRefseqgeneVariant": "NG_012829.2:g.86247A>G", + "hgvsTranscriptVariant": "NM_016356.5:c.349-2A>G", + "primaryAssemblyLoci": { + "grch37": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T", + }, + }, + "grch38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T", + }, + }, + "hg19": { + "hgvsGenomicDescription": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T", + }, + }, + "hg38": { + "hgvsGenomicDescription": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T", + }, + }, + }, + "referenceSequenceRecords": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_057440.2", + "refseqgene": "https://www.ncbi.nlm.nih.gov/nuccore/NG_012829.2", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_016356.5", + }, + "refseqgeneContextIntronicSequence": "NG_012829.2(NM_016356.5):c.349-2A>G", + "rnaVariantDescriptions": null, + "selectedAssembly": "hg19", + "submittedVariant": "6-24302274-T-C", + "transcriptVariant": undefined, + "validationWarnings": [], + "variantExonicPositions": { + "NC_000006.11": { + "endExon": "2i", + "startExon": "2i", + }, + "NC_000006.12": { + "endExon": "2i", + "startExon": "2i", + }, + "NG_012829.2": { + "endExon": "2i", + "startExon": "2i", + }, + }, + }, + ], + "flag": "gene_variant", + "metadata": { + "variantvalidatorHgvsVersion": "2.2.0", + "variantvalidatorVersion": "2.2.1.dev492+g032aa70", + "vvdbVersion": "vvdb_2023_8", + "vvseqrepoDb": "VV_SR_2023_05/master", + "vvtaVersion": "vvta_2023_05", + }, +} +`; + +exports[`Response.fromJson > handles telomeric variant correctly 2`] = ` +{ + "entries": [ + { + "annotations": { + "chromosome": undefined, + "dbXref": undefined, + "ensemblSelect": undefined, + "manePlusClinicalTranscript": undefined, + "maneSelect": undefined, + "map": undefined, + "note": undefined, + "refseqSelect": undefined, + "variant": undefined, + }, + "geneIds": { + "ccdIds": undefined, + "ensemblGeneId": undefined, + "entrezGeneId": undefined, + "hgncId": undefined, + "omimId": undefined, + "ucscId": undefined, + }, + "geneSymbol": "", + "genomeContextIntronicSequence": "", + "hgvsLrgTranscriptVariant": "", + "hgvsLrgVariant": "", + "hgvsPredictedProteinConsequence": { + "lrgSlr": "", + "lrgTlr": "", + "slr": "", + "tlr": "", + }, + "hgvsRefseqgeneVariant": "", + "hgvsTranscriptVariant": "", + "primaryAssemblyLoci": { + "grch37": { + "hgvsGenomicDescription": "NC_000006.11:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "100000", + "ref": "G", + }, + }, + "grch38": { + "hgvsGenomicDescription": "NC_000006.12:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "100000", + "ref": "G", + }, + }, + "hg19": { + "hgvsGenomicDescription": "NC_000006.11:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "100000", + "ref": "G", + }, + }, + "hg38": { + "hgvsGenomicDescription": "NC_000006.12:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "100000", + "ref": "G", + }, + }, + }, + "referenceSequenceRecords": "", + "refseqgeneContextIntronicSequence": "", + "rnaVariantDescriptions": null, + "selectedAssembly": "hg19", + "submittedVariant": "6-100000-G-C", + "transcriptVariant": undefined, + "validationWarnings": [ + "No transcripts found that fully overlap the described variation in the genomic sequence", + ], + "variantExonicPositions": {}, + }, + ], + "flag": "intergenic", + "metadata": { + "variantvalidatorHgvsVersion": "2.2.0", + "variantvalidatorVersion": "2.2.1.dev492+g032aa70", + "vvdbVersion": "vvdb_2023_8", + "vvseqrepoDb": "VV_SR_2023_05/master", + "vvtaVersion": "vvta_2023_05", + }, +} +`; diff --git a/src/api/variantValidator/client.spec.ts b/src/api/variantValidator/client.spec.ts new file mode 100644 index 0000000..de6a435 --- /dev/null +++ b/src/api/variantValidator/client.spec.ts @@ -0,0 +1,54 @@ +import fs from 'fs' +import path from 'path' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import createFetchMock from 'vitest-fetch-mock' + +import { SeqvarImpl } from '../../lib/genomicVars' +import { VariantValidatorClient } from './client' +import { Response } from './types' + +/** Fixture Seqvar */ +const seqvar = new SeqvarImpl('grch37', '6', 24302274, 'T', 'C') + +/** Fixture with response from API. */ +const responseManeBrca1Json = JSON.parse( + fs.readFileSync(path.resolve(__dirname, './fixture.maneResponse.BRCA1.json'), 'utf8') +) + +/** Initialize mock for `fetch()`. */ +const fetchMocker = createFetchMock(vi) + +describe.concurrent('VariantValidator', () => { + beforeEach(() => { + fetchMocker.enableMocks() + fetchMocker.resetMocks() + }) + + it('handles response correctly', async () => { + // arrange: + fetchMocker.mockResponseOnce(JSON.stringify(responseManeBrca1Json)) + + // act: + const client = new VariantValidatorClient() + const result = await client.fetchVvResults(seqvar) + + // assert: + expect(result).toMatchSnapshot() + }) + + it('throws in case of fetching problems', async () => { + // arrange: + fetchMocker.mockResponse(() => { + return Promise.reject(new Error('failed to fetch from VariantValidator')) + }) + + // act: + const client = new VariantValidatorClient() + // (with guard) + await expect(async () => await client.fetchVvResults(seqvar)).rejects.toThrow( + 'failed to fetch from VariantValidator' + ) + + // assert: + }) +}) diff --git a/src/api/variantValidator/client.ts b/src/api/variantValidator/client.ts new file mode 100644 index 0000000..aab2ac1 --- /dev/null +++ b/src/api/variantValidator/client.ts @@ -0,0 +1,36 @@ +import type { Seqvar } from '../../lib/genomicVars' + +/** Base URL for VariantValidator. */ +const API_BASE_URL = `/remote/variantvalidator` + +/** + * Client for the VariantValidator API. + */ +export class VariantValidatorClient { + private apiBaseUrl: string + + constructor(apiBaseUrl?: string) { + this.apiBaseUrl = apiBaseUrl ?? API_BASE_URL + } + + /** + * Call variant validator API via proxy. + * + * @param seqvar The `Seqvar` object to be validated. + * @returns The response from the API. + * @throws Error if the API call fails. + */ + async fetchVvResults(seqvar: Seqvar): Promise { + const { genomeBuild, chrom, pos, del, ins } = seqvar + const release = genomeBuild === 'grch37' ? 'hg19' : 'hg38' + const url = + `${this.apiBaseUrl}/${release}/` + + `${chrom}-${pos}-${del}-${ins}/mane?content-type=application%2Fjson` + + const response = await fetch(url, { method: 'GET' }) + if (!response.ok) { + throw new Error(`Failed to fetch ACMG rating for ${seqvar.userRepr}`) + } + return await response.json() + } +} diff --git a/src/api/variantValidator/fixture.maneResponse.BRCA1.json b/src/api/variantValidator/fixture.maneResponse.BRCA1.json new file mode 100644 index 0000000..58c365d --- /dev/null +++ b/src/api/variantValidator/fixture.maneResponse.BRCA1.json @@ -0,0 +1,416 @@ +{ + "NM_001195610.1:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": false, + "variant": "2" + }, + "gene_ids": { + "ccds_ids": ["CCDS4550"], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": ["605755"], + "ucsc_id": "uc003ndx.4" + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_001195610.1):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_001182539.1:p.?", + "tlr": "NP_001182539.1:p.?" + }, + "hgvs_refseqgene_variant": "", + "hgvs_transcript_variant": "NM_001195610.1:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T" + } + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T" + } + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T" + } + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T" + } + } + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_001182539.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_001195610.1" + }, + "refseqgene_context_intronic_sequence": "", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 2, mRNA", + "validation_warnings": [ + "A more recent version of the selected reference sequence NM_001195610.1 is available (NM_001195610.2): NM_001195610.2:c.349-2A>G MUST be fully validated prior to use in reports: select_variants=NM_001195610.2:c.349-2A>G" + ], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "3i", + "start_exon": "3i" + }, + "NC_000006.12": { + "end_exon": "3i", + "start_exon": "3i" + } + } + }, + "NM_001195610.2:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": false, + "variant": "2" + }, + "gene_ids": { + "ccds_ids": ["CCDS4550"], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": ["605755"], + "ucsc_id": "uc003ndx.4" + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_001195610.2):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_001182539.1:p.?", + "tlr": "NP_001182539.1:p.?" + }, + "hgvs_refseqgene_variant": "", + "hgvs_transcript_variant": "NM_001195610.2:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T" + } + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T" + } + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T" + } + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T" + } + } + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_001182539.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_001195610.2" + }, + "refseqgene_context_intronic_sequence": "", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 2, mRNA", + "validation_warnings": [], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "3i", + "start_exon": "3i" + }, + "NC_000006.12": { + "end_exon": "3i", + "start_exon": "3i" + } + } + }, + "NM_016356.4:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": false + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": false, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": false, + "variant": "1" + }, + "gene_ids": { + "ccds_ids": ["CCDS4550"], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": ["605755"], + "ucsc_id": "uc003ndx.4" + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_016356.4):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_057440.2:p.?", + "tlr": "NP_057440.2:p.?" + }, + "hgvs_refseqgene_variant": "NG_012829.1:g.61007A>G", + "hgvs_transcript_variant": "NM_016356.4:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T" + } + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T" + } + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T" + } + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T" + } + } + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_057440.2", + "refseqgene": "https://www.ncbi.nlm.nih.gov/nuccore/NG_012829.1", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_016356.4" + }, + "refseqgene_context_intronic_sequence": "NG_012829.1(NM_016356.4):c.349-2A>G", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 1, mRNA", + "validation_warnings": [ + "A more recent version of the selected reference sequence NM_016356.4 is available (NM_016356.5): NM_016356.5:c.349-2A>G MUST be fully validated prior to use in reports: select_variants=NM_016356.5:c.349-2A>G" + ], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "2i", + "start_exon": "2i" + }, + "NC_000006.12": { + "end_exon": "2i", + "start_exon": "2i" + }, + "NG_012829.1": { + "end_exon": "2i", + "start_exon": "2i" + } + } + }, + "NM_016356.5:c.349-2A>G": { + "alt_genomic_loci": [], + "annotations": { + "chromosome": "6", + "db_xref": { + "CCDS": "CCDS4550.1", + "ensemblgene": null, + "hgnc": "HGNC:18141", + "ncbigene": "51473", + "select": "MANE" + }, + "ensembl_select": false, + "mane_plus_clinical": false, + "mane_select": true, + "map": "6p22.3", + "note": "doublecortin domain containing 2", + "refseq_select": true, + "variant": "1" + }, + "gene_ids": { + "ccds_ids": ["CCDS4550"], + "ensembl_gene_id": "ENSG00000146038", + "entrez_gene_id": "51473", + "hgnc_id": "HGNC:18141", + "omim_id": ["605755"], + "ucsc_id": "uc003ndx.4" + }, + "gene_symbol": "DCDC2", + "genome_context_intronic_sequence": "NC_000006.11(NM_016356.5):c.349-2A>G", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "NP_057440.2:p.?", + "tlr": "NP_057440.2:p.?" + }, + "hgvs_refseqgene_variant": "NG_012829.2:g.86247A>G", + "hgvs_transcript_variant": "NM_016356.5:c.349-2A>G", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302274", + "ref": "T" + } + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "24302046", + "ref": "T" + } + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.24302274T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302274", + "ref": "T" + } + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.24302046T>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "24302046", + "ref": "T" + } + } + }, + "reference_sequence_records": { + "protein": "https://www.ncbi.nlm.nih.gov/nuccore/NP_057440.2", + "refseqgene": "https://www.ncbi.nlm.nih.gov/nuccore/NG_012829.2", + "transcript": "https://www.ncbi.nlm.nih.gov/nuccore/NM_016356.5" + }, + "refseqgene_context_intronic_sequence": "NG_012829.2(NM_016356.5):c.349-2A>G", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-24302274-T-C", + "transcript_description": "Homo sapiens doublecortin domain containing 2 (DCDC2), transcript variant 1, mRNA", + "validation_warnings": [], + "variant_exonic_positions": { + "NC_000006.11": { + "end_exon": "2i", + "start_exon": "2i" + }, + "NC_000006.12": { + "end_exon": "2i", + "start_exon": "2i" + }, + "NG_012829.2": { + "end_exon": "2i", + "start_exon": "2i" + } + } + }, + "flag": "gene_variant", + "metadata": { + "variantvalidator_hgvs_version": "2.2.0", + "variantvalidator_version": "2.2.1.dev492+g032aa70", + "vvdb_version": "vvdb_2023_8", + "vvseqrepo_db": "VV_SR_2023_05/master", + "vvta_version": "vvta_2023_05" + } +} diff --git a/src/api/variantValidator/fixture.maneResponse.telomeric.json b/src/api/variantValidator/fixture.maneResponse.telomeric.json new file mode 100644 index 0000000..afc7f72 --- /dev/null +++ b/src/api/variantValidator/fixture.maneResponse.telomeric.json @@ -0,0 +1,75 @@ +{ + "flag": "intergenic", + "intergenic_variant_1": { + "alt_genomic_loci": [], + "annotations": {}, + "gene_ids": {}, + "gene_symbol": "", + "genome_context_intronic_sequence": "", + "hgvs_lrg_transcript_variant": "", + "hgvs_lrg_variant": "", + "hgvs_predicted_protein_consequence": { + "lrg_slr": "", + "lrg_tlr": "", + "slr": "", + "tlr": "" + }, + "hgvs_refseqgene_variant": "", + "hgvs_transcript_variant": "", + "primary_assembly_loci": { + "grch37": { + "hgvs_genomic_description": "NC_000006.11:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "100000", + "ref": "G" + } + }, + "grch38": { + "hgvs_genomic_description": "NC_000006.12:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "6", + "pos": "100000", + "ref": "G" + } + }, + "hg19": { + "hgvs_genomic_description": "NC_000006.11:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "100000", + "ref": "G" + } + }, + "hg38": { + "hgvs_genomic_description": "NC_000006.12:g.100000G>C", + "vcf": { + "alt": "C", + "chr": "chr6", + "pos": "100000", + "ref": "G" + } + } + }, + "reference_sequence_records": "", + "refseqgene_context_intronic_sequence": "", + "rna_variant_descriptions": null, + "selected_assembly": "hg19", + "submitted_variant": "6-100000-G-C", + "transcript_description": "", + "validation_warnings": [ + "No transcripts found that fully overlap the described variation in the genomic sequence" + ], + "variant_exonic_positions": null + }, + "metadata": { + "variantvalidator_hgvs_version": "2.2.0", + "variantvalidator_version": "2.2.1.dev492+g032aa70", + "vvdb_version": "vvdb_2023_8", + "vvseqrepo_db": "VV_SR_2023_05/master", + "vvta_version": "vvta_2023_05" + } +} diff --git a/src/api/variantValidator/index.ts b/src/api/variantValidator/index.ts new file mode 100644 index 0000000..886d07b --- /dev/null +++ b/src/api/variantValidator/index.ts @@ -0,0 +1,2 @@ +export * from './types' +export * from './client' diff --git a/src/api/variantValidator/types.spec.ts b/src/api/variantValidator/types.spec.ts new file mode 100644 index 0000000..73c6921 --- /dev/null +++ b/src/api/variantValidator/types.spec.ts @@ -0,0 +1,41 @@ +import fs from 'fs' +import path from 'path' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import createFetchMock from 'vitest-fetch-mock' + +import { SeqvarImpl } from '../../lib/genomicVars' +import { VariantValidatorClient } from './client' +import { Response } from './types' + +/** Fixture Seqvar */ +const seqvar = new SeqvarImpl('grch37', '6', 24302274, 'T', 'C') + +/** Fixtures with response from API. */ +const maneResponseBrca1Json = JSON.parse( + fs.readFileSync(path.resolve(__dirname, './fixture.maneResponse.BRCA1.json'), 'utf8') +) +const maneResponseTelomericJson = JSON.parse( + fs.readFileSync(path.resolve(__dirname, './fixture.maneResponse.telomeric.json'), 'utf8') +) + +describe.concurrent('Response.fromJson', () => { + it('handles BRCA1 variant correctly', async () => { + // arrange: + + // act: + const result = Response.fromJson(maneResponseBrca1Json) + + // assert: + expect(result).toMatchSnapshot() + }) + + it('handles telomeric variant correctly', async () => { + // arrange: + + // act: + const result = Response.fromJson(maneResponseTelomericJson) + + // assert: + expect(result).toMatchSnapshot() + }) +}) diff --git a/src/api/variantValidator/types.ts b/src/api/variantValidator/types.ts new file mode 100644 index 0000000..008cc5e --- /dev/null +++ b/src/api/variantValidator/types.ts @@ -0,0 +1,503 @@ +/** GeneID information as returned by the API. */ +export interface GeneIds$Api { + ccd_ids?: string[] + ensembl_gene_id?: string + entrez_gene_id?: string + hgnc_id?: string + omim_id?: string[] + ucsc_id?: string +} + +/** + * Data structure for gene IDs. + */ +export interface GeneIds { + ccdIds?: string[] + ensemblGeneId?: string + entrezGeneId?: string + hgncId?: string + omimId?: string[] + ucscId?: string +} + +/** Helper class for converting from `GeneIds$Api` to `GeneIds` */ +class GeneIds$Type { + fromJson(json: GeneIds$Api): GeneIds { + return { + ccdIds: json.ccd_ids, + ensemblGeneId: json.ensembl_gene_id, + entrezGeneId: json.entrez_gene_id, + hgncId: json.hgnc_id, + omimId: json.omim_id, + ucscId: json.ucsc_id + } + } +} + +/** + * Helper instance for converting from `GeneIds$Api` to `GeneIds`. + */ +export const GeneIds = new GeneIds$Type() + +/** + * HGVS predicted protein consequence as returned by the API. + */ +export interface HgvsPredictedProteinConsequence$Api { + lrg_slr: string + lrg_tlr: string + slr: string + tlr: string +} + +/** + * Data structure for HGVS predicted protein consequence. + */ +export interface HgvsPredictedProteinConsequence { + lrgSlr: string + lrgTlr: string + slr: string + tlr: string +} + +/** + * Helper class for converting from `HgvsPredictedProteinConsequence$Api` to + * `HgvsPredictedProteinConsequence` + */ +class HgvsPredictedProteinConsequence$Type { + fromJson(json: HgvsPredictedProteinConsequence$Api): HgvsPredictedProteinConsequence { + return { + lrgSlr: json.lrg_slr, + lrgTlr: json.lrg_tlr, + slr: json.slr, + tlr: json.tlr + } + } +} + +/** + * Helper instance for converting from `HgvsPredictedProteinConsequence$Api` to + * `HgvsPredictedProteinConsequence`. + */ +export const HgvsPredictedProteinConsequence = new HgvsPredictedProteinConsequence$Type() + +/** + * DB x-references as returned by the API. + */ +export interface DbXref$Api { + CCDS: string | null + ensemblgene: string | null + hgnc: string | null + ncbigene: string | null + select: string | null +} + +/** + * Data structure for DB x-references. + */ +export interface DbXref { + ccds: string | null + ensemblgene: string | null + hgnc: string | null + ncbigene: string | null + select: string | null +} + +/** + * Helper class for converting from `DbXref$Api` to `DbXref`. + */ +class DbXref$Type { + fromJson(json: DbXref$Api): DbXref { + return { + ccds: json.CCDS, + ensemblgene: json.ensemblgene, + hgnc: json.hgnc, + ncbigene: json.ncbigene, + select: json.select + } + } +} + +/** + * Helper instance for converting from `DbXref$Api` to `DbXref`. + */ +export const DbXref = new DbXref$Type() + +/** + * Annotation information as returned by the API. + */ +export interface Annotations$Api { + chromosome?: string + db_xref?: DbXref$Api + ensembl_select?: boolean + mane_plus_clinical_transcript?: boolean + mane_select?: boolean + map?: string + note?: string + refseq_select?: boolean + variant?: string +} + +/** + * Data structure for annotations. + */ +export interface Annotations { + chromosome?: string + dbXref?: DbXref + ensemblSelect?: boolean + manePlusClinicalTranscript?: boolean + maneSelect?: boolean + map?: string + note?: string + refseqSelect?: boolean + variant?: string +} + +/** Helper class for converting from `Annotations$Api` to `Annotations` */ +class Annotations$Type { + fromJson(json: Annotations$Api): Annotations { + return { + chromosome: json.chromosome, + dbXref: json.db_xref === undefined ? undefined : DbXref.fromJson(json.db_xref), + ensemblSelect: json.ensembl_select, + manePlusClinicalTranscript: json.mane_plus_clinical_transcript, + maneSelect: json.mane_select, + map: json.map, + note: json.note, + refseqSelect: json.refseq_select, + variant: json.variant + } + } +} + +/** + * Helper instance for converting from `Annotations$Api` to `Annotations`. + */ +export const Annotations = new Annotations$Type() + +/** + * VCF information from assembly locus as returned by the API. + */ +export interface Vcf$Api { + alt: string + chr: string + pos: string + ref: string +} + +/** + * Data structure for VCF information from assembly locus. + */ +export interface Vcf { + alt: string + chr: string + pos: string + ref: string +} + +/** Helper class for converting from `Vcf$Api` to `Vcf` */ +class Vcf$Type { + fromJson(json: Vcf$Api): Vcf { + return { + alt: json.alt, + chr: json.chr, + pos: json.pos, + ref: json.ref + } + } +} + +/** + * Helper instance for converting from `Vcf$Api` to `Vcf`. + */ +export const Vcf = new Vcf$Type() + +/** + * Assembly locus description as returned by the API. + */ +export interface AssemblyLocus$Api { + hgvs_genomic_description: string + vcf: Vcf$Api +} + +/** + * Data structure for assembly locus description. + */ +export interface AssemblyLocus { + hgvsGenomicDescription: string + vcf: Vcf +} + +/** Helper class for converting from `AssemblyLocus$Api` to `AssemblyLocus` */ +class AssemblyLocus$Type { + fromJson(json: AssemblyLocus$Api): AssemblyLocus { + return { + hgvsGenomicDescription: json.hgvs_genomic_description, + vcf: Vcf.fromJson(json.vcf) + } + } +} + +/** + * Helper instance for converting from `AssemblyLocus$Api` to `AssemblyLocus`. + */ +export const AssemblyLocus = new AssemblyLocus$Type() + +/** + * Primary assembly loci as returned by the API. + */ +export interface PrimaryAssemblyLoci$Api { + grch37: AssemblyLocus$Api | null + grch38: AssemblyLocus$Api | null + hg19: AssemblyLocus$Api | null + hg38: AssemblyLocus$Api | null +} + +/** + * Data structure for primary assembly loci. + */ +export interface PrimaryAssemblyLoci { + grch37: AssemblyLocus | null + grch38: AssemblyLocus | null + hg19: AssemblyLocus | null + hg38: AssemblyLocus | null +} + +/** Helper class for converting from `PrimaryAssemblyLoci$Api` to `PrimaryAssemblyLoci` */ +class PrimaryAssemblyLoci$Type { + fromJson(json: PrimaryAssemblyLoci$Api): PrimaryAssemblyLoci { + return { + grch37: json.grch37 ? AssemblyLocus.fromJson(json.grch37) : null, + grch38: json.grch38 ? AssemblyLocus.fromJson(json.grch38) : null, + hg19: json.hg19 ? AssemblyLocus.fromJson(json.hg19) : null, + hg38: json.hg38 ? AssemblyLocus.fromJson(json.hg38) : null + } + } +} + +/** + * Helper instance for converting from `PrimaryAssemblyLoci$Api` to `PrimaryAssemblyLoci`. + */ +export const PrimaryAssemblyLoci = new PrimaryAssemblyLoci$Type() + +/** + * Reference sequence records as returned by the API. + */ +export interface ReferenceSequenceRecords$Api { + protein: string | null + refseqgene: string | null + transcript: string | null +} + +/** + * Data structure for reference sequence records. + */ +export interface ReferenceSequenceRecords { + protein: string | null + refseqgene: string | null + transcript: string | null +} + +/** + * Helper class for converting from `ReferenceSequenceRecords$Api` to + * `ReferenceSequenceRecords` + */ +class ReferenceSequenceRecords$Type { + fromJson(json: ReferenceSequenceRecords$Api): ReferenceSequenceRecords { + return { + protein: json.protein, + refseqgene: json.refseqgene, + transcript: json.transcript + } + } +} + +/** + * Helper instance for converting from `ReferenceSequenceRecords$Api` to + * `ReferenceSequenceRecords`. + */ +export const ReferenceSequenceRecords = new ReferenceSequenceRecords$Type() + +/** + * Variant exonic position as returned by the API. + */ +export interface VariantExonicPosition$Api { + end_exon: string + start_exon: string +} + +/** + * Data structure for variant exonic position. + */ +export interface VariantExonicPosition { + endExon: string + startExon: string +} + +/** Helper class for converting from `VariantExonicPosition$Api` to `VariantExonicPosition` */ +class VariantExonicPosition$Type { + fromJson(json: VariantExonicPosition$Api): VariantExonicPosition { + return { + endExon: json.end_exon, + startExon: json.start_exon + } + } +} + +/** + * Helper instance for converting from `VariantExonicPosition$Api` to `VariantExonicPosition`. + */ +export const VariantExonicPosition = new VariantExonicPosition$Type() + +/** + * Single entry as returned by the API. + */ +export interface Entry$Api { + annotations: Annotations$Api + gene_ids: GeneIds$Api + gene_symbol: string | null + genome_context_intronic_sequence: string | null + hgvs_lrg_transcript_variant: string | null + hgvs_lrg_variant: string | null + hgvs_predicted_protein_consequence: never + hgvs_refseqgene_variant: string | null + hgvs_transcript_variant: string | null + primary_assembly_loci: PrimaryAssemblyLoci$Api + reference_sequence_records: ReferenceSequenceRecords$Api | '' + refseqgene_context_intronic_sequence: string | '' + rna_variant_descriptions: string | null + selected_assembly: string + submitted_variant: string + transcript_variant: string | null + validation_warnings: string[] + variant_exonic_positions: { [key: string]: VariantExonicPosition$Api } | null +} + +/** Data structure for result entries. */ +export interface Entry { + annotations: Annotations + geneIds: GeneIds + geneSymbol: string | null + genomeContextIntronicSequence: string | null + hgvsLrgTranscriptVariant: string | null + hgvsLrgVariant: string | null + hgvsPredictedProteinConsequence: HgvsPredictedProteinConsequence | null + hgvsRefseqgeneVariant: string | null + hgvsTranscriptVariant: string | null + primaryAssemblyLoci: PrimaryAssemblyLoci + referenceSequenceRecords: ReferenceSequenceRecords | '' + refseqgeneContextIntronicSequence: string + rnaVariantDescriptions: string | null + selectedAssembly: string + submittedVariant: string + transcriptVariant: string | null + validationWarnings: string[] + variantExonicPositions: { [key: string]: VariantExonicPosition } +} + +/** Helper class for converting from `Entry$Api` to `Entry` */ +class Entry$Type { + fromJson(json: Entry$Api): Entry { + return { + annotations: Annotations.fromJson(json.annotations), + geneIds: GeneIds.fromJson(json.gene_ids), + geneSymbol: json.gene_symbol, + genomeContextIntronicSequence: json.genome_context_intronic_sequence, + hgvsLrgTranscriptVariant: json.hgvs_lrg_transcript_variant, + hgvsLrgVariant: json.hgvs_lrg_variant, + hgvsPredictedProteinConsequence: HgvsPredictedProteinConsequence.fromJson( + json.hgvs_predicted_protein_consequence + ), + hgvsRefseqgeneVariant: json.hgvs_refseqgene_variant, + hgvsTranscriptVariant: json.hgvs_transcript_variant, + primaryAssemblyLoci: PrimaryAssemblyLoci.fromJson(json.primary_assembly_loci), + referenceSequenceRecords: + json.reference_sequence_records === '' + ? '' + : ReferenceSequenceRecords.fromJson(json.reference_sequence_records), + refseqgeneContextIntronicSequence: json.refseqgene_context_intronic_sequence, + rnaVariantDescriptions: json.rna_variant_descriptions, + selectedAssembly: json.selected_assembly, + submittedVariant: json.submitted_variant, + transcriptVariant: json.transcript_variant, + validationWarnings: json.validation_warnings, + variantExonicPositions: + json.variant_exonic_positions === null + ? {} + : Object.entries(json.variant_exonic_positions).reduce( + (acc, [key, value]) => { + acc[key] = VariantExonicPosition.fromJson(value) + return acc + }, + {} as { [key: string]: VariantExonicPosition } + ) + } + } +} + +/** + * Helper instance for converting from `Entry$Api` to `Entry`. + */ +export const Entry = new Entry$Type() + +/** + * Metadata as returned by the API. + */ +export interface Metadata$Api { + variantvalidator_hgvs_version: string + variantvalidator_version: string + vvdb_version: string + vvseqrepo_db: string + vvta_version: string +} + +/** Data structure for metadata. */ +export interface Metadata { + variantvalidatorHgvsVersion: string + variantvalidatorVersion: string + vvdbVersion: string + vvseqrepoDb: string + vvtaVersion: string +} + +/** Helper class for converting from `Metadata$Api` to `Metadata` */ +class Metadata$Type { + fromJson(json: Metadata$Api): Metadata { + return { + variantvalidatorHgvsVersion: json.variantvalidator_hgvs_version, + variantvalidatorVersion: json.variantvalidator_version, + vvdbVersion: json.vvdb_version, + vvseqrepoDb: json.vvseqrepo_db, + vvtaVersion: json.vvta_version + } + } +} + +/** + * Helper instance for converting from `Metadata$Api` to `Metadata`. + */ +export const Metadata = new Metadata$Type() + +/** Representation of VariantValidator result. */ +export interface Response { + entries: Entry[] + flag: string + metadata: Metadata +} + +/** Helper class for converting from response JSON to `Response` */ +class Response$Type { + fromJson(json: any): Response { + return { + entries: Object.entries(json) + .filter(([key, _]) => !['flag', 'metadata'].includes(key)) + .map(([_, value]) => Entry.fromJson(value as any)), + flag: json.flag, + metadata: Metadata.fromJson(json.metadata) + } + } +} + +/** + * Helper instance for converting from response JSON to `Response`. + */ +export const Response = new Response$Type()