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

serializy

v1.0.0-beta.1

Published

Object schema validation and data serialization

Downloads

60

Readme

serializy

license npm build status downloads per month min size minzip size install size

❓ What is that ?

This thing allows you to don't have to worry about changing server-side structures!

Sometimes when server change JSON structures or frontend start using different API
These situations can make some problems in frontend applications
Because mostly use the same structure from server when develop user interfaces

But with serializy you can describe structure which you will use and which server wants to see

Sounds interesting, yeah ? :-)
Scroll down and take a look at the examples ;-)

💡 How to use

Nothing to hard, just create a class or simple object which will contain all your structure declarations (using field(), fieldArray()).
And send this class/object to the model() function as argument
Like in example:

import { field, fieldArray, model } from 'serializy'

class DeveloperDeclaration {
  likeCoffee = field('LIKE_COFFEE', 'boolean')
  languages = fieldArray('LaNgUagEs', 'string')
}

Creating declaration using class is not necessarily, you can create just a simple object:


const DeveloperDeclaration = {
  likeCoffee: field('LIKE_COFFEE', 'boolean'),
  languages: fieldArray('LaNgUagEs', 'string'),
}
const DeveloperModel = model(DeveloperDeclaration)

And when you get server structure just create instance of your declared model:


const ServerStructure = {
  LIKE_COFFEE: true,
  LaNgUagEs: ['GoLang', 'Python']
}

const developer = new DeveloperModel(ServerStructure)
/*
  developer object will be
  {
    likeCoffee: true,
    languages: ['GoLang', 'Python']
  }
*/

But what if you need to change your client model and send it to the server ?
You can use .deserialize() of the each created instance of declared model:


developer.likeCoffee = false
developer.languages.push('JavaScript')

developer.deserialize()
/*
{
  LIKE_COFFEE: false,
  LaNgUagEs: ['GoLang', 'Python', 'JavaScript']
}
*/

Also your created structure declaration (like DeveloperModel) have methods:

  • .serialize(serverModel) - to convert server-side structure to client-side
  • .deserialize(clientModel) - to convert client-side structure to server-side
    In addition, structure declarations have methods:
  • .getUsagePropertyNames() - returns array of usage property names declared in model
  • .getOriginalPropertyNames() - returns array of original property names declared in model
  • .getPropertiesMap(reverseNames?: boolean) - returns map where key is usage property name and value is original property name. reverseNames - just changing sides key/value

📚 Documentation

Serializy have exports: field(), fieldArray(), model()

🔹 field(...options: FieldOptions)[Source]

This function needed for transforming property of the original structure to usage property.
Syntax: field(...options: FieldOptions) or field(...options: FieldOptions)(propertyOptions: Partial<CommonPropertyOptions>)

Property options it is configuration object which can allows to change various behaviour of this property. Currently object have:

{
  optional: boolean
  // true - will say to serializy that this property
  // can be not contains in original/usage structure
  // By default: false
}

For example, you've got object { FirsT_naMe: 'John' } and you need to convert property "FirsT_naMe" to the "firstName", you can just write:

  const Struct = model({ // it is required wrapper for structure declarations
    firstName: field('FirsT_naMe', 'string')
    // firstName - name of the usage property
    // 'FirsT_naMe' (first arg) - name of the original property
    // 'string' (second arg) - type of the both sides properties
  })

Or you've got object with string value of number like { Age: '19' } but you need to use type number, you can just write:

  const Struct = model({ // it is required wrapper for structure declarations
    age: field('Age', 'string', 'number')
    // firstName - name of the usage property
    // 'FirsT_naMe' (first arg) - name of the original property
    // 'string' (second arg) - type of original property
    // 'number' (third arg) - type of usage property
  })

Options:

  • field(originalPropertyName: string, originalType?: string, usageType?: string)

    This type of the field declaration allows you to describe simple properties which are mostly primitive values.
    Arguments:
    - originalPropertyName: string - name of the property in original structure. Original property with this name will be assigned to usage property.
    - originalType?: string - type of the original property.
    - usageType?: string - needed type of the usage property.

    note: originalType and usageType should be one of the following strings ('boolean', 'number', 'string', 'object', 'any')

    Examples:

    
    const Model = model({
      someProp: field('SomeProp','number','string')
      hidden: field('Hidden','boolean')({ optional: true })
      any: field('Any', 'any')
    })
    
    const structure = new Model({
      SomeProp: 12345,
      Any: { foo: 'bar' }
    })
    
    console.log(structure.someProp) // '12345'
    console.log(structure.deserialize()) // { SomeProp: 12345, Any: { foo: 'bar' } }

