Giter VIP home page Giter VIP logo

pichillilorenzo / jackson-js Goto Github PK

View Code? Open in Web Editor NEW
91.0 91.0 12.0 3.08 MB

JavaScript object serialization and deserialization library using decorators. It supports also advanced Object concepts such as polymorphism, Object identity and cyclic objects.

Home Page: https://pichillilorenzo.github.io/jackson-js/latest/index.html

License: MIT License

JavaScript 1.53% TypeScript 98.47%
jackson-javascript jackson-js jackson-json javascript javascript-library json json-decoder json-decorators json-deserialization json-encoder json-parse json-parser json-serialization json-stringifier json-stringify

jackson-js's Introduction

Hi πŸ‘‹, I'm Lorenzo Pichilli

A Heroku Architecture Designer and a Software Engineer mostly focused on Web (Full Stack) and Mobile Development. JavaScript, TypeScript & Flutter enthusiast πŸ’™.

pichillilorenzo

Latest Blog posts

Connect with me:

lorenzopichilli lorenzo-pichilli 4637638 lorenzopichilli @pichillilorenzo

Β pichillilorenzo

Support me and my projects

Donate with PayPal

jackson-js's People

Contributors

pichillilorenzo 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

jackson-js's Issues

Apply JSON to existing object using JsonProperty or other descriptors

NodeJS

Is there a way to use jackson-js to apply either a JSON string or an already transformed JSON plain javascript object to an existing object (typescript class) so that JSON properties are applied (copied / set) based on the @JsonProperty (or other descriptors within jackson-js)? (eg: ObjectMapper.apply(targetObject, "{ name: 'John', age: 45 }") ) where output "targetObject" then has all fields / properties with jackson-js descriptors values applied. (Apply should incorporate views and other jackson-js logic)

serialisation support for custom date implementations like moment-js

Description

What you'd like to happen:

i've tried running the code below in order to get my moment object into a specific shape when making a request but it seems to be ignored as it ignores the configuration i provide(uses default config instead(toString()))

ie:

export class TestClass {
  @JsonProperty()
  @JsonClassType({ type: () => [Moment] })
  @JsonFormat({
    shape: JsonFormatShape.STRING,
    pattern: 'YYYY-MM-DD',
  })
  someDateInMoment: Moment;
}

const testObj: TestClass = {
  someDateInMoment: moment()
}

const result = new JsonStringifier().transform(testObj, {
      mainCreator: () => [TestClass]
});

console.log(result); // < ------- {someDateInMoment: 'Fri Jan 15 2021 20:17:21 GMT+0000'}
// i would expect it to produce this: {someDateInMoment: '2021-01-15'}

Metadata not stored correctly using Safari + Webpack

Environment

Any Safari browser with client code that is webpacked.

Description

Expected behavior:

JsonProperty and its siblings annotations are stored correctly against constructor parameters.

Current behavior:

Annotations used against constructor parameters are stored against the wrong object and then are "missing" when the code attempts to read them back.

Steps to reproduce

  1. Build package that serializes/deserializes by using JsonProperty annotations on typescript constructor property definitions.
  2. Use package in app that is webpack'd (e.g. using Angular in production mode)
  3. Attempt to use code that serializes/deserializes; which fails due to missing JsonProperty metadata.

Metrics/Comparison

Would suggest adding metrics for comparison against other validation frameworks (Joi for example) to see how much overhead this adds vs. no validation (just json stringify/parse) or input validation including valid/invalid data in both shallow and deeper object structures. Using multiple simultaneous requests and measuring in requests per second over multiple seige runs on the same hardware.

Fails when client package is minified

Environment

Any environment that minifies code. For example, Angular production builds which use WebPack with optimization enabled.

Description

Minification should not have any effect on usage including serialization and/or deserialization.

After minification serialization/deserialization fails with the error Invalid Keyword. This can be traced to an issue with getArgumentNames and meriyah's parseScript failing to parse the minified function signature.

Also, it appears that even if the parsing succeeded the argument names would then be incorrect but I am not sure if this affects usage.

