@dudousxd/nestjs-durable 0.51.0 → 0.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { WorkflowCtx, SearchAttributes, WorkflowClass, StandardSchemaV1, StepError, OnErrorInput, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, StalledRunInfo, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, RunRequest, RunReply, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
2
- export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, OnErrorInput, RunDetail, RunGateway, RunListItem, RunQuery, RunSchedulesOptions, RunStatus, RunWaiting, ScheduledWorkflow, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, prevCronFireMs, readSearchAttributes, runSchedules, scheduleRunIdAt, scheduledRunId } from '@dudousxd/nestjs-durable-core';
1
+ import { WorkflowCtx, SearchAttributes, WorkflowClass, StandardSchemaV1, StepError, OnErrorInput, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, StalledRunInfo, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, TenantVerifier, TenantTokenSource, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, RunRequest, RunReply, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
2
+ export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, OnErrorInput, RunDetail, RunGateway, RunListItem, RunQuery, RunSchedulesOptions, RunStatus, RunWaiting, ScheduledWorkflow, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, TenantTokenSource, TenantVerifier, VerifiedTenant, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, hmacTenantVerifier, prevCronFireMs, readSearchAttributes, runSchedules, scheduleRunIdAt, scheduledRunId, signTenantToken } from '@dudousxd/nestjs-durable-core';
3
3
  import { z } from 'zod';
4
4
  import { ConcurrencyOption, StartRunDeps, RunRedisWorkerOptions, RunningWorker, DurableWorkerRuntime } from '@dudousxd/durable-worker';
5
5
  import { DynamicModule, InjectionToken, OnModuleInit, OnApplicationBootstrap, OnApplicationShutdown, Provider } from '@nestjs/common';