image

  • field(originalPropertyName: string, modelDeclaration: ModelDeclaration)

    This type of the field declaration allows you to describe complex structures to usage structures
    Arguments:
    - originalPropertyName: string - name of the property in original structure. Original property with this name will be assigned to usage property.
    - modelDeclaration: ModelDeclaration - model declaration needed for convert original object into usage object.
    modelDeclaration should be object/model(DeclarationsClass)
    And keys/properties should have values created via field(), fieldArray() function

    Examples:

    const FooModel = model(class FooModel {
      foo = field('Foo', 'number', 'string')
    })
    
    class Model = model({class Model {
      fooStruct = field('FooStruct', FooModel)
    }})
    class Model = model({class Model {
      // or you can not create additional wrapped model() class
      fooStruct = field('FooStruct', {
        foo = field('Foo', 'number', 'string')
      })
    }})
    
    const fooBarStruct = new Model({
      FooStruct: { Foo: 12345 }
    })
    
    console.log(fooBarStruct) // { fooStruct: { foo: '12345' } }
    console.log(fooBarStruct.deserialize()) // { FooStruct: { Foo: 12345 } }

image

  • field(customSerializer: function, customDeserializer?: function)

    You can attach custom serializer/deserializer for specific cases.
    Arguments:
    - customSerializer: function - this function should return value of the usage property. Takes one argument - original structure
    - customDeserializer?: function - this function should return object which will been merged to the original structure. Takes one argument - usage structure

    Examples:

    const Model = model({
      barBaz: field(
        ({ bar, baz }) => `${bar}/${baz}`,
        ({ barBaz }) => {
          const [bar, baz] = barBaz.split('/')
          return { bar, baz }
        }
      ),
      foo: field(({ foo }) => foo, ({ foo }) => ({ foo })) // in this case just better to use field('foo')
    })
    
    const structure = new Model({
      foo: 'foo',
      bar: 'bar',
      baz: 'baz'
    })
    
    console.log(structure) // { barBaz: 'bar/baz', foo: 'foo' }
    console.log(structure.deserialize()) // { foo: 'foo', bar: 'bar', baz: 'baz' }

image

  • field({ name: 'property_name', type: 'original_type', usageType: 'usage_type' }: object)

    This is just another way to describe property.
    Properties:
    - name: string - key name in the original structure
    - type?: PropertyType - type of the original property
    - usageType?: PropertyType - type for usage property
    - arrayType?: boolean - property have array type or not
    - optional?: boolean - same from property options but have more priority

    Examples:

    const Model = model({
      someProp: field({
        name: 'SomeProp',
        optional: true,
        type: 'number',
        usageType: 'string'
      })
    })
    
    const structure = new Model({
      SomeProp: 12345
    })
    
    console.log(structure.someProp) // '12345' because usageType - 'string'
    console.log(structure.deserialize()) // { SomeProp: 12345 }

image

🔹 fieldArray()[Source]

This is the same thing like field() but it needs to describe array of data

  const Struct = model({ // it is required wrapper for structure declarations
    stringsArray: fieldArray('DataArray', 'string')
    // stringsArray - name of the usage property
    // 'DataArray' (first arg) - name of the original property which should be array
    // 'string' (second arg) - type of the each element in array
  })

Argument variations:

  • fieldArray(originalPropertyName: string, originalType?: string, usageType?: string)
    - originalPropertyName - name of property which should be exist in original structure
    - originalType?: string - type of the original property.
    - usageType?: string - needed type of the usage property.

  • fieldArray(originalPropertyName: string, modelDeclaration: ModelDeclaration)
    - originalPropertyName - name of property which should be exist in original structure
    modelDeclaration should be object/model(DeclarationsClass)
    And keys/properties should have values created via field(), fieldArray() function

🔹 model()[Source]

This function allows to make model from structure declaration.
Syntax:

  model(YourStructDeclaration: object | class, config?: object)

  // YourStructDeclaration can be:

  YourStructDeclaration = {
    foo: field('foo')
  }
  class YourStructDeclaration {
    foo = field('foo')
  }

  // config contains properties:
  const config = {
    warnings: boolean // - disable/enable most warnings based on this declaration
  }

Examples:

  const Struct = model({ // it is required wrapper for structure declarations
    // your property declarations
    firstName: field('FirstName')
    lastName: field('LastName')
  })

📄 Examples

All examples are located here

example of usage 1 example of usage 2

📢 Integrations

kinka-serializy - integration serializy with http web-client kinka
axios-serializy - integration serializy with http web-client axios

📝 License

Licensed under the MIT License.