UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

111 lines (97 loc) 3.07 kB
import {type ClientConfig} from '@sanity/client' import {type ValidationMarker} from '@sanity/types' import path from 'path' import readPkgUp from 'read-pkg-up' import {Worker} from 'worker_threads' import { type ValidateDocumentsWorkerData, type ValidationWorkerChannel, } from '../../threads/validateDocuments' import {createReceiver, type WorkerChannelReceiver} from '../../util/workerChannels' const DEFAULT_MAX_CUSTOM_VALIDATION_CONCURRENCY = 5 export interface ValidateDocumentsOptions<TReturn = unknown> { level?: 'error' | 'warning' | 'info' workspace?: string workDir?: string configPath?: string clientConfig?: Partial<ClientConfig> projectId?: string // override dataset?: string // override ndjsonFilePath?: string maxCustomValidationConcurrency?: number reporter?: (worker: WorkerChannelReceiver<ValidationWorkerChannel>) => TReturn } export interface DocumentValidationResult { documentId: string documentType: string revision: string level: ValidationMarker['level'] markers: ValidationMarker[] } const defaultReporter = ({stream, dispose}: WorkerChannelReceiver<ValidationWorkerChannel>) => { async function* createValidationGenerator() { for await (const {documentId, documentType, markers, revision, level} of stream.validation()) { const result: DocumentValidationResult = { documentId, documentType, revision, level, markers, } yield result } await dispose() } return createValidationGenerator() } export function validateDocuments<TReturn>( options: ValidateDocumentsOptions<TReturn> & Required<Pick<ValidateDocumentsOptions<TReturn>, 'reporter'>>, ): TReturn export function validateDocuments( options: ValidateDocumentsOptions, ): AsyncIterable<DocumentValidationResult> export function validateDocuments(options: ValidateDocumentsOptions): unknown { const { workspace, clientConfig, configPath, dataset, projectId, workDir = process.cwd(), reporter = defaultReporter, level, maxCustomValidationConcurrency, ndjsonFilePath, } = options const rootPkgPath = readPkgUp.sync({cwd: __dirname})?.path if (!rootPkgPath) { throw new Error('Could not find root directory for `sanity` package') } const workerPath = path.join( path.dirname(rootPkgPath), 'lib', '_internal', 'cli', 'threads', 'validateDocuments.js', ) const worker = new Worker(workerPath, { workerData: { workDir, // removes props in the config that make this object fail to serialize clientConfig: JSON.parse(JSON.stringify(clientConfig)), configPath, workspace, dataset, projectId, level, ndjsonFilePath, maxCustomValidationConcurrency: maxCustomValidationConcurrency ?? DEFAULT_MAX_CUSTOM_VALIDATION_CONCURRENCY, } satisfies ValidateDocumentsWorkerData, // eslint-disable-next-line no-process-env env: process.env, }) return reporter(createReceiver<ValidationWorkerChannel>(worker)) }