npm.io
6.17.0 • Published 2d ago

@sanity/validation

Licence
MIT
Version
6.17.0
Deps
9
Size
213 kB
Vulns
0
Weekly
0
Stars
6.3K

@sanity/validation

Validates complete Sanity documents against a compiled Sanity schema.

import {validateDocument, validationMarkerCodes} from '@sanity/validation'

const result = await validateDocument({document, schema, client})

for (const marker of result.markers) {
  if (marker.code === validationMarkerCodes.stringMinimumLength) {
    const {actualLength, minimumLength} = marker.details || {}
    if (typeof actualLength === 'number' && typeof minimumLength === 'number') {
      console.log(`Expected at least ${minimumLength} characters, got ${actualLength}`)
    }
  }
}

const summary = result.markers
  .map((marker) => {
    const path = marker.path
      .map((segment) => (typeof segment === 'object' ? segment._key : segment))
      .join('.')

    return `[${marker.level}] ${path || '<document>'}: ${marker.message} (${marker.code})`
  })
  .join('\n')

Every failed marker includes a stable machine-readable code alongside its localized message, level, and path. Built-in failures may also include structured details. Custom validators can return their own code and details; custom codes should be namespaced, for example custom.seo-title.

When a check cannot run, result.status is notEvaluated. Omitting client disables custom callbacks and skips network checks. Pass customValidation: false to disable custom callbacks while still providing a client.

Pass one AbortSignal to cancel validation and its pending network work. Built-in checks and client requests made through a custom validator's context.getClient() inherit this signal. A custom getDocumentExists callback receives it as an argument; custom work using another API should pass context.signal to that API. Cancellation rejects with the signal's reason (an AbortError when no custom reason was supplied). Work that does not accept an abort signal cannot be stopped, even though validation itself rejects immediately.

const controller = new AbortController()
const validation = validateDocument({document, schema, client, signal: controller.signal})
const reason = new Error('Validation cancelled')

controller.abort(reason)
try {
  await validation
} catch (error) {
  if (error !== reason) throw error
}

The package does not apply mutations or decide whether a document may be edited or published.

Migrating from sanity

Add @sanity/validation as a direct dependency. The workspace-based API is available as a deprecated compatibility helper, so call sites that only import the validation function can migrate by changing the imported symbol:

import {validateDocumentWithWorkspace} from '@sanity/validation'

const markers = await validateDocumentWithWorkspace({document, workspace})

Call sites that also import ValidateDocumentOptions from sanity should use ValidateDocumentWorkspaceOptions for the workspace-shaped options.

Prefer validateDocument({document, schema, client}) for new code.

Keywords