Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/react angular #144

Merged
merged 4 commits into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
<a name="3.4.1"></a>
# 3.4.1 (2021-06-11)

### Bug fixes

* **getPropertyNames:** improve regex to take in account Angular and React builds ([#132](https://github.com/GillianPerard/typescript-json-serializer/issues/132)) ([#135](https://github.com/GillianPerard/typescript-json-serializer/issues/135)) ([8470679](https://github.com/GillianPerard/typescript-json-serializer/commit/84706799a9e51aea17ddb6d42200af5bdcc3ed05))
* **docs:** add a section to explain how to use the library with CRA (create-react-app) ([#132](https://github.com/GillianPerard/typescript-json-serializer/issues/132)) ([2c0ddbc](https://github.com/GillianPerard/typescript-json-serializer/commit/2c0ddbc8793e44e1d8a6db00720e16df6a203df0))

<a name="3.4.0"></a>
# 3.4.0 (2021-06-08)

Expand Down
122 changes: 108 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![](https://github.com/GillianPerard/typescript-json-serializer/workflows/Build/badge.svg)
![npm](https://img.shields.io/npm/dt/typescript-json-serializer)
![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/typescript-json-serializer/3.4.0)
![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/typescript-json-serializer/3.4.1)
[![Coverage Status](https://coveralls.io/repos/github/GillianPerard/typescript-json-serializer/badge.svg)](https://coveralls.io/github/GillianPerard/typescript-json-serializer)
[![Known Vulnerabilities](https://snyk.io/test/github/gillianperard/typescript-json-serializer/badge.svg?targetFile=package.json)](https://snyk.io/test/github/gillianperard/typescript-json-serializer?targetFile=package.json)

Expand Down Expand Up @@ -31,12 +31,19 @@ For example:
}
```

**WARNING:** If you use CRA (create-react-app) please refer to the [Using with Create React App](#using-with-create-react-app) section.

## Import

There are two decorators and two functions that you can import inside a typescript file.

```typescript
import { JsonProperty, Serializable, deserialize, serialize } from 'typescript-json-serializer';
import {
JsonProperty,
Serializable,
deserialize,
serialize
} from 'typescript-json-serializer';
```

## Library
Expand Down Expand Up @@ -73,7 +80,8 @@ type SerializableOptions = {
// - the names of properties to merge (the `formatPropertyNames`
// from `Serializable` decorator is ignored)
// - a boolean to tell that the property is a dictionary
// - a boolean to tell that the property is required (throw an error if undefined, null or missing)
// - a boolean to tell that the property is required
// (throw an error if undefined, null or missing)

// BREAKING CHANGES: since version 3.0.0
// - onSerialize has become afterSerialize
Expand Down Expand Up @@ -186,7 +194,8 @@ export class Human extends LivingBeing {
// This comment works
// Override LivingBeing id property name
// and set required to true
@JsonProperty({name: 'humanId', required: true}) public name: string,
@JsonProperty({name: 'humanId', required: true})
public name: string,
public id: number,
@JsonProperty() public gender: Gender,
/** This comment works */
Expand Down Expand Up @@ -214,7 +223,8 @@ export class Employee extends Human {
/** The employee's email */
@JsonProperty({required: true}) email: string;

/** Predicate function to determine if the property type is PhoneNumber or a primitive type */
/** Predicate function to determine if the property type
* is PhoneNumber or a primitive type */
@JsonProperty({
predicate: property => {
if (property && property.value !== undefined) {
Expand Down Expand Up @@ -281,7 +291,8 @@ export class Panther extends Animal {
}


// Create a serializable class that extends Animal (which extends LivingBeing): Snake
// Create a serializable class that extends Animal
// (which extends LivingBeing): Snake

@Serializable()
export class Snake extends Animal {
Expand All @@ -295,7 +306,8 @@ export class Snake extends Animal {
}


// Create a serializable empty class that extends Animal (which extends LivingBeing): UnknownAnimal
// Create a serializable empty class that extends Animal
// (which extends LivingBeing): UnknownAnimal

@Serializable()
export class UnknownAnimal extends Animal {
Expand All @@ -308,12 +320,20 @@ export class UnknownAnimal extends Animal {
// Create a serializable class: Zoo

// Function to transform coordinates into an array
const coordinatesToArray = (coordinates: { x: number; y: number; z: number }): Array<number> => {
const coordinatesToArray = (coordinates: {
x: number;
y: number;
z: number;
}): Array<number> => {
return Object.values(coordinates);
};

// Function to transform an array into coordinates
const arrayToCoordinates = (array: Array<number>): { x: number; y: number; z: number } => {
const arrayToCoordinates = (array: Array<number>): {
x: number;
y: number;
z: number
} => {
return {
x: array[0],
y: array[1],
Expand All @@ -324,7 +344,9 @@ const arrayToCoordinates = (array: Array<number>): { x: number; y: number; z: nu
// A predicate function use to determine what is the
// right type of the data (Snake or Panther)
const snakeOrPanther = animal => {
return animal && animal['isPoisonous'] !== undefined ? Snake : Panther;
return animal && animal['isPoisonous'] !== undefined
? Snake
: Panther;
};

@Serializable()
Expand All @@ -339,7 +361,10 @@ export class Zoo {

// Property with transform functions executed respectively
// on serialize and on deserialize
@JsonProperty({ beforeDeserialize: arrayToCoordinates, afterSerialize: coordinatesToArray })
@JsonProperty({
beforeDeserialize: arrayToCoordinates,
afterSerialize: coordinatesToArray
})
coordinates: { x: number; y: number; z: number };

// Array of none-basic type elements
Expand Down Expand Up @@ -393,11 +418,15 @@ export class Organization extends Society {
// To merge multiple properties in a single one
// use the property `names`.
// If you don't create your own merge with the `beforeDeserialize`
// and `afterSerialize` function, it will just merge properties in this
// one when using `deserialize` and split back
// and `afterSerialize` function, it will just merge properties
// in this one when using `deserialize` and split back
// when using `serialize`
@JsonProperty({
names: ['_mainShareholder', '_secondaryShareholder', '_thirdShareholder'],
names: [
'_mainShareholder',
'_secondaryShareholder',
'_thirdShareholder'
],
type: Human,
beforeDeserialize: value => Object.values(value),
afterSerialize: value => {
Expand Down Expand Up @@ -595,6 +624,71 @@ const data = serialize(organization);
const data = serialize(organization, false);
```

## Using with Create React App

If you are using [CRA](https://create-react-app.dev/) to create your React App you will need to add a custom configuration in order to add `Decorator` and `Metadata` features (not supported by React) using [customize-cra](https://github.com/arackaf/customize-cra) and [react-app-rewired](https://github.com/timarney/react-app-rewired/).

First, don't forget to add `emitDecoratorMetadata` and `experimentalDecorators` inside the `tsconfig.json` file (explain in the [Installation](#installation) section).

Next install the dependencies to override the React build config:

```sh
npm install -D customize-cra react-app-rewired
# or
yarn add -D customize-cra react-app-rewired
```

Replace the scripts using `react-scripts` in the `package.json` file by `react-app-rewired`:

```json
// example
{
...
"scripts": {
...
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
...
},
...
}
```

Install dependencies to add support for `Decorator` and `Metadata`:

```sh
npm install -D @babel/plugin-proposal-decorators \
@babel/preset-typescript \
babel-plugin-parameter-decorator \
babel-plugin-transform-typescript-metadata
# or
yarn add -D @babel/plugin-proposal-decorators \
@babel/preset-typescript \
babel-plugin-parameter-decorator \
babel-plugin-transform-typescript-metadata
```

Create the `config-overrides.js` file in the root of your project
with the following content:

```js
const {
override,
addDecoratorsLegacy,
addBabelPlugin,
addBabelPreset,
} = require("customize-cra");

module.exports = override(
addDecoratorsLegacy(),
addBabelPlugin("babel-plugin-parameter-decorator"),
addBabelPlugin("babel-plugin-transform-typescript-metadata"),
addBabelPreset(["@babel/preset-typescript"])
);
```

## Test

```sh
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json-serializer",
"version": "3.4.0",
"version": "3.4.1",
"description": "Typescript library to serialize classes into json and deserialize json into classes.",
"source": "src/index.ts",
"main": "dist/index.cjs.js",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function getPropertyNames(ctor: object): Map<number, string> {

// Parse function body
const constructorParamPattern = /(?:.*(?:constructor|function).*?(?=\())(?:\()(.+?(?=\)))/m;
const propertyPattern = /(?:this\.)([^\n\r\t\f\v;]+)([\s;])/gm;
const propertyPattern = /(?:this\.)([^,;\n}]+)/gm;
const propertyNames = new Map<number, string>();
const paramsExecArray = constructorParamPattern.exec(ctorWithoutSuccessiveWhiteSpaces);

Expand Down