npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jkt

v2.3.8

Published

Simple and efficient library for JSON data structure

Downloads

1,608

Readme

JKT Parser

Simple helper to parse your JSON.

UPDATE: Take a look at Podeng a similar parser like JKT with richer features, go visit the project here

Background

At the first time I wonder how could I make my JSON to be more manageable. So confusing when every time I checking up the right parameters to my function, make sure the produced JSON data are valid and parsing all over the JSON properties to follow my rules (types).

Then I do research and no one module is available to fit in with my case, so I built this one.

JKT is a simple Javascript module to create a structure for your JSON. It's basically just a simple parser to handle property types, the structure and provide a small helper to handle the data.

Requirements

To use JKT you need a NodeJS version 6.4.0 and up. Basically JKT really depends on ES6 style which using template literal in practice.

const jkt = require('jkt') // CommonJs

const Person = jkt`
  name: String
  age: Number
  birthday: Date
  hobbies: Array
`

Installing

As described before, you need NodeJs with version 6.4.0 and up before using this module. After that installing JKT is just simply as.

Using NPM

npm i jkt --save

Using Yarn

yarn add jkt

When finished you'll notice that this modules requires some libraries like lodash, moment and shortid.

Running the tests

The test is very very simple, you just have to clone the project, do npm install and run npm run test, nothing special.

API References

Struct

You just have to define the JKT struct once and then you could rely on them. The struct is defined by using template literal.

const Person = jkt`
  name: String
  age: Number
  birthday: Date
  Hobbies: Array
`

Available Types

| Type | Description | Show on Invalid? | Show on JSON result | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | ------------------- | | String | String type value | Yes | Yes | | String! | Force to only accept string value | No | No | | Number | Numeric type value, works for either Integer or Float | Yes | Yes | | Number! | Force to only accept numeric value | No | No | | Boolean | Boolean type value, works for either Integer or Float | Yes | Yes | | Boolean! | Force to only accept boolean value | No | No | | Date | Date type value that accept ISO 8601, supported by Moment and it is timezone aware (will convert to UTC time) based on your machine timezone | Yes | Yes | | Date! | Force to only accept valid date value and will produce timezone aware date | No | No | | DatePlain | Date type value that accept ISO 8601, supported by Moment and it is not timezone aware | Yes | Yes | | DatePlain! | Force to only accept valid date value and will not produce timezone aware date | No | No | | Array | Array type value | Yes | Yes | | Array! | Force to only accept array value | No | No | | Object | Object type value | Yes | Yes | | Object! | Force to only accept object value | No | No | | Function | Function type value | No | No | | Function! | Force to only accept function | No | No | | ANY | Any type value will be valid | Yes | Yes |

Instance of Struct

You can assume the Person as a structure for json data, then every time you do parsing, you just have to pass an argument into Person.

const aditya = Person({
  name: "Aditya Kresna",
  age: '26',
  birthday: '1991-06-18' // ISO 8601
})

// now aditya is the instance of Person

Then you could use aditya properties or produce valid JSON format from it

aditya.name // "Aditya Kresna"
aditya.birthday // moment time
aditya.toJSON() // produce valid json format
aditya.j() // the shorthand method

One thing that you should know is if JKT fails to identify type of the value, it will returning null as a default, except you use force type like String! and Number!

> See the result on RunKit

One Line vs Multi Line

There is a few method you can follow while making a struct, One Line and Multi Line. If you think your struct object is short and don't wanna make more space with using multi lines, you could simply create a struct separated by comma ,.

const Animal = jkt`type: String, color: String, isWild: Boolean`

or by multiple lines like this

const Animal = jkt`
  type: String
  color: String
  isWild: Boolean
`

const Animal2 = jkt`
  type: String,
  color: String,
  beast: Boolean
`

const Animal3 = jkt`
  type: String!,
  color: String!,
  beast: Boolean
`

> See the result on RunKit

Custom Predefined Value

When you need to setup custom value upfront, without checking it's type or doing some validations, You could use it as a predefined value by put them inside of expression ${}. Predefined value is the value you define when defining the struct.

