@dipscope/type-manager 4.0.4 → 5.0.0-beta.0
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 +38 -0
- package/{LICENSE.txt → LICENSE.md} +0 -0
- package/README.md +143 -321
- package/alias.d.ts +3 -7
- package/custom-data.d.ts +3 -8
- package/default-value-resolver.d.ts +7 -0
- package/default-value.d.ts +4 -7
- 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 -7
- 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} +0 -0
- 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 -12
- package/{core/property-name.d.ts → property-name.d.ts} +0 -0
- package/{core/property-options.d.ts → property-options.d.ts} +21 -4
- package/property.d.ts +3 -2
- package/{core/reference-callback.d.ts → reference-callback.d.ts} +0 -0
- package/reference-handler.d.ts +29 -8
- package/reference-handlers/direct-reference-handler.d.ts +6 -6
- package/reference-handlers/lead-reference-handler.d.ts +6 -6
- package/reference-handlers/path-reference-handler.d.ts +6 -6
- package/{core/reference-key.d.ts → reference-key.d.ts} +0 -0
- package/{core/reference-value-initializer.d.ts → reference-value-initializer.d.ts} +0 -0
- package/{core/reference-value-resolver.d.ts → reference-value-resolver.d.ts} +0 -0
- package/{core/reference-value.d.ts → reference-value.d.ts} +0 -0
- package/{core/serializer-context-options.d.ts → serializer-context-options.d.ts} +0 -0
- package/{core/serializer-context.d.ts → serializer-context.d.ts} +9 -3
- 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 +3 -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 +3 -3
- 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} +9 -3
- package/{core/type-name.d.ts → type-name.d.ts} +0 -0
- package/{core/type-options-base.d.ts → type-options-base.d.ts} +0 -9
- package/{core/type-options.d.ts → type-options.d.ts} +26 -0
- 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/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 -42
- 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/serializer.d.ts +0 -27
- package/deserializable.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/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,23 @@ 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
|
-
* [Reference handler
|
|
35
|
-
* [Serializable
|
|
36
|
-
* [Serializer
|
|
37
|
-
* [Use default value
|
|
38
|
-
* [Use implicit conversion
|
|
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
|
+
* [Reference handler option](#reference-handler-option)
|
|
35
|
+
* [Serializable option](#serializable-option)
|
|
36
|
+
* [Serializer option](#serializer-option)
|
|
37
|
+
* [Use default value option](#use-default-value-option)
|
|
38
|
+
* [Use implicit conversion option](#use-implicit-conversion-option)
|
|
39
39
|
* [Defining configuration manually](#defining-configuration-manually)
|
|
40
40
|
* [Configuring global options](#configuring-global-options)
|
|
41
41
|
* [Configuring options per type](#configuring-options-per-type)
|
|
@@ -57,6 +57,9 @@ If you like or are using this project please give it a star. Thanks!
|
|
|
57
57
|
* [Generic types](#generic-types)
|
|
58
58
|
* [Integration with Angular](#integration-with-angular)
|
|
59
59
|
* [Polymorphic types](#polymorphic-types)
|
|
60
|
+
* [Versioning](#versioning)
|
|
61
|
+
* [Contributing](#contributing)
|
|
62
|
+
* [Authors](#authors)
|
|
60
63
|
* [Notes](#notes)
|
|
61
64
|
* [License](#license)
|
|
62
65
|
|
|
@@ -158,12 +161,12 @@ Now we can use all power provided by `JavaScript` class instances. Want to know
|
|
|
158
161
|
`TypeManager.TS` is available from NPM, both for browser (e.g. using webpack) and NodeJS:
|
|
159
162
|
|
|
160
163
|
```
|
|
161
|
-
npm
|
|
164
|
+
npm i @dipscope/type-manager
|
|
162
165
|
```
|
|
163
166
|
|
|
164
167
|
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
168
|
|
|
166
|
-
|
|
169
|
+
_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
170
|
|
|
168
171
|
## How it works?
|
|
169
172
|
|
|
@@ -192,8 +195,7 @@ Here we have a `User` class with `Type` and `Property` decorators assigned to it
|
|
|
192
195
|
The same configuration can be rewritten using declarative style.
|
|
193
196
|
|
|
194
197
|
```typescript
|
|
195
|
-
import { TypeManager } from '@dipscope/type-manager';
|
|
196
|
-
import { PropertyName, PropertyOptions } from '@dipscope/type-manager/core';
|
|
198
|
+
import { TypeManager, PropertyName, PropertyOptions } from '@dipscope/type-manager';
|
|
197
199
|
|
|
198
200
|
export class User
|
|
199
201
|
{
|
|
@@ -251,7 +253,7 @@ At first glance, it may seems that there is no difference but creating an instan
|
|
|
251
253
|
|
|
252
254
|
## Defining decorators
|
|
253
255
|
|
|
254
|
-
|
|
256
|
+
There are few decorators which controls the main flow. This are `Type`, `Property` and `Inject` decorators. Let's go through each of them.
|
|
255
257
|
|
|
256
258
|
### Type decorator
|
|
257
259
|
|
|
@@ -284,7 +286,7 @@ export class User
|
|
|
284
286
|
|
|
285
287
|
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
288
|
|
|
287
|
-
There are more options can be provided for a type, so check `TypeOptions` definition or section with [
|
|
289
|
+
There are more options can be provided for a type, so check `TypeOptions` definition or section with [decorator options](#defining-decorator-options) below.
|
|
288
290
|
|
|
289
291
|
### Property decorator
|
|
290
292
|
|
|
@@ -340,7 +342,7 @@ export class User
|
|
|
340
342
|
}
|
|
341
343
|
```
|
|
342
344
|
|
|
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 [
|
|
345
|
+
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
346
|
|
|
345
347
|
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
348
|
|
|
@@ -594,16 +596,18 @@ When a string key is provided then a certain value will be resolved from JSON co
|
|
|
594
596
|
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
597
|
|
|
596
598
|
```typescript
|
|
597
|
-
import {
|
|
599
|
+
import { Type } from '@dipscope/type-manager';
|
|
598
600
|
|
|
599
|
-
@
|
|
601
|
+
@Type({
|
|
602
|
+
injectable: true
|
|
603
|
+
})
|
|
600
604
|
export class UserService
|
|
601
605
|
{
|
|
602
606
|
public property: string;
|
|
603
607
|
}
|
|
604
608
|
```
|
|
605
609
|
|
|
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.
|
|
610
|
+
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
611
|
|
|
608
612
|
If you are using [reflect-metadata](https://github.com/rbuckton/reflect-metadata) the injection of services can be simplified.
|
|
609
613
|
|
|
@@ -626,26 +630,13 @@ export class User
|
|
|
626
630
|
|
|
627
631
|
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
632
|
|
|
629
|
-
## Defining
|
|
633
|
+
## Defining decorator options
|
|
630
634
|
|
|
631
|
-
`Type` and `Property` decorators provide full configuration for your classes using configure options
|
|
635
|
+
`Type` and `Property` decorators provide full configuration for your classes using configure options. In this section we will go through each of them.
|
|
632
636
|
|
|
633
|
-
### Alias
|
|
637
|
+
### Alias option
|
|
634
638
|
|
|
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:
|
|
639
|
+
This option can be used both on type and property to define an alias.
|
|
649
640
|
|
|
650
641
|
```typescript
|
|
651
642
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -663,22 +654,9 @@ Alias defined for a class can be used later for resolving property types. Note t
|
|
|
663
654
|
|
|
664
655
|
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
656
|
|
|
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
|
-
```
|
|
657
|
+
### Custom data option
|
|
680
658
|
|
|
681
|
-
|
|
659
|
+
This option can be used to provide any custom data for type or property.
|
|
682
660
|
|
|
683
661
|
```typescript
|
|
684
662
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -694,22 +672,9 @@ export class User
|
|
|
694
672
|
|
|
695
673
|
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
674
|
|
|
697
|
-
### Default value
|
|
675
|
+
### Default value option
|
|
698
676
|
|
|
699
|
-
This
|
|
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
|
-
```
|
|
711
|
-
|
|
712
|
-
Such declaration is an alternative for:
|
|
677
|
+
This option is used to define a default value when one is undefined. It can be used on type or property.
|
|
713
678
|
|
|
714
679
|
```typescript
|
|
715
680
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -723,23 +688,26 @@ export class User
|
|
|
723
688
|
}
|
|
724
689
|
```
|
|
725
690
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
### Deserializable decorator
|
|
729
|
-
|
|
730
|
-
This decorator is used to enable or disable deserialization for a certain property.
|
|
691
|
+
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.
|
|
731
692
|
|
|
732
693
|
```typescript
|
|
733
|
-
import { Type, Property
|
|
694
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
734
695
|
|
|
735
|
-
@Type(
|
|
696
|
+
@Type({
|
|
697
|
+
serializedDefaultValue: () => new User(),
|
|
698
|
+
deserializedDefaultValue: () => new User()
|
|
699
|
+
})
|
|
736
700
|
export class User
|
|
737
701
|
{
|
|
738
|
-
@Property(String
|
|
702
|
+
@Property(String, { serializedDefaultValue: 'BestName', deserializedDefaultValue: 'BestName' }) public name: string;
|
|
739
703
|
}
|
|
740
704
|
```
|
|
741
705
|
|
|
742
|
-
|
|
706
|
+
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.
|
|
707
|
+
|
|
708
|
+
### Deserializable option
|
|
709
|
+
|
|
710
|
+
This option is used to enable or disable deserialization for a certain property.
|
|
743
711
|
|
|
744
712
|
```typescript
|
|
745
713
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -753,22 +721,9 @@ export class User
|
|
|
753
721
|
|
|
754
722
|
By default all properties are deserializable.
|
|
755
723
|
|
|
756
|
-
### Discriminant
|
|
757
|
-
|
|
758
|
-
This decorator is used to define a custom discriminant for a type which is later used during serialization and deserialization of polymorphic types.
|
|
759
|
-
|
|
760
|
-
```typescript
|
|
761
|
-
import { Type, Property, Discriminant } from '@dipscope/type-manager';
|
|
762
|
-
|
|
763
|
-
@Type()
|
|
764
|
-
@Discriminant('Company.Api.Entities.User')
|
|
765
|
-
export class User
|
|
766
|
-
{
|
|
767
|
-
@Property(String) public name: string;
|
|
768
|
-
}
|
|
769
|
-
```
|
|
724
|
+
### Discriminant option
|
|
770
725
|
|
|
771
|
-
|
|
726
|
+
This option is used to define a custom discriminant for a type which is later used during serialization and deserialization of polymorphic types.
|
|
772
727
|
|
|
773
728
|
```typescript
|
|
774
729
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -784,22 +739,9 @@ export class User
|
|
|
784
739
|
|
|
785
740
|
You can read more about handling of polymorphic types in this [section](#configuring-usage-of-polymorphic-types).
|
|
786
741
|
|
|
787
|
-
### Discriminator
|
|
742
|
+
### Discriminator option
|
|
788
743
|
|
|
789
|
-
This
|
|
790
|
-
|
|
791
|
-
```typescript
|
|
792
|
-
import { Type, Property, Discriminator } from '@dipscope/type-manager';
|
|
793
|
-
|
|
794
|
-
@Type()
|
|
795
|
-
@Discriminator('__typename__')
|
|
796
|
-
export class User
|
|
797
|
-
{
|
|
798
|
-
@Property(String) public name: string;
|
|
799
|
-
}
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
Such declaration is an alternative for:
|
|
744
|
+
This option can be used to define a custom property which stores discriminant of polymorphic type.
|
|
803
745
|
|
|
804
746
|
```typescript
|
|
805
747
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -815,22 +757,9 @@ export class User
|
|
|
815
757
|
|
|
816
758
|
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).
|
|
817
759
|
|
|
818
|
-
### Factory
|
|
760
|
+
### Factory option
|
|
819
761
|
|
|
820
|
-
This
|
|
821
|
-
|
|
822
|
-
```typescript
|
|
823
|
-
import { Type, Property, Factory } from '@dipscope/type-manager';
|
|
824
|
-
|
|
825
|
-
@Type()
|
|
826
|
-
@Factory(new UserFactory())
|
|
827
|
-
export class User
|
|
828
|
-
{
|
|
829
|
-
@Property(String) public name: string;
|
|
830
|
-
}
|
|
831
|
-
```
|
|
832
|
-
|
|
833
|
-
Such declaration is an alternative for:
|
|
762
|
+
This option can be used to register a handler which should be used for constructing a type instead of default one.
|
|
834
763
|
|
|
835
764
|
```typescript
|
|
836
765
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -846,22 +775,9 @@ export class User
|
|
|
846
775
|
|
|
847
776
|
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.
|
|
848
777
|
|
|
849
|
-
### Injectable
|
|
778
|
+
### Injectable option
|
|
850
779
|
|
|
851
|
-
This
|
|
852
|
-
|
|
853
|
-
```typescript
|
|
854
|
-
import { Injectable } from '@dipscope/type-manager';
|
|
855
|
-
|
|
856
|
-
@Type()
|
|
857
|
-
@Injectable()
|
|
858
|
-
export class UserService
|
|
859
|
-
{
|
|
860
|
-
public property: string;
|
|
861
|
-
}
|
|
862
|
-
```
|
|
863
|
-
|
|
864
|
-
Such declaration is an alternative for:
|
|
780
|
+
This option is used to register a type in dependency injection container.
|
|
865
781
|
|
|
866
782
|
```typescript
|
|
867
783
|
import { Type } from '@dipscope/type-manager';
|
|
@@ -894,24 +810,11 @@ export class User
|
|
|
894
810
|
}
|
|
895
811
|
```
|
|
896
812
|
|
|
897
|
-
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.
|
|
813
|
+
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.
|
|
898
814
|
|
|
899
|
-
### Injector
|
|
900
|
-
|
|
901
|
-
This decorator can be used to define a custom injector implementation which should be used in a type scope.
|
|
902
|
-
|
|
903
|
-
```typescript
|
|
904
|
-
import { Type, Property, Injector } from '@dipscope/type-manager';
|
|
905
|
-
|
|
906
|
-
@Type()
|
|
907
|
-
@Injector(new UserInjector())
|
|
908
|
-
export class User
|
|
909
|
-
{
|
|
910
|
-
@Property(String) public name: string;
|
|
911
|
-
}
|
|
912
|
-
```
|
|
815
|
+
### Injector option
|
|
913
816
|
|
|
914
|
-
|
|
817
|
+
This option can be used to define a custom injector implementation which should be used in a type scope.
|
|
915
818
|
|
|
916
819
|
```typescript
|
|
917
820
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -927,27 +830,12 @@ export class User
|
|
|
927
830
|
|
|
928
831
|
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.
|
|
929
832
|
|
|
930
|
-
### Naming convention
|
|
931
|
-
|
|
932
|
-
This decorator can be used both on type and property to provide custom naming strategy.
|
|
933
|
-
|
|
934
|
-
```typescript
|
|
935
|
-
import { Type, Property, NamingConvention } from '@dipscope/type-manager';
|
|
936
|
-
import { CamelCaseNamingConvention, SnakeCaseNamingConvention } from '@dipscope/type-manager/naming-conventions';
|
|
937
|
-
|
|
938
|
-
@Type()
|
|
939
|
-
@NamingConvention(new CamelCaseNamingConvention())
|
|
940
|
-
export class User
|
|
941
|
-
{
|
|
942
|
-
@Property(String) @NamingConvention(new SnakeCaseNamingConvention()) public name: string;
|
|
943
|
-
}
|
|
944
|
-
```
|
|
833
|
+
### Naming convention option
|
|
945
834
|
|
|
946
|
-
|
|
835
|
+
This option can be used both on type and property to provide custom naming strategy.
|
|
947
836
|
|
|
948
837
|
```typescript
|
|
949
|
-
import { Type, Property } from '@dipscope/type-manager';
|
|
950
|
-
import { CamelCaseNamingConvention, SnakeCaseNamingConvention } from '@dipscope/type-manager/naming-conventions';
|
|
838
|
+
import { Type, Property, CamelCaseNamingConvention, SnakeCaseNamingConvention } from '@dipscope/type-manager';
|
|
951
839
|
|
|
952
840
|
@Type({
|
|
953
841
|
namingConvention: new CamelCaseNamingConvention()
|
|
@@ -960,22 +848,9 @@ export class User
|
|
|
960
848
|
|
|
961
849
|
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.
|
|
962
850
|
|
|
963
|
-
### Preserve discriminator
|
|
851
|
+
### Preserve discriminator option
|
|
964
852
|
|
|
965
|
-
This
|
|
966
|
-
|
|
967
|
-
```typescript
|
|
968
|
-
import { Type, Property, PreserveDiscriminator } from '@dipscope/type-manager';
|
|
969
|
-
|
|
970
|
-
@Type()
|
|
971
|
-
@PreserveDiscriminator()
|
|
972
|
-
export class User
|
|
973
|
-
{
|
|
974
|
-
@Property(String) public name: string;
|
|
975
|
-
}
|
|
976
|
-
```
|
|
977
|
-
|
|
978
|
-
Such declaration is an alternative for:
|
|
853
|
+
This option defines if discriminator should be preserved in objects during serialization and deserialization.
|
|
979
854
|
|
|
980
855
|
```typescript
|
|
981
856
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -991,27 +866,12 @@ export class User
|
|
|
991
866
|
|
|
992
867
|
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).
|
|
993
868
|
|
|
994
|
-
### Reference handler
|
|
869
|
+
### Reference handler option
|
|
995
870
|
|
|
996
|
-
This
|
|
871
|
+
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.
|
|
997
872
|
|
|
998
873
|
```typescript
|
|
999
|
-
import { Type, Property,
|
|
1000
|
-
import { DirectReferenceHandler, LeadReferenceHandler } from '@dipscope/type-manager/reference-handlers';
|
|
1001
|
-
|
|
1002
|
-
@Type()
|
|
1003
|
-
@ReferenceHandler(new DirectReferenceHandler())
|
|
1004
|
-
export class User
|
|
1005
|
-
{
|
|
1006
|
-
@Property(String) @ReferenceHandler(new LeadReferenceHandler()) public name: string;
|
|
1007
|
-
}
|
|
1008
|
-
```
|
|
1009
|
-
|
|
1010
|
-
Such declaration is an alternative for:
|
|
1011
|
-
|
|
1012
|
-
```typescript
|
|
1013
|
-
import { Type, Property } from '@dipscope/type-manager';
|
|
1014
|
-
import { DirectReferenceHandler, LeadReferenceHandler } from '@dipscope/type-manager/reference-handlers';
|
|
874
|
+
import { Type, Property, DirectReferenceHandler, LeadReferenceHandler } from '@dipscope/type-manager';
|
|
1015
875
|
|
|
1016
876
|
@Type({
|
|
1017
877
|
referenceHandler: new DirectReferenceHandler()
|
|
@@ -1024,21 +884,9 @@ export class User
|
|
|
1024
884
|
|
|
1025
885
|
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.
|
|
1026
886
|
|
|
1027
|
-
### Serializable
|
|
887
|
+
### Serializable option
|
|
1028
888
|
|
|
1029
|
-
This
|
|
1030
|
-
|
|
1031
|
-
```typescript
|
|
1032
|
-
import { Type, Property, Serializable } from '@dipscope/type-manager';
|
|
1033
|
-
|
|
1034
|
-
@Type()
|
|
1035
|
-
export class User
|
|
1036
|
-
{
|
|
1037
|
-
@Property(String) @Serializable() public name: string;
|
|
1038
|
-
}
|
|
1039
|
-
```
|
|
1040
|
-
|
|
1041
|
-
Such declaration is an alternative for:
|
|
889
|
+
This option is used to enable or disable serialization for a certain property.
|
|
1042
890
|
|
|
1043
891
|
```typescript
|
|
1044
892
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1052,22 +900,9 @@ export class User
|
|
|
1052
900
|
|
|
1053
901
|
By default all properties are serializable.
|
|
1054
902
|
|
|
1055
|
-
### Serializer
|
|
1056
|
-
|
|
1057
|
-
This decorator is used to define custom serializer for a type or property.
|
|
1058
|
-
|
|
1059
|
-
```typescript
|
|
1060
|
-
import { Type, Property, Serializer } from '@dipscope/type-manager';
|
|
1061
|
-
|
|
1062
|
-
@Type()
|
|
1063
|
-
@Serializer(new UserSerializer())
|
|
1064
|
-
export class User
|
|
1065
|
-
{
|
|
1066
|
-
@Property(String) @Serializer(new UserNameSerializer()) public name: string;
|
|
1067
|
-
}
|
|
1068
|
-
```
|
|
903
|
+
### Serializer option
|
|
1069
904
|
|
|
1070
|
-
|
|
905
|
+
This option is used to define custom serializer for a type or property.
|
|
1071
906
|
|
|
1072
907
|
```typescript
|
|
1073
908
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1083,22 +918,9 @@ export class User
|
|
|
1083
918
|
|
|
1084
919
|
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.
|
|
1085
920
|
|
|
1086
|
-
### Use default value
|
|
1087
|
-
|
|
1088
|
-
This decorator enables or disables using default value per type or property.
|
|
1089
|
-
|
|
1090
|
-
```typescript
|
|
1091
|
-
import { Type, Property, UseDefaultValue } from '@dipscope/type-manager';
|
|
1092
|
-
|
|
1093
|
-
@Type()
|
|
1094
|
-
@UseDefaultValue()
|
|
1095
|
-
export class User
|
|
1096
|
-
{
|
|
1097
|
-
@Property(String) @UseDefaultValue(false) public name: string;
|
|
1098
|
-
}
|
|
1099
|
-
```
|
|
921
|
+
### Use default value option
|
|
1100
922
|
|
|
1101
|
-
|
|
923
|
+
This option enables or disables using default value per type or property.
|
|
1102
924
|
|
|
1103
925
|
```typescript
|
|
1104
926
|
import { Type, Property } from '@dipscope/type-manager';
|
|
@@ -1114,22 +936,10 @@ export class User
|
|
|
1114
936
|
|
|
1115
937
|
Using default values is turned off by default. You can enable them globally using `TypeManager` configure method.
|
|
1116
938
|
|
|
1117
|
-
### Use implicit conversion
|
|
939
|
+
### Use implicit conversion option
|
|
1118
940
|
|
|
1119
941
|
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.
|
|
1120
942
|
|
|
1121
|
-
```typescript
|
|
1122
|
-
import { Type, Property, UseImplicitConversion } from '@dipscope/type-manager';
|
|
1123
|
-
|
|
1124
|
-
@Type()
|
|
1125
|
-
export class User
|
|
1126
|
-
{
|
|
1127
|
-
@Property(String) @UseImplicitConversion() public name: string;
|
|
1128
|
-
}
|
|
1129
|
-
```
|
|
1130
|
-
|
|
1131
|
-
Such declaration is an alternative for:
|
|
1132
|
-
|
|
1133
943
|
```typescript
|
|
1134
944
|
import { Type, Property } from '@dipscope/type-manager';
|
|
1135
945
|
|
|
@@ -1140,7 +950,7 @@ export class User
|
|
|
1140
950
|
}
|
|
1141
951
|
```
|
|
1142
952
|
|
|
1143
|
-
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 `
|
|
953
|
+
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.
|
|
1144
954
|
|
|
1145
955
|
## Defining configuration manually
|
|
1146
956
|
|
|
@@ -1153,8 +963,7 @@ We have separate methods to configure each type manager option, so the provided
|
|
|
1153
963
|
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.
|
|
1154
964
|
|
|
1155
965
|
```typescript
|
|
1156
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1157
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
966
|
+
import { TypeManagerOptions, TypeOptionsBase } from '@dipscope/type-manager';
|
|
1158
967
|
|
|
1159
968
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1160
969
|
useDefaultValue: true
|
|
@@ -1175,8 +984,7 @@ Here is an example of declarative configuration which can be used for 3rd party
|
|
|
1175
984
|
|
|
1176
985
|
```typescript
|
|
1177
986
|
import { DateTime } from '@external-library';
|
|
1178
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1179
|
-
import { TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager/core';
|
|
987
|
+
import { TypeManagerOptions, TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager';
|
|
1180
988
|
|
|
1181
989
|
const dateTimeOptions: TypeOptions<DateTime> = {
|
|
1182
990
|
alias: 'DateTime',
|
|
@@ -1381,8 +1189,7 @@ In some cases your `Discriminator` or `Discriminant` values will not match to ou
|
|
|
1381
1189
|
To change `Discriminator` globally you have to use `TypeManager` configure method.
|
|
1382
1190
|
|
|
1383
1191
|
```typescript
|
|
1384
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1385
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1192
|
+
import { TypeManagerOptions, TypeOptionsBase } from '@dipscope/type-manager';
|
|
1386
1193
|
|
|
1387
1194
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1388
1195
|
discriminator: '$customType'
|
|
@@ -1398,8 +1205,7 @@ TypeManager.configure(typeManagerOptions);
|
|
|
1398
1205
|
To change `Discriminant` you have to use per type configuration.
|
|
1399
1206
|
|
|
1400
1207
|
```typescript
|
|
1401
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1402
|
-
import { TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager/core';
|
|
1208
|
+
import { TypeManagerOptions, TypeFn, TypeOptions, PropertyName, PropertyOptions } from '@dipscope/type-manager';
|
|
1403
1209
|
|
|
1404
1210
|
const rectangleOptions: TypeOptions<Rectangle> = {
|
|
1405
1211
|
discriminant: 'Company.Api.Entities.Rectangle'
|
|
@@ -1427,32 +1233,36 @@ TypeManager.configure(typeManagerOptions);
|
|
|
1427
1233
|
As an alternative you can change `Discriminant` as the following using decorators.
|
|
1428
1234
|
|
|
1429
1235
|
```typescript
|
|
1430
|
-
import { Type, Property
|
|
1236
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1431
1237
|
|
|
1432
|
-
@Type(
|
|
1433
|
-
|
|
1238
|
+
@Type({
|
|
1239
|
+
discriminant: 'Company.Api.Entities.Shape'
|
|
1240
|
+
})
|
|
1434
1241
|
export abstract class Shape
|
|
1435
1242
|
{
|
|
1436
1243
|
@Property(String) public title: string;
|
|
1437
1244
|
}
|
|
1438
1245
|
|
|
1439
|
-
@Type(
|
|
1440
|
-
|
|
1246
|
+
@Type({
|
|
1247
|
+
discriminant: 'Company.Api.Entities.Rectangle'
|
|
1248
|
+
})
|
|
1441
1249
|
export class Rectangle extends Shape
|
|
1442
1250
|
{
|
|
1443
1251
|
@Property(Number) public width: number;
|
|
1444
1252
|
@Property(Number) public height: number;
|
|
1445
1253
|
}
|
|
1446
1254
|
|
|
1447
|
-
@Type(
|
|
1448
|
-
|
|
1255
|
+
@Type({
|
|
1256
|
+
discriminant: 'Company.Api.Entities.Square'
|
|
1257
|
+
})
|
|
1449
1258
|
export class Square extends Shape
|
|
1450
1259
|
{
|
|
1451
1260
|
@Property(Number) public width: number;
|
|
1452
1261
|
}
|
|
1453
1262
|
|
|
1454
|
-
@Type(
|
|
1455
|
-
|
|
1263
|
+
@Type({
|
|
1264
|
+
discriminant: 'Company.Api.Entities.Circle'
|
|
1265
|
+
})
|
|
1456
1266
|
export class Circle extends Shape
|
|
1457
1267
|
{
|
|
1458
1268
|
@Property(Number) public radius: number;
|
|
@@ -1462,8 +1272,7 @@ export class Circle extends Shape
|
|
|
1462
1272
|
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.
|
|
1463
1273
|
|
|
1464
1274
|
```typescript
|
|
1465
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1466
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1275
|
+
import { TypeManagerOptions, TypeOptionsBase } from '@dipscope/type-manager';
|
|
1467
1276
|
|
|
1468
1277
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1469
1278
|
preserveDiscriminator: true
|
|
@@ -1541,14 +1350,14 @@ But what to do if we don't control the JSON naming convention so it comes to us
|
|
|
1541
1350
|
We can still parse such a JSON by specifying an alias for each property but this will become a pain in a while.
|
|
1542
1351
|
|
|
1543
1352
|
```typescript
|
|
1544
|
-
import { Type, Property
|
|
1353
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1545
1354
|
|
|
1546
1355
|
@Type()
|
|
1547
1356
|
export class User
|
|
1548
1357
|
{
|
|
1549
1358
|
@Property(String) public name: string;
|
|
1550
|
-
@Property(Number
|
|
1551
|
-
@Property(DateTime
|
|
1359
|
+
@Property(Number, { alias: 'login_count' }) public loginCount: number;
|
|
1360
|
+
@Property(DateTime, { alias: 'created_at' }) public createdAt: DateTime;
|
|
1552
1361
|
}
|
|
1553
1362
|
```
|
|
1554
1363
|
|
|
@@ -1566,9 +1375,7 @@ export class User
|
|
|
1566
1375
|
To set one we have to configure global options.
|
|
1567
1376
|
|
|
1568
1377
|
```typescript
|
|
1569
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1570
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1571
|
-
import { SnakeCaseNamingConvention } from '@dipscope/type-manager/naming-conventions';
|
|
1378
|
+
import { TypeManagerOptions, TypeOptionsBase, SnakeCaseNamingConvention } from '@dipscope/type-manager';
|
|
1572
1379
|
|
|
1573
1380
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1574
1381
|
namingConvention: new SnakeCaseNamingConvention()
|
|
@@ -1639,9 +1446,7 @@ Here are results returned by different reference handlers:
|
|
|
1639
1446
|
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.
|
|
1640
1447
|
|
|
1641
1448
|
```typescript
|
|
1642
|
-
import { TypeManagerOptions } from '@dipscope/type-manager';
|
|
1643
|
-
import { TypeOptionsBase } from '@dipscope/type-manager/core';
|
|
1644
|
-
import { PathReferenceHandler } from '@dipscope/type-manager/reference-handlers';
|
|
1449
|
+
import { TypeManagerOptions, TypeOptionsBase, PathReferenceHandler } from '@dipscope/type-manager';
|
|
1645
1450
|
|
|
1646
1451
|
const typeOptionsBase: TypeOptionsBase<any> = {
|
|
1647
1452
|
referenceHandler: new PathReferenceHandler()
|
|
@@ -1665,13 +1470,14 @@ Our goal is to cover as much use cases as possible without making you to write a
|
|
|
1665
1470
|
You can attach you custom metadata to our decorators using `customData` option available on `Type` and `Property`.
|
|
1666
1471
|
|
|
1667
1472
|
```typescript
|
|
1668
|
-
import { Type, Property
|
|
1473
|
+
import { Type, Property } from '@dipscope/type-manager';
|
|
1669
1474
|
|
|
1670
|
-
@Type(
|
|
1671
|
-
|
|
1475
|
+
@Type({
|
|
1476
|
+
customData: { rank: 1 }
|
|
1477
|
+
})
|
|
1672
1478
|
class User
|
|
1673
1479
|
{
|
|
1674
|
-
@Property(String
|
|
1480
|
+
@Property(String, { customData: { priority: 10 } }) public name: string;
|
|
1675
1481
|
}
|
|
1676
1482
|
```
|
|
1677
1483
|
|
|
@@ -1698,7 +1504,8 @@ for (const propertyMetadata of userMetadata.propertyMetadataMap.values())
|
|
|
1698
1504
|
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.
|
|
1699
1505
|
|
|
1700
1506
|
```typescript
|
|
1701
|
-
import { Serializer, TypeLike, SerializerContext
|
|
1507
|
+
import { Serializer, TypeLike, SerializerContext } from '@dipscope/type-manager';
|
|
1508
|
+
import { Fn } from '@app/module';
|
|
1702
1509
|
|
|
1703
1510
|
export class DateTimeSerializer implements Serializer<DateTime>
|
|
1704
1511
|
{
|
|
@@ -1706,7 +1513,7 @@ export class DateTimeSerializer implements Serializer<DateTime>
|
|
|
1706
1513
|
{
|
|
1707
1514
|
if (Fn.isUndefined(x))
|
|
1708
1515
|
{
|
|
1709
|
-
return serializerContext.
|
|
1516
|
+
return serializerContext.serializedDefaultValue;
|
|
1710
1517
|
}
|
|
1711
1518
|
|
|
1712
1519
|
if (Fn.isNull(x))
|
|
@@ -1721,7 +1528,7 @@ export class DateTimeSerializer implements Serializer<DateTime>
|
|
|
1721
1528
|
|
|
1722
1529
|
if (serializerContext.log.errorEnabled)
|
|
1723
1530
|
{
|
|
1724
|
-
serializerContext.log.error(`${serializerContext.path}:
|
|
1531
|
+
serializerContext.log.error(`${serializerContext.path}: cannot serialize value as date time.`, x);
|
|
1725
1532
|
}
|
|
1726
1533
|
|
|
1727
1534
|
return undefined;
|
|
@@ -1731,7 +1538,7 @@ export class DateTimeSerializer implements Serializer<DateTime>
|
|
|
1731
1538
|
{
|
|
1732
1539
|
if (Fn.isUndefined(x))
|
|
1733
1540
|
{
|
|
1734
|
-
return serializerContext.
|
|
1541
|
+
return serializerContext.deserializedDefaultValue;
|
|
1735
1542
|
}
|
|
1736
1543
|
|
|
1737
1544
|
if (Fn.isNull(x))
|
|
@@ -1746,7 +1553,7 @@ export class DateTimeSerializer implements Serializer<DateTime>
|
|
|
1746
1553
|
|
|
1747
1554
|
if (serializerContext.log.errorEnabled)
|
|
1748
1555
|
{
|
|
1749
|
-
serializerContext.log.error(`${serializerContext.path}:
|
|
1556
|
+
serializerContext.log.error(`${serializerContext.path}: cannot deserialize value as date time.`, x);
|
|
1750
1557
|
}
|
|
1751
1558
|
|
|
1752
1559
|
return undefined;
|
|
@@ -1763,8 +1570,9 @@ When you are finished with definitions there are two possible ways to register a
|
|
|
1763
1570
|
```typescript
|
|
1764
1571
|
import { Type, Serializer } from '@dipscope/type-manager';
|
|
1765
1572
|
|
|
1766
|
-
@Type(
|
|
1767
|
-
|
|
1573
|
+
@Type({
|
|
1574
|
+
serializer: new DateTimeSerializer()
|
|
1575
|
+
})
|
|
1768
1576
|
export class DateTime
|
|
1769
1577
|
{
|
|
1770
1578
|
...
|
|
@@ -1789,7 +1597,7 @@ With declarative configuration it is possible to override built in serializers i
|
|
|
1789
1597
|
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`.
|
|
1790
1598
|
|
|
1791
1599
|
```typescript
|
|
1792
|
-
import { Injector, TypeMetadata } from '@dipscope/type-manager
|
|
1600
|
+
import { Injector, TypeMetadata } from '@dipscope/type-manager';
|
|
1793
1601
|
import { Injector as AngularInjector } from '@angular/core';
|
|
1794
1602
|
|
|
1795
1603
|
export class CustomInjector implements Injector
|
|
@@ -1830,8 +1638,7 @@ Now types will be resolved using framework injector.
|
|
|
1830
1638
|
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`.
|
|
1831
1639
|
|
|
1832
1640
|
```typescript
|
|
1833
|
-
import { TypeContext, Injector } from '@dipscope/type-manager
|
|
1834
|
-
import { TypeFactory } from '@dipscope/type-manager/factories';
|
|
1641
|
+
import { TypeContext, Injector, TypeFactory } from '@dipscope/type-manager';
|
|
1835
1642
|
|
|
1836
1643
|
export class CustomTypeFactory extends TypeFactory
|
|
1837
1644
|
{
|
|
@@ -1858,11 +1665,12 @@ export class CustomTypeFactory extends TypeFactory
|
|
|
1858
1665
|
When you are finished with definitions there are two possible ways to register a factory. You can use decorators.
|
|
1859
1666
|
|
|
1860
1667
|
```typescript
|
|
1861
|
-
import { Type, Factory
|
|
1668
|
+
import { Type, Factory } from '@dipscope/type-manager';
|
|
1862
1669
|
|
|
1863
|
-
@Type(
|
|
1864
|
-
|
|
1865
|
-
|
|
1670
|
+
@Type({
|
|
1671
|
+
customData: { rank: 1 },
|
|
1672
|
+
factory: new CustomTypeFactory()
|
|
1673
|
+
})
|
|
1866
1674
|
export class User
|
|
1867
1675
|
{
|
|
1868
1676
|
...
|
|
@@ -1891,13 +1699,13 @@ TypeManager.configureTypeOptionsBase({
|
|
|
1891
1699
|
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.
|
|
1892
1700
|
|
|
1893
1701
|
```typescript
|
|
1894
|
-
import { NamingConvention,
|
|
1702
|
+
import { NamingConvention, getWords } from '@dipscope/type-manager';
|
|
1895
1703
|
|
|
1896
1704
|
export class CamelCaseNamingConvention implements NamingConvention
|
|
1897
1705
|
{
|
|
1898
1706
|
public convert(name: string): string
|
|
1899
1707
|
{
|
|
1900
|
-
return
|
|
1708
|
+
return getWords(name).reduce(this.reduce, '');
|
|
1901
1709
|
}
|
|
1902
1710
|
|
|
1903
1711
|
private reduce(result: string, word: string, index: number): string
|
|
@@ -1919,7 +1727,7 @@ export class CamelCaseNamingConvention implements NamingConvention
|
|
|
1919
1727
|
}
|
|
1920
1728
|
```
|
|
1921
1729
|
|
|
1922
|
-
Public `convert` method receives a property name as it declared in a class. You have to call internal `
|
|
1730
|
+
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`.
|
|
1923
1731
|
|
|
1924
1732
|
```typescript
|
|
1925
1733
|
import { TypeManager } from '@dipscope/type-manager';
|
|
@@ -1990,9 +1798,23 @@ To make `Angular` injector work for you a custom `Injector` needs to be implemen
|
|
|
1990
1798
|
|
|
1991
1799
|
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.
|
|
1992
1800
|
|
|
1993
|
-
##
|
|
1801
|
+
## Versioning
|
|
1802
|
+
|
|
1803
|
+
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).
|
|
1804
|
+
|
|
1805
|
+
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.
|
|
1994
1806
|
|
|
1995
|
-
|
|
1807
|
+
## Contributing
|
|
1808
|
+
|
|
1809
|
+
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.
|
|
1810
|
+
|
|
1811
|
+
## Authors
|
|
1812
|
+
|
|
1813
|
+
* **Dmitry Pimonov** - *Initial work* - [dpimonov](https://github.com/dpimonov)
|
|
1814
|
+
|
|
1815
|
+
See also the list of [contributors](https://github.com/dipscope/TypeManager.TS/contributors) who participated in this project.
|
|
1816
|
+
|
|
1817
|
+
## Notes
|
|
1996
1818
|
|
|
1997
1819
|
Thanks for checking this package.
|
|
1998
1820
|
|
|
@@ -2002,4 +1824,4 @@ We wish you good luck and happy coding!
|
|
|
2002
1824
|
|
|
2003
1825
|
## License
|
|
2004
1826
|
|
|
2005
|
-
|
|
1827
|
+
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.
|