@dudousxd/nestjs-durable 0.50.0 → 0.51.0
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 +18 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +20 -34
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/skills/durable-workflows/SKILL.md +5 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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, RunStatus, RunWaiting, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, readSearchAttributes } 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';
|
|
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';
|
|
@@ -242,14 +242,16 @@ interface WorkflowOptions {
|
|
|
242
242
|
inputSchema?: IoSchema;
|
|
243
243
|
/**
|
|
244
244
|
* A custom check at `start` (throw to reject) for a rule a schema can't express — a cross-field
|
|
245
|
-
* invariant, an async lookup. It
|
|
245
|
+
* invariant, an async lookup. It runs after `input` parses and receives the parsed value (the input
|
|
246
|
+
* as sent when there is no `input` schema).
|
|
246
247
|
*/
|
|
247
248
|
validateInput?: (input: unknown) => void | Promise<void>;
|
|
248
249
|
/**
|
|
249
250
|
* Validate this workflow's {@link WorkflowCtx.upsertSearchAttributes} writes against a **Standard
|
|
250
251
|
* Schema** (https://standardschema.dev — zod 3.24+, valibot, arktype, …). `ctx.upsertSearchAttributes`
|
|
251
252
|
* validates the MERGED result (existing attributes shallow-merged with the patch) on every call —
|
|
252
|
-
* an invalid merge throws
|
|
253
|
+
* an invalid merge throws a `SchemaValidationError` (code `schema_validation`) naming this workflow,
|
|
254
|
+
* with the schema's issues. The
|
|
253
255
|
* schema's inferred output must be search-attribute-shaped (flat `string`/`number`/`boolean` values
|
|
254
256
|
* only) — a schema whose output has a nested object/array is a compile-time error here. Omit for
|
|
255
257
|
* the prior unvalidated behavior.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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, RunStatus, RunWaiting, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, readSearchAttributes } 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';
|
|
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';
|
|
@@ -242,14 +242,16 @@ interface WorkflowOptions {
|
|
|
242
242
|
inputSchema?: IoSchema;
|
|
243
243
|
/**
|
|
244
244
|
* A custom check at `start` (throw to reject) for a rule a schema can't express — a cross-field
|
|
245
|
-
* invariant, an async lookup. It
|
|
245
|
+
* invariant, an async lookup. It runs after `input` parses and receives the parsed value (the input
|
|
246
|
+
* as sent when there is no `input` schema).
|
|
246
247
|
*/
|
|
247
248
|
validateInput?: (input: unknown) => void | Promise<void>;
|
|
248
249
|
/**
|
|
249
250
|
* Validate this workflow's {@link WorkflowCtx.upsertSearchAttributes} writes against a **Standard
|
|
250
251
|
* Schema** (https://standardschema.dev — zod 3.24+, valibot, arktype, …). `ctx.upsertSearchAttributes`
|
|
251
252
|
* validates the MERGED result (existing attributes shallow-merged with the patch) on every call —
|
|
252
|
-
* an invalid merge throws
|
|
253
|
+
* an invalid merge throws a `SchemaValidationError` (code `schema_validation`) naming this workflow,
|
|
254
|
+
* with the schema's issues. The
|
|
253
255
|
* schema's inferred output must be search-attribute-shaped (flat `string`/`number`/`boolean` values
|
|
254
256
|
* only) — a schema whose output has a nested object/array is a compile-time error here. Omit for
|
|
255
257
|
* the prior unvalidated behavior.
|
package/dist/index.js
CHANGED
|
@@ -393,34 +393,20 @@ import { Inject, Injectable as Injectable2 } from "@nestjs/common";
|
|
|
393
393
|
import { DiscoveryService, MetadataScanner } from "@nestjs/core";
|
|
394
394
|
|
|
395
395
|
// src/schema-parse.ts
|
|
396
|
-
import {
|
|
396
|
+
import { SchemaValidationError } from "@dudousxd/nestjs-durable-core";
|
|
397
397
|
function schemaParser(schema, kind, label) {
|
|
398
398
|
const code = kind === "input" ? "invalid_input" : "invalid_output";
|
|
399
399
|
if (isStandardSchema(schema)) {
|
|
400
400
|
return async (value) => {
|
|
401
401
|
const result = await schema["~standard"].validate(value);
|
|
402
|
-
if (result.issues)
|
|
403
|
-
const issues = result.issues.map((i) => ({
|
|
404
|
-
message: i.message,
|
|
405
|
-
...i.path ? {
|
|
406
|
-
path: i.path.map((p) => String(typeof p === "object" ? p.key : p))
|
|
407
|
-
} : {}
|
|
408
|
-
}));
|
|
409
|
-
throw new FatalError(`invalid ${label}: ${formatIssues(issues)}`, code, issues);
|
|
410
|
-
}
|
|
402
|
+
if (result.issues) throw new SchemaValidationError(label, result.issues, code);
|
|
411
403
|
return result.value;
|
|
412
404
|
};
|
|
413
405
|
}
|
|
414
406
|
if (isZodLike(schema)) {
|
|
415
407
|
return async (value) => {
|
|
416
408
|
const result = schema.safeParse(value);
|
|
417
|
-
if (!result.success)
|
|
418
|
-
const issues = result.error.issues.map((i) => ({
|
|
419
|
-
message: i.message,
|
|
420
|
-
path: i.path.map(String)
|
|
421
|
-
}));
|
|
422
|
-
throw new FatalError(`invalid ${label}: ${formatIssues(issues)}`, code, issues);
|
|
423
|
-
}
|
|
409
|
+
if (!result.success) throw new SchemaValidationError(label, result.error.issues, code);
|
|
424
410
|
return result.data;
|
|
425
411
|
};
|
|
426
412
|
}
|
|
@@ -440,12 +426,11 @@ function classValidatorParser(cls, code, label) {
|
|
|
440
426
|
}
|
|
441
427
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
442
428
|
const got = value === null ? "null" : Array.isArray(value) ? "an array" : typeof value;
|
|
443
|
-
|
|
444
|
-
throw new FatalError(`invalid ${label}: ${message}`, code, [
|
|
429
|
+
throw new SchemaValidationError(label, [
|
|
445
430
|
{
|
|
446
|
-
message
|
|
431
|
+
message: `expected an object, got ${got}`
|
|
447
432
|
}
|
|
448
|
-
]);
|
|
433
|
+
], code);
|
|
449
434
|
}
|
|
450
435
|
const instance = ct.plainToInstance(cls, value);
|
|
451
436
|
const errors = await cv.validate(instance, {
|
|
@@ -460,8 +445,8 @@ function classValidatorParser(cls, code, label) {
|
|
|
460
445
|
String(e.property)
|
|
461
446
|
]
|
|
462
447
|
}));
|
|
463
|
-
const
|
|
464
|
-
throw new
|
|
448
|
+
const summary = issues.map((i) => i.message).join("; ");
|
|
449
|
+
throw new SchemaValidationError(label, issues, code, summary);
|
|
465
450
|
}
|
|
466
451
|
return instance;
|
|
467
452
|
};
|
|
@@ -475,10 +460,6 @@ function isZodLike(schema) {
|
|
|
475
460
|
return typeof schema === "object" && schema !== null && typeof schema.safeParse === "function";
|
|
476
461
|
}
|
|
477
462
|
__name(isZodLike, "isZodLike");
|
|
478
|
-
function formatIssues(issues) {
|
|
479
|
-
return issues.map((i) => i.path && i.path.length > 0 ? `${i.path.join(".")}: ${i.message}` : i.message).join("; ");
|
|
480
|
-
}
|
|
481
|
-
__name(formatIssues, "formatIssues");
|
|
482
463
|
|
|
483
464
|
// src/discovery-helpers.ts
|
|
484
465
|
function scanWorkflows(discovery, register) {
|
|
@@ -558,8 +539,8 @@ function workflowIo(meta) {
|
|
|
558
539
|
const validateInput = meta.validateInput;
|
|
559
540
|
return {
|
|
560
541
|
validateAtStart: parseInput || validateInput ? async (input) => {
|
|
561
|
-
|
|
562
|
-
await validateInput?.(
|
|
542
|
+
const parsed = parseInput ? await parseInput(input) : input;
|
|
543
|
+
await validateInput?.(parsed);
|
|
563
544
|
} : void 0,
|
|
564
545
|
wrap: /* @__PURE__ */ __name((body) => !parseInput && !parseOutput ? body : async (ctx, input) => {
|
|
565
546
|
const output = await body(ctx, parseInput ? await parseInput(input) : input);
|
|
@@ -2076,7 +2057,7 @@ var TenantEventRepublisher = class {
|
|
|
2076
2057
|
};
|
|
2077
2058
|
|
|
2078
2059
|
// src/timer-poller.ts
|
|
2079
|
-
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL5, WorkflowEngine as WorkflowEngine3, runSchedules } from "@dudousxd/nestjs-durable-core";
|
|
2060
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL5, WorkflowEngine as WorkflowEngine3, runSchedules, workflowName as workflowName3 } from "@dudousxd/nestjs-durable-core";
|
|
2080
2061
|
import { Inject as Inject6, Injectable as Injectable9 } from "@nestjs/common";
|
|
2081
2062
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
2082
2063
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -2120,6 +2101,7 @@ var TimerPoller = class {
|
|
|
2120
2101
|
this.options = options;
|
|
2121
2102
|
}
|
|
2122
2103
|
async onApplicationBootstrap() {
|
|
2104
|
+
for (const s of this.options.schedules ?? []) workflowName3(s.workflow);
|
|
2123
2105
|
if (!isDrivingOperator(this.options)) return;
|
|
2124
2106
|
this.unsubscribeEnqueued = this.engine.onEnqueued((runId) => {
|
|
2125
2107
|
void this.engine.runOne(runId).catch((error) => {
|
|
@@ -2221,7 +2203,7 @@ var CONTEXT_ACCESSOR = Symbol.for("@dudousxd/nestjs-context:accessor");
|
|
|
2221
2203
|
var RUN_GATEWAY = RunGateway;
|
|
2222
2204
|
|
|
2223
2205
|
// src/workflow.registrar.ts
|
|
2224
|
-
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL6, RemoteWorkflowExecutor, STATE_STORE_CANONICAL as STATE_STORE_CANONICAL3, WorkflowEngine as WorkflowEngine4, bindWorkflowClass, parseDuration as parseDuration2, sanitizeQueueToken, tenantGroup, workflowName as
|
|
2206
|
+
import { DURABLE_OPTIONS_CANONICAL as DURABLE_OPTIONS_CANONICAL6, RemoteWorkflowExecutor, STATE_STORE_CANONICAL as STATE_STORE_CANONICAL3, WorkflowEngine as WorkflowEngine4, bindWorkflowClass, parseDuration as parseDuration2, sanitizeQueueToken, tenantGroup, workflowName as workflowName4 } from "@dudousxd/nestjs-durable-core";
|
|
2225
2207
|
import { Inject as Inject7, Injectable as Injectable10 } from "@nestjs/common";
|
|
2226
2208
|
import { DiscoveryService as DiscoveryService4, MetadataScanner as MetadataScanner4 } from "@nestjs/core";
|
|
2227
2209
|
|
|
@@ -2388,7 +2370,7 @@ var WorkflowRegistrar = class {
|
|
|
2388
2370
|
});
|
|
2389
2371
|
deadLetterByWorkflow.set(meta.name, dlqName);
|
|
2390
2372
|
} else if (meta.deadLetterWorkflow) {
|
|
2391
|
-
deadLetterByWorkflow.set(meta.name,
|
|
2373
|
+
deadLetterByWorkflow.set(meta.name, workflowName4(meta.deadLetterWorkflow));
|
|
2392
2374
|
}
|
|
2393
2375
|
});
|
|
2394
2376
|
this.reportUnattributed(unattributed);
|
|
@@ -2436,7 +2418,7 @@ var WorkflowRegistrar = class {
|
|
|
2436
2418
|
* a `dlq:<runId>` id, so re-recovery never double-dispatches.
|
|
2437
2419
|
*/
|
|
2438
2420
|
installDeadLetterRouting(byWorkflow) {
|
|
2439
|
-
const fallback = this.options.deadLetterWorkflow ?
|
|
2421
|
+
const fallback = this.options.deadLetterWorkflow ? workflowName4(this.options.deadLetterWorkflow) : void 0;
|
|
2440
2422
|
if (byWorkflow.size === 0 && !fallback) return;
|
|
2441
2423
|
this.engine.onDead((run) => {
|
|
2442
2424
|
const target = byWorkflow.get(run.workflow) ?? fallback;
|
|
@@ -2972,7 +2954,7 @@ DurableModule = _ts_decorate12([
|
|
|
2972
2954
|
], DurableModule);
|
|
2973
2955
|
|
|
2974
2956
|
// src/index.ts
|
|
2975
|
-
import { readSearchAttributes as readSearchAttributes2, RunGateway as RunGateway3, WorkflowEngine as WorkflowEngine7 } from "@dudousxd/nestjs-durable-core";
|
|
2957
|
+
import { prevCronFireMs, readSearchAttributes as readSearchAttributes2, RunGateway as RunGateway3, runSchedules as runSchedules2, scheduledRunId, scheduleRunIdAt, WorkflowEngine as WorkflowEngine7 } from "@dudousxd/nestjs-durable-core";
|
|
2976
2958
|
export {
|
|
2977
2959
|
CONTEXT_ACCESSOR,
|
|
2978
2960
|
DEAD_LETTER_METADATA,
|
|
@@ -3028,7 +3010,11 @@ export {
|
|
|
3028
3010
|
isOperatorRole,
|
|
3029
3011
|
isStepInterceptor,
|
|
3030
3012
|
onErrorCodesOf,
|
|
3013
|
+
prevCronFireMs,
|
|
3031
3014
|
readSearchAttributes2 as readSearchAttributes,
|
|
3015
|
+
runSchedules2 as runSchedules,
|
|
3016
|
+
scheduleRunIdAt,
|
|
3017
|
+
scheduledRunId,
|
|
3032
3018
|
thinWorkerProviders,
|
|
3033
3019
|
unavailableRunGateway
|
|
3034
3020
|
};
|