@dudousxd/nestjs-durable 0.52.0 → 0.52.2

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,4 +1,4 @@
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, 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';
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
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';
@@ -1098,6 +1098,77 @@ declare class InAppWorkerBootstrap implements OnModuleInit, OnApplicationBootstr
1098
1098
  */
1099
1099
  declare function inAppWorkerProviders(): Provider[];
1100
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
+ }
1101
1172
  /**
1102
1173
  * Tenant-side `RunGateway` — round-trips every verb as a `RunRequest`/`RunReply` pair over the
1103
1174
  * transport, correlated by a minted `requestId`, and bridges `subscribe` onto the transport's
@@ -1136,6 +1207,7 @@ declare class ProxyRunGateway implements RunGateway {
1136
1207
  tenantToken?: TenantTokenSource | undefined);
1137
1208
  private handleReply;
1138
1209
  private request;
1210
+ private send;
1139
1211
  topology(): DurableTopology;
1140
1212
  /**
1141
1213
  * A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
@@ -1187,62 +1259,6 @@ declare function isOperatorRole(options: DurableModuleOptions): boolean;
1187
1259
  */
1188
1260
  declare function isDrivingOperator(options: DurableModuleOptions): boolean;
1189
1261
 
1190
- /**
1191
- * The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
1192
- * "this control plane is older than me" from a real failure and fall back at once. Earlier
1193
- * responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
1194
- */
1195
- declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1196
- /** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
1197
- * correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
1198
- * transports carry the run-request/reply protocol); the caller capability-checks before wiring
1199
- * this up (see `durable.module.ts`). */
1200
- interface RunRequestTransport {
1201
- onRunRequest(handler: (msg: RunRequest) => Promise<void>): void;
1202
- publishRunReply(reply: RunReply): Promise<void>;
1203
- }
1204
- /** Options for {@link RunRequestResponder}. */
1205
- interface RunRequestResponderOptions {
1206
- /**
1207
- * Verifies the signed token a tenant presents in the wire `tenant` field and DERIVES the real
1208
- * tenant from it (see `hmacTenantVerifier`). Present: an invalid, tampered or absent token is
1209
- * rejected with an `unauthorized` error reply and the wire claim is discarded in favour of the
1210
- * verified tenant. Absent: the wire `tenant` is trusted verbatim (prefix/network isolation only).
1211
- */
1212
- verifyTenant?: TenantVerifier | undefined;
1213
- /**
1214
- * Warn at construction when no {@link verifyTenant} is set. Default `true`. `DurableModule` passes
1215
- * `true` only for an explicit `topology: { role: 'control-plane' }`, so a plain operator app that
1216
- * never serves tenants boots silently.
1217
- */
1218
- warnWithoutVerifier?: boolean | undefined;
1219
- }
1220
- /**
1221
- * Operator-side consumer of a tenant's {@link RunRequest}s: answers each one against a
1222
- * `RunGateway`, enforcing the tenant boundary before touching the run. For every runId-bearing
1223
- * verb it loads the run via `getRunDetail` FIRST and compares `run.namespace` to the requesting
1224
- * `msg.tenant` — a mismatch short-circuits into a `cross-tenant` error reply WITHOUT calling the
1225
- * verb, so a tenant can never read or act on another tenant's run. `listRuns` is scoped by
1226
- * overwriting the query's `namespace` with the requester's tenant, ignoring whatever the client
1227
- * sent. This is the security boundary of the tenant run gateway — do not weaken it.
1228
- *
1229
- * With {@link RunRequestResponderOptions.verifyTenant}, every request is authenticated FIRST: the
1230
- * wire `tenant` is treated as a signed token, the real tenant is derived from it, and an invalid
1231
- * token short-circuits into an `unauthorized` error reply before any run is touched. A verifier
1232
- * that throws becomes an error reply too.
1233
- */
1234
- declare class RunRequestResponder {
1235
- private readonly transport;
1236
- private readonly gateway;
1237
- private readonly verifyTenant;
1238
- constructor(transport: RunRequestTransport, gateway: RunGateway, options?: RunRequestResponderOptions);
1239
- /** Register the consumer on the transport. Each request is answered independently; a handler
1240
- * failure never throws back into the transport (errors are captured into an error reply). */
1241
- start(): void;
1242
- private handle;
1243
- private callVerb;
1244
- }
1245
-
1246
1262
  declare const STEP_INTERCEPTOR_METADATA: unique symbol;
