Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: most recent mehari rest service causes unknown fields error (#249) #250

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,6 @@
"vitest-canvas-mock": "^0.3.3",
"vitest-fetch-mock": "^0.2.2",
"vue-tsc": "^2.0.19"
}
},
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
10 changes: 10 additions & 0 deletions protos/mehari/txs.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ message GeneToTxId {
string gene_id = 1;
// Vector of all transcript IDs.
repeated string tx_ids = 2;
// Whether this gene has been filtered out because of missing transcripts.
optional bool filtered = 3;
// Reason for filtering.
optional uint32 filter_reason = 4;
}

// Container for the transcript-related database.
Expand Down Expand Up @@ -59,6 +63,8 @@ enum TranscriptTag {
TRANSCRIPT_TAG_REF_SEQ_SELECT = 5;
// Flagged as being a selenoprotein (UGA => selenon).
TRANSCRIPT_TAG_SELENOPROTEIN = 6;
// Member of GENCODE Primary
TRANSCRIPT_TAG_GENCODE_PRIMARY = 7;
}

// Store information about a transcript.
Expand All @@ -81,6 +87,10 @@ message Transcript {
optional int32 stop_codon = 8;
// Alignments on the different genome builds.
repeated GenomeAlignment genome_alignments = 9;
// Whether this transcript has an issue (e.g. MissingStopCodon), cf. `mehari::db::create::mod::Reason`.
optional bool filtered = 10;
// Reason for filtering.
optional uint32 filter_reason = 11;
}

