UNPKG

@confluentinc/schemaregistry

Version:
113 lines (112 loc) 3.99 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateSchema = generateSchema; exports.deepEqual = deepEqual; /* * Copyright (c) 2023 Menglin "Mark" Xu <mark@remarkablemark.org> * (c) 2024 Confluent, Inc. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE.txt file for details. */ const validator_1 = __importDefault(require("validator")); const assert_1 = require("assert"); /** * Generate JSON schema from value. * * @param value - Value. * @returns JSON schema. */ function generateSchema(value) { switch (true) { case value === undefined: case typeof value === 'undefined': case typeof value === 'function': case typeof value === 'symbol': case value instanceof Date: throw new TypeError(`Invalid JSON value: ${String(value)}`); /** * @see https://json-schema.org/understanding-json-schema/reference/null.html */ case value === null: return { type: 'null' }; /** * @see https://json-schema.org/understanding-json-schema/reference/numeric.html */ case typeof value === 'number': return { type: Number.isInteger(value) ? 'integer' : 'number' }; /** * @see https://json-schema.org/understanding-json-schema/reference/boolean.html */ case typeof value === 'boolean': return { type: 'boolean' }; /** * @see https://json-schema.org/understanding-json-schema/reference/string.html */ case typeof value === 'string': if (validator_1.default.isISO8601(value)) { return { type: 'string', format: value.includes('T') ? 'date-time' : 'date', }; } if (validator_1.default.isTime(value.split('+')[0], { mode: 'withSeconds' })) { return { type: 'string', format: 'time' }; } if (validator_1.default.isEmail(value)) { return { type: 'string', format: 'email' }; } return { type: 'string' }; /** * @see https://json-schema.org/understanding-json-schema/reference/array.html */ case Array.isArray(value): if (value.length === 1) { return { type: 'array', items: generateSchema(value[0]) }; } if (value.length > 1) { const items = value.map(generateSchema); if (deepEqual(...items)) { return { type: 'array', items: items[0] }; } } return { type: 'array' }; /** * @see https://json-schema.org/understanding-json-schema/reference/object.html */ case value instanceof Object: if (!Object.keys(value).length) { return { type: 'object' }; } return { type: 'object', properties: Object.entries(value).reduce((accumulator, [key, value]) => { accumulator[key] = generateSchema(value); return accumulator; }, {}), }; /* istanbul ignore next */ default: throw new TypeError(`Invalid JSON value: ${value}`); } } /** * Tests for deep equality between the `actual` and `expected` parameters. */ function deepEqual(...args) { try { for (let index = 0, count = args.length; index < count; index++) { if (index + 1 === count) { continue; } (0, assert_1.deepStrictEqual)(args[index], args[index + 1]); } return true; } catch (error) { return false; } }