const Mother = jkt`
  name: String
  birthday: Date
  haveChild: ${true}
`

const angela = Mother({
  name: "Angela",
  Birthday: "1990-06-06"
})

const christy = Mother({
  name: "Angela",
  Birthday: "1990-06-06",
  haveChild: false
})

const Person = jkt`
  name: String
  sayTheWords: ${(words) => `Hi, ${words}`},
  someOptions: ${{some: "options"}}
`

const aditya = Person({
  name: "Aditya"
})

angela.haveChild // true
christy.haveChild // false

aditya.sayTheWords('How are you') // "Hi, How are you"

aditya.j()
// { name: "Aditya", someOptions: { some: "options" } }

> See the result on RunKit

You could pass anything you want, but if you pass a function for example, it will not showing on the output when you calling toJSON or j function, because the value wasn't a valid JSON type.

Extending Struct

Once you define a struct it possible to extend into another struct.

const Person = jkt`
  name: String
  age: Number
  hobby: Array
  birthday: Date
`

const Driver = Person`
  useBike: Boolean
  useCar: Boolean
`

const Doctor = Person`
  specialist: String
  hospitalLocation: String
`

> See the result on RunKit

Both of Driver and Doctor is a child of Person, so you will get the name, age, hobby and birthday properties when you do parse of the driver and doctor instance.

Removing Parent Property

Sometimes we want to extend from existing struct but on a few situation we don't wanna include some properties. By using !DELETE we can exclude the property when extending from existing struct.

const Person = jkt`
  name: String
  age: Number
  hobby: Array
  drinkBeer: Boolean
`

const Child = Person`
  toys: Array
  drinkBeer: !DELETE   // this "drinkBeer" will be deleted on child struct
`

> See the result on RunKit

Check The Instance and Child

It is also possible to checking the instance and child.

const Person = jkt`
  name: String
  age: Number
  hobby: Array
`
const Child = Person`
  toys: Array
  doingHomework: Boolean
`

const Mother = Person`
  singleParent: Boolean
`

const John = Child({
  name: "John Doe"
})

Child.childOf(Person) // true
Mother.childOf(Person) // true

John.instanceOf(Person) // true
John.instanceOf(Child) // true

> See the result on RunKit

Strict Types

As mentioned before (on a table), every unsupplied value or invalid type would make the property have null value when parsed. But we can force the property to not exist when invalid value raised.

const Person = jkt`
  name: String
  age: Number!
  hobby: Array!
`

const John = Person({ name: "John Doe", age: "not sure"})

John.j() // { name: "John Doe" }

> See the result on RunKit

ENUM Value

We often need to reference some value based on it's own defined types. This could be done with ENUM, where ENUM is a feature when we need some property to strictly follow the type as we defined on ENUM itself.

const Colors = jkt.ENUM`
  RED: Maroon
  WHITE
  BLUE: ${'just blue'}
`

const TSize = jkt.ENUM`small, medium, large, extra_large: ${'EXTRA-LARGE'}`

const TShirt = jkt`
  model: String
  brand: Number!
  color: ${Colors}
  size: ${TSize}
`

// Calling enum directly
Colors() // { RED: 'Maroon', WHITE: 'WHITE', BLUE: 'just blue' }

TSize() // { SMALL: 'SMALL', MEDIUM: 'MEDIUM', LARGE: 'LARGE', EXTRA_LARGE: 'EXTRA-LARGE' }


// Callling enum from struct using "E" property
TShirt.E.COLOR.RED // "Maroon"

> See the result on RunKit

The E stands for the collection of the ENUM on TShirt. If you want to see complete values of ENUM just take the E property.

