@loopback/metadata 4.0.0-alpha.9 → 4.0.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.
Files changed (97) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +273 -150
  3. package/dist/decorator-factory.d.ts +297 -0
  4. package/{dist6/src → dist}/decorator-factory.js +197 -90
  5. package/dist/decorator-factory.js.map +1 -0
  6. package/dist/index.d.ts +22 -1
  7. package/dist/index.js +24 -7
  8. package/dist/index.js.map +1 -0
  9. package/dist/inspector.d.ts +120 -0
  10. package/dist/inspector.js +186 -0
  11. package/dist/inspector.js.map +1 -0
  12. package/dist/{src/reflect.d.ts → reflect.d.ts} +16 -15
  13. package/dist/{src/reflect.js → reflect.js} +7 -8
  14. package/dist/reflect.js.map +1 -0
  15. package/dist/types.d.ts +70 -0
  16. package/dist/types.js +32 -0
  17. package/dist/types.js.map +1 -0
  18. package/package.json +43 -44
  19. package/src/decorator-factory.ts +289 -140
  20. package/src/index.ts +22 -2
  21. package/src/inspector.ts +118 -126
  22. package/src/reflect.ts +32 -21
  23. package/src/types.ts +94 -0
  24. package/CHANGELOG.md +0 -99
  25. package/api-docs/apple-touch-icon-114x114-precomposed.png +0 -0
  26. package/api-docs/apple-touch-icon-144x144-precomposed.png +0 -0
  27. package/api-docs/apple-touch-icon-57x57-precomposed.png +0 -0
  28. package/api-docs/apple-touch-icon-72x72-precomposed.png +0 -0
  29. package/api-docs/apple-touch-icon-precomposed.png +0 -0
  30. package/api-docs/apple-touch-icon.png +0 -0
  31. package/api-docs/css/bootstrap.min.css +0 -9
  32. package/api-docs/css/code-themes/arta.css +0 -158
  33. package/api-docs/css/code-themes/ascetic.css +0 -50
  34. package/api-docs/css/code-themes/brown_paper.css +0 -104
  35. package/api-docs/css/code-themes/brown_papersq.png +0 -0
  36. package/api-docs/css/code-themes/dark.css +0 -103
  37. package/api-docs/css/code-themes/default.css +0 -135
  38. package/api-docs/css/code-themes/far.css +0 -111
  39. package/api-docs/css/code-themes/github.css +0 -127
  40. package/api-docs/css/code-themes/googlecode.css +0 -144
  41. package/api-docs/css/code-themes/idea.css +0 -121
  42. package/api-docs/css/code-themes/ir_black.css +0 -104
  43. package/api-docs/css/code-themes/magula.css +0 -121
  44. package/api-docs/css/code-themes/monokai.css +0 -114
  45. package/api-docs/css/code-themes/pojoaque.css +0 -104
  46. package/api-docs/css/code-themes/pojoaque.jpg +0 -0
  47. package/api-docs/css/code-themes/rainbow.css +0 -114
  48. package/api-docs/css/code-themes/school_book.css +0 -111
  49. package/api-docs/css/code-themes/school_book.png +0 -0
  50. package/api-docs/css/code-themes/sl-theme.css +0 -45
  51. package/api-docs/css/code-themes/solarized_dark.css +0 -88
  52. package/api-docs/css/code-themes/solarized_light.css +0 -88
  53. package/api-docs/css/code-themes/sunburst.css +0 -158
  54. package/api-docs/css/code-themes/tomorrow-night-blue.css +0 -52
  55. package/api-docs/css/code-themes/tomorrow-night-bright.css +0 -51
  56. package/api-docs/css/code-themes/tomorrow-night-eighties.css +0 -51
  57. package/api-docs/css/code-themes/tomorrow-night.css +0 -52
  58. package/api-docs/css/code-themes/tomorrow.css +0 -49
  59. package/api-docs/css/code-themes/vs.css +0 -86
  60. package/api-docs/css/code-themes/xcode.css +0 -154
  61. package/api-docs/css/code-themes/zenburn.css +0 -115
  62. package/api-docs/css/main.css +0 -139
  63. package/api-docs/favicon.ico +0 -0
  64. package/api-docs/fonts/0ihfXUL2emPh0ROJezvraLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
  65. package/api-docs/fonts/OsJ2DjdpjqFRVUSto6IffLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
  66. package/api-docs/fonts/_aijTyevf54tkVDLy-dlnLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
  67. package/api-docs/index.html +0 -53
  68. package/api-docs/js/main.js +0 -19
  69. package/api-docs/js/vendor/bootstrap.min.js +0 -6
  70. package/api-docs/js/vendor/jquery-1.10.1.min.js +0 -6
  71. package/api-docs/js/vendor/jquery.scrollTo-1.4.3.1.js +0 -218
  72. package/api-docs/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js +0 -11
  73. package/dist/src/decorator-factory.d.ts +0 -252
  74. package/dist/src/decorator-factory.js +0 -468
  75. package/dist/src/decorator-factory.js.map +0 -1
  76. package/dist/src/index.d.ts +0 -3
  77. package/dist/src/index.js +0 -13
  78. package/dist/src/index.js.map +0 -1
  79. package/dist/src/inspector.d.ts +0 -150
  80. package/dist/src/inspector.js +0 -163
  81. package/dist/src/inspector.js.map +0 -1
  82. package/dist/src/reflect.js.map +0 -1
  83. package/dist6/index.d.ts +0 -1
  84. package/dist6/index.js +0 -13
  85. package/dist6/src/decorator-factory.d.ts +0 -252
  86. package/dist6/src/decorator-factory.js.map +0 -1
  87. package/dist6/src/index.d.ts +0 -3
  88. package/dist6/src/index.js +0 -13
  89. package/dist6/src/index.js.map +0 -1
  90. package/dist6/src/inspector.d.ts +0 -150
  91. package/dist6/src/inspector.js +0 -163
  92. package/dist6/src/inspector.js.map +0 -1
  93. package/dist6/src/reflect.d.ts +0 -38
  94. package/dist6/src/reflect.js +0 -143
  95. package/dist6/src/reflect.js.map +0 -1
  96. package/index.d.ts +0 -6
  97. package/index.js +0 -7
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) IBM Corp. 2017,2018. All Rights Reserved.
1
+ Copyright (c) IBM Corp. 2017,2019.
2
2
  Node module: @loopback/metadata
