diff --git a/data/jq/pair/biothings.jq b/data/jq/pair/biothings.jq index cf57f40..9430656 100644 --- a/data/jq/pair/biothings.jq +++ b/data/jq/pair/biothings.jq @@ -1,4 +1,4 @@ -if $edge.query_operation._method == "post" then +if $edge.query.method == "post" then # if response is not an array, then use response.hits if (.response | type) == "array" then .response else .response.hits end | reduce .[] as $item ({}; @@ -6,17 +6,18 @@ if $edge.query_operation._method == "post" then if ($item | keys | contains(["notfound"])) then . else - if $edge.input | type == "object" then - generateCurieWithInputs($edge.association.input_id; $item.query; $edge.input.queryInputs) as $curie | .[$curie] = .[$curie] + [$item] - else - generateCurieWithInputs($edge.association.input_id; $item.query; $edge.input | toArray) as $curie | .[$curie] = .[$curie] + [$item] - end + generateCurieWithInputs( + $edge.input.id; + $item.query; + $edge.input.curies + | toArray + | map(. | split(":"))[0] + ) as $curie | .[$curie] = .[$curie] + [$item] end ) else - if ($edge.input | type) == "object" then - .response as $res | generateCurie($edge.association.input_id; $edge.input.queryInputs) as $curie | {} | .[$curie] = [$res] - else - .response as $res | generateCurie($edge.association.input_id; ($edge.input | toArray)[0]) as $curie | {} | .[$curie] = [$res] - end + .response as $res | generateCurie( + $edge.input.id; + ($edge.input.curies | toArray | map(. | split(":"))[0])[0] + ) as $curie | {} | .[$curie] = [$res] end diff --git a/data/jq/pair/ctd.jq b/data/jq/pair/ctd.jq index a912f1f..2f03503 100644 --- a/data/jq/pair/ctd.jq +++ b/data/jq/pair/ctd.jq @@ -1,23 +1,11 @@ reduce .response[] as $item ( - {}; .[( - if ($edge.input | type) == "object" then - ($edge.input.queryInputs | toArray)[] - else - ($edge.input | toArray)[] - end - ) + {}; .[$edge.input.curies | select(($item.Input | ascii_upcase | split(":") | last) == (. | ascii_upcase)) - | generateCurie($edge.association.input_id; .) + | generateCurie($edge.input.id; .) ] = [] - + .[( - if ($edge.input | type) == "object" then - ($edge.input.queryInputs | toArray)[] - else - ($edge.input | toArray)[] - end - ) + + .[$edge.input.curies | select(($item.Input | ascii_upcase | split(":") | last) == (. | ascii_upcase)) - | generateCurie($edge.association.input_id; .) + | generateCurie($edge.input.id; .) ] + [$item] ) | map_values([.]) diff --git a/src/jq_utils.ts b/src/jq_utils.ts index d6c4d7b..aadcbf2 100644 --- a/src/jq_utils.ts +++ b/src/jq_utils.ts @@ -1,8 +1,12 @@ import { JQVariable, BTEKGOperationObject } from "./types"; import Path from "path"; import fs from "fs"; +import { toArray } from "./utils"; -const functions = fs.readFileSync(Path.resolve(`${__dirname}/../data/jq/utils.jq`), { encoding: "utf8" }); +const functions = fs.readFileSync( + Path.resolve(`${__dirname}/../data/jq/utils.jq`), + { encoding: "utf8" }, +); function generateVariables(variables: JQVariable[]) { let variableString = ""; @@ -12,12 +16,6 @@ function generateVariables(variables: JQVariable[]) { return variableString; } -export function generateFilterString(filterString: string, edge: BTEKGOperationObject) { - const variables = [ - { - name: "$edge", - value: JSON.stringify(edge), - }, - ]; - return `${functions}\n${generateVariables(variables)}${filterString}`; +export function generateFilterString(filterString: string) { + return `${functions}\n${filterString}`; } diff --git a/src/transformers/jq_transformer.ts b/src/transformers/jq_transformer.ts index 1489fde..d690b03 100644 --- a/src/transformers/jq_transformer.ts +++ b/src/transformers/jq_transformer.ts @@ -5,52 +5,73 @@ import Path from "path"; import * as jq from "node-jq"; // If converted to import, ts compile breaks it (imports default as undefined) import { JSONDoc, PairedResponse } from "../json_transform/types"; +import { toArray } from "../utils"; // Get prefab JQ strings from data/jq const filterStringsWrap = Object.fromEntries( fs.readdirSync(Path.resolve(`${__dirname}/../../data/jq/wrap`)).map(file => { const filePath = Path.resolve(`${__dirname}/../../data/jq/wrap/${file}`); - return [Path.parse(filePath).name, fs.readFileSync(filePath, { encoding: "utf8" })]; + return [ + Path.parse(filePath).name, + fs.readFileSync(filePath, { encoding: "utf8" }), + ]; }), ); const filterStringsPair = Object.fromEntries( fs.readdirSync(Path.resolve(`${__dirname}/../../data/jq/pair`)).map(file => { const filePath = Path.resolve(`${__dirname}/../../data/jq/pair/${file}`); - return [Path.parse(filePath).name, fs.readFileSync(filePath, { encoding: "utf8" })]; + return [ + Path.parse(filePath).name, + fs.readFileSync(filePath, { encoding: "utf8" }), + ]; }), ); export default class JQTransformer extends BaseTransformer { // TODO more specific typing? async wrap(res: JSONDoc | JSONDoc[]): Promise { - if (this.config.wrap) - res = JSON.parse( - (await jq.run(generateFilterString(this.config.wrap, this.edge), res, { input: "json" })) as string, - ); - else if (filterStringsWrap[this.config.type]) - res = JSON.parse( - (await jq.run(generateFilterString(filterStringsWrap[this.config.type], this.edge), res, { - input: "json", - })) as string, - ); - else res = super.wrap(res); - - return res; + const filterString: string | undefined = + this.config.wrap ?? filterStringsWrap[this.config.type]; + if (typeof filterString === "undefined") return super.wrap(res); + return JSON.parse( + (await jq.run(generateFilterString(filterString), res, { + input: "json", + })) as string, + ); } async pairCurieWithAPIResponse(): Promise { - if (this.config.pair) - return JSON.parse( - (await jq.run(generateFilterString(this.config.pair, this.edge), this.data, { input: "json" })) as string, - ); - else if (filterStringsPair[this.config.type]) - return JSON.parse( - (await jq.run(generateFilterString(filterStringsPair[this.config.type], this.edge), this.data, { - input: "json", - })) as string, - ); - - return super.pairCurieWithAPIResponse(); + let filterString: string | undefined = + this.config.pair ?? filterStringsPair[this.config.type]; + if (typeof filterString === "undefined") + return super.pairCurieWithAPIResponse(); + const data = { + response: this.data.response, + edge: { + query: { + method: this.edge.query_operation.method, + }, + input: { + id: this.edge.association.input_id, + type: this.edge.association.input_type, + // input is array or is object with queryInputs + curies: + Array.isArray(this.edge.input) || + typeof this.edge.input === "string" + ? toArray(this.edge.input) + : this.edge.input.queryInputs, + }, + predicate: this.edge.association.predicate, + output: { + id: this.edge.association.output_id, + type: this.edge.association.output_type, + }, + }, + }; + filterString = `.edge as $edge | ${generateFilterString(filterString)}`; + return JSON.parse( + (await jq.run(filterString, data, { input: "json" })) as string, + ); } }