dinoql icon indicating copy to clipboard operation
dinoql copied to clipboard

A customizable GraphQL style query language for interacting with JavaScript objects.

dinoql

Build Status license

A customizable GraphQL style query language for interacting with JavaScript objects. Use dinoql to traverse JavaScript objects the same way you query APIs with GraphQL.

Table of Contents

  • Installation
  • Why ?
  • Documentation
    • Getting only name from users

    • Get user by id

    • Aliases - Renaming keys

    • Variables

    • Conditions to get fields

    • Keep key from object

    • Resolvers

      • Order by
      • Merge
      • Default value
      • Parse to Number
      • Get object values
      • Parse to array
      • First
      • Last
      • Get Prop
      • Get Path
    • Building your own resolver

    • Custom options

      • Keep structure
    • Improve Performance

  • Organizations and projects using dinoql

Installation

dinoql is available from npm.

$ npm install dinoql -S

Why ?

The main objective is to use the same idea of GraphQL, however instead of being for API, it will be for javascript objects.

  • β™₯️ GraphQL syntax.
  • πŸ”« Safe access (no runtime errors to keys that does not exist).
  • ⚑️ Aliases support (You can rename your keys in the query).
  • 🌟 Many resolvers implemented by default.
  • 🐣 Build your own resolver.
  • πŸ’₯ Fragments support(share piece of query logic).
  • πŸ‘‚ Variables support(dynamic queries).
  • πŸ„ Parse your queries in build time. (Example)
  • πŸŽ’ Filter values according to the value.
  • πŸ’Ύ Caching support
  • πŸ”₯ Customizable.

Documentation

All examples are using this data:

const data = {
  requests: {
    products: [],
    
    users: [{
      name: 'Victor Igor',
      id: "100",
      age: 40
    }, {
      name: 'Kant Jonas',
      id: "200",
      age: 35
    }],
    
    friends: [{
      name: 'KΓ‘tia',
      id: "300",
      age: 10
    }]
  }
}

Getting only name from users

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    users {
      name
    }
  }
`

console.log(users) //{ users: [{ name: 'Victor Igor' }, { name: 'Kant Jonas' }] }

Get user by id

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    users(id: "200") {
      name
    }
  }
`

console.log(users) //{ users: [{ name: 'Kant Jonas' }] }

Aliases - Renaming keys

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    changeUsers: users(id: "200") {
      name
    }
  }
`

console.log(users) //{ changeUsers: [{ name: 'Kant Jonas' }] }

Variables

Build dynamic queries with variables.

const data = {
  users: [{
    name: 'Victor Igor',
    id: "100",
    age: 18
  }, {
    name: 'Paul Gilbert',
    id: "200",
    age: 35
  }],	
};

const variables = {
  id: "100"
};

const gql = dinoql(data, { variables })`
  users(id: $id) {
    name
  }
`

// { users: [{ name: 'Victor Igor' }] }

Conditions to get fields

You can create conditions to get a field.

const data = {
  dashboard: {
    value: '#54'	
  },
  
  name: 'Vic'
};

const variables = {
  cond: false
};

const gql = dql(data, { variables })` 
  dashboard(if: $cond) {
    value
  },
  name
}`;
//{ name: 'Vic' }

const otherGql = dql(data, { variables })` 
  dashboard(unless: $cond) {
    value
  },
  name
}`;
//{ name: 'Vic', value: '#54' }

Keep key from object

Sometimes, we need to keep specific keys.


const data = {
  requests: {
    user: {
      name: {
        text: 'Dinoql'
      },
      
      description: {
        text: 'I am dinoql.'
      }
    }
  }
}

If you wanna keep some keys, like:

//{ user: { name: 'Dinoql', description: 'I am dinoql.'} }

You can use (keep: true) in key, like:

import dinoql from 'dinoql'

//keeping user key
const user = dinoql(data)`
  requests {
    user(keep: true) {
       name {
         name: text
       },
       description {
         description: text
       }
    }
  }
`
//{ user: { name: 'Dinoql', description: 'I am dinoql.'} }

Resolvers

Resolvers provide the instructions for turning a dinoQL operation into data.

Order by

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    users(orderBy: age) {
      name,
      age
    }
  }
`

console.log(users) 

//{ users: [{ name: 'Kant Jonas', age: 35 }, { name: 'Victor Igor', age: 40 }] }

Merge

You can merge array or objects.

Array
import dinoql from 'dinoql'
const data = {
  requests: {
    users: [{ id: 10, age: 10 }]
  }
}

const variables = { 
  user: { id: 15, age: 40 }
}

const users = dinoql(data, { variables })`
  requests {
    users(merge: $user) {
      age
    }
  }
`

console.log(users) 

