@dudousxd/nestjs-durable 0.52.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.cjs +23 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -58
- package/dist/index.d.ts +74 -58
- package/dist/index.js +22 -14
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
}))
|
|
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);
|
|
@@ -3030,6 +3037,7 @@ export {
|
|
|
3030
3037
|
RUN_GATEWAY,
|
|
3031
3038
|
RUN_REDIS_WORKER,
|
|
3032
3039
|
RunGateway3 as RunGateway,
|
|
3040
|
+
RunGatewayError,
|
|
3033
3041
|
RunRequestResponder,
|
|
3034
3042
|
STEP_INTERCEPTOR_METADATA,
|
|
3035
3043
|
Step,
|