"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Oas2Types = void 0;
const _1 = require(".");
const responseCodeRegexp = /^[0-9][0-9Xx]{2}$/;
const Root = {
    properties: {
        swagger: { type: 'string' },
        info: 'Info',
        host: { type: 'string' },
        basePath: { type: 'string' },
        schemes: { type: 'array', items: { type: 'string' } },
        consumes: { type: 'array', items: { type: 'string' } },
        produces: { type: 'array', items: { type: 'string' } },
        paths: 'Paths',
        definitions: 'NamedSchemas',
        parameters: 'NamedParameters',
        responses: 'NamedResponses',
        securityDefinitions: 'NamedSecuritySchemes',
        security: 'SecurityRequirementList',
        tags: 'TagList',
        externalDocs: 'ExternalDocs',
        'x-servers': 'XServerList',
        'x-tagGroups': 'TagGroups',
        'x-ignoredHeaderParameters': { type: 'array', items: { type: 'string' } },
    },
    required: ['swagger', 'paths', 'info'],
    extensionsPrefix: 'x-',
};
const Info = {
    properties: {
        title: { type: 'string' },
        description: { type: 'string' },
        termsOfService: { type: 'string' },
        contact: 'Contact',
        license: 'License',
        version: { type: 'string' },
        'x-logo': 'Logo',
    },
    required: ['title', 'version'],
    extensionsPrefix: 'x-',
};
const Logo = {
    properties: {
        url: { type: 'string' },
        altText: { type: 'string' },
        backgroundColor: { type: 'string' },
        href: { type: 'string' },
    },
    extensionsPrefix: 'x-',
};
const Contact = {
    properties: {
        name: { type: 'string' },
        url: { type: 'string' },
        email: { type: 'string' },
    },
    extensionsPrefix: 'x-',
};
const License = {
    properties: {
        name: { type: 'string' },
        url: { type: 'string' },
    },
    required: ['name'],
    extensionsPrefix: 'x-',
};
const Paths = {
    properties: {},
    additionalProperties: (_value, key) => key.startsWith('/') ? 'PathItem' : undefined,
};
const PathItem = {
    properties: {
        $ref: { type: 'string' }, // TODO: verify special $ref handling for Path Item
        parameters: 'ParameterList',
        get: 'Operation',
        put: 'Operation',
        post: 'Operation',
        delete: 'Operation',
        options: 'Operation',
        head: 'Operation',
        patch: 'Operation',
    },
    extensionsPrefix: 'x-',
};
const Operation = {
    properties: {
        tags: { type: 'array', items: { type: 'string' } },
        summary: { type: 'string' },
        description: { type: 'string' },
        externalDocs: 'ExternalDocs',
        operationId: { type: 'string' },
        consumes: { type: 'array', items: { type: 'string' } },
        produces: { type: 'array', items: { type: 'string' } },
        parameters: 'ParameterList',
        responses: 'Responses',
        schemes: { type: 'array', items: { type: 'string' } },
        deprecated: { type: 'boolean' },
        security: 'SecurityRequirementList',
        'x-codeSamples': 'XCodeSampleList',
        'x-code-samples': 'XCodeSampleList', // deprecated
        'x-hideTryItPanel': { type: 'boolean' },
    },
    required: ['responses'],
    extensionsPrefix: 'x-',
};
const XCodeSample = {
    properties: {
        lang: { type: 'string' },
        label: { type: 'string' },
        source: { type: 'string' },
    },
};
const XServer = {
    properties: {
        url: { type: 'string' },
        description: { type: 'string' },
    },
    required: ['url'],
};
const ExternalDocs = {
    properties: {
        description: { type: 'string' },
        url: { type: 'string' },
    },
    required: ['url'],
    extensionsPrefix: 'x-',
};
const Parameter = {
    properties: {
        name: { type: 'string' },
        in: { type: 'string', enum: ['query', 'header', 'path', 'formData', 'body'] },
        description: { type: 'string' },
        required: { type: 'boolean' },
        schema: 'Schema',
        type: { type: 'string', enum: ['string', 'number', 'integer', 'boolean', 'array', 'file'] },
        format: { type: 'string' },
        allowEmptyValue: { type: 'boolean' },
        items: 'ParameterItems',
        collectionFormat: { type: 'string', enum: ['csv', 'ssv', 'tsv', 'pipes', 'multi'] },
        default: null,
        maximum: { type: 'integer' },
        exclusiveMaximum: { type: 'boolean' },
        minimum: { type: 'integer' },
        exclusiveMinimum: { type: 'boolean' },
        maxLength: { type: 'integer' },
        minLength: { type: 'integer' },
        pattern: { type: 'string' },
        maxItems: { type: 'integer' },
        minItems: { type: 'integer' },
        uniqueItems: { type: 'boolean' },
        enum: { type: 'array' },
        multipleOf: { type: 'number' },
        'x-example': {}, // any
        'x-examples': 'ExamplesMap',
    },
    required(value) {
        if (!value || !value.in) {
            return ['name', 'in'];
        }
        if (value.in === 'body') {
            return ['name', 'in', 'schema'];
        }
        else {
            if (value.type === 'array') {
                return ['name', 'in', 'type', 'items'];
            }
            else {
                return ['name', 'in', 'type'];
            }
        }
    },
    extensionsPrefix: 'x-',
};
const ParameterItems = {
    properties: {
        type: { type: 'string', enum: ['string', 'number', 'integer', 'boolean', 'array'] },
        format: { type: 'string' },
        items: 'ParameterItems',
        collectionFormat: { type: 'string', enum: ['csv', 'ssv', 'tsv', 'pipes', 'multi'] },
        default: null,
        maximum: { type: 'integer' },
        exclusiveMaximum: { type: 'boolean' },
        minimum: { type: 'integer' },
        exclusiveMinimum: { type: 'boolean' },
        maxLength: { type: 'integer' },
        minLength: { type: 'integer' },
        pattern: { type: 'string' },
        maxItems: { type: 'integer' },
        minItems: { type: 'integer' },
        uniqueItems: { type: 'boolean' },
        enum: { type: 'array' },
        multipleOf: { type: 'number' },
    },
    required(value) {
        if (value && value.type === 'array') {
            return ['type', 'items'];
        }
        else {
            return ['type'];
        }
    },
    extensionsPrefix: 'x-',
};
const Responses = {
    properties: {
        default: 'Response',
    },
    additionalProperties: (_v, key) => responseCodeRegexp.test(key) ? 'Response' : undefined,
};
const Response = {
    properties: {
        description: { type: 'string' },
        schema: 'Schema',
        headers: (0, _1.mapOf)('Header'),
        examples: 'Examples',
        'x-summary': { type: 'string' },
    },
    required: ['description'],
    extensionsPrefix: 'x-',
};
const Examples = {
    properties: {},
    additionalProperties: { isExample: true },
};
const Header = {
    properties: {
        description: { type: 'string' },
        type: { type: 'string', enum: ['string', 'number', 'integer', 'boolean', 'array'] },
        format: { type: 'string' },
        items: 'ParameterItems',
        collectionFormat: { type: 'string', enum: ['csv', 'ssv', 'tsv', 'pipes', 'multi'] },
        default: null,
        maximum: { type: 'integer' },
        exclusiveMaximum: { type: 'boolean' },
        minimum: { type: 'integer' },
        exclusiveMinimum: { type: 'boolean' },
        maxLength: { type: 'integer' },
        minLength: { type: 'integer' },
        pattern: { type: 'string' },
        maxItems: { type: 'integer' },
        minItems: { type: 'integer' },
        uniqueItems: { type: 'boolean' },
        enum: { type: 'array' },
        multipleOf: { type: 'number' },
    },
    required(value) {
        if (value && value.type === 'array') {
            return ['type', 'items'];
        }
        else {
            return ['type'];
        }
    },
    extensionsPrefix: 'x-',
};
const Tag = {
    properties: {
        name: { type: 'string' },
        description: { type: 'string' },
        externalDocs: 'ExternalDocs',
        'x-traitTag': { type: 'boolean' },
        'x-displayName': { type: 'string' },
    },
    required: ['name'],
    extensionsPrefix: 'x-',
};
const TagGroup = {
    properties: {
        name: { type: 'string' },
        tags: { type: 'array', items: { type: 'string' } },
    },
};
const Schema = {
    properties: {
        format: { type: 'string' },
        title: { type: 'string' },
        description: { type: 'string' },
        default: null,
        multipleOf: { type: 'number' },
        maximum: { type: 'number' },
        minimum: { type: 'number' },
        exclusiveMaximum: { type: 'boolean' },
        exclusiveMinimum: { type: 'boolean' },
        maxLength: { type: 'number' },
        minLength: { type: 'number' },
        pattern: { type: 'string' },
        maxItems: { type: 'number' },
        minItems: { type: 'number' },
        uniqueItems: { type: 'boolean' },
        maxProperties: { type: 'number' },
        minProperties: { type: 'number' },
        required: { type: 'array', items: { type: 'string' } },
        enum: { type: 'array' },
        type: {
            type: 'string',
            enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'],
        },
        items: (value) => {
            if (Array.isArray(value)) {
                return (0, _1.listOf)('Schema');
            }
            else {
                return 'Schema';
            }
        },
        allOf: (0, _1.listOf)('Schema'),
        properties: 'SchemaProperties',
        additionalProperties: (value) => {
            if (typeof value === 'boolean') {
                return { type: 'boolean' };
            }
            else {
                return 'Schema';
            }
        },
        discriminator: { type: 'string' },
        readOnly: { type: 'boolean' },
        xml: 'Xml',
        externalDocs: 'ExternalDocs',
        example: { isExample: true },
        'x-tags': { type: 'array', items: { type: 'string' } },
        'x-nullable': { type: 'boolean' },
        'x-extendedDiscriminator': { type: 'string' },
        'x-additionalPropertiesName': { type: 'string' },
        'x-explicitMappingOnly': { type: 'boolean' },
        'x-enumDescriptions': 'EnumDescriptions',
    },
    extensionsPrefix: 'x-',
};
const EnumDescriptions = {
    properties: {},
    additionalProperties: { type: 'string' },
};
const SchemaProperties = {
    properties: {},
    additionalProperties: 'Schema',
};
const Xml = {
    properties: {
        name: { type: 'string' },
        namespace: { type: 'string' },
        prefix: { type: 'string' },
        attribute: { type: 'boolean' },
        wrapped: { type: 'boolean' },
    },
    extensionsPrefix: 'x-',
};
const SecurityScheme = {
    properties: {
        type: { enum: ['basic', 'apiKey', 'oauth2'] },
        description: { type: 'string' },
        name: { type: 'string' },
        in: { type: 'string', enum: ['query', 'header'] },
        flow: { enum: ['implicit', 'password', 'application', 'accessCode'] },
        authorizationUrl: { type: 'string' },
        tokenUrl: { type: 'string' },
        scopes: { type: 'object', additionalProperties: { type: 'string' } },
        'x-defaultClientId': { type: 'string' },
    },
    required(value) {
        switch (value?.type) {
            case 'apiKey':
                return ['type', 'name', 'in'];
            case 'oauth2':
                switch (value?.flow) {
                    case 'implicit':
                        return ['type', 'flow', 'authorizationUrl', 'scopes'];
                    case 'accessCode':
                        return ['type', 'flow', 'authorizationUrl', 'tokenUrl', 'scopes'];
                    case 'application':
                    case 'password':
                        return ['type', 'flow', 'tokenUrl', 'scopes'];
                    default:
                        return ['type', 'flow', 'scopes'];
                }
            default:
                return ['type'];
        }
    },
    allowed(value) {
        switch (value?.type) {
            case 'basic':
                return ['type', 'description'];
            case 'apiKey':
                return ['type', 'name', 'in', 'description'];
            case 'oauth2':
                switch (value?.flow) {
                    case 'implicit':
                        return ['type', 'flow', 'authorizationUrl', 'description', 'scopes'];
                    case 'accessCode':
                        return ['type', 'flow', 'authorizationUrl', 'tokenUrl', 'description', 'scopes'];
                    case 'application':
                    case 'password':
                        return ['type', 'flow', 'tokenUrl', 'description', 'scopes'];
                    default:
                        return ['type', 'flow', 'tokenUrl', 'authorizationUrl', 'description', 'scopes'];
                }
            default:
                return ['type', 'description'];
        }
    },
    extensionsPrefix: 'x-',
};
const SecurityRequirement = {
    properties: {},
    additionalProperties: { type: 'array', items: { type: 'string' } },
};
const Example = {
    properties: {
        value: { isExample: true },
        summary: { type: 'string' },
        description: { type: 'string' },
        externalValue: { type: 'string' },
    },
    extensionsPrefix: 'x-',
};
exports.Oas2Types = {
    Root,
    Tag,
    TagList: (0, _1.listOf)('Tag'),
    TagGroups: (0, _1.listOf)('TagGroup'),
    TagGroup,
    ExternalDocs,
    Example,
    ExamplesMap: (0, _1.mapOf)('Example'),
    EnumDescriptions,
    SecurityRequirement,
    SecurityRequirementList: (0, _1.listOf)('SecurityRequirement'),
    Info,
    Contact,
    License,
    Logo,
    Paths,
    PathItem,
    Parameter,
    ParameterItems,
    ParameterList: (0, _1.listOf)('Parameter'),
    Operation,
    Examples,
    Header,
    Responses,
    Response,
    Schema,
    Xml,
    SchemaProperties,
    NamedSchemas: (0, _1.mapOf)('Schema'),
    NamedResponses: (0, _1.mapOf)('Response'),
    NamedParameters: (0, _1.mapOf)('Parameter'),
    NamedSecuritySchemes: (0, _1.mapOf)('SecurityScheme'),
    SecurityScheme,
    XCodeSample,
    XCodeSampleList: (0, _1.listOf)('XCodeSample'),
    XServerList: (0, _1.listOf)('XServer'),
    XServer,
};
