UNPKG

@adobe/jsonschema2md

Version:

Validate and document complex JSON Schemas the easy way.

57 lines (50 loc) 2.09 kB
/* * Copyright 2019 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import { list, eq, contains } from 'ferrum'; import s from './symbols.js'; const { parent, pointer } = s; function isSkippableKeyword(schema) { const skippableKeywords = ['examples', 'required', 'properties']; const containsCurrentSchema = contains((keyword) => eq(keyword, schema[pointer].split('/').pop())); const schemaMember = schema[parent] && (schema[parent].type === 'object' || schema[parent].type === 'array'); return schemaMember && containsCurrentSchema(skippableKeywords); } function reducer({ seen, ids }, schema) { if (schema && schema[parent] && (seen.has(schema) || (schema.$id && ids.indexOf(schema.$id) >= 0))) { return { seen, ids }; } else if (Array.isArray(schema)) { if (isSkippableKeyword(schema)) { return { seen, ids }; } return schema.reduce(reducer, { seen, ids }); } else if (schema && typeof schema === 'object') { if (isSkippableKeyword(schema)) { return [...Object.values(schema)].reduce(reducer, { seen, ids }); } seen.add(schema); if (schema.$id) { ids.push(schema.$id); } return [...Object.values(schema)].reduce(reducer, { seen, ids }); } return { seen, ids }; } /** * Traverses a Schema node (containing a JSON Schema) to find sub-schemas, * which are then emitted as asequence. * @param {Schema} node */ export default function traverse(schemas) { return Array.from(list(schemas).reduce(reducer, { seen: new Set(), ids: [] }).seen); }