Isolates tenants by stamping a tenant column on every row.
-
getTenantColumn(): string
Return the column name used to stamp tenant ids on rows.
- kind: "column"
Isolates tenants by assigning each a separate database.
- kind: "database"
-
resolveDatabase(tenantId: string): string
Derive the database name for a tenant id.
Resolves the tenant id from an HTTP header.
-
resolve(request: IRequest): Promise<Option<ITenant>>
Resolve the tenant id from the configured request header.
& { decode: (token: string) => Record<string, unknown> | null; }
Resolves the tenant id from a claim in an unverified JWT payload.
-
resolve(request: IRequest): Promise<Option<ITenant>>
Resolve the tenant id from the configured JWT claim.
A zero-dependency in-memory ITenantDataStore that partitions rows by
strategy-derived scope ('column' → tenantId, 'schema' → resolved schema,
'database' → resolved database).
-
close(): Promise<void>
Gracefully close any connections.
-
create<E>(): Promise<E>tenantId: string,entity: string,data: Readonly<Record<string, unknown>>
Create a new record; returns the stored entity including its id.
-
delete<Id>(): Promise<boolean>tenantId: string,entity: string,id: Id
Delete a record. Returns
trueif a record was deleted. -
find<E>(): Promise<readonly E[]>tenantId: string,entity: string,filter: Readonly<Record<string, unknown>>
Find records matching a filter.
-
findAll<E>(): Promise<readonly E[]>tenantId: string,entity: string
Retrieve all records of an entity for a tenant.
-
findById<E, Id>(): Promise<E | null>tenantId: string,entity: string,id: Id
Find a single record by its identifier.
-
update<E, Id>(): Promise<E | null>tenantId: string,entity: string,id: Id,data: Readonly<Record<string, unknown>>
Update an existing record; returns
nullwhen the id is unknown. -
useIsolation(strategy: ITenantIsolationStrategy): void
Receive the isolation strategy from the plugin's
register().
Resolves the tenant id from a segment of request.path.
-
resolve(request: IRequest): Promise<Option<ITenant>>
Resolve the tenant id from a segment of
request.path.
Isolates tenants by assigning each a separate database schema.
- kind: "schema"
-
resolveSchema(tenantId: string): string
Derive the schema name for a tenant id.
Resolves the tenant id from the first subdomain label of request.url.
-
resolve(request: IRequest): Promise<Option<ITenant>>
Resolve the tenant id from the request's subdomain.
Thrown by IMultiTenancyService.getRepository when no tenant
is resolved in the request context.
Exported accessor that reads the cache-prefix stamped into ctx.state by
the middleware. Consumers never hardcode the state key string.
Multi-tenancy plugin factory.
Factory that creates a middleware function resolving the tenant and attaching
it to ctx.request.tenant.
Options for HeaderResolver.
-
name: string
HTTP header name to read (default
'x-tenant-id').
Multi-tenancy service — exposes tenant context, repository creation, and cache-key helpers.
-
getCurrentTenant(ctx: IRequestContext): ITenant | undefined
Return the tenant resolved for this request context, or
undefined. -
getRepository<Entity, Id = string>(): ITenantRepository<Entity, Id>ctx: IRequestContext,entity: string
Create a tenant-scoped repository for the given entity type. Throws
TenantNotResolvedErrorif no tenant is resolved. -
getRepositoryFor<Entity, Id = string>(): ITenantRepository<Entity, Id>tenantId: string,entity: string
Create a tenant-scoped repository for the given entity type, scoped to the tenant id GIVEN — no
IRequestContextrequired. This is the entry point for non-HTTP work (an ingress behaviour, a queue processor, a scheduled job), where no request exists to resolve a tenant from; the caller reads the tenant id from the work item's own payload. Modelled onprefixCacheKey— this interface's other ctx-free, id-taking member. -
prefixCacheKey(): stringtenantId: string,key: string
Build a cache key that includes the tenant id, joined by the separator the plugin was configured with (
cache.separator, default':'). The separator is deliberately NOT a per-call argument: this method is the single home for separator resolution, so the middleware'sctx.stateprefix and a caller's key can never disagree.
A resolved tenant.
-
id: string
Stable tenant identifier.
-
metadata: Readonly<Record<string, unknown>>
Tenant-specific configuration.
-
name: string
Display name.
Tenant-scoped data-store port.
-
close(): Promise<void>
Gracefully close any connections.
-
create<E>(): Promise<E>tenantId: string,entity: string,data: Readonly<Record<string, unknown>>
Create a new record; returns the stored entity including its id.
-
delete<Id>(): Promise<boolean>tenantId: string,entity: string,id: Id
Delete a record. Returns
trueif a record was deleted. -
find<E>(): Promise<readonly E[]>tenantId: string,entity: string,filter: Readonly<Record<string, unknown>>
Find records matching a filter.
-
findAll<E>(): Promise<readonly E[]>tenantId: string,entity: string
Retrieve all records of an entity for a tenant.
-
findById<E, Id>(): Promise<E | null>tenantId: string,entity: string,id: Id
Find a single record by its identifier.
-
update<E, Id>(): Promise<E | null>tenantId: string,entity: string,id: Id,data: Readonly<Record<string, unknown>>
Update an existing record; returns
nullwhen the id is unknown. -
useIsolation(strategy: ITenantIsolationStrategy): void
Receives the resolved isolation strategy once, during
register(). Optional so a store may ignore isolation metadata entirely.
Tenant-scoped repository — delegates CRUD to the data store the
multi-tenancy plugin was configured with (ITenantDataStore, declared in
that plugin), while threading the resolved tenant id.
-
create(data: Readonly<Record<string, unknown>>): Promise<Entity>
Create a new record.
-
delete(id: Id): Promise<boolean>
Delete a record by its identifier. Returns
trueif a record was deleted. -
find(filter: Readonly<Record<string, unknown>>): Promise<readonly Entity[]>
Find records matching a filter.
-
findAll(): Promise<readonly Entity[]>
Retrieve all records.
-
findById(id: Id): Promise<Entity | null>
Find a single record by its identifier.
-
update(): Promise<Entity | null>id: Id,data: Readonly<Record<string, unknown>>
Update an existing record by its identifier.
Resolves the tenant for an incoming request (by subdomain, header, path, or JWT claim, depending on the implementation).
-
resolve(request: IRequest): Promise<Option<ITenant>>
Resolves the request's tenant.
Options for JwtResolver.
-
claim: string
JWT claim name that holds the tenant id (default
'tenant_id'). -
decode: (token: string) => Record<string, unknown> | null
Custom JWT-decode function. When absent the plugin resolves
IJwtService.decodefrom the capability token inregister(). -
headerName: string
Authorization header name (default
'authorization').
Options passed to the MemoryTenantDataStore constructor.
-
generateId: () => string
Generate a unique identifier for new records when
data.idis not astringornumber. Defaults to a monotonic counter ('1','2', …).
Top-level options for MultiTenancyPlugin.
-
cache: TenantCacheOptions
Cache-prefix behaviour.
-
dataStore: ITenantDataStore
An application-provided data store. When absent the plugin ships a zero-dependency
MemoryTenantDataStore. -
database: DatabaseStrategyKind | ITenantIsolationStrategy
Database-isolation strategy: a discriminant string, or a custom
ITenantIsolationStrategyinstance. Default:'column-per-tenant'. -
exclude: readonly PathPattern[]
Paths that skip tenant resolution entirely — no resolver runs, no tenant is stamped, and a
requireddeployment does not reject them. Matched againstctx.request.pathby exact string equality orRegExp.test. -
header: HeaderResolverOptions
Options forwarded to
HeaderResolver. -
jwt: JwtResolverOptions
Options forwarded to
JwtResolver. -
middlewarePriority: number
Priority passed to
ctx.middleware.add(default40). -
path: PathResolverOptions
Options forwarded to
PathResolver. -
rejectionStatus: number
HTTP status code returned when short-circuiting (default
400). -
required: boolean
When
trueand no resolver returns a tenant, short-circuit with an error response. Default:false. -
resolver: ResolverConfig
Which resolver(s) to use for tenant resolution (required).
-
subdomain: SubdomainResolverOptions
Options forwarded to
SubdomainResolver.
Options for PathResolver.
-
segment: number
Segment index in
request.path(default0).
Options for SubdomainResolver.
-
baseDomain: string
When set, strip this suffix from the host before taking the first label.
Options for cache-prefix stamping.
-
prefix: boolean
When
true, write the resolved prefix intoctx.state. -
separator: string
Separator between tenant id and key (default
':').
| "schema-per-tenant"
| "database-per-tenant"
A string discriminant that maps to an isolation-strategy class.
| "header"
| "path"
| "jwt"
| ITenantResolver
| readonly ITenantResolver[]
Resolver configuration — one string name, a custom instance, or a chain.
Standard capability tokens provided by the first-party plugins.
-
AUDIT: string
Audit trail logging.
-
AUTH: string
Authentication service.
-
AUTHORIZATION: string
Authorization service (RBAC, permissions).
-
CACHE: string
Key/value caching.
-
CLI_COMMAND: string
CLI command contributions (multi-provider).
-
CLOUDFLARE: string
Cloudflare Workers platform bindings (KV, R2, D1, Queues, service and Durable Object namespaces) published as one typed accessor.
-
COMMAND_BUS: string
Command bus (CQRS).
-
CONFIG: string
Configuration access.
-
CQRS: string
CQRS facade.
-
DATABASE: string
Database access (repositories, unit of work).
-
DECORATOR_HANDLER: string
Decorator handler contributions (multi-provider).
-
DI_CONTAINER: string
Optional dependency injection container.
-
EVENTS: string
In-memory domain event bus.
-
FEATURE_FLAGS: string
Feature flag evaluation.
-
GRAPHQL: string
GraphQL plugin — schema-first and code-first GraphQL-over-HTTP.
-
GRPC: string
gRPC plugin — server-side Connect/gRPC/gRPC-Web co-serving.
-
HEALTH: string
Health checks.
-
HEALTH_INDICATOR: string
Health indicator contributions (multi-provider).
-
HTTP_ADAPTER: string
HTTP server adapter — the runtime plugin registers its IHttpAdapter here.
-
JWT: string
JWT sign/verify service.
-
LOGGER: string
Structured logger.
-
MAIL: string
Email sending.
-
MESSAGING: string
Message broker for integration events.
-
METADATA_STORE: string
Decorator metadata store (from the DecoratorPlugin, when registered).
-
METRICS: string
Metrics collection.
-
METRIC_REGISTRATION: string
Metric registration contributions (multi-provider).
-
MULTI_TENANCY: string
Multi-tenancy service.
-
NOTIFICATION: string
Multi-channel notifications.
-
OPENAPI: string
OpenAPI spec contribution and generation.
-
OPENAPI_SCHEMA: string
OpenAPI schema contributions (multi-provider).
-
QUERY_BUS: string
Query bus (CQRS).
-
QUEUE: string
Background job queue.
-
REALTIME_BACKPLANE: string
Pub/sub transport carrying real-time broadcasts between application instances, so WebSocket rooms and SSE channels fan out across replicas. Consumed optionally — absent means purely in-process broadcasting.
-
RESILIENCE: string
Resilience patterns (circuit breaker, retry, timeout, bulkhead).
-
RUNTIME: string
Runtime services provided by the RuntimePlugin. Mandatory in every application.
-
SCHEDULER: string
Job scheduling (cron, delayed, recurring).
-
SECRETS: string
Secret management.
-
SERVICE_DISCOVERY: string
Service discovery — logical service name to reachable instances.
-
SESSION: string
Cookie-backed sessions for server-rendered applications.
-
SSE: string
Server-Sent Events (SSE) hub for in-process real-time broadcasting.
-
SSR: string
Server-side rendering (SSR) — React Router or similar framework.
-
STATIC_FILES: string
Static file serving plugin.
-
STORAGE: string
File storage.
-
TELEMETRY: string
Distributed tracing.
-
VALIDATION: string
Request/data validation.
-
VIEW: string
View rendering (server-rendered HTML) — an
IViewEnginethat turns a view component and its props into an HTML string, so a handler can answer with markup it did not concatenate by hand. -
WEBSOCKET: string
WebSocket hub for bidirectional real-time messaging.
-
WORKER_POOL: string
Worker-thread pool for CPU-bound tasks.
State key for the cache prefix — consumers should use getTenantCachePrefix
instead of reading this directly.
Usage
import * as __setu_ts_multi_tenancy_plugin____multi_tenancy_support_for_Setu_TS_ from "multi-tenancy-plugin/src/index.ts";