@dipscope/type-manager 4.1.0 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/{LICENSE.txt → LICENSE.md} +0 -0
- package/README.md +150 -324
- package/alias.d.ts +3 -7
- package/custom-data.d.ts +3 -8
- package/{core/default-value-resolver.d.ts → default-value-resolver.d.ts} +0 -0
- package/default-value.d.ts +4 -8
- package/discriminant.d.ts +5 -8
- package/discriminator.d.ts +3 -8
- package/factories/type-factory.d.ts +3 -3
- package/factory.d.ts +15 -8
- package/functions/get-own-reflect-metadata.d.ts +9 -0
- package/functions/get-reflect-metadata.d.ts +10 -0
- package/functions/get-words.d.ts +8 -0
- package/functions/index.d.ts +16 -0
- package/functions/is-arrow-function.d.ts +8 -0
- package/functions/is-ctor-function.d.ts +8 -0
- package/functions/is-data-view.d.ts +8 -0
- package/functions/is-float-32-array.d.ts +8 -0
- package/functions/is-float-64-array.d.ts +8 -0
- package/functions/is-int-16-array.d.ts +8 -0
- package/functions/is-int-32-array.d.ts +8 -0
- package/functions/is-int-8-array.d.ts +8 -0
- package/functions/is-uint-16-array.d.ts +8 -0
- package/functions/is-uint-32-array.d.ts +8 -0
- package/functions/is-uint-8-array.d.ts +8 -0
- package/functions/is-uint-8-clamped-array.d.ts +8 -0
- package/functions/name-of.d.ts +8 -0
- package/{core/generic-argument.d.ts → generic-argument.d.ts} +0 -0
- package/{core/generic-metadata.d.ts → generic-metadata.d.ts} +0 -0
- package/index.d.ts +39 -9
- package/index.js +1 -2
- package/{core/inject-index.d.ts → inject-index.d.ts} +0 -0
- package/{core/inject-metadata.d.ts → inject-metadata.d.ts} +0 -0
- package/{core/inject-options.d.ts → inject-options.d.ts} +2 -2
- package/inject.d.ts +2 -2
- package/injector.d.ts +13 -8
- package/injectors/singleton-injector.d.ts +2 -2
- package/{core/log-level.d.ts → log-level.d.ts} +0 -0
- package/{core/log.d.ts → log.d.ts} +41 -11
- package/{core/metadata.d.ts → metadata.d.ts} +0 -0
- package/naming-convention.d.ts +12 -8
- package/naming-conventions/camel-case-naming-convention.d.ts +1 -1
- package/naming-conventions/flat-case-naming-convention.d.ts +1 -1
- package/naming-conventions/flat-upper-case-naming-convention.d.ts +1 -1
- package/naming-conventions/kebab-case-naming-convention.d.ts +1 -1
- package/naming-conventions/kebab-upper-case-naming-convention.d.ts +1 -1
- package/naming-conventions/pascal-case-naming-convention.d.ts +1 -1
- package/naming-conventions/snake-case-naming-convention.d.ts +1 -1
- package/naming-conventions/snake-upper-case-naming-convention.d.ts +1 -1
- package/package.json +6 -3
- package/{core/property-metadata.d.ts → property-metadata.d.ts} +18 -0
- package/{core/property-name.d.ts → property-name.d.ts} +0 -0
- package/{core/property-options.d.ts → property-options.d.ts} +18 -2
- package/property.d.ts +3 -2
- package/{core/reference-callback.d.ts → reference-callback.d.ts} +1 -1
- package/reference-handler.d.ts +28 -8
- package/reference-handlers/direct-reference-handler.d.ts +11 -12
- package/reference-handlers/lead-reference-handler.d.ts +11 -12
- package/reference-handlers/path-reference-handler.d.ts +11 -12
- package/{core/reference-key.d.ts → reference-key.d.ts} +0 -0
- package/reference-value-getter.d.ts +7 -0
- package/reference-value-setter.d.ts +7 -0
- package/{core/reference-value.d.ts → reference-value.d.ts} +0 -0
- package/serializer-context-options.d.ts +43 -0
- package/{core/serializer-context.d.ts → serializer-context.d.ts} +110 -44
- package/serializer.d.ts +24 -8
- package/serializers/array-buffer-serializer.d.ts +3 -3
- package/serializers/array-serializer.d.ts +3 -3
- package/serializers/boolean-serializer.d.ts +3 -3
- package/serializers/data-view-serializer.d.ts +3 -3
- package/serializers/date-serializer.d.ts +3 -3
- package/serializers/float-32-array-serializer.d.ts +3 -3
- package/serializers/float-64-array-serializer.d.ts +3 -3
- package/serializers/int-16-array-serializer.d.ts +3 -3
- package/serializers/int-32-array-serializer.d.ts +3 -3
- package/serializers/int-8-array-serializer.d.ts +3 -3
- package/serializers/map-serializer.d.ts +15 -3
- package/serializers/number-serializer.d.ts +3 -3
- package/serializers/set-serializer.d.ts +3 -3
- package/serializers/string-serializer.d.ts +3 -3
- package/serializers/type-serializer.d.ts +3 -3
- package/serializers/uint-16-array-serializer.d.ts +3 -3
- package/serializers/uint-32-array-serializer.d.ts +3 -3
- package/serializers/uint-8-array-serializer.d.ts +3 -3
- package/serializers/uint-8-clamped-array-serializer.d.ts +3 -3
- package/{core/type-abstraction.d.ts → type-abstraction.d.ts} +0 -0
- package/{core/type-argument.d.ts → type-argument.d.ts} +0 -0
- package/{core/type-context-entry.d.ts → type-context-entry.d.ts} +0 -0
- package/{core/type-context.d.ts → type-context.d.ts} +0 -0
- package/{core/type-ctor.d.ts → type-ctor.d.ts} +0 -0
- package/{core/type-fn.d.ts → type-fn.d.ts} +0 -0
- package/{core/type-like.d.ts → type-like.d.ts} +0 -0
- package/type-manager-options.d.ts +5 -5
- package/type-manager.d.ts +10 -10
- package/{core/type-metadata-resolver.d.ts → type-metadata-resolver.d.ts} +0 -0
- package/{core/type-metadata-symbol.d.ts → type-metadata-symbol.d.ts} +0 -0
- package/{core/type-metadata.d.ts → type-metadata.d.ts} +24 -6
- package/{core/type-name.d.ts → type-name.d.ts} +0 -0
- package/{core/type-options-base.d.ts → type-options-base.d.ts} +9 -19
- package/{core/type-options.d.ts → type-options.d.ts} +28 -2
- package/{core/type-resolver.d.ts → type-resolver.d.ts} +0 -0
- package/type.d.ts +1 -1
- package/core/alias.d.ts +0 -6
- package/core/custom-data.d.ts +0 -6
- package/core/default-value.d.ts +0 -7
- package/core/discriminant.d.ts +0 -8
- package/core/discriminator.d.ts +0 -6
- package/core/factory.d.ts +0 -18
- package/core/fn.d.ts +0 -316
- package/core/index.d.ts +0 -44
- package/core/index.js +0 -2
- package/core/injector.d.ts +0 -16
- package/core/naming-convention.d.ts +0 -15
- package/core/reference-handler.d.ts +0 -32
- package/core/reference-value-initializer.d.ts +0 -8
- package/core/reference-value-resolver.d.ts +0 -8
- package/core/serializer-context-options.d.ts +0 -63
- package/core/serializer.d.ts +0 -27
- package/deserializable.d.ts +0 -11
- package/deserialized-default-value.d.ts +0 -11
- package/factories/index.js +0 -2
- package/injectable.d.ts +0 -10
- package/injectors/index.js +0 -2
- package/naming-conventions/index.js +0 -2
- package/preserve-discriminator.d.ts +0 -10
- package/reference-handlers/index.js +0 -2
- package/serializable.d.ts +0 -11
- package/serialized-default-value.d.ts +0 -11
- package/serializers/index.js +0 -2
- package/type-and-property.d.ts +0 -12
- package/use-default-value.d.ts +0 -10
- package/use-implicit-conversion.d.ts +0 -10
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TypeManager.TS
|
|
2
2
|
|
|
3
|
-
 