All enum properties and value would be converted to Upper-Case string (even if it's a number), it doesn't accept any special characters except underscore _ and If you want to set custom value just use an expression ${}.

Nested Struct

Every single struct we define is an independent structure that could be used with another struct. By this point you got a very reusable component as you may need the same structure on another struct (eg. as a collection).

const Person = jkt`
  name: String
  age: Number
  birthday: Date
`

const SchoolClass = jkt`
  name: String
  grade: Number
  teacher: ${Person}
`

// show the schema
SchoolClass.schema

/**
{
  name: "String",
  grade: "Number",
  teacher: {
    name: "String",
    age: "Number",
    birthday: "Date"
  }
}
*/

const mySchoolClass = SchoolClass({
  name: 'Awesome Class',
  grade: '10',
  teacher: {
    name: 'Amelia',
    age: 25,
    birthday: '1992-05-31' // ISO 8601
  }
})

mySchoolClass.j()
/**
{ name: "Awesome Class",
  grade: 10,
  teacher: {
    name: "Amelia",
    age: 25,
    birthday: "1992-05-30T17:00:00.000Z"
  }
}
*/

> See the result on RunKit

Array Container

Container to keep our struct inside json array.

const Person = jkt`
  name: String
  age: Number
  birthday: Date
`

const SchoolClass = jkt`
  name: String
  grade: Number
  students: ${jkt.c.array(Person)}
`

const strictNull = false  // if some value has null, the item will not added into list
const defaultToArray = true // set default value to array ( not null )
const People = jkt.array(Person, strictNull, defaultToArray)

const listOfPeople = People([
  {
    name: 'Aditya',
    age: '27',
    birthday: '1991-06-18',
  },
  {
    name: 'John',
    age: '20',
    birthday: '1996-10-04',
  },
])

> See the result on RunKit

Custom Value Translator

With all of provided parsers, I believe there is always not enough to cover up our desired types. So here's translator comes in.

const Person = jkt`
  name: String
  age: Number
  birthday: ${jkt.trans.custom(val => "I'm old man =,=")}
`

const nina = Person({
  name: "Nina",
  age: "25",
  birthday: new Date() // this will produce "I'm old man =,="
});

nina.birthday // "I'm old man =,="
nina.j().birthday // "I'm old man =,="

> See the result on RunKit

Arrow Mapping Key -> Values

With mapping you could reuse key-value on supplied json to make your own custom key based on that source.

const Person = jkt`
  name: String
  name->full_name: String // mapping from source key (name) to new key (full_name)
  address: String
  address->address2: String // mapping from source key (address) to new key (address2)
  age: Number
  age->ageInString: String // mapping from source key (age) to new key (ageInString) with type String
`

const aditya = Person({
  name: "Aditya",
  age: "27",
  address: "Kota Bekasi"
});

aditya.name // "Aditya"
aditya.full_name // "Aditya"
aditya.address2 // "Kota Bekasi"
aditya.age // 27
aditya.ageInString // "27"

> See the result on RunKit

Struct & Instance References

These are detailed function & properties you could use when using jkt struct. You shouldn't use the following reserved words as a property for your struct, because it was reserved to support the module.

Struct Property & Function

| Name | Type | Description | | ---------- | -------------- | ---------------------------------------------------------------------------------------------------------------------- | | isJKT | Boolean (true) | Nothing special about this, just used to to identify JKT struct on internal parser. | | schema | JSON | Schema of struct, you could inspect this property after defining the struct. | | childOf | Function | To check if the struct is a child of the given struct | | __id | String | The id of struct, every struct has an unique id generated based on shortid library | | __schema | JSON | The dirty schema of the struct which used internally to parse value | | E | JSON | A container of all enum values on the struct, this property only available when we set some property with ENUM type. |

Instance Function

| Name | Description | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------- | | instanceOf | To identify the instance of struct | | getSchema | To get struct schema from the instance | | getDirtySchema | To get the real struct schema from the instance. The result including the function and properties to do parse inside the module | | toJSON | To get valid json from the instance. | | j | To get valid json from the instance. This is a shorthand method of toJSON | | toString | To get json string from the instance. |

Author

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments

  • This module may have some limitation based on reserved naming of the methods and properties
  • Highly inspired with styled-components style
  • This module may still buggy, make a pull request or make an issue if you found them.