Skip to content

Commit

Permalink
fix: minimize arg input to JQ
Browse files Browse the repository at this point in the history
  • Loading branch information
tokebe committed Nov 17, 2023
1 parent 4ea2f9e commit 4782e28
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 63 deletions.
23 changes: 12 additions & 11 deletions data/jq/pair/biothings.jq
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
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 ({};
# if the item is notfound, then proceed to next item & keep current object
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
20 changes: 4 additions & 16 deletions data/jq/pair/ctd.jq
Original file line number Diff line number Diff line change
@@ -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([.])
16 changes: 7 additions & 9 deletions src/jq_utils.ts
Original file line number Diff line number Diff line change
@@ -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 = "";
Expand All @@ -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}`;
}
75 changes: 48 additions & 27 deletions src/transformers/jq_transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<JSONDoc> {
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<PairedResponse> {
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,
);
}
}

0 comments on commit 4782e28

Please sign in to comment.