GithubHelp home page GithubHelp logo

kantord / emuto Goto Github PK

View Code? Open in Web Editor NEW
222.0 5.0 7.0 7.08 MB

manipulate JSON files

Home Page: https://kantord.github.io/emuto/

License: MIT License

JavaScript 99.33% Dockerfile 0.11% CSS 0.36% Shell 0.20%
json data-mining frontend programming-language script jq sed awk node javascript

emuto's Introduction

WebsiteTutorialLive demoCLI versionCompile-to-JS version


Emuto is a small language for manipulating and restructuring JSON and other data files. Emuto is inspired by jq and GraphQL

build Codecov David NPM GitHub release Twitter URL

Features

  • Transform and query data structures
  • Integrate with unix commands in the command line
  • Conversions between different file formats
  • Supported input formats: JSON, text, csv, tsv, dsv
  • Supported output formats: JSON, text
  • Available as a Webpack loader

Getting started

Emuto as a CLI tool

npm install -g emuto emuto-cli

Read more in the tutorial

For Arch Linux users, also available as an AUR package

Webpack loader for emuto

yarn add --dev emuto emuto-loader

Read more in the Webpack guide

What is emuto good for? Examples

Number of items in JSON file

curl my_file.json | emuto 'length'

Your karma on HackerNews

curl https://hacker-news.firebaseio.com/v0/user/kantord.json -s | emuto '$.karma'

Convert another command's output to JSON

ls | emuto -i=raw '$[0:-1]'

See number of NPM dependencies

cat package.json | emuto -c '$.dependencies | keys | length'

List available scripts in package.json

cat package.json | emuto -c '$.scripts | keys | join " · "'

Get only the relevant data from a huge JSON file

curl https://api.github.com/repos/stedolan/jq/commits |\
emuto -c 'map ($ => $ { commit { message } committer { login } } )'

Automate the restructuring of data by creating scripts with emuto

restructure.emu

#! emuto -s

$
  | map ($ => $ { commit { message } committer { login } } )
  | map ($ => {
      "committer": $.committer.login,
      "message":   $.commit.message,
    })

Calling your script

curl https://api.github.com/repos/stedolan/jq/commits | ./restructure.emu

Read our contributing guide to learn about our development process, how to create bugfixes and improvements, and how to build and test your changes to emuto.

emuto's People

Contributors

dependabot-preview[bot] avatar dependabot-support avatar jacekk avatar kantord avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

emuto's Issues

Implement ternary

The syntax should by Python-like:

"Reject" if $salary < 1000 else "Accept"

Precedence should probably be the same as ternary in JavaScript

Idea: Disallow non-zero-element pipes in operations

If there's only one item in a pipe, that should be handled as a value

Otherwise a type error should be thrown (there's no way that a generator could be multiplied by 4 for example)

Valid:

(4) * 2

Not valid:

(4 | 4) * 2

Implement .*. projection

For this input:

{
  "users": [
    {
      "posts": [
        {
          "title": "foo"
        },
        {
          "title": "bar"
        }
      ],
      "articles": [
        {
          "title": "baz"
        }
      ]
    },
    {
      "posts": [],
      "articles": []
    }
  ]
}

The following filter:

.users.*.*.title

Should produce the following output:

["foo", "bar", "baz"]

Implement built in function 'has(key)'

Implement a function that returns whether the input object has the given key, or the input array has an element at the given index.

A code example that should work:

{"foo": "bar"} | has "foo" // results true
{"foo": "bar"} | has "bar" // results false

Don't show regular expressions in syntax error messages

When a syntax error is reported, a bunch of regular expressions are shown:

SyntaxError: Expected '!' or '$' or '(' or '+' or '-' or '//' or '[' or '' or 'false' or 'null' or 'true' or '{' or /("(((?=\)\(["\/bfnrt]|u[0-9a-fA-F]{4}))|[^"\\\0-\x1F\x7F]+)")/ or /((?!null|false|true)[a-zA-Z][0-9a-zA-Z_$]|(null|false|true)[0-9a-zA-Z_$])/ or /-?(?:0|[1-9]\d*)(?:.\d+)?(?:[eE][+-]?\d+)?/ or /.[$A-Z_][0-9A-Z_$]*/i on line 1 column 82, found '}' instead

