@cadenza.io/core 3.19.3 → 3.19.4

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.mts CHANGED
@@ -335,13 +335,14 @@ type SchemaDefinition = {
335
335
  type: SchemaType;
336
336
  required?: string[];
337
337
  properties?: {
338
- [key: string]: SchemaDefinition;
338
+ [key: string]: Schema;
339
339
  };
340
- items?: SchemaDefinition;
340
+ items?: Schema;
341
341
  constraints?: SchemaConstraints;
342
342
  description?: string;
343
343
  strict?: boolean;
344
344
  };
345
+ type Schema = SchemaDefinition | SchemaDefinition[];
345
346
 
346
347
  interface Intent {
347
348
  name: string;
@@ -848,9 +849,9 @@ declare class Task extends SignalEmitter implements Graph {
848
849
  readonly isDeputy: boolean;
849
850
  readonly isEphemeral: boolean;
850
851
  readonly isDebounce: boolean;
851
- inputContextSchema: SchemaDefinition;
852
+ inputContextSchema: Schema;
852
853
  validateInputContext: boolean;
853
- outputContextSchema: SchemaDefinition;
854
+ outputContextSchema: Schema;
854
855
  validateOutputContext: boolean;
855
856
  readonly retryCount: number;
856
857
  readonly retryDelay: number;
@@ -886,16 +887,16 @@ declare class Task extends SignalEmitter implements Graph {
886
887
  * @param {boolean} [isSubMeta=false] - Indicates if the task is a sub-meta-task.
887
888
  * @param {boolean} [isHidden=false] - Determines if the task is hidden and not exposed publicly.
888
889
  * @param {ThrottleTagGetter} [getTagCallback=undefined] - A callback to generate a throttle tag for the task.
889
- * @param {SchemaDefinition} [inputSchema=undefined] - The input schema for validating the task's input context.
890
+ * @param {Schema} [inputSchema=undefined] - The input schema for validating the task's input context.
890
891
  * @param {boolean} [validateInputContext=false] - Specifies if the input context should be validated against the input schema.
891
- * @param {SchemaDefinition} [outputSchema=undefined] - The output schema for validating the task's output context.
892
+ * @param {Schema} [outputSchema=undefined] - The output schema for validating the task's output context.
892
893
  * @param {boolean} [validateOutputContext=false] - Specifies if the output context should be validated against the output schema.
893
894
  * @param {number} [retryCount=0] - The number of retry attempts allowed for the task in case of failure.
894
895
  * @param {number} [retryDelay=0] - The initial delay (in milliseconds) between retry attempts.
895
896
  * @param {number} [retryDelayMax=0] - The maximum delay (in milliseconds) allowed between retries.
896
897
  * @param {number} [retryDelayFactor=1] - The factor by which the retry delay increases after each attempt.
897
898
  */
898
- constructor(name: string, task: TaskFunction, description?: string, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: SchemaDefinition, validateInputContext?: boolean, outputSchema?: SchemaDefinition, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
899
+ constructor(name: string, task: TaskFunction, description?: string, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: Schema, validateInputContext?: boolean, outputSchema?: Schema, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
899
900
  clone(traverse?: boolean, includeSignals?: boolean): Task;
900
901
  /**
901
902
  * Retrieves the tag associated with the instance.
@@ -909,8 +910,8 @@ declare class Task extends SignalEmitter implements Graph {
909
910
  setTimeout(timeout: number): void;
910
911
  setConcurrency(concurrency: number): void;
911
912
  setProgressWeight(weight: number): void;
912
- setInputContextSchema(schema: SchemaDefinition): void;
913
- setOutputContextSchema(schema: SchemaDefinition): void;
913
+ setInputContextSchema(schema: Schema): void;
914
+ setOutputContextSchema(schema: Schema): void;
914
915
  setValidateInputContext(value: boolean): void;
915
916
  setValidateOutputContext(value: boolean): void;
916
917
  /**
@@ -937,15 +938,16 @@ declare class Task extends SignalEmitter implements Graph {
937
938
  * Validates a data object against a specified schema definition and returns validation results.
938
939
  *
939
940
  * @param {any} data - The target object to validate against the schema.
940
- * @param {SchemaDefinition | undefined} schema - The schema definition describing the expected structure and constraints of the data.
941
+ * @param {Schema | undefined} schema - The schema definition describing the expected structure and constraints of the data.
941
942
  * @param {string} [path="context"] - The base path or context for traversing the data, used in generating error messages.
942
943
  * @return {{ valid: boolean, errors: Record<string, string> }} - An object containing a validity flag (`valid`)
943
944
  * and a map (`errors`) of validation error messages keyed by property paths.
944
945
  */
945
- validateSchema(data: any, schema: SchemaDefinition | undefined, path?: string): {
946
+ validateSchema(data: any, schema: Schema | undefined, path?: string): {
946
947
  valid: boolean;
947
948
  errors: Record<string, string>;
948
949
  };
950
+ validateProp(prop: SchemaDefinition, key: string, value?: any, path?: string): Record<string, string>;
949
951
  /**
950
952
  * Validates the input context against the predefined schema and emits metadata if validation fails.
951
953
  *
@@ -1686,7 +1688,7 @@ declare class DebounceTask extends Task {
1686
1688
  lastProgressCallback: ((progress: number) => void) | null;
1687
1689
  lastEmitFunction: ((signal: string, context: any) => void) | null;
1688
1690
  lastInquireFunction: ((inquiry: string, context: AnyObject, options: InquiryOptions) => Promise<AnyObject>) | null;
1689
- constructor(name: string, task: TaskFunction, description?: string, debounceTime?: number, leading?: boolean, trailing?: boolean, maxWait?: number, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, inputSchema?: SchemaDefinition | undefined, validateInputSchema?: boolean, outputSchema?: SchemaDefinition | undefined, validateOutputSchema?: boolean);
1691
+ constructor(name: string, task: TaskFunction, description?: string, debounceTime?: number, leading?: boolean, trailing?: boolean, maxWait?: number, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, inputSchema?: Schema | undefined, validateInputSchema?: boolean, outputSchema?: Schema | undefined, validateOutputSchema?: boolean);
1690
1692
  /**
1691
1693
  * Executes the taskFunction with the provided context, emit function, and progress callback.
1692
1694
  * It clears any existing timeout before execution.
@@ -1740,7 +1742,7 @@ declare class EphemeralTask extends Task {
1740
1742
  readonly once: boolean;
1741
1743
  readonly condition: (context: any) => boolean;
1742
1744
  readonly isEphemeral: boolean;
1743
- constructor(name: string, task: TaskFunction, description?: string, once?: boolean, condition?: (context: any) => boolean, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: SchemaDefinition | undefined, validateInputContext?: boolean, outputSchema?: SchemaDefinition | undefined, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
1745
+ constructor(name: string, task: TaskFunction, description?: string, once?: boolean, condition?: (context: any) => boolean, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: Schema | undefined, validateInputContext?: boolean, outputSchema?: Schema | undefined, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
1744
1746
  /**
1745
1747
  * Executes the process logic with the provided context, emit function, progress callback, and node data.
1746
1748
  *
@@ -1801,9 +1803,9 @@ interface TaskOptions {
1801
1803
  isSubMeta?: boolean;
1802
1804
  isHidden?: boolean;
1803
1805
  getTagCallback?: ThrottleTagGetter;
1804
- inputSchema?: SchemaDefinition;
1806
+ inputSchema?: Schema;
1805
1807
  validateInputContext?: boolean;
1806
- outputSchema?: SchemaDefinition;
1808
+ outputSchema?: Schema;
1807
1809
  validateOutputContext?: boolean;
1808
1810
  retryCount?: number;
1809
1811
  retryDelay?: number;
@@ -2256,4 +2258,4 @@ declare class Cadenza {
2256
2258
  static reset(): void;
2257
2259
  }
2258
2260
 
2259
- export { type AnyObject, type CadenzaMode, type DebounceOptions, DebounceTask, type EmitOptions, EphemeralTask, type EphemeralTaskOptions, GraphContext, GraphRegistry, GraphRoutine, GraphRun, GraphRunner, InquiryBroker, type InquiryOptions, type Intent, type SchemaConstraints, type SchemaDefinition, type SchemaType, SignalBroker, SignalEmitter, Task, type TaskFunction, type TaskOptions, type TaskResult, type ThrottleTagGetter, Cadenza as default };
2261
+ export { type AnyObject, type CadenzaMode, type DebounceOptions, DebounceTask, type EmitOptions, EphemeralTask, type EphemeralTaskOptions, GraphContext, GraphRegistry, GraphRoutine, GraphRun, GraphRunner, InquiryBroker, type InquiryOptions, type Intent, type Schema, type SchemaConstraints, type SchemaDefinition, type SchemaType, SignalBroker, SignalEmitter, Task, type TaskFunction, type TaskOptions, type TaskResult, type ThrottleTagGetter, Cadenza as default };
package/dist/index.d.ts CHANGED
@@ -335,13 +335,14 @@ type SchemaDefinition = {
335
335
  type: SchemaType;
336
336
  required?: string[];
337
337
  properties?: {
338
- [key: string]: SchemaDefinition;
338
+ [key: string]: Schema;
339
339
  };
340
- items?: SchemaDefinition;
340
+ items?: Schema;
341
341
  constraints?: SchemaConstraints;
342
342
  description?: string;
343
343
  strict?: boolean;
344
344
  };
345
+ type Schema = SchemaDefinition | SchemaDefinition[];
345
346
 
346
347
  interface Intent {
347
348
  name: string;
@@ -848,9 +849,9 @@ declare class Task extends SignalEmitter implements Graph {
848
849
  readonly isDeputy: boolean;
849
850
  readonly isEphemeral: boolean;
850
851
  readonly isDebounce: boolean;
851
- inputContextSchema: SchemaDefinition;
852
+ inputContextSchema: Schema;
852
853
  validateInputContext: boolean;
853
- outputContextSchema: SchemaDefinition;
854
+ outputContextSchema: Schema;
854
855
  validateOutputContext: boolean;
855
856
  readonly retryCount: number;
856
857
  readonly retryDelay: number;
@@ -886,16 +887,16 @@ declare class Task extends SignalEmitter implements Graph {
886
887
  * @param {boolean} [isSubMeta=false] - Indicates if the task is a sub-meta-task.
887
888
  * @param {boolean} [isHidden=false] - Determines if the task is hidden and not exposed publicly.
888
889
  * @param {ThrottleTagGetter} [getTagCallback=undefined] - A callback to generate a throttle tag for the task.
889
- * @param {SchemaDefinition} [inputSchema=undefined] - The input schema for validating the task's input context.
890
+ * @param {Schema} [inputSchema=undefined] - The input schema for validating the task's input context.
890
891
  * @param {boolean} [validateInputContext=false] - Specifies if the input context should be validated against the input schema.
891
- * @param {SchemaDefinition} [outputSchema=undefined] - The output schema for validating the task's output context.
892
+ * @param {Schema} [outputSchema=undefined] - The output schema for validating the task's output context.
892
893
  * @param {boolean} [validateOutputContext=false] - Specifies if the output context should be validated against the output schema.
893
894
  * @param {number} [retryCount=0] - The number of retry attempts allowed for the task in case of failure.
894
895
  * @param {number} [retryDelay=0] - The initial delay (in milliseconds) between retry attempts.
895
896
  * @param {number} [retryDelayMax=0] - The maximum delay (in milliseconds) allowed between retries.
896
897
  * @param {number} [retryDelayFactor=1] - The factor by which the retry delay increases after each attempt.
897
898
  */
898
- constructor(name: string, task: TaskFunction, description?: string, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: SchemaDefinition, validateInputContext?: boolean, outputSchema?: SchemaDefinition, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
899
+ constructor(name: string, task: TaskFunction, description?: string, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: Schema, validateInputContext?: boolean, outputSchema?: Schema, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
899
900
  clone(traverse?: boolean, includeSignals?: boolean): Task;
900
901
  /**
901
902
  * Retrieves the tag associated with the instance.
@@ -909,8 +910,8 @@ declare class Task extends SignalEmitter implements Graph {
909
910
  setTimeout(timeout: number): void;
910
911
  setConcurrency(concurrency: number): void;
911
912
  setProgressWeight(weight: number): void;
912
- setInputContextSchema(schema: SchemaDefinition): void;
913
- setOutputContextSchema(schema: SchemaDefinition): void;
913
+ setInputContextSchema(schema: Schema): void;
914
+ setOutputContextSchema(schema: Schema): void;
914
915
  setValidateInputContext(value: boolean): void;
915
916
  setValidateOutputContext(value: boolean): void;
916
917
  /**
@@ -937,15 +938,16 @@ declare class Task extends SignalEmitter implements Graph {
937
938
  * Validates a data object against a specified schema definition and returns validation results.
938
939
  *
939
940
  * @param {any} data - The target object to validate against the schema.
940
- * @param {SchemaDefinition | undefined} schema - The schema definition describing the expected structure and constraints of the data.
941
+ * @param {Schema | undefined} schema - The schema definition describing the expected structure and constraints of the data.
941
942
  * @param {string} [path="context"] - The base path or context for traversing the data, used in generating error messages.
942
943
  * @return {{ valid: boolean, errors: Record<string, string> }} - An object containing a validity flag (`valid`)
943
944
  * and a map (`errors`) of validation error messages keyed by property paths.
944
945
  */
945
- validateSchema(data: any, schema: SchemaDefinition | undefined, path?: string): {
946
+ validateSchema(data: any, schema: Schema | undefined, path?: string): {
946
947
  valid: boolean;
947
948
  errors: Record<string, string>;
948
949
  };
950
+ validateProp(prop: SchemaDefinition, key: string, value?: any, path?: string): Record<string, string>;
949
951
  /**
950
952
  * Validates the input context against the predefined schema and emits metadata if validation fails.
951
953
  *
@@ -1686,7 +1688,7 @@ declare class DebounceTask extends Task {
1686
1688
  lastProgressCallback: ((progress: number) => void) | null;
1687
1689
  lastEmitFunction: ((signal: string, context: any) => void) | null;
1688
1690
  lastInquireFunction: ((inquiry: string, context: AnyObject, options: InquiryOptions) => Promise<AnyObject>) | null;
1689
- constructor(name: string, task: TaskFunction, description?: string, debounceTime?: number, leading?: boolean, trailing?: boolean, maxWait?: number, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, inputSchema?: SchemaDefinition | undefined, validateInputSchema?: boolean, outputSchema?: SchemaDefinition | undefined, validateOutputSchema?: boolean);
1691
+ constructor(name: string, task: TaskFunction, description?: string, debounceTime?: number, leading?: boolean, trailing?: boolean, maxWait?: number, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, inputSchema?: Schema | undefined, validateInputSchema?: boolean, outputSchema?: Schema | undefined, validateOutputSchema?: boolean);
1690
1692
  /**
1691
1693
  * Executes the taskFunction with the provided context, emit function, and progress callback.
1692
1694
  * It clears any existing timeout before execution.
@@ -1740,7 +1742,7 @@ declare class EphemeralTask extends Task {
1740
1742
  readonly once: boolean;
1741
1743
  readonly condition: (context: any) => boolean;
1742
1744
  readonly isEphemeral: boolean;
1743
- constructor(name: string, task: TaskFunction, description?: string, once?: boolean, condition?: (context: any) => boolean, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: SchemaDefinition | undefined, validateInputContext?: boolean, outputSchema?: SchemaDefinition | undefined, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
1745
+ constructor(name: string, task: TaskFunction, description?: string, once?: boolean, condition?: (context: any) => boolean, concurrency?: number, timeout?: number, register?: boolean, isUnique?: boolean, isMeta?: boolean, isSubMeta?: boolean, isHidden?: boolean, getTagCallback?: ThrottleTagGetter | undefined, inputSchema?: Schema | undefined, validateInputContext?: boolean, outputSchema?: Schema | undefined, validateOutputContext?: boolean, retryCount?: number, retryDelay?: number, retryDelayMax?: number, retryDelayFactor?: number);
1744
1746
  /**
1745
1747
  * Executes the process logic with the provided context, emit function, progress callback, and node data.
1746
1748
  *
@@ -1801,9 +1803,9 @@ interface TaskOptions {
1801
1803
  isSubMeta?: boolean;
1802
1804
  isHidden?: boolean;
1803
1805
  getTagCallback?: ThrottleTagGetter;
1804
- inputSchema?: SchemaDefinition;
1806
+ inputSchema?: Schema;
1805
1807
  validateInputContext?: boolean;
1806
- outputSchema?: SchemaDefinition;
1808
+ outputSchema?: Schema;
1807
1809
  validateOutputContext?: boolean;
1808
1810
  retryCount?: number;
1809
1811
  retryDelay?: number;
@@ -2256,4 +2258,4 @@ declare class Cadenza {
2256
2258
  static reset(): void;
2257
2259
  }
2258
2260
 
2259
- export { type AnyObject, type CadenzaMode, type DebounceOptions, DebounceTask, type EmitOptions, EphemeralTask, type EphemeralTaskOptions, GraphContext, GraphRegistry, GraphRoutine, GraphRun, GraphRunner, InquiryBroker, type InquiryOptions, type Intent, type SchemaConstraints, type SchemaDefinition, type SchemaType, SignalBroker, SignalEmitter, Task, type TaskFunction, type TaskOptions, type TaskResult, type ThrottleTagGetter, Cadenza as default };
2261
+ export { type AnyObject, type CadenzaMode, type DebounceOptions, DebounceTask, type EmitOptions, EphemeralTask, type EphemeralTaskOptions, GraphContext, GraphRegistry, GraphRoutine, GraphRun, GraphRunner, InquiryBroker, type InquiryOptions, type Intent, type Schema, type SchemaConstraints, type SchemaDefinition, type SchemaType, SignalBroker, SignalEmitter, Task, type TaskFunction, type TaskOptions, type TaskResult, type ThrottleTagGetter, Cadenza as default };
package/dist/index.js CHANGED
@@ -3640,9 +3640,9 @@ var Task = class _Task extends SignalEmitter {
3640
3640
  * @param {boolean} [isSubMeta=false] - Indicates if the task is a sub-meta-task.
3641
3641
  * @param {boolean} [isHidden=false] - Determines if the task is hidden and not exposed publicly.
3642
3642
  * @param {ThrottleTagGetter} [getTagCallback=undefined] - A callback to generate a throttle tag for the task.
3643
- * @param {SchemaDefinition} [inputSchema=undefined] - The input schema for validating the task's input context.
3643
+ * @param {Schema} [inputSchema=undefined] - The input schema for validating the task's input context.
3644
3644
  * @param {boolean} [validateInputContext=false] - Specifies if the input context should be validated against the input schema.
3645
- * @param {SchemaDefinition} [outputSchema=undefined] - The output schema for validating the task's output context.
3645
+ * @param {Schema} [outputSchema=undefined] - The output schema for validating the task's output context.
3646
3646
  * @param {boolean} [validateOutputContext=false] - Specifies if the output context should be validated against the output schema.
3647
3647
  * @param {number} [retryCount=0] - The number of retry attempts allowed for the task in case of failure.
3648
3648
  * @param {number} [retryDelay=0] - The initial delay (in milliseconds) between retry attempts.
@@ -3887,14 +3887,27 @@ var Task = class _Task extends SignalEmitter {
3887
3887
  * Validates a data object against a specified schema definition and returns validation results.
3888
3888
  *
3889
3889
  * @param {any} data - The target object to validate against the schema.
3890
- * @param {SchemaDefinition | undefined} schema - The schema definition describing the expected structure and constraints of the data.
3890
+ * @param {Schema | undefined} schema - The schema definition describing the expected structure and constraints of the data.
3891
3891
  * @param {string} [path="context"] - The base path or context for traversing the data, used in generating error messages.
3892
3892
  * @return {{ valid: boolean, errors: Record<string, string> }} - An object containing a validity flag (`valid`)
3893
3893
  * and a map (`errors`) of validation error messages keyed by property paths.
3894
3894
  */
3895
3895
  validateSchema(data, schema, path = "context") {
3896
3896
  const errors = {};
3897
- if (!schema || typeof schema !== "object") return { valid: true, errors };
3897
+ if (!schema || typeof schema !== "object" && !Array.isArray(schema))
3898
+ return { valid: true, errors };
3899
+ if (Array.isArray(schema)) {
3900
+ for (const s of schema) {
3901
+ const subValidation = this.validateSchema(data, s, path);
3902
+ if (!subValidation.valid) {
3903
+ Object.assign(errors, subValidation.errors);
3904
+ }
3905
+ if (subValidation.valid) {
3906
+ return { valid: true, errors: {} };
3907
+ }
3908
+ }
3909
+ return { valid: false, errors };
3910
+ }
3898
3911
  const required = schema.required || [];
3899
3912
  for (const key of required) {
3900
3913
  if (!(key in data)) {
@@ -3905,84 +3918,12 @@ var Task = class _Task extends SignalEmitter {
3905
3918
  for (const [key, value] of Object.entries(data)) {
3906
3919
  if (key in properties) {
3907
3920
  const prop = properties[key];
3908
- const propType = prop.type;
3909
- if (propType === "any") {
3910
- continue;
3911
- }
3912
- if ((value === void 0 || value === null) && !prop.strict) {
3913
- continue;
3914
- }
3915
- if (propType === "string" && typeof value !== "string") {
3916
- errors[`${path}.${key}`] = `Expected 'string' for '${key}', got '${typeof value}'`;
3917
- } else if (propType === "number" && typeof value !== "number") {
3918
- errors[`${path}.${key}`] = `Expected 'number' for '${key}', got '${typeof value}'`;
3919
- } else if (propType === "boolean" && typeof value !== "boolean") {
3920
- errors[`${path}.${key}`] = `Expected 'boolean' for '${key}', got '${typeof value}'`;
3921
- } else if (propType === "array" && !Array.isArray(value)) {
3922
- errors[`${path}.${key}`] = `Expected 'array' for '${key}', got '${typeof value}'`;
3923
- } else if (propType === "object" && (typeof value !== "object" || value === null || Array.isArray(value))) {
3924
- errors[`${path}.${key}`] = `Expected 'object' for '${key}', got '${typeof value}'`;
3925
- } else if (propType === "array" && prop.items) {
3926
- if (Array.isArray(value)) {
3927
- value.forEach((item, index) => {
3928
- const subValidation = this.validateSchema(
3929
- item,
3930
- prop.items,
3931
- `${path}.${key}[${index}]`
3932
- );
3933
- if (!subValidation.valid) {
3934
- Object.assign(errors, subValidation.errors);
3935
- }
3936
- });
3937
- }
3938
- } else if (propType === "object" && !Array.isArray(value) && value !== null) {
3939
- const subValidation = this.validateSchema(
3940
- value,
3941
- prop,
3942
- `${path}.${key}`
3943
- );
3944
- if (!subValidation.valid) {
3945
- Object.assign(errors, subValidation.errors);
3946
- }
3947
- }
3948
- const constraints = prop.constraints || {};
3949
- if (typeof value === "string") {
3950
- if (constraints.minLength && value.length < constraints.minLength) {
3951
- errors[`${path}.${key}`] = `String '${key}' shorter than minLength ${constraints.minLength}`;
3952
- }
3953
- if (constraints.maxLength && value.length > constraints.maxLength) {
3954
- errors[`${path}.${key}`] = `String '${key}' exceeds maxLength ${constraints.maxLength}`;
3955
- }
3956
- if (constraints.pattern && !new RegExp(constraints.pattern).test(value)) {
3957
- errors[`${path}.${key}`] = `String '${key}' does not match pattern ${constraints.pattern}`;
3958
- }
3959
- } else if (typeof value === "number") {
3960
- if (constraints.min && value < constraints.min) {
3961
- errors[`${path}.${key}`] = `Number '${key}' below min ${constraints.min}`;
3962
- }
3963
- if (constraints.max && value > constraints.max) {
3964
- errors[`${path}.${key}`] = `Number '${key}' exceeds max ${constraints.max}`;
3965
- }
3966
- if (constraints.multipleOf && value % constraints.multipleOf !== 0) {
3967
- errors[`${path}.${key}`] = `Number '${key}' not multiple of ${constraints.multipleOf}`;
3921
+ if (Array.isArray(prop)) {
3922
+ for (const p of prop) {
3923
+ Object.assign(errors, this.validateProp(p, key, value, path));
3968
3924
  }
3969
- } else if (constraints.enum && !constraints.enum.includes(value)) {
3970
- errors[`${path}.${key}`] = `Value '${value}' for '${key}' not in enum ${JSON.stringify(constraints.enum)}`;
3971
- } else if (constraints.format) {
3972
- const formats = {
3973
- email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
3974
- url: /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/,
3975
- "date-time": /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/,
3976
- uuid: /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,
3977
- custom: /.*/
3978
- // Placeholder; override with prop.constraints.pattern if present
3979
- };
3980
- const regex = formats[constraints.format] || new RegExp(constraints.pattern || ".*");
3981
- if (typeof value === "string" && !regex.test(value)) {
3982
- errors[`${path}.${key}`] = `Value '${value}' for '${key}' does not match format '${constraints.format}'`;
3983
- }
3984
- } else if (constraints.oneOf && !constraints.oneOf.includes(value)) {
3985
- errors[`${path}.${key}`] = `Value '${value}' for '${key}' not in oneOf ${JSON.stringify(constraints.oneOf)}`;
3925
+ } else {
3926
+ Object.assign(errors, this.validateProp(prop, key, value, path));
3986
3927
  }
3987
3928
  } else if (schema.strict) {
3988
3929
  errors[`${path}.${key}`] = `Key '${key}' is not allowed`;
@@ -3993,6 +3934,83 @@ var Task = class _Task extends SignalEmitter {
3993
3934
  }
3994
3935
  return { valid: true, errors: {} };
3995
3936
  }
3937
+ validateProp(prop, key, value, path = "context") {
3938
+ const propType = prop.type;
3939
+ const errors = {};
3940
+ if (propType === "any") {
3941
+ return errors;
3942
+ }
3943
+ if ((value === void 0 || value === null) && !prop.strict) {
3944
+ return errors;
3945
+ }
3946
+ if (propType === "string" && typeof value !== "string") {
3947
+ errors[`${path}.${key}`] = `Expected 'string' for '${key}', got '${typeof value}'`;
3948
+ } else if (propType === "number" && typeof value !== "number") {
3949
+ errors[`${path}.${key}`] = `Expected 'number' for '${key}', got '${typeof value}'`;
3950
+ } else if (propType === "boolean" && typeof value !== "boolean") {
3951
+ errors[`${path}.${key}`] = `Expected 'boolean' for '${key}', got '${typeof value}'`;
3952
+ } else if (propType === "array" && !Array.isArray(value)) {
3953
+ errors[`${path}.${key}`] = `Expected 'array' for '${key}', got '${typeof value}'`;
3954
+ } else if (propType === "object" && (typeof value !== "object" || value === null || Array.isArray(value))) {
3955
+ errors[`${path}.${key}`] = `Expected 'object' for '${key}', got '${typeof value}'`;
3956
+ } else if (propType === "array" && prop.items) {
3957
+ value.forEach((item, index) => {
3958
+ const subValidation = this.validateSchema(
3959
+ item,
3960
+ prop.items,
3961
+ `${path}.${key}[${index}]`
3962
+ );
3963
+ if (!subValidation.valid) {
3964
+ Object.assign(errors, subValidation.errors);
3965
+ }
3966
+ });
3967
+ } else if (propType === "object" && !Array.isArray(value) && value !== null) {
3968
+ const subValidation = this.validateSchema(value, prop, `${path}.${key}`);
3969
+ if (!subValidation.valid) {
3970
+ Object.assign(errors, subValidation.errors);
3971
+ }
3972
+ }
3973
+ const constraints = prop.constraints || {};
3974
+ if (typeof value === "string") {
3975
+ if (constraints.minLength && value.length < constraints.minLength) {
3976
+ errors[`${path}.${key}`] = `String '${key}' shorter than minLength ${constraints.minLength}`;
3977
+ }
3978
+ if (constraints.maxLength && value.length > constraints.maxLength) {
3979
+ errors[`${path}.${key}`] = `String '${key}' exceeds maxLength ${constraints.maxLength}`;
3980
+ }
3981
+ if (constraints.pattern && !new RegExp(constraints.pattern).test(value)) {
3982
+ errors[`${path}.${key}`] = `String '${key}' does not match pattern ${constraints.pattern}`;
3983
+ }
3984
+ } else if (typeof value === "number") {
3985
+ if (constraints.min && value < constraints.min) {
3986
+ errors[`${path}.${key}`] = `Number '${key}' below min ${constraints.min}`;
3987
+ }
3988
+ if (constraints.max && value > constraints.max) {
3989
+ errors[`${path}.${key}`] = `Number '${key}' exceeds max ${constraints.max}`;
3990
+ }
3991
+ if (constraints.multipleOf && value % constraints.multipleOf !== 0) {
3992
+ errors[`${path}.${key}`] = `Number '${key}' not multiple of ${constraints.multipleOf}`;
3993
+ }
3994
+ } else if (constraints.enum && !constraints.enum.includes(value)) {
3995
+ errors[`${path}.${key}`] = `Value '${value}' for '${key}' not in enum ${JSON.stringify(constraints.enum)}`;
3996
+ } else if (constraints.format) {
3997
+ const formats = {
3998
+ email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
3999
+ url: /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/,
4000
+ "date-time": /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/,
4001
+ uuid: /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,
4002
+ custom: /.*/
4003
+ // Placeholder; override with prop.constraints.pattern if present
4004
+ };
4005
+ const regex = formats[constraints.format] || new RegExp(constraints.pattern || ".*");
4006
+ if (typeof value === "string" && !regex.test(value)) {
4007
+ errors[`${path}.${key}`] = `Value '${value}' for '${key}' does not match format '${constraints.format}'`;
4008
+ }
4009
+ } else if (constraints.oneOf && !constraints.oneOf.includes(value)) {
4010
+ errors[`${path}.${key}`] = `Value '${value}' for '${key}' not in oneOf ${JSON.stringify(constraints.oneOf)}`;
4011
+ }
4012
+ return errors;
4013
+ }
3996
4014
  /**
3997
4015
  * Validates the input context against the predefined schema and emits metadata if validation fails.
3998
4016
  *