1247
1263
  /**
1248
1264
  * The shape a `@StepInterceptor()` provider must implement: `intercept(invocation, next)` wraps the
@@ -1433,4 +1449,4 @@ declare class WorkflowService {
1433
1449
  }): Promise<number>;
1434
1450
  }
1435
1451
 
1436
- 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 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 };
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,4 +1,4 @@
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, 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';
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
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';
@@ -1098,6 +1098,77 @@ declare class InAppWorkerBootstrap implements OnModuleInit, OnApplicationBootstr
1098
1098
  */
1099
1099
  declare function inAppWorkerProviders(): Provider[];
1100
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
+ }
1101
1172
  /**
1102
1173
  * Tenant-side `RunGateway` — round-trips every verb as a `RunRequest`/`RunReply` pair over the
1103
1174
  * transport, correlated by a minted `requestId`, and bridges `subscribe` onto the transport's
@@ -1136,6 +1207,7 @@ declare class ProxyRunGateway implements RunGateway {
1136
1207
  tenantToken?: TenantTokenSource | undefined);
1137
1208
  private handleReply;
1138
1209
  private request;
1210
+ private send;
1139
1211
  topology(): DurableTopology;
1140
1212
  /**
1141
1213
  * A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
@@ -1187,62 +1259,6 @@ declare function isOperatorRole(options: DurableModuleOptions): boolean;
1187
1259
  */
1188
1260
  declare function isDrivingOperator(options: DurableModuleOptions): boolean;
1189
1261
 
1190
- /**
1191
- * The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
1192
- * "this control plane is older than me" from a real failure and fall back at once. Earlier
1193
- * responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
1194
- */
1195
- declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1196
- /** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
1197
- * correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
1198
- * transports carry the run-request/reply protocol); the caller capability-checks before wiring
1199
- * this up (see `durable.module.ts`). */
1200
- interface RunRequestTransport {
1201
- onRunRequest(handler: (msg: RunRequest) => Promise<void>): void;
1202
- publishRunReply(reply: RunReply): Promise<void>;
1203
- }
1204
- /** Options for {@link RunRequestResponder}. */
1205
- interface RunRequestResponderOptions {
1206
- /**
1207
- * Verifies the signed token a tenant presents in the wire `tenant` field and DERIVES the real
1208
- * tenant from it (see `hmacTenantVerifier`). Present: an invalid, tampered or absent token is
1209
- * rejected with an `unauthorized` error reply and the wire claim is discarded in favour of the
1210
- * verified tenant. Absent: the wire `tenant` is trusted verbatim (prefix/network isolation only).
1211
- */
1212
- verifyTenant?: TenantVerifier | undefined;
1213
- /**
1214
- * Warn at construction when no {@link verifyTenant} is set. Default `true`. `DurableModule` passes
1215
- * `true` only for an explicit `topology: { role: 'control-plane' }`, so a plain operator app that
1216
- * never serves tenants boots silently.
1217
- */
1218
- warnWithoutVerifier?: boolean | undefined;
1219
- }
1220
- /**
1221
- * Operator-side consumer of a tenant's {@link RunRequest}s: answers each one against a
1222
- * `RunGateway`, enforcing the tenant boundary before touching the run. For every runId-bearing
1223
- * verb it loads the run via `getRunDetail` FIRST and compares `run.namespace` to the requesting
1224
- * `msg.tenant` — a mismatch short-circuits into a `cross-tenant` error reply WITHOUT calling the
1225
- * verb, so a tenant can never read or act on another tenant's run. `listRuns` is scoped by
1226
- * overwriting the query's `namespace` with the requester's tenant, ignoring whatever the client
1227
- * sent. This is the security boundary of the tenant run gateway — do not weaken it.
1228
- *
1229
- * With {@link RunRequestResponderOptions.verifyTenant}, every request is authenticated FIRST: the
1230
- * wire `tenant` is treated as a signed token, the real tenant is derived from it, and an invalid
1231
- * token short-circuits into an `unauthorized` error reply before any run is touched. A verifier
1232
- * that throws becomes an error reply too.
1233
- */
1234
- declare class RunRequestResponder {
1235
- private readonly transport;
1236
- private readonly gateway;
1237
- private readonly verifyTenant;
1238
- constructor(transport: RunRequestTransport, gateway: RunGateway, options?: RunRequestResponderOptions);
1239
- /** Register the consumer on the transport. Each request is answered independently; a handler
1240
- * failure never throws back into the transport (errors are captured into an error reply). */
1241
- start(): void;
1242
- private handle;
1243
- private callVerb;
1244
- }
1245
-
1246
1262
  declare const STEP_INTERCEPTOR_METADATA: unique symbol;
