Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@loopback/metadata

Package Overview
Dependencies
Maintainers
7
Versions
167
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@loopback/metadata - npm Package Compare versions

Comparing version 1.3.10 to 1.4.0

18

CHANGELOG.md

@@ -6,2 +6,20 @@ # Change Log

# [1.4.0](https://github.com/strongloop/loopback-next/compare/@loopback/metadata@1.3.10...@loopback/metadata@1.4.0) (2020-01-27)
### Bug Fixes
* clarify the decorator application order ([ab0dc3d](https://github.com/strongloop/loopback-next/commit/ab0dc3d9f1dedb6b61ccf5b4d63854a4f9dfa814))
* ensure tests follow parameter patterns ([d9d8154](https://github.com/strongloop/loopback-next/commit/d9d815403b8b7c39aa71494f46b352c646324673))
* makes multi-decorator behavior more predictable ([0e00068](https://github.com/strongloop/loopback-next/commit/0e00068ccee12e004a2684afcf8bec5d651a9a20))
### Features
* adds MultiMethodDecoratorFactory ([bf6c787](https://github.com/strongloop/loopback-next/commit/bf6c7872bb8ce492b43ab8f57a641dcbb341e96e))
## [1.3.10](https://github.com/strongloop/loopback-next/compare/@loopback/metadata@1.3.9...@loopback/metadata@1.3.10) (2020-01-07)

@@ -8,0 +26,0 @@

@@ -263,1 +263,30 @@ import { DecoratorType, MetadataKey, MetadataMap } from './types';

}
/**
* Factory for an append-array of method-level decorators
* The @response metadata for a method is an array.
* Each item in the array should be a single value, containing
* a response code and a single spec or Model. This should allow:
* ```ts
* @response(200, MyFirstModel)
* @response(403, [NotAuthorizedReasonOne, NotAuthorizedReasonTwo])
* @response(404, NotFoundOne)
* @response(404, NotFoundTwo)
* @response(409, {schema: {}})
* public async myMethod() {}
* ```
*
* In the case that a ResponseObject is passed, it becomes the
* default for description/content, and if possible, further Models are
* incorporated as a `oneOf: []` array.
*
* In the case that a ReferenceObject is passed, it and it alone is used, since
* references can be external and we cannot `oneOf` their content.
*
* The factory creates and updates an array of items T[], and the getter
* provides the values as that array.
*/
export declare class MethodMultiDecoratorFactory<T> extends MethodDecoratorFactory<T[]> {
protected mergeWithInherited(inheritedMetadata: MetadataMap<T[]>, target: Object, methodName?: string): MetadataMap<T[]>;
protected mergeWithOwn(ownMetadata: MetadataMap<T[]>, target: Object, methodName?: string, methodDescriptor?: TypedPropertyDescriptor<any> | number): MetadataMap<T[]>;
private _mergeArray;
}

@@ -513,2 +513,58 @@ "use strict";

exports.MethodParameterDecoratorFactory = MethodParameterDecoratorFactory;
/**
* Factory for an append-array of method-level decorators
* The @response metadata for a method is an array.
* Each item in the array should be a single value, containing
* a response code and a single spec or Model. This should allow:
* ```ts
* @response(200, MyFirstModel)
* @response(403, [NotAuthorizedReasonOne, NotAuthorizedReasonTwo])
* @response(404, NotFoundOne)
* @response(404, NotFoundTwo)
* @response(409, {schema: {}})
* public async myMethod() {}
* ```
*
* In the case that a ResponseObject is passed, it becomes the
* default for description/content, and if possible, further Models are
* incorporated as a `oneOf: []` array.
*
* In the case that a ReferenceObject is passed, it and it alone is used, since
* references can be external and we cannot `oneOf` their content.
*
* The factory creates and updates an array of items T[], and the getter
* provides the values as that array.
*/
class MethodMultiDecoratorFactory extends MethodDecoratorFactory {
mergeWithInherited(inheritedMetadata, target, methodName) {
inheritedMetadata = inheritedMetadata || {};
inheritedMetadata[methodName] = this._mergeArray(inheritedMetadata[methodName], this.withTarget(this.spec, target));
return inheritedMetadata;
}
mergeWithOwn(ownMetadata, target, methodName, methodDescriptor) {
ownMetadata = ownMetadata || {};
ownMetadata[methodName] = this._mergeArray(ownMetadata[methodName], this.withTarget(this.spec, target));
return ownMetadata;
}
_mergeArray(result, methodMeta) {
if (!result) {
if (Array.isArray(methodMeta)) {
result = methodMeta;
}
else {
result = [methodMeta];
}
}
else {
if (Array.isArray(methodMeta)) {
result.push(...methodMeta);
}
else {
result.push(methodMeta);
}
}
return result;
}
}
exports.MethodMultiDecoratorFactory = MethodMultiDecoratorFactory;
//# sourceMappingURL=decorator-factory.js.map

10

package.json
{
"name": "@loopback/metadata",
"version": "1.3.10",
"version": "1.4.0",
"description": "LoopBack's metadata utilities for reflection and decoration",

@@ -26,5 +26,5 @@ "engines": {

"devDependencies": {
"@loopback/build": "^3.0.1",
"@loopback/eslint-config": "^5.0.1",
"@loopback/testlab": "^1.10.1",
"@loopback/build": "^3.1.0",
"@loopback/eslint-config": "^5.0.2",
"@loopback/testlab": "^1.10.2",
"@types/debug": "^4.1.5",

@@ -55,3 +55,3 @@ "@types/lodash": "^4.14.149",

},
"gitHead": "598baf6e84de3917bb67aff47a1ab1cb1111e3d2"
"gitHead": "d08f135a0d1040edc61497739a8d86a866e4e29a"
}

@@ -90,2 +90,110 @@ # @loopback/metadata

### To create a decorator that can be used multiple times on a single method
Instead of a single immutable object to be merged, the
`MethodMultiDecoratorFactory` reduced parameters into a flat array of items.
When fetching the metadata later, you will receive it as an array.
```ts
import {MethodMultiDecoratorFactory} from '@loopback/metadata';
function myMultiMethodDecorator(spec: object): MethodDecorator {
return MethodMultiDecoratorFactory.createDecorator<object>(
'metadata-key-for-my-method-multi-decorator',
spec,
);
}
```
Now, you can use it multiple times on a method:
```ts
class MyController {
@myMultiMethodDecorator({x: 1})
@myMultiMethodDecorator({y: 2})
@myMultiMethodDecorator({z: 3})
public point() {}
}
class MyOtherController {
@myMultiMethodDecorator([{x: 1}, {y: 2}, {z: 3}])
public point() {}
}
```
And when you access this data:
```ts
const arrayOfSpecs = MetadataInspector.getMethodMetadata<object>(
'metadata-key-for-my-method-multi-decorator',
constructor.prototype,
op,
);
// [{z: 3}, {y: 2}, {x: 1}]
```
Typescript
[applies decorators in reverse order](https://www.typescriptlang.org/docs/handbook/decorators.html)
per class, from the parent down. The metadata array resurned by `getOwnMetadata`
will be in this order:
```ts
class Parent {
@myMultiMethodDecorator('A') // second
@myMultiMethodDecorator('B') // first
public greet() {}
}
class Child extends Parent {
@myMultiMethodDecorator(['C', 'D']) // [third, fourth]
public greet() {}
}
class Grandchild extends Child {
@myMultiMethodDecorator('E') // sixth
@myMultiMethodDecorator('F') // fifth
public greet() {}
}
// getMethodMetadata = ['B', 'A', 'C', 'D', 'F', 'E']
```
You can also create a decorator that takes an object that can contain an array:
```ts
interface Point {
x?: number;
y?: number;
z?: number;
}
interface GeometryMetadata {
points: Point[];
}
function geometry(...points: Point[]): MethodDecorator {
return MethodMultiDecoratorFactory.createDecorator<GeometryMetadata>(
'metadata-key-for-my-method-multi-decorator',
points,
);
}
class MyGeoController {
@geometry({x: 1})
@geometry({x: 2}, {y: 3})
@geometry({z: 5})
public abstract() {}
}
const arrayOfSpecs = MetadataInspector.getMethodMetadata<GeometryMetadata>(
'metadata-key-for-my-method-multi-decorator',
constructor.prototype,
op,
);
// [
// { points: [{x: 1}]},
// { points: [{x:2}, {y:3}]},
// { points: [{z: 5}]},
// ]
```
### To create a property decorator

@@ -92,0 +200,0 @@

@@ -792,1 +792,76 @@ // Copyright IBM Corp. 2017,2019. All Rights Reserved.

}
/**
* Factory for an append-array of method-level decorators
* The @response metadata for a method is an array.
* Each item in the array should be a single value, containing
* a response code and a single spec or Model. This should allow:
* ```ts
* @response(200, MyFirstModel)
* @response(403, [NotAuthorizedReasonOne, NotAuthorizedReasonTwo])
* @response(404, NotFoundOne)
* @response(404, NotFoundTwo)
* @response(409, {schema: {}})
* public async myMethod() {}
* ```
*
* In the case that a ResponseObject is passed, it becomes the
* default for description/content, and if possible, further Models are
* incorporated as a `oneOf: []` array.
*
* In the case that a ReferenceObject is passed, it and it alone is used, since
* references can be external and we cannot `oneOf` their content.
*
* The factory creates and updates an array of items T[], and the getter
* provides the values as that array.
*/
export class MethodMultiDecoratorFactory<T> extends MethodDecoratorFactory<
T[]
> {
protected mergeWithInherited(
inheritedMetadata: MetadataMap<T[]>,
target: Object,
methodName?: string,
) {
inheritedMetadata = inheritedMetadata || {};
inheritedMetadata[methodName!] = this._mergeArray(
inheritedMetadata[methodName!],
this.withTarget(this.spec, target),
);
return inheritedMetadata;
}
protected mergeWithOwn(
ownMetadata: MetadataMap<T[]>,
target: Object,
methodName?: string,
methodDescriptor?: TypedPropertyDescriptor<any> | number,
) {
ownMetadata = ownMetadata || {};
ownMetadata[methodName!] = this._mergeArray(
ownMetadata[methodName!],
this.withTarget(this.spec, target),
);
return ownMetadata;
}
private _mergeArray(result: T[], methodMeta: T | T[]) {
if (!result) {
if (Array.isArray(methodMeta)) {
result = methodMeta;
} else {
result = [methodMeta];
}
} else {
if (Array.isArray(methodMeta)) {
result.push(...methodMeta);
} else {
result.push(methodMeta);
}
}
return result;
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc