UNPKG

@dossierhq/core

Version:

The core Dossier library used by clients and server alike, used to interact with schema and entities directly, as well as remotely through a client.

148 lines 5.42 kB
/// <reference types="./ContentUtils.d.ts" /> import { FieldType, } from '../schema/SchemaSpecification.js'; import { assertExhaustive } from '../utils/Asserts.js'; import { isRichTextRootNode } from './ContentTypeUtils.js'; export function getEntityNameBase(name) { const hashIndex = name.lastIndexOf('#'); if (hashIndex < 0) { return name; } return name.slice(0, hashIndex); } export function isEntityNameAsRequested(currentName, requestedName) { if (requestedName === currentName) { return true; } const currentNameBase = getEntityNameBase(currentName); return requestedName === currentNameBase; } export function copyEntity(entity, changes) { const copy = { ...entity }; if (typeof changes.id === 'string') { copy.id = changes.id; } if (changes.info) { copy.info = { ...entity.info }; for (const [key, value] of Object.entries(changes.info)) { copy.info[key] = value; } } if (changes.fields) { const fieldsCopy = { ...entity.fields }; copy.fields = fieldsCopy; for (const [key, value] of Object.entries(changes.fields)) { fieldsCopy[key] = value; } } return copy; } export function checkFieldTraversable(fieldSpec, value) { if (fieldSpec.list) { if (value !== null && value !== undefined && !Array.isArray(value)) { return { path: [], message: `Expected a list of ${fieldSpec.type}, got ${typeof value}` }; } } return null; } export function checkFieldItemTraversable(fieldSpec, value) { const { type } = fieldSpec; if (value === null || value === undefined) { return null; } if (Array.isArray(value)) { return { path: [], message: `Expected single ${type}, got a list` }; } switch (type) { case FieldType.Boolean: { if (typeof value !== 'boolean') { return { path: [], message: `Expected a boolean, got ${typeof value}` }; } break; } case FieldType.Component: { if (typeof value !== 'object') { return { path: [], message: `Expected a Component object, got ${typeof value}` }; } if (!('type' in value)) { return { path: ['type'], message: `Missing a Component type` }; } if (typeof value.type !== 'string') { return { path: ['type'], message: `Expected a Component type, got ${typeof value}` }; } break; } case FieldType.Reference: { if (typeof value !== 'object') { return { path: [], message: `Expected an entity reference, got ${typeof value}` }; } if (typeof value.id !== 'string') { return { path: ['id'], message: `Expected an entity reference id, got ${typeof value.id}`, }; } break; } case FieldType.Location: { if (typeof value !== 'object') { return { path: [], message: `Expected a Location object, got ${typeof value}` }; } const { lat, lng } = value; if (typeof lat !== 'number' || typeof lng !== 'number') { return { path: [], message: `Expected {lat: number, lng: number}, got {lat: ${typeof lat}, lng: ${typeof lng}}`, }; } break; } case FieldType.Number: { if (typeof value !== 'number') { return { path: [], message: `Expected a number, got ${typeof value}` }; } break; } case FieldType.RichText: { if (typeof value !== 'object') { return { path: [], message: `Expected a RichText object, got ${typeof value}` }; } const root = value.root; if (!root) { return { path: [], message: `RichText object is missing root` }; } const rootTraversalError = checkRichTextNodeTraversable(root); if (rootTraversalError) { return { path: ['root', ...rootTraversalError.path], message: rootTraversalError.message }; } if (!isRichTextRootNode(root)) { return { path: ['root'], message: `RichText root is not a valid RichText node, (got ${root.type})`, }; } break; } case FieldType.String: { if (typeof value !== 'string') { return { path: [], message: `Expected a string, got ${typeof value}` }; } break; } default: assertExhaustive(type); } return null; } export function checkRichTextNodeTraversable(node) { if (!node || typeof node !== 'object') { return { path: [], message: `Expected a RichText node, got ${typeof node}` }; } if (typeof node.type !== 'string') { return { path: [], message: `RichText node is missing type` }; } if ('children' in node && !Array.isArray(node.children)) { return { path: [], message: `RichText node children is not an array` }; } return null; } //# sourceMappingURL=ContentUtils.js.map