Skip to content

Commit

Permalink
fix: determine type of combinedKeywords
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Jan 26, 2024
1 parent ec48648 commit 48a440a
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"scripts": {
"lint": "standard | snazzy",
"lint:fix": "standard --fix",
"test": "npm run test:unit && npm run test:typescript",
"test:unit": "jest --coverage",
"test:watch": "jest src/*.test.js --verbose --watch",
Expand Down
5 changes: 4 additions & 1 deletion src/BaseSchema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,10 @@ describe('BaseSchema', () => {
).toEqual({
$schema: 'http://json-schema.org/draft-07/schema#',
properties: {
prop: { anyOf: [{ type: 'string' }, { type: 'null' }] }
prop: {
type: ['string', 'null'],
anyOf: [{ type: 'string' }, { type: 'null' }]
}
},
type: 'object'
})
Expand Down
4 changes: 3 additions & 1 deletion src/FluentSchema.integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,9 @@ describe('S', () => {
})

describe('compose keywords', () => {
const ajv = new Ajv()
const ajv = new Ajv({
allowUnionTypes: true
})
const schema = S.object()
.prop('foo', S.anyOf([S.string()]))
.prop('bar', S.not(S.anyOf([S.integer()])))
Expand Down
14 changes: 13 additions & 1 deletion src/FluentSchema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,24 @@ describe('S', () => {
})

describe('composition', () => {
it('anyOf', () => {
const schema = S.object()
.prop('foo', S.string().anyOf([S.string()]))
.valueOf()
expect(schema).toEqual({
$schema: 'http://json-schema.org/draft-07/schema#',
properties: { foo: { type: 'string', anyOf: [{ type: 'string' }] } },
type: 'object'
})
})

it('anyOf', () => {
const schema = S.object()
.prop('foo', S.anyOf([S.string()]))
.valueOf()
expect(schema).toEqual({
$schema: 'http://json-schema.org/draft-07/schema#',
properties: { foo: { anyOf: [{ type: 'string' }] } },
properties: { foo: { type: 'string', anyOf: [{ type: 'string' }] } },
type: 'object'
})
})
Expand All @@ -225,6 +236,7 @@ describe('S', () => {
$schema: 'http://json-schema.org/draft-07/schema#',
properties: {
multipleRestrictedTypesKey: {
type: ['string', 'number'],
oneOf: [{ type: 'string' }, { minimum: 10, type: 'number' }]
},
notTypeKey: { not: { oneOf: [{ pattern: 'js$', type: 'string' }] } }
Expand Down
5 changes: 3 additions & 2 deletions src/ObjectSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const {
patchIdsWithParentId,
appendRequired,
FluentSchemaError,
combineDeepmerge
combineDeepmerge,
getCombinedType
} = require('./utils')

const initialState = {
Expand Down Expand Up @@ -303,7 +304,7 @@ const ObjectSchema = ({ schema = initialState, ...options } = {}) => {
}

const type = hasCombiningKeywords(attributes)
? undefined
? getCombinedType(attributes)
: attributes.type

// strip undefined values or empty arrays or internals
Expand Down
33 changes: 33 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,38 @@ const isFluentSchema = obj => obj && obj.isFluentSchema
const hasCombiningKeywords = attributes =>
attributes.allOf || attributes.anyOf || attributes.oneOf || attributes.not

const getCombinedType = (attributes) => {
const resultSet = new Set()

if (attributes.type) {
resultSet.add(attributes.type)
}

if (attributes.allOf) {
for (const item of attributes.allOf) {
resultSet.add(item.type)
}
}

if (attributes.anyOf) {
for (const item of attributes.anyOf) {
resultSet.add(item.type)
}
}

if (attributes.oneOf) {
for (const item of attributes.oneOf) {
resultSet.add(item.type)
}
}

if (resultSet.size === 1) {
return [...resultSet][0]
}

return [...resultSet]
}

class FluentSchemaError extends Error {
constructor (message) {
super(message)
Expand Down Expand Up @@ -224,6 +256,7 @@ const setComposeType = ({ prop, schemas, schema, options }) => {

module.exports = {
isFluentSchema,
getCombinedType,
hasCombiningKeywords,
FluentSchemaError,
last,
Expand Down

0 comments on commit 48a440a

Please sign in to comment.