3
3
  This project is licensed under the MIT License, full text below.
4
4
 
package/README.md CHANGED
@@ -1,19 +1,20 @@
1
1
  # @loopback/metadata
2
2
 
3
- This module contains utilities to help developers implement [TypeScript decorators](https://www.typescriptlang.org/docs/handbook/decorators.html), define/merge
4
- metadata, and inspect metadata.
3
+ This module contains utilities to help developers implement
4
+ [TypeScript decorators](https://www.typescriptlang.org/docs/handbook/decorators.html),
5
+ define/merge metadata, and inspect metadata.
5
6
 
6
- * Reflector: Wrapper of
7
+ - Reflector: Wrapper of
7
8
  [reflect-metadata](https://github.com/rbuckton/reflect-metadata)
8
- * Decorator factories: A set of factories for class/method/property/parameter
9
+ - Decorator factories: A set of factories for class/method/property/parameter
9
10
  decorators to apply metadata to a given class and its static or instance
10
11
  members.
11
- * MetadataInspector: High level APIs to inspect a class and/or its members to
12
+ - MetadataInspector: High level APIs to inspect a class and/or its members to
12
13
  get metadata applied by decorators.
13
14
 
14
- # Usage
15
+ ## Basic Use
15
16
 
16
- ## To create a class decorator
17
+ ### To create a class decorator
17
18
 
18
19
  ```ts
19
20
  import {ClassDecoratorFactory} from '@loopback/metadata';
@@ -27,11 +28,12 @@ function myClassDecorator(spec: MyClassMetadata): ClassDecorator {
27
28
  return ClassDecoratorFactory.createDecorator<MyClassMetadata>(
28
29
  'metadata-key-for-my-class-decorator',
29
30
  spec,
31
+ {decoratorName: '@myClassDecorator'},
30
32
  );
31
33
  }
32
34
  ```
33
35
 
34
- Alternativley, we can instantiate the factory and create a decorator:
36
+ Alternatively, we can instantiate the factory and create a decorator:
35
37
 
36
38
  ```ts
37
39
  function myClassDecorator(spec: MyClassMetadata): ClassDecorator {
@@ -50,7 +52,7 @@ Now we can use `@myClassDecorator` to add metadata to a class as follows:
50
52
  class MyController {}
51
53
  ```
52
54
 
53
- ## To create a method decorator
55
+ ### To create a method decorator
54
56
 
55
57
  ```ts
56
58
  import {MethodDecoratorFactory} from '@loopback/metadata';
@@ -85,7 +87,115 @@ class MyController {
85
87
  }
86
88
  ```
87
89
 
88
- ## To create a property decorator
90
+ ### To create a decorator that can be used multiple times on a single method
91
+
92
+ Instead of a single immutable object to be merged, the
93
+ `MethodMultiDecoratorFactory` reduced parameters into a flat array of items.
94
+ When fetching the metadata later, you will receive it as an array.
95
+
96
+ ```ts
97
+ import {MethodMultiDecoratorFactory} from '@loopback/metadata';
98
+
99
+ function myMultiMethodDecorator(spec: object): MethodDecorator {
100
+ return MethodMultiDecoratorFactory.createDecorator<object>(
101
+ 'metadata-key-for-my-method-multi-decorator',
102
+ spec,
103
+ );
104
+ }
105
+ ```
106
+
107
+ Now, you can use it multiple times on a method:
108
+
109
+ ```ts
110
+ class MyController {
111
+ @myMultiMethodDecorator({x: 1})
112
+ @myMultiMethodDecorator({y: 2})
113
+ @myMultiMethodDecorator({z: 3})
114
+ public point() {}
115
+ }
116
+
117
+ class MyOtherController {
118
+ @myMultiMethodDecorator([{x: 1}, {y: 2}, {z: 3}])
119
+ public point() {}
120
+ }
121
+ ```
122
+
123
+ And when you access this data:
124
+
125
+ ```ts
126
+ const arrayOfSpecs = MetadataInspector.getMethodMetadata<object>(
127
+ 'metadata-key-for-my-method-multi-decorator',
128
+ constructor.prototype,
129
+ op,
130
+ );
131
+
132
+ // [{z: 3}, {y: 2}, {x: 1}]
133
+ ```
134
+
135
+ Typescript
136
+ [applies decorators in reverse order](https://www.typescriptlang.org/docs/handbook/decorators.html)
137
+ per class, from the parent down. The metadata array resurned by `getOwnMetadata`
138
+ will be in this order:
139
+
140
+ ```ts
141
+ class Parent {
142
+ @myMultiMethodDecorator('A') // second
143
+ @myMultiMethodDecorator('B') // first
144
+ public greet() {}
145
+ }
146
+
147
+ class Child extends Parent {
148
+ @myMultiMethodDecorator(['C', 'D']) // [third, fourth]
149
+ public greet() {}
150
+ }
151
+
152
+ class Grandchild extends Child {
153
+ @myMultiMethodDecorator('E') // sixth
154
+ @myMultiMethodDecorator('F') // fifth
155
+ public greet() {}
156
+ }
157
+ // getMethodMetadata = ['B', 'A', 'C', 'D', 'F', 'E']
158
+ ```
159
+
160
+ You can also create a decorator that takes an object that can contain an array:
161
+
162
+ ```ts
163
+ interface Point {
164
+ x?: number;
165
+ y?: number;
166
+ z?: number;
167
+ }
168
+ interface GeometryMetadata {
169
+ points: Point[];
170
+ }
171
+ function geometry(...points: Point[]): MethodDecorator {
172
+ return MethodMultiDecoratorFactory.createDecorator<GeometryMetadata>(
173
+ 'metadata-key-for-my-method-multi-decorator',
174
+ points,
175
+ );
176
+ }
177
+
178
+ class MyGeoController {
179
+ @geometry({x: 1})
180
+ @geometry({x: 2}, {y: 3})
181
+ @geometry({z: 5})
182
+ public abstract() {}
183
+ }
184
+
185
+ const arrayOfSpecs = MetadataInspector.getMethodMetadata<GeometryMetadata>(
186
+ 'metadata-key-for-my-method-multi-decorator',
187
+ constructor.prototype,
188
+ op,
189
+ );
190
+
191
+ // [
192
+ // { points: [{x: 1}]},
193
+ // { points: [{x:2}, {y:3}]},
194
+ // { points: [{z: 5}]},
195
+ // ]
196
+ ```
197
+
198
+ ### To create a property decorator
89
199
 
90
200
  ```ts
91
201
  import {PropertyDecoratorFactory} from '@loopback/metadata';
@@ -95,7 +205,7 @@ export interface MyPropertyMetadata {
95
205
  description?: string;
96
206
  }
97
207
 
98
- function myPropertydDecorator(spec: MyPropertyMetadata): PropertyDecorator {
208
+ function myPropertyDecorator(spec: MyPropertyMetadata): PropertyDecorator {
99
209
  return PropertyDecoratorFactory.createDecorator<MyPropertyMetadata>(
100
210
  'metadata-key-for-my-property-decorator',
101
211
  spec,
@@ -118,7 +228,7 @@ class MyController {
118
228
  }
119
229
  ```
120
230
 
121
- ## To create a parameter decorator
231
+ ### To create a parameter decorator
122
232
 
123
233
  ```ts
124
234
  import {ParameterDecoratorFactory} from '@loopback/metadata';
@@ -128,7 +238,7 @@ export interface MyParameterMetadata {
128
238
  description?: string;
129
239
  }
130
240
 
131
- function myParameterdDecorator(spec: MyParameterMetadata): ParameterDecorator {
241
+ function myParameterDecorator(spec: MyParameterMetadata): ParameterDecorator {
132
242
  return ParameterDecoratorFactory.createDecorator<MyParameterMetadata>(
133
243
  'metadata-key-for-my-parameter-decorator',
134
244
  spec,
@@ -136,34 +246,29 @@ function myParameterdDecorator(spec: MyParameterMetadata): ParameterDecorator {
136
246
  }
137
247
  ```
138
248
 
139
- Now we can use `@myParameterDecorator` to add metadata to a parameter as follows:
249
+ Now we can use `@myParameterDecorator` to add metadata to a parameter as
250
+ follows:
140
251
 
141
252
  ```ts
142
253
  class MyController {
143
254
  constructor(
144
- @myParameterDecorator({name: 'logging-prefix'})
145
- public prefix: string,
146
- @myParameterDecorator({name: 'logging-level'})
147
- public level: number,
255
+ @myParameterDecorator({name: 'logging-prefix'}) public prefix: string,
256
+ @myParameterDecorator({name: 'logging-level'}) public level: number,
148
257
  ) {}
149
258
 
150
259
  myMethod(
151
- @myParameterDecorator({name: 'x'})
152
- x: number,
153
- @myParameterDecorator({name: 'y'})
154
- y: number,
260
+ @myParameterDecorator({name: 'x'}) x: number,
261
+ @myParameterDecorator({name: 'y'}) y: number,
155
262
  ) {}
156
263
 
157
264
  static myStaticMethod(
158
- @myParameterDecorator({name: 'a'})
159
- a: string,
160
- @myParameterDecorator({name: 'b'})
161
- b: string,
265
+ @myParameterDecorator({name: 'a'}) a: string,
266
+ @myParameterDecorator({name: 'b'}) b: string,
162
267
  ) {}
163
268
  }
164
269
  ```
165
270
 
166
- ## To create method decorator for parameters
271
+ ### To create method decorator for parameters
167
272
 
168
273
  ```ts
169
274
  import {MethodParameterDecoratorFactory} from '@loopback/metadata';
@@ -183,149 +288,150 @@ function myMethodParameterDecorator(
183
288
  }
184
289
  ```
185
290
 
186
- Now we can use `@myMethodParameterDecorator` to add metadata to a parameter
187
- as follows:
291
+ Now we can use `@myMethodParameterDecorator` to add metadata to a parameter as
292
+ follows:
188
293
 
189
294
  ```ts
190
295
  class MyController {
191
296
  @myMethodParameterDecorator({name: 'x'})
192
297
  @myMethodParameterDecorator({name: 'y'})
193
- myMethod(
194
- x: number,
195
- y: number,
196
- ) {}
298
+ myMethod(x: number, y: number) {}
299
+ }
197
300
  ```
198
301
 
199
302
  **WARNING**: Using method decorators to provide metadata for parameters is
200
303
  strongly discouraged for a few reasons:
201
304
 
202
- 1. Method decorators cannot be applied to a constructor
203
- 2. Method decorators depends on the positions to match parameters
305
+ 1. Method decorators cannot be applied to a constructor
306
+ 2. Method decorators depends on the positions to match parameters
204
307
 
205
308
  We recommend that `ParameterDecorator` be used instead.
206
309
 
207
- ## Decorator options
310
+ ### Decorator options
208
311
 
209
312
  An object of type `DecoratorOptions` can be passed in to create decorator
210
313
  functions. There are two flags for the options:
211
314
 
212
- - allowInheritance: Controls if inherited metadata will be honored. Default to `true`.
315
+ - allowInheritance: Controls if inherited metadata will be honored. Default to
316
+ `true`.
213
317
  - cloneInputSpec: Controls if the value of `spec` argument will be cloned.
214
- Sometimes we use shared spec for the decoration, but the decorator function
215
- might need to mutate the object. Cloning the input spec makes it safe to use
216
- the same spec (`template`) to decorate different members. Default to `true`.
318
+ Sometimes we use shared spec for the decoration, but the decorator function
319
+ might need to mutate the object. Cloning the input spec makes it safe to use
320
+ the same spec (`template`) to decorate different members. Default to `true`.
321
+ - decoratorName: Name for the decorator such as `@inject` for error and
322
+ debugging messages.
217
323
 
218
- ## Customize inheritance of metadata
324
+ ### Customize inheritance of metadata
219
325
 
220
326
  By default, the decorator factories allow inheritance with the following rules:
221
327
 
222
- 1. If the metadata is an object, we merge the `spec` argument from the decorator
223
- function into the inherited value from base classes. For metadata of array and
224
- other primitive types, the `spec` argument is used if provided.
328
+ 1. If the metadata is an object, we merge the `spec` argument from the
329
+ decorator function into the inherited value from base classes. For metadata
330
+ of array and other primitive types, the `spec` argument is used if provided.
225
331
 
226
- - We can override `inherit` method of the decorator factory to customize
227
- how to resolve `spec` against the inherited metadata. For example:
332
+ - We can override `inherit` method of the decorator factory to customize how
333
+ to resolve `spec` against the inherited metadata. For example:
228
334
 
229
- ```ts
230
- protected inherit(inheritedMetadata: T | undefined | null): T {
231
- // Ignore the inherited metadata
232
- return this.spec;
233
- }
234
- ```
335
+ ```ts
336
+ protected inherit(inheritedMetadata: T | undefined | null): T {
337
+ // Ignore the inherited metadata
338
+ return this.spec;
339
+ }
340
+ ```
235
341
 
236
- 2. Method/property/parameter level metadata is applied to the class or its
237
- prototype as a map keyed method/property names. We think this approach is better
238
- than keeping metadata at method/property level as it's not easy to inspect a
239
- class to find static/instance methods and properties with decorations. The
240
- metadata for a class is illustrated below:
342
+ 2. Method/property/parameter level metadata is applied to the class or its
343
+ prototype as a map keyed method/property names. We think this approach is
344
+ better than keeping metadata at method/property level as it's not easy to
345
+ inspect a class to find static/instance methods and properties with
346
+ decorations. The metadata for a class is illustrated below:
241
347
 
242
348
  - MyClass (the constructor function itself)
243
349
 
244
- ```ts
245
- {
246
- // Class level metadata
247
- 'my-class-decorator-key': MyClassMetadata,
248
- // Static method (including the construtor) parameter metadata
249
- 'my-static-parameter-decorator-key': {
250
- '': [MyConstructorParameterMetadata], // Constructor parameter metadata
251
- 'myStaticMethod1': [MyStaticMethodParameterMetadata],
252
- 'myStaticMethod2': [MyStaticMethodParameterMetadata],
253
- },
254
- // Static method metadata
255
- 'my-static-method-decorator-key': {
256
- 'myStaticMethod1': MyStaticMethodMetadata,
257
- 'myStaticMethod2': MyStaticMethodMetadata,
258
- },
259
- // Static property metadata
260
- 'my-static-property-decorator-key': {
261
- 'myStaticMethod1': MyStaticPropertyMetadata,
262
- 'myStaticMethod1': MyStaticPropertyMetadata,
263
- }
264
- }
265
- ```
266
-
267
- - MyClass.prototype
268
-
269
- ```ts
270
- {
271
- // Instance method parameter metadata
272
- 'my-instance-parameter-decorator-key': {
273
- 'myMethod1': [MyMethodParameterMetadata],
274
- 'myMethod2': [MyMethodParameterMetadata],
275
- },
276
- // Instance method metadata
277
- 'my-instance-method-decorator-key': {
278
- 'myMethod1': MyMethodMetadata,
279
- 'myMethod2': MyMethodMetadata,
280
- },
281
- // Instance property metadata
282
- 'my-instance-property-decorator-key': {
283
- 'myProperty1': MyPropertyMetadata,
284
- 'myProperty2': MyPropertyMetadata,
285
- }
286
- }
287
- ```
288
-
289
- The following methods in `DecoratorFactory` allow subclasses to customize how
290
- to merge the `spec` with existing metadata for a class, methods, properties, and
291
- method parameters. Please note `M` is a map for methods/properties/parameters.
292
-
293
- ```ts
294
- protected mergeWithInherited(
295
- inheritedMetadata: M,
296
- target: Object,
297
- member?: string | symbol,
298
- descriptorOrIndex?: TypedPropertyDescriptor<any> | number,
299
- ): M {
300
- // ...
301
- }
302
-
303
- protected mergeWithOwn(
304
- ownMetadata: M,
305
- target: Object,
306
- member?: string | symbol,
307
- descriptorOrIndex?: TypedPropertyDescriptor<any> | number,
308
- ): M {
309
- // ...
310
- }
311
- ```
312
-
313
- 3. The default implemention throws errors if the same decorator function is applied
314
- to a given target member (class/method/property/parameter) more than once.
315
- For example, the following usage will report an error at runtime.
316
-
317
- ```ts
318
- @myClassDecorator({name: 'my-controller'})
319
- @myClassDecorator({name: 'your-controller'})
320
- class MyController {}
321
- ```
322
-
323
- ## Inspect metadata
350
+ ```ts
351
+ {
352
+ // Class level metadata
353
+ 'my-class-decorator-key': MyClassMetadata,
354
+ // Static method (including the constructor) parameter metadata
355
+ 'my-static-parameter-decorator-key': {
356
+ '': [MyConstructorParameterMetadata], // Constructor parameter metadata
357
+ 'myStaticMethod1': [MyStaticMethodParameterMetadata],
358
+ 'myStaticMethod2': [MyStaticMethodParameterMetadata],
359
+ },
360
+ // Static method metadata
361
+ 'my-static-method-decorator-key': {
362
+ 'myStaticMethod1': MyStaticMethodMetadata,
363
+ 'myStaticMethod2': MyStaticMethodMetadata,
364
+ },
365
+ // Static property metadata
366
+ 'my-static-property-decorator-key': {
367
+ 'myStaticMethod1': MyStaticPropertyMetadata,
368
+ 'myStaticMethod1': MyStaticPropertyMetadata,
369
+ }
370
+ }
371
+ ```
372
+
373
+ - MyClass.prototype
374
+
375
+ ```ts
376
+ {
377
+ // Instance method parameter metadata
378
+ 'my-instance-parameter-decorator-key': {
379
+ 'myMethod1': [MyMethodParameterMetadata],
380
+ 'myMethod2': [MyMethodParameterMetadata],
381
+ },
382
+ // Instance method metadata
383
+ 'my-instance-method-decorator-key': {
384
+ 'myMethod1': MyMethodMetadata,
385
+ 'myMethod2': MyMethodMetadata,
386
+ },
387
+ // Instance property metadata
388
+ 'my-instance-property-decorator-key': {
389
+ 'myProperty1': MyPropertyMetadata,
390
+ 'myProperty2': MyPropertyMetadata,
391
+ }
392
+ }
393
+ ```
394
+
395
+ The following methods in `DecoratorFactory` allow subclasses to customize how to
396
+ merge the `spec` with existing metadata for a class, methods, properties, and
397
+ method parameters. Please note `M` is a map for methods/properties/parameters.
398
+
399
+ ```ts
400
+ protected mergeWithInherited(
401
+ inheritedMetadata: M,
402
+ target: Object,
403
+ member?: string,
404
+ descriptorOrIndex?: TypedPropertyDescriptor<any> | number,
405
+ ): M {
406
+ // ...
407
+ }
408
+
409
+ protected mergeWithOwn(
410
+ ownMetadata: M,
411
+ target: Object,
412
+ member?: string,
413
+ descriptorOrIndex?: TypedPropertyDescriptor<any> | number,
414
+ ): M {
415
+ // ...
416
+ }
417
+ ```
418
+
419
+ 3. The default implementation throws errors if the same decorator function is
420
+ applied to a given target member (class/method/property/parameter) more than
421
+ once. For example, the following usage will report an error at runtime.
422
+
423
+ ```ts
424
+ @myClassDecorator({name: 'my-controller'})
425
+ @myClassDecorator({name: 'your-controller'})
426
+ class MyController {}
427
+ ```
428
+
429
+ ### Inspect metadata
324
430
 
325
431
  `MetadataInspector` provides API to inspect metadata from a class and its
326
432
  members.
327
433
 
328
- ## Inspect metadata of a class
434
+ ### Inspect metadata of a class
329
435
 
330
436
  ```ts
331
437
  import {MetadataInspector} from '@loopback/metadata';
@@ -336,7 +442,7 @@ const meta = MetadataInspector.getClassMetadata(
336
442
  );
337
443
  ```
338
444
 
339
- ## Inspect own metadata of a class
445
+ ### Inspect own metadata of a class
340
446
 
341
447
  ```ts
342
448
  import {MetadataInspector} from '@loopback/metadata';
@@ -350,7 +456,7 @@ const meta = MetadataInspector.getClassMetadata<MyClassMetaData>(
350
456
  );
351
457
  ```
352
458
 
353
- ## Inspect metadata of a method
459
+ ### Inspect metadata of a method
354
460
 
355
461
  ```ts
356
462
  import {MetadataInspector} from '@loopback/metadata';
@@ -367,7 +473,7 @@ const myMethod = MetadataInspector.getMethodMetaData<MyMethodMetadata>(
367
473
  );
368
474
  ```
369
475
 
370
- ## Inspect metadata of a property
476
+ ### Inspect metadata of a property
371
477
 
372
478
  ```ts
373
479
  import {MetadataInspector} from '@loopback/metadata';
@@ -384,7 +490,7 @@ const myProp = MetadataInspector.getMethodMetaData<MyMethodMetadata>(
384
490
  );
385
491
  ```
386
492
 
387
- ## Inspect metadata of method parameters
493
+ ### Inspect metadata of method parameters
388
494
 
389
495
  ```ts
390
496
  import {MetadataInspector} from '@loopback/metadata';
@@ -412,7 +518,26 @@ const allParamsForConstructor =
412
518
  );
413
519
  ```
414
520
 
415
- ## Inspect design-time metadata of properties/methods
521
+ ### Use strong-typed metadata access key
522
+
523
+ You can use MetadataAccessor to provide type checks for metadata access via
524
+ keys. For example,
525
+
526
+ ```ts
527
+ const CLASS_KEY = MetadataAccessor.create<MyClassMetadata, ClassDecorator>(
528
+ 'my-class-decorator-key',
529
+ );
530
+
531
+ // Create a class decorator with the key
532
+ const myClassDecorator = ClassDecoratorFactory.createDecorator(CLASS_KEY);
533
+
534
+ // Inspect a class with the key
535
+ const myClassMeta = MetadataInspector.getClassMetaData(CLASS_KEY, MyController);
536
+ ```
537
+
538
+ Please note MetadataKey can be an instance of MetadataAccessor or a string.
539
+
540
+ ### Inspect design-time metadata of properties/methods
416
541
 
417
542
  ```ts
418
543
  import {MetadataInspector} from '@loopback/metadata';
@@ -435,16 +560,14 @@ const myMethod = MetadataInspector.getDesignTypeForMethod(
435
560
 
436
561
  ## Installation
437
562
 
438
- ```
439
- $ npm install --save @loopback/metadata
563
+ ```sh
564
+ npm install --save @loopback/metadata
440
565
  ```
441
566
 
442
567
  ## Contributions
443
568
 
444
- IBM/StrongLoop is an active supporter of open source and welcomes contributions
445
- to our projects as well as those of the Node.js community in general. For more
446
- information on how to contribute please refer to the
447
- [Contribution Guide](https://loopback.io/doc/en/contrib/index.html).
569
+ - [Guidelines](https://github.com/loopbackio/loopback-next/blob/master/docs/CONTRIBUTING.md)
570
+ - [Join the team](https://github.com/loopbackio/loopback-next/issues/110)
448
571
 
449
572
  ## Tests
450
573
 
@@ -453,7 +576,7 @@ Run `npm test` from the root folder.
453
576
  ## Contributors
454
577
 
455
578
  See
456
- [all contributors](https://github.com/strongloop/loopback-next/graphs/contributors).
579
+ [all contributors](https://github.com/loopbackio/loopback-next/graphs/contributors).
457
580
 
458
581
  ## License
459
582