opinionated-machine
Version:
Very opinionated DI framework for fastify, built on top of awilix
124 lines (123 loc) • 5.59 kB
TypeScript
import type { AwilixContainer, NameAndRegistrationPair } from 'awilix';
import { AwilixManager } from 'awilix-manager';
import type { FastifyInstance } from 'fastify';
import type { AbstractModule } from './AbstractModule.js';
import { type NestedPartial } from './configUtils.js';
import type { ENABLE_ALL } from './diConfigUtils.js';
import { type BuildGatewayManifestOptions, type GatewayManifest } from './gateway/index.js';
import { type RegisterDualModeRoutesOptions, type RegisterSSERoutesOptions } from './routes/index.js';
export type RegisterDependenciesParams<Dependencies, Config, ExternalDependencies> = {
modules: readonly AbstractModule<unknown, ExternalDependencies>[];
secondaryModules?: readonly AbstractModule<unknown, ExternalDependencies>[];
dependencyOverrides?: NameAndRegistrationPair<Dependencies>;
configOverrides?: NestedPartial<Config>;
configDependencyId?: string;
};
export type DependencyInjectionOptions = {
jobQueuesEnabled?: false | typeof ENABLE_ALL | string[];
enqueuedJobWorkersEnabled?: false | typeof ENABLE_ALL | string[];
messageQueueConsumersEnabled?: false | typeof ENABLE_ALL | string[];
periodicJobsEnabled?: false | typeof ENABLE_ALL | string[];
/**
* Enable SSE test mode features like connection spying.
* Only relevant for SSE controllers. Set to true in test environments.
* @default false
*/
isTestMode?: boolean;
};
export declare class DIContext<Dependencies extends object, Config extends object, ExternalDependencies = undefined> {
private readonly options;
readonly awilixManager: AwilixManager;
readonly diContainer: AwilixContainer<Dependencies>;
private readonly controllerResolvers;
private readonly sseControllerNames;
private readonly dualModeControllerNames;
private readonly apiControllerNames;
private readonly appConfig;
constructor(diContainer: AwilixContainer<Dependencies>, options: DependencyInjectionOptions, appConfig: Config, awilixManager?: AwilixManager);
private registerControllers;
private registerModule;
registerDependencies(params: RegisterDependenciesParams<Dependencies, Config, ExternalDependencies>, externalDependencies: ExternalDependencies, resolveControllers?: boolean): void;
registerRoutes(app: FastifyInstance<any, any, any, any>): void;
/**
* Build a vendor-neutral gateway manifest from all registered REST and
* api-contract controllers. Routes carrying gateway metadata (attached via
* `withGatewayMetadata()`) get that metadata merged with controller-level
* `gatewayDefaults` and the `defaults` passed here. Routes without any
* metadata still appear in the manifest with empty metadata.
*
* The returned object is JSON-serializable; pass it to a generator package
* like `@opinionated-machine/gateway-envoy` or
* `@opinionated-machine/gateway-krakend` to produce a config.
*
* SSE and dual-mode controllers are not included in v1.
*
* @example
* ```ts
* const manifest = context.buildGatewayManifest({
* service: 'users-api',
* defaults: { cors: { origins: ['https://app.example.com'] } },
* })
* const envoy = renderEnvoyConfig(manifest, { listenPort: 8080, clusters: { 'users-service': { hosts: ['users:8081'] } } })
* writeFileSync('envoy.yaml', envoy.yaml)
* ```
*/
buildGatewayManifest(options: BuildGatewayManifestOptions): GatewayManifest;
/**
* Check if any SSE controllers are registered.
* Use this to conditionally call registerSSERoutes().
*/
hasSSEControllers(): boolean;
/**
* Check if any dual-mode controllers are registered.
* Use this to conditionally call registerDualModeRoutes().
*/
hasDualModeControllers(): boolean;
/**
* Register SSE routes with the Fastify app.
*
* Must be called separately from registerRoutes().
* Requires @fastify/sse plugin to be registered on the app.
*
* @param app - Fastify instance with @fastify/sse registered
* @param options - Optional configuration for SSE routes
*
* @example
* ```typescript
* // Register @fastify/sse plugin first
* await app.register(fastifySSE, { heartbeatInterval: 30000 })
*
* // Then register SSE routes
* context.registerSSERoutes(app)
* ```
*/
registerSSERoutes(app: FastifyInstance<any, any, any, any>, options?: RegisterSSERoutesOptions): void;
/**
* Register dual-mode routes with the Fastify app.
*
* Dual-mode routes handle both SSE streaming and JSON responses on the
* same path, automatically branching based on the `Accept` header.
*
* Must be called separately from registerRoutes() and registerSSERoutes().
* Requires @fastify/sse plugin to be registered on the app.
*
* @param app - Fastify instance with @fastify/sse registered
* @param options - Optional configuration for dual-mode routes
*
* @example
* ```typescript
* // Register @fastify/sse plugin first
* await app.register(fastifySSE, { heartbeatInterval: 30000 })
*
* // Then register dual-mode routes
* context.registerDualModeRoutes(app)
* ```
*/
registerDualModeRoutes(app: FastifyInstance<any, any, any, any>, options?: RegisterDualModeRoutesOptions): void;
private applyDualModeRouteOptions;
private applySSERouteOptions;
private applyPreHandlers;
private applyRateLimit;
destroy(): Promise<void>;
init(): Promise<void>;
}