// Enumeration for the known genome builds.
Expand Down
6 changes: 4 additions & 2 deletions src/api/annonars/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ export class AnnonarsClient {
const responseJson = await response.json()
if (responseJson?.genes && responseJson?.genes[hgncId]) {
try {
return ClinvarPerGeneRecord.fromJson(responseJson.genes[hgncId])
return ClinvarPerGeneRecord.fromJson(responseJson.genes[hgncId], {
ignoreUnknownFields: true
})
} catch (e) {
throw new InvalidResponseContent(`failed to parse gene clinvar info response: ${e}`)
}
Expand Down Expand Up @@ -176,7 +178,7 @@ export class AnnonarsClient {
resultJsons.forEach((chunk: any) => {
for (const value of Object.values(chunk.genes)) {
// @ts-ignore
result.push(GeneInfoRecord.fromJson(value as JsonValue))
result.push(GeneInfoRecord.fromJson(value as JsonValue, { ignoreUnknownFields: true }))
}
})
return result
Expand Down
20 changes: 14 additions & 6 deletions src/api/annonars/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ class ClinvarSvQueryResponse$Type {
fromJson(apiResponse: ClinvarSvQueryResponse$Api): ClinvarSvQueryResponse {
const records = apiResponse.records ?? []
return {
records: records.map((value) => ClinvarStrucvarResponseRecord.fromJson(value))
records: records.map((value) =>
ClinvarStrucvarResponseRecord.fromJson(value, { ignoreUnknownFields: true })
)
}
}
}
Expand Down Expand Up @@ -176,7 +178,7 @@ class GeneInfoResult$Type {
return {
genes: Object.values(apiResult.genes).map((gene$Api) =>
// @ts-ignore
GeneInfoRecord.fromJson(gene$Api as JsonValue)
GeneInfoRecord.fromJson(gene$Api as JsonValue, { ignoreUnknownFields: true })
)
}
}
Expand Down Expand Up @@ -278,27 +280,33 @@ class SeqvarInfoResult$Type {
// @ts-ignore
apiResult.dbsnp === null
? undefined // @ts-ignore
: DbsnpRecord.fromJson(apiResult.dbsnp as JsonValue),
: DbsnpRecord.fromJson(apiResult.dbsnp as JsonValue, { ignoreUnknownFields: true }),
dbnsfp: apiResult.dbnsfp === null ? undefined : apiResult.dbnsfp,
dbscsnv: apiResult.dbscsnv === null ? undefined : apiResult.dbscsnv,
gnomadMtdna:
apiResult.gnomad_mtdna === null
? undefined
: // @ts-ignore
GnomadMtdnaRecord.fromJson(apiResult.gnomad_mtdna as JsonValue),
GnomadMtdnaRecord.fromJson(apiResult.gnomad_mtdna as JsonValue, {
ignoreUnknownFields: true
}),
gnomadExomes: apiResult.gnomad_exomes === null ? undefined : apiResult.gnomad_exomes,
gnomadGenomes: apiResult.gnomad_genomes === null ? undefined : apiResult.gnomad_genomes,
helixmtdb:
apiResult.helixmtdb === null
? undefined
: // @ts-ignore
HelixmtdbRecord.fromJson(apiResult.helixmtdb as JsonValue),
HelixmtdbRecord.fromJson(apiResult.helixmtdb as JsonValue, {
ignoreUnknownFields: true
}),
ucscConservation: apiResult.ucsc_conservation.map((cons) => cons.records),
clinvar:
apiResult.clinvar === null
? undefined
: // @ts-ignore
ExtractedVcvRecordList.fromJson(apiResult.clinvar as JsonValue)
ExtractedVcvRecordList.fromJson(apiResult.clinvar as JsonValue, {
ignoreUnknownFields: true
})
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/api/mehari/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class MehariClient {
}
try {
const responseJson = await response.json()
return GeneTranscriptsResponse.fromJson(responseJson)
return GeneTranscriptsResponse.fromJson(responseJson, { ignoreUnknownFields: true })
} catch (e) {
throw new InvalidResponseContent(`Failed to parse transcript response: ${e}`)
}
Expand Down
8 changes: 6 additions & 2 deletions src/components/GeneClinvarCard/ClinvarFreqPlot.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import geneClinvarTgdsJson from './fixture.clinvarPerGene.TGDS.json'
// as in the tests fails with "process is not defined" error in the browser.

// @ts-ignore
const clinvarPerGeneTgds = ClinvarPerGeneRecord.fromJson(geneClinvarTgdsJson as JsonValue)
const clinvarPerGeneTgds = ClinvarPerGeneRecord.fromJson(geneClinvarTgdsJson as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const clinvarPerGeneBrca1 = ClinvarPerGeneRecord.fromJson(geneClinvarBrca1Json as JsonValue)
const clinvarPerGeneBrca1 = ClinvarPerGeneRecord.fromJson(geneClinvarBrca1Json as JsonValue, {
ignoreUnknownFields: true
})

const meta = {
title: 'Gene/Clinvar/ClinvarFreqPlot',
Expand Down
28 changes: 21 additions & 7 deletions src/components/GeneClinvarCard/GeneClinvarCard.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,33 @@ import genesTxsTgdsJson38 from './fixture.genesTxs.TGDS.38.json'
// as in the tests fails with "process is not defined" error in the browser.

// @ts-ignore
const clinvarPerGeneTgds = ClinvarPerGeneRecord.fromJson(geneClinvarTgdsJson as JsonValue)
const clinvarPerGeneTgds = ClinvarPerGeneRecord.fromJson(geneClinvarTgdsJson as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const clinvarPerGeneBrca1 = ClinvarPerGeneRecord.fromJson(geneClinvarBrca1Json as JsonValue)
const clinvarPerGeneBrca1 = ClinvarPerGeneRecord.fromJson(geneClinvarBrca1Json as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const genesTxsTgds37 = GeneTranscriptsResponse.fromJson(genesTxsTgdsJson37 as JsonValue)
const genesTxsTgds37 = GeneTranscriptsResponse.fromJson(genesTxsTgdsJson37 as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const genesTxsTgds38 = GeneTranscriptsResponse.fromJson(genesTxsTgdsJson38 as JsonValue)
const genesTxsTgds38 = GeneTranscriptsResponse.fromJson(genesTxsTgdsJson38 as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const genesTxsBrca137 = GeneTranscriptsResponse.fromJson(genesTxsBrca1Json37 as JsonValue)
const genesTxsBrca137 = GeneTranscriptsResponse.fromJson(genesTxsBrca1Json37 as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const geneInfoTgds = GeneInfoRecord.fromJson(geneInfoTgdsJson as JsonValue)
const geneInfoTgds = GeneInfoRecord.fromJson(geneInfoTgdsJson as JsonValue, {
ignoreUnknownFields: true
})
// @ts-ignore
const geneInfoBrca1 = GeneInfoRecord.fromJson(geneInfoBrca1Json as JsonValue)
const geneInfoBrca1 = GeneInfoRecord.fromJson(geneInfoBrca1Json as JsonValue, {
ignoreUnknownFields: true
})

const meta = {
title: 'Gene/Clinvar/GeneClinvarCard',
Expand Down
62 changes: 59 additions & 3 deletions src/pbs/mehari/txs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ export interface GeneToTxId {
* @generated from protobuf field: repeated string tx_ids = 2;
*/
txIds: string[]
/**
* Whether this gene has been filtered out because of missing transcripts.
*
* @generated from protobuf field: optional bool filtered = 3;
*/
filtered?: boolean
/**
* Reason for filtering.
*
* @generated from protobuf field: optional uint32 filter_reason = 4;
*/
filterReason?: number
}
/**
* Container for the transcript-related database.
Expand Down Expand Up @@ -139,6 +151,18 @@ export interface Transcript {
* @generated from protobuf field: repeated mehari.txs.GenomeAlignment genome_alignments = 9;
*/
genomeAlignments: GenomeAlignment[]
/**
* Whether this transcript has an issue (e.g. MissingStopCodon), cf. `mehari::db::create::mod::Reason`.
*
* @generated from protobuf field: optional bool filtered = 10;
*/
filtered?: boolean
/**
* Reason for filtering.
*
* @generated from protobuf field: optional uint32 filter_reason = 11;
*/
filterReason?: number
}
/**
* Store information about a transcript aligning to a genome.
Expand Down Expand Up @@ -329,7 +353,13 @@ export enum TranscriptTag {
*
* @generated from protobuf enum value: TRANSCRIPT_TAG_SELENOPROTEIN = 6;
*/
TRANSCRIPT_TAG_SELENOPROTEIN = 6
TRANSCRIPT_TAG_SELENOPROTEIN = 6,
/**
* Member of GENCODE Primary
*
* @generated from protobuf enum value: TRANSCRIPT_TAG_GENCODE_PRIMARY = 7;
*/
TRANSCRIPT_TAG_GENCODE_PRIMARY = 7
}
/**
* Enumeration for the known genome builds.
Expand Down Expand Up @@ -495,7 +525,9 @@ class GeneToTxId$Type extends MessageType<GeneToTxId> {
kind: 'scalar',
repeat: 2 /*RepeatType.UNPACKED*/,
T: 9 /*ScalarType.STRING*/
}
},
{ no: 3, name: 'filtered', kind: 'scalar', opt: true, T: 8 /*ScalarType.BOOL*/ },
{ no: 4, name: 'filter_reason', kind: 'scalar', opt: true, T: 13 /*ScalarType.UINT32*/ }
])
}
create(value?: PartialMessage<GeneToTxId>): GeneToTxId {
Expand All @@ -522,6 +554,12 @@ class GeneToTxId$Type extends MessageType<GeneToTxId> {
case /* repeated string tx_ids */ 2:
message.txIds.push(reader.string())
break
case /* optional bool filtered */ 3:
message.filtered = reader.bool()
break
case /* optional uint32 filter_reason */ 4:
message.filterReason = reader.uint32()
break
default:
const u = options.readUnknownField
if (u === 'throw')
Expand Down Expand Up @@ -551,6 +589,11 @@ class GeneToTxId$Type extends MessageType<GeneToTxId> {
/* repeated string tx_ids = 2; */
for (let i = 0; i < message.txIds.length; i++)
writer.tag(2, WireType.LengthDelimited).string(message.txIds[i])
/* optional bool filtered = 3; */
if (message.filtered !== undefined) writer.tag(3, WireType.Varint).bool(message.filtered)
/* optional uint32 filter_reason = 4; */
if (message.filterReason !== undefined)
writer.tag(4, WireType.Varint).uint32(message.filterReason)
const u = options.writeUnknownFields
if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer)
return writer
Expand Down Expand Up @@ -680,7 +723,9 @@ class Transcript$Type extends MessageType<Transcript> {
kind: 'message',
repeat: 1 /*RepeatType.PACKED*/,
T: () => GenomeAlignment
}
},
{ no: 10, name: 'filtered', kind: 'scalar', opt: true, T: 8 /*ScalarType.BOOL*/ },
{ no: 11, name: 'filter_reason', kind: 'scalar', opt: true, T: 13 /*ScalarType.UINT32*/ }
])
}
create(value?: PartialMessage<Transcript>): Transcript {
Expand Down Expand Up @@ -737,6 +782,12 @@ class Transcript$Type extends MessageType<Transcript> {
GenomeAlignment.internalBinaryRead(reader, reader.uint32(), options)
)
break
case /* optional bool filtered */ 10:
message.filtered = reader.bool()
break
case /* optional uint32 filter_reason */ 11:
message.filterReason = reader.uint32()
break
default:
const u = options.readUnknownField
if (u === 'throw')
Expand Down Expand Up @@ -790,6 +841,11 @@ class Transcript$Type extends MessageType<Transcript> {
writer.tag(9, WireType.LengthDelimited).fork(),
options
).join()
/* optional bool filtered = 10; */
if (message.filtered !== undefined) writer.tag(10, WireType.Varint).bool(message.filtered)
/* optional uint32 filter_reason = 11; */
if (message.filterReason !== undefined)
writer.tag(11, WireType.Varint).uint32(message.filterReason)
const u = options.writeUnknownFields
if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer)
return writer
Expand Down
Loading