Skip to content

Commit

Permalink
fix(schema): correctly assert optional fields with enforce required f…
Browse files Browse the repository at this point in the history
…ields
  • Loading branch information
sgulseth committed Mar 25, 2024
1 parent a272c71 commit d4639aa
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
7 changes: 6 additions & 1 deletion packages/@sanity/schema/src/sanity/extractSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,15 @@ export function extractSchema(
if (value === null) {
continue
}

// if we extract with enforceRequiredFields, we will mark the field as optional only if it is not a required field,
// else we will always mark it as optional
const optional = extractOptions.enforceRequiredFields ? fieldIsRequired === false : true

attributes[field.name] = {
type: 'objectAttribute',
value,
optional: extractOptions.enforceRequiredFields ? fieldIsRequired : true,
optional,
}
}

Expand Down
72 changes: 71 additions & 1 deletion packages/@sanity/schema/test/extractSchema/extractSchema.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from 'node:assert'

import {describe, expect, test} from '@jest/globals'
import {defineType} from '@sanity/types'
import {defineField, defineType} from '@sanity/types'

import {Schema} from '../../src/legacy/Schema'
import {extractSchema} from '../../src/sanity/extractSchema'
Expand Down Expand Up @@ -367,6 +367,76 @@ describe('Extract schema test', () => {
])
})

test('all fields are marked as optional without "enforceRequiredFields"', () => {
const schema1 = createSchema({
name: 'test',
types: [
{
title: 'Book',
name: 'book',
type: 'document',
fields: [
{
title: 'Title',
name: 'title',
type: 'string',
},
defineField({
title: 'Subtitle',
name: 'subtitle',
type: 'string',
validation: (Rule) => Rule.required(),
}),
],
},
],
})

const extracted = extractSchema(schema1, {enforceRequiredFields: false})

const book = extracted.find((type) => type.name === 'book')
expect(book).toBeDefined()
assert(book !== undefined) // this is a workaround for TS, but leave the expect above for clarity in case of failure
assert(book.type === 'document') // this is a workaround for TS, but leave the expect above for clarity in case of failure
expect(book.attributes.title.optional).toBe(true)
expect(book.attributes.subtitle.optional).toBe(true)
})

test('can extract with enforceRequiredFields', () => {
const schema1 = createSchema({
name: 'test',
types: [
{
title: 'Book',
name: 'book',
type: 'document',
fields: [
{
title: 'Title',
name: 'title',
type: 'string',
},
defineField({
title: 'Subtitle',
name: 'subtitle',
type: 'string',
validation: (Rule) => Rule.required(),
}),
],
},
],
})

const extracted = extractSchema(schema1, {enforceRequiredFields: true})

const book = extracted.find((type) => type.name === 'book')
expect(book).toBeDefined()
assert(book !== undefined) // this is a workaround for TS, but leave the expect above for clarity in case of failure
assert(book.type === 'document') // this is a workaround for TS, but leave the expect above for clarity in case of failure
expect(book.attributes.title.optional).toBe(true)
expect(book.attributes.subtitle.optional).toBe(false)
})

describe('Can extract sample fixtures', () => {
const cases = Object.keys(schemaFixtures).map((schemaName) => {
const schema = createSchema(schemaFixtures[schemaName])
Expand Down

0 comments on commit d4639aa

Please sign in to comment.