"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
exports.isPrimitive = exports.getSchemaVersionString = void 0;
var json_schema_merge_allof_1 = __importDefault(require("json-schema-merge-allof"));
var jsonpointer_1 = __importDefault(require("jsonpointer"));
var RMOAS = __importStar(require("../rmoas.types"));
/**
 * This list has been pulled from `openapi-schema-to-json-schema` but been slightly modified to fit
 * within the constraints in which ReadMe uses the output from this library in schema form
 * rendering as while properties like `readOnly` aren't represented within JSON Schema, we support
 * it within that library's handling of OpenAPI-friendly JSON Schema.
 *
 * @see {@link https://github.com/openapi-contrib/openapi-schema-to-json-schema/blob/master/index.js#L23-L27}
 */
var UNSUPPORTED_SCHEMA_PROPS = [
    'nullable',
    // 'discriminator',
    // 'readOnly',
    // 'writeOnly',
    'xml',
    'externalDocs',
    'example', // OpenAPI supports `example`, but we're mapping it to `examples` below.
    // 'deprecated',
];
/**
 * List partially sourced from `openapi-schema-to-json-schema`.
 *
 * @see {@link https://github.com/openapi-contrib/openapi-schema-to-json-schema/blob/master/lib/converters/schema.js#L140-L154}
 */
var FORMAT_OPTIONS = {
    INT8_MIN: 0 - Math.pow(2, 7),
    INT8_MAX: Math.pow(2, 7) - 1,
    INT16_MIN: 0 - Math.pow(2, 15),
    INT16_MAX: Math.pow(2, 15) - 1,
    INT32_MIN: 0 - Math.pow(2, 31),
    INT32_MAX: Math.pow(2, 31) - 1,
    INT64_MIN: 0 - Math.pow(2, 63),
    INT64_MAX: Math.pow(2, 63) - 1,
    UINT8_MIN: 0,
    UINT8_MAX: Math.pow(2, 8) - 1,
    UINT16_MIN: 0,
    UINT16_MAX: Math.pow(2, 16) - 1,
    UINT32_MIN: 0,
    UINT32_MAX: Math.pow(2, 32) - 1,
    UINT64_MIN: 0,
    UINT64_MAX: Math.pow(2, 64) - 1,
    FLOAT_MIN: 0 - Math.pow(2, 128),
    FLOAT_MAX: Math.pow(2, 128) - 1,
    DOUBLE_MIN: 0 - Number.MAX_VALUE,
    DOUBLE_MAX: Number.MAX_VALUE
};
/**
 * Encode a string to be used as a JSON pointer.
 *
 * @see {@link https://tools.ietf.org/html/rfc6901}
 * @param str String to encode into string that can be used as a JSON pointer.
 */
function encodePointer(str) {
    return str.replace('~', '~0').replace('/', '~1');
}
function getSchemaVersionString(schema, api) {
    // If we're not on version 3.1.0, we always fall back to the default schema version for pre-3.1.0.
    if (!RMOAS.isOAS31(api)) {
        // This should remain as an HTTP url, not HTTPS.
        return 'http://json-schema.org/draft-04/schema#';
    }
    /**
     * If the schema indicates the version, prefer that.
     *
     * We use `as` here because the schema *should* be an OAS 3.1 schema due to the `isOAS31` check
     * above.
     */
    if (schema.$schema) {
        return schema.$schema;
    }
    // If the user defined a global schema version on their OAS document, prefer that.
    if (api.jsonSchemaDialect) {
        return api.jsonSchemaDialect;
    }
    return 'https://json-schema.org/draft/2020-12/schema#';
}
exports.getSchemaVersionString = getSchemaVersionString;
function isPrimitive(val) {
    return typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean';
}
exports.isPrimitive = isPrimitive;
function isPolymorphicSchema(schema) {
    return 'allOf' in schema || 'anyOf' in schema || 'oneOf' in schema;
}
function isRequestBodySchema(schema) {
    return 'content' in schema;
}
/**
 * Given a JSON pointer and an array of examples do a reverse search through them until we find the
 * JSON pointer, or part of it, within the array.
 *
 * This function will allow you to take a pointer like `/tags/name` and return back `buster` from
 * the following array:
 *
 * ```
 *  [
 *    {
 *      example: {id: 20}
 *    },
 *    {
 *      examples: {
 *        distinctName: {
 *          tags: {name: 'buster'}
 *        }
 *      }
 *    }
 *  ]
 * ```
 *
 * As with most things however, this is not without its quirks! If a deeply nested property shares
 * the same name as an example that's further up the stack (like `tags.id` and an example for `id`),
 * there's a chance that it'll be misidentified as having an example and receive the wrong value.
 *
 * That said, any example is usually better than no example though, so while it's quirky behavior
 * it shouldn't raise immediate cause for alarm.
 *
 * @see {@link https://tools.ietf.org/html/rfc6901}
 * @param pointer JSON pointer to search for an example for.
 * @param examples Array of previous schemas we've found relating to this pointer.
 */
