New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@aurelia/kernel

Package Overview
Dependencies
Maintainers
1
Versions
1121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aurelia/kernel - npm Package Compare versions

Comparing version 2.0.1-dev.202403021005 to 2.0.1-dev.202403150512

dist/types/di.resolvers.d.ts

35

CHANGELOG.md

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

<a name="2.0.0-beta.13"></a>
# 2.0.0-beta.13 (2024-03-15)
### Features:
* **template-controller:** ability to have a container per factory (#1924) ([6727b56](https://github.com/aurelia/aurelia/commit/6727b56))
* **convention:** add import as support (#1920) ([7a15551](https://github.com/aurelia/aurelia/commit/7a15551))
* **di:** api to register resources with alias key ([7a15551](https://github.com/aurelia/aurelia/commit/7a15551))
* **dev:** better DI error messages for instantiation (#1917) ([2fca6ea](https://github.com/aurelia/aurelia/commit/2fca6ea))
### Bug Fixes:
* **router:** dont swallow instantiation error details ([deee8e6](https://github.com/aurelia/aurelia/commit/deee8e6))
* ***:** cleanup di & router tests, add timeout ([deee8e6](https://github.com/aurelia/aurelia/commit/deee8e6))
* ***:** router errors stringify ([deee8e6](https://github.com/aurelia/aurelia/commit/deee8e6))
* ***:** deepscan issues ([deee8e6](https://github.com/aurelia/aurelia/commit/deee8e6))
* ***:** element get own metadata call ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **di:** cache factory on singleton resolution ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
### Refactorings:
* ***:** smaller di files, assert text options, more au slot tests ([deee8e6](https://github.com/aurelia/aurelia/commit/deee8e6))
* **runtime:** move ctor reg into controller ([7a15551](https://github.com/aurelia/aurelia/commit/7a15551))
* **resource:** cleanup registration, APIs (#1918) ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* ***:** cleanup util fn ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **resources:** move find to corresponding resource kind ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **di:** add registrable, remove unecessary infra for attr pattern ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **resources:** use registrable ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **di:** dont search for resources when register ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **resource:** remove resource protocol, simplify resource metadata ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **resources:** add get for vc & bb resource kinds ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
* **resource:** binding command resolution ([dc22fb7](https://github.com/aurelia/aurelia/commit/dc22fb7))
<a name="2.0.0-beta.12"></a>

@@ -8,0 +43,0 @@ # 2.0.0-beta.12 (2024-03-02)

26

dist/types/di.container.d.ts

@@ -1,3 +0,25 @@

import { type Key, type IResolver, type Resolved, type IFactoryResolver, type ILazyResolver, type INewInstanceResolver, type IResolvedFactory, type IResolvedLazy, type IAllResolver, type IOptionalResolver } from './di';
export type IResolvedInjection<K extends Key> = K extends IAllResolver<infer R> ? readonly Resolved<R>[] : K extends INewInstanceResolver<infer R> ? Resolved<R> : K extends ILazyResolver<infer R> ? IResolvedLazy<R> : K extends IOptionalResolver<infer R> ? Resolved<R> | undefined : K extends IFactoryResolver<infer R> ? IResolvedFactory<R> : K extends IResolver<infer R> ? Resolved<R> : K extends [infer R1 extends Key, ...infer R2] ? [IResolvedInjection<R1>, ...IResolvedInjection<R2>] : K extends {
import { IContainer, type Key, type IResolver, type Resolved, type IContainerConfiguration } from './di';
import type { IAllResolver, INewInstanceResolver, ILazyResolver, IResolvedLazy, IOptionalResolver, IFactoryResolver, IResolvedFactory } from './di.resolvers';
export declare const Registrable: Readonly<{
/**
* Associate an object as a registrable, making the container recognize & use
* the specific given register function during the registration
*/
define: <T extends WeakKey>(object: T, register: (this: T, container: IContainer) => IContainer | void) => T;
get: <T_1 extends WeakKey>(object: T_1) => ((container: IContainer) => IContainer | void) | undefined;
has: <T_2 extends WeakKey>(object: T_2) => boolean;
}>;
export declare const DefaultResolver: {
none(key: Key): IResolver;
singleton: (key: Key) => IResolver;
transient: (key: Key) => IResolver;
};
export declare class ContainerConfiguration implements IContainerConfiguration {
readonly inheritParentResources: boolean;
readonly defaultResolver: (key: Key, handler: IContainer) => IResolver;
static readonly DEFAULT: ContainerConfiguration;
private constructor();
static from(config?: IContainerConfiguration): ContainerConfiguration;
}
export type IResolvedInjection<K extends Key> = K extends IAllResolver<infer R> ? Resolved<R>[] : K extends INewInstanceResolver<infer R> ? Resolved<R> : K extends ILazyResolver<infer R> ? IResolvedLazy<R> : K extends IOptionalResolver<infer R> ? Resolved<R> | undefined : K extends IFactoryResolver<infer R> ? IResolvedFactory<R> : K extends IResolver<infer R> ? Resolved<R> : K extends [infer R1 extends Key, ...infer R2] ? [IResolvedInjection<R1>, ...IResolvedInjection<R2>] : K extends {
__resolved__: infer T;

@@ -4,0 +26,0 @@ } ? T : Resolved<K>;

274

dist/types/di.d.ts
import { Constructable, IDisposable } from './interfaces';
import { IResourceKind, ResourceDefinition, ResourceType } from './resource';
import { ResourceType } from './resource';
import type { IAllResolver, IFactoryResolver, ILazyResolver, INewInstanceResolver, IOptionalResolver, IResolvedFactory, IResolvedLazy } from './di.resolvers';
export type ResolveCallback<T = any> = (handler: IContainer, requestor: IContainer, resolver: IResolver<T>) => T;

@@ -36,5 +37,5 @@ export type InterfaceSymbol<K = any> = (target: Injectable | AbstractInjectable, property: string | symbol | undefined, index?: number) => void;

get<K extends Key>(key: K | Key): Resolved<K>;
getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];
getAll<K extends Key>(key: Key, searchAncestors?: boolean): readonly Resolved<K>[];
getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): readonly Resolved<K>[];
getAll<K extends Key>(key: K, searchAncestors?: boolean): Resolved<K>[];
getAll<K extends Key>(key: Key, searchAncestors?: boolean): Resolved<K>[];
getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): Resolved<K>[];
}

@@ -64,3 +65,3 @@ export interface IRegistry {

useResources(container: IContainer): void;
find<TType extends ResourceType, TDef extends ResourceDefinition>(kind: IResourceKind<TType, TDef>, name: string): TDef | null;
find<TResType extends ResourceType>(key: string): TResType | null;
}

@@ -101,16 +102,5 @@ export declare class ResolverBuilder<K> {

}
export declare const DefaultResolver: {
none(key: Key): IResolver;
singleton: (key: Key) => IResolver;
transient: (key: Key) => IResolver;
};
export declare class ContainerConfiguration implements IContainerConfiguration {
readonly inheritParentResources: boolean;
readonly defaultResolver: (key: Key, handler: IContainer) => IResolver;
static readonly DEFAULT: ContainerConfiguration;
private constructor();
static from(config?: IContainerConfiguration): ContainerConfiguration;
}
export declare const inject: (...dependencies: Key[]) => (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number) => void;
export declare const DI: {
createContainer: (config?: Partial<IContainerConfiguration>) => IContainer;
createContainer: (config?: Partial<IContainerConfiguration> | undefined) => IContainer;
getDesignParamtypes: (Type: Constructable | Injectable) => readonly Key[] | undefined;

@@ -162,3 +152,3 @@ getAnnotationParamtypes: (Type: Constructable | Injectable) => readonly Key[] | undefined;

createInterface: <K extends Key>(configureOrName?: string | ((builder: ResolverBuilder<K>) => IResolver<K>) | undefined, configuror?: ((builder: ResolverBuilder<K>) => IResolver<K>) | undefined) => InterfaceSymbol<K>;
inject(...dependencies: Key[]): (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number) => void;
inject: (...dependencies: Key[]) => (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number) => void;
/**

@@ -204,10 +194,2 @@ * Registers the `target` class as a transient dependency; each time the dependency is resolved

export declare const IServiceLocator: InterfaceSymbol<IServiceLocator>;
export type ICallableResolver<T> = IResolver<T> & ((...args: unknown[]) => any);
/**
* ! Semi private API to avoid repetitive work creating resolvers.
*
* Naming isn't entirely correct, but it's good enough for internal usage.
*/
export declare function createResolver<T extends Key>(getter: (key: T, handler: IContainer, requestor: IContainer) => any): ((key: T) => ICallableResolver<T>);
export declare const inject: (...dependencies: Key[]) => (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number) => void;
declare function transientDecorator<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;

@@ -263,226 +245,2 @@ /**

export declare function singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;
/**
* Create a resolver that will resolve all values of a key from resolving container
*/
export declare const all: <T extends Key>(key: T, searchAncestors?: boolean) => IAllResolver<T>;
export type IAllResolver<T> = IResolver<readonly Resolved<T>[]> & {
__isAll: undefined;
(...args: unknown[]): any;
};
/**
* Lazily inject a dependency depending on whether the [[`Key`]] is present at the time of function call.
*
* You need to make your argument a function that returns the type, for example
* ```ts
* class Foo {
* constructor( @lazy('random') public random: () => number )
* }
* const foo = container.get(Foo); // instanceof Foo
* foo.random(); // throws
* ```
* would throw an exception because you haven't registered `'random'` before calling the method. This, would give you a
* new [['Math.random()']] number each time.
* ```ts
* class Foo {
* constructor( @lazy('random') public random: () => random )
* }
* container.register(Registration.callback('random', Math.random ));
* container.get(Foo).random(); // some random number
* container.get(Foo).random(); // another random number
* ```
* `@lazy` does not manage the lifecycle of the underlying key. If you want a singleton, you have to register as a
* `singleton`, `transient` would also behave as you would expect, providing you a new instance each time.
*
* - @param key [[`Key`]]
* see { @link DI.createInterface } on interactions with interfaces
*/
export declare const lazy: <K extends Key>(key: K) => ILazyResolver<K>;
export type ILazyResolver<K extends Key = Key> = IResolver<() => K> & {
__isLazy: undefined;
} & ((...args: unknown[]) => any);
export type IResolvedLazy<K> = () => Resolved<K>;
/**
* Allows you to optionally inject a dependency depending on whether the [[`Key`]] is present, for example
* ```ts
* class Foo {
* constructor( @inject('mystring') public str: string = 'somestring' )
* }
* container.get(Foo); // throws
* ```
* would fail
* ```ts
* class Foo {
* constructor( @optional('mystring') public str: string = 'somestring' )
* }
* container.get(Foo).str // somestring
* ```
* if you use it without a default it will inject `undefined`, so rember to mark your input type as
* possibly `undefined`!
*
* - @param key: [[`Key`]]
*
* see { @link DI.createInterface } on interactions with interfaces
*/
export declare const optional: <K extends Key>(key: K) => IOptionalResolver<K>;
export type IOptionalResolver<K extends Key = Key> = IResolver<K | undefined> & {
__isOptional: undefined;
(...args: unknown[]): any;
};
/**
* ignore tells the container not to try to inject a dependency
*/
export declare const ignore: {
(target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void;
$isResolver: boolean;
resolve(): undefined;
};
/**
* Inject a function that will return a resolved instance of the [[key]] given.
* Also supports passing extra parameters to the invocation of the resolved constructor of [[key]]
*
* For typings, it's a function that take 0 or more arguments and return an instance. Example:
* ```ts
* class Foo {
* constructor( @factory(MyService) public createService: (...args: unknown[]) => MyService)
* }
* const foo = container.get(Foo); // instanceof Foo
* const myService_1 = foo.createService('user service')
* const myService_2 = foo.createService('content service')
* ```
*
* ```ts
* class Foo {
* constructor( @factory('random') public createRandomizer: () => Randomizer)
* }
* container.get(Foo).createRandomizer(); // create a randomizer
* ```
* would throw an exception because you haven't registered `'random'` before calling the method. This, would give you a
* new instance of Randomizer each time.
*
* `@factory` does not manage the lifecycle of the underlying key. If you want a singleton, you have to register as a
* `singleton`, `transient` would also behave as you would expect, providing you a new instance each time.
*
* - @param key [[`Key`]]
* see { @link DI.createInterface } on interactions with interfaces
*/
export declare const factory: <K>(key: K) => IFactoryResolver<K>;
export type IFactoryResolver<K = any> = IResolver<K> & {
__isFactory: undefined;
} & ((...args: unknown[]) => any);
export type IResolvedFactory<K> = (...args: unknown[]) => Resolved<K>;
/**
* Create a resolver that will resolve a new instance of a key, and register the newly created instance with the requestor container
*/
export declare const newInstanceForScope: <K>(key: K) => INewInstanceResolver<K>;
/**
* Create a resolver that will resolve a new instance of a key
*/
export declare const newInstanceOf: <K>(key: K) => INewInstanceResolver<K>;
export type INewInstanceResolver<T> = IResolver<T> & {
__newInstance: undefined;
(...args: unknown[]): any;
};
/**
* An implementation of IRegistry that delegates registration to a
* separately registered class. The ParameterizedRegistry facilitates the
* passing of parameters to the final registry.
*/
export declare class ParameterizedRegistry implements IRegistry {
private readonly key;
private readonly params;
constructor(key: Key, params: unknown[]);
register(container: IContainer): void;
}
/**
* you can use the resulting {@linkcode IRegistration} of any of the factory methods
* to register with the container, e.g.
* ```
* class Foo {}
* const container = DI.createContainer();
* container.register(Registration.instance(Foo, new Foo()));
* container.get(Foo);
* ```
*/
export declare const Registration: {
/**
* allows you to pass an instance.
* Every time you request this {@linkcode Key} you will get this instance back.
* ```
* Registration.instance(Foo, new Foo()));
* ```
*
* @param key - key to register the instance with
* @param value - the instance associated with the key
*/
instance: <T>(key: Key, value: T) => IRegistration<T>;
/**
* Creates an instance from the class.
* Every time you request this {@linkcode Key} you will get the same one back.
* ```
* Registration.singleton(Foo, Foo);
* ```
*
* @param key - key to register the singleton class with
* @param value - the singleton class to instantiate when a container resolves the associated key
*/
singleton: <T_1 extends Constructable>(key: Key, value: T_1) => IRegistration<InstanceType<T_1>>;
/**
* Creates an instance from a class.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.instance(Foo, Foo);
* ```
*
* @param key - key to register the transient class with
* @param value - the class to instantiate when a container resolves the associated key
*/
transient: <T_2 extends Constructable>(key: Key, value: T_2) => IRegistration<InstanceType<T_2>>;
/**
* Creates an instance from the method passed.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.callback(Foo, () => new Foo());
* Registration.callback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the callback with
* @param callback - the callback to invoke when a container resolves the associated key
*/
callback: <T_3>(key: Key, callback: ResolveCallback<T_3>) => IRegistration<Resolved<T_3>>;
/**
* Creates an instance from the method passed.
* On the first request for the {@linkcode Key} your callback is called and returns an instance.
* subsequent requests for the {@linkcode Key}, the initial instance returned will be returned.
* If you pass the same {@linkcode Registration} to another container the same cached value will be used.
* Should all references to the resolver returned be removed, the cache will expire.
* ```
* Registration.cachedCallback(Foo, () => new Foo());
* Registration.cachedCallback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the cached callback with
* @param callback - the cache callback to invoke when a container resolves the associated key
*/
cachedCallback: <T_4>(key: Key, callback: ResolveCallback<T_4>) => IRegistration<Resolved<T_4>>;
/**
* creates an alternate {@linkcode Key} to retrieve an instance by.
* Returns the same scope as the original {@linkcode Key}.
* ```
* Register.singleton(Foo, Foo)
* Register.aliasTo(Foo, MyFoos);
*
* container.getAll(MyFoos) // contains an instance of Foo
* ```
*
* @param originalKey - the real key to resolve the get call from a container
* @param aliasKey - the key that a container allows to resolve the real key associated
*/
aliasTo: <T_5>(originalKey: T_5, aliasKey: Key) => IRegistration<Resolved<T_5>>;
/**
* @internal
* @param key - the key to register a defer registration
* @param params - the parameters that should be passed to the resolution of the key
*/
defer: (key: Key, ...params: unknown[]) => IRegistry;
};
export declare class InstanceProvider<K extends Key> implements IDisposableResolver<K | null> {

@@ -495,9 +253,21 @@ get friendlyName(): string | undefined;

*/
instance?: Resolved<K> | null);
instance?: Resolved<K> | null, Type?: Constructable | null);
prepare(instance: Resolved<K>): void;
get $isResolver(): true;
resolve(): Resolved<K> | null;
getFactory(container: IContainer): (K extends Constructable ? IFactory<K> : never) | null;
dispose(): void;
}
/**
* An implementation of IRegistry that delegates registration to a
* separately registered class. The ParameterizedRegistry facilitates the
* passing of parameters to the final registry.
*/
export declare class ParameterizedRegistry implements IRegistry {
private readonly key;
private readonly params;
constructor(key: Key, params: unknown[]);
register(container: IContainer): void;
}
export {};
//# sourceMappingURL=di.d.ts.map

@@ -1,3 +0,95 @@

import { type ResolveCallback } from './di';
export declare const cacheCallbackResult: <T>(fun: ResolveCallback<T>) => ResolveCallback<T>;
import { type Key, IRegistration, type ResolveCallback, type Resolved, type IRegistry } from './di';
import { Constructable } from './interfaces';
/**
* you can use the resulting {@linkcode IRegistration} of any of the factory methods
* to register with the container, e.g.
* ```
* class Foo {}
* const container = DI.createContainer();
* container.register(Registration.instance(Foo, new Foo()));
* container.get(Foo);
* ```
*/
export declare const Registration: {
/**
* allows you to pass an instance.
* Every time you request this {@linkcode Key} you will get this instance back.
* ```
* Registration.instance(Foo, new Foo()));
* ```
*
* @param key - key to register the instance with
* @param value - the instance associated with the key
*/
instance: <T>(key: Key, value: T) => IRegistration<T>;
/**
* Creates an instance from the class.
* Every time you request this {@linkcode Key} you will get the same one back.
* ```
* Registration.singleton(Foo, Foo);
* ```
*
* @param key - key to register the singleton class with
* @param value - the singleton class to instantiate when a container resolves the associated key
*/
singleton: <T_1 extends Constructable>(key: Key, value: T_1) => IRegistration<InstanceType<T_1>>;
/**
* Creates an instance from a class.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.instance(Foo, Foo);
* ```
*
* @param key - key to register the transient class with
* @param value - the class to instantiate when a container resolves the associated key
*/
transient: <T_2 extends Constructable>(key: Key, value: T_2) => IRegistration<InstanceType<T_2>>;
/**
* Creates an instance from the method passed.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.callback(Foo, () => new Foo());
* Registration.callback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the callback with
* @param callback - the callback to invoke when a container resolves the associated key
*/
callback: <T_3>(key: Key, callback: ResolveCallback<T_3>) => IRegistration<Resolved<T_3>>;
/**
* Creates an instance from the method passed.
* On the first request for the {@linkcode Key} your callback is called and returns an instance.
* subsequent requests for the {@linkcode Key}, the initial instance returned will be returned.
* If you pass the same {@linkcode Registration} to another container the same cached value will be used.
* Should all references to the resolver returned be removed, the cache will expire.
* ```
* Registration.cachedCallback(Foo, () => new Foo());
* Registration.cachedCallback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the cached callback with
* @param callback - the cache callback to invoke when a container resolves the associated key
*/
cachedCallback: <T_4>(key: Key, callback: ResolveCallback<T_4>) => IRegistration<Resolved<T_4>>;
/**
* creates an alternate {@linkcode Key} to retrieve an instance by.
* Returns the same scope as the original {@linkcode Key}.
* ```
* Register.singleton(Foo, Foo)
* Register.aliasTo(Foo, MyFoos);
*
* container.getAll(MyFoos) // contains an instance of Foo
* ```
*
* @param originalKey - the real key to resolve the get call from a container
* @param aliasKey - the key that a container allows to resolve the real key associated
*/
aliasTo: <T_5>(originalKey: T_5, aliasKey: Key) => IRegistration<Resolved<T_5>>;
/**
* @internal
* @param key - the key to register a defer registration
* @param params - the parameters that should be passed to the resolution of the key
*/
defer: (key: Key, ...params: unknown[]) => IRegistry;
};
//# sourceMappingURL=di.registration.d.ts.map
export { IPlatform, } from './platform';
export { createResolver, all, factory, type IAllResolver, type IFactoryResolver, type IOptionalResolver, type IResolvedFactory, type INewInstanceResolver, DI, IContainer, type IFactory, inject, type IRegistration, type IRegistry, type IResolver, IServiceLocator, type Key, lazy, type ILazyResolver, type IResolvedLazy, optional, ignore, type RegisterSelf, Registration, type ResolveCallback, singleton, transient, type AbstractInjectable, type Injectable, type InterfaceSymbol, InstanceProvider, type Resolved, type Transformer, newInstanceForScope, newInstanceOf, ContainerConfiguration, DefaultResolver, type IContainerConfiguration, } from './di';
export { resolve, type IResolvedInjection, } from './di.container';
export { DI, IContainer, type IFactory, inject, type IRegistration, type IRegistry, type IResolver, IServiceLocator, type Key, type RegisterSelf, type ResolveCallback, singleton, transient, type AbstractInjectable, type Injectable, type InterfaceSymbol, InstanceProvider, type Resolved, type Transformer, type IContainerConfiguration, } from './di';
export { resolve, type IResolvedInjection, Registrable, ContainerConfiguration, DefaultResolver, } from './di.container';
export { Registration, } from './di.registration';
export { createResolver, all, factory, type IAllResolver, type IFactoryResolver, type IOptionalResolver, type IResolvedFactory, type INewInstanceResolver, lazy, type ILazyResolver, type IResolvedLazy, optional, ignore, newInstanceForScope, newInstanceOf, type ICallableResolver, allResources, optionalResource, own, resource, } from './di.resolvers';
export { type Class, type Constructable, type ConstructableClass, type IDisposable, type IIndexable, type Overwrite, type Primitive, type Writable, } from './interfaces';
export { LogLevel, type IConsoleLike, type ColorOptions, ILogConfig, type ILogEvent, ILogEventFactory, ISink, ILogger, LogConfig, DefaultLogEvent, DefaultLogEventFactory, DefaultLogger, ConsoleSink, LoggerConfiguration, format, sink, } from './logger';
export { type IModule, IModuleLoader, AnalyzedModule, ModuleItem, } from './module-loader';
export { type IModule, IModuleLoader, AnalyzedModule, ModuleItem, aliasedResourcesRegistry, } from './module-loader';
export { noop, emptyArray, emptyObject, } from './platform';
export { type IResourceKind, type PartialResourceDefinition, Protocol, type ResourceDefinition, type ResourceType, fromAnnotationOrDefinitionOrTypeOrDefault, fromAnnotationOrTypeOrDefault, fromDefinitionOrDefault, } from './resource';
export { resourceBaseName, getResourceKeyFor, type IResourceKind, type PartialResourceDefinition, Protocol, type ResourceDefinition, type ResourceType, fromAnnotationOrDefinitionOrTypeOrDefault, fromAnnotationOrTypeOrDefault, fromDefinitionOrDefault, } from './resource';
export { EventAggregator, IEventAggregator, } from './eventaggregator';

@@ -10,0 +12,0 @@ export { isArrayIndex, camelCase, kebabCase, pascalCase, toArray, bound, mergeArrays, firstDefined, getPrototypeChain, isNativeFunction, onResolve, onResolveAll, } from './functions';

@@ -233,3 +233,3 @@ import { IContainer, IRegistry } from './di';

*/
config?: ILogConfig, factory?: ILogEventFactory, sinks?: readonly ISink[],
config?: ILogConfig, factory?: ILogEventFactory, sinks?: ISink[],
/**

@@ -236,0 +236,0 @@ * The scopes that this logger was created for, if any.

@@ -71,3 +71,3 @@ import type { IRegistry } from './di';

readonly isConstructable: TisConstructable;
readonly definitions: readonly ResourceDefinition[];
readonly definition: ResourceDefinition | null;
}

@@ -88,5 +88,9 @@ export interface ITypedModuleItem_Unknown extends ITypedModuleItem<false, false, unknown> {

readonly isConstructable: boolean;
readonly definitions: readonly ResourceDefinition[];
constructor(key: string, value: unknown, isRegistry: boolean, isConstructable: boolean, definitions: readonly ResourceDefinition[]);
readonly definition: ResourceDefinition | null;
constructor(key: string, value: unknown, isRegistry: boolean, isConstructable: boolean, definition: ResourceDefinition | null);
}
/**
* Iterate through the exports of a module and register aliases for resources respectively
*/
export declare const aliasedResourcesRegistry: (mod: IModule, mainKeyAlias: string | null | undefined, aliases?: Record<string, string>) => IRegistry;
//# sourceMappingURL=module-loader.d.ts.map

@@ -7,6 +7,16 @@ import { IContainer } from './di';

export type ResourceDefinition<TUserType extends Constructable = Constructable, TResInstance extends {} = {}, TDef extends {} = {}, TResType extends {} = {}, TUserInstance extends InstanceType<TUserType> = InstanceType<TUserType>> = {
/**
* Unique key to identify the resource.
*/
readonly key: string;
/**
* A common name for the resource.
*/
readonly name: string;
readonly Type: ResourceType<TUserType, TResInstance, TResType, TUserInstance>;
readonly aliases?: readonly string[];
register(container: IContainer): void;
/**
* @param aliasName - If provided, the resource will be registered with this alias key.
*/
register(container: IContainer, aliasName?: string): void;
} & TDef;

@@ -21,3 +31,7 @@ export type PartialResourceDefinition<TDef extends {} = {}> = {

}
export declare const hasResources: (target: unknown) => target is Constructable;
export declare const resourceBaseName = "au:resource";
/**
* Builds a resource key from the provided parts.
*/
export declare const getResourceKeyFor: (type: string, name?: string, context?: string) => string;
export declare const Protocol: {

@@ -33,11 +47,2 @@ annotation: Readonly<{

}>;
resource: Readonly<{
name: "au:resource";
appendTo(target: Constructable, key: string): void;
has: (target: unknown) => target is Constructable;
getAll: (target: Constructable) => readonly ResourceDefinition[];
getKeys(target: Constructable): readonly string[];
isKey: (key: string) => boolean;
keyFor(name: string, context?: string): string;
}>;
};

@@ -44,0 +49,0 @@ /**

{
"name": "@aurelia/kernel",
"version": "2.0.1-dev.202403021005",
"version": "2.0.1-dev.202403150512",
"main": "dist/cjs/index.cjs",

@@ -55,4 +55,4 @@ "module": "dist/esm/index.mjs",

"dependencies": {
"@aurelia/metadata": "2.0.1-dev.202403021005",
"@aurelia/platform": "2.0.1-dev.202403021005"
"@aurelia/metadata": "2.0.1-dev.202403150512",
"@aurelia/platform": "2.0.1-dev.202403150512"
},

@@ -59,0 +59,0 @@ "devDependencies": {

/* eslint-disable @typescript-eslint/no-unused-vars */
import { DI, all, inject, lazy, optional, newInstanceOf, newInstanceForScope, factory } from './di';
import { DI, inject } from './di';
import { all, lazy, optional, newInstanceOf, newInstanceForScope, factory, own, resource, allResources, optionalResource } from './di.resolvers';
import { resolve } from './di.container';
function testAll() {
function test() {
const d = DI.createContainer();

@@ -11,111 +12,137 @@ const I = DI.createInterface<I>();

}
const instances = d.get(all(class Abc { public b: number = 5; }));
instances.forEach(i => i.b);
const ii = d.get(all(I));
ii.forEach(i => i.c);
function testAll() {
const instances = d.get(all(class Abc { public b: number = 5; }));
instances.forEach(i => i.b);
class Def {
public constructor(@all(I) private readonly i: I) {}
}
const ii = d.get(all(I));
ii.forEach(i => i.c);
@inject(all(I))
class G {}
}
class Def {
public constructor(@all(I) private readonly i: I) {}
}
function testLazy() {
const d = DI.createContainer();
const I = DI.createInterface<I>();
interface I {
c: number;
@inject(all(I))
class G {}
}
const instance = d.get(lazy(class Abc { public b: number = 5; }));
if (instance().b === 5) {
// good
}
class Def {
public constructor(@lazy(I) private readonly i: I) {}
}
function testLazy() {
const instance = d.get(lazy(class Abc { public b: number = 5; }));
if (instance().b === 5) {
// good
}
@inject(lazy(I))
class G {
public i = resolve(lazy(I));
public b: I = this.i();
class Def {
public constructor(@lazy(I) private readonly i: I) {}
}
@inject(lazy(I))
class G {
public i = resolve(lazy(I));
public b: I = this.i();
}
}
}
function testOptional() {
const d = DI.createContainer();
const I = DI.createInterface<I>();
interface I {
c: number;
function testOptional() {
const instance = d.get(optional(class Abc { public b: number = 5; }));
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
if (instance.b === 5) {
// good
}
class Def {
public constructor(@optional(I) private readonly i: I) { }
}
@inject(optional(I))
class G {
public i = resolve(optional(I));
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
public b: I = this.i;
}
}
const instance = d.get(optional(class Abc { public b: number = 5; }));
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
if (instance.b === 5) {
// good
}
class Def {
public constructor(@optional(I) private readonly i: I) { }
function testNewInstance() {
const instance = d.get(newInstanceOf(class Abc { public b: number = 5; }));
if (instance.b === 5) {
// good
}
const instance2 = d.get(newInstanceForScope(class Abc { public b: number = 5; }));
if (instance2.b === 5) {
// good
}
class Def {
public constructor(
@newInstanceOf(I) private readonly i: I,
@newInstanceForScope(I) private readonly j: I,
) { }
}
@inject(newInstanceOf(I))
class G {
public i = resolve(newInstanceOf(I));
public ii: I = this.i;
public j = resolve(newInstanceForScope(I));
public jj: I = this.j;
}
}
@inject(optional(I))
class G {
public i = resolve(optional(I));
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment, prefer-const */
function testOwn() {
const instance = d.get(own(I));
// @ts-expect-error
public b: I = this.i;
if (instance.c) {/* */}
}
}
function testNewInstance() {
const d = DI.createContainer();
const I = DI.createInterface<I>();
interface I {
c: number;
function testResource() {
const d = DI.createContainer();
const I = DI.createInterface<I>();
interface I {
c: number;
}
const instance = d.get(resource(I));
if (instance.c) {/* */}
}
const instance = d.get(newInstanceOf(class Abc { public b: number = 5; }));
if (instance.b === 5) {
// good
function testOptionalResource() {
const instance = d.get(optionalResource(I));
// @ts-expect-error
if (instance.c) {/* */}
}
const instance2 = d.get(newInstanceForScope(class Abc { public b: number = 5; }));
if (instance2.b === 5) {
// good
}
class Def {
public constructor(
@newInstanceOf(I) private readonly i: I,
@newInstanceForScope(I) private readonly j: I,
) { }
function testAllResources() {
const instances = d.get(allResources(I));
instances.forEach(i => i.c);
}
@inject(newInstanceOf(I))
class G {
public i = resolve(newInstanceOf(I));
public ii: I = this.i;
public j = resolve(newInstanceForScope(I));
public jj: I = this.j;
function testResolve() {
class Abc { public a = 1; }
class Def { public b = 2; }
class Abc2 { public c = '3'; }
const [{ a: _ }] = resolve(all(Abc));
const [ [{ a: a_ }], [{ b: b_ }], [{ c: c_ }]] = resolve(all(Abc), all(Def), all(Abc2));
let [{ a }, { b }, { c }, lazyDef, factoryAbc2, optionalAbc, newDef, newAbc] = resolve(Abc, Def, Abc2, lazy(Def), factory(Abc2), optional(Abc), newInstanceForScope(Def), newInstanceOf(Abc));
a = 3; b = 4; c = '1';
lazyDef().b = 5;
factoryAbc2(1, 2, 3).c = '2';
// @ts-expect-error
if (optionalAbc.a) {/* */}
newDef.b = 4;
newAbc.a = 2;
const [ownAbc, resourceAbc, optionalResourceAbc, allResourceAbcs] = resolve(own(Abc), resource(Abc), optionalResource(Abc), allResources(Abc));
// @ts-expect-error
if (ownAbc.a) {/* */}
if (resourceAbc.a) {/* */}
// @ts-expect-error
if (optionalResourceAbc.a) {/* */}
allResourceAbcs.forEach(a => a.a);
}
/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment, prefer-const */
}
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment, prefer-const */
function testResolve() {
class Abc { public a = 1; }
class Def { public b = 2; }
class Abc2 { public c = '3'; }
const [{ a: _ }] = resolve(all(Abc));
const [ [{ a: a_ }], [{ b: b_ }], [{ c: c_ }]] = resolve(all(Abc), all(Def), all(Abc2));
let [{ a }, { b }, { c }, lazyDef, factoryAbc2, optionalAbc, newDef, newAbc] = resolve(Abc, Def, Abc2, lazy(Def), factory(Abc2), optional(Abc), newInstanceForScope(Def), newInstanceOf(Abc));
a = 3; b = 4; c = '1';
lazyDef().b = 5;
factoryAbc2(1, 2, 3).c = '2';
// @ts-expect-error
if (optionalAbc.a) {/* */}
newDef.b = 4;
newAbc.a = 2;
}
/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment, prefer-const */
/* eslint-disable @typescript-eslint/no-this-alias */
/* eslint-disable @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
import { isObject } from '@aurelia/metadata';
import { Metadata, isObject } from '@aurelia/metadata';
import { isNativeFunction } from './functions';
import { type Class, type Constructable, type IDisposable } from './interfaces';
import { emptyArray } from './platform';
import { type IResourceKind, type ResourceDefinition, type ResourceType, getAllResources, hasResources } from './resource';
import { getOwnMetadata, isFunction, isString } from './utilities';
import { resourceBaseName, ResourceDefinition, type ResourceType } from './resource';
import { isFunction, isString, objectFreeze } from './utilities';
import {

@@ -14,5 +14,3 @@ IContainer,

type IDisposableResolver,
ContainerConfiguration,
type IRegistry,
Registration,
Resolver,

@@ -26,12 +24,61 @@ ResolverStrategy,

type IContainerConfiguration,
type IFactoryResolver,
type ILazyResolver,
type INewInstanceResolver,
type IResolvedFactory,
type IResolvedLazy,
type IAllResolver,
type IOptionalResolver,
} from './di';
import { ErrorNames, createMappedError } from './errors';
import { ErrorNames, createMappedError, logError, logWarn } from './errors';
import { singletonRegistration } from './di.registration';
import type { IAllResolver, INewInstanceResolver, ILazyResolver, IResolvedLazy, IOptionalResolver, IFactoryResolver, IResolvedFactory } from './di.resolvers';
export const Registrable = /*@__PURE__*/(() => {
const map = new WeakMap<WeakKey, (container: IContainer) => IContainer | void>();
return objectFreeze({
/**
* Associate an object as a registrable, making the container recognize & use
* the specific given register function during the registration
*/
define: <T extends WeakKey>(object: T, register: (this: T, container: IContainer) => IContainer | void): T => {
if (__DEV__) {
if (map.has(object) && map.get(object) !== register) {
logWarn(`Overriding registrable found for key:`, object);
}
}
map.set(object, register);
return object;
},
get: <T extends WeakKey>(object: T) => map.get(object),
has: <T extends WeakKey>(object: T) => map.has(object),
});
})();
export const DefaultResolver = {
none(key: Key): IResolver {
throw createMappedError(ErrorNames.none_resolver_found, key);
},
singleton: (key: Key): IResolver => new Resolver(key, ResolverStrategy.singleton, key),
transient: (key: Key): IResolver => new Resolver(key, ResolverStrategy.transient, key),
};
export class ContainerConfiguration implements IContainerConfiguration {
public static readonly DEFAULT: ContainerConfiguration = ContainerConfiguration.from({});
private constructor(
public readonly inheritParentResources: boolean,
public readonly defaultResolver: (key: Key, handler: IContainer) => IResolver,
) {}
public static from(config?: IContainerConfiguration): ContainerConfiguration {
if (
config === void 0 ||
config === ContainerConfiguration.DEFAULT
) {
return ContainerConfiguration.DEFAULT;
}
return new ContainerConfiguration(
config.inheritParentResources ?? false,
config.defaultResolver ?? DefaultResolver.singleton,
);
}
}
/** @internal */
export const createContainer = (config?: Partial<IContainerConfiguration>): IContainer => new Container(null, ContainerConfiguration.from(config));
const InstrinsicTypeNames = new Set<string>('Array ArrayBuffer Boolean DataView Date Error EvalError Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Number Object Promise RangeError ReferenceError RegExp Set SharedArrayBuffer String SyntaxError TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array URIError WeakMap WeakSet'.split(' '));

@@ -129,2 +176,4 @@ // const factoryKey = 'di:factory';

let ii = params.length;
let def: ResourceDefinition;
for (; i < ii; ++i) {

@@ -137,17 +186,8 @@ current = params[i];

current.register(this);
} else if (hasResources(current)) {
const defs = getAllResources(current);
if (defs.length === 1) {
// Fast path for the very common case
defs[0].register(this);
} else {
j = 0;
jj = defs.length;
while (jj > j) {
defs[j].register(this);
++j;
}
}
} else if (Registrable.has(current)) {
Registrable.get(current)!.call(current, this);
} else if ((def = Metadata.getOwn(resourceBaseName, current)) != null) {
def.register(this);
} else if (isClass(current)) {
Registration.singleton(current, current as Constructable).register(this);
singletonRegistration(current, current as Constructable).register(this);
} else {

@@ -166,2 +206,4 @@ keys = Object.keys(current);

value.register(this);
} else if (Registrable.has(value)) {
Registrable.get(value)!.call(value, this);
} else {

@@ -331,3 +373,3 @@ this.register(value);

public getAll<K extends Key>(key: K, searchAncestors: boolean = false): readonly Resolved<K>[] {
public getAll<K extends Key>(key: K, searchAncestors: boolean = false): Resolved<K>[] {
validateKey(key);

@@ -374,8 +416,31 @@

public invoke<T extends {}, TDeps extends unknown[] = unknown[]>(Type: Constructable<T>, dynamicDependencies?: TDeps): T {
if (isNativeFunction(Type)) {
throw createMappedError(ErrorNames.no_construct_native_fn, Type);
}
const previousContainer = currentContainer;
currentContainer = this;
if (__DEV__) {
let resolvedDeps: unknown[];
let dep: Key | undefined;
try {
resolvedDeps = getDependencies(Type).map(_ => this.get(dep = _));
} catch (ex) {
logError(`[DEV:aurelia] Error during construction of ${!Type.name ? `(Anonymous) ${String(Type)}` : Type.name}, caused by dependency: ${String(dep)}`);
currentContainer = previousContainer;
throw ex;
}
try {
return dynamicDependencies === void 0
? new Type(...resolvedDeps)
: new Type(...resolvedDeps, ...dynamicDependencies);
} catch (ex) {
logError(`[DEV:aurelia] Error during construction of ${!Type.name ? `(Anonymous) ${String(Type)}` : Type.name}`);
throw ex;
} finally {
currentContainer = previousContainer;
}
}
try {
if (isNativeFunction(Type)) {
throw createMappedError(ErrorNames.no_construct_native_fn, Type);
}
return dynamicDependencies === void 0

@@ -445,22 +510,13 @@ ? new Type(...getDependencies(Type).map(containerGetKey, this))

public find<TType extends ResourceType, TDef extends ResourceDefinition>(kind: IResourceKind<TType, TDef>, name: string): TDef | null {
const key = kind.keyFrom(name);
let resolver = this.res[key];
public find<TResType extends ResourceType>(key: string): TResType | null {
let container: Container = this;
let resolver = container.res[key];
if (resolver == null) {
resolver = this.root.res[key];
if (resolver == null) {
return null;
}
container = container.root;
resolver = container.res[key];
}
if (isFunction(resolver.getFactory)) {
const factory = resolver.getFactory(this);
if (factory == null) {
return null;
}
return getOwnMetadata(kind.name, factory.Type) ?? null;
if (resolver == null) {
return null;
}
return null;
return resolver.getFactory?.(container)?.Type as TResType ?? null;
}

@@ -523,2 +579,33 @@

let instance: Resolved<T>;
/* istanbul ignore next */
if (__DEV__) {
let resolvedDeps: unknown[];
let dep: Key | undefined;
try {
resolvedDeps = this.dependencies.map(_ => container.get(dep = _));
} catch (ex) {
logError(`[DEV:aurelia] Error during construction of ${!this.Type.name ? `(Anonymous) ${String(this.Type)}` : this.Type.name}, caused by dependency: ${String(dep)}`);
currentContainer = previousContainer;
throw ex;
}
try {
if (dynamicDependencies === void 0) {
instance = new this.Type(...resolvedDeps) as Resolved<T>;
} else {
instance = new this.Type(...resolvedDeps, ...dynamicDependencies) as Resolved<T>;
}
if (this.transformers == null) {
return instance;
}
return this.transformers.reduce(transformInstance, instance);
} catch (ex) {
logError(`[DEV:aurelia] Error during construction of ${!this.Type.name ? `(Anonymous) ${String(this.Type)}` : this.Type.name}`);
throw ex;
} finally {
currentContainer = previousContainer;
}
}
try {

@@ -562,3 +649,3 @@ if (dynamicDependencies === void 0) {

K extends IAllResolver<infer R>
? readonly Resolved<R>[]
? Resolved<R>[]
: K extends INewInstanceResolver<infer R>

@@ -591,2 +678,21 @@ ? Resolved<R>

}
/* istanbul ignore next */
if (__DEV__) {
if (keys.length === 1) {
try {
return currentContainer.get(keys[0]);
} catch (ex) {
logError(`[DEV:aurelia] resolve() call error for: ${String(keys[0])}`);
throw ex;
}
} else {
let key: Key | undefined;
try {
return keys.map(_ => currentContainer!.get(key = _));
} catch (ex) {
logError(`[DEV:aurelia] resolve() call error for: ${String(key)}`);
throw ex;
}
}
}
return keys.length === 1

@@ -593,0 +699,0 @@ ? currentContainer.get(keys[0])

@@ -9,5 +9,5 @@ import {

type IRegistry,
type IContainer,
IResolver,
ParameterizedRegistry,
type IContainer,
IResolver
} from './di';

@@ -47,2 +47,3 @@ import { Constructable } from './interfaces';

/** @internal */
export const cacheCallbackResult = <T>(fun: ResolveCallback<T>): ResolveCallback<T> => {

@@ -62,1 +63,94 @@ return (handler: IContainer, requestor: IContainer, resolver: IResolver): T => {

};
/**
* you can use the resulting {@linkcode IRegistration} of any of the factory methods
* to register with the container, e.g.
* ```
* class Foo {}
* const container = DI.createContainer();
* container.register(Registration.instance(Foo, new Foo()));
* container.get(Foo);
* ```
*/
export const Registration = {
/**
* allows you to pass an instance.
* Every time you request this {@linkcode Key} you will get this instance back.
* ```
* Registration.instance(Foo, new Foo()));
* ```
*
* @param key - key to register the instance with
* @param value - the instance associated with the key
*/
instance: instanceRegistration,
/**
* Creates an instance from the class.
* Every time you request this {@linkcode Key} you will get the same one back.
* ```
* Registration.singleton(Foo, Foo);
* ```
*
* @param key - key to register the singleton class with
* @param value - the singleton class to instantiate when a container resolves the associated key
*/
singleton: singletonRegistration,
/**
* Creates an instance from a class.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.instance(Foo, Foo);
* ```
*
* @param key - key to register the transient class with
* @param value - the class to instantiate when a container resolves the associated key
*/
transient: transientRegistation,
/**
* Creates an instance from the method passed.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.callback(Foo, () => new Foo());
* Registration.callback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the callback with
* @param callback - the callback to invoke when a container resolves the associated key
*/
callback: callbackRegistration,
/**
* Creates an instance from the method passed.
* On the first request for the {@linkcode Key} your callback is called and returns an instance.
* subsequent requests for the {@linkcode Key}, the initial instance returned will be returned.
* If you pass the same {@linkcode Registration} to another container the same cached value will be used.
* Should all references to the resolver returned be removed, the cache will expire.
* ```
* Registration.cachedCallback(Foo, () => new Foo());
* Registration.cachedCallback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the cached callback with
* @param callback - the cache callback to invoke when a container resolves the associated key
*/
cachedCallback: cachedCallbackRegistration,
/**
* creates an alternate {@linkcode Key} to retrieve an instance by.
* Returns the same scope as the original {@linkcode Key}.
* ```
* Register.singleton(Foo, Foo)
* Register.aliasTo(Foo, MyFoos);
*
* container.getAll(MyFoos) // contains an instance of Foo
* ```
*
* @param originalKey - the real key to resolve the get call from a container
* @param aliasKey - the key that a container allows to resolve the real key associated
*/
aliasTo: aliasToRegistration,
/**
* @internal
* @param key - the key to register a defer registration
* @param params - the parameters that should be passed to the resolution of the key
*/
defer: deferRegistration,
};

@@ -10,8 +10,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

import { isArrayIndex } from './functions';
import { Container } from './di.container';
import { createContainer } from './di.container';
import { Constructable, IDisposable } from './interfaces';
import { appendAnnotation, getAnnotationKeyFor, IResourceKind, ResourceDefinition, ResourceType } from './resource';
import { defineMetadata, getOwnMetadata, isFunction, isString, safeString } from './utilities';
import { instanceRegistration, singletonRegistration, transientRegistation, callbackRegistration, cachedCallbackRegistration, aliasToRegistration, deferRegistration, cacheCallbackResult } from './di.registration';
import { appendAnnotation, getAnnotationKeyFor, ResourceType } from './resource';
import { defineMetadata, getOwnMetadata, isFunction, isString } from './utilities';
import { singletonRegistration, cacheCallbackResult, transientRegistation } from './di.registration';
import { ErrorNames, createMappedError } from './errors';
import type { IAllResolver, IFactoryResolver, ILazyResolver, INewInstanceResolver, IOptionalResolver, IResolvedFactory, IResolvedLazy } from './di.resolvers';

@@ -60,5 +61,5 @@ export type ResolveCallback<T = any> = (handler: IContainer, requestor: IContainer, resolver: IResolver<T>) => T;

get<K extends Key>(key: K | Key): Resolved<K>;
getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];
getAll<K extends Key>(key: Key, searchAncestors?: boolean): readonly Resolved<K>[];
getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): readonly Resolved<K>[];
getAll<K extends Key>(key: K, searchAncestors?: boolean): Resolved<K>[];
getAll<K extends Key>(key: Key, searchAncestors?: boolean): Resolved<K>[];
getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): Resolved<K>[];
}

@@ -92,3 +93,3 @@

useResources(container: IContainer): void;
find<TType extends ResourceType, TDef extends ResourceDefinition>(kind: IResourceKind<TType, TDef>, name: string): TDef | null;
find<TResType extends ResourceType>(key: string): TResType | null;
}

@@ -182,35 +183,2 @@

export const DefaultResolver = {
none(key: Key): IResolver {
throw createMappedError(ErrorNames.none_resolver_found, key);
},
singleton: (key: Key): IResolver => new Resolver(key, ResolverStrategy.singleton, key),
transient: (key: Key): IResolver => new Resolver(key, ResolverStrategy.transient, key),
};
export class ContainerConfiguration implements IContainerConfiguration {
public static readonly DEFAULT: ContainerConfiguration = ContainerConfiguration.from({});
private constructor(
public readonly inheritParentResources: boolean,
public readonly defaultResolver: (key: Key, handler: IContainer) => IResolver,
) {}
public static from(config?: IContainerConfiguration): ContainerConfiguration {
if (
config === void 0 ||
config === ContainerConfiguration.DEFAULT
) {
return ContainerConfiguration.DEFAULT;
}
return new ContainerConfiguration(
config.inheritParentResources ?? false,
config.defaultResolver ?? DefaultResolver.singleton,
);
}
}
/** @internal */
export const createContainer = (config?: Partial<IContainerConfiguration>): IContainer => new Container(null, ContainerConfiguration.from(config));
const getAnnotationParamtypes = (Type: Constructable | Injectable): readonly Key[] | undefined => {

@@ -252,3 +220,3 @@ const key = getAnnotationKeyFor('di:paramtypes');

// design:paramtypes is set by tsc when emitDecoratorMetadata is enabled.
const designParamtypes = DI.getDesignParamtypes(Type);
const designParamtypes = getDesignParamtypes(Type);
// au:annotation:di:paramtypes is set by the parameter decorator from DI.createInterface or by @inject

@@ -338,2 +306,41 @@ const annotationParamtypes = getAnnotationParamtypes(Type);

export const inject = (...dependencies: Key[]): (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number) => void => {
return (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number): void => {
if (typeof descriptor === 'number') { // It's a parameter decorator.
const annotationParamtypes = getOrCreateAnnotationParamTypes(target);
const dep = dependencies[0];
if (dep !== void 0) {
annotationParamtypes[descriptor] = dep;
}
} else if (key) { // It's a property decorator. Not supported by the container without plugins.
const annotationParamtypes = getOrCreateAnnotationParamTypes((target as unknown as { constructor: Injectable }).constructor);
const dep = dependencies[0];
if (dep !== void 0) {
annotationParamtypes[key as number] = dep;
}
} else if (descriptor) { // It's a function decorator (not a Class constructor)
const fn = descriptor.value;
const annotationParamtypes = getOrCreateAnnotationParamTypes(fn);
let dep: Key;
let i = 0;
for (; i < dependencies.length; ++i) {
dep = dependencies[i];
if (dep !== void 0) {
annotationParamtypes[i] = dep;
}
}
} else { // It's a class decorator.
const annotationParamtypes = getOrCreateAnnotationParamTypes(target);
let dep: Key;
let i = 0;
for (; i < dependencies.length; ++i) {
dep = dependencies[i];
if (dep !== void 0) {
annotationParamtypes[i] = dep;
}
}
}
};
};
export const DI = {

@@ -387,40 +394,3 @@ createContainer,

createInterface,
inject(...dependencies: Key[]): (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number) => void {
return (target: Injectable, key?: string | number, descriptor?: PropertyDescriptor | number): void => {
if (typeof descriptor === 'number') { // It's a parameter decorator.
const annotationParamtypes = getOrCreateAnnotationParamTypes(target);
const dep = dependencies[0];
if (dep !== void 0) {
annotationParamtypes[descriptor] = dep;
}
} else if (key) { // It's a property decorator. Not supported by the container without plugins.
const annotationParamtypes = getOrCreateAnnotationParamTypes((target as unknown as { constructor: Injectable }).constructor);
const dep = dependencies[0];
if (dep !== void 0) {
annotationParamtypes[key as number] = dep;
}
} else if (descriptor) { // It's a function decorator (not a Class constructor)
const fn = descriptor.value;
const annotationParamtypes = getOrCreateAnnotationParamTypes(fn);
let dep: Key;
let i = 0;
for (; i < dependencies.length; ++i) {
dep = dependencies[i];
if (dep !== void 0) {
annotationParamtypes[i] = dep;
}
}
} else { // It's a class decorator.
const annotationParamtypes = getOrCreateAnnotationParamTypes(target);
let dep: Key;
let i = 0;
for (; i < dependencies.length; ++i) {
dep = dependencies[i];
if (dep !== void 0) {
annotationParamtypes[i] = dep;
}
}
}
};
},
inject,
/**

@@ -446,3 +416,3 @@ * Registers the `target` class as a transient dependency; each time the dependency is resolved

target.register = function (container: IContainer): IResolver<InstanceType<T>> {
const registration = Registration.transient(target as T, target as T);
const registration = transientRegistation(target as T, target as T);
return registration.register(container, target);

@@ -473,3 +443,3 @@ };

target.register = function (container: IContainer): IResolver<InstanceType<T>> {
const registration = Registration.singleton(target, target);
const registration = singletonRegistration(target, target);
return registration.register(container, target);

@@ -485,26 +455,2 @@ };

export type ICallableResolver<T> = IResolver<T> & ((...args: unknown[]) => any);
/**
* ! Semi private API to avoid repetitive work creating resolvers.
*
* Naming isn't entirely correct, but it's good enough for internal usage.
*/
export function createResolver<T extends Key>(getter: (key: T, handler: IContainer, requestor: IContainer) => any): ((key: T) => ICallableResolver<T>) {
return function (key: any) {
function Resolver(target: any, property?: string | number, descriptor?: PropertyDescriptor | number): void {
inject(Resolver)(target, property, descriptor);
}
Resolver.$isResolver = true;
Resolver.resolve = function (handler: IContainer, requestor: IContainer): any {
return getter(key, handler, requestor);
};
return Resolver as ICallableResolver<T>;
};
}
export const inject = DI.inject;
function transientDecorator<T extends Constructable>(target: T & Partial<RegisterSelf<T>>):

@@ -582,205 +528,2 @@ T & RegisterSelf<T> {

/**
* Create a resolver that will resolve all values of a key from resolving container
*/
export const all = <T extends Key>(key: T, searchAncestors: boolean = false): IAllResolver<T> => {
function resolver(target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void {
inject(resolver)(target, property, descriptor);
}
resolver.$isResolver = true;
resolver.resolve = (handler: IContainer, requestor: IContainer) => requestor.getAll(key, searchAncestors);
return resolver as IAllResolver<T>;
};
export type IAllResolver<T> = IResolver<readonly Resolved<T>[]> & {
// type only hack
__isAll: undefined;
// any for decorator
(...args: unknown[]): any;
};
/**
* Lazily inject a dependency depending on whether the [[`Key`]] is present at the time of function call.
*
* You need to make your argument a function that returns the type, for example
* ```ts
* class Foo {
* constructor( @lazy('random') public random: () => number )
* }
* const foo = container.get(Foo); // instanceof Foo
* foo.random(); // throws
* ```
* would throw an exception because you haven't registered `'random'` before calling the method. This, would give you a
* new [['Math.random()']] number each time.
* ```ts
* class Foo {
* constructor( @lazy('random') public random: () => random )
* }
* container.register(Registration.callback('random', Math.random ));
* container.get(Foo).random(); // some random number
* container.get(Foo).random(); // another random number
* ```
* `@lazy` does not manage the lifecycle of the underlying key. If you want a singleton, you have to register as a
* `singleton`, `transient` would also behave as you would expect, providing you a new instance each time.
*
* - @param key [[`Key`]]
* see { @link DI.createInterface } on interactions with interfaces
*/
export const lazy = /*@__PURE__*/createResolver((key: Key, handler: IContainer, requestor: IContainer) => {
return () => requestor.get(key);
}) as <K extends Key>(key: K) => ILazyResolver<K>;
export type ILazyResolver<K extends Key = Key> = IResolver<() => K>
// type only hack
& { __isLazy: undefined }
// any is needed for decorator usages
& ((...args: unknown[]) => any);
export type IResolvedLazy<K> = () => Resolved<K>;
/**
* Allows you to optionally inject a dependency depending on whether the [[`Key`]] is present, for example
* ```ts
* class Foo {
* constructor( @inject('mystring') public str: string = 'somestring' )
* }
* container.get(Foo); // throws
* ```
* would fail
* ```ts
* class Foo {
* constructor( @optional('mystring') public str: string = 'somestring' )
* }
* container.get(Foo).str // somestring
* ```
* if you use it without a default it will inject `undefined`, so rember to mark your input type as
* possibly `undefined`!
*
* - @param key: [[`Key`]]
*
* see { @link DI.createInterface } on interactions with interfaces
*/
export const optional = /*@__PURE__*/createResolver((key: Key, handler: IContainer, requestor: IContainer) => {
if (requestor.has(key, true)) {
return requestor.get(key);
} else {
return undefined;
}
}) as <K extends Key>(key: K) => IOptionalResolver<K>;
export type IOptionalResolver<K extends Key = Key> = IResolver<K | undefined> & {
// type only hack
__isOptional: undefined;
// any is needed for decorator usages
(...args: unknown[]): any;
};
/**
* ignore tells the container not to try to inject a dependency
*/
export const ignore = (target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void => {
inject(ignore)(target, property, descriptor);
};
ignore.$isResolver = true;
ignore.resolve = () => undefined;
/**
* Inject a function that will return a resolved instance of the [[key]] given.
* Also supports passing extra parameters to the invocation of the resolved constructor of [[key]]
*
* For typings, it's a function that take 0 or more arguments and return an instance. Example:
* ```ts
* class Foo {
* constructor( @factory(MyService) public createService: (...args: unknown[]) => MyService)
* }
* const foo = container.get(Foo); // instanceof Foo
* const myService_1 = foo.createService('user service')
* const myService_2 = foo.createService('content service')
* ```
*
* ```ts
* class Foo {
* constructor( @factory('random') public createRandomizer: () => Randomizer)
* }
* container.get(Foo).createRandomizer(); // create a randomizer
* ```
* would throw an exception because you haven't registered `'random'` before calling the method. This, would give you a
* new instance of Randomizer each time.
*
* `@factory` does not manage the lifecycle of the underlying key. If you want a singleton, you have to register as a
* `singleton`, `transient` would also behave as you would expect, providing you a new instance each time.
*
* - @param key [[`Key`]]
* see { @link DI.createInterface } on interactions with interfaces
*/
export const factory = /*@__PURE__*/createResolver((key: any, handler: IContainer, requestor: IContainer) => {
return (...args: unknown[]) => handler.getFactory(key).construct(requestor, args);
}) as <K>(key: K) => IFactoryResolver<K>;
export type IFactoryResolver<K = any> = IResolver<K>
// type only hack
& { __isFactory: undefined }
// any is needed for decorator usage
& ((...args: unknown[]) => any);
export type IResolvedFactory<K> = (...args: unknown[]) => Resolved<K>;
/**
* Create a resolver that will resolve a new instance of a key, and register the newly created instance with the requestor container
*/
export const newInstanceForScope = /*@__PURE__*/createResolver(
(key: any, handler: IContainer, requestor: IContainer) => {
const instance = createNewInstance(key, handler, requestor);
const instanceProvider = new InstanceProvider<{}>(safeString(key), instance);
/**
* By default the new instances for scope are disposable.
* If need be, we can always enhance the `createNewInstance` to support a 'injection' context, to make a non/disposable registration here.
*/
requestor.registerResolver(key, instanceProvider, true);
return instance;
}) as <K>(key: K) => INewInstanceResolver<K>;
/**
* Create a resolver that will resolve a new instance of a key
*/
export const newInstanceOf = /*@__PURE__*/createResolver(
(key: any, handler: IContainer, requestor: IContainer) => createNewInstance(key, handler, requestor)
) as <K>(key: K) => INewInstanceResolver<K>;
export type INewInstanceResolver<T> = IResolver<T> & {
// type only hack
__newInstance: undefined;
// any is needed for decorator usage
(...args: unknown[]): any;
};
const createNewInstance = (key: any, handler: IContainer, requestor: IContainer) => {
// 1. if there's a factory registration for the key
if (handler.hasFactory(key)) {
return handler.getFactory(key).construct(requestor);
}
// 2. if key is an interface
if (isInterface(key)) {
const hasDefault = isFunction((key as unknown as IRegistry).register);
const resolver = handler.getResolver(key, false) as IResolver<Constructable<typeof key>>;
let factory: IFactory | null | undefined;
if (resolver == null) {
if (hasDefault) {
// creating a new container as we do not want to pollute the resolver registry
factory = (newInstanceContainer ??= createContainer()).getResolver(key, true)?.getFactory?.(handler);
}
newInstanceContainer.dispose();
} else {
factory = resolver.getFactory?.(handler);
}
// 2.1 and has resolvable factory
if (factory != null) {
return factory.construct(requestor);
}
// 2.2 cannot instantiate a dummy interface
throw createMappedError(ErrorNames.invalid_new_instance_on_interface, key);
}
// 3. jit factory, in case of newInstanceOf(SomeClass)
return handler.getFactory(key).construct(requestor);
};
let newInstanceContainer: IContainer;
_START_CONST_ENUM();

@@ -794,3 +537,3 @@ /** @internal */

array = 4,
alias = 5
alias = 5,
}

@@ -808,2 +551,7 @@ _END_CONST_ENUM();

public get $isResolver(): true { return true; }
/** @internal */
private _resolving: boolean = false;
public constructor(

@@ -819,6 +567,9 @@ key: Key,

public get $isResolver(): true { return true; }
/**
* When resolving a singleton, the internal state is changed,
* so cache the original constructable factory for future requests
* @internal
*/
private _cachedFactory: IFactory | null = null;
private resolving: boolean = false;
public register(container: IContainer, key?: Key): IResolver {

@@ -833,9 +584,9 @@ return container.registerResolver(key || this._key, this);

case ResolverStrategy.singleton: {
if (this.resolving) {
if (this._resolving) {
throw createMappedError(ErrorNames.cyclic_dependency, this._state.name);
}
this.resolving = true;
this._state = handler.getFactory(this._state as Constructable).construct(requestor);
this._resolving = true;
this._state = (this._cachedFactory = handler.getFactory(this._state as Constructable)).construct(requestor);
this._strategy = ResolverStrategy.instance;
this.resolving = false;
this._resolving = false;
return this._state;

@@ -869,2 +620,4 @@ }

return container.getResolver(this._state)?.getFactory?.(container) ?? null;
case ResolverStrategy.instance:
return this._cachedFactory;
default:

@@ -887,119 +640,6 @@ return null;

/**
* An implementation of IRegistry that delegates registration to a
* separately registered class. The ParameterizedRegistry facilitates the
* passing of parameters to the final registry.
*/
export class ParameterizedRegistry implements IRegistry {
public constructor(
private readonly key: Key,
private readonly params: unknown[]
) {}
public register(container: IContainer): void {
if (container.has(this.key, true)) {
const registry = container.get<IRegistry>(this.key);
registry.register(container, ...this.params);
} else {
container.register(...this.params.filter(x => typeof x === 'object'));
}
}
}
/**
* you can use the resulting {@linkcode IRegistration} of any of the factory methods
* to register with the container, e.g.
* ```
* class Foo {}
* const container = DI.createContainer();
* container.register(Registration.instance(Foo, new Foo()));
* container.get(Foo);
* ```
*/
export const Registration = {
/**
* allows you to pass an instance.
* Every time you request this {@linkcode Key} you will get this instance back.
* ```
* Registration.instance(Foo, new Foo()));
* ```
*
* @param key - key to register the instance with
* @param value - the instance associated with the key
*/
instance: instanceRegistration,
/**
* Creates an instance from the class.
* Every time you request this {@linkcode Key} you will get the same one back.
* ```
* Registration.singleton(Foo, Foo);
* ```
*
* @param key - key to register the singleton class with
* @param value - the singleton class to instantiate when a container resolves the associated key
*/
singleton: singletonRegistration,
/**
* Creates an instance from a class.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.instance(Foo, Foo);
* ```
*
* @param key - key to register the transient class with
* @param value - the class to instantiate when a container resolves the associated key
*/
transient: transientRegistation,
/**
* Creates an instance from the method passed.
* Every time you request this {@linkcode Key} you will get a new instance.
* ```
* Registration.callback(Foo, () => new Foo());
* Registration.callback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the callback with
* @param callback - the callback to invoke when a container resolves the associated key
*/
callback: callbackRegistration,
/**
* Creates an instance from the method passed.
* On the first request for the {@linkcode Key} your callback is called and returns an instance.
* subsequent requests for the {@linkcode Key}, the initial instance returned will be returned.
* If you pass the same {@linkcode Registration} to another container the same cached value will be used.
* Should all references to the resolver returned be removed, the cache will expire.
* ```
* Registration.cachedCallback(Foo, () => new Foo());
* Registration.cachedCallback(Bar, (c: IContainer) => new Bar(c.get(Foo)));
* ```
*
* @param key - key to register the cached callback with
* @param callback - the cache callback to invoke when a container resolves the associated key
*/
cachedCallback: cachedCallbackRegistration,
/**
* creates an alternate {@linkcode Key} to retrieve an instance by.
* Returns the same scope as the original {@linkcode Key}.
* ```
* Register.singleton(Foo, Foo)
* Register.aliasTo(Foo, MyFoos);
*
* container.getAll(MyFoos) // contains an instance of Foo
* ```
*
* @param originalKey - the real key to resolve the get call from a container
* @param aliasKey - the key that a container allows to resolve the real key associated
*/
aliasTo: aliasToRegistration,
/**
* @internal
* @param key - the key to register a defer registration
* @param params - the parameters that should be passed to the resolution of the key
*/
defer: deferRegistration,
};
export class InstanceProvider<K extends Key> implements IDisposableResolver<K | null> {
/** @internal */ private _instance: Resolved<K> | null = null;
/** @internal */ private _instance: Resolved<K> | null;
/** @internal */ private readonly _name?: string;
/** @internal */ private readonly _Type: Constructable | null;

@@ -1016,8 +656,8 @@ public get friendlyName() {

*/
instance?: Resolved<K> | null,
instance: Resolved<K> | null = null,
Type: Constructable | null = null,
) {
this._name = name;
if (instance !== void 0) {
this._instance = instance;
}
this._instance = instance;
this._Type = Type;
}

@@ -1038,2 +678,6 @@

public getFactory(container: IContainer): (K extends Constructable ? IFactory<K> : never) | null {
return this._Type == null ? null : container.getFactory(this._Type) as (K extends Constructable ? IFactory<K> : never) | null;
}
public dispose(): void {

@@ -1044,2 +688,21 @@ this._instance = null;

const isInterface = <K>(key: any): key is InterfaceSymbol<K> => isFunction(key) && key.$isInterface === true;
/**
* An implementation of IRegistry that delegates registration to a
* separately registered class. The ParameterizedRegistry facilitates the
* passing of parameters to the final registry.
*/
export class ParameterizedRegistry implements IRegistry {
public constructor(
private readonly key: Key,
private readonly params: unknown[]
) {}
public register(container: IContainer): void {
if (container.has(this.key, true)) {
const registry = container.get<IRegistry>(this.key);
registry.register(container, ...this.params);
} else {
container.register(...this.params.filter(x => typeof x === 'object'));
}
}
}

@@ -60,3 +60,3 @@ /* eslint-disable prefer-template */

[ErrorNames.first_defined_no_value]: `No defined value found when calling firstDefined()`,
[ErrorNames.invalid_module_transform_input]: `Invalid module transform input: {{0}}. Expected Promise or Object.`
[ErrorNames.invalid_module_transform_input]: `Invalid module transform input: {{0}}. Expected Promise or Object.`,
// [ErrorNames.module_loader_received_null]: `Module loader received null/undefined input. Expected Object.`,

@@ -81,1 +81,9 @@ };

}
/** @internal */
// eslint-disable-next-line
export const logError = (...args: unknown[]) => (globalThis as any).console.error(...args);
/** @internal */
// eslint-disable-next-line
export const logWarn = (...args: unknown[]) => (globalThis as any).console.warn(...args);
import { ErrorNames, createMappedError } from './errors';
import { Constructable, Overwrite } from './interfaces';
import { createObject } from './utilities';
import { createObject, objectAssign } from './utilities';
const isNumericLookup: Record<string, boolean> = {};
/**

@@ -17,29 +15,35 @@ * Efficiently determine whether the provided property key is numeric

*/
export const isArrayIndex = (value: unknown): value is number | string => {
switch (typeof value) {
case 'number':
return value >= 0 && (value | 0) === value;
case 'string': {
const result = isNumericLookup[value];
if (result !== void 0) {
return result;
}
const length = value.length;
if (length === 0) {
return isNumericLookup[value] = false;
}
let ch = 0;
let i = 0;
for (; i < length; ++i) {
ch = charCodeAt(value, i);
if (i === 0 && ch === 0x30 && length > 1 /* must not start with 0 */ || ch < 0x30 /* 0 */ || ch > 0x39/* 9 */) {
export const isArrayIndex = (() => {
const isNumericLookup: Record<string, boolean> = {};
let result: boolean | undefined = false;
let length = 0;
let ch = 0;
let i = 0;
return (value: unknown): value is number | string => {
switch (typeof value) {
case 'number':
return value >= 0 && (value | 0) === value;
case 'string':
result = isNumericLookup[value];
if (result !== void 0) {
return result;
}
length = value.length;
if (length === 0) {
return isNumericLookup[value] = false;
}
}
return isNumericLookup[value] = true;
ch = 0;
i = 0;
for (; i < length; ++i) {
ch = charCodeAt(value, i);
if (i === 0 && ch === 0x30 && length > 1 /* must not start with 0 */ || ch < 0x30 /* 0 */ || ch > 0x39/* 9 */) {
return isNumericLookup[value] = false;
}
}
return isNumericLookup[value] = true;
default:
return false;
}
default:
return false;
}
};
};
})();

@@ -60,3 +64,3 @@ /**

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const isDigit = Object.assign(createObject(), {
const isDigit = objectAssign(createObject(), {
'0': true,

@@ -371,4 +375,5 @@ '1': true,

): Readonly<T1 & T2 & T3 & T4 & T5>;
/** @internal */
export function toLookup(...objs: {}[]): Readonly<{}> {
return Object.assign(createObject(), ...objs);
return objectAssign(createObject(), ...objs);
}

@@ -418,5 +423,4 @@

charCodeAt(sourceText, i - 14) === 0x6E && // n
charCodeAt(sourceText, i - 15) === 0x58 // [
charCodeAt(sourceText, i - 15) === 0x5B // [
);
lookup.set(fn, isNative);

@@ -423,0 +427,0 @@ }

@@ -6,10 +6,2 @@ export {

export {
createResolver,
all,
factory,
type IAllResolver,
type IFactoryResolver,
type IOptionalResolver,
type IResolvedFactory,
type INewInstanceResolver,
DI,

@@ -24,9 +16,3 @@ IContainer,

type Key,
lazy,
type ILazyResolver,
type IResolvedLazy,
optional,
ignore,
type RegisterSelf,
Registration,
type ResolveCallback,

@@ -41,6 +27,2 @@ singleton,

type Transformer,
newInstanceForScope,
newInstanceOf,
ContainerConfiguration,
DefaultResolver,
type IContainerConfiguration,

@@ -52,5 +34,35 @@ } from './di';

type IResolvedInjection,
Registrable,
ContainerConfiguration,
DefaultResolver,
} from './di.container';
export {
Registration,
} from './di.registration';
export {
createResolver,
all,
factory,
type IAllResolver,
type IFactoryResolver,
type IOptionalResolver,
type IResolvedFactory,
type INewInstanceResolver,
lazy,
type ILazyResolver,
type IResolvedLazy,
optional,
ignore,
newInstanceForScope,
newInstanceOf,
type ICallableResolver,
allResources,
optionalResource,
own,
resource,
} from './di.resolvers';
export {
type Class,

@@ -90,2 +102,3 @@ type Constructable,

ModuleItem,
aliasedResourcesRegistry,
} from './module-loader';

@@ -100,2 +113,4 @@

export {
resourceBaseName,
getResourceKeyFor,
type IResourceKind,

@@ -102,0 +117,0 @@ type PartialResourceDefinition,

import { Metadata } from '@aurelia/metadata';
import { all, createInterface, IContainer, IRegistry, optional } from './di';
import { createInterface, IContainer, IRegistry } from './di';
import { instanceRegistration, singletonRegistration } from './di.registration';

@@ -10,2 +10,3 @@ import { bound, toLookup } from './functions';

import { resolve } from './di.container';
import { all, optional } from './di.resolvers';

@@ -12,0 +13,0 @@ /** @internal */ export const trace = 0;

import { createInterface } from './di';
import { emptyArray } from './platform';
import { getAllResources } from './resource';
import { isFunction } from './utilities';
import { resourceBaseName } from './resource';
import { getOwnMetadata, isFunction } from './utilities';
import { ErrorNames, createMappedError } from './errors';

@@ -9,3 +9,2 @@ import type { IRegistry } from './di';

import type { ResourceDefinition } from './resource';
import { ErrorNames, createMappedError } from './errors';

@@ -86,3 +85,3 @@ export interface IModule {

let isConstructable: boolean;
let definitions: readonly ResourceDefinition[];
let definition: ResourceDefinition | null;
const items: ModuleItem[] = [];

@@ -98,3 +97,3 @@

isConstructable = false;
definitions = emptyArray;
definition = null;
break;

@@ -104,3 +103,3 @@ case 'function':

isConstructable = (value as Constructable).prototype !== void 0;
definitions = getAllResources(value as Constructable);
definition = getOwnMetadata(resourceBaseName, value) ?? null;
break;

@@ -116,3 +115,3 @@ default:

isConstructable,
definitions,
definition,
));

@@ -205,3 +204,3 @@ }

readonly isConstructable: TisConstructable;
readonly definitions: readonly ResourceDefinition[];
readonly definition: ResourceDefinition | null;
}

@@ -224,4 +223,92 @@ export interface ITypedModuleItem_Unknown extends ITypedModuleItem<false, false, unknown> {}

public readonly isConstructable: boolean,
public readonly definitions: readonly ResourceDefinition[],
public readonly definition: ResourceDefinition | null,
) {}
}
/**
* Iterate through the exports of a module and register aliases for resources respectively
*/
export const aliasedResourcesRegistry = (mod: IModule, mainKeyAlias: string | null | undefined, aliases: Record<string, string> = {}): IRegistry => {
return {
register(container) {
const analyzedModule = container.get(IModuleLoader).load(mod);
let mainAliasRegistered = false;
analyzedModule.items.forEach((item) => {
const definition = item.definition;
if (definition == null) {
container.register(item.value);
return;
}
if (!mainAliasRegistered && mainKeyAlias != null) {
mainAliasRegistered = true;
definition.register(container, mainKeyAlias);
return;
}
// cannot use item.key, since it could contain an uppercase letter
// while if import as is used in html, then it'll be lowercase letters only
// using definition name, however, comes with an issue, which is that it's not guaranteed to be unique
//
// for example: a module can export both an element and an attribute with the name "foo"
// but if that's the case, devs can always split the exports into two modules
const alias = aliases[definition.name];
definition.register(container, alias);
});
},
};
};
// or extract the registry part into a class?
//
// class AliasModuleKeysRegistry implements IRegistry {
// /** @internal */ private readonly _mod: IModule;
// /** @internal */ private readonly _mainKeyAlias: string | null;
// /** @internal */ private readonly _otherAliases: Record<string, string>;
// public constructor(
// mod: IModule,
// mainKeyAlias: string | null,
// aliases: Record<string, string>,
// ) {
// this._mod = mod;
// this._mainKeyAlias = mainKeyAlias;
// this._otherAliases = aliases;
// }
// /** @internal */
// private _getAliasedKeyForName(key: string, name: string): string {
// // replace the part after the last : with the name
// const parts = key.split(':');
// parts[parts.length - 1] = name;
// return parts.join(':');
// }
// public register(container: IContainer) {
// const analyzedModule = container.get(IModuleLoader).load(this._mod);
// let mainAliasRegistered = false;
// analyzedModule.items.forEach((item) => {
// const definition = item.definition;
// if (definition == null) {
// container.register(item.value);
// return;
// }
// if (!mainAliasRegistered && this._mainKeyAlias != null) {
// mainAliasRegistered = true;
// aliasToRegistration(definition.key, this._mainKeyAlias).register(container);
// return;
// }
// for (const aliasedExport in this._otherAliases) {
// const aliasName = this._otherAliases[aliasedExport];
// const aliasKey = this._getAliasedKeyForName(definition.key, aliasName);
// if (item.key === aliasedExport) {
// aliasToRegistration(definition.key, aliasKey).register(container);
// }
// }
// });
// }
// }
import { IContainer } from './di';
import { Constructable } from './interfaces';
import { emptyArray } from './platform';
import { defineMetadata, hasOwnMetadata, getOwnMetadata, objectFreeze } from './utilities';
import { defineMetadata, getOwnMetadata, objectFreeze } from './utilities';

@@ -25,2 +24,9 @@ export type ResourceType<

> = {
/**
* Unique key to identify the resource.
*/
readonly key: string;
/**
* A common name for the resource.
*/
readonly name: string;

@@ -30,3 +36,6 @@ readonly Type: ResourceType<TUserType, TResInstance, TResType, TUserInstance>;

register(container: IContainer): void;
/**
* @param aliasName - If provided, the resource will be registered with this alias key.
*/
register(container: IContainer, aliasName?: string): void;
} & TDef;

@@ -63,2 +72,3 @@

};
const annotation = /*@__PURE__*/ objectFreeze({

@@ -82,46 +92,19 @@ name: 'au:annotation',

const resBaseName = 'au:resource';
export const hasResources = (target: unknown): target is Constructable => hasOwnMetadata(resBaseName, target);
/** @internal */
export const getAllResources = (target: Constructable): readonly ResourceDefinition[] => {
const keys = getOwnMetadata(resBaseName, target) as string[];
if (keys === void 0) {
return emptyArray;
} else {
return keys.map(k => getOwnMetadata(k, target));
export const resourceBaseName = 'au:resource';
/**
* Builds a resource key from the provided parts.
*/
export const getResourceKeyFor = (type: string, name?: string, context?: string): string => {
if (name == null) {
return `${resourceBaseName}:${type}`;
}
if (context == null) {
return `${resourceBaseName}:${type}:${name}`;
}
return `${resourceBaseName}:${type}:${name}:${context}`;
};
const resource = /*@__PURE__*/ objectFreeze({
name: resBaseName,
appendTo(target: Constructable, key: string): void {
const keys = getOwnMetadata(resBaseName, target) as string[];
if (keys === void 0) {
defineMetadata(resBaseName, [key], target);
} else {
keys.push(key);
}
},
has: hasResources,
getAll: getAllResources,
getKeys(target: Constructable): readonly string[] {
let keys = getOwnMetadata(resBaseName, target) as string[];
if (keys === void 0) {
defineMetadata(resBaseName, keys = [], target);
}
return keys;
},
isKey: (key: string): boolean => key.startsWith(resBaseName),
keyFor(name: string, context?: string): string {
if (context === void 0) {
return `${resBaseName}:${name}`;
}
return `${resBaseName}:${name}:${context}`;
},
});
export const Protocol = {
annotation,
resource,
};

@@ -128,0 +111,0 @@

import { Metadata } from '@aurelia/metadata';
/** @internal */ export const objectFreeze = Object.freeze;
/** @internal */ export const objectAssign = Object.assign;
/** @internal */ export const safeString = String;

@@ -5,0 +6,0 @@ /** @internal */ export const getOwnMetadata = Metadata.getOwn;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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