@@ -790,6 +790,26 @@ interface DurableModuleOptions {
790
790
  /** Timeout for a thin worker's `RunGateway` round-trip over `transport` before it rejects. Defaults
791
791
  * to 10_000ms inside `ProxyRunGateway`. Ignored for an operator (bound to `StoreRunGateway`). */
792
792
  runGatewayTimeoutMs?: number;
793
+ /**
794
+ * **Operator.** Verifies the signed tenant token a store-less tenant worker presents in the wire
795
+ * `tenant` field of every run request and start-run message, and DERIVES the tenant from it,
796
+ * discarding the wire claim. An invalid, tampered or absent token is rejected: a run request gets
797
+ * an `unauthorized` error reply, a start-run creates nothing. Use `hmacTenantVerifier(secret)`
798
+ * (tokens minted by `signTenantToken`, wire-compatible with Agora) or supply your own.
799
+ *
800
+ * Optional. Absent: the wire `tenant` is trusted verbatim (prefix/network isolation only), exactly
801
+ * as before. An explicit `topology: { role: 'control-plane' }` without a verifier logs a warning
802
+ * at boot; a plain operator (`store` + `transport`, no `topology`) boots silently.
803
+ */
804
+ verifyTenant?: TenantVerifier;
805
+ /**
806
+ * **Tenant worker.** The signed token (see `signTenantToken`) this worker presents, verbatim, in
807
+ * the `tenant` field of every run request (`ProxyRunGateway`) and start-run (`engine.start`), so
808
+ * an operator with {@link verifyTenant} can authenticate it. A string, or a function called before
809
+ * every request (rotation, short-lived tokens). Optional: absent, the raw {@link partition} is
810
+ * sent, as before. Live-tail stays keyed by the partition, never the token.
811
+ */
812
+ tenantToken?: TenantTokenSource;
793
813
  /**
794
814
  * An explicit preset that NAMES the deployment role instead of leaving it to `store`/`connection`
795
815
  * inference, and VALIDATES the axes that are otherwise only prose (see the interface doc's role
@@ -1078,6 +1098,77 @@ declare class InAppWorkerBootstrap implements OnModuleInit, OnApplicationBootstr
1078
1098
  */
1079
1099
  declare function inAppWorkerProviders(): Provider[];
1080
1100
 
1101
+ /**
1102
+ * The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
1103
+ * "this control plane is older than me" from a real failure and fall back at once. Earlier
1104
+ * responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
1105
+ */
1106
+ declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1107
+ /** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
1108
+ * correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
1109
+ * transports carry the run-request/reply protocol); the caller capability-checks before wiring
1110
+ * this up (see `durable.module.ts`). */
1111
+ interface RunRequestTransport {
1112
+ onRunRequest(handler: (msg: RunRequest) => Promise<void>): void;
1113
+ publishRunReply(reply: RunReply): Promise<void>;
1114
+ }
1115
+ /** Options for {@link RunRequestResponder}. */
1116
+ interface RunRequestResponderOptions {
1117
+ /**
1118
+ * Verifies the signed token a tenant presents in the wire `tenant` field and DERIVES the real
1119
+ * tenant from it (see `hmacTenantVerifier`). Present: an invalid, tampered or absent token is
1120
+ * rejected with an `unauthorized` error reply and the wire claim is discarded in favour of the
1121
+ * verified tenant. Absent: the wire `tenant` is trusted verbatim (prefix/network isolation only).
1122
+ */
1123
+ verifyTenant?: TenantVerifier | undefined;
1124
+ /**
1125
+ * Warn at construction when no {@link verifyTenant} is set. Default `true`. `DurableModule` passes
1126
+ * `true` only for an explicit `topology: { role: 'control-plane' }`, so a plain operator app that
1127
+ * never serves tenants boots silently.
1128
+ */
1129
+ warnWithoutVerifier?: boolean | undefined;
1130
+ }
1131
+ /**
1132
+ * Operator-side consumer of a tenant's {@link RunRequest}s: answers each one against a
1133
+ * `RunGateway`, enforcing the tenant boundary before touching the run. For every runId-bearing
1134
+ * verb it loads the run via `getRunDetail` FIRST and compares `run.namespace` to the requesting
1135
+ * `msg.tenant` — a mismatch short-circuits into a `cross-tenant` error reply WITHOUT calling the
1136
+ * verb, so a tenant can never read or act on another tenant's run. `listRuns` is scoped by
1137
+ * overwriting the query's `namespace` with the requester's tenant, ignoring whatever the client
1138
+ * sent. This is the security boundary of the tenant run gateway — do not weaken it.
1139
+ *
1140
+ * With {@link RunRequestResponderOptions.verifyTenant}, every request is authenticated FIRST: the
1141
+ * wire `tenant` is treated as a signed token, the real tenant is derived from it, and an invalid
1142
+ * token short-circuits into an `unauthorized` error reply before any run is touched. A verifier
1143
+ * that throws becomes an error reply too.
1144
+ */
1145
+ declare class RunRequestResponder {
1146
+ private readonly transport;
1147
+ private readonly gateway;
1148
+ private readonly verifyTenant;
1149
+ constructor(transport: RunRequestTransport, gateway: RunGateway, options?: RunRequestResponderOptions);
1150
+ /** Register the consumer on the transport. Each request is answered independently; a handler
1151
+ * failure never throws back into the transport (errors are captured into an error reply). */
1152
+ start(): void;
1153
+ private handle;
1154
+ private callVerb;
1155
+ }
1156
+
1157
+ /**
1158
+ * An error reply from the control plane. `code` carries the reply's machine-readable reason when it
1159
+ * sent one — `unauthorized` (the tenant token was rejected), `cross-tenant` (the run belongs to
1160
+ * another tenant), ... — so a caller can tell an authentication failure from a real one, as with
1161
+ * Agora's proxy.
1162
+ */
1163
+ /**
1164
+ * The codes the run-request responder replies with. `string & {}` keeps a code from a newer control
1165
+ * plane assignable without losing autocomplete on the known ones.
1166
+ */
1167
+ type RunGatewayErrorCode = 'unauthorized' | 'cross-tenant' | typeof UNSUPPORTED_RUN_REQUEST | (string & {});
1168
+ declare class RunGatewayError extends Error {
1169
+ readonly code: RunGatewayErrorCode | undefined;
1170
+ constructor(message: string, code?: RunGatewayErrorCode);
1171
+ }
1081
1172
  /**
1082
1173
  * Tenant-side `RunGateway` — round-trips every verb as a `RunRequest`/`RunReply` pair over the
1083
1174
  * transport, correlated by a minted `requestId`, and bridges `subscribe` onto the transport's
@@ -1091,15 +1182,32 @@ declare class ProxyRunGateway implements RunGateway {
1091
1182
  private readonly tenant;
1092
1183
  private readonly timeoutMs;
1093
1184
  private readonly capabilityTtlMs;
1185
+ /**
1186
+ * The tenant's signed token (see `signTenantToken`), presented VERBATIM in the `tenant` field of
1187
+ * every {@link RunRequest} so an operator with `verifyTenant` can authenticate it and derive the
1188
+ * tenant from it. A function is called before every request (rotation / short-lived tokens).
1189
+ * Omit to send the raw `tenant` (prefix/network isolation only). The live-tail channel always
1190
+ * stays keyed by `tenant`, never the token: the operator republishes by the run's namespace.
1191
+ */
1192
+ private readonly tenantToken?;
1094
1193
  private readonly pending;
1095
1194
  /** Verb → when to ask the control plane for it again, after it answered that it does not know it.
1096
1195
  * During a rolling upgrade the control plane is several pods of mixed versions behind one queue,
1097
1196
  * and a reply does not say which pod sent it, so the whole control plane is assumed old until the
1098
1197
  * entry expires. */
1099
1198
  private readonly unsupportedUntil;
1100
- constructor(transport: Transport, tenant: string, timeoutMs?: number, capabilityTtlMs?: number);
1199
+ constructor(transport: Transport, tenant: string, timeoutMs?: number, capabilityTtlMs?: number,
1200
+ /**
1201
+ * The tenant's signed token (see `signTenantToken`), presented VERBATIM in the `tenant` field of
1202
+ * every {@link RunRequest} so an operator with `verifyTenant` can authenticate it and derive the
1203
+ * tenant from it. A function is called before every request (rotation / short-lived tokens).
1204
+ * Omit to send the raw `tenant` (prefix/network isolation only). The live-tail channel always
1205
+ * stays keyed by `tenant`, never the token: the operator republishes by the run's namespace.
1206
+ */
1207
+ tenantToken?: TenantTokenSource | undefined);
1101
1208
  private handleReply;
1102
1209
  private request;
1210
+ private send;
1103
1211
  topology(): DurableTopology;
1104
1212
  /**
1105
1213
  * A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
@@ -1151,40 +1259,6 @@ declare function isOperatorRole(options: DurableModuleOptions): boolean;
1151
1259
  */
1152
1260
  declare function isDrivingOperator(options: DurableModuleOptions): boolean;
1153
1261
 
1154
- /**
1155
- * The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
1156
- * "this control plane is older than me" from a real failure and fall back at once. Earlier
1157
- * responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
1158
- */
1159
- declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1160
- /** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
1161
- * correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
1162
- * transports carry the run-request/reply protocol); the caller capability-checks before wiring
1163
- * this up (see `durable.module.ts`). */
1164
- interface RunRequestTransport {
1165
- onRunRequest(handler: (msg: RunRequest) => Promise<void>): void;
1166
- publishRunReply(reply: RunReply): Promise<void>;
1167
- }
1168
- /**
1169
- * Operator-side consumer of a tenant's {@link RunRequest}s: answers each one against a
1170
- * `RunGateway`, enforcing the tenant boundary before touching the run. For every runId-bearing
1171
- * verb it loads the run via `getRunDetail` FIRST and compares `run.namespace` to the requesting
1172
- * `msg.tenant` — a mismatch short-circuits into a `cross-tenant` error reply WITHOUT calling the
1173
- * verb, so a tenant can never read or act on another tenant's run. `listRuns` is scoped by
1174
- * overwriting the query's `namespace` with the requester's tenant, ignoring whatever the client
1175
- * sent. This is the security boundary of the tenant run gateway — do not weaken it.
1176
- */
1177
- declare class RunRequestResponder {
1178
- private readonly transport;
1179
- private readonly gateway;
1180
- constructor(transport: RunRequestTransport, gateway: RunGateway);
1181
- /** Register the consumer on the transport. Each request is answered independently; a handler
1182
- * failure never throws back into the transport (errors are captured into an error reply). */
1183
- start(): void;
1184
- private handle;
1185
- private callVerb;
1186
- }
1187
-
1188
1262
  declare const STEP_INTERCEPTOR_METADATA: unique symbol;
1189
1263
  /**
1190
1264
  * The shape a `@StepInterceptor()` provider must implement: `intercept(invocation, next)` wraps the
@@ -1375,4 +1449,4 @@ declare class WorkflowService {
1375
1449
  }): Promise<number>;
1376
1450
  }
1377
1451
 
1378
- export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, type DtoClass, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, type ErrorClassWithCode, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, type IoSchema, ON_ERROR_METADATA, ON_EVENT_METADATA, On, OnDurableEvent, OnError, type OnErrorMethod, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, UNSUPPORTED_RUN_REQUEST, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, onErrorCodesOf, thinWorkerProviders, unavailableRunGateway };
1452
+ export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, type DtoClass, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, type ErrorClassWithCode, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, type IoSchema, ON_ERROR_METADATA, ON_EVENT_METADATA, On, OnDurableEvent, OnError, type OnErrorMethod, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, RunGatewayError, type RunGatewayErrorCode, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestResponderOptions, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, UNSUPPORTED_RUN_REQUEST, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, onErrorCodesOf, thinWorkerProviders, unavailableRunGateway };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { WorkflowCtx, SearchAttributes, WorkflowClass, StandardSchemaV1, StepError, OnErrorInput, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, StalledRunInfo, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, RunRequest, RunReply, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
2
- export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, OnErrorInput, RunDetail, RunGateway, RunListItem, RunQuery, RunSchedulesOptions, RunStatus, RunWaiting, ScheduledWorkflow, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, prevCronFireMs, readSearchAttributes, runSchedules, scheduleRunIdAt, scheduledRunId } from '@dudousxd/nestjs-durable-core';
1
+ import { WorkflowCtx, SearchAttributes, WorkflowClass, StandardSchemaV1, StepError, OnErrorInput, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, StalledRunInfo, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, TenantVerifier, TenantTokenSource, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, RunRequest, RunReply, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
2
+ export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, OnErrorInput, RunDetail, RunGateway, RunListItem, RunQuery, RunSchedulesOptions, RunStatus, RunWaiting, ScheduledWorkflow, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, TenantTokenSource, TenantVerifier, VerifiedTenant, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, hmacTenantVerifier, prevCronFireMs, readSearchAttributes, runSchedules, scheduleRunIdAt, scheduledRunId, signTenantToken } from '@dudousxd/nestjs-durable-core';
3
3
  import { z } from 'zod';
4
4
  import { ConcurrencyOption, StartRunDeps, RunRedisWorkerOptions, RunningWorker, DurableWorkerRuntime } from '@dudousxd/durable-worker';
5
5
  import { DynamicModule, InjectionToken, OnModuleInit, OnApplicationBootstrap, OnApplicationShutdown, Provider } from '@nestjs/common';
@@ -790,6 +790,26 @@ interface DurableModuleOptions {
790
790
  /** Timeout for a thin worker's `RunGateway` round-trip over `transport` before it rejects. Defaults
791
791
  * to 10_000ms inside `ProxyRunGateway`. Ignored for an operator (bound to `StoreRunGateway`). */
792
792
  runGatewayTimeoutMs?: number;
793
+ /**
794
+ * **Operator.** Verifies the signed tenant token a store-less tenant worker presents in the wire
795
+ * `tenant` field of every run request and start-run message, and DERIVES the tenant from it,
796
+ * discarding the wire claim. An invalid, tampered or absent token is rejected: a run request gets
797
+ * an `unauthorized` error reply, a start-run creates nothing. Use `hmacTenantVerifier(secret)`
798
+ * (tokens minted by `signTenantToken`, wire-compatible with Agora) or supply your own.
799
+ *
800
+ * Optional. Absent: the wire `tenant` is trusted verbatim (prefix/network isolation only), exactly
801
+ * as before. An explicit `topology: { role: 'control-plane' }` without a verifier logs a warning
802
+ * at boot; a plain operator (`store` + `transport`, no `topology`) boots silently.
803
+ */
804
+ verifyTenant?: TenantVerifier;
805
+ /**
806
+ * **Tenant worker.** The signed token (see `signTenantToken`) this worker presents, verbatim, in
807
+ * the `tenant` field of every run request (`ProxyRunGateway`) and start-run (`engine.start`), so
808
+ * an operator with {@link verifyTenant} can authenticate it. A string, or a function called before
809
+ * every request (rotation, short-lived tokens). Optional: absent, the raw {@link partition} is
810
+ * sent, as before. Live-tail stays keyed by the partition, never the token.
811
+ */
812
+ tenantToken?: TenantTokenSource;
793
813
  /**
794
814
  * An explicit preset that NAMES the deployment role instead of leaving it to `store`/`connection`
795
815
  * inference, and VALIDATES the axes that are otherwise only prose (see the interface doc's role
@@ -1078,6 +1098,77 @@ declare class InAppWorkerBootstrap implements OnModuleInit, OnApplicationBootstr
1078
1098
  */
1079
1099
  declare function inAppWorkerProviders(): Provider[];
1080
1100
 
1101
+ /**
1102
+ * The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
1103
+ * "this control plane is older than me" from a real failure and fall back at once. Earlier
1104
+ * responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
1105
+ */
1106
+ declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1107
+ /** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
1108
+ * correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
1109
+ * transports carry the run-request/reply protocol); the caller capability-checks before wiring
1110
+ * this up (see `durable.module.ts`). */
1111
+ interface RunRequestTransport {
1112
+ onRunRequest(handler: (msg: RunRequest) => Promise<void>): void;
1113
+ publishRunReply(reply: RunReply): Promise<void>;
1114
+ }
1115
+ /** Options for {@link RunRequestResponder}. */
1116
+ interface RunRequestResponderOptions {
1117
+ /**
1118
+ * Verifies the signed token a tenant presents in the wire `tenant` field and DERIVES the real
1119
+ * tenant from it (see `hmacTenantVerifier`). Present: an invalid, tampered or absent token is
1120
+ * rejected with an `unauthorized` error reply and the wire claim is discarded in favour of the
1121
+ * verified tenant. Absent: the wire `tenant` is trusted verbatim (prefix/network isolation only).
1122
+ */
1123
+ verifyTenant?: TenantVerifier | undefined;
1124
+ /**
1125
+ * Warn at construction when no {@link verifyTenant} is set. Default `true`. `DurableModule` passes
1126
+ * `true` only for an explicit `topology: { role: 'control-plane' }`, so a plain operator app that
1127
+ * never serves tenants boots silently.
1128
+ */
1129
+ warnWithoutVerifier?: boolean | undefined;
1130
+ }
1131
+ /**
1132
+ * Operator-side consumer of a tenant's {@link RunRequest}s: answers each one against a
1133
+ * `RunGateway`, enforcing the tenant boundary before touching the run. For every runId-bearing
1134
+ * verb it loads the run via `getRunDetail` FIRST and compares `run.namespace` to the requesting
1135
+ * `msg.tenant` — a mismatch short-circuits into a `cross-tenant` error reply WITHOUT calling the
1136
+ * verb, so a tenant can never read or act on another tenant's run. `listRuns` is scoped by
1137
+ * overwriting the query's `namespace` with the requester's tenant, ignoring whatever the client
1138
+ * sent. This is the security boundary of the tenant run gateway — do not weaken it.
1139
+ *
1140
+ * With {@link RunRequestResponderOptions.verifyTenant}, every request is authenticated FIRST: the
1141
+ * wire `tenant` is treated as a signed token, the real tenant is derived from it, and an invalid
1142
+ * token short-circuits into an `unauthorized` error reply before any run is touched. A verifier
1143
+ * that throws becomes an error reply too.
1144
+ */
1145
+ declare class RunRequestResponder {
1146
+ private readonly transport;
1147
+ private readonly gateway;
1148
+ private readonly verifyTenant;
1149
+ constructor(transport: RunRequestTransport, gateway: RunGateway, options?: RunRequestResponderOptions);
1150
+ /** Register the consumer on the transport. Each request is answered independently; a handler
1151
+ * failure never throws back into the transport (errors are captured into an error reply). */
1152
+ start(): void;
1153
+ private handle;
1154
+ private callVerb;
1155
+ }
1156
+
1157
+ /**
1158
+ * An error reply from the control plane. `code` carries the reply's machine-readable reason when it
1159
+ * sent one — `unauthorized` (the tenant token was rejected), `cross-tenant` (the run belongs to
1160
+ * another tenant), ... — so a caller can tell an authentication failure from a real one, as with
1161
+ * Agora's proxy.
1162
+ */
1163
+ /**
1164
+ * The codes the run-request responder replies with. `string & {}` keeps a code from a newer control
1165
+ * plane assignable without losing autocomplete on the known ones.
1166
+ */
1167
+ type RunGatewayErrorCode = 'unauthorized' | 'cross-tenant' | typeof UNSUPPORTED_RUN_REQUEST | (string & {});
1168
+ declare class RunGatewayError extends Error {
1169
+ readonly code: RunGatewayErrorCode | undefined;
1170
+ constructor(message: string, code?: RunGatewayErrorCode);
1171
+ }
1081
1172
  /**
1082
1173
  * Tenant-side `RunGateway` — round-trips every verb as a `RunRequest`/`RunReply` pair over the
1083
1174
  * transport, correlated by a minted `requestId`, and bridges `subscribe` onto the transport's
@@ -1091,15 +1182,32 @@ declare class ProxyRunGateway implements RunGateway {
1091
1182
  private readonly tenant;
1092
1183
  private readonly timeoutMs;
1093
1184
  private readonly capabilityTtlMs;
1185
+ /**
1186
+ * The tenant's signed token (see `signTenantToken`), presented VERBATIM in the `tenant` field of
1187
+ * every {@link RunRequest} so an operator with `verifyTenant` can authenticate it and derive the
1188
+ * tenant from it. A function is called before every request (rotation / short-lived tokens).
1189
+ * Omit to send the raw `tenant` (prefix/network isolation only). The live-tail channel always
1190
+ * stays keyed by `tenant`, never the token: the operator republishes by the run's namespace.
1191
+ */
1192
+ private readonly tenantToken?;
1094
1193
  private readonly pending;
1095
1194
  /** Verb → when to ask the control plane for it again, after it answered that it does not know it.
1096
1195
  * During a rolling upgrade the control plane is several pods of mixed versions behind one queue,
1097
1196
  * and a reply does not say which pod sent it, so the whole control plane is assumed old until the
1098
1197
  * entry expires. */
1099
1198
  private readonly unsupportedUntil;
1100
- constructor(transport: Transport, tenant: string, timeoutMs?: number, capabilityTtlMs?: number);
1199
+ constructor(transport: Transport, tenant: string, timeoutMs?: number, capabilityTtlMs?: number,
1200
+ /**
1201
+ * The tenant's signed token (see `signTenantToken`), presented VERBATIM in the `tenant` field of
1202
+ * every {@link RunRequest} so an operator with `verifyTenant` can authenticate it and derive the
1203
+ * tenant from it. A function is called before every request (rotation / short-lived tokens).
1204
+ * Omit to send the raw `tenant` (prefix/network isolation only). The live-tail channel always
1205
+ * stays keyed by `tenant`, never the token: the operator republishes by the run's namespace.
1206
+ */
1207
+ tenantToken?: TenantTokenSource | undefined);
1101
1208
  private handleReply;
1102
1209
  private request;
1210
+ private send;
1103
1211
  topology(): DurableTopology;
1104
1212
  /**
1105
1213
  * A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
@@ -1151,40 +1259,6 @@ declare function isOperatorRole(options: DurableModuleOptions): boolean;
1151
1259
  */
1152
1260
  declare function isDrivingOperator(options: DurableModuleOptions): boolean;
1153
1261
 
1154
- /**
1155
- * The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
1156
- * "this control plane is older than me" from a real failure and fall back at once. Earlier
1157
- * responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
1158
- */
1159
- declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1160
- /** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
1161
- * correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
1162
- * transports carry the run-request/reply protocol); the caller capability-checks before wiring
1163
- * this up (see `durable.module.ts`). */
1164
- interface RunRequestTransport {
1165
- onRunRequest(handler: (msg: RunRequest) => Promise<void>): void;
1166
- publishRunReply(reply: RunReply): Promise<void>;
1167
- }
1168
- /**
1169
- * Operator-side consumer of a tenant's {@link RunRequest}s: answers each one against a
1170
- * `RunGateway`, enforcing the tenant boundary before touching the run. For every runId-bearing
1171
- * verb it loads the run via `getRunDetail` FIRST and compares `run.namespace` to the requesting
1172
- * `msg.tenant` — a mismatch short-circuits into a `cross-tenant` error reply WITHOUT calling the
1173
- * verb, so a tenant can never read or act on another tenant's run. `listRuns` is scoped by
1174
- * overwriting the query's `namespace` with the requester's tenant, ignoring whatever the client
1175
- * sent. This is the security boundary of the tenant run gateway — do not weaken it.
1176
- */
1177
- declare class RunRequestResponder {
1178
- private readonly transport;
1179
- private readonly gateway;
1180
- constructor(transport: RunRequestTransport, gateway: RunGateway);
1181
- /** Register the consumer on the transport. Each request is answered independently; a handler
1182
- * failure never throws back into the transport (errors are captured into an error reply). */
1183
- start(): void;
1184
- private handle;
1185
- private callVerb;
1186
- }
1187
-
1188
1262
  declare const STEP_INTERCEPTOR_METADATA: unique symbol;
1189
1263
  /**
1190
1264
  * The shape a `@StepInterceptor()` provider must implement: `intercept(invocation, next)` wraps the
@@ -1375,4 +1449,4 @@ declare class WorkflowService {
1375
1449
  }): Promise<number>;
1376
1450
  }
1377
1451
 
1378
- export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, type DtoClass, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, type ErrorClassWithCode, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, type IoSchema, ON_ERROR_METADATA, ON_EVENT_METADATA, On, OnDurableEvent, OnError, type OnErrorMethod, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, UNSUPPORTED_RUN_REQUEST, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, onErrorCodesOf, thinWorkerProviders, unavailableRunGateway };
1452
+ export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, type DtoClass, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, type ErrorClassWithCode, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, type IoSchema, ON_ERROR_METADATA, ON_EVENT_METADATA, On, OnDurableEvent, OnError, type OnErrorMethod, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, RunGatewayError, type RunGatewayErrorCode, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestResponderOptions, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, UNSUPPORTED_RUN_REQUEST, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, onErrorCodesOf, thinWorkerProviders, unavailableRunGateway };
package/dist/index.js CHANGED
@@ -264,7 +264,7 @@ function attributesOf(workflow, run) {
264
264
  __name(attributesOf, "attributesOf");
265
265
 
266
266
  // src/durable-start-client.ts
267
- import { workflowName } from "@dudousxd/nestjs-durable-core";
267
+ import { resolveTenantToken, workflowName } from "@dudousxd/nestjs-durable-core";
268
268
  import { Injectable } from "@nestjs/common";
269
269
 
270
270
  // src/worker-sdk.ts
@@ -322,7 +322,9 @@ var DurableStartClient = class {
322
322
  async start(workflow, input, runId = globalThis.crypto.randomUUID(), opts) {
323
323
  const name = workflowName(workflow);
324
324
  await startRun(this.options.connection, {
325
- tenant: this.tenant,
325
+ // The signed token (when configured) rides in the `tenant` field, as on every run request; an
326
+ // operator with `verifyTenant` derives the run's namespace from it.
327
+ tenant: this.options.tenantToken !== void 0 ? await resolveTenantToken(this.options.tenantToken) : this.tenant,
326
328
  workflow: name,
327
329
  input,
328
330
  runId,
@@ -1159,10 +1161,11 @@ function inAppWorkerProviders() {
1159
1161
  __name(inAppWorkerProviders, "inAppWorkerProviders");
1160
1162
 
1161
1163
  // src/proxy-run-gateway.ts
1162
- import { SUMMARY_CHILD_LIMIT, childIdsOf, pageFan, summarizeTimeline } from "@dudousxd/nestjs-durable-core";
1164
+ import { SUMMARY_CHILD_LIMIT, childIdsOf, pageFan, resolveTenantToken as resolveTenantToken2, summarizeTimeline } from "@dudousxd/nestjs-durable-core";
1163
1165
  import { Injectable as Injectable6 } from "@nestjs/common";
1164
1166
 
1165
1167
  // src/run-request-responder.ts
1168
+ import { resolveWireTenant } from "@dudousxd/nestjs-durable-core";
1166
1169
  var UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1167
1170
  var KNOWN_KINDS = /* @__PURE__ */ new Set([
1168
1171
  "getRunDetail",
@@ -1184,9 +1187,14 @@ var RunRequestResponder = class {
1184
1187
  }
1185
1188
  transport;
1186
1189
  gateway;
1187
- constructor(transport, gateway) {
1190
+ verifyTenant;
1191
+ constructor(transport, gateway, options = {}) {
1188
1192
  this.transport = transport;
1189
1193
  this.gateway = gateway;
1194
+ this.verifyTenant = options.verifyTenant;
1195
+ if (!this.verifyTenant && options.warnWithoutVerifier !== false) {
1196
+ console.warn("[nestjs-durable] run-request responder started WITHOUT a tenant verifier: the wire `tenant` claim is trusted verbatim (prefix/network isolation only). Any broker client can act as any tenant. Configure `verifyTenant` (e.g. hmacTenantVerifier(secret)) and signed tenant tokens unless your broker is fully isolated per tenant.");
1197
+ }
1190
1198
  }
1191
1199
  /** Register the consumer on the transport. Each request is answered independently; a handler
1192
1200
  * failure never throws back into the transport (errors are captured into an error reply). */
@@ -1209,7 +1217,24 @@ var RunRequestResponder = class {
1209
1217
  await this.transport.publishRunReply(reply);
1210
1218
  });
1211
1219
  }
1212
- async handle(msg) {
1220
+ async handle(wire) {
1221
+ const tenant = await resolveWireTenant(wire.tenant, this.verifyTenant);
1222
+ if (tenant === null) {
1223
+ return {
1224
+ requestId: wire.requestId,
1225
+ result: {
1226
+ ok: false,
1227
+ error: {
1228
+ message: "invalid or unauthorized tenant token",
1229
+ code: "unauthorized"
1230
+ }
1231
+ }
1232
+ };
1233
+ }
1234
+ const msg = {
1235
+ ...wire,
1236
+ tenant
1237
+ };
1213
1238
  const { body } = msg;
1214
1239
  if (!KNOWN_KINDS.has(body.kind)) {
1215
1240
  return {
@@ -1385,7 +1410,18 @@ function _ts_metadata6(metadataKey, metadataValue) {
1385
1410
  }
1386
1411
  }
1387
1412
  __name(_ts_metadata6, "_ts_metadata");
1388
- var UnsupportedRunRequestError = class UnsupportedRunRequestError2 extends Error {
1413
+ var RunGatewayError = class extends Error {
1414
+ static {
1415
+ __name(this, "RunGatewayError");
1416
+ }
1417
+ code;
1418
+ constructor(message, code) {
1419
+ super(message);
1420
+ this.name = "RunGatewayError";
1421
+ this.code = code;
1422
+ }
1423
+ };
1424
+ var UnsupportedRunRequestError = class UnsupportedRunRequestError2 extends RunGatewayError {
1389
1425
  static {
1390
1426
  __name(this, "UnsupportedRunRequestError");
1391
1427
  }
@@ -1402,17 +1438,19 @@ var ProxyRunGateway = class {
1402
1438
  tenant;
1403
1439
  timeoutMs;
1404
1440
  capabilityTtlMs;
1441
+ tenantToken;
1405
1442
  pending = /* @__PURE__ */ new Map();
1406
1443
  /** Verb → when to ask the control plane for it again, after it answered that it does not know it.
1407
1444
  * During a rolling upgrade the control plane is several pods of mixed versions behind one queue,
1408
1445
  * and a reply does not say which pod sent it, so the whole control plane is assumed old until the
1409
1446
  * entry expires. */
1410
1447
  unsupportedUntil = /* @__PURE__ */ new Map();
1411
- constructor(transport, tenant, timeoutMs = 1e4, capabilityTtlMs = 6e4) {
1448
+ constructor(transport, tenant, timeoutMs = 1e4, capabilityTtlMs = 6e4, tenantToken) {
1412
1449
  this.transport = transport;
1413
1450
  this.tenant = tenant;
1414
1451
  this.timeoutMs = timeoutMs;
1415
1452
  this.capabilityTtlMs = capabilityTtlMs;
1453
+ this.tenantToken = tenantToken;
1416
1454
  this.transport.onRunReply?.((reply) => this.handleReply(reply));
1417
1455
  }
1418
1456
  handleReply(reply) {
@@ -1423,12 +1461,17 @@ var ProxyRunGateway = class {
1423
1461
  if (reply.result.ok) {
1424
1462
  pending.resolve(reply.result.data);
1425
1463
  } else if (reply.result.error.code === UNSUPPORTED_RUN_REQUEST) {
1426
- pending.reject(new UnsupportedRunRequestError(reply.result.error.message));
1464
+ pending.reject(new UnsupportedRunRequestError(reply.result.error.message, UNSUPPORTED_RUN_REQUEST));
1427
1465
  } else {
1428
- pending.reject(new Error(reply.result.error.message));
1466
+ pending.reject(new RunGatewayError(reply.result.error.message, reply.result.error.code));
1429
1467
  }
1430
1468
  }
1431
1469
  request(body) {
1470
+ const source = this.tenantToken;
1471
+ if (typeof source !== "function") return this.send(source ?? this.tenant, body);
1472
+ return resolveTenantToken2(source).then((tenant) => this.send(tenant, body));
1473
+ }
1474
+ send(tenant, body) {
1432
1475
  return new Promise((resolve, reject) => {
1433
1476
  const requestId = globalThis.crypto.randomUUID();
1434
1477
  const timer = setTimeout(() => {
@@ -1442,9 +1485,9 @@ var ProxyRunGateway = class {
1442
1485
  });
1443
1486
  this.transport.dispatchRunRequest?.({
1444
1487
  requestId,
1445
- tenant: this.tenant,
1488
+ tenant,
1446
1489
  body
1447
- }).catch((error) => {
1490
+ })?.catch((error) => {
1448
1491
  const stillPending = this.pending.get(requestId);
1449
1492
  if (!stillPending) return;
1450
1493
  clearTimeout(stillPending.timer);
@@ -1602,7 +1645,8 @@ ProxyRunGateway = _ts_decorate6([
1602
1645
  typeof Transport === "undefined" ? Object : Transport,
1603
1646
  String,
1604
1647
  void 0,
1605
- void 0
1648
+ void 0,
1649
+ typeof TenantTokenSource === "undefined" ? Object : TenantTokenSource
1606
1650
  ])
1607
1651
  ], ProxyRunGateway);
1608
1652
 
@@ -2727,7 +2771,15 @@ var RunGatewayBootstrap = class RunGatewayBootstrap2 {
2727
2771
  onRunRequest: onRunRequest.bind(this.transport),
2728
2772
  publishRunReply: publishRunReply.bind(this.transport)
2729
2773
  };
2730
- new RunRequestResponder(runRequestTransport, this.gateway).start();
2774
+ new RunRequestResponder(runRequestTransport, this.gateway, {
2775
+ verifyTenant: this.options.verifyTenant,
2776
+ // Mirrors Agora's rule (`warnWithoutVerifier: role === 'control-plane'`): only a deployment
2777
+ // that EXPLICITLY names itself the control plane is told it runs without tenant auth. A plain
2778
+ // operator (role inferred from `store`) is Agora's `standalone`: anyone with broker access
2779
+ // can already enqueue steps and results there, so the warning would be noise on every boot
2780
+ // of an app that never serves tenants.
2781
+ warnWithoutVerifier: this.options.topology?.role === "control-plane"
2782
+ }).start();
2731
2783
  }
2732
2784
  if (typeof publishTenantEvent === "function") {
2733
2785
  const republisher = new TenantEventRepublisher(store, publishTenantEvent.bind(this.transport));
@@ -2879,6 +2931,7 @@ var DurableModule = class _DurableModule {
2879
2931
  context,
2880
2932
  rehydrate: rehydrate || void 0,
2881
2933
  compensationRetries: options.compensationRetries,
2934
+ verifyTenant: options.verifyTenant,
2882
2935
  // A non-driving (dashboard/API) operator must not run workflows: enqueue-only, leaving
2883
2936
  // each `pending` run in the store for a DRIVING instance's poll. A driving operator gets
2884
2937
  // the engine's default in-process dispatcher: for a body registered inline, it runs
@@ -2919,7 +2972,7 @@ var DurableModule = class _DurableModule {
2919
2972
  }
2920
2973
  return new StoreRunGateway(store, engine);
2921
2974
  }
2922
- return options.transport ? new ProxyRunGateway(options.transport, options.partition ?? "default", options.runGatewayTimeoutMs) : unavailableRunGateway();
2975
+ return options.transport ? new ProxyRunGateway(options.transport, options.partition ?? "default", options.runGatewayTimeoutMs, void 0, options.tenantToken) : unavailableRunGateway();
2923
2976
  }, "useFactory"),
2924
2977
  inject: [
2925
2978
  DURABLE_OPTIONS_CANONICAL7,
@@ -2954,7 +3007,7 @@ DurableModule = _ts_decorate12([
2954
3007
  ], DurableModule);
2955
3008
 
2956
3009
  // src/index.ts
2957
- import { prevCronFireMs, readSearchAttributes as readSearchAttributes2, RunGateway as RunGateway3, runSchedules as runSchedules2, scheduledRunId, scheduleRunIdAt, WorkflowEngine as WorkflowEngine7 } from "@dudousxd/nestjs-durable-core";
3010
+ import { hmacTenantVerifier, prevCronFireMs, readSearchAttributes as readSearchAttributes2, RunGateway as RunGateway3, runSchedules as runSchedules2, scheduledRunId, scheduleRunIdAt, signTenantToken, WorkflowEngine as WorkflowEngine7 } from "@dudousxd/nestjs-durable-core";
2958
3011
  export {
2959
3012
  CONTEXT_ACCESSOR,
2960
3013
  DEAD_LETTER_METADATA,
@@ -2984,6 +3037,7 @@ export {
2984
3037
  RUN_GATEWAY,
2985
3038
  RUN_REDIS_WORKER,
2986
3039
  RunGateway3 as RunGateway,
3040
+ RunGatewayError,
2987
3041
  RunRequestResponder,
2988
3042
  STEP_INTERCEPTOR_METADATA,
2989
3043
  Step,
@@ -3004,6 +3058,7 @@ export {
3004
3058
  getEntityMeta,
3005
3059
  getOnEvents,
3006
3060
  getWorkflowMeta,
3061
+ hmacTenantVerifier,
3007
3062
  inAppWorkerProviders,
3008
3063
  isDeadLetterHandler,
3009
3064
  isDrivingOperator,
@@ -3015,6 +3070,7 @@ export {
3015
3070
  runSchedules2 as runSchedules,
3016
3071
  scheduleRunIdAt,
3017
3072
  scheduledRunId,
3073
+ signTenantToken,
3018
3074
  thinWorkerProviders,
3019
3075
  unavailableRunGateway
3020
3076
  };