Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Jpex is an Inversion of Control framework.
npm install jpex
import jpex from 'jpex';
import { IFoo, IBah } from './types';
jpex.factory<IFoo>((bah: IBah) => bah.baz);
const foo = jpex.resolve<IFoo>();
Services and factories are small modules or functions that provide a reusable or common piece of functionality. In Jpex, you can register factories:
jpex.factory('myFactory', () => {
return {};
});
services:
jpex.service('myService', function(){
this.method = function(){
...
};
});
and constants:
jpex.constant('myConstant', 'foo');
If you're using typescript you can use type inference to automatically register factories:
jpex.factory<MyFactory>(() => {
return {};
});
jpex.service<IMyService>(class MyService implements IMyService {
method() {}
});
type MyConstant = string;
jpex.constant<MyConstant>('foo');
const myFactory = jpex.resolve('myFactory');
You can also request a dependency from within another factory:
jpex.constant('myConstant', 'foo');
jpex.factory('myFactory', (myConstant) => {
return {
injectedValue : myConstant
};
});
jpex.service('myService', function(myFactory){
this.method = function(){
return myFactory.injectedValue;
};
});
jpex.resolve('myService').method(); // returns 'foo'!
Again, with typescript you can use types to automatically pull in your dependencies:
jpex.factory<MyFactory>((myConstant: MyConstant) => {
return {
injectedValue: myConstant,
};
});
jpex.service<MyService>(function(myFactory: MyFactory) {
this.method = function(){
return myFactory.injectedValue;
};
});
jpex.resolve<MyService>().method();
In order to use the inferred typescript functionality, you need to run your code through babel using the plugin in this package. You can import it from jpex/babel-plugin
plugins: [ 'jpex/babel-plugin' ]
By default it only checks for an object named jpex
. If you decide to rename it to anything else, or have multiple containers, you can pass an identifier option in.
By default the types are converted to strings based on the path where they originate from i.e. type:/src/types/index/MyType
. You can optionally pass in a publicPath
which will override this behaviour, instead returning type:myPublicPath/MyType
. This is useful if you want to expose factories via an npm package, for example.
plugins: [
[
'jpex/babel-plugin',
{
identifier: [ 'jpex', 'ioc' ],
publicPath: 'my-library'
}
]
]
You can also set this to true
which will automatically use your library's name
property from its package.json
as the public path.
There are a number of caveats to this method, however:
jpex.factory<{}>()
interface Bah extends Foo {}
you can't then try to resolve Foo
and expect to be given Bah
, they are treated as 2 separate thingsThis is still a work in progress so hopefully more in depth type inferrence will be added in the future.
For more information, see the full documentation at https://jpex-js.github.io
jpex.constant(name: string, obj: any)
jpex.constant<T>(obj: T)
Registers a constant value
jpex.factory(name: string, deps?: string[], fn: (...deps: any[]) => any)
jpex.factory<T>(fn(...deps: any[]) => T)
Registers a factory function.
jpex.service(name: string, deps?: string[], c: ClassType)
jpex.service<T>(c: ClassType<T>)
Registers a service, the dependencies will be passed in to the constructor function. It is possible to pass in a regular function instead of an ES6 class.
jpex.factory(...args).lifecycle.application();
jpex.factory(...args).lifecycle.class();
jpex.factory(...args).lifecycle.instance();
jpex.factory(...args).lifecycle.none();
sets the lifecycle of the factory. This determines how long a resolved factory is cached for.
jpex.extend
will require the factory to be resolved again)jpex.service(...args).bindToInstance();
Automatically binds dependencies to a service's instance.
jpex.factory(...args).dependencies('foo', 'bah');
Allows you to set a factory's dependencies after-the-fact.
jpex.alias(alias: string, factory: string): void
jpex.alias<T>(alias: string): void
jpex.resolve<T>(name: string): T
jpex.resolve<T>(): T
Resolves a specified dependency. You can omit the name
parameter if using the babel plugin
jpex.resolveWith<T>(name: string, namedParameters: object): T
jpex.resolveWith<T>(namedParameters: object): T
allows you to pass in values for specific dependencies. Rather than attempting to resolve those dependencies, it will use the given value instead.
jpex.constant('myConstant', 'foo');
jpex.factory('myFactory', [ 'myConstant' ], (c) => c);
const x = jpex.resolveWith('myFactory', { myConstant: 'bah' });
// x -> bah
jpex.encase(
dependencies: string[],
fn: (...deps: any[]) => Function
): Function
jpex.encase(
fn: (...deps: any[]) => Function
) => Function
Wraps a function and injects values into it, it then returns the inner function for use. It supports type inference.
The easiest way to explain this method is with an example:
const getStuff = jpex.encase((http: Http) => (thing: string) => {
return http(`api/app/${thing}`);
});
await getStuff('my-thing');
For testing purposes, you can access the wrapper function of your encased method using this property.
getStuff.encased(fakeHttp)('my-thing');
(): void
<T>(): void
(name: string): void
(name: string[]): void
Clears the cache. If you provide a name or a type, it will only clear that dependency's cache. If you omit name altogether, it will clear the entire cache.
jpex.extend(config?: {
lifecycle?: Lifecycle,
inherit?: boolean,
}): Jpex
Creates a new container. You will still have access to all factories registered on the parent container.
If you pass inherit: false
you will not get any of the parent's factories, you will just get a clearn instance.
jpex.infer<T>(): string
If you're working with typescript inference, you can use this function to get the inferred name of a type.
const dependencyName = jpex.infer<IFactory>(); // something like src/types/IFactory
jpex.raw<T>(): (...args: any[]) => T
returns the raw factory function
const factory = jpex.raw<IFactory>;
const result = factory(dep1, dep2)('my-thing');
3.5.0
FAQs
Javascript Prototype Extension
The npm package jpex receives a total of 690 weekly downloads. As such, jpex popularity was classified as not popular.
We found that jpex demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.