Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,14 @@ export type {
TestResultInvalid,
SchemaValidationRecordErrorDetails,
SchemaRecordError,
SchemaValidationErrorReason,
DictionaryValidationRecordErrorDetails,
DictionaryValidationError,
DictionaryValidationErrorReason,
FieldValidationErrorRestrictionInfo,
FieldValidationError,
FieldValidationErrorReason,
RecordValidationErrorReason,
ParseDictionaryData,
ParseDictionaryFailure,
ParseDictionaryResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,25 @@
import type { FieldDetails } from '../validateRecord';
import type { SchemaRecordError, SchemaValidationRecordErrorDetails } from '../validateSchema';

/**
* Shared properties for all dictionary validation errors. Carries the name of the schema
* being validated.
*/
export type DictionaryValidationErrorBase = {
schemaName: string;
};

/**
* Error for a record submitted for a schema name that does not exist in the dictionary.
*/
export type DictionaryValidationErrorUnrecognizedSchema = DictionaryValidationErrorBase & {
reason: 'UNRECOGNIZED_SCHEMA';
};

/**
* Error for a field value that fails a foreign key constraint; `foreignSchema` identifies the
* referenced schema and field that the value must exist in.
*/
export type DictionaryValidationErrorRecordForeignKey = FieldDetails & {
reason: 'INVALID_BY_FOREIGNKEY';
foreignSchema: {
Expand All @@ -36,15 +47,31 @@ export type DictionaryValidationErrorRecordForeignKey = FieldDetails & {
};
};

/**
* All error detail types that can appear on a record when validating against a dictionary,
* including foreign key errors.
*/
export type DictionaryValidationRecordErrorDetails =
| SchemaValidationRecordErrorDetails
| DictionaryValidationErrorRecordForeignKey;

/**
* Error for a schema submission that contains one or more invalid records; `invalidRecords` contains a list of
* record validation errors grouped by record.
*/
export type DictionaryValidationErrorInvalidRecords = DictionaryValidationErrorBase & {
reason: 'INVALID_RECORDS';
invalidRecords: SchemaRecordError<DictionaryValidationRecordErrorDetails>[];
};

/**
* A dictionary-level validation error. Narrow on `reason` to access the specific error properties.
*/
export type DictionaryValidationError =
| DictionaryValidationErrorUnrecognizedSchema
| DictionaryValidationErrorInvalidRecords;

/**
* All `reason` values for a `DictionaryValidationError`.
*/
export type DictionaryValidationErrorReason = DictionaryValidationError['reason'];
20 changes: 18 additions & 2 deletions packages/validation/src/validateField/FieldValidationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,39 @@ import type { SchemaFieldValueType } from '@overture-stack/lectern-dictionary';
import type { FieldRestrictionRule } from '../validateField/FieldRestrictionRule';
import type { RestrictionTestInvalidInfo } from '../validateField/FieldRestrictionTest';

/**
* Information for an error validating a field against a restriction. Includes a restriction rule
* paired with the details of why it failed.
*/
export type FieldValidationErrorRestrictionInfo = RestrictionTestInvalidInfo & {
restriction: FieldRestrictionRule;
};

/**
* Error for a field value that fails one or more restriction rules (codeList, regex, range, etc.).
* `errors` lists each individual restriction that was violated.
*/
export type FieldValidationErrorRestrictions = {
reason: 'INVALID_BY_RESTRICTION';
errors: Array<FieldValidationErrorRestrictionInfo>;
};

/**
* This is the result when the value does not match the value type defined in the field. The properties
* `valueType` and `isArray` are the expected type values as defined in the field definition.
* Validation error for a field value that does not match the field's declared `valueType` or
* `isArray`.
*/
export type FieldValidationErrorValueType = {
reason: 'INVALID_VALUE_TYPE';
valueType: SchemaFieldValueType;
isArray: boolean;
};

/**
* A field-level validation error. Narrow on `reason` to access the specific error properties.
*/
export type FieldValidationError = FieldValidationErrorRestrictions | FieldValidationErrorValueType;

/**
* All `reason` values for a `FieldValidationError`.
*/
export type FieldValidationErrorReason = FieldValidationError['reason'];
Comment thread
justincorrigible marked this conversation as resolved.
24 changes: 24 additions & 0 deletions packages/validation/src/validateRecord/RecordValidationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,42 @@ import type {
FieldValidationErrorValueType,
} from '../validateField/FieldValidationError';

/**
* The name and submitted value of a field involved in a validation error.
*/
export type FieldDetails = {
fieldName: string;
fieldValue: DataRecordValue;
};

/**
* Record-level validation error for a field value that does not match the field's declared
* `valueType` or `isArray`. Includes the field name and submitted value alongside the type mismatch details.
*/
export type RecordValidationErrorInvalidValue = FieldDetails & FieldValidationErrorValueType;

/**
* Record-level validation error for a field value that violates one or more restriction rules.
* Includes the field name and submitted value alongside the restriction failure details.
*/
export type RecordValidationErrorRestrictions = FieldDetails & FieldValidationErrorRestrictions;

/**
* Error for a field name present in the record that is not defined in the schema.
*/
export type RecordValidationErrorUnrecognizedField = FieldDetails & {
reason: 'UNRECOGNIZED_FIELD';
};

/**
* A record-level validation error. Narrow on `reason` to access the specific error properties.
*/
export type RecordValidationError =
| RecordValidationErrorInvalidValue
| RecordValidationErrorRestrictions
| RecordValidationErrorUnrecognizedField;

/**
* All `reason` values for a `RecordValidationError`.
*/
export type RecordValidationErrorReason = RecordValidationError['reason'];
23 changes: 23 additions & 0 deletions packages/validation/src/validateSchema/SchemaValidationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,48 @@
import type { DataRecord } from '@overture-stack/lectern-dictionary';
import type { RecordValidationError, FieldDetails } from '../validateRecord';

/**
* Error for a record that violates a `uniqueKey` constraint. `uniqueKey` holds the conflicting
* composite key values; `matchingRecords` lists indices of records sharing that key.
*/
export type SchemaValidationRecordErrorUniqueKey = {
reason: 'INVALID_BY_UNIQUE_KEY';
uniqueKey: DataRecord;
matchingRecords: number[];
};

/**
* Error for a Record where a field value that violates a `unique` constraint.
* `matchingRecords` lists the indices of records with the same value in the specified field.
*/
export type SchemaValidationRecordErrorUnique = FieldDetails & {
reason: 'INVALID_BY_UNIQUE';
matchingRecords: number[];
};

/**
* All error detail types that can appear on a record when validating against a schema.
*/
export type SchemaValidationRecordErrorDetails =
| RecordValidationError
| SchemaValidationRecordErrorUnique
| SchemaValidationRecordErrorUniqueKey;

/**
* Pairing of a record's position in the submitted data alongside the validation errors it produced.
*/
export type SchemaRecordError<ErrorDetails> = {
recordIndex: number;
recordErrors: ErrorDetails[];
};

/**
* Error produced when validating a set of records against a schema. Groups per-record errors by
* their index in the submitted data.
*/
export type SchemaValidationError = SchemaRecordError<SchemaValidationRecordErrorDetails>;

/**
* All `reason` values across schema-level record errors.
*/
export type SchemaValidationErrorReason = SchemaValidationRecordErrorDetails['reason'];
Comment thread
justincorrigible marked this conversation as resolved.