|
|
3
|
+
  
|
|
4
4
|
|
|
5
5
|
Type manager is a parsing package for `TypeScript` which will help you to transform JSON strings or plain objects into `JavaScript` object instances. It supports [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) or declarative configuration and allows you to configure parsing of your or 3rd party classes easily.
|
|
6
6
|
|
|
@@ -19,23 +19,24 @@ If you like or are using this project please give it a star. Thanks!
|
|
|
19
19
|
* [Type decorator](#type-decorator)
|
|
20
20
|
* [Property decorator](#property-decorator)
|
|
21
21
|
* [Inject decorator](#inject-decorator)
|
|
22
|
-
* [Defining
|
|
23
|
-
* [Alias
|
|
24
|
-
* [Custom data
|
|
25
|
-
* [Default value
|
|
26
|
-
* [Deserializable
|
|
27
|
-
* [Discriminant
|
|
28
|
-
* [Discriminator
|
|
29
|
-
* [Factory
|
|
30
|
-
* [Injectable
|
|
31
|
-
* [Injector
|
|
32
|
-
* [Naming convention
|
|
33
|
-
* [Preserve discriminator
|
|
34
|
-
* [
|
|
35
|
-
* [
|
|
36
|
-
* [
|
|
37
|
-
* [
|
|
38
|
-
* [Use
|
|
22
|
+
* [Defining decorator options](#defining-decorator-options)
|
|
23
|
+
* [Alias option](#alias-option)
|
|
24
|
+
* [Custom data option](#custom-data-option)
|
|
25
|
+
* [Default value option](#default-value-option)
|
|
26
|
+
* [Deserializable option](#deserializable-option)
|
|
27
|
+
* [Discriminant option](#discriminant-option)
|
|
28
|
+
* [Discriminator option](#discriminator-option)
|
|
29
|
+
* [Factory option](#factory-option)
|
|
30
|
+
* [Injectable option](#injectable-option)
|
|
31
|
+
* [Injector option](#injector-option)
|
|
32
|
+
* [Naming convention option](#naming-convention-option)
|
|
33
|
+
* [Preserve discriminator option](#preserve-discriminator-option)
|
|
34
|
+
* [Preserve null option](#preserve-null-option)
|
|
35
|
+
* [Reference handler option](#reference-handler-option)
|
|
36
|
+
* [Serializable option](#serializable-option)
|
|
37
|
+
* [Serializer option](#serializer-option)
|
|
38
|
+
* [Use default value option](#use-default-value-option)
|
|
39
|
+
* [Use implicit conversion option](#use-implicit-conversion-option)
|
|
39
40
|
* [Defining configuration manually](#defining-configuration-manually)
|
|
40
41
|
* [Configuring global options](#configuring-global-options)
|
|
41
42
|
* [Configuring options per type](#configuring-options-per-type)
|
|
@@ -57,6 +58,9 @@ If you like or are using this project please give it a star. Thanks!
|
|
|
57
58
|
* [Generic types](#generic-types)
|
|
58
59
|
* [Integration with Angular](#integration-with-angular)
|
|
59
60
|
* [Polymorphic types](#polymorphic-types)
|
|
61
|
+
* [Versioning](#versioning)
|
|
62
|
+
* [Contributing](#contributing)
|
|
63
|
+
* [Authors](#authors)
|
|
60
64
|
* [Notes](#notes)
|
|
61
65
|
* [License](#license)
|
|
62
66
|
|
|
@@ -158,12 +162,12 @@ Now we can use all power provided by `JavaScript` class instances. Want to know
|
|
|
158
162
|
`TypeManager.TS` is available from NPM, both for browser (e.g. using webpack) and NodeJS:
|
|
159
163
|
|
|
160
164
|
```
|
|
161
|
-
npm
|
|
165
|
+
npm i @dipscope/type-manager
|
|
162
166
|
```
|
|
163
167
|
|
|
164
168
|
TypeScript needs to run with the `experimentalDecorators` and `emitDecoratorMetadata` options enabled when using decorator annotations. So make sure you have properly configured your `tsconfig.json` file.
|
|
165
169
|
|
|
166
|
-
|
|
170
|
+
_If you want additional type-safety and reduced syntax you may wish to install [reflect-metadata](https://github.com/rbuckton/reflect-metadata). This step is on your choice and fully optional. When installed it must be available globally to work. This can usually be done with `import 'reflect-metadata';` in your main index file._
|
|
167
171
|
|
|
168
172
|
## How it works?
|
|
169
173
|
|
|
@@ -192,8 +196,7 @@ Here we have a `User` class with `Type` and `Property` decorators assigned to it
|
|
|
192
196
|
The same configuration can be rewritten using declarative style.
|
|
193
197
|
|
|
194
198
|
```typescript
|
|
195
|
-
import { TypeManager } from '@dipscope/type-manager';
|
|
196
|
-
import { PropertyName, PropertyOptions } from '@dipscope/type-manager/core';
|
|
199
|
+
import { TypeManager, PropertyName, PropertyOptions } from '@dipscope/type-manager';
|
|
197
200
|
|
|
198
201
|
export class User
|
|
199
202
|
{
|
|
@@ -251,7 +254,7 @@ At first glance, it may seems that there is no difference but creating an instan
|
|
|
251
254
|
|
|
252
255
|
## Defining decorators
|
|
253
256
|
|
|
254
|
-
|
|
257
|
+
There are few decorators which controls the main flow. This are `Type`, `Property` and `Inject` decorators. Let's go through each of them.
|
|
255
258
|
|
|
256
259
|
### Type decorator
|
|
257
260
|
|
|
@@ -284,7 +287,7 @@ export class User
|
|
|
284
287
|
|
|
285
288
|
This call defines a type alias which can be later used to resolve a type for a property at runtime. We will talk about details in the property decorator section. Also we defined custom serializer for a type which is an implementation of `Serializer` interface. This serializer will be used later to serialize and deserialize a type including all custom logic of your choice. You can read more about [creating a custom serializer](#defining-custom-serializer) in a separate section.
|
|
286
289
|
|
|
287
|
-
There are more options can be provided for a type, so check `TypeOptions` definition or section with [
|
|
290
|
+
There are more options can be provided for a type, so check `TypeOptions` definition or section with [decorator options](#defining-decorator-options) below.
|
|
288
291
|
|
|
289
292
|
### Property decorator
|
|
290
293
|
|
|
@@ -340,7 +343,7 @@ export class User
|
|
|
340
343
|
}
|
|
341
344
|
```
|
|
342
345
|
|
|
343
|
-
This option configures an alias so `username` property will be used instead of `name` when deserializing from object. There are plenty of configure options, so check `PropertyOptions` definition or section with [
|
|
346
|
+
This option configures an alias so `username` property will be used instead of `name` when deserializing from object. There are plenty of configure options, so check `PropertyOptions` definition or section with [decorator options](#defining-decorator-options) below. For example you can make some properties serializable only or define custom property serialization.
|
|
344
347
|
|
|
345
348
|
Now let's have a look at more complex definitions with generic types. This are `Array<TType>`, `Map<TKey, TValue>` and others. To declare one of this you have to use extra argument available for `Property` decorator. Generic arguments are always passed as array to exactly see them within a source code.
|
|
346
349
|
|
|
@@ -594,16 +597,18 @@ When a string key is provided then a certain value will be resolved from JSON co
|
|
|
594
597
|
When a certain type is provided it will be resolved from the dependency injection container. If you are going to use internal type injector then you should register injectable types as the following. By default singleton injector is used to resolve such services.
|
|
595
598
|
|
|
596
599
|
```typescript
|
|
597
|
-
import {
|
|
600
|
+
import { Type } from '@dipscope/type-manager';
|
|
598
601
|
|
|
599
|
-
@
|
|
602
|
+
@Type({
|
|
603
|
+
injectable: true
|
|
604
|
+
})
|
|
600
605
|
export class UserService
|
|
601
606
|
{
|
|
602
607
|
public property: string;
|
|
603
608
|
}
|
|
604
609
|
```
|
|
605
610
|
|
|
606
|
-
In most cases you will work in environment where dependency injection system is already setted up. In this case you have to implement custom `Injector` to be used instead of our default one. Besides you should follow the steps to register injectable services specified by the vendor.
|
|
611
|
+
In most cases you will work in environment where dependency injection system is already setted up. In this case you have to implement custom `Injector` to be used instead of our default one. Besides you should follow the steps to register injectable services specified by the vendor. You can read more about [creating a custom injector](#defining-custom-injector) in a separate section.
|
|
607
612
|
|
|
608
613
|
If you are using [reflect-metadata](https://github.com/rbuckton/reflect-metadata) the injection of services can be simplified.
|
|
609
614
|
|
|
@@ -626,26 +631,13 @@ export class User
|
|
|
626
631
|
|
|
627
632
|
Note that now you don't have to specify injection for types explicitly. However injection of values by key from JSON context still present. It's because argument names cannot be resolved using reflection.
|
|
628
633
|
|
|
629
|
-
## Defining
|
|
634
|
+
## Defining decorator options
|
|
630
635
|
|
|
631
|
-
`Type` and `Property` decorators provide full configuration for your classes using configure options
|
|
636
|
+
`Type` and `Property` decorators provide full configuration for your classes using configure options. In this section we will go through each of them.
|
|
632
637
|
|
|
633
|
-
### Alias
|
|
638
|
+
### Alias option
|
|
634
639
|
|
|
635
|
-
This
|
|
636
|
-
|
|
637
|
-
```typescript
|
|
638
|
-
import { Type, Property, Alias } from '@dipscope/type-manager';
|
|
639
|
-
|
|
640
|
-
@Type()
|
|
641
|
-
@Alias('User')
|
|
642
|
-
export class User
|
|
643
|
-
{
|
|
644
|
-
@Property(String) @Alias('username') public name: string;
|
|
645
|
-
}
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
Such declaration is an alternative for:
|
|
640
|
+
This option can be used both on type and property to define an alias.
|
|
649
641
|
|
|
650
642
|
```typescript
|
|
651
643
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -663,22 +655,9 @@ Alias defined for a class can be used later for resolving property types. Note t
|
|
|
663
655
|
|
|
664
656
|
Alias defined for a property declares that property name differs from one specified in JSON. In our case `username` will be used instead of `name` during JSON serialization and deserialization.
|
|
665
657
|
|
|
666
|
-
### Custom data
|
|
667
|
-
|
|
668
|
-
This decorator can be used to provide any custom data for type or property.
|
|
669
|
-
|
|
670
|
-
```typescript
|
|
671
|
-
import { Type, Property, CustomData } from '@dipscope/type-manager';
|
|
672
|
-
|
|
673
|
-
@Type()
|
|
674
|
-
@CustomData({ rank: 1 })
|
|
675
|
-
export class User
|
|
676
|
-
{
|
|
677
|
-
@Property(String) @CustomData({ order: 1 }) public name: string;
|
|
678
|
-
}
|
|
679
|
-
```
|
|
658
|
+
### Custom data option
|
|
680
659
|
|
|
681
|
-
|
|
660
|
+
This option can be used to provide any custom data for type or property.
|
|
682
661
|
|
|
683
662
|
```typescript
|
|
684
663
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -694,36 +673,23 @@ export class User
|
|
|
694
673
|
|
|
695
674
|
This custom data later can be accessed in serializers, factories, injectors or your code and used accordingly. Read more about [defining custom data](#defining-custom-data) in a separate section.
|
|
696
675
|
|
|
697
|
-
### Default value
|
|
698
|
-
|
|
699
|
-
This decorator is used to define a default value when one is undefined. It can be used on type or property.
|
|
700
|
-
|
|
701
|
-
```typescript
|
|
702
|
-
import { Type, Property, DefaultValue } from '@dipscope/type-manager';
|
|
703
|
-
|
|
704
|
-
@Type()
|
|
705
|
-
@DefaultValue(() => new User())
|
|
706
|
-
export class User
|
|
707
|
-
{
|
|
708
|
-
@Property(String) @DefaultValue('BestName') public name: string;
|
|
709
|
-
}
|
|
710
|
-
```
|
|
676
|
+
### Default value option
|
|
711
677
|
|
|
712
|
-
This
|
|
678
|
+
This option is used to define a default value when one is undefined. It can be used on type or property.
|
|
713
679
|
|
|
714
680
|
```typescript
|
|
715
|
-
import { Type, Property
|
|
681
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
716
682
|
|
|
717
|
-
@Type(
|
|
718
|
-
|
|
719
|
-
|
|
683
|
+
@Type({
|
|
684
|
+
defaultValue: () => new User()
|
|
685
|
+
})
|
|
720
686
|
export class User
|
|
721
687
|
{
|
|
722
|
-
@Property(String
|
|
688
|
+
@Property(String, { defaultValue: 'BestName' }) public name: string;
|
|
723
689
|
}
|
|
724
690
|
```
|
|
725
691
|
|
|
726
|
-
|
|
692
|
+
This will affect both serialized and deserialized default value. This will fit perfectly for most types. You can also specify serialized and deserialized default value explicitly for complex types by using two other options.
|
|
727
693
|
|
|
728
694
|
```typescript
|
|
729
695
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -734,27 +700,15 @@ import { Type, Property } from '@dipscope/type-manager';
|
|
|
734
700
|
})
|
|
735
701
|
export class User
|
|
736
702
|
{
|
|
737
|
-
@Property(String, { serializedDefaultValue: '
|
|
703
|
+
@Property(String, { serializedDefaultValue: 'SerializedName', deserializedDefaultValue: 'DeserializedName' }) public name: string;
|
|
738
704
|
}
|
|
739
705
|
```
|
|
740
706
|
|
|
741
|
-
As you can see it accepts an arrow function or a certain value. Both are valid for type and property. Using default values is turned off by default. You can enable them using `
|
|
707
|
+
As you can see it accepts an arrow function or a certain value. Both are valid for type and property. Using default values is turned off by default. You can enable them using `useDefaultValue` option per type and property or enable globally using `TypeManager` configure method.
|
|
742
708
|
|
|
743
|
-
### Deserializable
|
|
709
|
+
### Deserializable option
|
|
744
710
|
|
|
745
|
-
This
|
|
746
|
-
|
|
747
|
-
```typescript
|
|
748
|
-
import { Type, Property, Deserializable } from '@dipscope/type-manager';
|
|
749
|
-
|
|
750
|
-
@Type()
|
|
751
|
-
export class User
|
|
752
|
-
{
|
|
753
|
-
@Property(String) @Deserializable() public name: string;
|
|
754
|
-
}
|
|
755
|
-
```
|
|
756
|
-
|
|
757
|
-
Such declaration is an alternative for:
|
|
711
|
+
This option is used to enable or disable deserialization for a certain property.
|
|
758
712
|
|
|
759
713
|
```typescript
|
|
760
714
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -768,22 +722,9 @@ export class User
|
|
|
768
722
|
|
|
769
723
|
By default all properties are deserializable.
|
|
770
724
|
|
|
771
|
-
### Discriminant
|
|
725
|
+
### Discriminant option
|
|
772
726
|
|
|
773
|
-
This
|
|
774
|
-
|
|
775
|
-
```typescript
|
|
776
|
-
import { Type, Property, Discriminant } from '@dipscope/type-manager';
|
|
777
|
-
|
|
778
|
-
@Type()
|
|
779
|
-
@Discriminant('Company.Api.Entities.User')
|
|
780
|
-
export class User
|
|
781
|
-
{
|
|
782
|
-
@Property(String) public name: string;
|
|
783
|
-
}
|
|
784
|
-
```
|
|
785
|
-
|
|
786
|
-
Such declaration is an alternative for:
|
|
727
|
+
This option is used to define a custom discriminant for a type which is later used during serialization and deserialization of polymorphic types.
|
|
787
728
|
|
|
788
729
|
```typescript
|
|
789
730
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -799,22 +740,9 @@ export class User
|
|
|
799
740
|
|
|
800
741
|
You can read more about handling of polymorphic types in this [section](#configuring-usage-of-polymorphic-types).
|
|
801
742
|
|
|
802
|
-
### Discriminator
|
|
743
|
+
### Discriminator option
|
|
803
744
|
|
|
804
|
-
This
|
|
805
|
-
|
|
806
|
-
```typescript
|
|
807
|
-
import { Type, Property, Discriminator } from '@dipscope/type-manager';
|
|
808
|
-
|
|
809
|
-
@Type()
|
|
810
|
-
@Discriminator('__typename__')
|
|
811
|
-
export class User
|
|
812
|
-
{
|
|
813
|
-
@Property(String) public name: string;
|
|
814
|
-
}
|
|
815
|
-
```
|
|
816
|
-
|
|
817
|
-
Such declaration is an alternative for:
|
|
745
|
+
This option can be used to define a custom property which stores discriminant of polymorphic type.
|
|
818
746
|
|
|
819
747
|
```typescript
|
|
820
748
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -830,22 +758,9 @@ export class User
|
|
|
830
758
|
|
|
831
759
|
In common use cases discriminator should be set globally using `TypeManager` configure method. Using this option on a type level makes sense only if discriminator differs from the global one. You can read more about handling of polymorphic types in this [section](#configuring-usage-of-polymorphic-types).
|
|
832
760
|
|
|
833
|
-
### Factory
|
|
834
|
-
|
|
835
|
-
This decorator can be used to register a handler which should be used for constructing a type instead of default one.
|
|
836
|
-
|
|
837
|
-
```typescript
|
|
838
|
-
import { Type, Property, Factory } from '@dipscope/type-manager';
|
|
839
|
-
|
|
840
|
-
@Type()
|
|
841
|
-
@Factory(new UserFactory())
|
|
842
|
-
export class User
|
|
843
|
-
{
|
|
844
|
-
@Property(String) public name: string;
|
|
845
|
-
}
|
|
846
|
-
```
|
|
761
|
+
### Factory option
|
|
847
762
|
|
|
848
|
-
|
|
763
|
+
This option can be used to register a handler which should be used for constructing a type instead of default one.
|
|
849
764
|
|
|
850
765
|
```typescript
|
|
851
766
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -861,22 +776,9 @@ export class User
|
|
|
861
776
|
|
|
862
777
|
This may be useful in cases when you want to init some special application specific properties. Read more about [defining custom factory](#defining-custom-factory) in a separate section.
|
|
863
778
|
|
|
864
|
-
### Injectable
|
|
779
|
+
### Injectable option
|
|
865
780
|
|
|
866
|
-
This
|
|
867
|
-
|
|
868
|
-
```typescript
|
|
869
|
-
import { Injectable } from '@dipscope/type-manager';
|
|
870
|
-
|
|
871
|
-
@Type()
|
|
872
|
-
@Injectable()
|
|
873
|
-
export class UserService
|
|
874
|
-
{
|
|
875
|
-
public property: string;
|
|
876
|
-
}
|
|
877
|
-
```
|
|
878
|
-
|
|
879
|
-
Such declaration is an alternative for:
|
|
781
|
+
This option is used to register a type in dependency injection container.
|
|
880
782
|
|
|
881
783
|
```typescript
|
|
882
784
|
import { Type } from '@dipscope/type-manager';
|
|
@@ -909,24 +811,11 @@ export class User
|
|
|
909
811
|
}
|
|
910
812
|
```
|
|
911
813
|
|
|
912
|
-
In most cases you will work in environment where dependency injection system is already setted up. In this case you have to implement custom `Injector` to be used instead of our default one. Besides you should follow the steps to register injectable services specified by the vendor.
|
|
913
|
-
|
|
914
|
-
### Injector decorator
|
|
915
|
-
|
|
916
|
-
This decorator can be used to define a custom injector implementation which should be used in a type scope.
|
|
814
|
+
In most cases you will work in environment where dependency injection system is already setted up. In this case you have to implement custom `Injector` to be used instead of our default one. Besides you should follow the steps to register injectable services specified by the vendor. You can read more about [creating a custom injector](#defining-custom-injector) in a separate section.
|
|
917
815
|
|
|
918
|
-
|
|
919
|
-
import { Type, Property, Injector } from '@dipscope/type-manager';
|
|
920
|
-
|
|
921
|
-
@Type()
|
|
922
|
-
@Injector(new UserInjector())
|
|
923
|
-
export class User
|
|
924
|
-
{
|
|
925
|
-
@Property(String) public name: string;
|
|
926
|
-
}
|
|
927
|
-
```
|
|
816
|
+
### Injector option
|
|
928
817
|
|
|
929
|
-
|
|
818
|
+
This option can be used to define a custom injector implementation which should be used in a type scope.
|
|
930
819
|
|
|
931
820
|
```typescript
|
|
932
821
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -942,27 +831,12 @@ export class User
|
|
|
942
831
|
|
|
943
832
|
In most cases this is not required and the common use case is to specify injector globally instead. You can read more about [defining custom injector](#defining-custom-injector) in a separate section.
|
|
944
833
|
|
|
945
|
-
### Naming convention
|
|
946
|
-
|
|
947
|
-
This decorator can be used both on type and property to provide custom naming strategy.
|
|
948
|
-
|
|
949
|
-
```typescript
|
|
950
|
-
import { Type, Property, NamingConvention } from '@dipscope/type-manager';
|
|
951
|
-
import { CamelCaseNamingConvention, SnakeCaseNamingConvention } from '@dipscope/type-manager/naming-conventions';
|
|
952
|
-
|
|
953
|
-
@Type()
|
|
954
|
-
@NamingConvention(new CamelCaseNamingConvention())
|
|
955
|
-
export class User
|
|
956
|
-
{
|
|
957
|
-
@Property(String) @NamingConvention(new SnakeCaseNamingConvention()) public name: string;
|
|
958
|
-
}
|
|
959
|
-
```
|
|
834
|
+
### Naming convention option
|
|
960
835
|
|
|
961
|
-
|
|
836
|
+
This option can be used both on type and property to provide custom naming strategy.
|
|
962
837
|
|
|
963
838
|
```typescript
|
|
964
|
-
import { Type, Property } from '@dipscope/type-manager';
|
|
965
|
-
import { CamelCaseNamingConvention, SnakeCaseNamingConvention } from '@dipscope/type-manager/naming-conventions';
|
|
839
|
+
import { Type, Property, CamelCaseNamingConvention, SnakeCaseNamingConvention } from '@dipscope/type-manager';
|
|
966
840
|
|
|
967
841
|
@Type({
|
|
968
842
|
namingConvention: new CamelCaseNamingConvention()
|
|
@@ -975,22 +849,9 @@ export class User
|
|
|
975
849
|
|
|
976
850
|
In most cases this is not required and the common use case is to specify naming strategy globally instead. You can read more about [configuring naming convention](#configuring-naming-convention) in a separate section.
|
|
977
851
|
|
|
978
|
-
### Preserve discriminator
|
|
852
|
+
### Preserve discriminator option
|
|
979
853
|
|
|
980
|
-
This
|
|
981
|
-
|
|
982
|
-
```typescript
|
|
983
|
-
import { Type, Property, PreserveDiscriminator } from '@dipscope/type-manager';
|
|
984
|
-
|
|
985
|
-
@Type()
|
|
986
|
-
@PreserveDiscriminator()
|
|
987
|
-
export class User
|
|
988
|
-
{
|
|
989
|
-
@Property(String) public name: string;
|
|
990
|
-
}
|
|
991
|
-
```
|
|
992
|
-
|
|
993
|
-
Such declaration is an alternative for:
|
|
854
|
+
This option defines if discriminator should be preserved in objects during serialization and deserialization.
|
|
994
855
|
|
|
995
856
|
```typescript
|
|
996
857
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1006,27 +867,30 @@ export class User
|
|
|
1006
867
|
|
|
1007
868
|
By default discriminator is not preserved and only used during deserialization of polymorphic types. You can read more about handling of polymorphic types in this [section](#configuring-usage-of-polymorphic-types).
|
|
1008
869
|
|
|
1009
|
-
###
|
|
870
|
+
### Preserve null option
|
|
1010
871
|
|
|
1011
|
-
This
|
|
872
|
+
This option defines if null values should be preserved during serialization and deserialization.
|
|
1012
873
|
|
|
1013
874
|
```typescript
|
|
1014
|
-
import { Type, Property
|
|
1015
|
-
import { DirectReferenceHandler, LeadReferenceHandler } from '@dipscope/type-manager/reference-handlers';
|
|
875
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1016
876
|
|
|
1017
|
-
@Type(
|
|
1018
|
-
|
|
877
|
+
@Type({
|
|
878
|
+
preserveNull: true
|
|
879
|
+
})
|
|
1019
880
|
export class User
|
|
1020
881
|
{
|
|
1021
|
-
@Property(String
|
|
882
|
+
@Property(String, { preserveNull: false }) public name: string;
|
|
1022
883
|
}
|
|
1023
884
|
```
|
|
1024
885
|
|
|
1025
|
-
|
|
886
|
+
By default null values are preserved. You can set it to `false` per type, property or globally using `TypeManager` configure method. This will result in treating null values as undefined so you will get all related behaviours like setting default values.
|
|
887
|
+
|
|
888
|
+
### Reference handler option
|
|
889
|
+
|
|
890
|
+
This option can be used both on type and property to specify how references to the same objects should be handled during serialization and deserialization.
|
|
1026
891
|
|
|
1027
892
|
```typescript
|
|
1028
|
-
import { Type, Property } from '@dipscope/type-manager';
|
|
1029
|
-
import { DirectReferenceHandler, LeadReferenceHandler } from '@dipscope/type-manager/reference-handlers';
|
|
893
|
+
import { Type, Property, DirectReferenceHandler, LeadReferenceHandler } from '@dipscope/type-manager';
|
|
1030
894
|
|
|
1031
895
|
@Type({
|
|
1032
896
|
referenceHandler: new DirectReferenceHandler()
|
|
@@ -1039,21 +903,9 @@ export class User
|
|
|
1039
903
|
|
|
1040
904
|
In most cases this is not required and the common use case is to specify reference handler globally instead. You can read more about [configuring reference handler](#configuring-reference-handler) in a separate section.
|
|
1041
905
|
|
|
1042
|
-
### Serializable
|
|
1043
|
-
|
|
1044
|
-
This decorator is used to enable or disable serialization for a certain property.
|
|
1045
|
-
|
|
1046
|
-
```typescript
|
|
1047
|
-
import { Type, Property, Serializable } from '@dipscope/type-manager';
|
|
1048
|
-
|
|
1049
|
-
@Type()
|
|
1050
|
-
export class User
|
|
1051
|
-
{
|
|
1052
|
-
@Property(String) @Serializable() public name: string;
|
|
1053
|
-
}
|
|
1054
|
-
```
|
|
906
|
+
### Serializable option
|
|
1055
907
|
|
|
1056
|
-
|
|
908
|
+
This option is used to enable or disable serialization for a certain property.
|
|
1057
909
|
|
|
1058
910
|
```typescript
|
|
1059
911
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1067,22 +919,9 @@ export class User
|
|
|
1067
919
|
|
|
1068
920
|
By default all properties are serializable.
|
|
1069
921
|
|
|
1070
|
-
### Serializer
|
|
922
|
+
### Serializer option
|
|
1071
923
|
|
|
1072
|
-
This
|
|
1073
|
-
|
|
1074
|
-
```typescript
|
|
1075
|
-
import { Type, Property, Serializer } from '@dipscope/type-manager';
|
|
1076
|
-
|
|
1077
|
-
@Type()
|
|
1078
|
-
@Serializer(new UserSerializer())
|
|
1079
|
-
export class User
|
|
1080
|
-
{
|
|
1081
|
-
@Property(String) @Serializer(new UserNameSerializer()) public name: string;
|
|
1082
|
-
}
|
|
1083
|
-
```
|
|
1084
|
-
|
|
1085
|
-
Such declaration is an alternative for:
|
|
924
|
+
This option is used to define custom serializer for a type or property.
|
|
1086
925
|
|
|
1087
926
|
```typescript
|
|
1088
927
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1098,22 +937,9 @@ export class User
|
|
|
1098
937
|
|
|
1099
938
|
Custom serializer should be an implementation of `Serializer` interface. You can read more about [creating a custom serializer](#defining-custom-serializer) in a separate section.
|
|
1100
939
|
|
|
1101
|
-
### Use default value
|
|
1102
|
-
|
|
1103
|
-
This decorator enables or disables using default value per type or property.
|
|
1104
|
-
|
|
1105
|
-
```typescript
|
|
1106
|
-
import { Type, Property, UseDefaultValue } from '@dipscope/type-manager';
|
|
1107
|
-
|
|
1108
|
-
@Type()
|
|
1109
|
-
@UseDefaultValue()
|
|
1110
|
-
export class User
|
|
1111
|
-
{
|
|
1112
|
-
@Property(String) @UseDefaultValue(false) public name: string;
|
|
1113
|
-
}
|
|
1114
|
-
```
|
|
940
|
+
### Use default value option
|
|
1115
941
|
|
|
1116
|
-
|
|
942
|
+
This option enables or disables using default value per type or property.
|
|
1117
943
|
|
|
1118
944
|
```typescript
|
|
1119
945
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1129,22 +955,10 @@ export class User
|
|
|
1129
955
|
|
|
1130
956
|
Using default values is turned off by default. You can enable them globally using `TypeManager` configure method.
|
|
1131
957
|
|
|
1132
|
-
### Use implicit conversion
|
|
958
|
+
### Use implicit conversion option
|
|
1133
959
|
|
|
1134
960
|
By default if declared type will not match provided during serialization or deserialization an error will be logged and result value will be undefined. This means that for example assigning `Number` to `String` will not work as `StringSerializer` expects `String`. However `Number` and other types can be converted to `String` for you when implicit conversion is enabled.
|
|
1135
961
|
|
|
1136
|
-
```typescript
|
|
1137
|
-
import { Type, Property, UseImplicitConversion } from '@dipscope/type-manager';
|
|
1138
|
-
|
|
1139
|
-
@Type()
|
|
1140
|
-
export class User
|
|
1141
|
-
{
|
|
1142
|
-
@Property(String) @UseImplicitConversion() public name: string;
|
|
1143
|
-
}
|
|
1144
|
-
```
|
|
1145
|
-
|
|
1146
|
-
Such declaration is an alternative for:
|
|
1147
|
-
|
|
1148
962
|
```typescript
|
|
1149
963
|
import { Type, Property } from '@dipscope/type-manager';
|
|
1150
964
|
|
|
@@ -1155,7 +969,7 @@ export class User
|
|
|
1155
969
|
}
|
|
1156
970
|
```
|
|
1157
971
|
|
|
1158
|
-
With this any value which can be converted to `String` will be converted properly. Such behaviour works for other built in serializers and supported for custom ones. By default implicit conversion is turned off. You can enable it using `
|
|
972
|
+
With this any value which can be converted to `String` will be converted properly. Such behaviour works for other built in serializers and supported for custom ones. By default implicit conversion is turned off. You can enable it using `useImplicitConversion` option per type and property or enable globally using `TypeManager` configure method.
|
|
1159
973
|
|
|
1160
974
|
## Defining configuration manually
|
|
1161
975
|
|
|
@@ -1168,8 +982,7 @@ We have separate methods to configure each type manager option, so the provided
|
|
|
1168
982
|
There are several options which can be configured globally. For example let's override using of default value option so we don't have to specify it explicitly per type or property.
|
|
1169
983
|
|
|
1170
984
|
```typescript
|
|
1171
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1172
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
985
|
+
import { TypeManagerOptions, TypeOptionsBase } from '@dipscope/type-manager';
|
|
1173
986
|
|
|
1174
987
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1175
988
|
useDefaultValue: true
|
|
@@ -1190,8 +1003,7 @@ Here is an example of declarative configuration which can be used for 3rd party
|
|
|
1190
1003
|
|
|
1191
1004
|
```typescript
|
|
1192
1005
|
import { DateTime } from '@external-library';
|
|
1193
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1194
|
-
import { TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager/core';
|
|
1006
|
+
import { TypeManagerOptions, TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager';
|
|
1195
1007
|
|
|
1196
1008
|
const dateTimeOptions: TypeOptions<DateTime> = {
|
|
1197
1009
|
alias: 'DateTime',
|
|
@@ -1396,8 +1208,7 @@ In some cases your `Discriminator` or `Discriminant` values will not match to ou
|
|
|
1396
1208
|
To change `Discriminator` globally you have to use `TypeManager` configure method.
|
|
1397
1209
|
|
|
1398
1210
|
```typescript
|
|
1399
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1400
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1211
|
+
import { TypeManagerOptions, TypeOptionsBase } from '@dipscope/type-manager';
|
|
1401
1212
|
|
|
1402
1213
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1403
1214
|
discriminator: '$customType'
|
|
@@ -1413,8 +1224,7 @@ TypeManager.configure(typeManagerOptions);
|
|
|
1413
1224
|
To change `Discriminant` you have to use per type configuration.
|
|
1414
1225
|
|
|
1415
1226
|
```typescript
|
|
1416
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1417
|
-
import { TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager/core';
|
|
1227
|
+
import { TypeManagerOptions, TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager';
|
|
1418
1228
|
|
|
1419
1229
|
const rectangleOptions: TypeOptions<Rectangle> = {
|
|
1420
1230
|
discriminant: 'Company.Api.Entities.Rectangle'
|
|
@@ -1442,32 +1252,36 @@ TypeManager.configure(typeManagerOptions);
|
|
|
1442
1252
|
As an alternative you can change `Discriminant` as the following using decorators.
|
|
1443
1253
|
|
|
1444
1254
|
```typescript
|
|
1445
|
-
import { Type, Property
|
|
1255
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1446
1256
|
|
|
1447
|
-
@Type(
|
|
1448
|
-
|
|
1257
|
+
@Type({
|
|
1258
|
+
discriminant: 'Company.Api.Entities.Shape'
|
|
1259
|
+
})
|
|
1449
1260
|
export abstract class Shape
|
|
1450
1261
|
{
|
|
1451
1262
|
@Property(String) public title: string;
|
|
1452
1263
|
}
|
|
1453
1264
|
|
|
1454
|
-
@Type(
|
|
1455
|
-
|
|
1265
|
+
@Type({
|
|
1266
|
+
discriminant: 'Company.Api.Entities.Rectangle'
|
|
1267
|
+
})
|
|
1456
1268
|
export class Rectangle extends Shape
|
|
1457
1269
|
{
|
|
1458
1270
|
@Property(Number) public width: number;
|
|
1459
1271
|
@Property(Number) public height: number;
|
|
1460
1272
|
}
|
|
1461
1273
|
|
|
1462
|
-
@Type(
|
|
1463
|
-
|
|
1274
|
+
@Type({
|
|
1275
|
+
discriminant: 'Company.Api.Entities.Square'
|
|
1276
|
+
})
|
|
1464
1277
|
export class Square extends Shape
|
|
1465
1278
|
{
|
|
1466
1279
|
@Property(Number) public width: number;
|
|
1467
1280
|
}
|
|
1468
1281
|
|
|
1469
|
-
@Type(
|
|
1470
|
-
|
|
1282
|
+
@Type({
|
|
1283
|
+
discriminant: 'Company.Api.Entities.Circle'
|
|
1284
|
+
})
|
|
1471
1285
|
export class Circle extends Shape
|
|
1472
1286
|
{
|
|
1473
1287
|
@Property(Number) public radius: number;
|
|
@@ -1477,8 +1291,7 @@ export class Circle extends Shape
|
|
|
1477
1291
|
By default `Discriminator` is not preserved inside objects and only used during deserialization. You can change this behavior by enabling preserving of discriminator globally or per type.
|
|
1478
1292
|
|
|
1479
1293
|
```typescript
|
|
1480
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1481
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1294
|
+
import { TypeManagerOptions, TypeOptionsBase } from '@dipscope/type-manager';
|
|
1482
1295
|
|
|
1483
1296
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1484
1297
|
preserveDiscriminator: true
|
|
@@ -1556,14 +1369,14 @@ But what to do if we don't control the JSON naming convention so it comes to us
|
|
|
1556
1369
|
We can still parse such a JSON by specifying an alias for each property but this will become a pain in a while.
|
|
1557
1370
|
|
|
1558
1371
|
```typescript
|
|
1559
|
-
import { Type, Property
|
|
1372
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1560
1373
|
|
|
1561
1374
|
@Type()
|
|
1562
1375
|
export class User
|
|
1563
1376
|
{
|
|
1564
1377
|
@Property(String) public name: string;
|
|
1565
|
-
@Property(Number
|
|
1566
|
-
@Property(DateTime
|
|
1378
|
+
@Property(Number, { alias: 'login_count' }) public loginCount: number;
|
|
1379
|
+
@Property(DateTime, { alias: 'created_at' }) public createdAt: DateTime;
|
|
1567
1380
|
}
|
|
1568
1381
|
```
|
|
1569
1382
|
|
|
@@ -1581,9 +1394,7 @@ export class User
|
|
|
1581
1394
|
To set one we have to configure global options.
|
|
1582
1395
|
|
|
1583
1396
|
```typescript
|
|
1584
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1585
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1586
|
-
import { SnakeCaseNamingConvention } from '@dipscope/type-manager/naming-conventions';
|
|
1397
|
+
import { TypeManagerOptions, TypeOptionsBase, SnakeCaseNamingConvention } from '@dipscope/type-manager';
|
|
1587
1398
|
|
|
1588
1399
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1589
1400
|
namingConvention: new SnakeCaseNamingConvention()
|
|
@@ -1654,9 +1465,7 @@ Here are results returned by different reference handlers:
|
|
|
1654
1465
|
As you can see `DirectReferenceHandler` does not make changes to your data and completely fine until you have to convert circular reference structure to a string. `JSON.stringify` method which we are using under the hood does not support such conversions so you will encounter an error. In this case you can select another reference handler. For example `PathReferenceHandler` which produces JSON string using JSONPath format for circular references supported by many libraries. Or you can simply ignore circular reference when it should be converted to a string and use `LeadReferenceHandler`. To change default reference handler you have to use `TypeManager` configure methods.
|
|
1655
1466
|
|
|
1656
1467
|
```typescript
|
|
1657
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1658
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1659
|
-
import { PathReferenceHandler } from '@dipscope/type-manager/reference-handlers';
|
|
1468
|
+
import { TypeManagerOptions, TypeOptionsBase, PathReferenceHandler } from '@dipscope/type-manager';
|
|
1660
1469
|
|
|
1661
1470
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1662
1471
|
referenceHandler: new PathReferenceHandler()
|
|
@@ -1680,13 +1489,14 @@ Our goal is to cover as much use cases as possible without making you to write a
|
|
|
1680
1489
|
You can attach you custom metadata to our decorators using `customData` option available on `Type` and `Property`.
|
|
1681
1490
|
|
|
1682
1491
|
```typescript
|
|
1683
|
-
import { Type, Property
|
|
1492
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1684
1493
|
|
|
1685
|
-
@Type(
|
|
1686
|
-
|
|
1494
|
+
@Type({
|
|
1495
|
+
customData: { rank: 1 }
|
|
1496
|
+
})
|
|
1687
1497
|
class User
|
|
1688
1498
|
{
|
|
1689
|
-
@Property(String
|
|
1499
|
+
@Property(String, { customData: { priority: 10 } }) public name: string;
|
|
1690
1500
|
}
|
|
1691
1501
|
```
|
|
1692
1502
|
|
|
@@ -1713,7 +1523,8 @@ for (const propertyMetadata of userMetadata.propertyMetadataMap.values())
|
|
|
1713
1523
|
You can create your own serializer or replace built in one. First you have to implement `Serializer` interface. It declares `serialize` and `deserialize` methods. Serialize method is called during conversion of `JavaScript` object instance into a plain object. Deserialize method is called during backward conversion. Here is an example of possible definition for custom `DateTime` class.
|
|
1714
1524
|
|
|
1715
1525
|
```typescript
|
|
1716
|
-
import { Serializer, TypeLike, SerializerContext
|
|
1526
|
+
import { Serializer, TypeLike, SerializerContext } from '@dipscope/type-manager';
|
|
1527
|
+
import { Fn } from '@app/module';
|
|
1717
1528
|
|
|
1718
1529
|
export class DateTimeSerializer implements Serializer<DateTime>
|
|
1719
1530
|
{
|
|
@@ -1736,7 +1547,7 @@ export class DateTimeSerializer implements Serializer<DateTime>
|
|
|
1736
1547
|
|
|
1737
1548
|
if (serializerContext.log.errorEnabled)
|
|
1738
1549
|
{
|
|
1739
|
-
serializerContext.log.error(`${serializerContext.path}:
|
|
1550
|
+
serializerContext.log.error(`${serializerContext.path}: cannot serialize value as date time.`, x);
|
|
1740
1551
|
}
|
|
1741
1552
|
|
|
1742
1553
|
return undefined;
|
|
@@ -1761,7 +1572,7 @@ export class DateTimeSerializer implements Serializer<DateTime>
|
|
|
1761
1572
|
|
|
1762
1573
|
if (serializerContext.log.errorEnabled)
|
|
1763
1574
|
{
|
|
1764
|
-
serializerContext.log.error(`${serializerContext.path}:
|
|
1575
|
+
serializerContext.log.error(`${serializerContext.path}: cannot deserialize value as date time.`, x);
|
|
1765
1576
|
}
|
|
1766
1577
|
|
|
1767
1578
|
return undefined;
|
|
@@ -1778,8 +1589,9 @@ When you are finished with definitions there are two possible ways to register a
|
|
|
1778
1589
|
```typescript
|
|
1779
1590
|
import { Type, Serializer } from '@dipscope/type-manager';
|
|
1780
1591
|
|
|
1781
|
-
@Type(
|
|
1782
|
-
|
|
1592
|
+
@Type({
|
|
1593
|
+
serializer: new DateTimeSerializer()
|
|
1594
|
+
})
|
|
1783
1595
|
export class DateTime
|
|
1784
1596
|
{
|
|
1785
1597
|
...
|
|
@@ -1804,7 +1616,7 @@ With declarative configuration it is possible to override built in serializers i
|
|
|
1804
1616
|
In modern world we are always use some kind of framework to build our application. It is definitely already have a configured dependency injection container so let's configure `TypeManager` for using it instead of build in one. You have to implement `Injector` interface with only one method. Here how it may look like in `Angular`.
|
|
1805
1617
|
|
|
1806
1618
|
```typescript
|
|
1807
|
-
import { Injector, TypeMetadata } from '@dipscope/type-manager
|
|
1619
|
+
import { Injector, TypeMetadata } from '@dipscope/type-manager';
|
|
1808
1620
|
import { Injector as AngularInjector } from '@angular/core';
|
|
1809
1621
|
|
|
1810
1622
|
export class CustomInjector implements Injector
|
|
@@ -1845,8 +1657,7 @@ Now types will be resolved using framework injector.
|
|
|
1845
1657
|
When you want to apply additional logic to how types are constructed you can specify custom factory globally or per type. Let's say you want to init some properties based on your custom data specified for a type. You can do this by extending default `TypeFactory`.
|
|
1846
1658
|
|
|
1847
1659
|
```typescript
|
|
1848
|
-
import { TypeContext, Injector } from '@dipscope/type-manager
|
|
1849
|
-
import { TypeFactory } from '@dipscope/type-manager/factories';
|
|
1660
|
+
import { TypeContext, Injector, TypeFactory } from '@dipscope/type-manager';
|
|
1850
1661
|
|
|
1851
1662
|
export class CustomTypeFactory extends TypeFactory
|
|
1852
1663
|
{
|
|
@@ -1873,11 +1684,12 @@ export class CustomTypeFactory extends TypeFactory
|
|
|
1873
1684
|
When you are finished with definitions there are two possible ways to register a factory. You can use decorators.
|
|
1874
1685
|
|
|
1875
1686
|
```typescript
|
|
1876
|
-
import { Type, Factory
|
|
1687
|
+
import { Type, Factory } from '@dipscope/type-manager';
|
|
1877
1688
|
|
|
1878
|
-
@Type(
|
|
1879
|
-
|
|
1880
|
-
|
|
1689
|
+
@Type({
|
|
1690
|
+
customData: { rank: 1 },
|
|
1691
|
+
factory: new CustomTypeFactory()
|
|
1692
|
+
})
|
|
1881
1693
|
export class User
|
|
1882
1694
|
{
|
|
1883
1695
|
...
|
|
@@ -1906,13 +1718,13 @@ TypeManager.configureTypeOptionsBase({
|
|
|
1906
1718
|
To define custom naming convention you have to implement `NamingConvention` interface with only one `convert` method. Here is an example implementation of camel case naming convention.
|
|
1907
1719
|
|
|
1908
1720
|
```typescript
|
|
1909
|
-
import { NamingConvention,
|
|
1721
|
+
import { NamingConvention, getWords } from '@dipscope/type-manager';
|
|
1910
1722
|
|
|
1911
1723
|
export class CamelCaseNamingConvention implements NamingConvention
|
|
1912
1724
|
{
|
|
1913
1725
|
public convert(name: string): string
|
|
1914
1726
|
{
|
|
1915
|
-
return
|
|
1727
|
+
return getWords(name).reduce(this.reduce, '');
|
|
1916
1728
|
}
|
|
1917
1729
|
|
|
1918
1730
|
private reduce(result: string, word: string, index: number): string
|
|
@@ -1934,7 +1746,7 @@ export class CamelCaseNamingConvention implements NamingConvention
|
|
|
1934
1746
|
}
|
|
1935
1747
|
```
|
|
1936
1748
|
|
|
1937
|
-
Public `convert` method receives a property name as it declared in a class. You have to call internal `
|
|
1749
|
+
Public `convert` method receives a property name as it declared in a class. You have to call internal `getWords` function on it which will split property name into array of the words. In the `reduce` function you can combine this words to whatever string you want. When you are finished with definitions you have to register custom naming convention for a `TypeManager`.
|
|
1938
1750
|
|
|
1939
1751
|
```typescript
|
|
1940
1752
|
import { TypeManager } from '@dipscope/type-manager';
|
|
@@ -2005,9 +1817,23 @@ To make `Angular` injector work for you a custom `Injector` needs to be implemen
|
|
|
2005
1817
|
|
|
2006
1818
|
Polymorphic types are supported. In most cases additional configuration is required. Check [configuring usage of polymorphic types](#configuring-usage-of-polymorphic-types) section for more info.
|
|
2007
1819
|
|
|
2008
|
-
##
|
|
1820
|
+
## Versioning
|
|
1821
|
+
|
|
1822
|
+
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the versions section on [NPM project page](https://www.npmjs.com/package/@dipscope/type-manager).
|
|
1823
|
+
|
|
1824
|
+
See information about breaking changes, release notes and migration steps between versions in [CHANGELOG.md](https://github.com/dipscope/TypeManager.TS/blob/master/CHANGELOG.md) file.
|
|
2009
1825
|
|
|
2010
|
-
|
|
1826
|
+
## Contributing
|
|
1827
|
+
|
|
1828
|
+
Please read [CONTRIBUTING.md](https://github.com/dipscope/TypeManager.TS/blob/master/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
|
|
1829
|
+
|
|
1830
|
+
## Authors
|
|
1831
|
+
|
|
1832
|
+
* **Dmitry Pimonov** - *Initial work* - [dpimonov](https://github.com/dpimonov)
|
|
1833
|
+
|
|
1834
|
+
See also the list of [contributors](https://github.com/dipscope/TypeManager.TS/contributors) who participated in this project.
|
|
1835
|
+
|
|
1836
|
+
## Notes
|
|
2011
1837
|
|
|
2012
1838
|
Thanks for checking this package.
|
|
2013
1839
|
|
|
@@ -2017,4 +1843,4 @@ We wish you good luck and happy coding!
|
|
|
2017
1843
|
|
|
2018
1844
|
## License
|
|
2019
1845
|
|
|
2020
|
-
|
|
1846
|
+
This project is licensed under the Apache 2.0 License - see the [LICENSE.md](https://github.com/dipscope/TypeManager.TS/blob/master/LICENSE.md) file for details.
|