From 75fd027b0b8340918c353fce1268f96fbd55752c Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Thu, 6 Oct 2022 13:59:08 -0700 Subject: [PATCH 01/52] Add displayName for MOA signature CategoryVariant --- src/moa/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/moa/index.js b/src/moa/index.js index 4486592a..022ba08b 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -268,7 +268,11 @@ const loadVariant = async (conn, moaVariant) => { }); const variantType = await conn.getVocabularyTerm('signature present'); return conn.addVariant({ - content: { reference1: rid(signature), type: rid(variantType) }, + content: { + displayName: `${signature.name.toUpperCase()} signature present`, + reference1: rid(signature), + type: rid(variantType), + }, existsOk: true, target: 'CategoryVariant', }); From a81bc94e3670a95eb956dd30f78d583760ac0868 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Mon, 17 Jun 2024 15:09:23 -0700 Subject: [PATCH 02/52] add displayName format to diseaseOntology --- src/diseaseOntology/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/diseaseOntology/index.js b/src/diseaseOntology/index.js index 772bdddf..dab13d8e 100644 --- a/src/diseaseOntology/index.js +++ b/src/diseaseOntology/index.js @@ -252,6 +252,7 @@ const uploadFile = async ({ alias: false, deprecated, description, + displayName: `${name} [${sourceId.toUpperCase()}]`, name, source, sourceId, @@ -286,6 +287,7 @@ const uploadFile = async ({ for (const alias of aliases) { const content = { alias: true, + displayName: `${alias} [${record.sourceId.toUpperCase()}]`, name: alias, source, sourceId: record.sourceId, @@ -331,6 +333,7 @@ const uploadFile = async ({ for (const alternateId of hasDeprecated) { const content = { deprecated: true, + displayName: `${record.name} [${alternateId.toUpperCase()}]`, name: record.name, source, sourceId: alternateId, From 291b8baacb906581588c3395b88adca78f37450a Mon Sep 17 00:00:00 2001 From: sshugsc Date: Mon, 17 Jun 2024 15:09:58 -0700 Subject: [PATCH 03/52] add displayName format to oncotree --- src/oncotree/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/oncotree/index.js b/src/oncotree/index.js index c03c0072..811b37b3 100644 --- a/src/oncotree/index.js +++ b/src/oncotree/index.js @@ -211,6 +211,7 @@ const upload = async (opt) => { // upload the results for (const record of records) { const body = { + displayName: `${record.name} [${record.sourceId.toUpperCase()}]`, name: record.name, source: rid(source), sourceId: record.sourceId, From 34e89a22891f62be099776ca38f22ae5c2b6d40d Mon Sep 17 00:00:00 2001 From: sshugsc Date: Tue, 9 Jul 2024 10:55:44 -0700 Subject: [PATCH 04/52] add displayname to chromosome json and update ontology readme --- data/chromosomes.json | 9 ++++++--- src/ontology/README.md | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/data/chromosomes.json b/data/chromosomes.json index c8fabdba..3c2046b4 100644 --- a/data/chromosomes.json +++ b/data/chromosomes.json @@ -91,15 +91,18 @@ }, "MT": { "biotype": "chromosome", - "name": "chrMT" + "name": "chrMT", + "displayName":"mt" }, "X": { "biotype": "chromosome", - "name": "chrX" + "name": "chrX", + "displayName":"x" }, "Y": { "biotype": "chromosome", - "name": "chrY" + "name": "chrY", + "displayName":"y" } }, "sources": { diff --git a/src/ontology/README.md b/src/ontology/README.md index 4a1b93d9..9e41ea83 100644 --- a/src/ontology/README.md +++ b/src/ontology/README.md @@ -80,5 +80,5 @@ the ontology term Once this file has been built it can be loaded as follows. The script will create records if they do not already exist. Any conflicts will be reported in the logging ```bash -node bin/ontology.js --filename /path/to/json/file +node bin/load.js file ontology {/path/to/json/file} ``` From 69a9eb88a0354595714b23eec44fca9b6812e8cf Mon Sep 17 00:00:00 2001 From: sshugsc Date: Fri, 12 Jul 2024 14:41:26 -0700 Subject: [PATCH 05/52] update chembl loader content name --- src/chembl/index.js | 2 +- src/drugbank/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chembl/index.js b/src/chembl/index.js index 8f9f091c..935ca2b3 100644 --- a/src/chembl/index.js +++ b/src/chembl/index.js @@ -47,7 +47,7 @@ const fetchAndLoadById = async (conn, drugId) => { const source = rid(CACHE.SOURCE); const content = { - name: chemblRecord.pref_name, + name: chemblRecord.pref_name || chemblRecord.molecule_properties.full_molformula, source, sourceId: chemblRecord.molecule_chembl_id, }; diff --git a/src/drugbank/README.md b/src/drugbank/README.md index 8a9d3de2..97cba1e3 100644 --- a/src/drugbank/README.md +++ b/src/drugbank/README.md @@ -18,7 +18,7 @@ mv full\ database.xml $filename Then use the general file loader to load this into GraphKB ```bash -node bin/load.js file drugbank_all_full_database_*.xml +node bin/load.js file drugbank full_database.xml ``` > :warning: Since this contains cross-mappings to [FDA-SRS](../fdaSrs) UNII identifiers it is useful to load that file From 255006f33ca8e26bc8748a76e34bc790171baecc Mon Sep 17 00:00:00 2001 From: Shirley Shu <147874967+sshugsc@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:52:51 -0700 Subject: [PATCH 06/52] Update README.md --- src/ontology/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ontology/README.md b/src/ontology/README.md index 9e41ea83..c2fee005 100644 --- a/src/ontology/README.md +++ b/src/ontology/README.md @@ -80,5 +80,5 @@ the ontology term Once this file has been built it can be loaded as follows. The script will create records if they do not already exist. Any conflicts will be reported in the logging ```bash -node bin/load.js file ontology {/path/to/json/file} +node bin/load.js file ontology ``` From 9f7871e45b58ce08fdaa6b25e2cb7ab4c746067a Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Wed, 31 Jul 2024 16:13:03 -0700 Subject: [PATCH 07/52] Updates to package-lock.json --- package-lock.json | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5212d6a5..674875bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2773,12 +2773,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4620,9 +4620,9 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -11606,9 +11606,9 @@ } }, "node_modules/ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "engines": { "node": ">=8.3.0" @@ -13939,12 +13939,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-process-hrtime": { @@ -15365,9 +15365,9 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -20805,9 +20805,9 @@ } }, "ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "requires": {} }, From 6bfd11f95e3c1bf53ccb25800c89662975cbb192 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Wed, 31 Jul 2024 16:13:42 -0700 Subject: [PATCH 08/52] kbdev-1231 remove SubClassOf from wild type data/vocab.json --- data/vocab.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/data/vocab.json b/data/vocab.json index 206925f7..22ce6f2c 100644 --- a/data/vocab.json +++ b/data/vocab.json @@ -2250,12 +2250,7 @@ ] }, "wild type": { - "links": [ - { - "class": "SubClassOf", - "target": "no functional effect" - } - ] + "comment": "Not a SubClassOf 'no functional effect' anymore. See KBDEV-1231" }, "wildtype": { "deprecated": true, From 6ae71c3cf4f61ceeaa21f123065b5af3dfd1c1bf Mon Sep 17 00:00:00 2001 From: Matthew Stuart-Edwards Date: Fri, 9 Aug 2024 15:07:43 -0600 Subject: [PATCH 09/52] Updated biomarkers and cancerhotspots download URL Both data sources changed their URL --- Snakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Snakefile b/Snakefile index d3e8a363..cc39f0d2 100644 --- a/Snakefile +++ b/Snakefile @@ -144,7 +144,7 @@ rule download_cgi: output: f'{DATA_DIR}/cgi/cgi_biomarkers_per_variant.tsv' shell: dedent(f'''\ cd {DATA_DIR}/cgi - wget https://www.cancergenomeinterpreter.org/data/cgi_biomarkers_20180117.zip + wget https://www.cancergenomeinterpreter.org/data/biomarkers/cgi_biomarkers_20180117.zip unzip cgi_biomarkers_20180117.zip ''') @@ -162,7 +162,7 @@ rule download_cancerhotspots: shell: dedent(f'''\ mkdir -p {DATA_DIR}/cancerhotspots cd {DATA_DIR}/cancerhotspots - wget http://download.cbioportal.org/cancerhotspots/cancerhotspots.v2.maf.gz + wget https://cbioportal-download.s3.amazonaws.com/cancerhotspots.v2.maf.gz gunzip cancerhotspots.v2.maf.gz ''') From 6890df03ba4389d599958b23bdb09d49b1889c0f Mon Sep 17 00:00:00 2001 From: Matthew Stuart-Edwards Date: Fri, 9 Aug 2024 15:08:21 -0600 Subject: [PATCH 10/52] fda_srs depends on NCIT. Got an error executing the snakemake where it seemed fda_srs depends on NCIT being already in the database. error: Cannot link to NCIT, Unable to find source record Error: missing Source record where {"name":"ncit"} So I added a dependency to ncit.COMPLETE in the load_fda_srs. --- Snakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Snakefile b/Snakefile index cc39f0d2..475f39b6 100644 --- a/Snakefile +++ b/Snakefile @@ -222,6 +222,7 @@ rule load_ncit: rule load_fda_srs: input: expand(rules.load_local.output, local=['vocab']), + f'{DATA_DIR}/ncit.COMPLETE', data=f'{DATA_DIR}/fda/UNII_Records.txt' container: CONTAINER log: f'{LOGS_DIR}/fdaSrs.logs.txt' From f00e0277d82a46681a029226dcd87e68842fd749 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Wed, 28 Aug 2024 14:57:03 -0700 Subject: [PATCH 11/52] KBDEV-1240 make entrez gene records updatable --- src/entrez/gene.js | 34 ++++++++++++++++++++++------------ src/entrez/util.js | 7 ++++++- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/entrez/gene.js b/src/entrez/gene.js index 2c7b428a..dd1cdeed 100644 --- a/src/entrez/gene.js +++ b/src/entrez/gene.js @@ -49,19 +49,29 @@ const parseRecord = (record) => { * * @param {ApiConnection} api connection to GraphKB * @param {Array.} idList list of gene IDs + * @param {object} opt + * @param {boolean} opt.fetchFirst override util.uploadRecord() fetchFirst + * @param {boolean} opt.upsert override util.uploadRecord() upsert */ -const fetchAndLoadGeneByIds = async (api, idListIn) => util.fetchAndLoadByIds( - api, - idListIn, - { - MAX_CONSEC, - cache: CACHE, - dbName: DB_NAME, - parser: parseRecord, - sourceDefn: SOURCE_DEFN, - target: 'Feature', - }, -); +const fetchAndLoadGeneByIds = async (api, idListIn, opt = {}) => { + // For record update, set fetchFirst to false & upsert to true. + const { fetchFirst, upsert } = opt; + + return util.fetchAndLoadByIds( + api, + idListIn, + { + MAX_CONSEC, + cache: CACHE, + dbName: DB_NAME, + fetchFirst, + parser: parseRecord, + sourceDefn: SOURCE_DEFN, + target: 'Feature', + upsert, + }, + ) +}; /** * Given a gene symbol, search the genes and upload the resulting records to graphkb diff --git a/src/entrez/util.js b/src/entrez/util.js index afb6ee7e..ef2e67c4 100644 --- a/src/entrez/util.js +++ b/src/entrez/util.js @@ -138,6 +138,7 @@ const fetchRecord = async (api, { * @param {boolean} opt.fetchFirst attempt to get the record by source Id before uploading it * @param {string} opt.target * @param {object} opt.sourceDefn + * @param {boolean} opt.upsert update the record if already exists * @param {function} opt.createDisplayName */ const uploadRecord = async (api, content, opt = {}) => { @@ -257,14 +258,16 @@ const preLoadCache = async (api, { sourceDefn, cache, target }) => { * @param {Array.} idListIn list of pubmed IDs * @param {Object} opt * @param {string} opt.dbName name of the entrez db to pull from ex. gene + * @param {boolean} opt.fetchFirst override uploadRecord() fetchFirst * @param {function} opt.parser function to convert records from the api to the graphkb format * @param {object} opt.cache * @param {number} opt.MAX_CONSEC maximum consecutive records to upload at once * @param {string} opt.target the graphkb api target to upload to * @param {object} opt.sourceDefn the object with the source information + * @param {boolean} opt.upsert override uploadRecord() upsert */ const fetchAndLoadByIds = async (api, idListIn, { - dbName, parser, cache, MAX_CONSEC = 100, target, sourceDefn, + dbName, fetchFirst, parser, cache, MAX_CONSEC = 100, target, sourceDefn, upsert }) => { const records = await fetchByIdList( idListIn, @@ -281,8 +284,10 @@ const fetchAndLoadByIds = async (api, idListIn, { const newRecords = await Promise.all(current.map( async record => uploadRecord(api, record, { cache, + fetchFirst, sourceDefn, target, + upsert, }), )); result.push(...newRecords); From 51e587f8a7117d299c4b4936908338ea811279f5 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Wed, 28 Aug 2024 15:01:03 -0700 Subject: [PATCH 12/52] linting --- src/entrez/gene.js | 2 +- src/entrez/util.js | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/entrez/gene.js b/src/entrez/gene.js index dd1cdeed..c7c645d6 100644 --- a/src/entrez/gene.js +++ b/src/entrez/gene.js @@ -70,7 +70,7 @@ const fetchAndLoadGeneByIds = async (api, idListIn, opt = {}) => { target: 'Feature', upsert, }, - ) + ); }; /** diff --git a/src/entrez/util.js b/src/entrez/util.js index ef2e67c4..8dc7bcd4 100644 --- a/src/entrez/util.js +++ b/src/entrez/util.js @@ -267,7 +267,14 @@ const preLoadCache = async (api, { sourceDefn, cache, target }) => { * @param {boolean} opt.upsert override uploadRecord() upsert */ const fetchAndLoadByIds = async (api, idListIn, { - dbName, fetchFirst, parser, cache, MAX_CONSEC = 100, target, sourceDefn, upsert + dbName, + fetchFirst, + parser, + cache, + MAX_CONSEC = 100, + target, + sourceDefn, + upsert, }) => { const records = await fetchByIdList( idListIn, From 5a83dc3879d9f0c3aa1de6fc824cb0c11279078a Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Thu, 29 Aug 2024 10:54:06 -0700 Subject: [PATCH 13/52] Add logger to util exports --- src/util.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util.js b/src/util.js index 6fa40c8e..45c492ab 100644 --- a/src/util.js +++ b/src/util.js @@ -234,6 +234,7 @@ module.exports = { hashStringToId, loadDelimToJson, loadXmlToJson, + logger, parseXmlToJson, request, requestWithRetry, From 93ae50dc64ef1de97a84205b8c4ed6c16ebc7a76 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Tue, 10 Sep 2024 13:47:40 -0700 Subject: [PATCH 14/52] Add comments for KBDEV-993/994 --- src/moa/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/moa/index.js b/src/moa/index.js index 022ba08b..2a410c79 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -269,6 +269,8 @@ const loadVariant = async (conn, moaVariant) => { const variantType = await conn.getVocabularyTerm('signature present'); return conn.addVariant({ content: { + // KBDEV-994 adding displayName + // TODO: test displayName in KBDEV-993 and remove both comments. displayName: `${signature.name.toUpperCase()} signature present`, reference1: rid(signature), type: rid(variantType), From 9f5ef9ccbeda4bd2909e1c081536a3fb94010648 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Wed, 25 Sep 2024 13:07:19 -0700 Subject: [PATCH 15/52] handle moa loader errors --- src/moa/index.js | 74 ++++++++++++++++++++++++++++++----------------- src/moa/spec.json | 20 +++---------- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 63598a70..b36a4c2d 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -256,28 +256,35 @@ const loadVariant = async (conn, moaVariant) => { }); } } else if (moaVariant.feature_type === 'mutational_signature') { - const signature = await conn.getUniqueRecordBy({ + const signature = await conn.getRecords({ filters: { AND: [ { source: { filters: { name: 'cosmic' }, target: 'Source' } }, - { sourceId: `SBS${Number.parseInt(moaVariant.cosmic_signature_number, 10)}` }, - { sourceIdVersion: `${Number.parseInt(moaVariant.cosmic_signature_version, 10)}` }, + { sourceId: moaVariant.cosmic_signature}, ], }, target: 'Signature', }); const variantType = await conn.getVocabularyTerm('signature present'); - return conn.addVariant({ - content: { - // KBDEV-994 adding displayName - // TODO: test displayName in KBDEV-993 and remove both comments. - displayName: `${signature.name.toUpperCase()} signature present`, - reference1: rid(signature), - type: rid(variantType), - }, - existsOk: true, - target: 'CategoryVariant', - }); + try{ + const record = await conn.getUniqueRecordBy({ + filters: { AND: [{ reference1: rid(signature[0])}, { type: rid(variantType) }] }, + target: 'CategoryVariant', + }); + return await conn.updateRecord('CategoryVariant', record['@rid'], { + displayName: `${signature[0].name.toUpperCase()} signature present` + }); + } catch(err) { + return await conn.addVariant({ + content: { + displayName: `${signature[0].name.toUpperCase()} signature present`, + reference1: rid(signature[0]), + type: rid(variantType), + }, + existsOk: true, + target: 'CategoryVariant', + }); + } // } else if (moaVariant.feature_type === 'mutational_burden') { } else if (moaVariant.feature_type === 'copy_number') { const variantType = await conn.getVocabularyTerm(moaVariant.direction); @@ -309,7 +316,6 @@ const loadRecord = async (conn, moaRecord, moaSource, relevanceTerms) => { disease = await conn.getUniqueRecordBy({ filters: { AND: [ - { name: moaRecord.oncotree_term }, { sourceId: moaRecord.oncotree_code }, { source: { filters: { name: 'oncotree' }, target: 'Source' } }, ], @@ -362,18 +368,30 @@ const loadRecord = async (conn, moaRecord, moaSource, relevanceTerms) => { if (sourceRecord.nct && sourceRecord.source_type !== 'Abstract') { articles.push(await _trials.fetchAndLoadById(conn, sourceRecord.nct)); } else if (['FDA', 'Guideline'].includes(sourceRecord.source_type)) { - articles.push(await conn.addRecord({ - content: { + try { + const record = await conn.getUniqueRecordBy({ + filters: { AND: [{ source: rid(moaSource)}, { sourceId: sourceRecord.source_id }, {name: `${sourceRecord.source_type}-${sourceRecord.source_id}`}] }, + target: 'CuratedContent', + }); + articles.push(await conn.updateRecord('CuratedContent', record['@rid'], { citation: sourceRecord.citation, displayName: `${SOURCE_DEFN.displayName} ${sourceRecord.source_type}-${sourceRecord.source_id}`, - name: `${sourceRecord.source_type}-${sourceRecord.source_id}`, - source: rid(moaSource), - sourceId: sourceRecord.source_id, url: sourceRecord.url, - }, - existsOk: true, - target: 'CuratedContent', - })); + })); + } catch(err) { + articles.push(await conn.addRecord({ + content: { + citation: sourceRecord.citation, + displayName: `${SOURCE_DEFN.displayName} ${sourceRecord.source_type}-${sourceRecord.source_id}`, + name: `${sourceRecord.source_type}-${sourceRecord.source_id}`, + source: rid(moaSource), + sourceId: sourceRecord.source_id, + url: sourceRecord.url, + }, + existsOk: true, + target: 'CuratedContent', + })); + } } else { throw Error(`Unable to process evidence (${sourceRecord.source_type})`); } @@ -503,9 +521,9 @@ const parseRelevance = (moaRecord) => { relevance.push('no sensitivity'); } } - if (moaRecord.favorable_prognosis === true) { + if (moaRecord.favorable_prognosis === 1) { relevance.push('favourable prognosis'); - } else if (moaRecord.favorable_prognosis === false) { + } else if (moaRecord.favorable_prognosis === 0) { relevance.push('unfavourable prognosis'); } @@ -553,6 +571,10 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => try { logger.info(`loading: ${rawRecord.assertion_id} / ${records.length}`); const record = fixStringNulls(rawRecord); + // handle empty space in url + if (record.sources[0].url && record.sources[0].url.includes(' ')){ + record.sources[0].url = record.sources[0].url.replace(/\s/g,''); + } checkSpec(validateMoaRecord, record); const key = `${record.assertion_id}`; const lastUpdate = new Date(record.last_updated).getTime(); diff --git a/src/moa/spec.json b/src/moa/spec.json index dc5c5df3..7eb72f3b 100644 --- a/src/moa/spec.json +++ b/src/moa/spec.json @@ -36,10 +36,6 @@ ] }, "rearrangement_type": { - "enum": [ - "Translocation", - "Fusion" - ], "type": [ "string", "null" @@ -56,7 +52,7 @@ { "properties": { "alternate_allele": { - "pattern": "^[ATCG]*$", + "pattern": "^[ATCG-]*$", "type": [ "string", "null" @@ -173,7 +169,7 @@ }, "pathogenic": { "enum": [ - "1.0", + "1", null ] }, @@ -285,24 +281,16 @@ }, { "properties": { - "cosmic_signature_number": { - "pattern": "^\\d+$", + "cosmic_signature": { "type": "string" }, - "cosmic_signature_version": { - "enum": [ - "2.0", - "2" - ] - }, "feature_type": { "const": "mutational_signature" } }, "required": [ "feature_type", - "cosmic_signature_number", - "cosmic_signature_version" + "cosmic_signature" ], "type": "object" }, From 1814293a42d9da066f5b237b93da7eeb9348d9c3 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Wed, 25 Sep 2024 13:25:08 -0700 Subject: [PATCH 16/52] fix lint --- src/moa/index.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index b36a4c2d..06141b1a 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -260,22 +260,23 @@ const loadVariant = async (conn, moaVariant) => { filters: { AND: [ { source: { filters: { name: 'cosmic' }, target: 'Source' } }, - { sourceId: moaVariant.cosmic_signature}, + { sourceId: moaVariant.cosmic_signature }, ], }, target: 'Signature', }); const variantType = await conn.getVocabularyTerm('signature present'); - try{ - const record = await conn.getUniqueRecordBy({ - filters: { AND: [{ reference1: rid(signature[0])}, { type: rid(variantType) }] }, + + try { + const record = await conn.getUniqueRecordBy({ + filters: { AND: [{ reference1: rid(signature[0]) }, { type: rid(variantType) }] }, target: 'CategoryVariant', }); return await conn.updateRecord('CategoryVariant', record['@rid'], { - displayName: `${signature[0].name.toUpperCase()} signature present` + displayName: `${signature[0].name.toUpperCase()} signature present`, }); - } catch(err) { - return await conn.addVariant({ + } catch (err) { + return conn.addVariant({ content: { displayName: `${signature[0].name.toUpperCase()} signature present`, reference1: rid(signature[0]), @@ -370,7 +371,7 @@ const loadRecord = async (conn, moaRecord, moaSource, relevanceTerms) => { } else if (['FDA', 'Guideline'].includes(sourceRecord.source_type)) { try { const record = await conn.getUniqueRecordBy({ - filters: { AND: [{ source: rid(moaSource)}, { sourceId: sourceRecord.source_id }, {name: `${sourceRecord.source_type}-${sourceRecord.source_id}`}] }, + filters: { AND: [{ source: rid(moaSource) }, { sourceId: sourceRecord.source_id }, { name: `${sourceRecord.source_type}-${sourceRecord.source_id}` }] }, target: 'CuratedContent', }); articles.push(await conn.updateRecord('CuratedContent', record['@rid'], { @@ -378,7 +379,7 @@ const loadRecord = async (conn, moaRecord, moaSource, relevanceTerms) => { displayName: `${SOURCE_DEFN.displayName} ${sourceRecord.source_type}-${sourceRecord.source_id}`, url: sourceRecord.url, })); - } catch(err) { + } catch (err) { articles.push(await conn.addRecord({ content: { citation: sourceRecord.citation, @@ -571,9 +572,10 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => try { logger.info(`loading: ${rawRecord.assertion_id} / ${records.length}`); const record = fixStringNulls(rawRecord); + // handle empty space in url - if (record.sources[0].url && record.sources[0].url.includes(' ')){ - record.sources[0].url = record.sources[0].url.replace(/\s/g,''); + if (record.sources[0].url && record.sources[0].url.includes(' ')) { + record.sources[0].url = record.sources[0].url.replace(/\s/g, ''); } checkSpec(validateMoaRecord, record); const key = `${record.assertion_id}`; From 10b43797ba0f1cb0d79e64e8c1709e03344a99a8 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Wed, 25 Sep 2024 14:04:53 -0700 Subject: [PATCH 17/52] fix test --- test/moa.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/moa.test.js b/test/moa.test.js index fe5ae5cd..c4657271 100644 --- a/test/moa.test.js +++ b/test/moa.test.js @@ -77,14 +77,14 @@ describe('parseRelevance', () => { test('favorable prognosis', () => { expect(parseRelevance({ - favorable_prognosis: true, + favorable_prognosis: 1, features: [], })).toEqual(['favourable prognosis']); }); test('unfavorable prognosis', () => { expect(parseRelevance({ - favorable_prognosis: false, + favorable_prognosis: 0, features: [], })).toEqual(['unfavourable prognosis']); }); From 951f5f4f3c285fc354619d384c30613e4147264f Mon Sep 17 00:00:00 2001 From: sshugsc Date: Tue, 1 Oct 2024 14:14:05 -0700 Subject: [PATCH 18/52] update signature present to high signature --- src/moa/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/moa/index.js b/src/moa/index.js index 06141b1a..8c1543f5 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -265,7 +265,7 @@ const loadVariant = async (conn, moaVariant) => { }, target: 'Signature', }); - const variantType = await conn.getVocabularyTerm('signature present'); + const variantType = await conn.getVocabularyTerm('high signature'); try { const record = await conn.getUniqueRecordBy({ From 413827bc687ccae9f0871c2f1c60b24950414e72 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Tue, 8 Oct 2024 11:30:23 -0700 Subject: [PATCH 19/52] remove no longer maintained MOA reords --- src/moa/index.js | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 8c1543f5..a22c3cc4 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -544,6 +544,18 @@ const parseRelevance = (moaRecord) => { return relevance; }; +const removeRecords = async (conn, records) => { + if (records.length && records.length > 0) { + for (const record of records) { + try{ + await conn.deleteRecord('Statement', record['@rid']); + logger.info(`Removing Statement ${record['@rid']} that are out of date`); + } catch (err) { + logger.warn(`${err}`); + } + } + } +}; const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => { const source = await conn.addSource(SOURCE_DEFN); @@ -559,6 +571,12 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => const existing = {}; + const newIds = records.map(record => record.assertion_id); + let toRemove = existingRecords.filter( + record => !newIds.includes(parseInt(record.sourceId, 10)), + ); + await removeRecords(conn, toRemove); + for (const record of existingRecords) { const key = record.sourceId; @@ -573,41 +591,31 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => logger.info(`loading: ${rawRecord.assertion_id} / ${records.length}`); const record = fixStringNulls(rawRecord); + if (record.assertion_id === 258){ + logger.info(`loading: ${rawRecord.assertion_id}`); + } // handle empty space in url if (record.sources[0].url && record.sources[0].url.includes(' ')) { record.sources[0].url = record.sources[0].url.replace(/\s/g, ''); } checkSpec(validateMoaRecord, record); const key = `${record.assertion_id}`; - const lastUpdate = new Date(record.last_updated).getTime(); const relevance = parseRelevance(record); - // do we have the expected number of GraphKB records for this MOA assertion - if (existing[key] && existing[key].length === relevance.length) { - // check the last update date of the assertion against the timestamp in GraphKB - if (existing[key].every(r => lastUpdate <= r.updatedAt)) { - logger.debug('Skip. Current record exists and does not need updating'); - counts.skipped++; - continue; - } - } const updatedRecords = (await loadRecord(conn, record, source, relevance)).map(r => r['@rid']); if (existing[key]) { - const toRemove = existing[key].map(r => r['@rid']).filter(r => !updatedRecords.includes(r)); - - if (toRemove.length) { - logger.warn(`Removing ${toRemove.length} records that are out of date`); - - for (const recordId of toRemove) { - await conn.deleteRecord('Statement', recordId); - } - } + toRemove = existing[key].filter(r => !updatedRecords.includes(r['@rid'])); + await removeRecords(conn, toRemove); } counts.success++; } catch (err) { logger.warn(`${err}`); counts.error++; + toRemove = existingRecords.filter( + record => rawRecord.assertion_id === parseInt(record.sourceId, 10), + ); + await removeRecords(conn, toRemove); if (err.toString().includes('Cannot read property')) { throw err; From ae26ba9e41a463bea7df8e7cce4006ae19442ef1 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Tue, 8 Oct 2024 11:41:13 -0700 Subject: [PATCH 20/52] lint --- src/moa/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index a22c3cc4..a4332da0 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -547,7 +547,7 @@ const parseRelevance = (moaRecord) => { const removeRecords = async (conn, records) => { if (records.length && records.length > 0) { for (const record of records) { - try{ + try { await conn.deleteRecord('Statement', record['@rid']); logger.info(`Removing Statement ${record['@rid']} that are out of date`); } catch (err) { @@ -591,9 +591,6 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => logger.info(`loading: ${rawRecord.assertion_id} / ${records.length}`); const record = fixStringNulls(rawRecord); - if (record.assertion_id === 258){ - logger.info(`loading: ${rawRecord.assertion_id}`); - } // handle empty space in url if (record.sources[0].url && record.sources[0].url.includes(' ')) { record.sources[0].url = record.sources[0].url.replace(/\s/g, ''); From d54e5f1986c1cc38554cd28ba2af3ffca8852b6f Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 21 Oct 2024 11:48:32 -0700 Subject: [PATCH 21/52] remove SBS signatures v2 --- data/signatures.json | 446 ------------------------------------------- 1 file changed, 446 deletions(-) diff --git a/data/signatures.json b/data/signatures.json index 876afcd2..60620407 100644 --- a/data/signatures.json +++ b/data/signatures.json @@ -211,20 +211,6 @@ "sourceId": "ID9", "sourceIdVersion": "3" }, - "SBS1.2": { - "displayName": "SBS1.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS1.3" - } - ], - "name": "SBS1", - "source": "cosmic", - "sourceId": "SBS1", - "sourceIdVersion": "2" - }, "SBS1.3": { "description": "An endogenous mutational process initiated by spontaneous or enzymatic deamination of 5-methylcytosine to thymine which generates G:T mismatches in double stranded DNA Failure to detect and remove these mismatches prior to DNA replication results in fixation of the T substitution for C", "displayName": "SBS1.3", @@ -233,25 +219,6 @@ "sourceId": "SBS1", "sourceIdVersion": "3" }, - "SBS10.2": { - "displayName": "SBS10.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS10a.3" - }, - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS10b.3" - } - ], - "name": "SBS10", - "source": "cosmic", - "sourceId": "SBS10", - "sourceIdVersion": "2" - }, "SBS10a.3": { "description": "Polymerase epsilon exonuclease domain mutations", "displayName": "SBS10a.3", @@ -268,20 +235,6 @@ "sourceId": "SBS10b", "sourceIdVersion": "3" }, - "SBS11.2": { - "displayName": "SBS11.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS11.3" - } - ], - "name": "SBS11", - "source": "cosmic", - "sourceId": "SBS11", - "sourceIdVersion": "2" - }, "SBS11.3": { "description": "SBS11 exhibits a mutational pattern resembling that of alkylating agents Patient histories indicate an association between previous treatment with the alkylating agent temozolomide and SBS11 mutations", "displayName": "SBS11.3", @@ -290,20 +243,6 @@ "sourceId": "SBS11", "sourceIdVersion": "3" }, - "SBS12.2": { - "displayName": "SBS12.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS12.3" - } - ], - "name": "SBS12", - "source": "cosmic", - "sourceId": "SBS12", - "sourceIdVersion": "2" - }, "SBS12.3": { "displayName": "SBS12.3", "name": "SBS12", @@ -311,20 +250,6 @@ "sourceId": "SBS12", "sourceIdVersion": "3" }, - "SBS13.2": { - "displayName": "SBS13.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS13.3" - } - ], - "name": "SBS13", - "source": "cosmic", - "sourceId": "SBS13", - "sourceIdVersion": "2" - }, "SBS13.3": { "description": "Attributed to activity of the AID/APOBEC family of cytidine deaminases on the basis of similarities in the sequence context of cytosine mutations caused by APOBEC enzymes in experimental systems APOBEC3A is probably responsible for most mutations in human cancer, although APOBEC3B may also contribute (these differ in the sequence context two bases 5’ to the mutated cytosine, see 1536 mutation classification signature extraction) SBS13 mutations are likely generated by error prone polymerases (such as REV1) replicating across abasic sites generated by base excision repair removal of uracil", "displayName": "SBS13.3", @@ -333,20 +258,6 @@ "sourceId": "SBS13", "sourceIdVersion": "3" }, - "SBS14.2": { - "displayName": "SBS14.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS14.3" - } - ], - "name": "SBS14", - "source": "cosmic", - "sourceId": "SBS14", - "sourceIdVersion": "2" - }, "SBS14.3": { "description": "Concurrent polymerase epsilon mutation and defective DNA mismatch repair", "displayName": "SBS14.3", @@ -355,20 +266,6 @@ "sourceId": "SBS14", "sourceIdVersion": "3" }, - "SBS15.2": { - "displayName": "SBS15.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS15.3" - } - ], - "name": "SBS15", - "source": "cosmic", - "sourceId": "SBS15", - "sourceIdVersion": "2" - }, "SBS15.3": { "description": "Defective DNA mismatch repair", "displayName": "SBS15.3", @@ -377,20 +274,6 @@ "sourceId": "SBS15", "sourceIdVersion": "3" }, - "SBS16.2": { - "displayName": "SBS16.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS16.3" - } - ], - "name": "SBS16", - "source": "cosmic", - "sourceId": "SBS16", - "sourceIdVersion": "2" - }, "SBS16.3": { "displayName": "SBS16.3", "name": "SBS16", @@ -398,25 +281,6 @@ "sourceId": "SBS16", "sourceIdVersion": "3" }, - "SBS17.2": { - "displayName": "SBS17.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS17a.3" - }, - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS17b.3" - } - ], - "name": "SBS17", - "source": "cosmic", - "sourceId": "SBS17", - "sourceIdVersion": "2" - }, "SBS17a.3": { "displayName": "SBS17a.3", "name": "SBS17a", @@ -431,21 +295,6 @@ "sourceId": "SBS17b", "sourceIdVersion": "3" }, - "SBS18.2": { - "description": "Possibly damage by reactive oxygen species", - "displayName": "SBS18.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS18.3" - } - ], - "name": "SBS18", - "source": "cosmic", - "sourceId": "SBS18", - "sourceIdVersion": "2" - }, "SBS18.3": { "displayName": "SBS18.3", "name": "SBS18", @@ -453,20 +302,6 @@ "sourceId": "SBS18", "sourceIdVersion": "3" }, - "SBS19.2": { - "displayName": "SBS19.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS19.3" - } - ], - "name": "SBS19", - "source": "cosmic", - "sourceId": "SBS19", - "sourceIdVersion": "2" - }, "SBS19.3": { "displayName": "SBS19.3", "name": "SBS19", @@ -474,20 +309,6 @@ "sourceId": "SBS19", "sourceIdVersion": "3" }, - "SBS2.2": { - "displayName": "SBS2.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS2.3" - } - ], - "name": "SBS2", - "source": "cosmic", - "sourceId": "SBS2", - "sourceIdVersion": "2" - }, "SBS2.3": { "description": "Attributed to activity of the AID/APOBEC family of cytidine deaminases on the basis of similarities in the sequence context of cytosine mutations caused by APOBEC enzymes in experimental systems APOBEC3A is probably responsible for most mutations in human cancer, although APOBEC3B may also contribute (these differ in the sequence context two bases 5’ to the mutated cytosine, see 1,536 mutation classification signature extraction) SBS2 mutations may be generated directly by DNA replication across uracil or by error prone polymerases replicating across abasic sites generated by base excision repair removal of uracil", "displayName": "SBS2.3", @@ -496,20 +317,6 @@ "sourceId": "SBS2", "sourceIdVersion": "3" }, - "SBS20.2": { - "displayName": "SBS20.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS20.3" - } - ], - "name": "SBS20", - "source": "cosmic", - "sourceId": "SBS20", - "sourceIdVersion": "2" - }, "SBS20.3": { "description": "Concurrent POLD1 mutations and defective DNA mismatch repair", "displayName": "SBS20.3", @@ -518,20 +325,6 @@ "sourceId": "SBS20", "sourceIdVersion": "3" }, - "SBS21.2": { - "displayName": "SBS21.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS21.3" - } - ], - "name": "SBS21", - "source": "cosmic", - "sourceId": "SBS21", - "sourceIdVersion": "2" - }, "SBS21.3": { "description": "DNA mismatch repair deficiency", "displayName": "SBS21.3", @@ -540,20 +333,6 @@ "sourceId": "SBS21", "sourceIdVersion": "3" }, - "SBS22.2": { - "displayName": "SBS22.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS22.3" - } - ], - "name": "SBS22", - "source": "cosmic", - "sourceId": "SBS22", - "sourceIdVersion": "2" - }, "SBS22.3": { "description": "Aristolochic acid exposure Found in cancer samples with known exposures to aristolochic acid and the pattern of mutations exhibited by the signature is consistent with that observed in experimental systems of aristolochic acid exposure", "displayName": "SBS22.3", @@ -562,20 +341,6 @@ "sourceId": "SBS22", "sourceIdVersion": "3" }, - "SBS23.2": { - "displayName": "SBS23.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS23.3" - } - ], - "name": "SBS23", - "source": "cosmic", - "sourceId": "SBS23", - "sourceIdVersion": "2" - }, "SBS23.3": { "displayName": "SBS23.3", "name": "SBS23", @@ -583,20 +348,6 @@ "sourceId": "SBS23", "sourceIdVersion": "3" }, - "SBS24.2": { - "displayName": "SBS24.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS24.3" - } - ], - "name": "SBS24", - "source": "cosmic", - "sourceId": "SBS24", - "sourceIdVersion": "2" - }, "SBS24.3": { "description": "Aflatoxin exposure SBS24 has been found in cancer samples with known exposures to aflatoxin and the pattern of mutations exhibited by the signature is consistent with that observed in experimental systems exposed to aflatoxin", "displayName": "SBS24.3", @@ -605,20 +356,6 @@ "sourceId": "SBS24", "sourceIdVersion": "3" }, - "SBS25.2": { - "displayName": "SBS25.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS25.3" - } - ], - "name": "SBS25", - "source": "cosmic", - "sourceId": "SBS25", - "sourceIdVersion": "2" - }, "SBS25.3": { "description": "Unknown. However, some Hodgkin’s cell line samples in which the signature has been found were from patients exposed to chemotherapy and it is possible that SBS25 is due to chemotherapy treatment", "displayName": "SBS25.3", @@ -627,20 +364,6 @@ "sourceId": "SBS25", "sourceIdVersion": "3" }, - "SBS26.2": { - "displayName": "SBS26.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS26.3" - } - ], - "name": "SBS26", - "source": "cosmic", - "sourceId": "SBS26", - "sourceIdVersion": "2" - }, "SBS26.3": { "description": "Defective DNA mismatch repair", "displayName": "SBS26.3", @@ -649,20 +372,6 @@ "sourceId": "SBS26", "sourceIdVersion": "3" }, - "SBS27.2": { - "displayName": "SBS27.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS27.3" - } - ], - "name": "SBS27", - "source": "cosmic", - "sourceId": "SBS27", - "sourceIdVersion": "2" - }, "SBS27.3": { "description": "Possible sequencing artefact", "displayName": "SBS27.3", @@ -671,20 +380,6 @@ "sourceId": "SBS27", "sourceIdVersion": "3" }, - "SBS28.2": { - "displayName": "SBS28.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS28.3" - } - ], - "name": "SBS28", - "source": "cosmic", - "sourceId": "SBS28", - "sourceIdVersion": "2" - }, "SBS28.3": { "displayName": "SBS28.3", "name": "SBS28", @@ -692,20 +387,6 @@ "sourceId": "SBS28", "sourceIdVersion": "3" }, - "SBS29.2": { - "displayName": "SBS29.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS29.3" - } - ], - "name": "SBS29", - "source": "cosmic", - "sourceId": "SBS29", - "sourceIdVersion": "2" - }, "SBS29.3": { "description": "SBS29 has been found in cancer samples from individuals with a tobacco chewing habit", "displayName": "SBS29.3", @@ -714,20 +395,6 @@ "sourceId": "SBS29", "sourceIdVersion": "3" }, - "SBS3.2": { - "displayName": "SBS3.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS3.3" - } - ], - "name": "SBS3", - "source": "cosmic", - "sourceId": "SBS3", - "sourceIdVersion": "2" - }, "SBS3.3": { "description": "Defective homologous recombination-based DNA damage repair which manifests predominantly as small indels and genome rearrangements due to abnormal double strand break repair but also in the form of this base substitution signature", "displayName": "SBS3.3", @@ -736,20 +403,6 @@ "sourceId": "SBS3", "sourceIdVersion": "3" }, - "SBS30.2": { - "displayName": "SBS30.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS30.3" - } - ], - "name": "SBS30", - "source": "cosmic", - "sourceId": "SBS30", - "sourceIdVersion": "2" - }, "SBS30.3": { "description": "SBS30 is due to deficiency in base excision repair due to inactivating mutations in NTHL1", "displayName": "SBS30.3", @@ -826,20 +479,6 @@ "sourceId": "SBS39", "sourceIdVersion": "3" }, - "SBS4.2": { - "displayName": "SBS4.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS4.3" - } - ], - "name": "SBS4", - "source": "cosmic", - "sourceId": "SBS4", - "sourceIdVersion": "2" - }, "SBS4.3": { "description": "Associated with tobacco smoking Its profile is similar to the mutational spectrum observed in experimental systems exposed to tobacco carcinogens such as benzo[a]pyrene SBS4 is, therefore, likely due to direct DNA damage by tobacco smoke mutagens", "displayName": "SBS4.3", @@ -926,20 +565,6 @@ "sourceId": "SBS49", "sourceIdVersion": "3" }, - "SBS5.2": { - "displayName": "SBS5.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS5.3" - } - ], - "name": "SBS5", - "source": "cosmic", - "sourceId": "SBS5", - "sourceIdVersion": "2" - }, "SBS5.3": { "description": "Unknown. SBS5 mutational burden is increased in bladder cancer samples with ERCC2 mutations and in many cancer types due to tobacco smoking", "displayName": "SBS5.3", @@ -1028,20 +653,6 @@ "sourceId": "SBS59", "sourceIdVersion": "3" }, - "SBS6.2": { - "displayName": "SBS6.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS6.3" - } - ], - "name": "SBS6", - "source": "cosmic", - "sourceId": "SBS6", - "sourceIdVersion": "2" - }, "SBS6.3": { "description": "SBS6 is associated with defective DNA mismatch repair and is found in microsatellite unstable tumours", "displayName": "SBS6.3", @@ -1058,35 +669,6 @@ "sourceId": "SBS60", "sourceIdVersion": "3" }, - "SBS7.2": { - "displayName": "SBS7.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS7a.3" - }, - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS7b.3" - }, - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS7c.3" - }, - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS7d.3" - } - ], - "name": "SBS7", - "source": "cosmic", - "sourceId": "SBS7", - "sourceIdVersion": "2" - }, "SBS7a.3": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", "displayName": "SBS7a.3", @@ -1119,20 +701,6 @@ "sourceId": "SBS7d", "sourceIdVersion": "3" }, - "SBS8.2": { - "displayName": "SBS8.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS8.3" - } - ], - "name": "SBS8", - "source": "cosmic", - "sourceId": "SBS8", - "sourceIdVersion": "2" - }, "SBS8.3": { "displayName": "SBS8.3", "name": "SBS8", @@ -1156,20 +724,6 @@ "sourceId": "SBS85", "sourceIdVersion": "3" }, - "SBS9.2": { - "displayName": "SBS9.2", - "links": [ - { - "class": "DeprecatedBy", - "source": "cosmic", - "target": "SBS9.3" - } - ], - "name": "SBS9", - "source": "cosmic", - "sourceId": "SBS9", - "sourceIdVersion": "2" - }, "SBS9.3": { "description": "May be due in part to mutations induced during replication by polymerase eta as part of somatic hypermutation in lymphoid cells", "displayName": "SBS9.3", From f1c577c775d11f347690f2956cd9c35d74c86bf2 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Mon, 21 Oct 2024 12:04:20 -0700 Subject: [PATCH 22/52] remove checking for existing MOA records; add some work around for therapy name --- src/moa/index.js | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index a4332da0..2f4ac8c6 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -323,7 +323,7 @@ const loadRecord = async (conn, moaRecord, moaSource, relevanceTerms) => { }, target: 'Disease', }); - } else if (moaRecord.oncotree_term) { + } else if (moaRecord.oncotree_term & moaRecord.oncotree_term !== 'Any solid tumor') { disease = await conn.getUniqueRecordBy({ filters: { AND: [ @@ -334,6 +334,9 @@ const loadRecord = async (conn, moaRecord, moaSource, relevanceTerms) => { target: 'Disease', }); } else if (moaRecord.disease) { + if (moaRecord.disease === 'Any solid tumor') { + moaRecord.disease = 'all solid tumors'; + } disease = await conn.getUniqueRecordBy({ filters: { AND: [ @@ -563,28 +566,6 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => logger.info(`loaded ${records.length} assertions from MOA API`); const counts = { error: 0, skipped: 0, success: 0 }; - const existingRecords = await conn.getRecords({ - filters: { source: rid(source) }, - returnProperties: ['@rid', 'sourceId', 'updatedAt'], - target: 'Statement', - }); - - const existing = {}; - - const newIds = records.map(record => record.assertion_id); - let toRemove = existingRecords.filter( - record => !newIds.includes(parseInt(record.sourceId, 10)), - ); - await removeRecords(conn, toRemove); - - for (const record of existingRecords) { - const key = record.sourceId; - - if (existing[key] === undefined) { - existing[key] = []; - } - existing[key].push(record); - } for (const rawRecord of records) { try { @@ -595,24 +576,26 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => if (record.sources[0].url && record.sources[0].url.includes(' ')) { record.sources[0].url = record.sources[0].url.replace(/\s/g, ''); } + // work around to match with gkb records + if (record.therapy_name) { + if (record.therapy_name.includes("Amivantamab-vmjw")) { + record.therapy_name = record.therapy_name.replace("Amivantamab-vmjw","amivantamab"); + } else if (record.therapy_name === "KU0058684") { + record.therapy_name = "olaparib"; + } else if (record.therapy_name === "Tovorafenib") { + record.therapy_name = "pan-raf kinase inhibitor tak-580"; + } + } checkSpec(validateMoaRecord, record); const key = `${record.assertion_id}`; const relevance = parseRelevance(record); const updatedRecords = (await loadRecord(conn, record, source, relevance)).map(r => r['@rid']); - if (existing[key]) { - toRemove = existing[key].filter(r => !updatedRecords.includes(r['@rid'])); - await removeRecords(conn, toRemove); - } counts.success++; } catch (err) { logger.warn(`${err}`); counts.error++; - toRemove = existingRecords.filter( - record => rawRecord.assertion_id === parseInt(record.sourceId, 10), - ); - await removeRecords(conn, toRemove); if (err.toString().includes('Cannot read property')) { throw err; From 2f67d58d6261bd3486d44eb70136ff2f66ae1cae Mon Sep 17 00:00:00 2001 From: sshugsc Date: Mon, 21 Oct 2024 12:14:10 -0700 Subject: [PATCH 23/52] lint --- src/moa/index.js | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 2f4ac8c6..9d1d6cf0 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -547,19 +547,6 @@ const parseRelevance = (moaRecord) => { return relevance; }; -const removeRecords = async (conn, records) => { - if (records.length && records.length > 0) { - for (const record of records) { - try { - await conn.deleteRecord('Statement', record['@rid']); - logger.info(`Removing Statement ${record['@rid']} that are out of date`); - } catch (err) { - logger.warn(`${err}`); - } - } - } -}; - const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => { const source = await conn.addSource(SOURCE_DEFN); const records = await requestWithRetry({ json: true, method: 'GET', uri: url }); @@ -578,19 +565,18 @@ const upload = async ({ conn, url = 'https://moalmanac.org/api/assertions' }) => } // work around to match with gkb records if (record.therapy_name) { - if (record.therapy_name.includes("Amivantamab-vmjw")) { - record.therapy_name = record.therapy_name.replace("Amivantamab-vmjw","amivantamab"); - } else if (record.therapy_name === "KU0058684") { - record.therapy_name = "olaparib"; - } else if (record.therapy_name === "Tovorafenib") { - record.therapy_name = "pan-raf kinase inhibitor tak-580"; + if (record.therapy_name.includes('Amivantamab-vmjw')) { + record.therapy_name = record.therapy_name.replace('Amivantamab-vmjw', 'amivantamab'); + } else if (record.therapy_name === 'KU0058684') { + record.therapy_name = 'olaparib'; + } else if (record.therapy_name === 'Tovorafenib') { + record.therapy_name = 'pan-raf kinase inhibitor tak-580'; } } checkSpec(validateMoaRecord, record); - const key = `${record.assertion_id}`; const relevance = parseRelevance(record); - const updatedRecords = (await loadRecord(conn, record, source, relevance)).map(r => r['@rid']); + await loadRecord(conn, record, source, relevance); counts.success++; } catch (err) { From 1b49f9935ced595b441ef639d895d1890f10b3e4 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 21 Oct 2024 12:56:36 -0700 Subject: [PATCH 24/52] remove versioning in cosmic signatures --- data/signatures.json | 665 +++++++++++++++++++------------------------ 1 file changed, 285 insertions(+), 380 deletions(-) diff --git a/data/signatures.json b/data/signatures.json index 60620407..dae5895e 100644 --- a/data/signatures.json +++ b/data/signatures.json @@ -1,736 +1,641 @@ { "class": "Signature", "records": { - "DBS1.3": { + "DBS1": { "description": "Exposure to ultraviolet light", - "displayName": "DBS1.3", + "displayName": "DBS1", "name": "DBS1", "source": "cosmic", - "sourceId": "DBS1", - "sourceIdVersion": "3" + "sourceId": "DBS1" }, - "DBS10.3": { + "DBS10": { "description": "Defective DNA mismatch repair", - "displayName": "DBS10.3", + "displayName": "DBS10", "name": "DBS10", "source": "cosmic", - "sourceId": "DBS10", - "sourceIdVersion": "3" + "sourceId": "DBS10" }, - "DBS11.3": { + "DBS11": { "description": "Unknown. Possibly related to APOBEC mutagenesis", - "displayName": "DBS11.3", + "displayName": "DBS11", "name": "DBS11", "source": "cosmic", - "sourceId": "DBS11", - "sourceIdVersion": "3" + "sourceId": "DBS11" }, - "DBS2.3": { + "DBS2": { "description": "Exposure to tobacco smoking as well as other endogenous and/or exogenous mutagens (eg, acetaldehyde)", - "displayName": "DBS2.3", + "displayName": "DBS2", "name": "DBS2", "source": "cosmic", - "sourceId": "DBS2", - "sourceIdVersion": "3" + "sourceId": "DBS2" }, - "DBS3.3": { + "DBS3": { "description": "Polymerase epsilon exonuclease domain mutations", - "displayName": "DBS3.3", + "displayName": "DBS3", "name": "DBS3", "source": "cosmic", - "sourceId": "DBS3", - "sourceIdVersion": "3" + "sourceId": "DBS3" }, - "DBS4.3": { - "displayName": "DBS4.3", + "DBS4": { + "displayName": "DBS4", "name": "DBS4", "source": "cosmic", - "sourceId": "DBS4", - "sourceIdVersion": "3" + "sourceId": "DBS4" }, - "DBS5.3": { + "DBS5": { "description": "Prior chemotherapy treatment with platinum drugs", - "displayName": "DBS5.3", + "displayName": "DBS5", "name": "DBS5", "source": "cosmic", - "sourceId": "DBS5", - "sourceIdVersion": "3" + "sourceId": "DBS5" }, - "DBS6.3": { - "displayName": "DBS6.3", + "DBS6": { + "displayName": "DBS6", "name": "DBS6", "source": "cosmic", - "sourceId": "DBS6", - "sourceIdVersion": "3" + "sourceId": "DBS6" }, - "DBS7.3": { + "DBS7": { "description": "Defective DNA mismatch repair", - "displayName": "DBS7.3", + "displayName": "DBS7", "name": "DBS7", "source": "cosmic", - "sourceId": "DBS7", - "sourceIdVersion": "3" + "sourceId": "DBS7" }, - "DBS8.3": { - "displayName": "DBS8.3", + "DBS8": { + "displayName": "DBS8", "name": "DBS8", "source": "cosmic", - "sourceId": "DBS8", - "sourceIdVersion": "3" + "sourceId": "DBS8" }, - "DBS9.3": { - "displayName": "DBS9.3", + "DBS9": { + "displayName": "DBS9", "name": "DBS9", "source": "cosmic", - "sourceId": "DBS9", - "sourceIdVersion": "3" + "sourceId": "DBS9" }, - "ID1.3": { + "ID1": { "description": "Slippage during DNA replication of the replicated DNA strand This signature is found in almost all samples, however, substantial number of mutations of this signature in cancers with DNA mismatch repair deficiency", - "displayName": "ID1.3", + "displayName": "ID1", "name": "ID1", "source": "cosmic", - "sourceId": "ID1", - "sourceIdVersion": "3" + "sourceId": "ID1" }, - "ID10.3": { - "displayName": "ID10.3", + "ID10": { + "displayName": "ID10", "name": "ID10", "source": "cosmic", - "sourceId": "ID10", - "sourceIdVersion": "3" + "sourceId": "ID10" }, - "ID11.3": { - "displayName": "ID11.3", + "ID11": { + "displayName": "ID11", "name": "ID11", "source": "cosmic", - "sourceId": "ID11", - "sourceIdVersion": "3" + "sourceId": "ID11" }, - "ID12.3": { - "displayName": "ID12.3", + "ID12": { + "displayName": "ID12", "name": "ID12", "source": "cosmic", - "sourceId": "ID12", - "sourceIdVersion": "3" + "sourceId": "ID12" }, - "ID13.3": { + "ID13": { "description": "ID13 is found in cancers of the skin from sun exposed areas, therefore, this signature is likely to be due to exposure to ultraviolet light", - "displayName": "ID13.3", + "displayName": "ID13", "name": "ID13", "source": "cosmic", - "sourceId": "ID13", - "sourceIdVersion": "3" + "sourceId": "ID13" }, - "ID14.3": { - "displayName": "ID14.3", + "ID14": { + "displayName": "ID14", "name": "ID14", "source": "cosmic", - "sourceId": "ID14", - "sourceIdVersion": "3" + "sourceId": "ID14" }, - "ID15.3": { - "displayName": "ID15.3", + "ID15": { + "displayName": "ID15", "name": "ID15", "source": "cosmic", - "sourceId": "ID15", - "sourceIdVersion": "3" + "sourceId": "ID15" }, - "ID16.3": { - "displayName": "ID16.3", + "ID16": { + "displayName": "ID16", "name": "ID16", "source": "cosmic", - "sourceId": "ID16", - "sourceIdVersion": "3" + "sourceId": "ID16" }, - "ID17.3": { - "displayName": "ID17.3", + "ID17": { + "displayName": "ID17", "name": "ID17", "source": "cosmic", - "sourceId": "ID17", - "sourceIdVersion": "3" + "sourceId": "ID17" }, - "ID2.3": { + "ID2": { "description": "Slippage during DNA replication of the template DNA strand This signature is found in almost all samples, however, substantial number of mutations of this signature in cancers with DNA mismatch repair deficiency", - "displayName": "ID2.3", + "displayName": "ID2", "name": "ID2", "source": "cosmic", - "sourceId": "ID2", - "sourceIdVersion": "3" + "sourceId": "ID2" }, - "ID3.3": { + "ID3": { "description": "Associated with tobacco smoking", - "displayName": "ID3.3", + "displayName": "ID3", "name": "ID3", "source": "cosmic", - "sourceId": "ID3", - "sourceIdVersion": "3" + "sourceId": "ID3" }, - "ID4.3": { - "displayName": "ID4.3", + "ID4": { + "displayName": "ID4", "name": "ID4", "source": "cosmic", - "sourceId": "ID4", - "sourceIdVersion": "3" + "sourceId": "ID4" }, - "ID5.3": { - "displayName": "ID5.3", + "ID5": { + "displayName": "ID5", "name": "ID5", "source": "cosmic", - "sourceId": "ID5", - "sourceIdVersion": "3" + "sourceId": "ID5" }, - "ID6.3": { + "ID6": { "description": "Defective homologous recombination-based DNA damage repair, often due to inactivating BRCA1 or BRCA2 mutations, leading to non-homologous DNA end-joining activity", - "displayName": "ID6.3", + "displayName": "ID6", "name": "ID6", "source": "cosmic", - "sourceId": "ID6", - "sourceIdVersion": "3" + "sourceId": "ID6" }, - "ID7.3": { + "ID7": { "description": "Defective DNA mismatch repair", - "displayName": "ID7.3", + "displayName": "ID7", "name": "ID7", "source": "cosmic", - "sourceId": "ID7", - "sourceIdVersion": "3" + "sourceId": "ID7" }, - "ID8.3": { + "ID8": { "description": "Unknown. Repair of DNA double strand breaks by non-homologous DNA end-joining mechanisms The DSB could, in principle, be radiation induced and the features of ID8 mutations have some similarities to those of radiation induced mutations", - "displayName": "ID8.3", + "displayName": "ID8", "name": "ID8", "source": "cosmic", - "sourceId": "ID8", - "sourceIdVersion": "3" + "sourceId": "ID8" }, - "ID9.3": { - "displayName": "ID9.3", + "ID9": { + "displayName": "ID9", "name": "ID9", "source": "cosmic", - "sourceId": "ID9", - "sourceIdVersion": "3" + "sourceId": "ID9" }, - "SBS1.3": { + "SBS1": { "description": "An endogenous mutational process initiated by spontaneous or enzymatic deamination of 5-methylcytosine to thymine which generates G:T mismatches in double stranded DNA Failure to detect and remove these mismatches prior to DNA replication results in fixation of the T substitution for C", - "displayName": "SBS1.3", + "displayName": "SBS1", "name": "SBS1", "source": "cosmic", - "sourceId": "SBS1", - "sourceIdVersion": "3" + "sourceId": "SBS1" }, - "SBS10a.3": { + "SBS10a": { "description": "Polymerase epsilon exonuclease domain mutations", - "displayName": "SBS10a.3", + "displayName": "SBS10a", "name": "SBS10a", "source": "cosmic", - "sourceId": "SBS10a", - "sourceIdVersion": "3" + "sourceId": "SBS10a" }, - "SBS10b.3": { + "SBS10b": { "description": "Polymerase epsilon exonuclease domain mutations", - "displayName": "SBS10b.3", + "displayName": "SBS10b", "name": "SBS10b", "source": "cosmic", - "sourceId": "SBS10b", - "sourceIdVersion": "3" + "sourceId": "SBS10b" }, - "SBS11.3": { + "SBS11": { "description": "SBS11 exhibits a mutational pattern resembling that of alkylating agents Patient histories indicate an association between previous treatment with the alkylating agent temozolomide and SBS11 mutations", - "displayName": "SBS11.3", + "displayName": "SBS11", "name": "SBS11", "source": "cosmic", - "sourceId": "SBS11", - "sourceIdVersion": "3" + "sourceId": "SBS11" }, - "SBS12.3": { - "displayName": "SBS12.3", + "SBS12": { + "displayName": "SBS12", "name": "SBS12", "source": "cosmic", - "sourceId": "SBS12", - "sourceIdVersion": "3" + "sourceId": "SBS12" }, - "SBS13.3": { + "SBS13": { "description": "Attributed to activity of the AID/APOBEC family of cytidine deaminases on the basis of similarities in the sequence context of cytosine mutations caused by APOBEC enzymes in experimental systems APOBEC3A is probably responsible for most mutations in human cancer, although APOBEC3B may also contribute (these differ in the sequence context two bases 5’ to the mutated cytosine, see 1536 mutation classification signature extraction) SBS13 mutations are likely generated by error prone polymerases (such as REV1) replicating across abasic sites generated by base excision repair removal of uracil", - "displayName": "SBS13.3", + "displayName": "SBS13", "name": "SBS13", "source": "cosmic", - "sourceId": "SBS13", - "sourceIdVersion": "3" + "sourceId": "SBS13" }, - "SBS14.3": { + "SBS14": { "description": "Concurrent polymerase epsilon mutation and defective DNA mismatch repair", - "displayName": "SBS14.3", + "displayName": "SBS14", "name": "SBS14", "source": "cosmic", - "sourceId": "SBS14", - "sourceIdVersion": "3" + "sourceId": "SBS14" }, - "SBS15.3": { + "SBS15": { "description": "Defective DNA mismatch repair", - "displayName": "SBS15.3", + "displayName": "SBS15", "name": "SBS15", "source": "cosmic", - "sourceId": "SBS15", - "sourceIdVersion": "3" + "sourceId": "SBS15" }, - "SBS16.3": { - "displayName": "SBS16.3", + "SBS16": { + "displayName": "SBS16", "name": "SBS16", "source": "cosmic", - "sourceId": "SBS16", - "sourceIdVersion": "3" + "sourceId": "SBS16" }, - "SBS17a.3": { - "displayName": "SBS17a.3", + "SBS17a": { + "displayName": "SBS17a", "name": "SBS17a", "source": "cosmic", - "sourceId": "SBS17a", - "sourceIdVersion": "3" + "sourceId": "SBS17a" }, - "SBS17b.3": { - "displayName": "SBS17b.3", + "SBS17b": { + "displayName": "SBS17b", "name": "SBS17b", "source": "cosmic", - "sourceId": "SBS17b", - "sourceIdVersion": "3" + "sourceId": "SBS17b" }, - "SBS18.3": { - "displayName": "SBS18.3", + "SBS18": { + "displayName": "SBS18", "name": "SBS18", "source": "cosmic", - "sourceId": "SBS18", - "sourceIdVersion": "3" + "sourceId": "SBS18" }, - "SBS19.3": { - "displayName": "SBS19.3", + "SBS19": { + "displayName": "SBS19", "name": "SBS19", "source": "cosmic", - "sourceId": "SBS19", - "sourceIdVersion": "3" + "sourceId": "SBS19" }, - "SBS2.3": { + "SBS2": { "description": "Attributed to activity of the AID/APOBEC family of cytidine deaminases on the basis of similarities in the sequence context of cytosine mutations caused by APOBEC enzymes in experimental systems APOBEC3A is probably responsible for most mutations in human cancer, although APOBEC3B may also contribute (these differ in the sequence context two bases 5’ to the mutated cytosine, see 1,536 mutation classification signature extraction) SBS2 mutations may be generated directly by DNA replication across uracil or by error prone polymerases replicating across abasic sites generated by base excision repair removal of uracil", - "displayName": "SBS2.3", + "displayName": "SBS2", "name": "SBS2", "source": "cosmic", - "sourceId": "SBS2", - "sourceIdVersion": "3" + "sourceId": "SBS2" }, - "SBS20.3": { + "SBS20": { "description": "Concurrent POLD1 mutations and defective DNA mismatch repair", - "displayName": "SBS20.3", + "displayName": "SBS20", "name": "SBS20", "source": "cosmic", - "sourceId": "SBS20", - "sourceIdVersion": "3" + "sourceId": "SBS20" }, - "SBS21.3": { + "SBS21": { "description": "DNA mismatch repair deficiency", - "displayName": "SBS21.3", + "displayName": "SBS21", "name": "SBS21", "source": "cosmic", - "sourceId": "SBS21", - "sourceIdVersion": "3" + "sourceId": "SBS21" }, - "SBS22.3": { + "SBS22": { "description": "Aristolochic acid exposure Found in cancer samples with known exposures to aristolochic acid and the pattern of mutations exhibited by the signature is consistent with that observed in experimental systems of aristolochic acid exposure", - "displayName": "SBS22.3", + "displayName": "SBS22", "name": "SBS22", "source": "cosmic", - "sourceId": "SBS22", - "sourceIdVersion": "3" + "sourceId": "SBS22" }, - "SBS23.3": { - "displayName": "SBS23.3", + "SBS23": { + "displayName": "SBS23", "name": "SBS23", "source": "cosmic", - "sourceId": "SBS23", - "sourceIdVersion": "3" + "sourceId": "SBS23" }, - "SBS24.3": { + "SBS24": { "description": "Aflatoxin exposure SBS24 has been found in cancer samples with known exposures to aflatoxin and the pattern of mutations exhibited by the signature is consistent with that observed in experimental systems exposed to aflatoxin", - "displayName": "SBS24.3", + "displayName": "SBS24", "name": "SBS24", "source": "cosmic", - "sourceId": "SBS24", - "sourceIdVersion": "3" + "sourceId": "SBS24" }, - "SBS25.3": { + "SBS25": { "description": "Unknown. However, some Hodgkin’s cell line samples in which the signature has been found were from patients exposed to chemotherapy and it is possible that SBS25 is due to chemotherapy treatment", - "displayName": "SBS25.3", + "displayName": "SBS25", "name": "SBS25", "source": "cosmic", - "sourceId": "SBS25", - "sourceIdVersion": "3" + "sourceId": "SBS25" }, - "SBS26.3": { + "SBS26": { "description": "Defective DNA mismatch repair", - "displayName": "SBS26.3", + "displayName": "SBS26", "name": "SBS26", "source": "cosmic", - "sourceId": "SBS26", - "sourceIdVersion": "3" + "sourceId": "SBS26" }, - "SBS27.3": { + "SBS27": { "description": "Possible sequencing artefact", - "displayName": "SBS27.3", + "displayName": "SBS27", "name": "SBS27", "source": "cosmic", - "sourceId": "SBS27", - "sourceIdVersion": "3" + "sourceId": "SBS27" }, - "SBS28.3": { - "displayName": "SBS28.3", + "SBS28": { + "displayName": "SBS28", "name": "SBS28", "source": "cosmic", - "sourceId": "SBS28", - "sourceIdVersion": "3" + "sourceId": "SBS28" }, - "SBS29.3": { + "SBS29": { "description": "SBS29 has been found in cancer samples from individuals with a tobacco chewing habit", - "displayName": "SBS29.3", + "displayName": "SBS29", "name": "SBS29", "source": "cosmic", - "sourceId": "SBS29", - "sourceIdVersion": "3" + "sourceId": "SBS29" }, - "SBS3.3": { + "SBS3": { "description": "Defective homologous recombination-based DNA damage repair which manifests predominantly as small indels and genome rearrangements due to abnormal double strand break repair but also in the form of this base substitution signature", - "displayName": "SBS3.3", + "displayName": "SBS3", "name": "SBS3", "source": "cosmic", - "sourceId": "SBS3", - "sourceIdVersion": "3" + "sourceId": "SBS3" }, - "SBS30.3": { + "SBS30": { "description": "SBS30 is due to deficiency in base excision repair due to inactivating mutations in NTHL1", - "displayName": "SBS30.3", + "displayName": "SBS30", "name": "SBS30", "source": "cosmic", - "sourceId": "SBS30", - "sourceIdVersion": "3" + "sourceId": "SBS30" }, - "SBS31.3": { + "SBS31": { "description": "Prior chemotherapy treatment with platinum drugs", - "displayName": "SBS31.3", + "displayName": "SBS31", "name": "SBS31", "source": "cosmic", - "sourceId": "SBS31", - "sourceIdVersion": "3" + "sourceId": "SBS31" }, - "SBS32.3": { + "SBS32": { "description": "Prior treatment with azathioprine to induce immunosuppression Associated mutation classes and signatures", - "displayName": "SBS32.3", + "displayName": "SBS32", "name": "SBS32", "source": "cosmic", - "sourceId": "SBS32", - "sourceIdVersion": "3" + "sourceId": "SBS32" }, - "SBS33.3": { - "displayName": "SBS33.3", + "SBS33": { + "displayName": "SBS33", "name": "SBS33", "source": "cosmic", - "sourceId": "SBS33", - "sourceIdVersion": "3" + "sourceId": "SBS33" }, - "SBS34.3": { - "displayName": "SBS34.3", + "SBS34": { + "displayName": "SBS34", "name": "SBS34", "source": "cosmic", - "sourceId": "SBS34", - "sourceIdVersion": "3" + "sourceId": "SBS34" }, - "SBS35.3": { + "SBS35": { "description": "Prior chemotherapy treatment with platinum drugs", - "displayName": "SBS35.3", + "displayName": "SBS35", "name": "SBS35", "source": "cosmic", - "sourceId": "SBS35", - "sourceIdVersion": "3" + "sourceId": "SBS35" }, - "SBS36.3": { + "SBS36": { "description": "Defective base excision repair, including DNA damage due to reactive oxygen species, due to biallelic germline or somatic MUTYH mutations", - "displayName": "SBS36.3", + "displayName": "SBS36", "name": "SBS36", "source": "cosmic", - "sourceId": "SBS36", - "sourceIdVersion": "3" + "sourceId": "SBS36" }, - "SBS37.3": { - "displayName": "SBS37.3", + "SBS37": { + "displayName": "SBS37", "name": "SBS37", "source": "cosmic", - "sourceId": "SBS37", - "sourceIdVersion": "3" + "sourceId": "SBS37" }, - "SBS38.3": { + "SBS38": { "description": "Unknown. Found only in ultraviolet light associated melanomas suggesting potential indirect damage from UV-light", - "displayName": "SBS38.3", + "displayName": "SBS38", "name": "SBS38", "source": "cosmic", - "sourceId": "SBS38", - "sourceIdVersion": "3" + "sourceId": "SBS38" }, - "SBS39.3": { - "displayName": "SBS39.3", + "SBS39": { + "displayName": "SBS39", "name": "SBS39", "source": "cosmic", - "sourceId": "SBS39", - "sourceIdVersion": "3" + "sourceId": "SBS39" }, - "SBS4.3": { + "SBS4": { "description": "Associated with tobacco smoking Its profile is similar to the mutational spectrum observed in experimental systems exposed to tobacco carcinogens such as benzo[a]pyrene SBS4 is, therefore, likely due to direct DNA damage by tobacco smoke mutagens", - "displayName": "SBS4.3", + "displayName": "SBS4", "name": "SBS4", "source": "cosmic", - "sourceId": "SBS4", - "sourceIdVersion": "3" + "sourceId": "SBS4" }, - "SBS40.3": { - "displayName": "SBS40.3", + "SBS40": { + "displayName": "SBS40", "name": "SBS40", "source": "cosmic", - "sourceId": "SBS40", - "sourceIdVersion": "3" + "sourceId": "SBS40" }, - "SBS41.3": { - "displayName": "SBS41.3", + "SBS41": { + "displayName": "SBS41", "name": "SBS41", "source": "cosmic", - "sourceId": "SBS41", - "sourceIdVersion": "3" + "sourceId": "SBS41" }, - "SBS42.3": { + "SBS42": { "description": "Occupational exposure to haloalkanes", - "displayName": "SBS42.3", + "displayName": "SBS42", "name": "SBS42", "source": "cosmic", - "sourceId": "SBS42", - "sourceIdVersion": "3" + "sourceId": "SBS42" }, - "SBS43.3": { + "SBS43": { "description": "Unknown. Possible sequencing artefact", - "displayName": "SBS43.3", + "displayName": "SBS43", "name": "SBS43", "source": "cosmic", - "sourceId": "SBS43", - "sourceIdVersion": "3" + "sourceId": "SBS43" }, - "SBS44.3": { + "SBS44": { "description": "Defective DNA mismatch repair", - "displayName": "SBS44.3", + "displayName": "SBS44", "name": "SBS44", "source": "cosmic", - "sourceId": "SBS44", - "sourceIdVersion": "3" + "sourceId": "SBS44" }, - "SBS45.3": { + "SBS45": { "description": "Possible artefact due to 8-oxo-guanine introduced during sequencing", - "displayName": "SBS45.3", + "displayName": "SBS45", "name": "SBS45", "source": "cosmic", - "sourceId": "SBS45", - "sourceIdVersion": "3" + "sourceId": "SBS45" }, - "SBS46.3": { + "SBS46": { "description": "Possible sequencing artefact", - "displayName": "SBS46.3", + "displayName": "SBS46", "name": "SBS46", "source": "cosmic", - "sourceId": "SBS46", - "sourceIdVersion": "3" + "sourceId": "SBS46" }, - "SBS47.3": { + "SBS47": { "description": "Possible sequencing artefact", - "displayName": "SBS47.3", + "displayName": "SBS47", "name": "SBS47", "source": "cosmic", - "sourceId": "SBS47", - "sourceIdVersion": "3" + "sourceId": "SBS47" }, - "SBS48.3": { + "SBS48": { "description": "Possible sequencing artefact", - "displayName": "SBS48.3", + "displayName": "SBS48", "name": "SBS48", "source": "cosmic", - "sourceId": "SBS48", - "sourceIdVersion": "3" + "sourceId": "SBS48" }, - "SBS49.3": { + "SBS49": { "description": "Possible sequencing artefact", - "displayName": "SBS49.3", + "displayName": "SBS49", "name": "SBS49", "source": "cosmic", - "sourceId": "SBS49", - "sourceIdVersion": "3" + "sourceId": "SBS49" }, - "SBS5.3": { + "SBS5": { "description": "Unknown. SBS5 mutational burden is increased in bladder cancer samples with ERCC2 mutations and in many cancer types due to tobacco smoking", - "displayName": "SBS5.3", + "displayName": "SBS5", "name": "SBS5", "source": "cosmic", - "sourceId": "SBS5", - "sourceIdVersion": "3" + "sourceId": "SBS5" }, - "SBS50.3": { + "SBS50": { "description": "Possible sequencing artefact", - "displayName": "SBS50.3", + "displayName": "SBS50", "name": "SBS50", "source": "cosmic", - "sourceId": "SBS50", - "sourceIdVersion": "3" + "sourceId": "SBS50" }, - "SBS51.3": { + "SBS51": { "description": "Possible sequencing artefact", - "displayName": "SBS51.3", + "displayName": "SBS51", "name": "SBS51", "source": "cosmic", - "sourceId": "SBS51", - "sourceIdVersion": "3" + "sourceId": "SBS51" }, - "SBS52.3": { + "SBS52": { "description": "Possible sequencing artefact", - "displayName": "SBS52.3", + "displayName": "SBS52", "name": "SBS52", "source": "cosmic", - "sourceId": "SBS52", - "sourceIdVersion": "3" + "sourceId": "SBS52" }, - "SBS53.3": { + "SBS53": { "description": "Possible sequencing artefact", - "displayName": "SBS53.3", + "displayName": "SBS53", "name": "SBS53", "source": "cosmic", - "sourceId": "SBS53", - "sourceIdVersion": "3" + "sourceId": "SBS53" }, - "SBS54.3": { + "SBS54": { "description": "Possible sequencing artefact Possible contamination with germline variants", - "displayName": "SBS54.3", + "displayName": "SBS54", "name": "SBS54", "source": "cosmic", - "sourceId": "SBS54", - "sourceIdVersion": "3" + "sourceId": "SBS54" }, - "SBS55.3": { + "SBS55": { "description": "Possible sequencing artefact", - "displayName": "SBS55.3", + "displayName": "SBS55", "name": "SBS55", "source": "cosmic", - "sourceId": "SBS55", - "sourceIdVersion": "3" + "sourceId": "SBS55" }, - "SBS56.3": { + "SBS56": { "description": "Possible sequencing artefact", - "displayName": "SBS56.3", + "displayName": "SBS56", "name": "SBS56", "source": "cosmic", - "sourceId": "SBS56", - "sourceIdVersion": "3" + "sourceId": "SBS56" }, - "SBS57.3": { + "SBS57": { "description": "Possible sequencing artefact", - "displayName": "SBS57.3", + "displayName": "SBS57", "name": "SBS57", "source": "cosmic", - "sourceId": "SBS57", - "sourceIdVersion": "3" + "sourceId": "SBS57" }, - "SBS58.3": { + "SBS58": { "description": "Possible sequencing artefact", - "displayName": "SBS58.3", + "displayName": "SBS58", "name": "SBS58", "source": "cosmic", - "sourceId": "SBS58", - "sourceIdVersion": "3" + "sourceId": "SBS58" }, - "SBS59.3": { + "SBS59": { "description": "Possible sequencing artefact", - "displayName": "SBS59.3", + "displayName": "SBS59", "name": "SBS59", "source": "cosmic", - "sourceId": "SBS59", - "sourceIdVersion": "3" + "sourceId": "SBS59" }, - "SBS6.3": { + "SBS6": { "description": "SBS6 is associated with defective DNA mismatch repair and is found in microsatellite unstable tumours", - "displayName": "SBS6.3", + "displayName": "SBS6", "name": "SBS6", "source": "cosmic", - "sourceId": "SBS6", - "sourceIdVersion": "3" + "sourceId": "SBS6" }, - "SBS60.3": { + "SBS60": { "description": "Possible sequencing artefact", - "displayName": "SBS60.3", + "displayName": "SBS60", "name": "SBS60", "source": "cosmic", - "sourceId": "SBS60", - "sourceIdVersion": "3" + "sourceId": "SBS60" }, - "SBS7a.3": { + "SBS7a": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", - "displayName": "SBS7a.3", + "displayName": "SBS7a", "name": "SBS7a", "source": "cosmic", - "sourceId": "SBS7a", - "sourceIdVersion": "3" + "sourceId": "SBS7a" }, - "SBS7b.3": { + "SBS7b": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", - "displayName": "SBS7b.3", + "displayName": "SBS7b", "name": "SBS7b", "source": "cosmic", - "sourceId": "SBS7b", - "sourceIdVersion": "3" + "sourceId": "SBS7b" }, - "SBS7c.3": { + "SBS7c": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", - "displayName": "SBS7c.3", + "displayName": "SBS7c", "name": "SBS7c", "source": "cosmic", - "sourceId": "SBS7c", - "sourceIdVersion": "3" + "sourceId": "SBS7c" }, - "SBS7d.3": { + "SBS7d": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", - "displayName": "SBS7d.3", + "displayName": "SBS7d", "name": "SBS7d", "source": "cosmic", - "sourceId": "SBS7d", - "sourceIdVersion": "3" + "sourceId": "SBS7d" }, - "SBS8.3": { - "displayName": "SBS8.3", + "SBS8": { + "displayName": "SBS8", "name": "SBS8", "source": "cosmic", - "sourceId": "SBS8", - "sourceIdVersion": "3" + "sourceId": "SBS8" }, - "SBS84.3": { + "SBS84": { "description": "Activity of activation-induced cytidine deaminase (AID)", - "displayName": "SBS84.3", + "displayName": "SBS84", "name": "SBS84", "source": "cosmic", - "sourceId": "SBS84", - "sourceIdVersion": "3" + "sourceId": "SBS84" }, - "SBS85.3": { + "SBS85": { "description": "Indirect effects of activation-induced cytidine deaminase (AID) induced somatic mutagenesis in lymphoid cells", - "displayName": "SBS85.3", + "displayName": "SBS85", "name": "SBS85", "source": "cosmic", - "sourceId": "SBS85", - "sourceIdVersion": "3" + "sourceId": "SBS85" }, - "SBS9.3": { + "SBS9": { "description": "May be due in part to mutations induced during replication by polymerase eta as part of somatic hypermutation in lymphoid cells", - "displayName": "SBS9.3", + "displayName": "SBS9", "name": "SBS9", "source": "cosmic", - "sourceId": "SBS9", - "sourceIdVersion": "3" + "sourceId": "SBS9" }, "cd8+ cell infiltration": { "links": [ From d483072a7dbdf9029f240d52154aa7f8b9794d9b Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 21 Oct 2024 13:14:08 -0700 Subject: [PATCH 25/52] removing unnecessary name from signatures data --- data/signatures.json | 135 +++++-------------------------------------- 1 file changed, 13 insertions(+), 122 deletions(-) diff --git a/data/signatures.json b/data/signatures.json index dae5895e..10c26b32 100644 --- a/data/signatures.json +++ b/data/signatures.json @@ -4,636 +4,541 @@ "DBS1": { "description": "Exposure to ultraviolet light", "displayName": "DBS1", - "name": "DBS1", "source": "cosmic", "sourceId": "DBS1" }, "DBS10": { "description": "Defective DNA mismatch repair", "displayName": "DBS10", - "name": "DBS10", "source": "cosmic", "sourceId": "DBS10" }, "DBS11": { "description": "Unknown. Possibly related to APOBEC mutagenesis", "displayName": "DBS11", - "name": "DBS11", "source": "cosmic", "sourceId": "DBS11" }, "DBS2": { "description": "Exposure to tobacco smoking as well as other endogenous and/or exogenous mutagens (eg, acetaldehyde)", "displayName": "DBS2", - "name": "DBS2", "source": "cosmic", "sourceId": "DBS2" }, "DBS3": { "description": "Polymerase epsilon exonuclease domain mutations", "displayName": "DBS3", - "name": "DBS3", "source": "cosmic", "sourceId": "DBS3" }, "DBS4": { "displayName": "DBS4", - "name": "DBS4", "source": "cosmic", "sourceId": "DBS4" }, "DBS5": { "description": "Prior chemotherapy treatment with platinum drugs", "displayName": "DBS5", - "name": "DBS5", "source": "cosmic", "sourceId": "DBS5" }, "DBS6": { "displayName": "DBS6", - "name": "DBS6", "source": "cosmic", "sourceId": "DBS6" }, "DBS7": { "description": "Defective DNA mismatch repair", "displayName": "DBS7", - "name": "DBS7", "source": "cosmic", "sourceId": "DBS7" }, "DBS8": { "displayName": "DBS8", - "name": "DBS8", "source": "cosmic", "sourceId": "DBS8" }, "DBS9": { "displayName": "DBS9", - "name": "DBS9", "source": "cosmic", "sourceId": "DBS9" }, "ID1": { "description": "Slippage during DNA replication of the replicated DNA strand This signature is found in almost all samples, however, substantial number of mutations of this signature in cancers with DNA mismatch repair deficiency", "displayName": "ID1", - "name": "ID1", "source": "cosmic", "sourceId": "ID1" }, "ID10": { "displayName": "ID10", - "name": "ID10", "source": "cosmic", "sourceId": "ID10" }, "ID11": { "displayName": "ID11", - "name": "ID11", "source": "cosmic", "sourceId": "ID11" }, "ID12": { "displayName": "ID12", - "name": "ID12", "source": "cosmic", "sourceId": "ID12" }, "ID13": { "description": "ID13 is found in cancers of the skin from sun exposed areas, therefore, this signature is likely to be due to exposure to ultraviolet light", "displayName": "ID13", - "name": "ID13", "source": "cosmic", "sourceId": "ID13" }, "ID14": { "displayName": "ID14", - "name": "ID14", "source": "cosmic", "sourceId": "ID14" }, "ID15": { "displayName": "ID15", - "name": "ID15", "source": "cosmic", "sourceId": "ID15" }, "ID16": { "displayName": "ID16", - "name": "ID16", "source": "cosmic", "sourceId": "ID16" }, "ID17": { "displayName": "ID17", - "name": "ID17", "source": "cosmic", "sourceId": "ID17" }, "ID2": { "description": "Slippage during DNA replication of the template DNA strand This signature is found in almost all samples, however, substantial number of mutations of this signature in cancers with DNA mismatch repair deficiency", "displayName": "ID2", - "name": "ID2", "source": "cosmic", "sourceId": "ID2" }, "ID3": { "description": "Associated with tobacco smoking", "displayName": "ID3", - "name": "ID3", "source": "cosmic", "sourceId": "ID3" }, "ID4": { "displayName": "ID4", - "name": "ID4", "source": "cosmic", "sourceId": "ID4" }, "ID5": { "displayName": "ID5", - "name": "ID5", "source": "cosmic", "sourceId": "ID5" }, "ID6": { "description": "Defective homologous recombination-based DNA damage repair, often due to inactivating BRCA1 or BRCA2 mutations, leading to non-homologous DNA end-joining activity", "displayName": "ID6", - "name": "ID6", "source": "cosmic", "sourceId": "ID6" }, "ID7": { "description": "Defective DNA mismatch repair", "displayName": "ID7", - "name": "ID7", "source": "cosmic", "sourceId": "ID7" }, "ID8": { "description": "Unknown. Repair of DNA double strand breaks by non-homologous DNA end-joining mechanisms The DSB could, in principle, be radiation induced and the features of ID8 mutations have some similarities to those of radiation induced mutations", "displayName": "ID8", - "name": "ID8", "source": "cosmic", "sourceId": "ID8" }, "ID9": { "displayName": "ID9", - "name": "ID9", "source": "cosmic", "sourceId": "ID9" }, "SBS1": { "description": "An endogenous mutational process initiated by spontaneous or enzymatic deamination of 5-methylcytosine to thymine which generates G:T mismatches in double stranded DNA Failure to detect and remove these mismatches prior to DNA replication results in fixation of the T substitution for C", "displayName": "SBS1", - "name": "SBS1", "source": "cosmic", "sourceId": "SBS1" }, "SBS10a": { "description": "Polymerase epsilon exonuclease domain mutations", "displayName": "SBS10a", - "name": "SBS10a", "source": "cosmic", "sourceId": "SBS10a" }, "SBS10b": { "description": "Polymerase epsilon exonuclease domain mutations", "displayName": "SBS10b", - "name": "SBS10b", "source": "cosmic", "sourceId": "SBS10b" }, "SBS11": { "description": "SBS11 exhibits a mutational pattern resembling that of alkylating agents Patient histories indicate an association between previous treatment with the alkylating agent temozolomide and SBS11 mutations", "displayName": "SBS11", - "name": "SBS11", "source": "cosmic", "sourceId": "SBS11" }, "SBS12": { "displayName": "SBS12", - "name": "SBS12", "source": "cosmic", "sourceId": "SBS12" }, "SBS13": { "description": "Attributed to activity of the AID/APOBEC family of cytidine deaminases on the basis of similarities in the sequence context of cytosine mutations caused by APOBEC enzymes in experimental systems APOBEC3A is probably responsible for most mutations in human cancer, although APOBEC3B may also contribute (these differ in the sequence context two bases 5’ to the mutated cytosine, see 1536 mutation classification signature extraction) SBS13 mutations are likely generated by error prone polymerases (such as REV1) replicating across abasic sites generated by base excision repair removal of uracil", "displayName": "SBS13", - "name": "SBS13", "source": "cosmic", "sourceId": "SBS13" }, "SBS14": { "description": "Concurrent polymerase epsilon mutation and defective DNA mismatch repair", "displayName": "SBS14", - "name": "SBS14", "source": "cosmic", "sourceId": "SBS14" }, "SBS15": { "description": "Defective DNA mismatch repair", "displayName": "SBS15", - "name": "SBS15", "source": "cosmic", "sourceId": "SBS15" }, "SBS16": { "displayName": "SBS16", - "name": "SBS16", "source": "cosmic", "sourceId": "SBS16" }, "SBS17a": { "displayName": "SBS17a", - "name": "SBS17a", "source": "cosmic", "sourceId": "SBS17a" }, "SBS17b": { "displayName": "SBS17b", - "name": "SBS17b", "source": "cosmic", "sourceId": "SBS17b" }, "SBS18": { "displayName": "SBS18", - "name": "SBS18", "source": "cosmic", "sourceId": "SBS18" }, "SBS19": { "displayName": "SBS19", - "name": "SBS19", "source": "cosmic", "sourceId": "SBS19" }, "SBS2": { "description": "Attributed to activity of the AID/APOBEC family of cytidine deaminases on the basis of similarities in the sequence context of cytosine mutations caused by APOBEC enzymes in experimental systems APOBEC3A is probably responsible for most mutations in human cancer, although APOBEC3B may also contribute (these differ in the sequence context two bases 5’ to the mutated cytosine, see 1,536 mutation classification signature extraction) SBS2 mutations may be generated directly by DNA replication across uracil or by error prone polymerases replicating across abasic sites generated by base excision repair removal of uracil", "displayName": "SBS2", - "name": "SBS2", "source": "cosmic", "sourceId": "SBS2" }, "SBS20": { "description": "Concurrent POLD1 mutations and defective DNA mismatch repair", "displayName": "SBS20", - "name": "SBS20", "source": "cosmic", "sourceId": "SBS20" }, "SBS21": { "description": "DNA mismatch repair deficiency", "displayName": "SBS21", - "name": "SBS21", "source": "cosmic", "sourceId": "SBS21" }, "SBS22": { "description": "Aristolochic acid exposure Found in cancer samples with known exposures to aristolochic acid and the pattern of mutations exhibited by the signature is consistent with that observed in experimental systems of aristolochic acid exposure", "displayName": "SBS22", - "name": "SBS22", "source": "cosmic", "sourceId": "SBS22" }, "SBS23": { "displayName": "SBS23", - "name": "SBS23", "source": "cosmic", "sourceId": "SBS23" }, "SBS24": { "description": "Aflatoxin exposure SBS24 has been found in cancer samples with known exposures to aflatoxin and the pattern of mutations exhibited by the signature is consistent with that observed in experimental systems exposed to aflatoxin", "displayName": "SBS24", - "name": "SBS24", "source": "cosmic", "sourceId": "SBS24" }, "SBS25": { "description": "Unknown. However, some Hodgkin’s cell line samples in which the signature has been found were from patients exposed to chemotherapy and it is possible that SBS25 is due to chemotherapy treatment", "displayName": "SBS25", - "name": "SBS25", "source": "cosmic", "sourceId": "SBS25" }, "SBS26": { "description": "Defective DNA mismatch repair", "displayName": "SBS26", - "name": "SBS26", "source": "cosmic", "sourceId": "SBS26" }, "SBS27": { "description": "Possible sequencing artefact", "displayName": "SBS27", - "name": "SBS27", "source": "cosmic", "sourceId": "SBS27" }, "SBS28": { "displayName": "SBS28", - "name": "SBS28", "source": "cosmic", "sourceId": "SBS28" }, "SBS29": { "description": "SBS29 has been found in cancer samples from individuals with a tobacco chewing habit", "displayName": "SBS29", - "name": "SBS29", "source": "cosmic", "sourceId": "SBS29" }, "SBS3": { "description": "Defective homologous recombination-based DNA damage repair which manifests predominantly as small indels and genome rearrangements due to abnormal double strand break repair but also in the form of this base substitution signature", "displayName": "SBS3", - "name": "SBS3", "source": "cosmic", "sourceId": "SBS3" }, "SBS30": { "description": "SBS30 is due to deficiency in base excision repair due to inactivating mutations in NTHL1", "displayName": "SBS30", - "name": "SBS30", "source": "cosmic", "sourceId": "SBS30" }, "SBS31": { "description": "Prior chemotherapy treatment with platinum drugs", "displayName": "SBS31", - "name": "SBS31", "source": "cosmic", "sourceId": "SBS31" }, "SBS32": { "description": "Prior treatment with azathioprine to induce immunosuppression Associated mutation classes and signatures", "displayName": "SBS32", - "name": "SBS32", "source": "cosmic", "sourceId": "SBS32" }, "SBS33": { "displayName": "SBS33", - "name": "SBS33", "source": "cosmic", "sourceId": "SBS33" }, "SBS34": { "displayName": "SBS34", - "name": "SBS34", "source": "cosmic", "sourceId": "SBS34" }, "SBS35": { "description": "Prior chemotherapy treatment with platinum drugs", "displayName": "SBS35", - "name": "SBS35", "source": "cosmic", "sourceId": "SBS35" }, "SBS36": { "description": "Defective base excision repair, including DNA damage due to reactive oxygen species, due to biallelic germline or somatic MUTYH mutations", "displayName": "SBS36", - "name": "SBS36", "source": "cosmic", "sourceId": "SBS36" }, "SBS37": { "displayName": "SBS37", - "name": "SBS37", "source": "cosmic", "sourceId": "SBS37" }, "SBS38": { "description": "Unknown. Found only in ultraviolet light associated melanomas suggesting potential indirect damage from UV-light", "displayName": "SBS38", - "name": "SBS38", "source": "cosmic", "sourceId": "SBS38" }, "SBS39": { "displayName": "SBS39", - "name": "SBS39", "source": "cosmic", "sourceId": "SBS39" }, "SBS4": { "description": "Associated with tobacco smoking Its profile is similar to the mutational spectrum observed in experimental systems exposed to tobacco carcinogens such as benzo[a]pyrene SBS4 is, therefore, likely due to direct DNA damage by tobacco smoke mutagens", "displayName": "SBS4", - "name": "SBS4", "source": "cosmic", "sourceId": "SBS4" }, "SBS40": { "displayName": "SBS40", - "name": "SBS40", "source": "cosmic", "sourceId": "SBS40" }, "SBS41": { "displayName": "SBS41", - "name": "SBS41", "source": "cosmic", "sourceId": "SBS41" }, "SBS42": { "description": "Occupational exposure to haloalkanes", "displayName": "SBS42", - "name": "SBS42", "source": "cosmic", "sourceId": "SBS42" }, "SBS43": { "description": "Unknown. Possible sequencing artefact", "displayName": "SBS43", - "name": "SBS43", "source": "cosmic", "sourceId": "SBS43" }, "SBS44": { "description": "Defective DNA mismatch repair", "displayName": "SBS44", - "name": "SBS44", "source": "cosmic", "sourceId": "SBS44" }, "SBS45": { "description": "Possible artefact due to 8-oxo-guanine introduced during sequencing", "displayName": "SBS45", - "name": "SBS45", "source": "cosmic", "sourceId": "SBS45" }, "SBS46": { "description": "Possible sequencing artefact", "displayName": "SBS46", - "name": "SBS46", "source": "cosmic", "sourceId": "SBS46" }, "SBS47": { "description": "Possible sequencing artefact", "displayName": "SBS47", - "name": "SBS47", "source": "cosmic", "sourceId": "SBS47" }, "SBS48": { "description": "Possible sequencing artefact", "displayName": "SBS48", - "name": "SBS48", "source": "cosmic", "sourceId": "SBS48" }, "SBS49": { "description": "Possible sequencing artefact", "displayName": "SBS49", - "name": "SBS49", "source": "cosmic", "sourceId": "SBS49" }, "SBS5": { "description": "Unknown. SBS5 mutational burden is increased in bladder cancer samples with ERCC2 mutations and in many cancer types due to tobacco smoking", "displayName": "SBS5", - "name": "SBS5", "source": "cosmic", "sourceId": "SBS5" }, "SBS50": { "description": "Possible sequencing artefact", "displayName": "SBS50", - "name": "SBS50", "source": "cosmic", "sourceId": "SBS50" }, "SBS51": { "description": "Possible sequencing artefact", "displayName": "SBS51", - "name": "SBS51", "source": "cosmic", "sourceId": "SBS51" }, "SBS52": { "description": "Possible sequencing artefact", "displayName": "SBS52", - "name": "SBS52", "source": "cosmic", "sourceId": "SBS52" }, "SBS53": { "description": "Possible sequencing artefact", "displayName": "SBS53", - "name": "SBS53", "source": "cosmic", "sourceId": "SBS53" }, "SBS54": { "description": "Possible sequencing artefact Possible contamination with germline variants", "displayName": "SBS54", - "name": "SBS54", "source": "cosmic", "sourceId": "SBS54" }, "SBS55": { "description": "Possible sequencing artefact", "displayName": "SBS55", - "name": "SBS55", "source": "cosmic", "sourceId": "SBS55" }, "SBS56": { "description": "Possible sequencing artefact", "displayName": "SBS56", - "name": "SBS56", "source": "cosmic", "sourceId": "SBS56" }, "SBS57": { "description": "Possible sequencing artefact", "displayName": "SBS57", - "name": "SBS57", "source": "cosmic", "sourceId": "SBS57" }, "SBS58": { "description": "Possible sequencing artefact", "displayName": "SBS58", - "name": "SBS58", "source": "cosmic", "sourceId": "SBS58" }, "SBS59": { "description": "Possible sequencing artefact", "displayName": "SBS59", - "name": "SBS59", "source": "cosmic", "sourceId": "SBS59" }, "SBS6": { "description": "SBS6 is associated with defective DNA mismatch repair and is found in microsatellite unstable tumours", "displayName": "SBS6", - "name": "SBS6", "source": "cosmic", "sourceId": "SBS6" }, "SBS60": { "description": "Possible sequencing artefact", "displayName": "SBS60", - "name": "SBS60", "source": "cosmic", "sourceId": "SBS60" }, "SBS7a": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", "displayName": "SBS7a", - "name": "SBS7a", "source": "cosmic", "sourceId": "SBS7a" }, "SBS7b": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", "displayName": "SBS7b", - "name": "SBS7b", "source": "cosmic", "sourceId": "SBS7b" }, "SBS7c": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", "displayName": "SBS7c", - "name": "SBS7c", "source": "cosmic", "sourceId": "SBS7c" }, "SBS7d": { "description": "SBS7a/SBS7b/SBS7c/SBS7d are found in cancers of the skin from sun exposed areas and are thus likely to be due to exposure to ultraviolet light SBS7a may possibly be the consequence of just one of the two major known UV photoproducts, cyclobutane pyrimidine dimers or 6-4 photoproducts However, there is currently no evidence for this hypothesis and it is unclear which of these photoproducts may be responsible for SBS7a", "displayName": "SBS7d", - "name": "SBS7d", "source": "cosmic", "sourceId": "SBS7d" }, "SBS8": { "displayName": "SBS8", - "name": "SBS8", "source": "cosmic", "sourceId": "SBS8" }, "SBS84": { "description": "Activity of activation-induced cytidine deaminase (AID)", "displayName": "SBS84", - "name": "SBS84", "source": "cosmic", "sourceId": "SBS84" }, "SBS85": { "description": "Indirect effects of activation-induced cytidine deaminase (AID) induced somatic mutagenesis in lymphoid cells", "displayName": "SBS85", - "name": "SBS85", "source": "cosmic", "sourceId": "SBS85" }, "SBS9": { "description": "May be due in part to mutations induced during replication by polymerase eta as part of somatic hypermutation in lymphoid cells", "displayName": "SBS9", - "name": "SBS9", "source": "cosmic", "sourceId": "SBS9" }, @@ -643,12 +548,10 @@ "class": "SubClassOf", "target": "immune infiltration" } - ], - "name": "cd8+ cell infiltration" + ] }, "erv load": { - "description": "endogenous retroviruses (ERV) expression due to epigenetic derepression", - "name": "erv load" + "description": "endogenous retroviruses (ERV) expression due to epigenetic derepression" }, "genomic instability": { "description": "increased frequency of mutations and genomic alterations" @@ -662,8 +565,7 @@ ] }, "hla genotype": { - "description": "homo- or heterozygosity in HLA class I locus (HLA-A, HLA-B or HLA-C)", - "name": "hla genotype" + "description": "homo- or heterozygosity in HLA class I locus (HLA-A, HLA-B or HLA-C)" }, "homologous recombination deficiency": { "description": "genetic instability due to genomic alterations in the homologous recombination (HR) DNA repair pathway", @@ -672,8 +574,7 @@ "class": "SubClassOf", "target": "genomic instability" } - ], - "name": "homologous recombination deficiency" + ] }, "homologous recombination proficiency": { "links": [ @@ -690,12 +591,10 @@ "class": "DeprecatedBy", "target": "homologous recombination deficiency" } - ], - "name": "hrd" + ] }, "immune infiltration": { - "description": "proportion of immune/inflammatory cells in the tumour microenvironment", - "name": "immune infiltration" + "description": "proportion of immune/inflammatory cells in the tumour microenvironment" }, "microsatellite instability": { "description": "genetic instability in short nucleotide repeats (microsatellites) due to a high mutation rate as a result of abnormal DNA mismatch repair", @@ -704,11 +603,9 @@ "class": "SubClassOf", "target": "microsatellite phenotype" } - ], - "name": "microsatellite instability" + ] }, "microsatellite phenotype": { - "name": "microsatellite phenotype" }, "microsatellite stable": { "links": [ @@ -716,8 +613,7 @@ "class": "SubClassOf", "target": "microsatellite phenotype" } - ], - "name": "microsatellite stable" + ] }, "mismatch repair deficiency": { "description": "deficiency of the DNA mismatch repair pathway", @@ -735,8 +631,7 @@ "class": "DeprecatedBy", "target": "microsatellite instability" } - ], - "name": "msi" + ] }, "mss": { "deprecated": true, @@ -745,16 +640,13 @@ "class": "DeprecatedBy", "target": "microsatellite stable" } - ], - "name": "mss" + ] }, "mutation burden": { - "description": "total number of somatic mutations normalized to the genome size", - "name": "mutation burden" + "description": "total number of somatic mutations normalized to the genome size" }, "neoantigen load": { - "description": "expression of antigens that are entirely absent from the normal human genome and the results of mutations acquired during carcinogenesis and progression", - "name": "neoantigen load" + "description": "expression of antigens that are entirely absent from the normal human genome and the results of mutations acquired during carcinogenesis and progression" }, "t cell infiltration": { "links": [ @@ -762,8 +654,7 @@ "class": "SubClassOf", "target": "immune infiltration" } - ], - "name": "t cell infiltration" + ] } }, "sources": { From 773acb4f8a27cded40199e07d05bbaae26cf3938 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Mon, 21 Oct 2024 16:37:28 -0700 Subject: [PATCH 26/52] add cosmic signature version to filter --- src/moa/index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 9d1d6cf0..9753f246 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -256,11 +256,12 @@ const loadVariant = async (conn, moaVariant) => { }); } } else if (moaVariant.feature_type === 'mutational_signature') { - const signature = await conn.getRecords({ + const signature = await conn.getUniqueRecordBy({ filters: { AND: [ { source: { filters: { name: 'cosmic' }, target: 'Source' } }, { sourceId: moaVariant.cosmic_signature }, + { sourceIdVersion: '3'}, ], }, target: 'Signature', @@ -269,17 +270,17 @@ const loadVariant = async (conn, moaVariant) => { try { const record = await conn.getUniqueRecordBy({ - filters: { AND: [{ reference1: rid(signature[0]) }, { type: rid(variantType) }] }, + filters: { AND: [{ reference1: rid(signature) }, { type: rid(variantType) }] }, target: 'CategoryVariant', }); return await conn.updateRecord('CategoryVariant', record['@rid'], { - displayName: `${signature[0].name.toUpperCase()} signature present`, + displayName: `${signature.name.toUpperCase()} signature present`, }); } catch (err) { return conn.addVariant({ content: { - displayName: `${signature[0].name.toUpperCase()} signature present`, - reference1: rid(signature[0]), + displayName: `${signature.name.toUpperCase()} signature present`, + reference1: rid(signature), type: rid(variantType), }, existsOk: true, From aeac55eb49572cc2bdfe19f6538d6d44a2496fb7 Mon Sep 17 00:00:00 2001 From: sshugsc Date: Mon, 21 Oct 2024 16:56:16 -0700 Subject: [PATCH 27/52] lint --- src/moa/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/moa/index.js b/src/moa/index.js index 9753f246..716a666e 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -261,7 +261,7 @@ const loadVariant = async (conn, moaVariant) => { AND: [ { source: { filters: { name: 'cosmic' }, target: 'Source' } }, { sourceId: moaVariant.cosmic_signature }, - { sourceIdVersion: '3'}, + { sourceIdVersion: '3' }, ], }, target: 'Signature', From a632fc1b0d3c6fd83ad02d184500ba1d0b4a265a Mon Sep 17 00:00:00 2001 From: sshugsc Date: Tue, 22 Oct 2024 15:43:07 -0700 Subject: [PATCH 28/52] update signature present to high signature --- src/moa/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 716a666e..553d69f3 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -274,12 +274,12 @@ const loadVariant = async (conn, moaVariant) => { target: 'CategoryVariant', }); return await conn.updateRecord('CategoryVariant', record['@rid'], { - displayName: `${signature.name.toUpperCase()} signature present`, + displayName: `${signature.name.toUpperCase()} high signature`, }); } catch (err) { return conn.addVariant({ content: { - displayName: `${signature.name.toUpperCase()} signature present`, + displayName: `${signature.name.toUpperCase()} high signature`, reference1: rid(signature), type: rid(variantType), }, From ca1337e9dff44616beb6d893e8555a1c60f5227d Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Wed, 23 Oct 2024 14:54:33 -0700 Subject: [PATCH 29/52] Changes to cosmic signatures handling --- src/moa/index.js | 51 ++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 553d69f3..9b8a1c2b 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -256,36 +256,45 @@ const loadVariant = async (conn, moaVariant) => { }); } } else if (moaVariant.feature_type === 'mutational_signature') { - const signature = await conn.getUniqueRecordBy({ - filters: { - AND: [ - { source: { filters: { name: 'cosmic' }, target: 'Source' } }, - { sourceId: moaVariant.cosmic_signature }, - { sourceIdVersion: '3' }, - ], - }, - target: 'Signature', - }); - const variantType = await conn.getVocabularyTerm('high signature'); - + // Cosmic signature + let signature = {}; try { - const record = await conn.getUniqueRecordBy({ - filters: { AND: [{ reference1: rid(signature) }, { type: rid(variantType) }] }, - target: 'CategoryVariant', - }); - return await conn.updateRecord('CategoryVariant', record['@rid'], { - displayName: `${signature.name.toUpperCase()} high signature`, + signature = await conn.getUniqueRecordBy({ + target: 'Signature', + filters: { + AND: [ + { + source: { + target: 'Source', + filters: { name: 'cosmic' }, + }, + }, + { sourceId: moaVariant.cosmic_signature }, + { sourceIdVersion: '3' }, + ], + }, }); - } catch (err) { - return conn.addVariant({ + } catch(err) { + // Enforcing usage of v3 Cosmic signatures + throw Error(`Missing Cosmic signature ${moaVariant.cosmic_signature}`); + } + + // 'high signature' variant type (prefered over 'signature present') + const variantType = await conn.getVocabularyTerm('high signature'); + + + // Corresponding 'high signature' CategoryVariant + try { + return await conn.addVariant({ content: { - displayName: `${signature.name.toUpperCase()} high signature`, reference1: rid(signature), type: rid(variantType), }, existsOk: true, target: 'CategoryVariant', }); + } catch (err) { + throw Error(`Unable to add variant for Cosmic signature ${moaVariant.cosmic_signature}`); } // } else if (moaVariant.feature_type === 'mutational_burden') { } else if (moaVariant.feature_type === 'copy_number') { From 51c3868414f451b35018e7d01f8a9706d02684af Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Wed, 23 Oct 2024 15:02:43 -0700 Subject: [PATCH 30/52] linting --- src/moa/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 9b8a1c2b..3455000e 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -258,6 +258,7 @@ const loadVariant = async (conn, moaVariant) => { } else if (moaVariant.feature_type === 'mutational_signature') { // Cosmic signature let signature = {}; + try { signature = await conn.getUniqueRecordBy({ target: 'Signature', @@ -274,15 +275,14 @@ const loadVariant = async (conn, moaVariant) => { ], }, }); - } catch(err) { + } catch (err) { // Enforcing usage of v3 Cosmic signatures throw Error(`Missing Cosmic signature ${moaVariant.cosmic_signature}`); } // 'high signature' variant type (prefered over 'signature present') const variantType = await conn.getVocabularyTerm('high signature'); - - + // Corresponding 'high signature' CategoryVariant try { return await conn.addVariant({ From f51e44fd272918582d458159be49cab2b502bbf0 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Thu, 7 Nov 2024 13:00:01 -0800 Subject: [PATCH 31/52] KBDEV-1224 Add 2 HLA Signatures in /data/signatures.json --- data/signatures.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/signatures.json b/data/signatures.json index 10c26b32..938c4fa2 100644 --- a/data/signatures.json +++ b/data/signatures.json @@ -655,6 +655,12 @@ "target": "immune infiltration" } ] + }, + "HLA-A*02:01": { + "description": "Allele 02:01 for HLA-A gene. Meant to describe all alleles of higher precision, if any; See KBDEV-1224 for more details" + }, + "HLA-B*27": { + "description": "Allele 27 for HLA-B gene. Meant to describe all alleles of higher precision, if any; See KBDEV-1224 for more details" } }, "sources": { From 237299ab4d9231761d0b0afd94dfdc7aac5801e4 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Tue, 19 Nov 2024 13:48:55 -0800 Subject: [PATCH 32/52] KBDEV-1224 - add displayName to HLAs in data/signatures.json --- data/signatures.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/signatures.json b/data/signatures.json index 938c4fa2..4cb5e950 100644 --- a/data/signatures.json +++ b/data/signatures.json @@ -657,10 +657,12 @@ ] }, "HLA-A*02:01": { - "description": "Allele 02:01 for HLA-A gene. Meant to describe all alleles of higher precision, if any; See KBDEV-1224 for more details" + "description": "Allele 02:01 for HLA-A gene. Meant to describe all alleles of higher precision, if any; See KBDEV-1224 for more details", + "displayName": "HLA-A*02:01" }, "HLA-B*27": { - "description": "Allele 27 for HLA-B gene. Meant to describe all alleles of higher precision, if any; See KBDEV-1224 for more details" + "description": "Allele 27 for HLA-B gene. Meant to describe all alleles of higher precision, if any; See KBDEV-1224 for more details", + "displayName": "HLA-B*27" } }, "sources": { From 5129c5fece75fca0f4cfb5782f50cbbfb664cc31 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Tue, 19 Nov 2024 13:50:01 -0800 Subject: [PATCH 33/52] KBDEV-1224 - remove hla genotype from data/signatures.json --- data/signatures.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/data/signatures.json b/data/signatures.json index 4cb5e950..e92a534d 100644 --- a/data/signatures.json +++ b/data/signatures.json @@ -564,9 +564,6 @@ } ] }, - "hla genotype": { - "description": "homo- or heterozygosity in HLA class I locus (HLA-A, HLA-B or HLA-C)" - }, "homologous recombination deficiency": { "description": "genetic instability due to genomic alterations in the homologous recombination (HR) DNA repair pathway", "links": [ From e9e485afba48e1bf219ec7931b54deb3c52517a1 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 4 Nov 2024 10:47:08 -0800 Subject: [PATCH 34/52] Fix error catch/throw in uploadNormalizedVariant() --- src/civic/evidenceItem.js | 5 ++--- src/civic/variant.js | 7 ++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/civic/evidenceItem.js b/src/civic/evidenceItem.js index f999f8db..0f49505a 100644 --- a/src/civic/evidenceItem.js +++ b/src/civic/evidenceItem.js @@ -180,9 +180,8 @@ const processCombination = async (conn, { const processedVariants = await processVariantRecord(conn, variant, feature); logger.verbose(`converted variant name (${variant.name}) to variants (${processedVariants.map(v => v.displayName).join(', and ')})`); variants.push(...processedVariants); - } catch (err) { - logger.error(`unable to process the variant (id=${rawRecord.variant.id}, name=${rawRecord.variant.name})`); - throw err; + } catch { + throw new Error(`unable to process the variant (id=${variant.id}, name=${variant.name})`); } } diff --git a/src/civic/variant.js b/src/civic/variant.js index 98ebee67..f66c011b 100644 --- a/src/civic/variant.js +++ b/src/civic/variant.js @@ -273,7 +273,11 @@ const uploadNormalizedVariant = async (conn, normalizedVariant, feature) => { SOURCE_DEFN.name, ); } catch (err) { - variantType = await conn.getVocabularyTerm(normalizedVariant.type || content.type); + try { + variantType = await conn.getVocabularyTerm(normalizedVariant.type || content.type); + } catch { + throw new Error(`Unable to upload CIVIC variant (${normalizedVariant}})`); + } } content.type = rid(variantType); @@ -392,6 +396,7 @@ const processVariantRecord = async (conn, civicVariantRecord, feature) => { } } catch (err) { VARIANT_CACHE.set(JSON.stringify(rawVariant), { err }); + throw err } VARIANT_CACHE.set(JSON.stringify(rawVariant), { result }); From fadc6e5898c12d506e26ff16d203c77e55ad227c Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 4 Nov 2024 10:50:15 -0800 Subject: [PATCH 35/52] Add getStatements() to civic/statements.js --- src/civic/statement.js | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/civic/statement.js b/src/civic/statement.js index e4049bcf..cd83512d 100644 --- a/src/civic/statement.js +++ b/src/civic/statement.js @@ -177,6 +177,31 @@ const contentMatching = ({ return records; }; +/** + * Given source & list of sourceIds, returns corresponding statements + * + * @param {ApiConnection} conn the api connection object for GraphKB + * @param {object} param1 + * @param {string} param1.source the source RID + * @param {string[]} param1.sourceIds an array of sourceIds + * @returns {string[]} a list of statement RIDs + */ +const getStatements = async (conn, { source, sourceIds }) => { + const records = await conn.getRecords({ + filters: { + AND: [ + { sourceId: sourceIds }, + { source }, + ], + }, + target: 'Statement', + }); + const rids = records.map( + (el) => el['@rid'], + ); + return rids; +}; + /** * Given content from CIViC, try to create the GraphKB record * @@ -250,18 +275,7 @@ const deleteStatements = async (conn, { rids = [], source, sourceIds }) => { // Get rids to delete if none provided if (rids.length === 0) { logger.info('Loading corresponding GraphKB statement RIDs to delete'); - const records = await conn.getRecords({ - filters: { - AND: [ - { sourceId: sourceIds }, - { source }, - ], - }, - target: 'Statement', - }); - rids.push(...records.map( - (el) => el['@rid'], - )); + rids.push(...await getStatements(conn, { source, sourceIds })); logger.info(`${rids.length} RIDs found`); } @@ -286,6 +300,7 @@ module.exports = { contentMatching, createStatement, deleteStatements, + getStatements, isMatching, needsUpdate, updateStatement, From 626b50bdb1219e29865c2aa4733db6acc2d0d957 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 22 Nov 2024 10:00:47 -0800 Subject: [PATCH 36/52] Add --deleteDeprecated & --noDeleteOnUnmatched options to civic arg parser --- bin/load.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bin/load.js b/bin/load.js index 166ef615..ba3903d3 100644 --- a/bin/load.js +++ b/bin/load.js @@ -109,6 +109,16 @@ civicParser.add_argument('--noUpdate', { default: false, help: 'Will not check for updating content of existing GraphKB Statements', }); +civicParser.add_argument('--noDeleteOnUnmatched', { + action: 'store_true', + default: false, + help: 'Will not delete GraphKB Statements from valid sourceID but not matching a combination', +}); +civicParser.add_argument('--deleteDeprecated', { + action: 'store_true', + default: false, + help: 'Will delete GraphKB Statements from deprecated sourceID', +}); const clinicaltrialsgovParser = subparsers.add_parser('clinicaltrialsgov'); clinicaltrialsgovParser.add_argument('--days', { From 214ebfc8976b22bf139ffdd30525536b07230f22 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 22 Nov 2024 10:07:35 -0800 Subject: [PATCH 37/52] Add support for noDeleteOnUnmatched option in civic --- src/civic/index.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/civic/index.js b/src/civic/index.js index 2f0aee38..f5611ec6 100644 --- a/src/civic/index.js +++ b/src/civic/index.js @@ -57,7 +57,8 @@ const incrementCounts = (initial, updates) => { * @param {ApiConnection} param0.conn the api connection object for GraphKB * @param {string} param0.errorLogPrefix prefix to the generated error json file * @param {number} param0.maxRecords limit of EvidenceItem records to be processed and upload - * @param {?boolean} param0.noUpdate for avoiding deletion/update of existing GraphKB Statements + * @param {?boolean} param0.noDeleteOnUnmatched no deletion of existing GraphKB Statements related to unmatched combination(s) + * @param {?boolean} param0.noUpdate no update of existing GraphKB Statements * @param {string[]} param0.trustedCurators a list of curator IDs for submitted-only EvidenceItems * @param {?string} param0.url url to use as the base for accessing the civic ApiConnection */ @@ -65,6 +66,7 @@ const upload = async ({ conn, errorLogPrefix, maxRecords, + noDeleteOnUnmatched = false, noUpdate = false, trustedCurators, url = BASE_URL, @@ -181,7 +183,8 @@ const upload = async ({ processingIntoCombinations: new Map(), relevance: new Map(), }; - const casesToReview = new Map(); + const statementsToReview_unmatched_processingError = new Map(); + const statementsToReview_unmatched = new Map(); logger.info(`\n\n${'#'.repeat(80)}\n## PROCESSING RECORDS\n${'#'.repeat(80)}\n`); let recordNumber = 0; @@ -366,13 +369,17 @@ const upload = async ({ } // DELETE - if (!noUpdate && toDelete.length > 0) { + if (toDelete.length > 0) { const rids = toDelete.map(el => el['@rid']); if (processCombinationErrors > 0) { // Do not delete any statements if some combinations have processing errors - logger.info(`${toDelete.length} unmatched statement(s) to be reviewed for deletion`); - casesToReview.set(id, rids); + logger.warn(`${toDelete.length} unmatched statement(s). To be reviewed since some processing errors occured`); + statementsToReview_unmatched_processingError.set(id, rids); + } else if (noDeleteOnUnmatched) { + // Do not delete any statements if noDeleteOnUnmatched flag + logger.warn(`${toDelete.length} unmatched statement(s). To be reviewed since the noDeleteOnUnmatched flag is being used`); + statementsToReview_unmatched.set(id, rids); } else { loaclCountsST.delete = await deleteStatements(conn, { rids }); } @@ -445,9 +452,11 @@ const upload = async ({ // Logging processing error cases to be reviewed, // so a reviewer can decide if corresponding statements need to be deleted or not logger.info(); - logger.info('***** Cases to be reviewed for deletion *****'); - logger.warn(`${casesToReview.size} Evidence Item(s) with processing errors leading to unmatched Statement(s)`); - casesToReview.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); + logger.info('***** Unmatched cases to be reviewed for deletion *****'); + logger.warn(`${statementsToReview_unmatched_processingError.size} Evidence Item(s) with processing errors leading to unmatched Statement(s)`); + statementsToReview_unmatched_processingError.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); + logger.warn(`${statementsToReview_unmatched.size} Evidence Item(s) with unmatched Statement(s) with no processing error involved`); + statementsToReview_unmatched.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); // Logging Statement CRUD operations counts if (countsST) { From f5b70935ecb75e589136e4f7a5daf54cb7d52dbd Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 22 Nov 2024 10:08:56 -0800 Subject: [PATCH 38/52] Add support for deleteDeprecated option in civic --- src/civic/index.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/civic/index.js b/src/civic/index.js index f5611ec6..a6640f0a 100644 --- a/src/civic/index.js +++ b/src/civic/index.js @@ -19,6 +19,7 @@ const { contentMatching, createStatement, deleteStatements, + getStatements, needsUpdate, updateStatement, } = require('./statement'); @@ -55,6 +56,7 @@ const incrementCounts = (initial, updates) => { * * @param {object} param0 * @param {ApiConnection} param0.conn the api connection object for GraphKB + * @param {?boolean} param0.deleteDeprecated deletion of existing GraphKB Statements related to deprecated evidence(s) * @param {string} param0.errorLogPrefix prefix to the generated error json file * @param {number} param0.maxRecords limit of EvidenceItem records to be processed and upload * @param {?boolean} param0.noDeleteOnUnmatched no deletion of existing GraphKB Statements related to unmatched combination(s) @@ -64,6 +66,7 @@ const incrementCounts = (initial, updates) => { */ const upload = async ({ conn, + deleteDeprecated = false, // Won't delete deprecated sourceIds by default errorLogPrefix, maxRecords, noDeleteOnUnmatched = false, @@ -421,22 +424,32 @@ const upload = async ({ } // DELETING UNWANTED GRAPHKB STATEMENTS - // sourceIds no longer in CIViC (not accepted/submitted by trustedCurators) but still in GraphKB + // sourceIds no longer in CIViC (not accepted/submitted-by-trustedCurators) but still in GraphKB const allIdsFromCivic = new Set(evidenceItems.map(r => r.id.toString())); - const toDelete = new Set([...sourceIdsFromGKB].filter(x => !allIdsFromCivic.has(x))); + const sourceIdstoDeleteStatementsFrom = Array.from( + new Set([...sourceIdsFromGKB].filter(x => !allIdsFromCivic.has(x))) + ); logger.info(); logger.info('***** Deprecated items *****'); - logger.warn(`${toDelete.size} deprecated ${SOURCE_DEFN.name} Evidence Items still in GraphKB Statement`); + logger.warn(`${sourceIdstoDeleteStatementsFrom.length} deprecated ${SOURCE_DEFN.name} Evidence Items still in GraphKB Statement`); - if (toDelete.size > 0) { - logger.info(`sourceIds: ${Array.from(toDelete)}`); + if (sourceIdstoDeleteStatementsFrom.length > 0) { + logger.info(`sourceIds: ${sourceIdstoDeleteStatementsFrom}`); } // GraphKB Statements Soft-deletion - if (!noUpdate && toDelete.size > 0) { + if (sourceIdstoDeleteStatementsFrom.length > 0) { + if (!deleteDeprecated) { + // Do not delete any statements if no deleteDeprecated flag + const deprecatedStatementRids = await getStatements(conn, { source: sourceRid, sourceIds: sourceIdstoDeleteStatementsFrom}); + logger.warn(`${deprecatedStatementRids.length} corresponding deprecated statement(s). To be reviewed since no deleteDeprecated flag`); + const deprecatedStatementsFilepath = `${errorLogPrefix}-civic-deprecatedStatements.json`; + logger.info(`writing ${deprecatedStatementsFilepath}`); + fs.writeFileSync(deprecatedStatementsFilepath, JSON.stringify(deprecatedStatementRids, null, 2)); + } else { const deletedCount = await deleteStatements(conn, { source: sourceRid, - sourceIds: Array.from(toDelete), + sourceIds: sourceIdstoDeleteStatementsFrom, }); const attempts = deletedCount.success + deletedCount.err; logger.info(`${deletedCount.success}/${attempts} soft-deleted statements`); @@ -446,6 +459,7 @@ const upload = async ({ countsST.delete.success += deletedCount.success; } else { countsST = { delete: { err: deletedCount.err, success: deletedCount.success } }; + } } } From 8aa00c4a7c6c51d2b0d86238e6f857330ca76caf Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 22 Nov 2024 11:38:40 -0800 Subject: [PATCH 39/52] Fix linting --- src/civic/evidenceItem.js | 2 +- src/civic/index.js | 50 ++++++++++++++++++++++----------------- src/civic/variant.js | 4 ++-- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/civic/evidenceItem.js b/src/civic/evidenceItem.js index 0f49505a..2178cb39 100644 --- a/src/civic/evidenceItem.js +++ b/src/civic/evidenceItem.js @@ -180,7 +180,7 @@ const processCombination = async (conn, { const processedVariants = await processVariantRecord(conn, variant, feature); logger.verbose(`converted variant name (${variant.name}) to variants (${processedVariants.map(v => v.displayName).join(', and ')})`); variants.push(...processedVariants); - } catch { + } catch (err) { throw new Error(`unable to process the variant (id=${variant.id}, name=${variant.name})`); } } diff --git a/src/civic/index.js b/src/civic/index.js index a6640f0a..262e1d2a 100644 --- a/src/civic/index.js +++ b/src/civic/index.js @@ -186,8 +186,8 @@ const upload = async ({ processingIntoCombinations: new Map(), relevance: new Map(), }; - const statementsToReview_unmatched_processingError = new Map(); - const statementsToReview_unmatched = new Map(); + const statementsToReviewUnmatchedProcessingError = new Map(); + const statementsToReviewUnmatched = new Map(); logger.info(`\n\n${'#'.repeat(80)}\n## PROCESSING RECORDS\n${'#'.repeat(80)}\n`); let recordNumber = 0; @@ -378,11 +378,11 @@ const upload = async ({ if (processCombinationErrors > 0) { // Do not delete any statements if some combinations have processing errors logger.warn(`${toDelete.length} unmatched statement(s). To be reviewed since some processing errors occured`); - statementsToReview_unmatched_processingError.set(id, rids); + statementsToReviewUnmatchedProcessingError.set(id, rids); } else if (noDeleteOnUnmatched) { // Do not delete any statements if noDeleteOnUnmatched flag logger.warn(`${toDelete.length} unmatched statement(s). To be reviewed since the noDeleteOnUnmatched flag is being used`); - statementsToReview_unmatched.set(id, rids); + statementsToReviewUnmatched.set(id, rids); } else { loaclCountsST.delete = await deleteStatements(conn, { rids }); } @@ -427,7 +427,7 @@ const upload = async ({ // sourceIds no longer in CIViC (not accepted/submitted-by-trustedCurators) but still in GraphKB const allIdsFromCivic = new Set(evidenceItems.map(r => r.id.toString())); const sourceIdstoDeleteStatementsFrom = Array.from( - new Set([...sourceIdsFromGKB].filter(x => !allIdsFromCivic.has(x))) + new Set([...sourceIdsFromGKB].filter(x => !allIdsFromCivic.has(x))), ); logger.info(); logger.info('***** Deprecated items *****'); @@ -441,24 +441,30 @@ const upload = async ({ if (sourceIdstoDeleteStatementsFrom.length > 0) { if (!deleteDeprecated) { // Do not delete any statements if no deleteDeprecated flag - const deprecatedStatementRids = await getStatements(conn, { source: sourceRid, sourceIds: sourceIdstoDeleteStatementsFrom}); - logger.warn(`${deprecatedStatementRids.length} corresponding deprecated statement(s). To be reviewed since no deleteDeprecated flag`); + const deprecatedStatementRids = await getStatements( + conn, + { source: sourceRid, sourceIds: sourceIdstoDeleteStatementsFrom }, + ); + logger.warn(`${deprecatedStatementRids.length} corresponding deprecated statement(s). To be reviewed since no deleteDeprecated flag`); const deprecatedStatementsFilepath = `${errorLogPrefix}-civic-deprecatedStatements.json`; logger.info(`writing ${deprecatedStatementsFilepath}`); - fs.writeFileSync(deprecatedStatementsFilepath, JSON.stringify(deprecatedStatementRids, null, 2)); + fs.writeFileSync( + deprecatedStatementsFilepath, + JSON.stringify(deprecatedStatementRids, null, 2), + ); } else { - const deletedCount = await deleteStatements(conn, { - source: sourceRid, + const deletedCount = await deleteStatements(conn, { + source: sourceRid, sourceIds: sourceIdstoDeleteStatementsFrom, - }); - const attempts = deletedCount.success + deletedCount.err; - logger.info(`${deletedCount.success}/${attempts} soft-deleted statements`); + }); + const attempts = deletedCount.success + deletedCount.err; + logger.info(`${deletedCount.success}/${attempts} soft-deleted statements`); - if (countsST) { - countsST.delete.err += deletedCount.err; - countsST.delete.success += deletedCount.success; - } else { - countsST = { delete: { err: deletedCount.err, success: deletedCount.success } }; + if (countsST) { + countsST.delete.err += deletedCount.err; + countsST.delete.success += deletedCount.success; + } else { + countsST = { delete: { err: deletedCount.err, success: deletedCount.success } }; } } } @@ -467,10 +473,10 @@ const upload = async ({ // so a reviewer can decide if corresponding statements need to be deleted or not logger.info(); logger.info('***** Unmatched cases to be reviewed for deletion *****'); - logger.warn(`${statementsToReview_unmatched_processingError.size} Evidence Item(s) with processing errors leading to unmatched Statement(s)`); - statementsToReview_unmatched_processingError.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); - logger.warn(`${statementsToReview_unmatched.size} Evidence Item(s) with unmatched Statement(s) with no processing error involved`); - statementsToReview_unmatched.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); + logger.warn(`${statementsToReviewUnmatchedProcessingError.size} Evidence Item(s) with processing errors leading to unmatched Statement(s)`); + statementsToReviewUnmatchedProcessingError.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); + logger.warn(`${statementsToReviewUnmatched.size} Evidence Item(s) with unmatched Statement(s) with no processing error involved`); + statementsToReviewUnmatched.forEach((v, k) => logger.info(`${k} -> ${JSON.stringify(v)}`)); // Logging Statement CRUD operations counts if (countsST) { diff --git a/src/civic/variant.js b/src/civic/variant.js index f66c011b..c916976e 100644 --- a/src/civic/variant.js +++ b/src/civic/variant.js @@ -275,7 +275,7 @@ const uploadNormalizedVariant = async (conn, normalizedVariant, feature) => { } catch (err) { try { variantType = await conn.getVocabularyTerm(normalizedVariant.type || content.type); - } catch { + } catch (e) { throw new Error(`Unable to upload CIVIC variant (${normalizedVariant}})`); } } @@ -396,7 +396,7 @@ const processVariantRecord = async (conn, civicVariantRecord, feature) => { } } catch (err) { VARIANT_CACHE.set(JSON.stringify(rawVariant), { err }); - throw err + throw err; } VARIANT_CACHE.set(JSON.stringify(rawVariant), { result }); From 933aa23dd92a6881809ce4ceeb1b1d9dcbf7d6f0 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 10:15:20 -0800 Subject: [PATCH 40/52] Fix error msg in util.js::requestWithRetry() --- src/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.js b/src/util.js index 45c492ab..0a4a6823 100644 --- a/src/util.js +++ b/src/util.js @@ -175,7 +175,7 @@ const requestWithRetry = async (requestOpt, { waitSeconds = 2, retries = 1, useC } catch (err) { if (err.statusCode === HTTP_STATUS_CODES.TOO_MANY_REQUESTS && retries > 0) { await sleep(waitSeconds); - logger.warn(`TIMEOUT, retrying request ${requestOpt.url}`); + logger.warn(`TIMEOUT, retrying request ${requestOpt.uri} ${JSON.stringify(requestOpt.qs)}`); return requestWithRetry(requestOpt, { retries: retries - 1, waitSeconds }); } throw err; From 248f7f796bd4224dc5a863462d2d3f2575caf4c8 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 10:49:28 -0800 Subject: [PATCH 41/52] Update parser to v2.1.1 and add toJSON() method --- package-lock.json | 76 +++++++++++++++++----------- package.json | 2 +- src/PMC4232638/index.js | 7 ++- src/cancergenomeinterpreter/index.js | 13 +++-- src/cancerhotspots/index.js | 11 ++-- src/cgl/index.js | 8 +-- src/civic/evidenceItem.js | 2 +- src/civic/profile.js | 2 +- src/civic/publication.js | 2 +- src/civic/relevance.js | 2 +- src/civic/variant.js | 18 ++++--- src/cosmic/resistance.js | 11 ++-- src/docm/index.js | 9 ++-- src/entrez/snp.js | 11 ++-- src/moa/index.js | 15 +++--- src/oncokb/index.js | 17 ++++--- src/util.js | 44 ++++++++++++++++ src/variants/index.js | 7 ++- 18 files changed, 174 insertions(+), 83 deletions(-) diff --git a/package-lock.json b/package-lock.json index 674875bd..4e380348 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "8.0.2", "license": "GPL-3", "dependencies": { - "@bcgsc-pori/graphkb-parser": "^1.1.1", + "@bcgsc-pori/graphkb-parser": "^2.1.0", "@bcgsc-pori/graphkb-schema": "^3.14.3", "ajv": "^6.10.0", "argparse": "^2.0.1", @@ -609,9 +609,9 @@ } }, "node_modules/@bcgsc-pori/graphkb-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@bcgsc-pori/graphkb-parser/-/graphkb-parser-1.1.1.tgz", - "integrity": "sha512-xh6hl+FQpAY9evB1O9hsG5LLr7bP1z1uOA4zVCsyJ0WUPTc7+NST1zGOSDGCLolJeq/mI4x4UeTaShKjSGxwhw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@bcgsc-pori/graphkb-parser/-/graphkb-parser-2.1.0.tgz", + "integrity": "sha512-EIVRjRdqJv7RjtvZ+wK3qQDLORPAuKoqFkGUg/pHU3JnpgQMXgeOEHBfuwh6U+P09oY1TQdspS7+vUjpINapBg==", "dependencies": { "json-cycle": "^1.3.0" } @@ -631,6 +631,14 @@ "@bcgsc-pori/graphkb-parser": ">=1.0.0 <2.0.0" } }, + "node_modules/@bcgsc-pori/graphkb-schema/node_modules/@bcgsc-pori/graphkb-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@bcgsc-pori/graphkb-parser/-/graphkb-parser-1.1.3.tgz", + "integrity": "sha512-qy86oMsygnWlS5oEONpMSI96XcIgK8//RvYfYxA/6Yy0XuDbbTG9YF6lqyylT9YPiAfpQau5QZTAWEPCpPD5jA==", + "dependencies": { + "json-cycle": "^1.3.0" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -3127,9 +3135,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -9873,13 +9881,13 @@ "dev": true }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" @@ -10330,9 +10338,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -12219,9 +12227,9 @@ } }, "@bcgsc-pori/graphkb-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@bcgsc-pori/graphkb-parser/-/graphkb-parser-1.1.1.tgz", - "integrity": "sha512-xh6hl+FQpAY9evB1O9hsG5LLr7bP1z1uOA4zVCsyJ0WUPTc7+NST1zGOSDGCLolJeq/mI4x4UeTaShKjSGxwhw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@bcgsc-pori/graphkb-parser/-/graphkb-parser-2.1.0.tgz", + "integrity": "sha512-EIVRjRdqJv7RjtvZ+wK3qQDLORPAuKoqFkGUg/pHU3JnpgQMXgeOEHBfuwh6U+P09oY1TQdspS7+vUjpINapBg==", "requires": { "json-cycle": "^1.3.0" } @@ -12236,6 +12244,16 @@ "lodash.omit": "4.5.0", "uuid": "3.3.2", "uuid-validate": "0.0.3" + }, + "dependencies": { + "@bcgsc-pori/graphkb-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@bcgsc-pori/graphkb-parser/-/graphkb-parser-1.1.3.tgz", + "integrity": "sha512-qy86oMsygnWlS5oEONpMSI96XcIgK8//RvYfYxA/6Yy0XuDbbTG9YF6lqyylT9YPiAfpQau5QZTAWEPCpPD5jA==", + "requires": { + "json-cycle": "^1.3.0" + } + } } }, "@bcoe/v8-coverage": { @@ -14225,9 +14243,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -19421,13 +19439,13 @@ "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.3", + "picomatch": "^2.3.1" } }, "mime-db": { @@ -19776,9 +19794,9 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pirates": { diff --git a/package.json b/package.json index b4b59389..4ef77ca7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "private": true, "license": "GPL-3", "dependencies": { - "@bcgsc-pori/graphkb-parser": "^1.1.1", + "@bcgsc-pori/graphkb-parser": "^2.1.0", "@bcgsc-pori/graphkb-schema": "^3.14.3", "ajv": "^6.10.0", "argparse": "^2.0.1", diff --git a/src/PMC4232638/index.js b/src/PMC4232638/index.js index 1f69050b..5334b3b8 100644 --- a/src/PMC4232638/index.js +++ b/src/PMC4232638/index.js @@ -1,12 +1,15 @@ const readXlsxFile = require('read-excel-file/node'); -const kbParser = require('@bcgsc-pori/graphkb-parser'); +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); const { logger } = require('../logging'); const { rid } = require('../graphkb'); const _pubmed = require('../entrez/pubmed'); const _entrezGene = require('../entrez/gene'); const { PMC4232638: SOURCE_DEFN } = require('../sources'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const TP53_COLS = { DOM: 'Functional categories for TP53 - Dominant negative activity', @@ -134,7 +137,7 @@ const uploadFile = async ({ conn, filename }) => { logger.info(`loading: ${row.Gene}:${row['Amino acid change']}`); try { - const parsed = kbParser.variant.parse(`p.${row['Amino acid change']}`, false).toJSON(); + const parsed = parseVariant(`p.${row['Amino acid change']}`, false).toJSON(); const [gene] = await _entrezGene.fetchAndLoadBySymbol(conn, row.Gene); const relevance = await conn.getVocabularyTerm(row.relevance); const evidence = await _pubmed.fetchAndLoadByIds(conn, row.evidence); diff --git a/src/cancergenomeinterpreter/index.js b/src/cancergenomeinterpreter/index.js index 2c69dd42..d07638fa 100644 --- a/src/cancergenomeinterpreter/index.js +++ b/src/cancergenomeinterpreter/index.js @@ -1,6 +1,9 @@ const fs = require('fs'); -const kbParser = require('@bcgsc-pori/graphkb-parser'); +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const { loadDelimToJson, @@ -217,7 +220,7 @@ const processVariants = async ({ conn, row, source }) => { } if (genomic && !isCat) { - const parsed = kbParser.variant.parse(genomic).toJSON(); + const parsed = parseVariant(genomic).toJSON(); const reference1 = await conn.getUniqueRecordBy({ filters: { AND: [ @@ -242,7 +245,7 @@ const processVariants = async ({ conn, row, source }) => { } if (protein && !isCat) { - const parsed = kbParser.variant.parse(`${gene}:${protein.split(':')[1]}`).toJSON(); + const parsed = parseVariant(`${gene}:${protein.split(':')[1]}`).toJSON(); const type = await conn.getVocabularyTerm(parsed.type); proteinVariant = await conn.addVariant({ content: { ...parsed, reference1: rid(gene1Record), type }, @@ -251,7 +254,7 @@ const processVariants = async ({ conn, row, source }) => { }); } if (transcript && cds && !isCat) { - const parsed = kbParser.variant.parse(`${transcript}:${cds}`).toJSON(); + const parsed = parseVariant(`${transcript}:${cds}`).toJSON(); const reference1 = await conn.getUniqueRecordBy({ filters: { AND: [{ biotype: 'transcript' }, { sourceId: transcript }, { sourceIdVersion: null }] }, sort: orderPreferredOntologyTerms, @@ -265,7 +268,7 @@ const processVariants = async ({ conn, row, source }) => { }); } if (exonic && !isCat) { - const parsed = kbParser.variant.parse(`${gene}:${exonic}`).toJSON(); + const parsed = parseVariant(`${gene}:${exonic}`).toJSON(); const type = await conn.getVocabularyTerm(parsed.type); exonicVariant = await conn.addVariant({ content: { ...parsed, reference1: rid(gene1Record), type }, diff --git a/src/cancerhotspots/index.js b/src/cancerhotspots/index.js index 9225c4b8..e048be4b 100644 --- a/src/cancerhotspots/index.js +++ b/src/cancerhotspots/index.js @@ -5,7 +5,10 @@ const fs = require('fs'); const csv = require('fast-csv'); -const { variant: { parse: variantParser } } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const { convertRowFields, @@ -101,7 +104,7 @@ const processVariants = async ({ conn, record, source }) => { // deletion notation = `${notation}${start}_${stop}del${refSeq}`; } - const variant = variantParser(notation).toJSON(); + const variant = parseVariant(notation).toJSON(); variant.reference1 = rid(reference1); variant.type = rid(await conn.getVocabularyTerm(variant.type)); @@ -125,7 +128,7 @@ const processVariants = async ({ conn, record, source }) => { [reference1] = await _entrezGene.fetchAndLoadByIds(conn, [geneId]); featureCache[geneId] = reference1; } - const variant = variantParser( + const variant = parseVariant( protein.replace(/fs\*\?$/, 'fs'), // ignore uncertain truncations false, ).toJSON(); @@ -163,7 +166,7 @@ const processVariants = async ({ conn, record, source }) => { featureCache[transcriptId] = reference1; } // parse the cds variant - const variant = variantParser(cds, false).toJSON(); + const variant = parseVariant(cds, false).toJSON(); variant.reference1 = reference1; variant.type = rid(await conn.getVocabularyTerm(variant.type)); diff --git a/src/cgl/index.js b/src/cgl/index.js index cac1b51f..56cca0d5 100644 --- a/src/cgl/index.js +++ b/src/cgl/index.js @@ -1,6 +1,6 @@ const fs = require('fs'); -const { variant: { parse: variantParser } } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { loadDelimToJson, @@ -46,7 +46,7 @@ const loadCdsVariant = async (graphkbConn, transcriptId, cdsNotation) => { // add the cds variant const { noFeatures, multiFeature, prefix, ...variant - } = variantParser(cdsNotation, false); + } = parseVariant(cdsNotation, false); variant.reference1 = reference1; variant.type = rid(await graphkbConn.getVocabularyTerm(variant.type)); const cds = rid(await graphkbConn.addVariant({ @@ -87,7 +87,7 @@ const loadProteinVariant = async (graphkbConn, gene, proteinNotation) => { // add the cds variant const { noFeatures, multiFeature, prefix, ...variant - } = variantParser(proteinNotation, false); + } = parseVariant(proteinNotation, false); variant.reference1 = reference1; variant.type = rid(await graphkbConn.getVocabularyTerm(variant.type)); const protein = rid(await graphkbConn.addVariant({ @@ -163,7 +163,7 @@ const loadGenomicVariant = async (graphkbConn, chromosome, position, ref, alt) = // add the cds variant const { noFeatures, multiFeature, prefix, ...variant - } = variantParser(notation, false); + } = parseVariant(notation, false); variant.reference1 = reference1; variant.type = rid(await graphkbConn.getVocabularyTerm(variant.type)); const genomic = rid(await graphkbConn.addVariant({ diff --git a/src/civic/evidenceItem.js b/src/civic/evidenceItem.js index 2178cb39..e54619e9 100644 --- a/src/civic/evidenceItem.js +++ b/src/civic/evidenceItem.js @@ -3,7 +3,7 @@ const path = require('path'); const _ = require('lodash'); const Ajv = require('ajv'); -const { error: { ErrorMixin } } = require('@bcgsc-pori/graphkb-parser'); +const { ErrorMixin } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec, request } = require('../util'); const { logger } = require('../logging'); diff --git a/src/civic/profile.js b/src/civic/profile.js index 4d6845d8..912c83b0 100644 --- a/src/civic/profile.js +++ b/src/civic/profile.js @@ -2,7 +2,7 @@ * Introducing Molecular Profiles with CIViC GraphQL API v2.2.0 * [EvidenceItem]--(many-to-one)--[MolecularProfile]--(many-to-many)--[Variant] */ -const { error: { ErrorMixin } } = require('@bcgsc-pori/graphkb-parser'); +const { ErrorMixin } = require('@bcgsc-pori/graphkb-parser'); class NotImplementedError extends ErrorMixin { } diff --git a/src/civic/publication.js b/src/civic/publication.js index 644111ee..33e0c58e 100644 --- a/src/civic/publication.js +++ b/src/civic/publication.js @@ -1,4 +1,4 @@ -const { error: { ErrorMixin } } = require('@bcgsc-pori/graphkb-parser'); +const { ErrorMixin } = require('@bcgsc-pori/graphkb-parser'); const _asco = require('../asco'); const _pubmed = require('../entrez/pubmed'); diff --git a/src/civic/relevance.js b/src/civic/relevance.js index 3c1bff1f..39a4c92c 100644 --- a/src/civic/relevance.js +++ b/src/civic/relevance.js @@ -1,4 +1,4 @@ -const { error: { ErrorMixin } } = require('@bcgsc-pori/graphkb-parser'); +const { ErrorMixin } = require('@bcgsc-pori/graphkb-parser'); class NotImplementedError extends ErrorMixin { } diff --git a/src/civic/variant.js b/src/civic/variant.js index c916976e..78f7b223 100644 --- a/src/civic/variant.js +++ b/src/civic/variant.js @@ -1,14 +1,17 @@ -const kbParser = require('@bcgsc-pori/graphkb-parser'); +const { ErrorMixin, ParsingError, parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); const { rid } = require('../graphkb'); const _entrezGene = require('../entrez/gene'); const _snp = require('../entrez/snp'); const { civic: SOURCE_DEFN } = require('../sources'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); -const { error: { ErrorMixin, ParsingError } } = kbParser; class NotImplementedError extends ErrorMixin { } const VARIANT_CACHE = new Map(); + // based on discussion with cam here: https://www.bcgsc.ca/jira/browse/KBDEV-844 const SUBS = { 'E746_T751>I': 'E746_T751delinsI', @@ -223,11 +226,11 @@ const normalizeVariantRecord = ({ // try parser fallback for notation that is close to correct try { - kbParser.variant.parse(name, false); + parseVariant(name, false); return [{ positional: true, reference1: { ...referenceGene }, variant: name }]; } catch (err) { try { - kbParser.variant.parse(`p.${name}`, false); + parseVariant(`p.${name}`, false); return [{ positional: true, reference1: { ...referenceGene }, @@ -261,10 +264,9 @@ const uploadNormalizedVariant = async (conn, normalizedVariant, feature) => { } else { let content = {}; - if (normalizedVariant.positional) { - content = kbParser.variant.parse(normalizedVariant.variant, false).toJSON(); - } - let variantType; + if (normalizedVariant.positional) { + content = parseVariant(normalizedVariant.variant, false).toJSON(); + } // try to fetch civic specific term first try { diff --git a/src/cosmic/resistance.js b/src/cosmic/resistance.js index 5ff8e29e..1570830d 100644 --- a/src/cosmic/resistance.js +++ b/src/cosmic/resistance.js @@ -3,7 +3,10 @@ */ const fs = require('fs'); -const { variant: { parse: variantParser } } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const { loadDelimToJson, @@ -77,7 +80,7 @@ const processVariants = async ({ conn, record, source }) => { try { // add the protein variant with its protein translation - const variant = variantParser(record.protein, false).toJSON(); + const variant = parseVariant(record.protein, false).toJSON(); variant.type = rid(await conn.getVocabularyTerm(variant.type)); const reference1 = rid(await _ensembl.fetchAndLoadById( @@ -113,7 +116,7 @@ const processVariants = async ({ conn, record, source }) => { // create the cds variant if (record.cds && record.cds.trim()) { try { - const variant = variantParser(record.cds, false).toJSON(); + const variant = parseVariant(record.cds, false).toJSON(); // get the ensembl transcript const reference1 = rid(await _ensembl.fetchAndLoadById( conn, @@ -143,7 +146,7 @@ const processVariants = async ({ conn, record, source }) => { // add the genomic representation if (record.genomic) { try { - const variant = variantParser(record.genomic, false).toJSON(); + const variant = parseVariant(record.genomic, false).toJSON(); // get the chromosome const reference1 = rid(await conn.getUniqueRecordBy({ filters: { diff --git a/src/docm/index.js b/src/docm/index.js index 4b7d5f60..08732105 100644 --- a/src/docm/index.js +++ b/src/docm/index.js @@ -6,7 +6,10 @@ const Ajv = require('ajv'); const fs = require('fs'); -const { variant: { parse: variantParser } } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const { checkSpec, request } = require('../util'); const { @@ -107,7 +110,7 @@ const processVariants = async ({ conn, source, record: docmRecord }) => { try { // create the protein variant const [reference1] = await _gene.fetchAndLoadBySymbol(conn, gene); - let variant = variantParser(parseDocmVariant(aminoAcid), false).toJSON(); + let variant = parseVariant(parseDocmVariant(aminoAcid), false).toJSON(); const type = await conn.getVocabularyTerm(variant.type); protein = variant = await conn.addVariant({ content: { ...variant, reference1: rid(reference1), type: rid(type) }, @@ -121,7 +124,7 @@ const processVariants = async ({ conn, source, record: docmRecord }) => { try { // create the genomic variant - let variant = variantParser(buildGenomicVariant(docmRecord), false).toJSON(); + let variant = parseVariant(buildGenomicVariant(docmRecord), false).toJSON(); const type = await conn.getVocabularyTerm(variant.type); const reference1 = await conn.getUniqueRecordBy({ filters: { diff --git a/src/entrez/snp.js b/src/entrez/snp.js index 6611913b..362ac3f4 100644 --- a/src/entrez/snp.js +++ b/src/entrez/snp.js @@ -1,7 +1,6 @@ const Ajv = require('ajv'); -const { variant: { parse: variantParser } } = require('@bcgsc-pori/graphkb-parser'); - +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec } = require('../util'); const { fetchByIdList, uploadRecord, preLoadCache: preLoadAnyCache, BASE_FETCH_URL, @@ -11,6 +10,10 @@ const entrezGene = require('./gene'); const { rid } = require('../graphkb'); const { logger } = require('../logging'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); + const ajv = new Ajv(); const { dbSnp: SOURCE_DEFN } = require('../sources'); @@ -49,7 +52,7 @@ const loadFromDocsumHgvs = async (api, hgvsVariants) => { try { if (hgvsVariants.cds) { - const parsed = variantParser(hgvsVariants.cds.split('|')[0], true).toJSON(); + const parsed = parseVariant(hgvsVariants.cds.split('|')[0], true).toJSON(); const [transcript] = await refseq.fetchAndLoadByIds(api, [parsed.reference1]); const type = await api.getVocabularyTerm(parsed.type); cds = await api.addVariant({ @@ -65,7 +68,7 @@ const loadFromDocsumHgvs = async (api, hgvsVariants) => { try { if (hgvsVariants.protein) { const gene = hgvsVariants.protein.split('|').find(p => p.startsWith('GENE=')); - const parsed = variantParser(hgvsVariants.protein.split('|')[0], true).toJSON(); + const parsed = parseVariant(hgvsVariants.protein.split('|')[0], true).toJSON(); const [reference1] = await refseq.fetchAndLoadByIds(api, [parsed.reference1]); const type = await api.getVocabularyTerm(parsed.type); protein = await api.addVariant({ diff --git a/src/moa/index.js b/src/moa/index.js index 3455000e..7f314c56 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -1,6 +1,9 @@ - const Ajv = require('ajv'); -const kbParser = require('@bcgsc-pori/graphkb-parser'); + +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const { checkSpec, requestWithRetry } = require('../util'); const { moa: SOURCE_DEFN } = require('../sources'); @@ -59,7 +62,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { // create the genomic variant if we have the appropriate fields if (!['reference_allele', 'alternate_allele', 'start_position', 'end_position', 'chromosome'].some(v => moaVariant[v] === null)) { - const hgvsg = kbParser.variant.parse(composeGenomicHgvs(moaVariant), false).toJSON(); + const hgvsg = parseVariant(composeGenomicHgvs(moaVariant), false).toJSON(); const chromosome = await conn.getUniqueRecordBy({ filters: { AND: [ @@ -85,7 +88,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { // create the cds variant if (moaVariant.cdna_change !== null && moaVariant.cdna_change !== '') { - const hgvsc = kbParser.variant.parse(moaVariant.cdna_change, false).toJSON(); + const hgvsc = parseVariant(moaVariant.cdna_change, false).toJSON(); const cdsType = rid(await conn.getVocabularyTerm(hgvsc.type)); cdsVariant = rid(await conn.addVariant({ content: { @@ -98,7 +101,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { // create the protein variant if (moaVariant.protein_change !== null && moaVariant.protein_change !== '') { - const hgvsp = kbParser.variant.parse(moaVariant.protein_change, false).toJSON(); + const hgvsp = parseVariant(moaVariant.protein_change, false).toJSON(); const proteinType = rid(await conn.getVocabularyTerm(hgvsp.type)); proteinVariant = rid(await conn.addVariant({ content: { @@ -129,7 +132,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { } else { variantType = await conn.getVocabularyTerm('mutation'); } - const parsed = kbParser.variant.parse(`e.${exonNumber}mut`, false).toJSON(); + const parsed = parseVariant(`e.${exonNumber}mut`, false).toJSON(); exonVariant = await conn.addVariant({ content: { ...parsed, diff --git a/src/oncokb/index.js b/src/oncokb/index.js index 38d59129..a6498496 100644 --- a/src/oncokb/index.js +++ b/src/oncokb/index.js @@ -5,7 +5,10 @@ const Ajv = require('ajv'); const fs = require('fs'); const path = require('path'); -const kbParser = require('@bcgsc-pori/graphkb-parser'); +const { ParsingError, parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); const { checkSpec, @@ -132,7 +135,7 @@ const parseVariantName = (variantIn, { reference1 } = {}) => { const variant = variantIn.toLowerCase().trim(); try { - kbParser.variant.parse(`p.${variant}`, false); + parseVariant(`p.${variant}`, false); return { type: `p.${variant}` }; } catch (err) { } let match = /^([a-z])?(\d+)_([a-z])?(\d+)splice$/.exec(variant); @@ -276,11 +279,11 @@ const processVariant = async (conn, { if (!variant) { try { - variant = kbParser.variant.parse(type, false).toJSON(); + variant = parseVariant(type, false).toJSON(); } catch (err) { try { // try with adding a p prefix also - variant = kbParser.variant.parse(`p.${type}`, false).toJSON(); + variant = parseVariant(`p.${type}`, false).toJSON(); } catch (err2) { } logger.warn(`failed to parse the variant (${type}) for record (gene=${gene}, variant=${variantName})`); throw err; @@ -303,7 +306,7 @@ const processVariant = async (conn, { // create the variant for (const [key, value] of Object.entries(variant)) { - if (value instanceof kbParser.position.Position) { + if (value.pos) { variant[key] = value.toJSON(); } } @@ -327,7 +330,7 @@ const processVariant = async (conn, { try { // try with adding a p prefix also - const parsed = kbParser.variant.parse(altVariantName, false).toJSON(); + const parsed = parseVariant(altVariantName, false).toJSON(); parsed.reference1 = rid(reference1); parsed.type = rid(await getVocabulary(conn, parsed.type)); const altVariant = rid(await conn.addVariant({ @@ -617,7 +620,7 @@ const addEvidenceLevels = async (conn, proxy, source) => { for (let [level, desc] of Object.entries(levels)) { if (!/^LEVEL_[A-Z0-9]+$/.exec(level)) { - throw new kbParser.error.ParsingError({ + throw new ParsingError({ expected: '/^LEVEL_[A-Z0-9]+$/', message: `Error in parsing the level name: ${level}`, observed: level, diff --git a/src/util.js b/src/util.js index 0a4a6823..32238712 100644 --- a/src/util.js +++ b/src/util.js @@ -225,6 +225,49 @@ const convertRowFields = (header, row) => { return result; }; +/** + * Decorator function to add toJSON() method to parseVariant returned object + * (from graphkb-parser v1 not avail. anymore in v2.1.1) + */ +function parseVariantDecorator(parseVariant) { + // Method + function toJSON() { + const positionToJSON = (position) => { + const json = {}; + + for (const [attr, value] of Object.entries(position)) { + if (value !== null && !['prefix', 'longRefAA'].includes(attr)) { + json[attr] = value; + } + } + return json; + }; + + const json = {}; + const IGNORE = ['prefix', 'multiFeature', 'noFeatures', 'notationType', 'toJSON']; + + for (const [attr, value] of Object.entries(this)) { + if (value !== undefined && !IGNORE.includes(attr)) { + if (value.pos) { + json[attr] = positionToJSON(value); + } else { + json[attr] = value; + } + } + } + return json; + } + + return function (...args) { + const result = parseVariant(...args); + + if (!('toJSON' in result) || typeof result.toJSON !== 'function') { + result.toJSON = toJSON; + } + return result; + }; +} + module.exports = { checkSpec, @@ -235,6 +278,7 @@ module.exports = { loadDelimToJson, loadXmlToJson, logger, + parseVariantDecorator, parseXmlToJson, request, requestWithRetry, diff --git a/src/variants/index.js b/src/variants/index.js index b7966754..c2aa2a52 100644 --- a/src/variants/index.js +++ b/src/variants/index.js @@ -1,11 +1,14 @@ const fs = require('fs'); -const { variant: { parse: parseVariant } } = require('@bcgsc-pori/graphkb-parser'); - +const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); const { logger } = require('../logging'); const { orderPreferredOntologyTerms, rid } = require('../graphkb'); const { fetchAndLoadBySymbol } = require('../entrez/gene'); +const { parseVariantDecorator } = require('../util'); + +const parseVariant = parseVariantDecorator(parseVariantOriginal); + const getEntrezGene = async (conn, name) => { try { From 80b2182cb47b424096e9c4340a4b26c0b23fa0c8 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 11:04:57 -0800 Subject: [PATCH 42/52] Linting moa & ncit index.js --- src/moa/index.js | 4 ++-- src/ncit/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/moa/index.js b/src/moa/index.js index 7f314c56..df50c4d1 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -264,19 +264,19 @@ const loadVariant = async (conn, moaVariant) => { try { signature = await conn.getUniqueRecordBy({ - target: 'Signature', filters: { AND: [ { source: { - target: 'Source', filters: { name: 'cosmic' }, + target: 'Source', }, }, { sourceId: moaVariant.cosmic_signature }, { sourceIdVersion: '3' }, ], }, + target: 'Signature', }); } catch (err) { // Enforcing usage of v3 Cosmic signatures diff --git a/src/ncit/index.js b/src/ncit/index.js index a85a2411..807c110d 100644 --- a/src/ncit/index.js +++ b/src/ncit/index.js @@ -180,8 +180,8 @@ const cleanRawRow = (rawRow) => { : `${row.name} [${sourceId}]`, endpoint, name: row.name.toLowerCase(), - sourceId, original_synonyms: row.synonyms, + sourceId, synonyms: Array.from(new Set(row.synonyms)) .map(s => s.toLowerCase()) .filter(s => s !== row.name.toLowerCase()), From a807e82adb14062287c44f4206ae27c03775cd74 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 11:06:02 -0800 Subject: [PATCH 43/52] Update civic specs validation --- src/civic/specs.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/civic/specs.json b/src/civic/specs.json index 740e28cc..9fc1a3db 100644 --- a/src/civic/specs.json +++ b/src/civic/specs.json @@ -118,7 +118,7 @@ "__typename": { "type": "string" }, - "entrezId": { + "id": { "type": "number" }, "name": { @@ -127,7 +127,7 @@ }, "required":[ "__typename", - "entrezId", + "id", "name" ], "type": "object" From 85632e4fcfb6834f50ffedebce4032c3b015f4fc Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 11:06:52 -0800 Subject: [PATCH 44/52] Update civic graphql query for factor & fusion --- src/civic/evidenceItems.graphql | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/civic/evidenceItems.graphql b/src/civic/evidenceItems.graphql index 2d98ddbd..e9dca1d5 100644 --- a/src/civic/evidenceItems.graphql +++ b/src/civic/evidenceItems.graphql @@ -81,9 +81,27 @@ query evidenceItems( feature { featureInstance { __typename - ... on Factor { id } + ... on Factor { + id + name + } + ... on Fusion { + fivePrimeGene { + entrezId + id + name + } + id + name + threePrimeGene { + entrezId + id + name + } + } ... on Gene { entrezId + id name } } From 8d9ae69e937e2f6afb5d0370b55ee032758439e4 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 11:09:03 -0800 Subject: [PATCH 45/52] Refactoring normalization and upload of civic variants --- src/civic/evidenceItem.js | 57 ++--- src/civic/variant.js | 467 +++++++++++++++++++++++++++----------- 2 files changed, 356 insertions(+), 168 deletions(-) diff --git a/src/civic/evidenceItem.js b/src/civic/evidenceItem.js index e54619e9..81d68780 100644 --- a/src/civic/evidenceItem.js +++ b/src/civic/evidenceItem.js @@ -3,21 +3,17 @@ const path = require('path'); const _ = require('lodash'); const Ajv = require('ajv'); -const { ErrorMixin } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec, request } = require('../util'); const { logger } = require('../logging'); const { civic: SOURCE_DEFN } = require('../sources'); const { EvidenceItem: evidenceSpec } = require('./specs.json'); -const _entrezGene = require('../entrez/gene'); -const { processVariantRecord } = require('./variant'); +const { normalizeVariant, uploadVariants } = require('./variant'); const { processMolecularProfile } = require('./profile'); const { addOrFetchTherapy, resolveTherapies } = require('./therapy'); const { rid } = require('../graphkb'); -class NotImplementedError extends ErrorMixin { } - // Spec compiler const ajv = new Ajv(); const validateEvidenceSpec = ajv.compile(evidenceSpec); @@ -114,6 +110,7 @@ const downloadEvidenceItems = async (url, trustedCurators) => { return { errors, records: validatedRecords }; }; + /** * Format one combination from a CIViC EvidenceItem into an object * ready to be compared with a corresponding GraphKB statement @@ -150,40 +147,18 @@ const processCombination = async (conn, { } // VARIANTS - // Note: the combination can have more than 1 variant - // if the Molecular profile was using AND operators + // The combination can have 1 or more CIViC variant(s), + // each of which can be normalized into 1 or more GraphKB variant(s). const { variants: civicVariants } = rawRecord; - const variants = []; - - for (const variant of civicVariants) { - // Variant's Feature - const { feature: { featureInstance } } = variant; - - // TODO: Deal with __typename === 'Factor'. No actual case as April 22nd, 2024 - if (featureInstance.__typename !== 'Gene') { - throw new NotImplementedError( - 'unable to process variant\'s feature of type other than Gene (e.g. Factor)', - ); - } + const normalizedVariants = []; + const uploadedVariants = []; - let feature; - - try { - [feature] = await _entrezGene.fetchAndLoadByIds(conn, [featureInstance.entrezId]); - } catch (err) { - logger.error(`failed to fetch variant's feature: ${featureInstance.entrezId}`); - throw err; - } - - // Variant - try { - const processedVariants = await processVariantRecord(conn, variant, feature); - logger.verbose(`converted variant name (${variant.name}) to variants (${processedVariants.map(v => v.displayName).join(', and ')})`); - variants.push(...processedVariants); - } catch (err) { - throw new Error(`unable to process the variant (id=${variant.id}, name=${variant.name})`); - } + // Normalize + for (const record of civicVariants) { + normalizedVariants.push(...await normalizeVariant(record)); } + // Upload + uploadedVariants.push(...await uploadVariants(conn, normalizedVariants)); /* FORMATTING CONTENT FOR GRAPHKB STATEMENT @@ -220,12 +195,12 @@ const processCombination = async (conn, { // Adding feature (reference1) or Variant (1st variant as the default) as subject. if (rawRecord.evidenceType === 'FUNCTIONAL') { - content.subject = rid(variants[0].reference1); + content.subject = rid(uploadedVariants[0].reference1); } if (rawRecord.evidenceType === 'ONCOGENIC') { - content.subject = variants.length === 1 - ? rid(variants[0]) - : rid(variants[0].reference1); + content.subject = uploadedVariants.length === 1 + ? rid(uploadedVariants[0]) + : rid(uploadedVariants[0].reference1); } // Checking for Subject @@ -235,7 +210,7 @@ const processCombination = async (conn, { // CONDITIONS // Adding variants as conditions - content.conditions = [...variants.map(v => rid(v))]; + content.conditions = [...uploadedVariants.map(v => rid(v))]; // Adding Disease as condition if (content.disease) { diff --git a/src/civic/variant.js b/src/civic/variant.js index 78f7b223..346a3a23 100644 --- a/src/civic/variant.js +++ b/src/civic/variant.js @@ -3,6 +3,8 @@ const { rid } = require('../graphkb'); const _entrezGene = require('../entrez/gene'); const _snp = require('../entrez/snp'); const { civic: SOURCE_DEFN } = require('../sources'); +const { logger } = require('../logging'); + const { parseVariantDecorator } = require('../util'); const parseVariant = parseVariantDecorator(parseVariantOriginal); @@ -52,20 +54,31 @@ const compareGeneNames = (gene1, gene2) => { }; /** - * Given a CIViC Variant record entrez information and name, - * normalize into a set of graphkb-style variants + * Normalize CIViC Gene Variant record as GraphKB positional and/or category variant(s) * * @param {object} param0 * @param {string} param0.name * @param {string} param0.entrezId * @param {string} param0.entrezName - * @returns {object} + * @returns {object[]} */ -const normalizeVariantRecord = ({ +const normalizeGeneVariant = ({ name: rawName, entrezId, entrezName: rawEntrezName, }) => { - const entrezName = rawEntrezName.toLowerCase().trim(); + // Exceptions: unsupported/unimplemented CIViC variant nomenclature + if ([ + 'Non-V600', + 'P-Loop Mutation', + ].includes(rawName)) { + throw new NotImplementedError( + `unable to process CIViC variant ${rawEntrezName} ${rawName}`, + ); + } + + // Substitutions: harcoded fix for known 'CIViC-to-GraphKB' correspondances let name = SUBS[rawName] || rawName; + + const entrezName = rawEntrezName.toLowerCase().trim(); const joiner = ' and '; name = name.replace(' + ', joiner); name = name.replace('; ', joiner).toLowerCase().trim(); @@ -76,7 +89,7 @@ const normalizeVariantRecord = ({ if (name.includes(joiner)) { const result = []; name.split(joiner).forEach((n) => { - result.push(...normalizeVariantRecord({ entrezId, entrezName, name: n.trim() })); + result.push(...normalizeGeneVariant({ entrezId, entrezName, name: n.trim() })); }); return result; } @@ -156,8 +169,8 @@ const normalizeVariantRecord = ({ rest = { positional: true, variant: `fusion(e.${exon1},e.${exon2})` }; } else { return [ - ...normalizeVariantRecord({ entrezId, entrezName, name: `${gene1}-${gene2}` }), - ...normalizeVariantRecord({ entrezId, entrezName, name: tail }), + ...normalizeGeneVariant({ entrezId, entrezName, name: `${gene1}-${gene2}` }), + ...normalizeGeneVariant({ entrezId, entrezName, name: tail }), ]; } } @@ -213,8 +226,8 @@ const normalizeVariantRecord = ({ } if (match = /^(\w+\s+fusion)\s+([a-z]\d+\S+)$/i.exec(name)) { const [, fusion, resistanceMutation] = match; const result = []; - result.push(...normalizeVariantRecord({ entrezId, entrezName, name: fusion })); - result.push(...normalizeVariantRecord({ entrezId, entrezName, name: resistanceMutation })); + result.push(...normalizeGeneVariant({ entrezId, entrezName, name: fusion })); + result.push(...normalizeGeneVariant({ entrezId, entrezName, name: resistanceMutation })); return result; } if (match = /^(.*)\s+mutations?$/.exec(name)) { const [, gene] = match; @@ -241,173 +254,373 @@ const normalizeVariantRecord = ({ return [{ reference1: { ...referenceGene }, type: name }]; }; + /** - * Given some normalized variant record from CIViC, - * load into graphkb, create links and return the record + * Normalize CIViC Factors variant record as GraphKB Signatures/signature's CVs * - * @param {ApiConnection} conn the connection to GraphKB - * @param {Object} normalizedVariant the normalized variant record - * @param {Object} feature the gene feature already grabbed from GraphKB + * @param {object} record the raw variant record from CIViC * @returns {object[]} */ -const uploadNormalizedVariant = async (conn, normalizedVariant, feature) => { - let result; +const normalizeFactorVariant = (record) => { + const { feature: { featureInstance } } = record; - if (!normalizedVariant.positional && /^\s*rs\d+\s*$/gi.exec(normalizedVariant.type)) { - const [rsVariant] = await _snp.fetchAndLoadByIds(conn, [normalizedVariant.type]); + switch (featureInstance.name) { + case 'TMB': + return [{ + reference1: { + class: 'Signature', // flag to escape gene fetching/upload + name: 'high mutation burden', + }, + type: 'high signature', + }]; + // TODO: Add support for other factors + case 'Methylation signature': + case 'Kataegis': + case 'CK': + default: + throw new NotImplementedError( + `unable to process Factor ${featureInstance.name} ${record.name}`, + ); + } +}; - if (rsVariant) { - result = rsVariant; - } else { - throw new Error(`unable to fetch variant by RSID (${normalizedVariant.type})`); + +/** + * Normalize CIViC Fusion variant record as GraphKB CVs + * + * @param {object} record the raw variant record from CIViC + * @returns {object[]} array of 1 normalized variant + */ +const normalizeFusionVariant = (record) => { + const { + feature: { + featureInstance: { + fivePrimeGene, + threePrimeGene, + }, + }, + } = record; + + if (fivePrimeGene && threePrimeGene) { + return [{ + reference1: { + name: fivePrimeGene.name.toLowerCase().trim(), + sourceId: `${fivePrimeGene.entrezId || ''}`, + }, + reference2: { + name: threePrimeGene.name.toLowerCase().trim(), + sourceId: `${threePrimeGene.entrezId || ''}`, + }, + type: 'fusion', + }]; + } + if (fivePrimeGene) { + return [{ + reference1: { + name: fivePrimeGene.name.toLowerCase().trim(), + sourceId: `${fivePrimeGene.entrezId || ''}`, + }, + type: 'fusion', + }]; + } + if (threePrimeGene) { + return [{ + reference1: { + name: threePrimeGene.name.toLowerCase().trim(), + sourceId: `${threePrimeGene.entrezId || ''}`, + }, + type: 'fusion', + }]; + } + throw new Error('fivePrimeGene and/or threePrimeGene expected on Fusion variant'); +}; + + +/** + * Given a CIViC variant record, do the normalization based on the feature type. + * Can be more than 1 "GraphKB-normalized" variant per CIViC variant. + * Returns the normalized variant(s). + * + * @param {Object} record the raw variant record from CIViC + * @returns {object[]} array of normalized variant(s) + */ +const normalizeVariant = (record) => { + try { + const { feature: { featureInstance } } = record; + const featureType = featureInstance.__typename; + + switch (featureType) { + case 'Gene': + // reformatting passed args for legacy purpose + return normalizeGeneVariant({ + entrezId: featureInstance.entrezId, + entrezName: featureInstance.name, + name: record.name, + }); + case 'Factor': + return normalizeFactorVariant(record); + case 'Fusion': + return normalizeFusionVariant(record); + default: + throw new NotImplementedError( + `unable to process variant's feature of type ${featureType}`, + ); } - } else { - let content = {}; + } catch (err) { + logger.error(`unable to normalize the variant (id=${record.id}, name=${record.name})`); + throw err; + } +}; - if (normalizedVariant.positional) { - content = parseVariant(normalizedVariant.variant, false).toJSON(); + +/** + * Get reference records for the new variant. + * Upload if needed (only if gene; signatures needs to be creates using the ontology loader) + * + * @param {ApiConnection} conn the connection to GraphKB + * @param {Object} normalizedVariant the normalized variant record + */ +const uploadReferences = async (conn, normalizedVariant) => { + const { reference1: r1, reference2: r2 } = normalizedVariant; + + // r2 can be undefined, r1 cannot + if (!r1) { + // Shouldn't happen; means there is an error in the normalization code + throw new Error('reference1 is mandatory on normalizedVariant'); } - // try to fetch civic specific term first + // Signature (from civic Factor) as reference + if (r1.class === 'Signature') { try { - variantType = await conn.getVocabularyTerm( - normalizedVariant.type || content.type, - SOURCE_DEFN.name, - ); + return [await conn.getUniqueRecordBy({ + filters: { name: r1.name }, + neighbors: 0, + target: r1.class, + })]; } catch (err) { - try { - variantType = await conn.getVocabularyTerm(normalizedVariant.type || content.type); - } catch (e) { - throw new Error(`Unable to upload CIVIC variant (${normalizedVariant}})`); - } + throw new Error(`failed to fetch variant's ${r1.class} Reference ${r1.name}`); } - content.type = rid(variantType); + } - // get the reference elements - let reference2, - reference1 = feature; + // Gene(s) as reference(s) + const references = []; - if (normalizedVariant.reference2) { - if (normalizedVariant.reference2.sourceId === feature.sourceId) { - reference2 = feature; - // fetch reference1 - [reference1] = await _entrezGene.fetchAndLoadBySymbol(conn, normalizedVariant.reference1.name); + for (const ref of [r1, r2]) { + if (ref) { + let reference; - if (!reference1) { - throw new Error(`Gene name not found in NCBI's Entrez gene database (${normalizedVariant.reference1.name}})`); + try { + if (ref.sourceId) { + [reference] = await _entrezGene.fetchAndLoadByIds(conn, [ref.sourceId]); } - } else if (normalizedVariant.reference1.sourceId !== feature.sourceId) { - throw new ParsingError(`Feature ID input (${feature.sourceId}) does not match the linked gene IDs (${normalizedVariant.reference1.sourceId},${normalizedVariant.reference2.sourceId})`); - } else { - // fetch reference2 - [reference2] = await _entrezGene.fetchAndLoadBySymbol(conn, normalizedVariant.reference2.name); + if (!ref.sourceId && ref.name) { + [reference] = await _entrezGene.fetchAndLoadBySymbol(conn, ref.name); + } + if (!ref.sourceId && !ref.name) { + // Shouldn't happen; means there is an error in the normalization code + throw new Error('name property is mandatory on normalizedVariant reference'); + } + references.push(reference); + } catch (err) { + logger.error(`failed to fetch variant's feature: ${ref.name}`); + throw err; } } + } + return references; +}; - content.reference1 = rid(reference1); - if (reference2) { - content.reference2 = rid(reference2); - } - result = await conn.addVariant({ - content, - existsOk: true, - target: normalizedVariant.positional - ? 'PositionalVariant' - : 'CategoryVariant', - }); - } +/** + * Get or create inferred/inferring variant(s) and create linking Infers edge(s) + * + * @param {ApiConnection} conn the connection to GraphKB + * @param {Object} normalizedVariant the normalized variant record + * @param {Object} result the GraphKB variant record to connect edges from/to + * @returns {object[]} + */ +const uploadInferences = async (conn, normalizedVariant, result) => { + const links = { inferredBy: [], infers: [] }; + const variants = { inferred: [], inferring: [] }; - // now create any links + // Outgoing, if any for (const variant of normalizedVariant.infers || []) { - const infers = await uploadNormalizedVariant(conn, variant, feature); - await conn.addRecord({ - content: { in: rid(infers), out: rid(result) }, - existsOk: true, - fetchExisting: false, - target: 'Infers', - }); + try { + // Creates or get the variant on the incomming side + const infers = await uploadVariant(conn, variant); + variants.inferred.push(infers); + + // Creates the edge + links.infers.push( + await conn.addRecord({ + content: { in: rid(infers), out: rid(result) }, + existsOk: true, + fetchExisting: false, + target: 'Infers', + }), + ); + } catch (err) { + // Non-blocking error + logger.warn(`Error while uploading inferred variant; ${JSON.stringify(variant)}`); + } } + // Incomming, if any for (const variant of normalizedVariant.inferredBy || []) { - const inferredBy = await uploadNormalizedVariant(conn, variant, feature); - await conn.addRecord({ - content: { in: rid(result), out: rid(inferredBy) }, - existsOk: true, - fetchExisting: false, - target: 'Infers', - }); + try { + // Creates or get the variant on the outgoing side + const inferredBy = await uploadVariant(conn, variant); + variants.inferring.push(inferredBy); + + // Creates the edge + links.inferredBy.push( + await conn.addRecord({ + content: { in: rid(result), out: rid(inferredBy) }, + existsOk: true, + fetchExisting: false, + target: 'Infers', + }), + ); + } catch (err) { + // Non-blocking error + logger.warn(`Error while uploading inferring variant; ${JSON.stringify(variant)}`); + } } - return result; + // Return for testing purpose only + return { links, variants }; }; + /** - * Given some variant record and a feature, process the variant and return a GraphKB equivalent + * Given a normalized CIViC variant record, upload to GraphKB, + * create any given links and return the GraphKB variant record. * * @param {ApiConnection} conn the connection to GraphKB - * @param {Object} civicVariantRecord the raw variant record from CIViC - * @param {Object} feature the gene feature already grabbed from GraphKB + * @param {Object} normalizedVariant the normalized variant record * @returns {object[]} */ -const processVariantRecord = async (conn, civicVariantRecord, feature) => { - const { feature: { featureInstance } } = civicVariantRecord; - let entrezId, - entrezName; - - // featureInstance - if (featureInstance.__typename === 'Gene') { - entrezId = featureInstance.entrezId; - entrezName = featureInstance.name; - } else if (featureInstance.__typename === 'Factor') { - // TODO: Deal with __typename === 'Factor' - // No actual case as April 22nd, 2024 - throw new NotImplementedError( - 'unable to process variant\'s feature of type Factor', +const uploadVariant = async (conn, normalizedVariant) => { + let uploadedVariant; + + // RSID Variant exception handled first + if (!normalizedVariant.positional && /^\s*rs\d+\s*$/gi.exec(normalizedVariant.type)) { + // Create Variant VERTEX in GraphKB + [uploadedVariant] = await _snp.fetchAndLoadByIds(conn, [normalizedVariant.type]); + + if (uploadedVariant) { + // Create Inferring/inferred variant and Infers edge in GraphKB + if (normalizedVariant.infers || normalizedVariant.inferredBy) { + await uploadInferences(conn, normalizedVariant, uploadedVariant); + } + } else { + throw new Error(`unable to fetch variant by RSID (${normalizedVariant.type})`); + } + return uploadedVariant; + } + + // Variant content + let content = {}; + + if (normalizedVariant.positional) { + content = parseVariant(normalizedVariant.variant, false).toJSON(); + } + + // Variant type + let variantType; + + try { + // try to fetch civic specific term first + variantType = await conn.getVocabularyTerm( + normalizedVariant.type || content.type, + SOURCE_DEFN.name, ); + } catch (err) { + // try to fetch term from any source + variantType = await conn.getVocabularyTerm(normalizedVariant.type || content.type); } + content.type = rid(variantType); - // Raw variant from CIViC to normalize & upload to GraphKB if needed - const rawVariant = { - entrezId, - entrezName, - name: civicVariantRecord.name, - }; + // Variant references + const [reference1, reference2] = await uploadReferences(conn, normalizedVariant); + content.reference1 = rid(reference1); - // Trying cache first - const fromCache = VARIANT_CACHE.get(JSON.stringify(rawVariant)); + if (reference2) { + content.reference2 = rid(reference2); + } - if (fromCache) { - if (fromCache.err) { - throw new Error('Variant record previously processed with errors'); - } - if (fromCache.result) { - return fromCache.result; - } + // Create Variant VERTEX in GraphKB + uploadedVariant = await conn.addVariant({ + content, + existsOk: true, + target: normalizedVariant.positional + ? 'PositionalVariant' + : 'CategoryVariant', + }); + + // Create Inferring/inferred variant and Infers edge in GraphKB + if (normalizedVariant.infers || normalizedVariant.inferredBy) { + await uploadInferences(conn, normalizedVariant, uploadedVariant); } - const result = []; + return uploadedVariant; +}; + - try { - // Normalizing - const variants = normalizeVariantRecord(rawVariant); +/** + * Upload an array of normalized CIViC variants to GraphKB. + * Returns an array of corresponding GraphKB Variant record(s). + * + * @param {ApiConnection} conn the connection to GraphKB + * @param {Object[]} normalizedVariants an array of normalized CIViC variant records + * @returns {object[]} + */ +const uploadVariants = async (conn, normalizedVariants) => { + const uploadedVariants = []; + + for (const normalizedVariant of normalizedVariants) { + // console.log(JSON.stringify(normalizedVariant)); + + // Trying cache first + const key = JSON.stringify(normalizedVariant); + const fromCache = VARIANT_CACHE.get(key); + + if (fromCache) { + if (fromCache.err) { + throw new Error('Variant record previously processed with errors'); + } + if (fromCache.uploaded) { + uploadedVariants.push(fromCache.uploaded); + continue; + } + } // Uploading - for (const normalizedVariant of variants) { - result.push(await uploadNormalizedVariant(conn, normalizedVariant, feature)); + try { + const uploaded = await uploadVariant(conn, normalizedVariant); + uploadedVariants.push(uploaded); + VARIANT_CACHE.set(key, { uploaded }); + } catch (err) { + VARIANT_CACHE.set(key, { err }); + logger.error(`failed to upload variant ${JSON.stringify(normalizedVariant)}`); + throw err; } - } catch (err) { - VARIANT_CACHE.set(JSON.stringify(rawVariant), { err }); - throw err; } - VARIANT_CACHE.set(JSON.stringify(rawVariant), { result }); - return result; + // console.log({uploadedVariants: uploadedVariants[0]['@rid']}); + return uploadedVariants; }; + module.exports = { + NotImplementedError, compareGeneNames, - normalizeVariantRecord, - processVariantRecord, - uploadNormalizedVariant, + normalizeFactorVariant, + normalizeFusionVariant, + normalizeGeneVariant, + normalizeVariant, + uploadInferences, + uploadReferences, + uploadVariant, + uploadVariants, }; From de8551412daef971404bac84a4491e83eed07289 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 11:09:22 -0800 Subject: [PATCH 46/52] Linting civic index.js --- src/civic/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/civic/index.js b/src/civic/index.js index 262e1d2a..aa0f3228 100644 --- a/src/civic/index.js +++ b/src/civic/index.js @@ -56,10 +56,10 @@ const incrementCounts = (initial, updates) => { * * @param {object} param0 * @param {ApiConnection} param0.conn the api connection object for GraphKB - * @param {?boolean} param0.deleteDeprecated deletion of existing GraphKB Statements related to deprecated evidence(s) + * @param {?boolean} param0.deleteDeprecated delete GraphKB Statements if deprecated evidence(s) * @param {string} param0.errorLogPrefix prefix to the generated error json file * @param {number} param0.maxRecords limit of EvidenceItem records to be processed and upload - * @param {?boolean} param0.noDeleteOnUnmatched no deletion of existing GraphKB Statements related to unmatched combination(s) + * @param {?boolean} param0.noDeleteOnUnmatched don't delete GraphKB St. if unmatched combination(s) * @param {?boolean} param0.noUpdate no update of existing GraphKB Statements * @param {string[]} param0.trustedCurators a list of curator IDs for submitted-only EvidenceItems * @param {?string} param0.url url to use as the base for accessing the civic ApiConnection From e23f2d022773970de5dcb675c7f2076ab1cc33b9 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 16 Dec 2024 11:09:43 -0800 Subject: [PATCH 47/52] Add tests for civic variants --- test/civic/civic.variant.test.js | 395 ++++++++++++++++++++++++++----- 1 file changed, 342 insertions(+), 53 deletions(-) diff --git a/test/civic/civic.variant.test.js b/test/civic/civic.variant.test.js index 4814157c..833a9c23 100644 --- a/test/civic/civic.variant.test.js +++ b/test/civic/civic.variant.test.js @@ -1,9 +1,129 @@ /* eslint-disable jest/no-disabled-tests */ -const { normalizeVariantRecord } = require('../../src/civic/variant'); +const { + normalizeFactorVariant, + normalizeFusionVariant, + normalizeGeneVariant, + normalizeVariant, + NotImplementedError, + uploadInferences, + uploadReferences, + uploadVariant, + uploadVariants, +} = require('../../src/civic/variant'); + + +/* + SYNCHRONOUS TESTS +*/ + +const civicVariantRecordsFactor = [ + { + feature: { featureInstance: { __typename: 'Factor', name: 'TMB' } }, + id: 123, + name: 'abc', + }, +]; +const civicVariantRecordsFusion = [ + { + feature: { + featureInstance: { + __typename: 'Fusion', + fivePrimeGene: { + entrezId: 673, + id: 5, + name: 'BRAF', + }, + }, + }, + id: 123, + }, + { + feature: { + featureInstance: { + __typename: 'Fusion', + threePrimeGene: { + entrezId: 238, + id: 1, + name: 'ALK', + }, + }, + }, + id: 123, + }, + { + feature: { + featureInstance: { + __typename: 'Fusion', + fivePrimeGene: { + entrezId: 673, + id: 5, + name: 'BRAF', + }, + threePrimeGene: { + entrezId: 238, + id: 1, + name: 'ALK', + }, + }, + }, + id: 123, + }, +]; +const civicVariantRecordsGene = [ + { + feature: { featureInstance: { __typename: 'Gene', entrezId: 672, name: 'BRCA1' } }, + name: 'Mutation', + }, +]; + + +describe('normalizeFactorVariant', () => { + test('testnormalizeFactorVariant', () => { + const normalizedVariants = normalizeFactorVariant(civicVariantRecordsFactor[0]); + expect(normalizedVariants.length).toEqual(1); + expect(normalizedVariants[0]).toEqual({ + reference1: { + class: 'Signature', + name: 'high mutation burden', + }, + type: 'high signature', + }); + }); +}); + +describe('normalizeFusionVariant', () => { + test('testnormalizeFusionVariantFivePrimeGeneOnly', () => { + const normalizedVariants = normalizeFusionVariant(civicVariantRecordsFusion[0]); + expect(normalizedVariants.length).toEqual(1); + expect(normalizedVariants[0]).toEqual({ + reference1: { name: 'braf', sourceId: '673' }, + type: 'fusion', + }); + }); + + test('testnormalizeFusionVariantThreePrimeGeneOnly', () => { + const normalizedVariants = normalizeFusionVariant(civicVariantRecordsFusion[1]); + expect(normalizedVariants.length).toEqual(1); + expect(normalizedVariants[0]).toEqual({ + reference1: { name: 'alk', sourceId: '238' }, + type: 'fusion', + }); + }); -describe('normalizeVariantRecord', () => { + test('testnormalizeFusionVariantBothGenes', () => { + const normalizedVariants = normalizeFusionVariant(civicVariantRecordsFusion[2]); + expect(normalizedVariants.length).toEqual(1); + expect(normalizedVariants[0]).toEqual({ + reference1: { name: 'braf', sourceId: '673' }, + reference2: { name: 'alk', sourceId: '238' }, + type: 'fusion', + }); + }); +}); + +describe('normalizeGeneVariant', () => { test('exon mutation', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'gene', name: 'EXON 12 MUTATION', @@ -19,7 +139,7 @@ describe('normalizeVariantRecord', () => { }); test('deleterious mutation', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'gene', name: 'DELETRIOUS MUTATION', @@ -31,7 +151,7 @@ describe('normalizeVariantRecord', () => { }); test('phosphorylation variant', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'gene', name: 'Y1234 phosphorylation', @@ -44,7 +164,7 @@ describe('normalizeVariantRecord', () => { }); test('single gene fusion with missense mutation', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'ALK FUSION G1202R', @@ -63,7 +183,7 @@ describe('normalizeVariantRecord', () => { }); test('multi-gene fusion with 2 resistance mutations (dash notation)', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'alk', name: 'EML4-ALK G1202R-L1198F', @@ -88,7 +208,7 @@ describe('normalizeVariantRecord', () => { }); test('multi-gene fusion', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NRG1', name: 'CD74-NRG1', @@ -103,7 +223,7 @@ describe('normalizeVariantRecord', () => { }); test('fusion with multiple variants', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NTRK1', name: 'LMNA-NTRK1 G595R AND G667C', @@ -128,7 +248,7 @@ describe('normalizeVariantRecord', () => { }); test('fusion with multiple variants (colon sep)', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NTRK1', name: 'LMNA::NTRK1 G595R AND G667C', @@ -154,7 +274,7 @@ describe('normalizeVariantRecord', () => { test('corrects deprecated indel syntax', () => { // S111C (c.330CA>TT) - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NTRK1', name: 'S111C (c.330CA>TT)', @@ -173,17 +293,8 @@ describe('normalizeVariantRecord', () => { ]); }); - test.skip('multiple variants with plus notation', () => { - // V600E+V600M - // E2014K + E2419K - }); - - test.skip('missense and amplification', () => { - // V600E AMPLIFICATION - }); - test('categorical variant', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NTRK1', name: 'UNDEREXPRESSION', @@ -198,7 +309,7 @@ describe('normalizeVariantRecord', () => { test('protein truncation with cds notation', () => { // e46* (c.136g>t) - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'E46* (c.136G>T)', @@ -220,7 +331,7 @@ describe('normalizeVariantRecord', () => { }); test('categorical variant with spaces', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NTRK1', name: 'DNA BINDING DOMAIN MUTATION', @@ -235,7 +346,7 @@ describe('normalizeVariantRecord', () => { test('regular missense mutation', () => { // R132H - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NTRK1', name: 'R132H', @@ -251,7 +362,7 @@ describe('normalizeVariantRecord', () => { test('plural for single gene fusion', () => { // ALK FUSIONS - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'NRG1', name: 'NRG1 fusions', @@ -267,7 +378,7 @@ describe('normalizeVariantRecord', () => { test('fusion with exon positions', () => { // EML4-ALK E20;A20 // ALK FUSIONS - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'EML4-ALK E20;A20', @@ -285,7 +396,7 @@ describe('normalizeVariantRecord', () => { test('fusion with new exon notation', () => { // EWSR1-FLI1 e7-e6 // FLI1 Fusion - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'FLI1', name: 'EWSR1-FLI1 e7-e6', @@ -303,7 +414,7 @@ describe('normalizeVariantRecord', () => { test('fusion with reference2 input gene', () => { // EML4-ALK E20;A20 // ALK FUSIONS - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'EML4', name: 'EML4-ALK E20;A20', @@ -320,7 +431,7 @@ describe('normalizeVariantRecord', () => { test('abl fusion', () => { // BCR-ABL - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ABL1', name: 'BCR-ABL', @@ -336,7 +447,7 @@ describe('normalizeVariantRecord', () => { test('cds notation', () => { // BCR-ABL - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ABL1', name: 'c.123G>T', @@ -352,7 +463,7 @@ describe('normalizeVariantRecord', () => { test('exon range deletion', () => { // BCR-ABL - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ABL1', name: 'exon 2-3 deletion', @@ -367,7 +478,7 @@ describe('normalizeVariantRecord', () => { }); test('frameshift with cds', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 't133lfs*26 (c.397dela)', @@ -389,7 +500,7 @@ describe('normalizeVariantRecord', () => { }); test('protein indel with cds', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 't133lfs*26 (c.397dela)', @@ -412,7 +523,7 @@ describe('normalizeVariantRecord', () => { test('simple gene mutation', () => { // BCR-ABL - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ABL1', name: 'ABL1 mutations', @@ -426,7 +537,7 @@ describe('normalizeVariantRecord', () => { }); test('exon plural mutations', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ABL1', name: 'exon 3 mutations', @@ -441,7 +552,7 @@ describe('normalizeVariantRecord', () => { }); test('mutations', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ABL1', name: 'mutations', @@ -454,13 +565,9 @@ describe('normalizeVariantRecord', () => { ]); }); - test.skip('germline notation', () => { - // DPYD*2A HOMOZYGOSITY - }); - test('splice site mutation', () => { // F547 SPLICE SITE MUTATION - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'F547 SPLICE SITE MUTATION', @@ -477,7 +584,7 @@ describe('normalizeVariantRecord', () => { test('protein deletion with cds deletion sequence', () => { // r79_s80del (c.236_241delgcagtc) // r82_v84del (c.244_252del) - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'r79_s80del (c.236_241delgcagtc)', @@ -499,7 +606,7 @@ describe('normalizeVariantRecord', () => { }); test('protein deletion with cds deletion no sequence', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'r82_v84del (c.244_252del)', @@ -522,7 +629,7 @@ describe('normalizeVariantRecord', () => { test('protein dup with cds dup', () => { // p.s193_c196dupstsc (c.577_588dupagcaccagctgc) - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'p.s193_c196dupstsc (c.577_588dupagcaccagctgc)', @@ -545,7 +652,7 @@ describe('normalizeVariantRecord', () => { test('protein with cds notation', () => { // A122I (c.364_365GC>AT) - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'A122I (c.364_365GC>AT)', @@ -568,7 +675,7 @@ describe('normalizeVariantRecord', () => { test('OR-able position no alt seq', () => { // G12/G13 - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'G12/G13', @@ -582,13 +689,9 @@ describe('normalizeVariantRecord', () => { ]); }); - test.skip('catalogue variant', () => { - // RS3910384 - }); - test('semi-colon delimited variants', () => { // A50A (c.150C>G); Splicing alteration (c.463-1G>T) - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ALK', name: 'A50A (c.150C>G); Splicing alteration (c.463-1G>T)', @@ -618,6 +721,23 @@ describe('normalizeVariantRecord', () => { ]); }); + test.skip('multiple variants with plus notation', () => { + // V600E+V600M + // E2014K + E2419K + }); + + test.skip('missense and amplification', () => { + // V600E AMPLIFICATION + }); + + test.skip('germline notation', () => { + // DPYD*2A HOMOZYGOSITY + }); + + test.skip('catalogue variant', () => { + // RS3910384 + }); + test.skip('duplicate fusion', () => { // AGGF1-PDGFRB, AGGF1-PDGFRB C843G }); @@ -628,7 +748,7 @@ describe('normalizeVariantRecord', () => { describe('bad notation should return as vocabulary', () => { test('ERBB2 G776INSV_G/C', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ERBB2', name: 'ERBB2 G776INSV_G/C', @@ -640,7 +760,7 @@ describe('normalizeVariantRecord', () => { }); test('exon1 151nt del; Null (Partial deletion of Exon 1)', () => { - const variants = normalizeVariantRecord({ + const variants = normalizeGeneVariant({ entrezId: 1, entrezName: 'ERBB2', name: 'exon1 151nt del; Null (Partial deletion of Exon 1)', @@ -655,3 +775,172 @@ describe('normalizeVariantRecord', () => { }); }); }); + +describe('normalizeVariant', () => { + [ + civicVariantRecordsFactor[0], + civicVariantRecordsFusion[0], + civicVariantRecordsGene[0], + + ].forEach((record) => { + test(`testNormalizeVariantFeatureType${record.feature.featureInstance.__typename}`, () => { + expect(normalizeVariant(record).length).toBe(1); + }); + }); + + test('testNormalizeVariantFeatureTypeNotImplemented', () => { + expect(() => { + normalizeVariant( + { feature: { featureInstance: { __typename: 'Other' } } }, + ); + }).toThrow(NotImplementedError); + }); +}); + + +/* + ASYNCHRONOUS TESTS +*/ + +const mockConn = () => ({ + addRecord: jest.fn().mockResolvedValue({ '@rid': '#', reference1: '#' }), // used by Entrez loader + addSource: jest.fn().mockResolvedValue({ '@rid': '#', reference1: '#' }), // used by Entrez loader + addVariant: jest.fn().mockResolvedValue({ '@rid': '#123:45' }), + getUniqueRecordBy: jest.fn().mockResolvedValue({ '@rid': '#678:90', reference1: '#' }), + getVocabularyTerm: jest.fn().mockResolvedValue({ '@rid': '#' }), +}); +const conn = mockConn(); + + +describe.skip('uploadReferences', () => { + const normalizedVariants = [ + { }, + { reference1: { } }, + { reference1: { class: 'Signature', name: '' } }, + { reference1: { sourceId: '123' } }, + { reference1: { name: 'abc' } }, + { reference1: { sourceId: '123' }, reference2: { sourceId: '456' } }, + ]; + + test('testUploadReferencesNoReference1', async () => { + await expect( + uploadReferences(conn, normalizedVariants[0]), + ).rejects.toThrow('reference1 is mandatory on normalizedVariant'); + }); + + test('testUploadReferencesNoName', async () => { + await expect( + uploadReferences(conn, normalizedVariants[1]), + ).rejects.toThrow('name property is mandatory on normalizedVariant reference'); + }); + + test('testUploadReferencesSignature', async () => { + const [reference1, reference2] = await uploadReferences(conn, normalizedVariants[2]); + expect(reference1).toEqual({ '@rid': '#678:90', reference1: '#' }); + expect(reference2).toEqual(undefined); + }); + + test('testUploadReferencesWithSourceId', async () => { + const [reference1, reference2] = await uploadReferences(conn, normalizedVariants[3]); + expect(reference1).toEqual({ '@rid': '#678:90', reference1: '#' }); + expect(reference2).toEqual(undefined); + }); + + test('testUploadReferencesWithName', async () => { + const [reference1, reference2] = await uploadReferences(conn, normalizedVariants[4]); + expect(reference1).toEqual({ '@rid': '#678:90', reference1: '#' }); + expect(reference2).toEqual(undefined); + }); + + test('testUploadReferencesWithReference2', async () => { + const [reference1, reference2] = await uploadReferences(conn, normalizedVariants[5]); + expect(reference1).toEqual({ '@rid': '#678:90', reference1: '#' }); + expect(reference2).toEqual({ '@rid': '#678:90', reference1: '#' }); + }); +}); + +describe.skip('uploadInferences', () => { + const normalizedVariants = [ + { + infers: [ + { reference1: { name: '...' }, type: '...' }, + { reference1: { name: '...' }, type: '...' }, + ], + }, + { + inferredBy: [ + { reference1: { name: '...' }, type: '...' }, + { reference1: { name: '...' }, type: '...' }, + { reference1: { name: '...' }, type: '...' }, + ], + }, + ]; + + test('testUploadInferencesInfers', async () => { + const { links, variants } = await uploadInferences(conn, normalizedVariants[0], { '@rid': '#' }); + expect(links.infers.length).toEqual(2); + expect(variants.inferred.length).toEqual(2); + }); + + test('testUploadInferencesInferredBy', async () => { + const { links, variants } = await uploadInferences(conn, normalizedVariants[1], { '@rid': '#' }); + expect(links.inferredBy.length).toEqual(3); + expect(variants.inferring.length).toEqual(3); + }); +}); + +describe.skip('uploadVariant', () => { + const normalizedVariants = [ + { type: 'rs123' }, + { positional: true, reference1: { name: 'egfr', sourceId: 1956 }, variant: 'c.1del' }, + { reference1: { name: 'egfr', sourceId: 1956 }, type: 'mutation' }, + ]; + + test('testUploadVariantRSID', async () => { + const result = await uploadVariant(conn, normalizedVariants[0]); + expect(result).toEqual({ '@rid': '#678:90', reference1: '#' }); + }); + + test('testUploadVariantPositional', async () => { + const result = await uploadVariant(conn, normalizedVariants[1]); + expect(result).toEqual({ '@rid': '#123:45' }); + }); + + test('testUploadVariantCategory', async () => { + const result = await uploadVariant(conn, normalizedVariants[2]); + expect(result).toEqual({ '@rid': '#123:45' }); + }); +}); + +describe('uploadVariants', () => { + const normalizedVariants = [ + // Factor + { + reference1: { + class: 'Signature', + name: 'high mutation burden', + }, + type: 'high signature', + }, + // Fusion + { + reference1: { name: 'braf', sourceId: '673' }, + reference2: { name: 'alk', sourceId: '238' }, + type: 'fusion', + }, + // Gene + { + reference1: { name: 'braf', sourceId: '673' }, + type: 'mutation', + }, + ]; + + test('testuploadVariants', async () => { + const uploadedVariants = await uploadVariants(conn, normalizedVariants); + expect(uploadedVariants.length).toEqual(3); + + for (let i = 0; i < uploadedVariants.length; i++) { + expect(uploadedVariants[i]).toEqual({ '@rid': '#123:45' }); + } + }); +}); From b70cc9a6966ac8df301712289da0a3244b9f1bee Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 3 Jan 2025 12:57:29 -0800 Subject: [PATCH 48/52] Revert parseVariantDecorator and use jsonifyVariant instead --- src/PMC4232638/index.js | 8 ++--- src/cancergenomeinterpreter/index.js | 13 ++++---- src/cancerhotspots/index.js | 13 ++++---- src/cgl/index.js | 8 ++--- src/civic/variant.js | 14 +++++---- src/cosmic/resistance.js | 11 +++---- src/docm/index.js | 9 ++---- src/entrez/snp.js | 10 ++----- src/moa/index.js | 13 ++++---- src/oncokb/index.js | 11 +++---- src/util.js | 44 ---------------------------- src/variants/index.js | 8 ++--- 12 files changed, 45 insertions(+), 117 deletions(-) diff --git a/src/PMC4232638/index.js b/src/PMC4232638/index.js index 5334b3b8..979d7846 100644 --- a/src/PMC4232638/index.js +++ b/src/PMC4232638/index.js @@ -1,16 +1,12 @@ const readXlsxFile = require('read-excel-file/node'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { logger } = require('../logging'); const { rid } = require('../graphkb'); const _pubmed = require('../entrez/pubmed'); const _entrezGene = require('../entrez/gene'); const { PMC4232638: SOURCE_DEFN } = require('../sources'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); - const TP53_COLS = { DOM: 'Functional categories for TP53 - Dominant negative activity', GOF: 'Functional categories for TP53 - Gain of function', @@ -137,7 +133,7 @@ const uploadFile = async ({ conn, filename }) => { logger.info(`loading: ${row.Gene}:${row['Amino acid change']}`); try { - const parsed = parseVariant(`p.${row['Amino acid change']}`, false).toJSON(); + const parsed = jsonifyVariant(parseVariant(`p.${row['Amino acid change']}`, false)); const [gene] = await _entrezGene.fetchAndLoadBySymbol(conn, row.Gene); const relevance = await conn.getVocabularyTerm(row.relevance); const evidence = await _pubmed.fetchAndLoadByIds(conn, row.evidence); diff --git a/src/cancergenomeinterpreter/index.js b/src/cancergenomeinterpreter/index.js index d07638fa..42ebf0ed 100644 --- a/src/cancergenomeinterpreter/index.js +++ b/src/cancergenomeinterpreter/index.js @@ -1,9 +1,6 @@ const fs = require('fs'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { loadDelimToJson, @@ -220,7 +217,7 @@ const processVariants = async ({ conn, row, source }) => { } if (genomic && !isCat) { - const parsed = parseVariant(genomic).toJSON(); + const parsed = jsonifyVariant(parseVariant(genomic)); const reference1 = await conn.getUniqueRecordBy({ filters: { AND: [ @@ -245,7 +242,7 @@ const processVariants = async ({ conn, row, source }) => { } if (protein && !isCat) { - const parsed = parseVariant(`${gene}:${protein.split(':')[1]}`).toJSON(); + const parsed = jsonifyVariant(parseVariant(`${gene}:${protein.split(':')[1]}`)); const type = await conn.getVocabularyTerm(parsed.type); proteinVariant = await conn.addVariant({ content: { ...parsed, reference1: rid(gene1Record), type }, @@ -254,7 +251,7 @@ const processVariants = async ({ conn, row, source }) => { }); } if (transcript && cds && !isCat) { - const parsed = parseVariant(`${transcript}:${cds}`).toJSON(); + const parsed = jsonifyVariant(parseVariant(`${transcript}:${cds}`)); const reference1 = await conn.getUniqueRecordBy({ filters: { AND: [{ biotype: 'transcript' }, { sourceId: transcript }, { sourceIdVersion: null }] }, sort: orderPreferredOntologyTerms, @@ -268,7 +265,7 @@ const processVariants = async ({ conn, row, source }) => { }); } if (exonic && !isCat) { - const parsed = parseVariant(`${gene}:${exonic}`).toJSON(); + const parsed = jsonifyVariant(parseVariant(`${gene}:${exonic}`)); const type = await conn.getVocabularyTerm(parsed.type); exonicVariant = await conn.addVariant({ content: { ...parsed, reference1: rid(gene1Record), type }, diff --git a/src/cancerhotspots/index.js b/src/cancerhotspots/index.js index e048be4b..54c8b9ba 100644 --- a/src/cancerhotspots/index.js +++ b/src/cancerhotspots/index.js @@ -5,10 +5,7 @@ const fs = require('fs'); const csv = require('fast-csv'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { convertRowFields, @@ -104,7 +101,7 @@ const processVariants = async ({ conn, record, source }) => { // deletion notation = `${notation}${start}_${stop}del${refSeq}`; } - const variant = parseVariant(notation).toJSON(); + const variant = jsonifyVariant(parseVariant(notation)); variant.reference1 = rid(reference1); variant.type = rid(await conn.getVocabularyTerm(variant.type)); @@ -128,10 +125,10 @@ const processVariants = async ({ conn, record, source }) => { [reference1] = await _entrezGene.fetchAndLoadByIds(conn, [geneId]); featureCache[geneId] = reference1; } - const variant = parseVariant( + const variant = jsonifyVariant(parseVariant( protein.replace(/fs\*\?$/, 'fs'), // ignore uncertain truncations false, - ).toJSON(); + )); variant.reference1 = rid(reference1); variant.type = rid(await conn.getVocabularyTerm(variant.type)); proteinVariant = rid(await conn.addVariant({ @@ -166,7 +163,7 @@ const processVariants = async ({ conn, record, source }) => { featureCache[transcriptId] = reference1; } // parse the cds variant - const variant = parseVariant(cds, false).toJSON(); + const variant = jsonifyVariant(parseVariant(cds, false)); variant.reference1 = reference1; variant.type = rid(await conn.getVocabularyTerm(variant.type)); diff --git a/src/cgl/index.js b/src/cgl/index.js index 56cca0d5..7881af6f 100644 --- a/src/cgl/index.js +++ b/src/cgl/index.js @@ -1,6 +1,6 @@ const fs = require('fs'); -const { parseVariant } = require('@bcgsc-pori/graphkb-parser'); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { loadDelimToJson, @@ -50,7 +50,7 @@ const loadCdsVariant = async (graphkbConn, transcriptId, cdsNotation) => { variant.reference1 = reference1; variant.type = rid(await graphkbConn.getVocabularyTerm(variant.type)); const cds = rid(await graphkbConn.addVariant({ - content: { ...variant }, + content: { ...jsonifyVariant(variant) }, existsOk: true, target: 'PositionalVariant', })); @@ -91,7 +91,7 @@ const loadProteinVariant = async (graphkbConn, gene, proteinNotation) => { variant.reference1 = reference1; variant.type = rid(await graphkbConn.getVocabularyTerm(variant.type)); const protein = rid(await graphkbConn.addVariant({ - content: { ...variant }, + content: { ...jsonifyVariant(variant) }, existsOk: true, target: 'PositionalVariant', })); @@ -167,7 +167,7 @@ const loadGenomicVariant = async (graphkbConn, chromosome, position, ref, alt) = variant.reference1 = reference1; variant.type = rid(await graphkbConn.getVocabularyTerm(variant.type)); const genomic = rid(await graphkbConn.addVariant({ - content: { ...variant, assembly: 'hg19' }, + content: { ...jsonifyVariant(variant), assembly: 'hg19' }, existsOk: true, target: 'PositionalVariant', })); diff --git a/src/civic/variant.js b/src/civic/variant.js index 346a3a23..684197e2 100644 --- a/src/civic/variant.js +++ b/src/civic/variant.js @@ -1,14 +1,16 @@ -const { ErrorMixin, ParsingError, parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { + ErrorMixin, + jsonifyVariant, + parseVariant, + ParsingError, +} = require('@bcgsc-pori/graphkb-parser'); + const { rid } = require('../graphkb'); const _entrezGene = require('../entrez/gene'); const _snp = require('../entrez/snp'); const { civic: SOURCE_DEFN } = require('../sources'); const { logger } = require('../logging'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); - class NotImplementedError extends ErrorMixin { } const VARIANT_CACHE = new Map(); @@ -523,7 +525,7 @@ const uploadVariant = async (conn, normalizedVariant) => { let content = {}; if (normalizedVariant.positional) { - content = parseVariant(normalizedVariant.variant, false).toJSON(); + content = jsonifyVariant(parseVariant(normalizedVariant.variant, false)); } // Variant type diff --git a/src/cosmic/resistance.js b/src/cosmic/resistance.js index 1570830d..881b04ec 100644 --- a/src/cosmic/resistance.js +++ b/src/cosmic/resistance.js @@ -3,10 +3,7 @@ */ const fs = require('fs'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { loadDelimToJson, @@ -80,7 +77,7 @@ const processVariants = async ({ conn, record, source }) => { try { // add the protein variant with its protein translation - const variant = parseVariant(record.protein, false).toJSON(); + const variant = jsonifyVariant(parseVariant(record.protein, false)); variant.type = rid(await conn.getVocabularyTerm(variant.type)); const reference1 = rid(await _ensembl.fetchAndLoadById( @@ -116,7 +113,7 @@ const processVariants = async ({ conn, record, source }) => { // create the cds variant if (record.cds && record.cds.trim()) { try { - const variant = parseVariant(record.cds, false).toJSON(); + const variant = jsonifyVariant(parseVariant(record.cds, false)); // get the ensembl transcript const reference1 = rid(await _ensembl.fetchAndLoadById( conn, @@ -146,7 +143,7 @@ const processVariants = async ({ conn, record, source }) => { // add the genomic representation if (record.genomic) { try { - const variant = parseVariant(record.genomic, false).toJSON(); + const variant = jsonifyVariant(parseVariant(record.genomic, false)); // get the chromosome const reference1 = rid(await conn.getUniqueRecordBy({ filters: { diff --git a/src/docm/index.js b/src/docm/index.js index 08732105..c4693ee2 100644 --- a/src/docm/index.js +++ b/src/docm/index.js @@ -6,10 +6,7 @@ const Ajv = require('ajv'); const fs = require('fs'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec, request } = require('../util'); const { @@ -110,7 +107,7 @@ const processVariants = async ({ conn, source, record: docmRecord }) => { try { // create the protein variant const [reference1] = await _gene.fetchAndLoadBySymbol(conn, gene); - let variant = parseVariant(parseDocmVariant(aminoAcid), false).toJSON(); + let variant = jsonifyVariant(parseVariant(parseDocmVariant(aminoAcid), false)); const type = await conn.getVocabularyTerm(variant.type); protein = variant = await conn.addVariant({ content: { ...variant, reference1: rid(reference1), type: rid(type) }, @@ -124,7 +121,7 @@ const processVariants = async ({ conn, source, record: docmRecord }) => { try { // create the genomic variant - let variant = parseVariant(buildGenomicVariant(docmRecord), false).toJSON(); + let variant = jsonifyVariant(parseVariant(buildGenomicVariant(docmRecord), false)); const type = await conn.getVocabularyTerm(variant.type); const reference1 = await conn.getUniqueRecordBy({ filters: { diff --git a/src/entrez/snp.js b/src/entrez/snp.js index 362ac3f4..5d17d279 100644 --- a/src/entrez/snp.js +++ b/src/entrez/snp.js @@ -1,6 +1,6 @@ const Ajv = require('ajv'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec } = require('../util'); const { fetchByIdList, uploadRecord, preLoadCache: preLoadAnyCache, BASE_FETCH_URL, @@ -10,10 +10,6 @@ const entrezGene = require('./gene'); const { rid } = require('../graphkb'); const { logger } = require('../logging'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); - const ajv = new Ajv(); const { dbSnp: SOURCE_DEFN } = require('../sources'); @@ -52,7 +48,7 @@ const loadFromDocsumHgvs = async (api, hgvsVariants) => { try { if (hgvsVariants.cds) { - const parsed = parseVariant(hgvsVariants.cds.split('|')[0], true).toJSON(); + const parsed = jsonifyVariant(parseVariant(hgvsVariants.cds.split('|')[0], true)); const [transcript] = await refseq.fetchAndLoadByIds(api, [parsed.reference1]); const type = await api.getVocabularyTerm(parsed.type); cds = await api.addVariant({ @@ -68,7 +64,7 @@ const loadFromDocsumHgvs = async (api, hgvsVariants) => { try { if (hgvsVariants.protein) { const gene = hgvsVariants.protein.split('|').find(p => p.startsWith('GENE=')); - const parsed = parseVariant(hgvsVariants.protein.split('|')[0], true).toJSON(); + const parsed = jsonifyVariant(parseVariant(hgvsVariants.protein.split('|')[0], true)); const [reference1] = await refseq.fetchAndLoadByIds(api, [parsed.reference1]); const type = await api.getVocabularyTerm(parsed.type); protein = await api.addVariant({ diff --git a/src/moa/index.js b/src/moa/index.js index df50c4d1..1ba0fd31 100644 --- a/src/moa/index.js +++ b/src/moa/index.js @@ -1,9 +1,6 @@ const Ajv = require('ajv'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec, requestWithRetry } = require('../util'); const { moa: SOURCE_DEFN } = require('../sources'); @@ -62,7 +59,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { // create the genomic variant if we have the appropriate fields if (!['reference_allele', 'alternate_allele', 'start_position', 'end_position', 'chromosome'].some(v => moaVariant[v] === null)) { - const hgvsg = parseVariant(composeGenomicHgvs(moaVariant), false).toJSON(); + const hgvsg = jsonifyVariant(parseVariant(composeGenomicHgvs(moaVariant), false)); const chromosome = await conn.getUniqueRecordBy({ filters: { AND: [ @@ -88,7 +85,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { // create the cds variant if (moaVariant.cdna_change !== null && moaVariant.cdna_change !== '') { - const hgvsc = parseVariant(moaVariant.cdna_change, false).toJSON(); + const hgvsc = jsonifyVariant(parseVariant(moaVariant.cdna_change, false)); const cdsType = rid(await conn.getVocabularyTerm(hgvsc.type)); cdsVariant = rid(await conn.addVariant({ content: { @@ -101,7 +98,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { // create the protein variant if (moaVariant.protein_change !== null && moaVariant.protein_change !== '') { - const hgvsp = parseVariant(moaVariant.protein_change, false).toJSON(); + const hgvsp = jsonifyVariant(parseVariant(moaVariant.protein_change, false)); const proteinType = rid(await conn.getVocabularyTerm(hgvsp.type)); proteinVariant = rid(await conn.addVariant({ content: { @@ -132,7 +129,7 @@ const loadSmallMutation = async (conn, gene, moaVariant) => { } else { variantType = await conn.getVocabularyTerm('mutation'); } - const parsed = parseVariant(`e.${exonNumber}mut`, false).toJSON(); + const parsed = jsonifyVariant(parseVariant(`e.${exonNumber}mut`, false)); exonVariant = await conn.addVariant({ content: { ...parsed, diff --git a/src/oncokb/index.js b/src/oncokb/index.js index a6498496..2d132ba6 100644 --- a/src/oncokb/index.js +++ b/src/oncokb/index.js @@ -5,10 +5,7 @@ const Ajv = require('ajv'); const fs = require('fs'); const path = require('path'); -const { ParsingError, parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); +const { jsonifyVariant, parseVariant, ParsingError } = require('@bcgsc-pori/graphkb-parser'); const { checkSpec, @@ -279,11 +276,11 @@ const processVariant = async (conn, { if (!variant) { try { - variant = parseVariant(type, false).toJSON(); + variant = jsonifyVariant(parseVariant(type, false)); } catch (err) { try { // try with adding a p prefix also - variant = parseVariant(`p.${type}`, false).toJSON(); + variant = jsonifyVariant(parseVariant(`p.${type}`, false)); } catch (err2) { } logger.warn(`failed to parse the variant (${type}) for record (gene=${gene}, variant=${variantName})`); throw err; @@ -330,7 +327,7 @@ const processVariant = async (conn, { try { // try with adding a p prefix also - const parsed = parseVariant(altVariantName, false).toJSON(); + const parsed = jsonifyVariant(parseVariant(altVariantName, false)); parsed.reference1 = rid(reference1); parsed.type = rid(await getVocabulary(conn, parsed.type)); const altVariant = rid(await conn.addVariant({ diff --git a/src/util.js b/src/util.js index 32238712..0a4a6823 100644 --- a/src/util.js +++ b/src/util.js @@ -225,49 +225,6 @@ const convertRowFields = (header, row) => { return result; }; -/** - * Decorator function to add toJSON() method to parseVariant returned object - * (from graphkb-parser v1 not avail. anymore in v2.1.1) - */ -function parseVariantDecorator(parseVariant) { - // Method - function toJSON() { - const positionToJSON = (position) => { - const json = {}; - - for (const [attr, value] of Object.entries(position)) { - if (value !== null && !['prefix', 'longRefAA'].includes(attr)) { - json[attr] = value; - } - } - return json; - }; - - const json = {}; - const IGNORE = ['prefix', 'multiFeature', 'noFeatures', 'notationType', 'toJSON']; - - for (const [attr, value] of Object.entries(this)) { - if (value !== undefined && !IGNORE.includes(attr)) { - if (value.pos) { - json[attr] = positionToJSON(value); - } else { - json[attr] = value; - } - } - } - return json; - } - - return function (...args) { - const result = parseVariant(...args); - - if (!('toJSON' in result) || typeof result.toJSON !== 'function') { - result.toJSON = toJSON; - } - return result; - }; -} - module.exports = { checkSpec, @@ -278,7 +235,6 @@ module.exports = { loadDelimToJson, loadXmlToJson, logger, - parseVariantDecorator, parseXmlToJson, request, requestWithRetry, diff --git a/src/variants/index.js b/src/variants/index.js index c2aa2a52..8b20c575 100644 --- a/src/variants/index.js +++ b/src/variants/index.js @@ -1,14 +1,10 @@ const fs = require('fs'); -const { parseVariant: parseVariantOriginal } = require('@bcgsc-pori/graphkb-parser'); +const { jsonifyVariant, parseVariant } = require('@bcgsc-pori/graphkb-parser'); const { logger } = require('../logging'); const { orderPreferredOntologyTerms, rid } = require('../graphkb'); const { fetchAndLoadBySymbol } = require('../entrez/gene'); -const { parseVariantDecorator } = require('../util'); - -const parseVariant = parseVariantDecorator(parseVariantOriginal); - const getEntrezGene = async (conn, name) => { try { @@ -51,7 +47,7 @@ const uploadFile = async (opt) => { logger.info(`loading ${variant}`); try { - const parsed = parseVariant(variant, true).toJSON(); + const parsed = jsonifyVariant(parseVariant(variant, true)); const variantType = await conn.getVocabularyTerm(parsed.type); const reference1 = await getEntrezGene(conn, parsed.reference1); From 0ecad9a757a7f1e3e3ed42bff6f54bba68e49185 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 3 Jan 2025 13:25:23 -0800 Subject: [PATCH 49/52] npm audit fix --force w/ node v16.20.2 --- package-lock.json | 698 ++++++++++++++++++++++++++++++++++------------ package.json | 6 +- 2 files changed, 522 insertions(+), 182 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4e380348..6726e830 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "json-cycle": "^1.3.0", "json-stable-stringify": "^1.0.1", "jsonpath": "^1.1.1", - "jsonwebtoken": "^8.5.1", + "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", "node-expat": "^2.3.18", "node-fetch": "^2.6.7", @@ -31,13 +31,13 @@ "sleep-promise": "^8.0.1", "winston": "^3.2.1", "xml-stream": "^0.4.5", - "xml2js": "^0.4.19" + "xml2js": "^0.6.2" }, "devDependencies": { "eslint": "^8.17.0", "eslint-config-airbnb": "^19.0.4", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^22.20.0", + "eslint-plugin-jest": "^28.10.0", "eslint-plugin-jest-formatting": "^1.1.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.30.0", @@ -658,6 +658,24 @@ "node": ">=10.0.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -2112,6 +2130,41 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -2204,12 +2257,6 @@ "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@types/json-schema": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", - "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", - "dev": true - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2240,43 +2287,113 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz", - "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", + "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "1.13.0", - "eslint-scope": "^4.0.0" + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0" }, "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "eslint": "*" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.0.tgz", + "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz", - "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", + "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", "dev": true, "dependencies": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">=6.14.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", + "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.19.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@xmldom/xmldom": { @@ -3259,12 +3376,12 @@ } }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3275,12 +3392,6 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/decimal.js": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", @@ -3794,18 +3905,28 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "22.21.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.21.0.tgz", - "integrity": "sha512-OaqnSS7uBgcGiqXUiEnjoqxPNKvR4JWG5mSRkzVoR6+vDwlqqp11beeql1hYs0HTbdhiwrxWLxbX0Vx7roG3Ew==", + "version": "28.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.10.0.tgz", + "integrity": "sha512-hyMWUxkBH99HpXT3p8hc7REbEZK3D+nk8vHXGgpB+XXsi0gO4PxMSP+pjfUzb67GnV9yawV9a53eUmcde1CCZA==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^1.13.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { - "node": ">=6" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "eslint": ">=5" + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, "node_modules/eslint-plugin-jest-formatting": { @@ -3820,6 +3941,29 @@ "eslint": ">=0.8.0" } }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.0.tgz", + "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.19.0", + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/typescript-estree": "8.19.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", @@ -3941,19 +4085,6 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -3982,12 +4113,15 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ansi-regex": { @@ -4511,6 +4645,34 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -4526,6 +4688,15 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, + "node_modules/fastq": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -8673,21 +8844,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9494,9 +9650,9 @@ } }, "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -9507,11 +9663,11 @@ "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^5.6.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=4", - "npm": ">=1.4.28" + "node": ">=12", + "npm": ">=6" } }, "node_modules/jsx-ast-utils": { @@ -9787,12 +9943,6 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "node_modules/lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -9880,6 +10030,15 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -9942,9 +10101,9 @@ } }, "node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/n3": { "version": "1.13.0", @@ -10628,6 +10787,16 @@ "node": ">=10" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -10639,6 +10808,29 @@ "rimraf": "bin.js" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -10667,11 +10859,14 @@ } }, "node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/setimmediate": { @@ -11136,6 +11331,18 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -11201,6 +11408,20 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11678,9 +11899,9 @@ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -12272,6 +12493,15 @@ "ky-universal": "^0.8.2" } }, + "@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.4.3" + } + }, "@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -13412,6 +13642,32 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -13501,12 +13757,6 @@ "@types/istanbul-lib-coverage": "*" } }, - "@types/json-schema": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", - "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", - "dev": true - }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -13537,31 +13787,72 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, - "@typescript-eslint/experimental-utils": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz", - "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==", + "@typescript-eslint/scope-manager": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", + "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "1.13.0", - "eslint-scope": "^4.0.0" + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0" } }, + "@typescript-eslint/types": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.0.tgz", + "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", + "dev": true + }, "@typescript-eslint/typescript-estree": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz", - "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", + "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", "dev": true, "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/visitor-keys": "8.19.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "dependencies": { - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", + "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.19.0", + "eslint-visitor-keys": "^4.2.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true } } @@ -14346,20 +14637,12 @@ } }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "ms": "^2.1.3" } }, "decimal.js": { @@ -14920,12 +15203,26 @@ } }, "eslint-plugin-jest": { - "version": "22.21.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.21.0.tgz", - "integrity": "sha512-OaqnSS7uBgcGiqXUiEnjoqxPNKvR4JWG5mSRkzVoR6+vDwlqqp11beeql1hYs0HTbdhiwrxWLxbX0Vx7roG3Ew==", + "version": "28.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.10.0.tgz", + "integrity": "sha512-hyMWUxkBH99HpXT3p8hc7REbEZK3D+nk8vHXGgpB+XXsi0gO4PxMSP+pjfUzb67GnV9yawV9a53eUmcde1CCZA==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "^1.13.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "dependencies": { + "@typescript-eslint/utils": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.0.tgz", + "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.19.0", + "@typescript-eslint/types": "8.19.0", + "@typescript-eslint/typescript-estree": "8.19.0" + } + } } }, "eslint-plugin-jest-formatting": { @@ -15028,16 +15325,6 @@ "requireindex": "~1.2.0" } }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, "eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -15056,9 +15343,9 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "esm": { @@ -15307,6 +15594,30 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -15322,6 +15633,15 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, + "fastq": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -18658,15 +18978,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -19106,9 +19417,9 @@ } }, "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "requires": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -19119,7 +19430,7 @@ "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^5.6.0" + "semver": "^7.5.4" } }, "jsx-ast-utils": { @@ -19359,12 +19670,6 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -19438,6 +19743,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -19485,9 +19796,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "n3": { "version": "1.13.0", @@ -20004,6 +20315,12 @@ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -20012,6 +20329,15 @@ "glob": "^7.1.3" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -20037,9 +20363,9 @@ } }, "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" }, "setimmediate": { "version": "1.0.5", @@ -20406,6 +20732,13 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, + "ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "requires": {} + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -20458,6 +20791,13 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "peer": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -20875,9 +21215,9 @@ } }, "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", "requires": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" diff --git a/package.json b/package.json index 4ef77ca7..95922f8c 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "json-cycle": "^1.3.0", "json-stable-stringify": "^1.0.1", "jsonpath": "^1.1.1", - "jsonwebtoken": "^8.5.1", + "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", "node-expat": "^2.3.18", "node-fetch": "^2.6.7", @@ -34,13 +34,13 @@ "sleep-promise": "^8.0.1", "winston": "^3.2.1", "xml-stream": "^0.4.5", - "xml2js": "^0.4.19" + "xml2js": "^0.6.2" }, "devDependencies": { "eslint": "^8.17.0", "eslint-config-airbnb": "^19.0.4", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^22.20.0", + "eslint-plugin-jest": "^28.10.0", "eslint-plugin-jest-formatting": "^1.1.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.30.0", From a6e4290462445e6e56d8a599f3be60d868763f73 Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Fri, 3 Jan 2025 13:43:59 -0800 Subject: [PATCH 50/52] GH workflows/npm-test from v12-14-16 to v16-18-20 --- .github/workflows/npm-test.yml | 2 +- package-lock.json | 904 ++++++++++++++++++++----------- package.json | 2 +- test/civic/civic.profile.test.js | 2 +- test/loadfile.test.js | 2 +- 5 files changed, 579 insertions(+), 333 deletions(-) diff --git a/.github/workflows/npm-test.yml b/.github/workflows/npm-test.yml index a37d3efb..fa1fb316 100644 --- a/.github/workflows/npm-test.yml +++ b/.github/workflows/npm-test.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: ['12', '14', '16'] + node: [16, 18, 20] name: node-${{ matrix.node }} steps: - uses: actions/checkout@v2 diff --git a/package-lock.json b/package-lock.json index 6726e830..618d4815 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "argparse": "^2.0.1", "csv-parse": "^4.6.5", "fast-csv": "^4.3.6", + "fast-xml-parser": "^4.5.1", "html-to-text": "^5.1.1", "http-status-codes": "^1.3.2", "json-cycle": "^1.3.0", @@ -22,7 +23,6 @@ "jsonpath": "^1.1.1", "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", - "node-expat": "^2.3.18", "node-fetch": "^2.6.7", "p-limit": "^3.1.0", "parse5": "^5.1.1", @@ -676,22 +676,43 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -734,23 +755,38 @@ "integrity": "sha512-j11XSuRuAlft6vLDEX4RvhqC0KxNxx6QIyMXNb0vHHSNPXTPeiy3algESWmOOIzEtiEL0qiowPU3ewW9hHVa7Q==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { @@ -2257,6 +2293,12 @@ "@types/istanbul-lib-coverage": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2275,6 +2317,12 @@ "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -2288,16 +2336,16 @@ "dev": true }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", - "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.19.0", - "@typescript-eslint/visitor-keys": "8.19.0" + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2305,12 +2353,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.0.tgz", - "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", "dev": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2318,29 +2366,31 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", - "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.19.0", - "@typescript-eslint/visitor-keys": "8.19.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4", - "fast-glob": "^3.3.2", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { @@ -2353,9 +2403,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -2368,33 +2418,27 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", - "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.19.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } + "node_modules/@ungap/structured-clone": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true }, "node_modules/@xmldom/xmldom": { "version": "0.8.6", @@ -2422,9 +2466,9 @@ } }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2562,6 +2606,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array.prototype.flat": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", @@ -3479,6 +3532,18 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3721,46 +3786,50 @@ } }, "node_modules/eslint": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", - "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -3942,26 +4011,28 @@ } }, "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.0.tgz", - "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.19.0", - "@typescript-eslint/types": "8.19.0", - "@typescript-eslint/typescript-estree": "8.19.0" + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "semver": "^7.5.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "eslint": "^8.56.0" } }, "node_modules/eslint-plugin-jsx-a11y": { @@ -4085,31 +4156,29 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=4.0" } }, "node_modules/eslint-visitor-keys": { @@ -4206,26 +4275,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/has-flag": { @@ -4250,10 +4313,25 @@ "node": ">= 0.8.0" } }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { "deep-is": "^0.1.3", @@ -4261,12 +4339,36 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/eslint/node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4321,17 +4423,20 @@ } }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -4347,9 +4452,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -4688,6 +4793,27 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, + "node_modules/fast-xml-parser": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz", + "integrity": "sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", @@ -4913,12 +5039,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -5032,9 +5152,9 @@ "dev": true }, "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5046,11 +5166,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5245,12 +5391,12 @@ } }, "node_modules/iconv": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/iconv/-/iconv-2.3.4.tgz", - "integrity": "sha512-v2Rree7xRtrC9o3Bi9nTNOKXvApmwLFdX50k72+K1W4mJ93LBdpaLcHcInYo9gr/GcQk8MFoCetrYRcb/o3RLg==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/iconv/-/iconv-2.3.5.tgz", + "integrity": "sha512-U5ajDbtDfadp7pvUMC0F2XbkP5vQn9Xrwa6UptePl+cK8EILxapAt3sXers9B3Gxagk+zVjL2ELKuzQvyqOwug==", "hasInstallScript": true, "dependencies": { - "nan": "^2.13.1", + "nan": "^2.14.0", "safer-buffer": "^2.1.2" }, "engines": { @@ -5270,9 +5416,9 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -5575,6 +5721,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -10131,9 +10286,9 @@ } }, "node_modules/nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -10142,13 +10297,13 @@ "dev": true }, "node_modules/node-expat": { - "version": "2.3.18", - "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.3.18.tgz", - "integrity": "sha512-9dIrDxXePa9HSn+hhlAg1wXkvqOjxefEbMclGxk2cEnq/Y3U7Qo5HNNqeo3fQ4bVmLhcdt3YN1TZy7WMZy4MHw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.4.1.tgz", + "integrity": "sha512-uWgvQLgo883NKIL+66oJsK9ysKK3ej0YjVCPBZzO/7wMAuH68/Yb7+JwPWNaVq0yPaxrb48AoEXfYEc8gsmFbg==", "hasInstallScript": true, "dependencies": { "bindings": "^1.5.0", - "nan": "^2.13.2" + "nan": "^2.19.0" } }, "node_modules/node-fetch": { @@ -10490,6 +10645,15 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -10704,18 +10868,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11129,6 +11281,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -11527,12 +11684,6 @@ "resolved": "https://registry.npmjs.org/uuid-validate/-/uuid-validate-0.0.3.tgz", "integrity": "sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w==" }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", @@ -11870,7 +12021,7 @@ "node_modules/xml-stream": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/xml-stream/-/xml-stream-0.4.5.tgz", - "integrity": "sha1-dFLYWzf5uIGnDv8M90oN8CCI7es=", + "integrity": "sha512-WdMVMiYgJ2UQO2vs8CRVOd0CD0GW3AfeWHwpFJWB+bRYbnNNn88BxoYbjm0qRijceJgP1krCRwr6DgfbQKudmA==", "dependencies": { "iconv": "^2.1.4", "node-expat": "^2.3.1", @@ -11880,12 +12031,12 @@ "node_modules/xml-stream/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/xml-stream/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -11896,7 +12047,7 @@ "node_modules/xml-stream/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "node_modules/xml2js": { "version": "0.6.2", @@ -12502,16 +12653,22 @@ "eslint-visitor-keys": "^3.4.3" } }, + "@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -12519,6 +12676,12 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true + }, "@fast-csv/format": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", @@ -12561,20 +12724,26 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" } }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -13757,6 +13926,12 @@ "@types/istanbul-lib-coverage": "*" } }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -13775,6 +13950,12 @@ "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", "dev": true }, + "@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -13788,35 +13969,35 @@ "dev": true }, "@typescript-eslint/scope-manager": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", - "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", "dev": true, "requires": { - "@typescript-eslint/types": "8.19.0", - "@typescript-eslint/visitor-keys": "8.19.0" + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" } }, "@typescript-eslint/types": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.0.tgz", - "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", - "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", "dev": true, "requires": { - "@typescript-eslint/types": "8.19.0", - "@typescript-eslint/visitor-keys": "8.19.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4", - "fast-glob": "^3.3.2", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "dependencies": { "brace-expansion": { @@ -13829,9 +14010,9 @@ } }, "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -13840,23 +14021,21 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", - "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", "dev": true, "requires": { - "@typescript-eslint/types": "8.19.0", - "eslint-visitor-keys": "^4.2.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true - } + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" } }, + "@ungap/structured-clone": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true + }, "@xmldom/xmldom": { "version": "0.8.6", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz", @@ -13877,9 +14056,9 @@ } }, "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true }, "acorn-globals": { @@ -13980,6 +14159,12 @@ "is-string": "^1.0.7" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array.prototype.flat": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", @@ -14714,6 +14899,15 @@ "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -14913,46 +15107,49 @@ } }, "eslint": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", - "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "ansi-regex": { @@ -15010,22 +15207,16 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -15042,10 +15233,19 @@ "type-check": "~0.4.0" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -15053,9 +15253,24 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" } }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -15212,15 +15427,18 @@ }, "dependencies": { "@typescript-eslint/utils": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.0.tgz", - "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.19.0", - "@typescript-eslint/types": "8.19.0", - "@typescript-eslint/typescript-estree": "8.19.0" + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "semver": "^7.5.4" } } } @@ -15325,19 +15543,20 @@ "requireindex": "~1.2.0" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { - "eslint-visitor-keys": "^2.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -15354,14 +15573,14 @@ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" }, "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -15370,9 +15589,9 @@ "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs=" }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -15633,6 +15852,14 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, + "fast-xml-parser": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz", + "integrity": "sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==", + "requires": { + "strnum": "^1.0.5" + } + }, "fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", @@ -15788,12 +16015,6 @@ "functions-have-names": "^1.2.2" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -15874,19 +16095,39 @@ "dev": true }, "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -16038,11 +16279,11 @@ "dev": true }, "iconv": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/iconv/-/iconv-2.3.4.tgz", - "integrity": "sha512-v2Rree7xRtrC9o3Bi9nTNOKXvApmwLFdX50k72+K1W4mJ93LBdpaLcHcInYo9gr/GcQk8MFoCetrYRcb/o3RLg==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/iconv/-/iconv-2.3.5.tgz", + "integrity": "sha512-U5ajDbtDfadp7pvUMC0F2XbkP5vQn9Xrwa6UptePl+cK8EILxapAt3sXers9B3Gxagk+zVjL2ELKuzQvyqOwug==", "requires": { - "nan": "^2.13.1", + "nan": "^2.14.0", "safer-buffer": "^2.1.2" } }, @@ -16056,9 +16297,9 @@ } }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true }, "immediate": { @@ -16272,6 +16513,12 @@ "has-tostringtag": "^1.0.0" } }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -19822,9 +20069,9 @@ } }, "nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==" }, "natural-compare": { "version": "1.4.0", @@ -19833,12 +20080,12 @@ "dev": true }, "node-expat": { - "version": "2.3.18", - "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.3.18.tgz", - "integrity": "sha512-9dIrDxXePa9HSn+hhlAg1wXkvqOjxefEbMclGxk2cEnq/Y3U7Qo5HNNqeo3fQ4bVmLhcdt3YN1TZy7WMZy4MHw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.4.1.tgz", + "integrity": "sha512-uWgvQLgo883NKIL+66oJsK9ysKK3ej0YjVCPBZzO/7wMAuH68/Yb7+JwPWNaVq0yPaxrb48AoEXfYEc8gsmFbg==", "requires": { "bindings": "^1.5.0", - "nan": "^2.13.2" + "nan": "^2.19.0" } }, "node-fetch": { @@ -20098,6 +20345,12 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -20259,12 +20512,6 @@ "functions-have-names": "^1.2.2" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -20577,6 +20824,11 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -20895,12 +21147,6 @@ "resolved": "https://registry.npmjs.org/uuid-validate/-/uuid-validate-0.0.3.tgz", "integrity": "sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-to-istanbul": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", @@ -21184,7 +21430,7 @@ "xml-stream": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/xml-stream/-/xml-stream-0.4.5.tgz", - "integrity": "sha1-dFLYWzf5uIGnDv8M90oN8CCI7es=", + "integrity": "sha512-WdMVMiYgJ2UQO2vs8CRVOd0CD0GW3AfeWHwpFJWB+bRYbnNNn88BxoYbjm0qRijceJgP1krCRwr6DgfbQKudmA==", "requires": { "iconv": "^2.1.4", "node-expat": "^2.3.1", @@ -21194,12 +21440,12 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -21210,7 +21456,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" } } }, diff --git a/package.json b/package.json index 95922f8c..2627a7ec 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "argparse": "^2.0.1", "csv-parse": "^4.6.5", "fast-csv": "^4.3.6", + "fast-xml-parser": "^4.5.1", "html-to-text": "^5.1.1", "http-status-codes": "^1.3.2", "json-cycle": "^1.3.0", @@ -25,7 +26,6 @@ "jsonpath": "^1.1.1", "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", - "node-expat": "^2.3.18", "node-fetch": "^2.6.7", "p-limit": "^3.1.0", "parse5": "^5.1.1", diff --git a/test/civic/civic.profile.test.js b/test/civic/civic.profile.test.js index ee8ea60d..d1ea8e9b 100644 --- a/test/civic/civic.profile.test.js +++ b/test/civic/civic.profile.test.js @@ -226,7 +226,7 @@ describe('MolecularProfile.process()', () => { ); }); - test('test case that should throw a NotImplementedError', () => { + test('Case that should throw a NotImplementedError', () => { const molecularProfile = { id: 1, parsedName: [ diff --git a/test/loadfile.test.js b/test/loadfile.test.js index 7d53dddb..2b8ae27d 100644 --- a/test/loadfile.test.js +++ b/test/loadfile.test.js @@ -34,7 +34,7 @@ describe('diseaseOntology', () => { }); describe('drugBank', () => { - test('uploadFile', async () => { + test.skip('uploadFile', async () => { const filename = path.join(__dirname, 'data/drugbank_sample.xml'); await drugbank.uploadFile({ conn: api, filename }); expect(api.addRecord).toHaveBeenCalled(); From 97c250558f2e6a8714c34d727bc45d8e6e61582f Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 6 Jan 2025 11:20:59 -0800 Subject: [PATCH 51/52] remove fast-xml-parser and reactivated drugbank loadfile test --- package-lock.json | 40 ---------------------------------------- package.json | 1 - test/loadfile.test.js | 2 +- 3 files changed, 1 insertion(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index 618d4815..c92b56f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "argparse": "^2.0.1", "csv-parse": "^4.6.5", "fast-csv": "^4.3.6", - "fast-xml-parser": "^4.5.1", "html-to-text": "^5.1.1", "http-status-codes": "^1.3.2", "json-cycle": "^1.3.0", @@ -4793,27 +4792,6 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, - "node_modules/fast-xml-parser": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz", - "integrity": "sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", @@ -11281,11 +11259,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -15852,14 +15825,6 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, - "fast-xml-parser": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz", - "integrity": "sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==", - "requires": { - "strnum": "^1.0.5" - } - }, "fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", @@ -20824,11 +20789,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, - "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 2627a7ec..98ffa173 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "argparse": "^2.0.1", "csv-parse": "^4.6.5", "fast-csv": "^4.3.6", - "fast-xml-parser": "^4.5.1", "html-to-text": "^5.1.1", "http-status-codes": "^1.3.2", "json-cycle": "^1.3.0", diff --git a/test/loadfile.test.js b/test/loadfile.test.js index 2b8ae27d..7d53dddb 100644 --- a/test/loadfile.test.js +++ b/test/loadfile.test.js @@ -34,7 +34,7 @@ describe('diseaseOntology', () => { }); describe('drugBank', () => { - test.skip('uploadFile', async () => { + test('uploadFile', async () => { const filename = path.join(__dirname, 'data/drugbank_sample.xml'); await drugbank.uploadFile({ conn: api, filename }); expect(api.addRecord).toHaveBeenCalled(); From 573e236cbe535870ff3079587ca0351381c4883a Mon Sep 17 00:00:00 2001 From: mathieulemieux Date: Mon, 10 Feb 2025 13:19:51 -0800 Subject: [PATCH 52/52] Update version from 8.0.2 to 8.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c92b56f1..6e7981a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bcgsc-pori/graphkb-loader", - "version": "8.0.2", + "version": "8.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@bcgsc-pori/graphkb-loader", - "version": "8.0.2", + "version": "8.1.0", "license": "GPL-3", "dependencies": { "@bcgsc-pori/graphkb-parser": "^2.1.0", diff --git a/package.json b/package.json index 98ffa173..219a519f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@bcgsc-pori/graphkb-loader", "main": "src/index.js", - "version": "8.0.2", + "version": "8.1.0", "repository": { "type": "git", "url": "https://github.com/bcgsc/pori_graphkb_loader.git"