@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.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 sees the input as it was sent, and runs after `input` parses.
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, naming this workflow, the offending key(s), and the schema's issues. The
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 sees the input as it was sent, and runs after `input` parses.
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, naming this workflow, the offending key(s), and the schema's issues. The
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 { FatalError } from "@dudousxd/nestjs-durable-core";
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
- const message = `expected an object, got ${got}`;
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 message = issues.map((i) => i.message).join("; ");
464
- throw new FatalError(`invalid ${label}: ${message}`, code, issues);
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
- if (parseInput) await parseInput(input);
562
- await validateInput?.(input);
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 workflowName3 } from "@dudousxd/nestjs-durable-core";
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, workflowName3(meta.deadLetterWorkflow));
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 ? workflowName3(this.options.deadLetterWorkflow) : void 0;
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
  };