import {z} from 'zod' export type CreateApiPublicV1VariantsInterpretArgs = {body: {assembly: string, chromosome: string, position: number, reference: string, alternate: string}}; export type CreateApiPublicV1VariantsInterpretOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const publicVariantIdentity = z.object({assembly: z.literal("GRCh38"), chromosome: z.string().min(1), position: z.number().int().gte(1), reference: z.string().min(1), alternate: z.string().min(1), variant_type: z.enum(["SNV", "INS", "DEL", "DELINS"]), canonical_key: z.string().min(1)}); export const publicVariantDisplay = z.object({label: z.string().min(1), hgvs_genomic: z.string().nullable(), hgvs_cdna: z.string().nullable(), hgvs_protein: z.string().nullable()}); export const publicVariantAnnotation = z.object({gene_symbol: z.string().min(1), gene_id: z.string().nullable(), transcript_id: z.string().nullable(), consequence: z.string().min(1), impact: z.string().nullable(), biotype: z.string().nullable(), exon_number: z.string().nullable(), domains: z.array(z.string().min(1))}); export const publicClinVarEvidence = z.object({clinical_significance: z.string().nullable(), review_status: z.string().nullable(), review_stars: z.number().int().nullable(), variation_id: z.string().nullable(), rsid: z.string().nullable(), disease_names: z.array(z.string().min(1)), protein_representation: z.string().nullable(), canonical_url: z.string().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicExpertEvidence = z.object({vcep_applied: z.boolean(), vcep_panel: z.string().nullable(), erepo_assertion: z.string().nullable(), erepo_panel: z.string().nullable(), erepo_disease: z.string().nullable(), erepo_summary: z.string().nullable(), erepo_url: z.string().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicPrediction = z.object({prediction: z.string().nullable(), score: z.number().nullable()}); export const publicPredictorEvidence = z.object({sift: publicPrediction, alphamissense: publicPrediction, metasvm: publicPrediction, dann_score: z.number().nullable(), bayesdel_noaf: publicPrediction, bayesdel_addaf: publicPrediction, availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicSpliceAIEvidence = z.object({prediction: z.string().nullable(), max_delta_score: z.number().nullable(), gene: z.string().nullable(), ds_ag: z.number().nullable(), ds_al: z.number().nullable(), ds_dg: z.number().nullable(), ds_dl: z.number().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicConservationEvidence = z.object({phylop100way_vertebrate: z.number().nullable(), gerp_rs: z.number().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicGeneConstraintEvidence = z.object({pli: z.number().nullable(), oe_lof: z.number().nullable(), loeuf: z.number().nullable(), missense_z: z.number().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicDosageEvidence = z.object({haploinsufficiency_score: z.number().int().nullable(), triplosensitivity_score: z.number().int().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicPopulationEvidence = z.object({global_allele_frequency: z.number().nullable(), global_allele_count: z.number().int().nullable(), global_allele_number: z.number().int().nullable(), homozygote_count: z.number().int().nullable(), group_max_allele_frequency: z.number().nullable(), popmax_population: z.string().nullable(), rsid: z.string().nullable(), canonical_url: z.string().nullable(), availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicExternalLinks = z.object({clinvar: z.string().nullable(), gnomad: z.string().nullable(), ensembl_gene: z.string().nullable(), ensembl_transcript: z.string().nullable(), clingen_erepo: z.string().nullable()}); export const publicVariantEvidence = z.object({clinvar_significance: z.string().nullable(), clinvar_review_stars: z.number().int().nullable(), vcep_applied: z.boolean(), vcep_panel: z.string().min(1).nullable(), erepo_assertion: z.string().nullable(), erepo_panel: z.string().nullable(), erepo_disease: z.string().nullable(), clinvar: publicClinVarEvidence, expert: publicExpertEvidence, predictors: publicPredictorEvidence, spliceai: publicSpliceAIEvidence, conservation: publicConservationEvidence, gene_constraints: publicGeneConstraintEvidence, dosage: publicDosageEvidence, population: publicPopulationEvidence, external_links: publicExternalLinks}); export const publicFunctionalVersions = z.object({specification: z.string().min(1).max(512), publication: z.string().min(1).max(512), calibration_controls: z.string().min(1).max(512), mavedb: z.string().min(1).max(512), protein_bridge: z.string().min(1).max(512).nullable().optional(), spliceai: z.string().min(1).max(512).nullable().optional()}); export const publicFunctionalHashes = z.object({specification: z.string(), publication: z.string(), calibration_controls: z.string(), mavedb: z.string(), protein_bridge: z.string().nullable().optional(), spliceai: z.string().nullable().optional()}); export const publicFunctionalHashKinds = z.object({specification: z.literal("source_set_sha256"), publication: z.literal("source_set_sha256"), calibration_controls: z.literal("source_set_sha256"), mavedb: z.literal("source_set_sha256"), protein_bridge: z.literal("identity_sha256").nullable().optional(), spliceai: z.literal("identity_sha256").nullable().optional()}); export const publicFunctionalAnnotationReferences = z.object({spliceai: z.string().min(1).nullable().optional()}); export const publicFunctionalRecord = z.object({variant_key: z.string().min(1), criterion: z.enum(["PS3", "BS3"]), strength: z.literal("Strong"), gene: z.string().min(1), transcript: z.string().min(1), protein_hgvs: z.string().min(1), disease_id: z.string().min(1), moi: z.string().min(1), score_set_urn: z.string().min(1), measurement_id: z.string().min(1), mapping_id: z.string().min(1), raw_score: z.number(), odds_path: z.number(), spliceai_delta_max: z.number().nullable().optional(), source_versions: publicFunctionalVersions, source_hashes: publicFunctionalHashes, source_hash_kinds: publicFunctionalHashKinds, annotation_references: publicFunctionalAnnotationReferences, source_context_id: z.string().min(1), publication_id: z.string().min(1), references: z.array(z.string().min(1))}); export const publicFunctionalEvidence = z.object({qualification_profile: z.literal("scott-mmr-dms-2022.v1"), combining_policy: z.literal("existing_classifier"), combining_policy_version: z.string().min(1), gn137_combining_rules_applied: z.literal(false), records: z.array(publicFunctionalRecord)}); export const publicVariantClassification = z.object({functional_evidence: publicFunctionalEvidence.nullable().optional(), framework: z.literal("acmg_2015"), automated_class: z.enum(["P", "LP", "VUS", "LB", "B"]), criteria: z.string(), confidence_score: z.number().gte(0).lte(1), pm1_evidence_source: z.enum(["pfam", "uniprot", "pfam+uniprot"]).nullable(), pm1_evidence_availability: z.enum(["available", "no_record", "not_applicable", "unavailable"])}); export const publicReferenceVersion = z.object({name: z.string().min(1), version: z.string().min(1)}); export const publicVariantProvenance = z.object({annotation_source: z.enum(["vep_cache", "vep_live"]).nullable(), vep_version: z.string(), vep_cache_version: z.string(), reference_assembly: z.string(), classifier_version: z.string(), classifier_version_label: z.string(), reference_versions: z.array(publicReferenceVersion), annotation_resolved: z.boolean(), classification_completed: z.boolean()}); export const publicVariantLimitations = z.object({scope: z.literal("Automated variant-level ACMG/AMP decision support for one GRCh38 nuclear SNV, simple indel, or delins smaller than 50 bp.").optional(), unavailable_context: z.literal("Patient phenotype, genotype, family, segregation, de novo, case-specific, and private override evidence were not evaluated.").optional(), diagnostic_use: z.literal("This result is not a patient diagnosis and must not be used as a substitute for qualified clinical interpretation.").optional()}); export const publicVariantSuccessResponse = z.object({transcript_representations: z.record(z.string(), z.unknown()).nullable().optional(), contract_version: z.literal("1.0").optional(), status: z.literal("success").optional(), identity: publicVariantIdentity, display: publicVariantDisplay, annotation: publicVariantAnnotation, evidence: publicVariantEvidence, classification: publicVariantClassification, provenance: publicVariantProvenance, warnings: z.array(z.enum(["hgvs_display_incomplete", "clinvar_evidence_not_available", "expert_evidence_not_available", "external_link_unavailable", "evidence_truncated"])), limitations: publicVariantLimitations}); export const publicVariantUnavailableError = z.object({code: z.enum(["annotation_unavailable", "reference_data_unavailable", "classification_unavailable"]), message: z.string().min(1), retryable: z.literal(true).optional()}); export const publicVariantUnavailableResponse = z.object({contract_version: z.literal("1.0").optional(), status: z.literal("unavailable").optional(), identity: publicVariantIdentity, display: publicVariantDisplay, error: publicVariantUnavailableError, provenance: publicVariantProvenance, warnings: z.array(z.enum(["hgvs_display_incomplete", "clinvar_evidence_not_available", "expert_evidence_not_available", "external_link_unavailable", "evidence_truncated"])), limitations: publicVariantLimitations}); export const publicVariantInvalidRequestError = z.object({code: z.enum(["unsupported_assembly", "invalid_chromosome", "invalid_position", "invalid_allele", "multi_allelic_not_supported", "symbolic_allele_not_supported", "reference_equals_alternate", "unsupported_variant_class"]), message: z.string().min(1), retryable: z.literal(false).optional()}); export const publicVariantValidationErrorResponse = z.object({contract_version: z.literal("1.0").optional(), status: z.literal("invalid_request").optional(), error: publicVariantInvalidRequestError, limitations: publicVariantLimitations}); export const createApiPublicV1VariantsInterpretResponse = z.discriminatedUnion("status", [publicVariantSuccessResponse, publicVariantUnavailableResponse, publicVariantValidationErrorResponse]); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Interpret one public GRCh38 variant * * POST /public/v1/variants/interpret */ export const createApiPublicV1VariantsInterpret = async (args: CreateApiPublicV1VariantsInterpretArgs, options: CreateApiPublicV1VariantsInterpretOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/public/v1/variants/interpret${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiPublicV1VariantsInterpretResponse, await res.json()) };