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

@loopback/context

Package Overview
Dependencies
Maintainers
19
Versions
196
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@loopback/context - npm Package Compare versions

Comparing version 4.0.0-alpha.6 to 4.0.0-alpha.7

31

lib/inject.d.ts
import 'reflect-metadata';
import { BoundValue } from './binding';
export interface Injection {
bindingKey: string;
metadata?: {
[attribute: string]: BoundValue;
};
}
/**

@@ -10,2 +17,4 @@ * A decorator to annotate method arguments for automatic injection

* class InfoController {
* @inject('authentication.user') public userName: string;
*
* constructor(@inject('application.name') public appName: string) {

@@ -21,6 +30,20 @@ * }

*
* @param bindingKey What binding to use in order to resolve the value
* of the annotated argument.
* @param bindingKey What binding to use in order to resolve the value of the
* decorated constructor parameter or property.
* @param metadata Optional metadata to help the injection
*
*/
export declare function inject(bindingKey: string): (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
export declare function describeInjectedArguments(target: Function): string[];
export declare function inject(bindingKey: string, metadata?: Object): (target: any, propertyKey?: string | symbol | undefined, propertyDescriptorOrParameterIndex?: number | TypedPropertyDescriptor<any> | undefined) => void;
/**
* Return an array of injection objects for constructor parameters
* @param target The target class
*/
export declare function describeInjectedArguments(target: Function): Injection[];
/**
* Return a map of injection objects for properties
* @param target The target class. Please note a property decorator function receives
* the target.prototype
*/
export declare function describeInjectedProperties(target: Function): {
[p: string]: Injection;
};

52

lib/inject.js

@@ -7,5 +7,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
require("reflect-metadata");
const REFLECTION_KEY = 'loopback.inject';
const REFLECTION_CDI_KEY = 'loopback:inject:constructor';
const REFLECTION_PDI_KEY = 'loopback:inject:properties';
/**

@@ -19,2 +19,4 @@ * A decorator to annotate method arguments for automatic injection

* class InfoController {
* @inject('authentication.user') public userName: string;
*
* constructor(@inject('application.name') public appName: string) {

@@ -30,17 +32,45 @@ * }

*
* @param bindingKey What binding to use in order to resolve the value
* of the annotated argument.
* @param bindingKey What binding to use in order to resolve the value of the
* decorated constructor parameter or property.
* @param metadata Optional metadata to help the injection
*
*/
function inject(bindingKey) {
return function markArgumentAsInjected(target, propertyKey, parameterIndex) {
assert(parameterIndex != undefined, '@inject decorator can be used on function arguments only!');
const injectedArgs = Reflect.getOwnMetadata(REFLECTION_KEY, target, propertyKey) || [];
injectedArgs[parameterIndex] = bindingKey;
Reflect.defineMetadata(REFLECTION_KEY, injectedArgs, target, propertyKey);
function inject(bindingKey, metadata) {
// tslint:disable-next-line:no-any
return function markArgumentAsInjected(target, propertyKey, propertyDescriptorOrParameterIndex) {
if (typeof propertyDescriptorOrParameterIndex === 'number') {
// The decorator is applied to a method parameter
// Please note propertyKey is `undefined` for constructor
const injectedArgs = Reflect.getOwnMetadata(REFLECTION_CDI_KEY, target, propertyKey) || [];
injectedArgs[propertyDescriptorOrParameterIndex] = { bindingKey, metadata };
Reflect.defineMetadata(REFLECTION_CDI_KEY, injectedArgs, target, propertyKey);
}
else if (propertyKey) {
// The decorator is applied to a property
const injections = Reflect.getOwnMetadata(REFLECTION_PDI_KEY, target) || {};
injections[propertyKey] = { bindingKey, metadata };
Reflect.defineMetadata(REFLECTION_PDI_KEY, injections, target);
}
else {
throw new Error('@inject can be used on properties or method parameters.');
}
};
}
exports.inject = inject;
/**
* Return an array of injection objects for constructor parameters
* @param target The target class
*/
function describeInjectedArguments(target) {
return Reflect.getOwnMetadata(REFLECTION_KEY, target) || [];
return Reflect.getOwnMetadata(REFLECTION_CDI_KEY, target) || [];
}
exports.describeInjectedArguments = describeInjectedArguments;
/**
* Return a map of injection objects for properties
* @param target The target class. Please note a property decorator function receives
* the target.prototype
*/
function describeInjectedProperties(target) {
return Reflect.getOwnMetadata(REFLECTION_PDI_KEY, target.prototype) || {};
}
exports.describeInjectedProperties = describeInjectedProperties;

@@ -27,1 +27,5 @@ import { Context } from './context';

export declare function resolveInjectedArguments(fn: Function, ctx: Context): BoundValue[] | Promise<BoundValue[]>;
export declare type KV = {
[p: string]: BoundValue;
};
export declare function resolveInjectedProperties(fn: Function, ctx: Context): KV | Promise<KV>;

@@ -21,8 +21,34 @@ "use strict";

const argsOrPromise = resolveInjectedArguments(ctor, ctx);
const propertiesOrPromise = resolveInjectedProperties(ctor, ctx);
let inst;
if (isPromise_1.isPromise(argsOrPromise)) {
return argsOrPromise.then(args => new ctor(...args));
// Instantiate the class asynchronously
inst = argsOrPromise.then(args => new ctor(...args));
}
else {
return new ctor(...argsOrPromise);
// Instantiate the class synchronously
inst = new ctor(...argsOrPromise);
}
if (isPromise_1.isPromise(propertiesOrPromise)) {
return propertiesOrPromise.then((props) => {
if (isPromise_1.isPromise(inst)) {
// Inject the properties asynchrounously
return inst.then(obj => Object.assign(obj, props));
}
else {
// Inject the properties synchrounously
return Object.assign(inst, props);
}
});
}
else {
if (isPromise_1.isPromise(inst)) {
// Inject the properties asynchrounously
return inst.then(obj => Object.assign(obj, propertiesOrPromise));
}
else {
// Inject the properties synchrounously
return Object.assign(inst, propertiesOrPromise);
}
}
}

@@ -50,3 +76,3 @@ exports.instantiateClass = instantiateClass;

for (let ix = 0; ix < fn.length; ix++) {
const bindingKey = injectedArgs[ix];
const bindingKey = injectedArgs[ix].bindingKey;
if (!bindingKey) {

@@ -75,1 +101,31 @@ throw new Error(`Cannot resolve injected arguments for function ${fn.name}: ` +

exports.resolveInjectedArguments = resolveInjectedArguments;
function resolveInjectedProperties(fn, ctx) {
const injectedProperties = inject_1.describeInjectedProperties(fn);
const properties = {};
let asyncResolvers = undefined;
const propertyResolver = (p) => ((v) => properties[p] = v);
for (const p in injectedProperties) {
const bindingKey = injectedProperties[p].bindingKey;
if (!bindingKey) {
throw new Error(`Cannot resolve injected property for class ${fn.name}: ` +
`The property ${p} was not decorated for dependency injection.`);
}
const binding = ctx.getBinding(bindingKey);
const valueOrPromise = binding.getValue(ctx);
if (isPromise_1.isPromise(valueOrPromise)) {
if (!asyncResolvers)
asyncResolvers = [];
asyncResolvers.push(valueOrPromise.then(propertyResolver(p)));
}
else {
properties[p] = valueOrPromise;
}
}
if (asyncResolvers) {
return Promise.all(asyncResolvers).then(() => properties);
}
else {
return properties;
}
}
exports.resolveInjectedProperties = resolveInjectedProperties;
import 'reflect-metadata';
import { BoundValue } from './binding';
export interface Injection {
bindingKey: string;
metadata?: {
[attribute: string]: BoundValue;
};
}
/**

@@ -10,2 +17,4 @@ * A decorator to annotate method arguments for automatic injection

* class InfoController {
* @inject('authentication.user') public userName: string;
*
* constructor(@inject('application.name') public appName: string) {

@@ -21,6 +30,20 @@ * }

*
* @param bindingKey What binding to use in order to resolve the value
* of the annotated argument.
* @param bindingKey What binding to use in order to resolve the value of the
* decorated constructor parameter or property.
* @param metadata Optional metadata to help the injection
*
*/
export declare function inject(bindingKey: string): (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
export declare function describeInjectedArguments(target: Function): string[];
export declare function inject(bindingKey: string, metadata?: Object): (target: any, propertyKey?: string | symbol | undefined, propertyDescriptorOrParameterIndex?: number | TypedPropertyDescriptor<any> | undefined) => void;
/**
* Return an array of injection objects for constructor parameters
* @param target The target class
*/
export declare function describeInjectedArguments(target: Function): Injection[];
/**
* Return a map of injection objects for properties
* @param target The target class. Please note a property decorator function receives
* the target.prototype
*/
export declare function describeInjectedProperties(target: Function): {
[p: string]: Injection;
};

@@ -7,5 +7,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
require("reflect-metadata");
const REFLECTION_KEY = 'loopback.inject';
const REFLECTION_CDI_KEY = 'loopback:inject:constructor';
const REFLECTION_PDI_KEY = 'loopback:inject:properties';
/**

@@ -19,2 +19,4 @@ * A decorator to annotate method arguments for automatic injection

* class InfoController {
* @inject('authentication.user') public userName: string;
*
* constructor(@inject('application.name') public appName: string) {

@@ -30,17 +32,45 @@ * }

*
* @param bindingKey What binding to use in order to resolve the value
* of the annotated argument.
* @param bindingKey What binding to use in order to resolve the value of the
* decorated constructor parameter or property.
* @param metadata Optional metadata to help the injection
*
*/
function inject(bindingKey) {
return function markArgumentAsInjected(target, propertyKey, parameterIndex) {
assert(parameterIndex != undefined, '@inject decorator can be used on function arguments only!');
const injectedArgs = Reflect.getOwnMetadata(REFLECTION_KEY, target, propertyKey) || [];
injectedArgs[parameterIndex] = bindingKey;
Reflect.defineMetadata(REFLECTION_KEY, injectedArgs, target, propertyKey);
function inject(bindingKey, metadata) {
// tslint:disable-next-line:no-any
return function markArgumentAsInjected(target, propertyKey, propertyDescriptorOrParameterIndex) {
if (typeof propertyDescriptorOrParameterIndex === 'number') {
// The decorator is applied to a method parameter
// Please note propertyKey is `undefined` for constructor
const injectedArgs = Reflect.getOwnMetadata(REFLECTION_CDI_KEY, target, propertyKey) || [];
injectedArgs[propertyDescriptorOrParameterIndex] = { bindingKey, metadata };
Reflect.defineMetadata(REFLECTION_CDI_KEY, injectedArgs, target, propertyKey);
}
else if (propertyKey) {
// The decorator is applied to a property
const injections = Reflect.getOwnMetadata(REFLECTION_PDI_KEY, target) || {};
injections[propertyKey] = { bindingKey, metadata };
Reflect.defineMetadata(REFLECTION_PDI_KEY, injections, target);
}
else {
throw new Error('@inject can be used on properties or method parameters.');
}
};
}
exports.inject = inject;
/**
* Return an array of injection objects for constructor parameters
* @param target The target class
*/
function describeInjectedArguments(target) {
return Reflect.getOwnMetadata(REFLECTION_KEY, target) || [];
return Reflect.getOwnMetadata(REFLECTION_CDI_KEY, target) || [];
}
exports.describeInjectedArguments = describeInjectedArguments;
/**
* Return a map of injection objects for properties
* @param target The target class. Please note a property decorator function receives
* the target.prototype
*/
function describeInjectedProperties(target) {
return Reflect.getOwnMetadata(REFLECTION_PDI_KEY, target.prototype) || {};
}
exports.describeInjectedProperties = describeInjectedProperties;

@@ -27,1 +27,5 @@ import { Context } from './context';

export declare function resolveInjectedArguments(fn: Function, ctx: Context): BoundValue[] | Promise<BoundValue[]>;
export declare type KV = {
[p: string]: BoundValue;
};
export declare function resolveInjectedProperties(fn: Function, ctx: Context): KV | Promise<KV>;

@@ -21,8 +21,34 @@ "use strict";

const argsOrPromise = resolveInjectedArguments(ctor, ctx);
const propertiesOrPromise = resolveInjectedProperties(ctor, ctx);
let inst;
if (isPromise_1.isPromise(argsOrPromise)) {
return argsOrPromise.then(args => new ctor(...args));
// Instantiate the class asynchronously
inst = argsOrPromise.then(args => new ctor(...args));
}
else {
return new ctor(...argsOrPromise);
// Instantiate the class synchronously
inst = new ctor(...argsOrPromise);
}
if (isPromise_1.isPromise(propertiesOrPromise)) {
return propertiesOrPromise.then((props) => {
if (isPromise_1.isPromise(inst)) {
// Inject the properties asynchrounously
return inst.then(obj => Object.assign(obj, props));
}
else {
// Inject the properties synchrounously
return Object.assign(inst, props);
}
});
}
else {
if (isPromise_1.isPromise(inst)) {
// Inject the properties asynchrounously
return inst.then(obj => Object.assign(obj, propertiesOrPromise));
}
else {
// Inject the properties synchrounously
return Object.assign(inst, propertiesOrPromise);
}
}
}

@@ -50,3 +76,3 @@ exports.instantiateClass = instantiateClass;

for (let ix = 0; ix < fn.length; ix++) {
const bindingKey = injectedArgs[ix];
const bindingKey = injectedArgs[ix].bindingKey;
if (!bindingKey) {

@@ -75,1 +101,31 @@ throw new Error(`Cannot resolve injected arguments for function ${fn.name}: ` +

exports.resolveInjectedArguments = resolveInjectedArguments;
function resolveInjectedProperties(fn, ctx) {
const injectedProperties = inject_1.describeInjectedProperties(fn);
const properties = {};
let asyncResolvers = undefined;
const propertyResolver = (p) => ((v) => properties[p] = v);
for (const p in injectedProperties) {
const bindingKey = injectedProperties[p].bindingKey;
if (!bindingKey) {
throw new Error(`Cannot resolve injected property for class ${fn.name}: ` +
`The property ${p} was not decorated for dependency injection.`);
}
const binding = ctx.getBinding(bindingKey);
const valueOrPromise = binding.getValue(ctx);
if (isPromise_1.isPromise(valueOrPromise)) {
if (!asyncResolvers)
asyncResolvers = [];
asyncResolvers.push(valueOrPromise.then(propertyResolver(p)));
}
else {
properties[p] = valueOrPromise;
}
}
if (asyncResolvers) {
return Promise.all(asyncResolvers).then(() => properties);
}
else {
return properties;
}
}
exports.resolveInjectedProperties = resolveInjectedProperties;
{
"name": "@loopback/context",
"version": "4.0.0-alpha.6",
"version": "4.0.0-alpha.7",
"description": "LoopBack's container for Inversion of Control",
"main": "index",
"scripts": {
"acceptance": "mocha --opts ../../test/mocha.opts 'test/acceptance/**/*.ts'",
"build": "npm run build:lib && npm run build:lib6",
"build:lib": "tsc --target es2017 --outDir lib",
"build:lib6": "tsc --target es2015 --outDir lib6",
"build:lib": "tsc -p tsconfig.build.json --target es2017 --outDir lib",
"build:lib6": "tsc -p tsconfig.build.json --target es2015 --outDir lib6",
"clean": "rm -f loopback-context*.tgz && rm -rf lib* && rm -rf package",

@@ -25,3 +24,3 @@ "prepublish": "npm run build",

"devDependencies": {
"@loopback/testlab": "^4.0.0-alpha.3",
"@loopback/testlab": "^4.0.0-alpha.4",
"@types/bluebird": "^3.5.2",

@@ -28,0 +27,0 @@ "bluebird": "^3.5.0",

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