//{ users: [{ age: 10 }, { age: 40 }] }
Object
import dinoql from 'dinoql'
const data = {
  requests: {
    user: { id: 10, name: 'Victor Igor' }
  }
}

const variables = { 
  user: { age: 40 }
}

const user = dinoql(data, { variables })`
  requests {
    user(merge: $user)
  }
`

console.log(user) 

//{ user: { id: 10, name: 'Victor Igor', age: 40 } }

Default value

You can add default value to keys not found or values (null/undefined).

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    notfound(defaultValue: "Hello")
  }
`

console.log(users) 

// {notfound: "Hello"}

Parse to Number

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    users {
      id(toNumber: 1)
    }
  }
`

console.log(users)  //{ users: [{ id: 100 }, { id: 200 }] }

Get object values

import dinoql from 'dinoql'

const data = {
  requests: {
    user: {
      name: 'vic',
      age: 10
    }
  }
}
const gql = dinoql(data)`
  requests {
    user(getObjectValues: true)
  }
`

console.log(gql) //['vic', 10]

Parse to array

import dinoql from 'dinoql'

const data = {
  requests: {
    fields: {
      field1: 'name',
      field2: 'age'
    }
  }
}

const users = dinoql(data)`
  requests {
    fields(toArray: true)
  }
`

console.log(users)  //[{ field1: 'name' }, { field2: 'age' }]

First

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    users(first: true) {
      name
    }
  }
`

console.log(users)  //{ users: { name: 'Victor Igor' } }

Last

import dinoql from 'dinoql'

const users = dinoql(data)`
  requests {
    users(last: true) {
      name
    }
  }
`

console.log(users)  //{ users: { name: 'Kant Jonas' } }

Get Prop

import dinoql from 'dinoql'

const newData = {
  requests: {
    users: { id: 10, name: 'Victor Fellype' },
    information: { 
      title: { text: 'my title' }, 
      description: { text: 'my description' } 
    }
  }
};

without getProp

const data = dinoql(newData)`
  requests {
    users {
      name
    }
    information {
      title {
        title: text
      }
      description {
        description: text
      }
    }
  }
`

with getProp

const data = dinoql(newData)`
  requests {
    users(getProp: name)
    information {
      title(getProp: text)
      description(getProp: text)
    }
  }
`

console.log(data) // { users: 'Victor Fellype', title: 'my title', description: 'my description' }

Get Path

import dinoql from 'dinoql'

const newData = {
  requests: {
    cms: {
      footer_data: {
        social_networks: [
          { name: 'facebook', url: 'facebook.com' },
          { name: 'instagram', url: 'instagram.com' }
        ]
      }
    }
  }
};

without getPath

const data = dinoql(newData)`
  requests {
    cms {
      footer_data {
        social_networks
      }
    }
  }
`

with getPath

const socialNetworks = dinoql(newData)`
  requests(getPath: "cms.footer_data.social_networks")
`

console.log(socialNetworks) 
/* 
  { 
    requests: [ 
      { name: 'facebook', url: 'facebook.com' }, 
      { name: 'instagram', url: 'instagram.com' }
    ]
  }
*/

Building your own resolver

You can create a function to change a value in query.

import dql, { addResolvers } from 'dinoql';

const incAge = (list, right) => {
  const valueToInc = Number(right);
  return list.map(item => ({ ...item, age: item.age + valueToInc }));
};

addResolvers(({ incAge }));

const value = dql(data)`
  requests {
    users(incAge: 2) {
      name,
      age
    }
  }
`;
// { users: [{ name: 'Victor Igor', age: 42 }, { name: 'Kant Jonas', age: 37 }] }

Custom options

Keep structure

import dinoql from 'dinoql'

const users = dinoql(data, { keep: true })`
  requests {
    users(id: "200") {
      name
    }
  }
`

console.log(users)
/*
{ 
 requests: { 
   users: [{ name: 'Kant Jonas' }] 
 }
} 
*/

Improve performance πŸ„

You can improve performance parsing in build time your queries.

How ?

  1. Create files .graphql or .gql and add your queries.

  2. Import your queries from .graphql|.gql

# your queries

query MyQuery {
  requests {
    users
  }
}
//your js
import dinoql from 'dinoql'
import { MyQuery } from './MyQueries';

const users = dinoql(data)(MyQuery)
  1. Setup your webpack - example

Fragments support πŸ’₯

You can share piece of query logic.

fragment queryOne on Query {
  users {
    name
  }
}

fragment queryTwo on Query {
  products
}

query Form {
  requests {
    ...queryOne,
    ...queryTwo,
    friends
  }
}

Organizations and projects using dinoql

⚑️ List of organizations and projects using dinoql

License

The code is available under the MIT License.