This is completely useless and annoying for the user. Instead of regular expressions it'd be much more useful to show names, such as 'Identifier' instead of /((?!null|false|true)[a-zA-Z][0-9a-zA-Z_$]*|(null|false|true)[0-9a-zA-Z_$])/

Luckily, Parsimmon has a really nice feature to solve this: the desc method. This code example shows how to use it: https://github.com/jneen/parsimmon/blob/master/API.md#parserparseinput

Therefore it's sufficient to add a desc call to each parser. To test this, I would just create a separate test file which parses the same invalid code (say ¡) with every parser and examines the result.

Idea: datasources

emuto could be used as a GraphQL-like query language to retrieve data from the backend.

To determine which file/database table/API should be queried, one possible way could be creating a datasource function which could work like this:

datasource "userPhotos" : {"userId": $.userId}

this would simply return the data from datasource, passing {"userId": $.userId} as variables. The result could be transformed by using projections or a pipeline:

datasource "userPhotos" : {"userId": $.userId} {
    title
    photoURL
    user {
        name
        avatar
    }
}

In this case the server would pass the variables received along with the query as the input to the transformation

Idea: add static type analysis

This feature would consist in 3 different parts:

  • Add a syntax for type casting (it should actually be a special way to use functions that take a value and either return a casted value or throw an exception). It should handle type arguments, for example, array of string vs array of integer
  • Add casting functions for basic types (integer, array, etc.)
  • A static type checker as a separate package that can be used to find errors and generate flow/typescript types for the entire application (or modules)

Design pattern matching syntax + roadmap

The basic idea is to have a syntax similar to this:

(
  ["foo", $bar] -> $bar.value * 2,
  [$first, {"baz": $value}] -> [$value, $first],
  $value, $value >= 3.14 -> "Bigger than 3.14",
  otherwise -> error "Nonsense"
)

Implement object projection

{"foo": 1, "bar": 2, "baz": 3} | ${foo, bar}  // {"foo": 1, "bar": 2}
{"foo": 1, "bar": 2, "baz": 3}{"foo", "bar"}  // {"foo": 1, "bar": 2}

Allow infix function calls

Example:

({"foo": "bar"} has "foo") // returns true
({"foo": "bar"} has "bar") // returns false

({"foo": "bar"} has "foo") should be equivalent to {"foo": "bar"} | has "foo"

Add git hook

yarn test and yarn checks should be always executed before commit, as well as commit message format enforcement

Implement nested projection

Projection rules should be nestable (GraphQL-style), for example:

{"foo": 1, "bar": {"x": [1, 0, 0]}, "baz": 3} | ${foo, bar{x[2,0]}}  // {"foo": 1, "bar": {"x": [0, 1]}}

Allow for a generator of inputs

Allow input to be a generator.

When the input is a generator, the filter should be executed on each element separately.

Two special filters should be added:

slurp - this filter should take every element in the input and convert it to an array

nibble - this should convert an array into a generator
nibble | $ * 2 should have the same result as map $ => $ * 2

Add contributing guidelines to website

The solution has the meet these criteria:

  • There should be a development section in the sidebar on the website, with the contributing guide with it
  • Contributing guide should still be in the root of the repo so that people can find it in its 'default' place without looking at the website

Add error function

error "Hello World"

should throw an exception

((function() { throw new Error('Hello World') })())

Implement comprehension syntax

[.title forEach $ if (.author.posts | length) >= 3 sortBy .author.age]

The sortBy .author.age part should actually just be a function call. :-) So this should also be valid

[.title forEach $ if (.author.posts | length) >= 3 reverse]

Or of course without the extra function call:

[.title forEach $ if (.author.posts | length) >= 3]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.