function searchForExampleByPointer(pointer, examples) {
    if (examples === void 0) { examples = []; }
    if (!examples.length || !pointer.length) {
        return undefined;
    }
    var locSplit = pointer.split('/').filter(Boolean).reverse();
    var pointers = [];
    var point = '';
    for (var i = 0; i < locSplit.length; i += 1) {
        point = "/".concat(locSplit[i]).concat(point);
        pointers.push(point);
    }
    var example;
    var rev = __spreadArray([], examples, true).reverse();
    for (var i = 0; i < pointers.length; i += 1) {
        for (var ii = 0; ii < rev.length; ii += 1) {
            var schema = rev[ii];
            if ('example' in schema) {
                schema = schema.example;
            }
            else {
                if (!Array.isArray(schema.examples) || !schema.examples.length) {
                    continue;
                }
                // Prevent us from crashing if `examples` is a completely empty object.
                schema = schema.examples.shift();
            }
            try {
                example = jsonpointer_1["default"].get(schema, pointers[i]);
            }
            catch (err) {
                // If the schema we're looking at is `{obj: null}` and our pointer if `/obj/propertyName`
                // jsonpointer will throw an error. If that happens, we should silently catch and toss it
                // and return no example.
            }
            if (example !== undefined) {
                break;
            }
        }
        if (example !== undefined) {
            break;
        }
    }
    return example;
}
/**
 * Given an OpenAPI-flavored JSON Schema, make an effort to modify it so it's shaped more towards
 * stock JSON Schema.
 *
 * Why do this?
 *
 *  1. OpenAPI 3.0.x supports its own flavor of JSON Schema that isn't fully compatible with most
 *    JSON Schema tooling (like `@readme/oas-form` or `@rjsf/core`).
 *  2. While validating an OpenAPI definition will prevent corrupted or improper schemas from
 *    occuring, we have a lot of legacy schemas in ReadMe that were ingested before we had proper
 *    validation in place, and as a result have some API definitions that will not pass validation
 *    right now. In addition to reshaping OAS-JSON Schema into JSON Schema this library will also
 *    fix these improper schemas: things like `type: object` having `items` instead of `properties`,
 *    or `type: array` missing `items`.
 *  3. To ease the burden of polymorphic handling on our form rendering engine we make an attempt
 *    to merge `allOf` schemas here.
 *  4. Additionally due to OpenAPI 3.0.x not supporting JSON Schema, in order to support the
 *    `example` keyword that OAS supports, we need to do some work in here to remap it into
 *    `examples`. However, since all we care about in respect to examples for usage within
 *    `@readme/oas-form`, we're only retaining primitives. This *slightly* deviates from JSON
 *    Schema in that JSON Schema allows for any schema to be an example, but since
 *    `@readme/oas-form` can only actually **render** primitives, that's what we're retaining.
 *  5. Though OpenAPI 3.1 does support full JSON Schema, this library should be able to handle it
 *    without any problems.
 *
 * And why use this over `@openapi-contrib/openapi-schema-to-json-schema`? Fortunately and
 * unfortunately we've got a lot of API definitions in our database that aren't currently valid so
 * we need to have a lot of bespoke handling for odd quirks, typos, and missing declarations that
 * might be present.
 *
 * @todo add support for `schema: false` and `not` cases.
 * @see {@link https://json-schema.org/draft/2019-09/json-schema-validation.html}
 * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schemaObject}
 * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject}
 * @param data OpenAPI Schema Object to convert to pure JSON Schema.
 */
