civic_execute
Execute JavaScript code against the CIViC GraphQL API. Code runs in a sandboxed V8 isolate with:
- gql.query(queryString, variables?) — execute GraphQL queries (returns data directly, e.g. result.gene not result.data.gene)
- schema.types(), schema.type(name), schema.search(query) — explore the schema
- schema.queryRoot() — list available query entry points with args
- schema.enumValues(name), schema.inputType(name) — inspect enums and input types
- console logging (log, warn, error, info) — captured output
Domain-specific helper functions and quirks are documented below.
The last expression or return value is the result.
Use schema.queryRoot() to discover available query fields.
STAGING: Large responses (>30KB) are auto-staged into SQLite. When this happens, gql.query returns {__staged: true, data_access_id, schema, tables_created, total_rows, message}. Scalar properties from the original response are preserved on the staged object.
When staging occurs:
- Check result.__staged === true
- Read any preserved scalars (result.count, result.total, etc.)
- Return the staging metadata — the caller will use civic_query_data with the data_access_id to explore the data with SQL
DO NOT try to access .results, .data, .entries, .items on a staged response — those arrays were replaced by SQLite tables.
For advanced use: api.query(data_access_id, sql) and db.queryStaged(data_access_id, sql) are available to query staged data within the same execution (returns {results, row_count}, max 1000 rows, SELECT only).
SCRATCHPAD: db.stage(data, tableName?) stages any array/object into SQLite and returns {data_access_id, tables_created, total_rows}. Use this to persist computed or filtered results for SQL queries.
IMPORTANT: Use pagination params (first/after, limit/offset) to keep responses small. If you need large datasets, let them auto-stage and return the staging info.
SERVER NOTES: --- CIViC quirks --- Gene lookup uses entrezSymbol, NOT symbol: gql.query('{ gene(entrezSymbol: "EGFR") { id name } }') Genes by list: gql.query('{ genes(entrezSymbols: ["EGFR","BRAF"]) { nodes { id name } } }')
Variants require gene ID (integer), NOT gene symbol: Step 1: const g = await gql.query('{ gene(entrezSymbol: "BRAF") { id } }'); Step 2: const v = await gql.query('{ variants(geneId: ' + g.data.gene.id + ') { nodes { id name } } }');
EvidenceItem.status is a scalar enum (string), NOT an object. Correct: status (returns string like "ACCEPTED") WRONG: status { name } — this will error
Known field name mappings (common mistakes): direction -> evidenceDirection (on EvidenceItem) level -> evidenceLevel type -> evidenceType direction -> assertionDirection (on Assertion) type -> assertionType cytobands -> cytogeneticRegions (on Region) iscn -> iscnName (on RegionVariant)
Feature types: Gene, Factor, Fusion, Region Regions represent chromosome/cytoband-level features (e.g., 17p Deletion) Region variants carry ISCN notation in their 'iscnName' field
Region lookup: gql.query('{ region(id: 62862) { id name featureType cytogeneticRegions { chromosome band } } }') Cytoband typeahead: gql.query('{ cytogeneticRegionTypeahead(queryTerm: "17p") { id name chromosome band } }')