structured-elements
Version:
A TypeScript package for modelling and validating data
160 lines • 10.6 kB
TypeScript
export { Mirror } from "./mirror";
import { referenceToken } from "./constants";
export declare namespace StructuredElements {
type BaseRegistry = Record<string, CacheableSubject>;
type ModelRegistry<Registry extends BaseRegistry> = Map<keyof Registry, RegistryEntry<Registry, keyof Registry>>;
type API<Registry extends BaseRegistry> = {
debugEnabled: () => boolean;
equality: APIMethods.BuildEqualityCheck<Registry>;
registeredModels: APIMethods.GetModelRegistry<Registry>;
reference: APIMethods.BuildReference<Registry>;
results: ExpectationResultCache<Registry, CacheableSubject>;
validator: APIMethods.GetValidator<Registry>;
attemptSalvage: {
array: Functions.AttemptSalvage<`array`>;
collection: Functions.AttemptSalvage<`collection`>;
item: Functions.AttemptSalvage<`item`>;
itemViaBlanking: Functions.AttemptSalvage<`item`>;
mirror: Functions.AttemptSalvage<`mirror`>;
};
privateFunctions: {
cacheResult: APIMethods.CacheResult<Registry>;
debug: typeof console.log;
getCachedResult: APIMethods.GetCachedResult<Registry>;
buildRegistryEntry: APIMethods.BuildRegistryEntry<Registry>;
};
internalCache: {
buildEqualityCheck?: APIMethods.BuildEqualityCheck<Registry>;
cacheResult?: APIMethods.CacheResult<Registry>;
getCachedResult?: APIMethods.GetCachedResult<Registry>;
getValidator?: APIMethods.GetValidator<Registry>;
modelRegistry?: ModelRegistry<Registry>;
prepareModelRegistry: Functions.PrepareModelRegistry<Registry>;
reference?: APIMethods.BuildReference<Registry>;
registerModel?: APIMethods.BuildRegistryEntry<Registry>;
validators: Map<Expectation<Registry, any>, ReferenceValidators<any>>;
};
};
const setup: <Registry extends BaseRegistry>({ debugEnabled, logDebugMessage, models, }: {
debugEnabled: () => boolean;
logDebugMessage?: ((...data: any[]) => void) | undefined;
models: Functions.PrepareModelRegistry<Registry>;
}) => API<Registry>;
type RegistryEntry<Registry extends BaseRegistry, ModelId extends keyof Registry> = {
modelId: ModelId;
expect: () => Expectation<Registry, Registry[ModelId]>;
validators: () => ReferenceValidators<Registry[ModelId]>;
};
type ReferenceContainer<Registry extends BaseRegistry, Subject, Structure extends StructureOption> = {
[referenceToken]: {
structure: Structure;
target: ReferenceTarget<Registry, Subject>;
};
};
type ReferenceTarget<Registry extends BaseRegistry, Subject> = Subject extends Registry[keyof Registry] ? keyof Registry : Expectation<Registry, Subject>;
type ReferenceToken = `_StructuredElementsReference`;
type ValidationResult<Subject> = {
failures: Failure[];
salvage: Subject | undefined;
} & ({
subject: Subject;
valid: true;
} | {
subject: unknown;
valid: false;
});
namespace APIMethods {
type CacheResult<Registry extends BaseRegistry> = <Structure extends StructureOption, Element>(args: {
expectation: Expectation<Registry, Element>;
result: ValidationResult<StructuredElement<Structure, Element>>;
structure: Structure;
}) => ValidationResult<StructuredElement<Structure, Element>>;
const curryCacheResult: <Registry extends BaseRegistry>(api: API<Registry>) => CacheResult<Registry>;
type GetCachedResult<Registry extends BaseRegistry> = <Structure extends StructureOption, Element>({ expectation, structure, subject, }: {
expectation: Expectation<Registry, Element>;
structure: Structure;
subject: StructuredElement<Structure, Element> | unknown;
}) => ValidationResult<StructuredElement<Structure, Element>> | undefined;
const curryGetCachedResult: <Registry extends BaseRegistry>(api: API<Registry>) => <Structure extends StructureOption, Element_1>({ expectation, structure, subject, }: {
expectation: Expectation<Registry, Element_1>;
structure: Structure;
subject: unknown;
}) => ValidationResult<StructuredElement<Structure, Element_1>> | undefined;
type GetValidator<Registry extends BaseRegistry> = <Element, ExpectationArg extends Expectation<Registry, Element> | keyof Registry, Structure extends StructureOption = `item`>(expectation: ExpectationArg, structure?: Structure) => Validator<ExpectationArg extends keyof Registry ? Registry[ExpectationArg] : Element, Structure>;
const curryGetValidator: <Registry extends BaseRegistry>(api: API<Registry>) => GetValidator<Registry>;
type BuildEqualityCheck<Registry extends BaseRegistry> = <Subject, Structure extends StructureOption>(structure: Structure, target: Subject | Subject[]) => ReferenceContainer<Registry, Subject, Structure>;
const curryBuildEqualityCheck: <Registry extends BaseRegistry>() => BuildEqualityCheck<Registry>;
type BuildReference<Registry extends BaseRegistry> = <Subject, Structure extends StructureOption>(structure: Structure, target: Subject extends Registry[keyof Registry] ? keyof Registry : Expectation<Registry, Subject>) => ReferenceContainer<Registry, Subject, Structure>;
const curryBuildReference: <Registry extends BaseRegistry>() => BuildReference<Registry>;
type BuildRegistryEntry<Registry extends BaseRegistry> = <ModelId extends keyof Registry>(args: {
modelId: ModelId;
expect: Functions.BuildModelExpectation<Registry, ModelId>;
}) => RegistryEntry<Registry, ModelId>;
const curryBuildRegistryEntry: <Registry extends BaseRegistry>(api: API<Registry>) => BuildRegistryEntry<Registry>;
type GetModelRegistry<Registry extends BaseRegistry> = () => Map<keyof Registry, RegistryEntry<Registry, keyof Registry>>;
}
type CacheableSubject = object;
type ExpectationResultCache<Registry extends BaseRegistry, Element> = Map<Expectation<Registry, Element>, StructuredResultCache<Element>>;
type StructuredResultCache<Element> = Map<StructureOption, SubjectResultCache<StructureOption, Element>>;
type SubjectResultCache<Structure extends StructureOption, Element> = WeakMap<CacheableSubject, ValidationResult<StructuredElement<Structure, Element>>>;
const isCacheable: <Subject extends object>(subject: unknown) => subject is Subject;
type StructureOption = `array` | `collection` | `item` | `mirror`;
type StructuredElement<Structure extends StructureOption, Element> = Structure extends `array` ? Element[] : Structure extends `collection` ? Collection<Element> : Structure extends `mirror` ? Mirror<Element> : Structure extends `item` ? Element : never;
type Collection<Element> = Record<string, Element> & {
[referenceToken]?: never;
};
type Item = Record<string, any> & {
[referenceToken]?: never;
};
type Mirror<Element> = {
array: Readonly<Element[]>;
collection: Readonly<Collection<Element>>;
[referenceToken]?: never;
};
type Expectation<Registry extends BaseRegistry, Subject> = keyof Registry | ExpectationArray<Registry, Subject> | ReferenceContainer<Registry, Subject, StructureOption> | RecordSchema<Registry, Subject> | PrimitiveExpectation<Subject> | FunctionalExpectation<Subject>;
type ExpectationArray<Registry extends BaseRegistry, Subject> = (Expectation<Registry, Subject> | null | undefined)[];
type ModelExpectation<Registry extends BaseRegistry, ModelId extends keyof Registry> = RecordSchema<Registry, Registry[ModelId]> | FunctionalExpectation<Registry[ModelId]> | ModelArray<Registry, ModelId>;
type ModelArray<Registry extends BaseRegistry, ModelId extends keyof Registry> = ModelExpectation<Registry, ModelId>[];
type FunctionalExpectation<Subject> = (subject: unknown) => subject is Subject;
type PrimitiveExpectation<Subject> = Subject extends string ? `string` : Subject extends number ? `number` : Subject extends boolean ? `boolean` : Subject extends Date ? `date` : never;
type Failure = {
element: unknown;
expectation: Expectation<any, any>;
failures?: Failure[];
key: string | number;
name: string;
reason: string | FailureReport[];
subject: unknown;
};
type FailureReport = {
expectation: Expectation<any, any>;
path: string;
reason: string;
value: unknown;
};
type RecordSchema<Registry extends BaseRegistry, Subject> = Subject extends object ? Required<{
[Key in keyof Subject]: Expectation<Registry, Subject[keyof Subject]>;
}> : never;
type typeofString = string;
type Validator<Element, Structure extends StructureOption = `item`> = {
getFailures: (subject: unknown, name: string) => Failure[];
getSalvage: (subject: unknown, name: string, attemptSalvage?: Functions.AttemptSalvage<Structure>) => StructuredElement<Structure, Element> | undefined;
isValid: (subject: unknown, name: string) => subject is StructuredElement<Structure, Element>;
validate: (subject: unknown, name: string, attemptSalvage?: Functions.AttemptSalvage<Structure>) => ValidationResult<StructuredElement<Structure, Element>>;
};
type ReferenceValidators<Element> = Record<StructureOption, Validator<Element, StructureOption>>;
namespace Functions {
type AttemptSalvage<Structure extends StructureOption> = <Registry extends BaseRegistry, Element>(args: {
api: API<Registry>;
failures: Failure[];
name: string;
subject: unknown;
validElements?: Structure extends `item` ? Partial<Element> : StructuredElement<Structure, Element>;
}) => StructuredElement<Structure, Element> | undefined;
type PrepareModelRegistry<Registry extends BaseRegistry> = () => Record<keyof Registry, BuildModelExpectation<Registry, keyof Registry>>;
type BuildModelExpectation<Registry extends BaseRegistry, ModelId extends keyof Registry> = () => ModelExpectation<Registry, ModelId>;
type Expect<Registry extends BaseRegistry, ModelId extends keyof Registry> = (modelId: ModelId) => Expectation<Registry, Registry[ModelId]>;
type IsValid<Subject> = (subject: unknown) => subject is Subject;
}
}
//# sourceMappingURL=index.d.ts.map