diff --git a/src/allOf.js b/src/allOf.js index 83c4f80..f7d69da 100644 --- a/src/allOf.js +++ b/src/allOf.js @@ -1,12 +1,16 @@ import { traverse } from './traverse'; -import { mergeDeep } from './utils'; +import { mergeDeep, SKIP_SYMBOL } from './utils'; + export function allOfSample(into, children, options, spec, context) { let res = traverse(into, options, spec); const subSamples = []; for (let subSchema of children) { - const { type, readOnly, writeOnly, value } = traverse({ type: res.type, ...subSchema }, options, spec, context); + const { type, readOnly, writeOnly, value } = traverse({ type: res.type, ...subSchema }, options, spec, { + ...context, + isAllOfChild: true, + }); if (res.type && type && type !== res.type) { console.warn('allOf: schemas with different types can\'t be merged'); res.type = type; @@ -19,6 +23,11 @@ export function allOfSample(into, children, options, spec, context) { if (res.type === 'object') { res.value = mergeDeep(res.value || {}, ...subSamples.filter(sample => typeof sample === 'object')); + for (const key in res.value) { + if (res.value[key] === SKIP_SYMBOL) { + delete res.value[key]; + } + } return res; } else { if (res.type === 'array') { diff --git a/src/samplers/object.js b/src/samplers/object.js index 09204ff..15a9a4f 100644 --- a/src/samplers/object.js +++ b/src/samplers/object.js @@ -1,5 +1,6 @@ import { traverse } from '../traverse'; import { applyXMLAttributes } from '../utils'; +import { SKIP_SYMBOL } from '../utils'; export function sampleObject(schema, options = {}, spec, context) { let res = {}; @@ -23,10 +24,16 @@ export function sampleObject(schema, options = {}, spec, context) { const sample = traverse(schema.properties[propertyName], options, spec, { propertyName, depth: depth + 1 }); if (options.skipReadOnly && sample.readOnly) { + if (context?.isAllOfChild) { + res[propertyName] = SKIP_SYMBOL; + } return; } if (options.skipWriteOnly && sample.writeOnly) { + if (context?.isAllOfChild) { + res[propertyName] = SKIP_SYMBOL; + } return; } diff --git a/src/utils.js b/src/utils.js index 0cf3c1f..949d5dd 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,7 @@ 'use strict'; +export const SKIP_SYMBOL = Symbol('skip'); + function pad(number) { if (number < 10) { return '0' + number; diff --git a/test/integration.spec.js b/test/integration.spec.js index a038a06..7edeb86 100644 --- a/test/integration.spec.js +++ b/test/integration.spec.js @@ -464,6 +464,30 @@ describe('Integration', () => { expect(result).toEqual(expected); }); + + + it('should repsect readOnly from schemas in allOf', () => { + const schema = { + allOf: [ + { + type: 'object', + properties: { + a: { type: 'string' }, + b: { type: 'integer' }, + }, + }, + { + properties: { + b: { readOnly: true }, + }, + } + ], + }; + const result = sample(schema, { skipReadOnly: true }); + expect(result).toEqual({ + a: 'string', + }); + }); }); describe('Inheritance', () => {