Steps to reproduce

  1. Create a class that uses JsonCreator or JsonPropertys on the constructor.
  2. Minify the class
  3. Attempt to serialize or deserialize using the minified class.

Add context parameter to JsonInclude valueFilter and contentFilter

Environment

Node.js 14.14.33

Description

Since there's only static filters, passing the current context to JsonInclude JsonIncludeOptions.valueFilter and JsonIncludeOptions.contentFilter would allow to recreate almost the same as the Java Jackson PropertyFilter. Currently, the only parameter passed to valueFilter and contentFilter is the value of the property to be inspected. This only allows simple validations like null or empty value detection and or global constants comparison. Having the context object as a parameter would allow real dynamic filtering.

Current Code

  private stringifyJsonInclude(obj: any, key: string, context: JsonStringifierTransformerContext): boolean {
    const currentMainCreator = context.mainCreator[0];

    let jsonInclude: JsonIncludeOptions =
      getMetadata('JsonInclude', currentMainCreator, key, context);
    if (!jsonInclude) {
      jsonInclude = getMetadata('JsonInclude', currentMainCreator, null, context);
      jsonInclude = jsonInclude ? jsonInclude : context.features.serialization.DEFAULT_PROPERTY_INCLUSION;
    }

    if (jsonInclude) {
      const value = obj[key];
      switch (jsonInclude.value) {
      case JsonIncludeType.NON_EMPTY:
        return !isValueEmpty(value);
      case JsonIncludeType.NON_NULL:
        return value != null;
      case JsonIncludeType.NON_DEFAULT:
        return value !== getDefaultValue(value) && !isValueEmpty(value);
      case JsonIncludeType.CUSTOM:
        return !jsonInclude.valueFilter(value);
      }
    }

    return true;
  }

Suggested update

  private stringifyJsonInclude(obj: any, key: string, context: JsonStringifierTransformerContext): boolean {
    const currentMainCreator = context.mainCreator[0];

    let jsonInclude: JsonIncludeOptions =
      getMetadata('JsonInclude', currentMainCreator, key, context);
    if (!jsonInclude) {
      jsonInclude = getMetadata('JsonInclude', currentMainCreator, null, context);
      jsonInclude = jsonInclude ? jsonInclude : context.features.serialization.DEFAULT_PROPERTY_INCLUSION;
    }

    if (jsonInclude) {
      const value = obj[key];
      switch (jsonInclude.value) {
      case JsonIncludeType.NON_EMPTY:
        return !isValueEmpty(value);
      case JsonIncludeType.NON_NULL:
        return value != null;
      case JsonIncludeType.NON_DEFAULT:
        return value !== getDefaultValue(value) && !isValueEmpty(value);
      case JsonIncludeType.CUSTOM:
        return !jsonInclude.valueFilter(value, context);
      }
    }

    return true;
  }

Another way to allow dynamic filtering would be to add a JsonFilterType.CUSTOM and a new JsonFilter property to specify a method, just like JsonIncludeOptions.valueFilter. This would mimic the Java filter implementation:

		SimpleFilterProvider filters = new SimpleFilterProvider();
		filters.addFilter("myFilter", MyClass.staticFilterMethod());

For now, it seems impossible to filter a property based on a context value or on a custom validation against other instance properties.

Having all core methods set to private makes any little overrides impossible. Being able to simply extend the JsonStringifier class to override few methods would have been an easy solution to easily implement dynamic filtering.

BigInt tests fail in browsers that do not implement it

Environment

Browsers that do not implement BigInt. For example, Safari <= 13.x

Description

In browsers that do not implement BigInt the if (BigInt) {...} test for existence fails because no symbol named BigInt exists.

Steps to reproduce

Attempt any usage of library in Safari 13.x

Slow for parsing large arrays containing objects

Environment

Browser. Timing tested in latest Firefox.

Description

During experimentation with Jackson-JS we noticed that its JSON deserialization is rather slow for large arrays. The JSON response we parse is an array containing roughly 1200 of the below objects - and parsing takes about 15 seconds.

I'm aware this use case is rather extreme, but unfortunately we are dealing with a legacy API within an enterprise here - so things won't improve somewhen soon.