function toJSONSchema(data, opts) {
    if (opts === void 0) { opts = {}; }
    var schema = data === true ? {} : __assign({}, data);
    var schemaAdditionalProperties = RMOAS.isSchema(schema) ? schema.additionalProperties : null;
    var _a = __assign({ addEnumsToDescriptions: false, currentLocation: '', globalDefaults: {}, isPolymorphicAllOfChild: false, prevSchemas: [], refLogger: function () { return true; }, transformer: function (s) { return s; } }, opts), addEnumsToDescriptions = _a.addEnumsToDescriptions, currentLocation = _a.currentLocation, globalDefaults = _a.globalDefaults, isPolymorphicAllOfChild = _a.isPolymorphicAllOfChild, prevSchemas = _a.prevSchemas, refLogger = _a.refLogger, transformer = _a.transformer;
    // If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just
    // return and move along.
    if (RMOAS.isRef(schema)) {
        refLogger(schema.$ref, 'ref');
        return transformer({
            $ref: schema.$ref
        });
    }
    // If we don't have a set type, but are dealing with an `anyOf`, `oneOf`, or `allOf`
    // representation let's run through them and make sure they're good.
    if (RMOAS.isSchema(schema, isPolymorphicAllOfChild)) {
        // If this is an `allOf` schema we should make an attempt to merge so as to ease the burden on
        // the tooling that ingests these schemas.
        if ('allOf' in schema && Array.isArray(schema.allOf)) {
            try {
                schema = (0, json_schema_merge_allof_1["default"])(schema, {
                    ignoreAdditionalProperties: true,
                    resolvers: {
                        // JSON Schema ony supports examples with the `examples` property, since we're
                        // ingesting OpenAPI definitions we need to add a custom resolver for its `example`
                        // property.
                        example: function (obj) { return obj[0]; },
                        // JSON Schema has no support for `format` on anything other than `string`, but since
                        // OpenAPI has it on `integer` and `number` we need to add a custom resolver here so we
                        // can still merge schemas that may have those.
                        format: function (obj) { return obj[0]; },
                        // Since JSON Schema obviously doesn't know about our vendor extension we need to tell
                        // the library to essentially ignore and pass it along.
                        'x-readme-ref-name': function (obj) { return obj[0]; }
                    }
                });
            }
            catch (e) {
                // If we can't merge the `allOf` for whatever reason (like if one item is a `string` and
                // the other is a `object`) then we should completely remove it from the schema and continue
                // with whatever we've got. Why? If we don't, any tooling that's ingesting this will need
                // to account for the incompatible `allOf` and it may be subject to more breakages than
                // just not having it present would be.
                var schemaWithoutAllOf = __rest(schema, []);
                schema = schemaWithoutAllOf;
                delete schema.allOf;
            }
        }
        ['anyOf', 'oneOf'].forEach(function (polyType) {
            if (polyType in schema && Array.isArray(schema[polyType])) {
                schema[polyType].forEach(function (item, idx) {
                    var polyOptions = {
                        addEnumsToDescriptions: addEnumsToDescriptions,
                        currentLocation: "".concat(currentLocation, "/").concat(idx),
                        globalDefaults: globalDefaults,
                        isPolymorphicAllOfChild: false,
                        prevSchemas: prevSchemas,
                        refLogger: refLogger,
                        transformer: transformer
                    };
                    // When `properties` or `items` are present alongside a polymorphic schema instead of
                    // letting whatever JSON Schema interpreter is handling these constructed schemas we can
                    // guide its hand a bit by manually transforming it into an inferred `allOf` of the
                    // `properties` + the polymorph schema.
                    //
                    // This `allOf` schema will be merged together when fed through `toJSONSchema`.
                    if ('properties' in schema) {
                        schema[polyType][idx] = toJSONSchema({ allOf: [item, { properties: schema.properties }] }, polyOptions);
                    }
                    else if ('items' in schema) {
                        schema[polyType][idx] = toJSONSchema({ allOf: [item, { items: schema.items }] }, polyOptions);
                    }
                    else {
                        schema[polyType][idx] = toJSONSchema(item, polyOptions);
                    }
                });
            }
        });
        if ('discriminator' in schema) {
            if ('mapping' in schema.discriminator && typeof schema.discriminator.mapping === 'object') {
                // Discriminator mappings aren't written as traditional `$ref` pointers so in order to log
                // them to the supplied `refLogger`.
                var mapping_1 = schema.discriminator.mapping;
                Object.keys(mapping_1).forEach(function (k) {
                    refLogger(mapping_1[k], 'discriminator');
                });
            }
        }
    }
    // If this schema is malformed for some reason, let's do our best to repair it.
    if (!('type' in schema) && !isPolymorphicSchema(schema) && !isRequestBodySchema(schema)) {
        if ('properties' in schema) {
            schema.type = 'object';
        }
        else if ('items' in schema) {
            schema.type = 'array';
        }
        else {
            // If there's still no `type` on the schema we should leave it alone because we don't have a
            // great way to know if it's part of a nested schema that should, and couldn't be merged,
            // into another, or it's just purely malformed.
            //
            // Whatever tooling that ingests the generated schema should handle it however it needs to.
        }
    }
    if (RMOAS.isSchema(schema, isPolymorphicAllOfChild)) {
        // JSON Schema doesn't support OpenAPI-style examples so we need to reshape them a bit.
        if ('example' in schema) {
            // Only bother adding primitive examples.
            if (isPrimitive(schema.example)) {
                schema.examples = [schema.example];
            }
            else if (Array.isArray(schema.example)) {
                schema.examples = schema.example.filter(function (example) { return isPrimitive(example); });
                if (!schema.examples.length) {
                    delete schema.examples;
                }
            }
            else {
                prevSchemas.push({ example: schema.example });
            }
            delete schema.example;
        }
        else if ('examples' in schema) {
            var reshapedExamples_1 = false;
            if (typeof schema.examples === 'object' && !Array.isArray(schema.examples)) {
                var examples_1 = [];
                Object.keys(schema.examples).forEach(function (name) {
                    var example = schema.examples[name];
                    if ('$ref' in example) {
                        // no-op because any `$ref` example here after dereferencing is circular so we should
                        // ignore it
                        refLogger(example.$ref, 'ref');
                    }
                    else if ('value' in example) {
                        if (isPrimitive(example.value)) {
                            examples_1.push(example.value);
                            reshapedExamples_1 = true;
                        }
                        else if (Array.isArray(example.value) && isPrimitive(example.value[0])) {
                            examples_1.push(example.value[0]);
                            reshapedExamples_1 = true;
                        }
                        else {
                            // If this example is neither a primitive or an array we should dump it into the
                            // `prevSchemas` array because we might be able to extract an example from it further
                            // downstream.
                            prevSchemas.push({
                                example: example.value
                            });
                        }
                    }
                });
                if (examples_1.length) {
                    reshapedExamples_1 = true;
                    schema.examples = examples_1;
                }
            }
            else if (Array.isArray(schema.examples) && isPrimitive(schema.examples[0])) {
                // We haven't reshaped `examples` here, but since it's in a state that's preferrable to us
                // let's keep it around.
                reshapedExamples_1 = true;
            }
            if (!reshapedExamples_1) {
                delete schema.examples;
            }
        }
        // If we didn't have any immediately defined examples, let's search backwards and see if we can
        // find one. But as we're only looking for primitive example, only try to search for one if
        // we're dealing with a primitive schema.
        if (schema.type !== 'array' && schema.type !== 'object' && !schema.examples) {
            var foundExample = searchForExampleByPointer(currentLocation, prevSchemas);
            if (foundExample) {
                // We can only really deal with primitives, so only promote those as the found example if
                // it is.
                if (isPrimitive(foundExample) || (Array.isArray(foundExample) && isPrimitive(foundExample[0]))) {
                    schema.examples = [foundExample];
                }
            }
        }
        if (schema.type === 'array') {
            if ('items' in schema) {
                if (!Array.isArray(schema.items) && Object.keys(schema.items).length === 1 && RMOAS.isRef(schema.items)) {
                    // `items` contains a `$ref`, so since it's circular we should do a no-op here and log
                    // and ignore it.
                    refLogger(schema.items.$ref, 'ref');
                }
                else if (schema.items !== true) {
                    // Run through the arrays contents and clean them up.
                    schema.items = toJSONSchema(schema.items, {
                        addEnumsToDescriptions: addEnumsToDescriptions,
                        currentLocation: "".concat(currentLocation, "/0"),
                        globalDefaults: globalDefaults,
                        prevSchemas: prevSchemas,
                        refLogger: refLogger,
                        transformer: transformer
                    });
                }
            }
            else if ('properties' in schema || 'additionalProperties' in schema) {
                // This is a fix to handle cases where someone may have typod `items` as `properties` on an
                // array. Since throwing a complete failure isn't ideal, we can see that they meant for the
                // type to be `object`, so we can do our best to shape the data into what they were
                // intending it to be.
                // README-6R
                schema.type = 'object';
            }
            else {
                // This is a fix to handle cases where we have a malformed array with no `items` property
                // present.
                // README-8E
                schema.items = {};
            }
        }
        else if (schema.type === 'object') {
            if ('properties' in schema) {
                Object.keys(schema.properties).forEach(function (prop) {
                    if (Array.isArray(schema.properties[prop]) ||
                        (typeof schema.properties[prop] === 'object' && schema.properties[prop] !== null)) {
                        schema.properties[prop] = toJSONSchema(schema.properties[prop], {
                            addEnumsToDescriptions: addEnumsToDescriptions,
                            currentLocation: "".concat(currentLocation, "/").concat(encodePointer(prop)),
                            globalDefaults: globalDefaults,
                            prevSchemas: prevSchemas,
                            refLogger: refLogger,
                            transformer: transformer
                        });
                    }
                });
            }
            if (typeof schemaAdditionalProperties === 'object' && schemaAdditionalProperties !== null) {
                // If this `additionalProperties` is completely empty and devoid of any sort of schema,
                // treat it as such. Otherwise let's recurse into it and see if we can sort it out.
                if (!('type' in schemaAdditionalProperties) &&
                    !('$ref' in schemaAdditionalProperties) &&
                    // We know it will be a schema object because it's dereferenced
                    !isPolymorphicSchema(schemaAdditionalProperties)) {
                    schema.additionalProperties = true;
                }
                else {
                    // We know it will be a schema object because it's dereferenced
                    schema.additionalProperties = toJSONSchema(schemaAdditionalProperties, {
                        addEnumsToDescriptions: addEnumsToDescriptions,
                        currentLocation: currentLocation,
                        globalDefaults: globalDefaults,
                        prevSchemas: prevSchemas,
                        refLogger: refLogger,
                        transformer: transformer
                    });
                }
            }
            // Since neither `properties` and `additionalProperties` are actually required to be present
            // on an object, since we construct this schema work to build up a form we still need
            // *something* for the user to enter in for this object so we'll add back in
            // `additionalProperties` for that.
            if (!isPolymorphicSchema(schema) && !('properties' in schema) && !('additionalProperties' in schema)) {
                schema.additionalProperties = true;
            }
        }
    }
    // Ensure that number schemas formats have properly constrained min/max attributes according to
    // whatever type of `format` and `type` they adhere to.
    if ('format' in schema) {
        var formatUpper = schema.format.toUpperCase();
        if ("".concat(formatUpper, "_MIN") in FORMAT_OPTIONS) {
            if ((!schema.minimum && schema.minimum !== 0) || schema.minimum < FORMAT_OPTIONS["".concat(formatUpper, "_MIN")]) {
                schema.minimum = FORMAT_OPTIONS["".concat(formatUpper, "_MIN")];
            }
        }
        if ("".concat(formatUpper, "_MAX") in FORMAT_OPTIONS) {
            if ((!schema.maximum && schema.maximum !== 0) || schema.maximum > FORMAT_OPTIONS["".concat(formatUpper, "_MAX")]) {
                schema.maximum = FORMAT_OPTIONS["".concat(formatUpper, "_MAX")];
            }
        }
    }
    /**
     * Users can pass in parameter defaults via JWT User Data. We're checking to see if the defaults
     * being passed in exist on endpoints via jsonpointer
     *
     * @see {@link https://docs.readme.com/docs/passing-data-to-jwt}
     */
    if (RMOAS.isSchema(schema, isPolymorphicAllOfChild) &&
        globalDefaults &&
        Object.keys(globalDefaults).length > 0 &&
        currentLocation) {
        try {
            var userJwtDefault = jsonpointer_1["default"].get(globalDefaults, currentLocation);
            if (userJwtDefault) {
                schema["default"] = userJwtDefault;
            }
        }
        catch (err) {
            // If jsonpointer returns an error, we won't show any defaults for that path.
        }
    }
    // Only add a default value if we actually have one.
    if ('default' in schema && typeof schema["default"] !== 'undefined') {
        if (('allowEmptyValue' in schema && schema.allowEmptyValue && schema["default"] === '') || schema["default"] !== '') {
            // If we have `allowEmptyValue` present, and the default is actually an empty string, let it
            // through as it's allowed.
        }
        else {
            // If the default is empty and we don't want to allowEmptyValue, we need to remove the
            // default.
            delete schema["default"];
        }
    }
    if (RMOAS.isSchema(schema, isPolymorphicAllOfChild) && 'enum' in schema && Array.isArray(schema["enum"])) {
        // Enums should not have duplicated items as those will break AJV validation.
        // If we ever target ES6 for typescript we can drop this array.from.
        // https://stackoverflow.com/questions/33464504/using-spread-syntax-and-new-set-with-typescript/56870548
        schema["enum"] = Array.from(new Set(schema["enum"]));
        // If we want to add enums to descriptions (like in the case of response JSON Schema)
        // generation we need to convert them into a list of Markdown tilda'd strings. We're also
        // filtering away empty and falsy strings here because adding empty `` blocks to the description
        // will serve nobody any good.
        if (addEnumsToDescriptions) {
            var enums = schema["enum"]
                .filter(Boolean)
                .map(function (str) { return "`".concat(str, "`"); })
                .join(' ');
            if (enums.length) {
                if ('description' in schema) {
                    schema.description += "\n\n".concat(enums);
                }
                else {
                    schema.description = enums;
                }
            }
        }
    }
    // Clean up any remaining `items` or `properties` schema fragments lying around if there's also
    // polymorphism present.
    if ('anyOf' in schema || 'oneOf' in schema) {
        if ('properties' in schema) {
            delete schema.properties;
        }
        if ('items' in schema) {
            delete schema.items;
        }
    }
    // Remove unsupported JSON Schema props.
    for (var i = 0; i < UNSUPPORTED_SCHEMA_PROPS.length; i += 1) {
        // Using the as here because the purpose is to delete keys we don't expect, so of course the
        // typing won't work
        delete schema[UNSUPPORTED_SCHEMA_PROPS[i]];
    }
    return transformer(schema);
}
exports["default"] = toJSONSchema;
