UNPKG

valia

Version:

A runtime data validator in TypeScript with advanced type inference, built-in validation functions, and seamless integration for server and client environments.

112 lines (102 loc) 3.27 kB
import type { RegistryKey, RegistryValue } from "./types"; import type { MountedCriteria } from "../formats"; import { metadataSymbol } from "../services"; import { Issue } from "../../utils"; export function registryManager() { return ({ registry: new Map<RegistryKey, RegistryValue>(), /** * Add the criteria node in the registry. * * @param prevCriteria Previous criteria of `currCriteria` node. * @param currCriteria Current criteria added to the registry. * @param pathSegments Path segments of the `currCriteria` node. */ set( prevNode: RegistryKey | null, currNode: RegistryKey, partPaths: RegistryValue['partPaths'] ) { if (prevNode !== null) { if (!this.registry.has(prevNode)) throw new Issue( "Registry", "The reference of 'prevNode' is not present in the current registry." ); this.registry.get(prevNode)!.nextNodes.add(currNode); } if (this.registry.has(currNode)) { throw new Issue( "Registry", "The reference of 'currNode' is already present in the current registry." ); } this.registry.set(currNode, { nextNodes: new Set(), partPaths }); }, junction(targetNode: MountedCriteria) { const sourceRegistry = targetNode[metadataSymbol].registry; const sourceNode = targetNode[metadataSymbol].saveNode; if (!sourceRegistry.has(sourceNode)) throw new Issue( "Registry", "The source node of the junction criteria is not present in its own registry." ); const valueOfTarget = this.registry.get(targetNode)!; const valueOfSource = sourceRegistry.get(sourceNode)!; // SET TARGET this.registry.set(targetNode, { nextNodes: valueOfSource.nextNodes, partPaths: valueOfTarget.partPaths }); // MERGE REGISTRY let queue: RegistryKey[] = [...valueOfSource.nextNodes.keys()]; while (queue.length > 0) { const referenceKey = queue.pop()!; const referenceValue = sourceRegistry.get(referenceKey)!; this.registry.set(referenceKey, referenceValue); queue.push(...referenceValue.nextNodes.keys()!); } }, getNextNodes(criteria: RegistryKey) { if (!this.registry.has(criteria)) throw new Issue( "Registry", "The criteria reference is not present in the current registry." ); return (this.registry.get(criteria)!.nextNodes); }, /** * **Composition of explicit path :** * ```py * segment = (string / number / symbol) * path = [*(...segment)] * ``` * * **Exemple :** * ```py * my-path = ["struct", "products", "item", "price"] * ``` * * **Composition of implicit path :** * ```py * dynamic-key = ["%", 1*3("string" / "number" / "symbol")] * static-key = ["&", (string / number / symbol)] * segment = dynamic-key / static-key * path = [1*(...segment)] * ``` * * **Exemple :** * ```py * my-path = ["&", "products", "%", "number", "&", "price"] * my-path is products[0].price or products[1].price and continue * ``` */ getPartPaths(criteria: RegistryKey) { if (!this.registry.has(criteria)) throw new Issue( "Registry", "The criteria reference is not present in the current registry." ); return (this.registry.get(criteria)!.partPaths); } }); }