import {
  JsonIgnoreProperties,
  JsonProperty,
  JsonAlias
} from 'jackson-js';

@JsonIgnoreProperties({ value: [
  'abc',
  'def',
  //... 67 more ignore properties
]})
export class MyModel {

	@JsonProperty()
	@JsonAlias({values: ['xyz']})
	myVarName: number;

	// ... 18 more properties with @JsonProperty and @JsonAlias
}

What you'd like to happen:

I'd love to hear your thoughts on strategies on how to mitigate the parsing impact and/or speed it up.

Alternatives you've considered:

  • Obviously, we can cache the result - but 15 secs still seems way too slow.
  • Although building a paging into the backend API would solve this, this is very unlikely to happen within a reasonable time span

es-build is not compatible with meriyah

jackson-js-bug

Environment

node.js v14.15.4

Description

repo https://github.com/Tarrowren/jackson-js-bug

npm run tsc:dev

npm run es-build:dev

es-build throw Class declaration must have a name in this context

at meriyah.parseScript

import { parseScript } from "meriyah";

export const getArgumentNames = (method): string[] => {
  // ...
  const ast = parseScript(code, {
    next: true,
    webcompat: true,
    directives: true,
  });
  // ...
};

now I use regular expressions solve it

export const getArgumentNames = (method): string[] => {
  return method
    .toString()
    .match(/constructor\(.*\)/)[0]
    .match(/[^constructor\(].*[^\)]/)[0]
    .split(", ");
};

(angular) Unable to serialize Date with JsonFormatShape.STRING

Disclaimer : please excuse me if this is not the good way to submit this problem

Environment

Angular version:
9 (compiler 9.1.9)

Description

Expected behavior:
Correct serialisation of Date field

Current behavior:
Error in console :
ERROR Error: No date library has been set. To be able to use @JsonFormat() on class properties of type "Date" with JsonFormatShape.STRING, a date library needs to be set. Date libraries supported: "https://github.com/moment/moment", "https://github.com/iamkun/dayjs/".

Steps to reproduce

  1. Create an Angular project (i.e. with stackblitz) then add dependencies in package.json
...
    "dayjs": "^1.8.28", <-- added for try but it's doesn't work
    "jackson-js": "^1.1.0",
    "moment": "^2.27.0",
...
  1. Create an entity with a Date field like :
export class User {
  
  @JsonProperty()
  @JsonClassType({type: () => [Date]})
  @JsonFormat({
    shape: JsonFormatShape.STRING,
    pattern: 'YYYY-MM-DD hh:mm:ss',
  })
  birthdate:Date;
}
  1. Then instanciate class, fill it and try to serialize
    let  user=new User();
    user.birthdate=new Date();

    let om = new ObjectMapper(); 
    let stringifiedUser = om.stringify<User>(user);

The console shows the error given higher.

I may add that I've tried import * as moment from 'moment'; without success.

Is there something I'm missing in configuration ? I haven't seen anything in the documentation.

Keep the good work, it's about to save my day (well, week I should say :) ): your library really rocks.

Using JsonIdentityInfo prevent building with aot

Description

Expected behavior:
When compiling a class with aot in prod there should be no error

Current behavior:
It cannot compile because we get a "Only initialized variables and constants can be referenced in decorators"

Steps to reproduce

  1. Create a Type
  2. Add to the type the JsonIdentifyInfo annotation
  3. Compiles with aot option at true

JsonStringifier not replacing my keys

Hello!

My data class is as follows:

export class UserInfo {
    constructor(
        @JsonProperty({ value: '0' })
        public dateOfBirth: Timestamp,
        @JsonProperty({ value: '1' })
        public email: string,
    ) { }
}

however JsonStringifier.transform() or .stringify() never returns the key that I specified in JsonProperty. It returns the name of the variable as a key.

Bundle size is huge: 124.7kb

See: https://bundlephobia.com/[email protected]

125kb for JSON serializing/deserializing is unacceptable for almost every frontend project I can think of. I didn't check the contents of the bundle nor the whole codebase but I guess there's something wrong with your bundling process and it includes some unrelated stuff into the bundle. FYI.

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.