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

@travetto/di

Package Overview
Dependencies
Maintainers
1
Versions
313
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@travetto/di - npm Package Compare versions

Comparing version 0.0.6 to 0.0.7

test/deps.ts

2

package.json

@@ -22,3 +22,3 @@ {

},
"version": "0.0.6"
"version": "0.0.7"
}

@@ -16,3 +16,3 @@ import { InjectableConfig, Dependency } from '../types';

export type InjectConfig = { name?: string, optional?: boolean };
export type InjectConfig = { qualifier?: symbol, optional?: boolean };

@@ -26,5 +26,8 @@ export function InjectArgs(configs?: InjectConfig[]): ClassDecorator {

export function Inject(config?: InjectConfig): PropertyDecorator {
return (target: any, propertyKey: string) => {
DependencyRegistry.registerProperty(target.constructor, propertyKey, config as any as Dependency);
return (target: any, propertyKey: string | symbol) => {
DependencyRegistry.registerProperty(
target.constructor,
propertyKey as string,
config as any as Dependency);
};
}

@@ -7,3 +7,3 @@ import { Dependency, InjectableConfig, ClassTarget } from '../types';

export const DEFAULT_INSTANCE = '__default';
export const DEFAULT_INSTANCE = Symbol('__default');

@@ -17,13 +17,17 @@ export interface ManagedExtra {

function getName(symbol: symbol) {
return symbol.toString().split(/[()]/g)[1];
}
export class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
private pendingFinalize: Class[] = [];
private instances = new Map<TargetId, Map<string, any>>();
private instancePromises = new Map<TargetId, Map<string, Promise<any>>>();
private instances = new Map<TargetId, Map<Symbol, any>>();
private instancePromises = new Map<TargetId, Map<Symbol, Promise<any>>>();
private aliases = new Map<TargetId, Map<string, string>>();
private targets = new Map<ClassId, Map<string, TargetId>>();
private aliases = new Map<TargetId, Map<Symbol, string>>();
private targets = new Map<ClassId, Map<Symbol, TargetId>>();
private proxies = new Map<TargetId, Map<string, Proxy<RetargettingHandler<any>>>>();
private proxyHandlers = new Map<TargetId, Map<string, RetargettingHandler<any>>>();
private proxies = new Map<TargetId, Map<Symbol, Proxy<RetargettingHandler<any>>>>();
private proxyHandlers = new Map<TargetId, Map<Symbol, RetargettingHandler<any>>>();

@@ -37,6 +41,6 @@ private autoCreate: (Dependency<any> & { priority: number })[] = [];

async initialInstall() {
let finalizing = this.pendingFinalize;
const finalizing = this.pendingFinalize;
this.pendingFinalize = [];
for (let cls of finalizing) {
for (const cls of finalizing) {
this.install(cls, { type: 'added', curr: cls });

@@ -48,5 +52,5 @@ }

console.debug('Auto-creating', this.autoCreate.map(x => x.target.name));
let items = this.autoCreate.slice(0).sort((a, b) => a.priority - b.priority);
for (let i of items) {
await this.getInstance(i.target, i.name);
const items = this.autoCreate.slice(0).sort((a, b) => a.priority - b.priority);
for (const i of items) {
await this.getInstance(i.target, i.qualifier);
}

@@ -62,3 +66,3 @@ }

return {
name: DEFAULT_INSTANCE,
qualifier: DEFAULT_INSTANCE,
class: cls,

@@ -77,18 +81,18 @@ target: cls,

async construct<T>(target: ClassTarget<T & ManagedExtra>, name: string = DEFAULT_INSTANCE): Promise<T> {
let targetId = target.__id;
async construct<T>(target: ClassTarget<T & ManagedExtra>, qualifier: symbol = DEFAULT_INSTANCE): Promise<T> {
const targetId = target.__id;
let aliasMap = this.aliases.get(targetId);
const aliasMap = this.aliases.get(targetId);
if (!aliasMap || !aliasMap.has(name)) {
throw new InjectionError(`Dependency not found: ${targetId}[${name}]`);
if (!aliasMap || !aliasMap.has(qualifier)) {
throw new InjectionError(`Dependency not found: ${targetId}[${getName(qualifier)}]`);
}
let clz = aliasMap.get(name)!;
let managed = this.get(clz)!;
const clz = aliasMap.get(qualifier)!;
const managed = this.get(clz)!;
const fieldKeys = Object.keys(managed.dependencies.fields!);
let consDeps = managed.dependencies.cons || [];
let allDeps = consDeps.concat(fieldKeys.map(x => managed.dependencies.fields[x]))
const consDeps = managed.dependencies.cons || [];
const allDeps = consDeps.concat(fieldKeys.map(x => managed.dependencies.fields[x]))

@@ -98,3 +102,3 @@ const promises = allDeps

try {
return await this.getInstance(x.target, x.name);
return await this.getInstance(x.target, x.qualifier);
} catch (e) {

@@ -126,4 +130,4 @@ if (x.optional && e instanceof InjectionError) {

private async createInstance<T>(target: ClassTarget<T>, name: string = DEFAULT_INSTANCE) {
let targetId = target.__id;
private async createInstance<T>(target: ClassTarget<T>, qualifier: symbol = DEFAULT_INSTANCE) {
const targetId = target.__id;

@@ -135,10 +139,10 @@ if (!this.instances.has(targetId)) {

if (this.instancePromises.get(targetId)!.has(name)) {
return this.instancePromises.get(targetId)!.get(name);
if (this.instancePromises.get(targetId)!.has(qualifier)) {
return this.instancePromises.get(targetId)!.get(qualifier);
}
let instancePromise = this.construct(target, name);
this.instancePromises.get(targetId)!.set(name, instancePromise);
const instancePromise = this.construct(target, qualifier);
this.instancePromises.get(targetId)!.set(qualifier, instancePromise);
let instance = await instancePromise;
const instance = await instancePromise;

@@ -154,37 +158,39 @@ if (AppEnv.watch) {

console.debug('Creating Instance', targetId, AppEnv.watch, !this.proxyHandlers.has(targetId), this.proxyHandlers.has(targetId) && !this.proxyHandlers.get(targetId)!.has(name))
console.debug('Creating Instance', targetId, AppEnv.watch,
!this.proxyHandlers.has(targetId),
this.proxyHandlers.has(targetId) && !this.proxyHandlers.get(targetId)!.has(qualifier))
// if in watch mode, create proxies
if (AppEnv.watch) {
if (!this.proxies.get(targetId)!.has(name)) {
let handler = new RetargettingHandler(out);
let proxy = new Proxy({}, handler);
this.proxyHandlers.get(targetId)!.set(name, handler);
this.proxies.get(targetId)!.set(name, proxy);
if (!this.proxies.get(targetId)!.has(qualifier)) {
const handler = new RetargettingHandler(out);
const proxy = new Proxy({}, handler);
this.proxyHandlers.get(targetId)!.set(qualifier, handler);
this.proxies.get(targetId)!.set(qualifier, proxy);
out = proxy;
console.debug('Registering proxy', target.__id, name);
console.debug('Registering proxy', target.__id, qualifier);
} else {
let handler = this.proxyHandlers.get(targetId)!.get(name)!;
console.debug('Updating target', target.__id, name, out);
const handler = this.proxyHandlers.get(targetId)!.get(qualifier)!;
console.debug('Updating target', target.__id, qualifier, out);
handler.target = out;
out = this.proxies.get(targetId)!.get(name);
out = this.proxies.get(targetId)!.get(qualifier);
}
}
this.instances.get(targetId)!.set(name, out);
this.instances.get(targetId)!.set(qualifier, out);
}
async getInstance<T>(target: ClassTarget<T>, name: string = DEFAULT_INSTANCE): Promise<T> {
let targetId = target.__id;
if (!this.instances.has(targetId) || !this.instances.get(targetId)!.has(name)) {
console.debug('Getting Intance', targetId, name);
await this.createInstance(target, name);
async getInstance<T>(target: ClassTarget<T>, qualifier: symbol = DEFAULT_INSTANCE): Promise<T> {
const targetId = target.__id;
if (!this.instances.has(targetId) || !this.instances.get(targetId)!.has(qualifier)) {
console.debug('Getting Intance', targetId, getName(qualifier));
await this.createInstance(target, qualifier);
}
return this.instances.get(targetId)!.get(name)!;
return this.instances.get(targetId)!.get(qualifier)!;
}
getCandidateTypes<T>(target: Class<T>) {
let targetId = target.__id;
let aliasMap = this.aliases.get(targetId)!;
let aliasedIds = aliasMap ? Array.from(aliasMap.values()) : [];
const targetId = target.__id;
const aliasMap = this.aliases.get(targetId)!;
const aliasedIds = aliasMap ? Array.from(aliasMap.values()) : [];
return aliasedIds.map(id => this.get(id)!)

@@ -195,7 +201,7 @@ }

registerConstructor<T>(cls: Class<T>, dependencies?: Dependency<any>[]) {
let conf = this.getOrCreatePending(cls);
const conf = this.getOrCreatePending(cls);
conf.dependencies!.cons = dependencies;
if (dependencies) {
for (let dependency of dependencies) {
dependency.name = dependency.name || DEFAULT_INSTANCE;
for (const dependency of dependencies) {
dependency.qualifier = dependency.qualifier || DEFAULT_INSTANCE;
}

@@ -206,13 +212,13 @@ }

registerProperty<T>(cls: Class<T>, field: string, dependency: Dependency<any>) {
let conf = this.getOrCreatePending(cls);
const conf = this.getOrCreatePending(cls);
conf.dependencies!.fields[field] = dependency;
dependency.name = dependency.name || DEFAULT_INSTANCE;
dependency.qualifier = dependency.qualifier || DEFAULT_INSTANCE;
}
registerClass<T>(cls: Class<T>, pconfig: Partial<InjectableConfig<T>>) {
let classId = pconfig.class!.__id;
let config = this.getOrCreatePending(pconfig.class!);
const classId = pconfig.class!.__id;
const config = this.getOrCreatePending(pconfig.class!);
if (pconfig.name) {
config.name = pconfig.name;
if (pconfig.qualifier) {
config.qualifier = pconfig.qualifier;
}

@@ -231,10 +237,10 @@ if (pconfig.target) {

onInstallFinalize<T>(cls: Class<T>) {
let classId = cls.__id;
const classId = cls.__id;
console.debug('Finalized', classId);
let config = this.getOrCreatePending(cls) as InjectableConfig<T>;
const config = this.getOrCreatePending(cls) as InjectableConfig<T>;
let parentClass = Object.getPrototypeOf(cls);
let parentConfig = this.get(parentClass.__id);
const parentClass = Object.getPrototypeOf(cls);
const parentConfig = this.get(parentClass.__id);

@@ -256,3 +262,3 @@ if (parentConfig) {

let targetId = config.target.__id;
const targetId = config.target.__id;

@@ -263,10 +269,10 @@ if (!this.aliases.has(targetId)) {

this.aliases.get(targetId)!.set(config.name, classId);
this.targets.get(classId)!.set(config.name, targetId);
this.aliases.get(targetId)!.set(config.qualifier, classId);
this.targets.get(classId)!.set(config.qualifier, targetId);
// TODO: Auto alias parent class if framework managed
if (parentClass.__id && config.name !== DEFAULT_INSTANCE) {
let parentId = parentClass.__id;
this.aliases.get(parentId)!.set(config.name, classId);
this.targets.get(classId)!.set(config.name, parentId);
if (parentClass.__id && config.qualifier !== DEFAULT_INSTANCE) {
const parentId = parentClass.__id;
this.aliases.get(parentId)!.set(config.qualifier, classId);
this.targets.get(classId)!.set(config.qualifier, parentId);
}

@@ -277,7 +283,7 @@

this.proxies.has(targetId) &&
this.proxies.get(targetId)!.has(config.name)
this.proxies.get(targetId)!.has(config.qualifier)
) {
console.debug('Reloading on next tick');
// Timing matters b/c of create instance
process.nextTick(() => this.createInstance(config.target, config.name));
process.nextTick(() => this.createInstance(config.target, config.qualifier));
} else if (config.autoCreate.create) {

@@ -287,3 +293,3 @@ // If not loaded, and autocreate

target: config.target,
name: config.name,
qualifier: config.qualifier,
priority: config.autoCreate.priority!

@@ -302,3 +308,3 @@ })

// Remove current instance
for (let [config, targetId] of this.targets.get(cls.__id)!.entries()) {
for (const [config, targetId] of this.targets.get(cls.__id)!.entries()) {
if (this.instances.has(targetId) &&

@@ -308,3 +314,3 @@ this.instances.get(targetId)!.has(config) &&

) {
let handler = this.proxyHandlers.get(targetId)!.get(config)
const handler = this.proxyHandlers.get(targetId)!.get(config)
if (handler) {

@@ -311,0 +317,0 @@ handler.target = null;

@@ -17,7 +17,7 @@ import * as ts from 'typescript';

function processDeclaration(state: State, param: ts.ParameterDeclaration | ts.PropertyDeclaration) {
let injection = TransformUtil.findAnyDecorator(param, { Inject: new Set(['@travetto/di']) }, state);
const injection = TransformUtil.findAnyDecorator(param, { Inject: new Set(['@travetto/di']) }, state);
if (injection || ts.isParameter(param)) {
let finalTarget = TransformUtil.importIfExternal(param.type!, state);
let injectConfig = TransformUtil.getPrimaryArgument<ts.ObjectLiteralExpression>(injection);
const finalTarget = TransformUtil.importIfExternal(param.type!, state);
const injectConfig = TransformUtil.getPrimaryArgument<ts.ObjectLiteralExpression>(injection);

@@ -47,3 +47,3 @@ let optional = TransformUtil.getObjectValue(injectConfig, 'optional');

}
let ident = ts.createIdentifier(name);
const ident = ts.createIdentifier(name);
state.decorators[name] = ts.createPropertyAccess(state.import, ident);

@@ -62,3 +62,3 @@ }

if (ts.isClassDeclaration(node)) {
let foundDec = TransformUtil.findAnyDecorator(node, INJECTABLES, state);
const foundDec = TransformUtil.findAnyDecorator(node, INJECTABLES, state);
let decls = node.decorators;

@@ -70,4 +70,4 @@

let declTemp = (node.decorators || []).slice(0);
let cons = (node as any as ts.ClassDeclaration).members.find(x => ts.isConstructorDeclaration(x)) as ts.ConstructorDeclaration;
const declTemp = (node.decorators || []).slice(0);
const cons = (node as any as ts.ClassDeclaration).members.find(x => ts.isConstructorDeclaration(x)) as ts.ConstructorDeclaration;
let injectArgs = undefined;

@@ -98,4 +98,4 @@

let cNode = node as any as ts.ClassDeclaration;
let out = ts.updateClassDeclaration(cNode,
const cNode = node as any as ts.ClassDeclaration;
const out = ts.updateClassDeclaration(cNode,
decls,

@@ -111,11 +111,11 @@ cNode.modifiers,

} if (ts.isPropertyDeclaration(node)) {
let expr = processDeclaration(state, node);
const expr = processDeclaration(state, node);
if (expr) {
let final = createInjectDecorator(state, 'Inject', expr);
let finalDecs = ((node.decorators as any as ts.Decorator[]) || [])
const final = createInjectDecorator(state, 'Inject', expr);
const finalDecs = ((node.decorators as any as ts.Decorator[]) || [])
.filter(x => TransformUtil.getDecoratorIdent(x).text !== 'Inject');
// Doing decls
let ret = ts.updateProperty(
const ret = ts.updateProperty(
node,

@@ -122,0 +122,0 @@ ts.createNodeArray([final, ...finalDecs]),

@@ -16,4 +16,4 @@ import { Class } from '@travetto/registry';

target: ClassTarget<T>;
name: string;
qualifier: symbol;
optional?: boolean;
}

@@ -1,46 +0,10 @@

import { Injectable, Inject } from '../src/decorator/injectable';
import { DbConfig, AltConfig } from './config';
import { DependencyRegistry } from '../src/service';
import { ServiceInherit, SERVICE_INHERIT_2 } from './deps';
import { Suite, Test } from '@travetto/test';
import * as assert from 'assert';
@Injectable()
class Database {
@Inject() dbConfig: DbConfig<any, any>;
@Inject({ optional: true }) altConfig: AltConfig;
postConstruct() {
console.log('Creating database', this.dbConfig.getUrl());
}
query() {
console.log('Getting 350', this.dbConfig.getUrl());
}
}
@Injectable()
class Service {
constructor(public db: Database) {
console.log('Creating service', db);
}
doWork() {
this.db.query();
}
}
@Injectable()
class ServiceInherit extends Service {
name = 'bob';
age = 30;
doWork() {
this.db.query();
}
}
const FOUR = 4;
function doWork() {
//throw new Error('ahhh');
// throw new Error('ahhh');
}

@@ -60,2 +24,7 @@

inst = await DependencyRegistry.getInstance(ServiceInherit, SERVICE_INHERIT_2);
inst.doWork();
assert.ok(inst.db);
assert(inst.age === 31);
assert.equal(inst.db.altConfig, undefined);

@@ -67,2 +36,3 @@ assert(inst.db.dbConfig.getUrl() === 'mongodb://oscar');

async runner() {
assert(1 === 1);

@@ -78,2 +48,3 @@ assert(2 + 2 === FOUR);

@Test('run')

@@ -83,3 +54,5 @@ async run() {

await DependencyRegistry.init();
let inst = await DependencyRegistry.getInstance(ServiceInherit);
assert(30 === 30);
const inst = await DependencyRegistry.getInstance(ServiceInherit);
inst.doWork();

@@ -90,4 +63,4 @@

assert.equal(inst.db.altConfig, undefined);
assert.equal(inst.db.altConfig, undefined);
assert(inst.db.dbConfig.getUrl() === 'mongodb://oscar');

@@ -99,4 +72,6 @@ }

assert(1 === 1);
console.log('hi')
assert(2 + 2 === FOUR);
}
}
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