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
75 lines (61 loc) • 2.1 kB
text/typescript
import {groupProblems, validateSchema} from '@sanity/schema/_internal'
import {type SchemaValidationProblem, type SchemaValidationProblemGroup} from '@sanity/types'
import {resolveSchemaTypes} from 'sanity'
import {isMainThread, parentPort, workerData as _workerData} from 'worker_threads'
import {getStudioConfig} from '../util/getStudioWorkspaces'
import {mockBrowserEnvironment} from '../util/mockBrowserEnvironment'
export interface ValidateSchemaWorkerData {
workDir: string
workspace?: string
level?: SchemaValidationProblem['severity']
}
export interface ValidateSchemaWorkerResult {
validation: SchemaValidationProblemGroup[]
}
const {
workDir,
workspace: workspaceName,
level = 'warning',
} = _workerData as ValidateSchemaWorkerData
if (isMainThread || !parentPort) {
throw new Error('This module must be run as a worker thread')
}
const cleanup = mockBrowserEnvironment(workDir)
try {
const workspaces = getStudioConfig({basePath: workDir})
if (!workspaces.length) {
throw new Error(`Configuration did not return any workspaces.`)
}
let workspace
if (workspaceName) {
workspace = workspaces.find((w) => w.name === workspaceName)
if (!workspace) {
throw new Error(`Could not find any workspaces with name \`${workspaceName}\``)
}
} else {
if (workspaces.length !== 1) {
throw new Error(
"Multiple workspaces found. Please specify which workspace to use with '--workspace'.",
)
}
workspace = workspaces[0]
}
const schemaTypes = resolveSchemaTypes({
config: workspace,
context: {dataset: workspace.dataset, projectId: workspace.projectId},
})
const validation = groupProblems(validateSchema(schemaTypes).getTypes())
const result: ValidateSchemaWorkerResult = {
validation: validation
.map((group) => ({
...group,
problems: group.problems.filter((problem) =>
level === 'error' ? problem.severity === 'error' : true,
),
}))
.filter((group) => group.problems.length),
}
parentPort?.postMessage(result)
} finally {
cleanup()
}