Reference for exported TypeScript types and interfaces in assemblerjs.
Interface that marks classes as injectable assemblages.
interface AbstractAssemblage {
onInit?(context: AssemblerContext, configuration: Record<string, any>): void | Promise<void>;
onDispose?(context: AssemblerContext, configuration: Record<string, any>): void | Promise<void>;
}Usage:
@Assemblage()
class MyService implements AbstractAssemblage {
onInit() {
// Optional initialization
}
onDispose() {
// Optional cleanup
}
}Interface for transversal (aspect) classes that provide cross-cutting concerns.
interface AbstractTransversal {
onInit?(context: AssemblerContext, configuration: Record<string, any>): void | Promise<void>;
onDispose?(context: AssemblerContext, configuration: Record<string, any>): void | Promise<void>;
static onRegister?(context: AssemblerContext, configuration?: Record<string, any>): void;
}Usage:
@Transversal()
class LoggingTransversal implements AbstractTransversal {
onInit() {
console.log('Transversal initialized');
}
@Before('execution(*.*)')
logMethodCall(context: AdviceContext) {
console.log('Method called:', context.methodName);
}
}Configuration interface for the @Assemblage decorator.
interface AssemblageDefinition {
singleton?: boolean; // Default: true
inject?: InjectDefinition[]; // Dependencies
use?: UseDefinition[]; // Objects to register
engage?: TransversalInjection[]; // Transversals to apply
tags?: string[]; // Tags for grouping
events?: string[]; // Event channels
metadata?: Record<string, any>; // Custom metadata
global?: Record<string, any>; // Global values
}Usage:
@Assemblage({
singleton: true,
inject: [[DatabaseService]],
engage: [[LoggingTransversal], [SecurityTransversal]],
tags: ['service'],
metadata: { version: '1.0' },
})
class MyService implements AbstractAssemblage {}Type for dependency injection definitions.
type InjectDefinition =
| [Identifier] // Simple injection
| [Identifier, Identifier] // Interface binding
| [Identifier, Record<string, any>] // With configuration
| [Identifier, Identifier, Record<string, any>]; // Interface + configExamples:
// Simple injection
[DatabaseService]
// Interface binding
[AbstractLogger, ConsoleLogger]
// With configuration
[DatabaseService, { host: 'localhost' }]
// Interface binding + configuration
[AbstractLogger, ConsoleLogger, { level: 'debug' }]Type for transversal (aspect) injection definitions.
type TransversalInjection<T = any> =
| [Identifier<T>] // Simple transversal
| [Identifier<T>, Record<string, any>] // Transversal with config
| [Identifier<T>, Identifier<T>] // Abstract binding
| [Identifier<T>, Identifier<T>, Record<string, any>]; // Abstract + configExamples:
// Simple transversal injection
[LoggingTransversal]
// With configuration
[PerformanceTransversal, { threshold: 100 }]
// Abstract binding
[AbstractLoggingTransversal, ConsoleLoggingTransversal]
// Abstract binding + configuration
[AbstractLoggingTransversal, ConsoleLoggingTransversal, { level: 'debug' }]Usage in engage:
@Assemblage({
inject: [[UserService]],
engage: [
[LoggingTransversal],
[SecurityTransversal, { requireAuth: true }]
]
})
class App implements AbstractAssemblage {}
### UseDefinition
Type for object registration with `use`.
```typescript
type UseDefinition = [string, any];Example:
@Assemblage({
use: [
['apiClient', new ApiClient()],
['config', { host: 'localhost' }],
],
})
class MyService implements AbstractAssemblage {}Type for custom class decorator callback functions.
type ConstructorDecoratorCallback<TInstance, TDefinition> =
(this: TInstance, definition?: TDefinition) => void;Usage:
const MyDecorator = createConstructorDecorator<MyClass, MyConfig>(
function(config) {
// `this` is typed as MyClass
// `config` is typed as MyConfig | undefined
}
);Type for the decorator function itself.
type ConstructorDecoratorFunction<TDefinition> =
(definition?: TDefinition) => ClassDecorator;Type for decorator factory return value.
type DecoratorFactory<TDefinition> =
ConstructorDecoratorFunction<TDefinition>;Type for dependency identifiers.
type Identifier<T = any> = Function | string | symbol;Examples:
// Class identifier
const id: Identifier = DatabaseService;
// String identifier
const id: Identifier = 'apiClient';
// Symbol identifier
const id: Identifier = Symbol('service');Interface for the DI container context.
interface AssemblerContext {
has(identifier: Identifier): boolean;
require<T>(identifier: Identifier<T>): T;
tagged(...tags: string[]): any[];
global<T = any>(identifier: string): T;
global<T = any>(identifier: string, value: T): void;
on(channel: string, callback: Listener): AssemblerContext;
once(channel: string, callback: Listener): AssemblerContext;
off(channel: string, callback?: Listener): AssemblerContext;
identifiers: Identifier[];
entryAssemblage: any;
}See AssemblerContext API for method details.
Type for event listeners.
type Listener = (...args: any[]) => void | Promise<void>;Example:
const listener: Listener = (data) => {
console.log('Event:', data);
};
context.on('event', listener);Type for advice execution timing.
type AdviceType = 'before' | 'after' | 'around';Usage:
const type: AdviceType = 'before';Information about the point of execution where an advice is applied.
interface JoinPoint {
target: any; // The target instance
methodName: string; // The name of the method being called
args: any[]; // The arguments passed to the method
result?: any; // The result of the method (for after advice)
error?: any; // The error thrown by the method (if any)
caller?: string; // Class name of the caller (if tracked)
callerIdentifier?: string | symbol; // Optional unique identifier for the caller
}Caller Properties:
caller- The name of the class or component that initiated the method call. Populated automatically for DI-managed calls, or set viaTransversalWeaver.withCaller()for external callers.callerIdentifier- Optional identifier (typically a Symbol or UUID) to uniquely identify the caller. Useful for request tracing and correlation IDs.
Usage:
function logJoinPoint(joinPoint: JoinPoint) {
console.log('Method:', joinPoint.methodName);
console.log('Args:', joinPoint.args);
console.log('Result:', joinPoint.result);
// Caller tracking
if (joinPoint.caller) {
console.log('Called by:', joinPoint.caller);
if (joinPoint.callerIdentifier) {
console.log('Caller ID:', joinPoint.callerIdentifier);
}
}
}Extended join point with control flow for advices.
interface AdviceContext extends JoinPoint {
proceed?(): any | Promise<any>; // Continue to next advice or original method
config?: Record<string, any>; // Optional config from @Affect decorator
caller?: string; // Class name of the caller (inherited from JoinPoint)
callerIdentifier?: string | symbol; // Caller ID (inherited from JoinPoint)
}Usage:
@Transversal()
class MyTransversal {
@Around('execution(*.*)')
async intercept(context: AdviceContext) {
console.log('Before:', context.methodName);
if (context.caller) {
console.log('Caller:', context.caller);
}
// Call next advice or original method
const result = await context.proceed!();
console.log('After:', result);
return result;
}
@Before('execution(*.delete)')
checkAuthority(context: AdviceContext) {
// Use caller information for authorization
if (context.caller && !this.canDelete(context.caller)) {
throw new Error(`${context.caller} not authorized to delete`);
}
}
}Definition of a single advice to be applied.
interface Advice {
type: AdviceType; // 'before' | 'after' | 'around'
pointcut: string; // Pointcut expression
method: Function; // The advice method to execute
transversalInstance: any; // The transversal instance that owns this advice
priority: number; // Execution priority (higher first)
enabled: boolean; // Whether this advice is enabled
role?: string; // Optional role identifier
config?: Record<string, any>; // Optional config from @Affect
}Usage:
const advice: Advice = {
type: 'before',
pointcut: 'execution(UserService.*)',
method: myTransversal.logBefore,
transversalInstance: myTransversal,
priority: 100,
enabled: true
};Metadata about a registered transversal.
interface TransversalMetadata {
definition: any; // The assemblage definition
advices: Advice[]; // The advices defined in this transversal
instance?: any; // The transversal instance
}Configuration for explicit transversal application via @Affect.
interface AffectedMethodConfig {
transversal: Identifier<any>; // The transversal class to apply
role?: string; // Optional role filter
config?: Record<string, any>; // Optional configuration
}Usage:
// Applied by @Affect decorator
@Affect(LoggingTransversal, { level: 'debug' })
methodName() { }
// Equivalent configuration:
const config: AffectedMethodConfig = {
transversal: LoggingTransversal,
config: { level: 'debug' }
};Interface for custom parameter decorator resolvers.
interface ParameterResolver {
resolve(value: any, context: AssemblerContext): any | Promise<any>;
}Usage:
class MyResolver implements ParameterResolver {
resolve(value: string, context: AssemblerContext): MyService {
return new MyService(value);
}
}Configuration for ParameterDecoratorFactory.create().
interface ParameterDecoratorOptions<T> {
name: string; // Unique name
valueType: 'single' | 'array' | 'map'; // How values are stored
resolver: ParameterResolver; // Resolver class
}Usage:
const MyDecorator = ParameterDecoratorFactory.create<string>({
name: 'MyDecorator',
valueType: 'single',
resolver: MyResolver,
});Base class for event emitting assemblages.
class EventManager {
addChannels(...channels: string[]): EventManager;
removeChannels(...channels: string[]): EventManager;
on(channel: string, callback: Listener): EventManager;
once(channel: string, callback: Listener): EventManager;
off(channel: string, callback?: Listener): EventManager;
emit(channel: string, ...args: any[]): EventManager;
dispose(): void;
}Usage:
@Assemblage({ events: ['app:event'] })
class MyService
extends EventManager
implements AbstractAssemblage
{
constructor() {
super('app:event');
}
}Use generics for type-safe dependency resolution:
// Type-safe
const service = context.require<DatabaseService>(DatabaseService);
// service is typed as DatabaseService
// Less specific
const service2 = context.require(DatabaseService);
// service2 is typed as anyUse generics for type-safe global values:
// Type-safe
const apiKey = context.global<string>('apiKey');
// apiKey is typed as string
// Less specific
const value = context.global('apiKey');
// value is typed as anyMake configuration properties optional:
interface MyConfig {
host: string;
port: number;
ssl: boolean;
}
type PartialConfig = Partial<MyConfig>;
@Assemblage()
class MyService implements AbstractAssemblage {
constructor(@Configuration() config: PartialConfig) {
// All properties are optional
}
}Ensure all properties are present:
type RequiredConfig = Required<MyConfig>;
@Assemblage()
class MyService implements AbstractAssemblage {
constructor(@Configuration() config: RequiredConfig) {
// All properties are required
}
}// Core types
import {
AbstractAssemblage,
AbstractTransversal,
AssemblageDefinition,
InjectDefinition,
TransversalInjection,
UseDefinition,
} from 'assemblerjs';
// Context types
import {
AssemblerContext,
Identifier,
Listener,
} from 'assemblerjs';
// AOP types
import {
AdviceType,
JoinPoint,
AdviceContext,
Advice,
TransversalMetadata,
AffectedMethodConfig,
} from 'assemblerjs';
// Decorator types
import {
ConstructorDecoratorCallback,
ConstructorDecoratorFunction,
DecoratorFactory,
} from 'assemblerjs';
// Parameter decorator types
import {
ParameterResolver,
ParameterDecoratorOptions,
} from 'assemblerjs';
// Event types
import { EventManager } from 'assemblerjs';
// Debug types
import { AssemblerDebugOptions } from 'assemblerjs';Configuration interface for the debug logging system.
interface AssemblerDebugOptions {
enabled?: boolean;
logger?: (level: 'info' | 'warn' | 'error', message: string, data?: any) => void;
logPhases?: {
registration?: boolean;
resolution?: boolean;
construction?: boolean;
hooks?: boolean;
cache?: boolean;
};
logTimings?: boolean;
logDependencyTree?: boolean;
useColors?: boolean;
}Properties:
enabled- Enable/disable debug logging (default:true)logger- Custom logging function (default: usesconsole.log)logPhases- Filter which build phases to log (default: alltrue)logTimings- Include execution time for operations (default:false)logDependencyTree- Log dependency tree visualization (default:true)useColors- Use ANSI color codes in output (default:true)
Usage:
Assembler.enableDebug({
logTimings: true,
useColors: false,
logPhases: {
registration: true,
hooks: true,
},
});See Debug Logging for complete documentation.
- Assembler API - Container methods
- AssemblerContext API - Context interface
- Transversals (AOP) - Aspect-oriented programming
- AOP Decorators - @Transversal, @Before, @After, @Around, @Affect
- Custom Class Decorators - Use decorator types
- Custom Parameter Decorators - Create resolvers