From e4f28e5e953c6bb7b2a1006bae0b2c4b21c6c5d5 Mon Sep 17 00:00:00 2001 From: Sindre Gulseth Date: Tue, 26 Mar 2024 09:34:12 +0100 Subject: [PATCH] fix(schemaExtract): guard for list options not being an array (#6128) * fix(schemaExtract): guard for list options not being an array * test(schema): add non-array field `list` option --------- Co-authored-by: Espen Hovlandsdal --- .../schema/src/sanity/extractSchema.ts | 10 ++++--- .../test/extractSchema/extractSchema.test.ts | 11 +++++++ .../test/legacy/fixtures/schemas/index.ts | 10 ++++--- .../fixtures/schemas/listObjectOption.ts | 30 +++++++++++++++++++ 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 packages/@sanity/schema/test/legacy/fixtures/schemas/listObjectOption.ts diff --git a/packages/@sanity/schema/src/sanity/extractSchema.ts b/packages/@sanity/schema/src/sanity/extractSchema.ts index 6eb6e1b2830..22376c0f88a 100644 --- a/packages/@sanity/schema/src/sanity/extractSchema.ts +++ b/packages/@sanity/schema/src/sanity/extractSchema.ts @@ -347,10 +347,11 @@ function isNumberType(typeDef: SanitySchemaType): typeDef is NumberSchemaType { function createStringTypeNodeDefintion( stringSchemaType: StringSchemaType, ): StringTypeNode | UnionTypeNode { - if (stringSchemaType.options?.list) { + const listOptions = stringSchemaType.options?.list + if (listOptions && Array.isArray(listOptions)) { return { type: 'union', - of: stringSchemaType.options.list.map((v) => ({ + of: listOptions.map((v) => ({ type: 'string', value: typeof v === 'string' ? v : v.value, })), @@ -364,10 +365,11 @@ function createStringTypeNodeDefintion( function createNumberTypeNodeDefintion( numberSchemaType: NumberSchemaType, ): NumberTypeNode | UnionTypeNode { - if (numberSchemaType.options?.list) { + const listOptions = numberSchemaType.options?.list + if (listOptions && Array.isArray(listOptions)) { return { type: 'union', - of: numberSchemaType.options.list.map((v) => ({ + of: listOptions.map((v) => ({ type: 'number', value: typeof v === 'number' ? v : v.value, })), diff --git a/packages/@sanity/schema/test/extractSchema/extractSchema.test.ts b/packages/@sanity/schema/test/extractSchema/extractSchema.test.ts index a6686c87bc6..d8df385f807 100644 --- a/packages/@sanity/schema/test/extractSchema/extractSchema.test.ts +++ b/packages/@sanity/schema/test/extractSchema/extractSchema.test.ts @@ -437,6 +437,17 @@ describe('Extract schema test', () => { expect(book.attributes.subtitle.optional).toBe(false) }) + describe('can handle `list` option that is not an array', () => { + const schema = createSchema(schemaFixtures.listObjectOption) + const extracted = extractSchema(schema) + + const post = extracted.find((type) => type.name === 'post') + assert(post !== undefined) // this is a workaround for TS, but leave the expect above for clarity in case of failure + assert(post.type === 'document') // this is a workaround for TS, but leave the expect above for clarity in case of failure + + expect(post.attributes.align.value.type).toBe('string') + }) + describe('Can extract sample fixtures', () => { const cases = Object.keys(schemaFixtures).map((schemaName) => { const schema = createSchema(schemaFixtures[schemaName]) diff --git a/packages/@sanity/schema/test/legacy/fixtures/schemas/index.ts b/packages/@sanity/schema/test/legacy/fixtures/schemas/index.ts index 84180de25b0..6af946c1755 100644 --- a/packages/@sanity/schema/test/legacy/fixtures/schemas/index.ts +++ b/packages/@sanity/schema/test/legacy/fixtures/schemas/index.ts @@ -3,6 +3,7 @@ import assets from './assets' import blocks from './blocks' import exampleBlog from './example-blog' import fieldsets from './fieldsets' +import listObjectOption from './listObjectOption' import messyDevSchema from './messy-dev' import oma from './oma' import reference from './reference' @@ -12,12 +13,13 @@ import vega from './vega' export default { arrays, assets, + blocks, exampleBlog, fieldsets, - reference, - vega, - blocks, + listObjectOption, + messyDevSchema, oma, + reference, selects, - messyDevSchema, + vega, } diff --git a/packages/@sanity/schema/test/legacy/fixtures/schemas/listObjectOption.ts b/packages/@sanity/schema/test/legacy/fixtures/schemas/listObjectOption.ts new file mode 100644 index 00000000000..5ec5e280eef --- /dev/null +++ b/packages/@sanity/schema/test/legacy/fixtures/schemas/listObjectOption.ts @@ -0,0 +1,30 @@ +export default { + name: 'listObjectOption', + types: [ + { + name: 'stringWithListOption', + type: 'string', + }, + { + name: 'post', + type: 'document', + fields: [ + { + name: 'title', + title: 'Title', + type: 'string', + }, + { + name: 'align', + title: 'Alignment', + type: 'stringWithListOption', + options: { + list: { + options: ['left', 'right', 'center'], + }, + }, + }, + ], + }, + ], +}