1247
1263
  /**
1248
1264
  * The shape a `@StepInterceptor()` provider must implement: `intercept(invocation, next)` wraps the
@@ -1433,4 +1449,4 @@ declare class WorkflowService {
1433
1449
  }): Promise<number>;
1434
1450
  }
1435
1451
 
1436
- 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 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 };
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
@@ -1410,7 +1410,18 @@ function _ts_metadata6(metadataKey, metadataValue) {
1410
1410
  }
1411
1411
  }
1412
1412
  __name(_ts_metadata6, "_ts_metadata");
1413
- 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 {
1414
1425
  static {
1415
1426
  __name(this, "UnsupportedRunRequestError");
1416
1427
  }
@@ -1450,15 +1461,17 @@ var ProxyRunGateway = class {
1450
1461
  if (reply.result.ok) {
1451
1462
  pending.resolve(reply.result.data);
1452
1463
  } else if (reply.result.error.code === UNSUPPORTED_RUN_REQUEST) {
1453
- pending.reject(new UnsupportedRunRequestError(reply.result.error.message));
1464
+ pending.reject(new UnsupportedRunRequestError(reply.result.error.message, UNSUPPORTED_RUN_REQUEST));
1454
1465
  } else {
1455
- const { message, code } = reply.result.error;
1456
- pending.reject(code !== void 0 ? Object.assign(new Error(message), {
1457
- code
1458
- }) : new Error(message));
1466
+ pending.reject(new RunGatewayError(reply.result.error.message, reply.result.error.code));
1459
1467
  }
1460
1468
  }
1461
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) {
1462
1475
  return new Promise((resolve, reject) => {
1463
1476
  const requestId = globalThis.crypto.randomUUID();
1464
1477
  const timer = setTimeout(() => {
@@ -1470,17 +1483,11 @@ var ProxyRunGateway = class {
1470
1483
  reject,
1471
1484
  timer
1472
1485
  });
1473
- const source = this.tenantToken;
1474
- const dispatched = typeof source === "function" ? resolveTenantToken2(source).then((tenant) => this.transport.dispatchRunRequest?.({
1486
+ this.transport.dispatchRunRequest?.({
1475
1487
  requestId,
1476
1488
  tenant,
1477
1489
  body
1478
- })) : this.transport.dispatchRunRequest?.({
1479
- requestId,
1480
- tenant: source ?? this.tenant,
1481
- body
1482
- });
1483
- dispatched?.catch((error) => {
1490
+ })?.catch((error) => {
1484
1491
  const stillPending = this.pending.get(requestId);
1485
1492
  if (!stillPending) return;
1486
1493
  clearTimeout(stillPending.timer);
@@ -2140,7 +2147,12 @@ var TimerPoller = class {
2140
2147
  async onApplicationBootstrap() {
2141
2148
  for (const s of this.options.schedules ?? []) workflowName3(s.workflow);
2142
2149
  if (!isDrivingOperator(this.options)) return;
2150
+ this.engine.consumeRuns?.();
2143
2151
  this.unsubscribeEnqueued = this.engine.onEnqueued((runId) => {
2152
+ if (typeof this.engine.runEnqueued === "function") {
2153
+ this.engine.runEnqueued(runId);
2154
+ return;
2155
+ }
2144
2156
  void this.engine.runOne(runId).catch((error) => {
2145
2157
  console.error(`[nestjs-durable] could not run enqueued run ${runId}:`, error);
2146
2158
  });
@@ -3030,6 +3042,7 @@ export {
3030
3042
  RUN_GATEWAY,
3031
3043
  RUN_REDIS_WORKER,
3032
3044
  RunGateway3 as RunGateway,
3045
+ RunGatewayError,
3033
3046
  RunRequestResponder,
3034
3047
  STEP_INTERCEPTOR_METADATA,
3035
3048
  Step,