WIP. I'm exploring this as a concept right now. See goals for more details. Next up: CICD for binary releases and tests.
JQ is a brilliant tool but having to lookup the syntax everytime you use it sucks. Javascript is pretty flexible, well known, and allows for a functional flavour.
JSQ aims to be a more intuitive and maintainable JQ, sacrificing binary size and potentially succinctness.
- easy syntax
- binary executable
- startup speed
- bundle size - we'll never beat jq here, <75mb should be fine.
- succinct expressions
A number of libraries are bundled to help allow for expressive function expressions.
Library | Template Variable | Documentation |
---|---|---|
lodash | _.<...> |
https://lodash.com/docs |
lodash/fp | f.<...> |
https://github.com/lodash/lodash/wiki/FP-Guide |
Ramdax | r.<...> |
https://selfrefactor.github.io/rambdax |
It's suggested to construct expressions using the library/libraries that are the most understandable or used within your team.
# Lodash => `_.`
$ echo '{"some-json": "blob"}' | jsq '(input) => _.get(input, "some-json")'
blob
# Lodash/fp => `f`
$ echo '{"some-json": "blob"}' | jsq '(input) => f.get("some-json", input)'
blob
# Shorthand
$ echo '{"some-json": "blob"}' | jsq 'f.get("some-json")'
blob
# Ramdax => `r.`
$ echo '{"some-json": "blob"}' | jsq '(input) => r.path("some-json", input)'
blob
# Shorthand
$ echo '{"some-json": "blob"}' | jsq 'r.path("some-json")'
blob
An array of functions will apply the result of the previous function and original object to each function.
$ echo '{"some-json": "blob"}' | jsq '[r.path("some-json"), (previous, original) => [previous, original]]'
[
"blob",
{
"some-json": "blob"
}
]
# expands to...
$ echo '{"some-json": "blob"}' | jsq '(input) => {
const fn1 = (previous, original) => r.path("some-json")(previous, original)
const fn2 = (previous, original) => [previous, original]
const r1 = fn1(input, input)
const r2 = fn2(r1, input)
return r2
}'
[
"blob",
{
"some-json": "blob"
}
]
Not recommended, but mixing and matching libraries is also possible
cat _test/country-data.json | jsq 'r.map(r.path("name.common"))'
[ "French Polynesia", "Saint Martin", "Venezuela", "Réunion", ... ]
cat _test/country-data.json | jsq '[o => _.map(o, f.get("name.common")), f.map(r.head)]'
[
"F", # from "French Polynesia"
"S", # from "Saint Martin"
"V", # from "Venezuela"
"R", # from "Réunion"
...
]
# Install asdf tooling
curl -sL https://raw.githubusercontent.com/olmesm/odd-scripts/main/shell/asdf-install.sh | bash
# For countries API
npm run poc -- '<function expression>'
# npm run poc -- 'r.map(r.path("name.common"))'
# Custom Blobs
echo '{"some-json": "blob"}' | npm start -- '<function expression>'
# echo '{"some-json": "blob"}' | npm start -- 'r.path("some-json")'
# Build
npm run build
# Check bundle size
ls -lh ./dist
-
git config diff.lockb.textconv bun git config diff.lockb.binary true
-
Refresh country data
curl -s https://restcountries.com/v3.1/all > _test/country-data.json