"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateJSONSchemaFromTypeNode = void 0;
const graphql_transformer_common_1 = require("graphql-transformer-common");
const generateJSONSchemaFromTypeNode = (type, ctx) => {
    const baseType = (0, graphql_transformer_common_1.getBaseType)(type);
    if ((0, graphql_transformer_common_1.isScalar)(type)) {
        return generateScalarSchema(baseType);
    }
    const inputType = ctx.output.getType(baseType);
    if (inputType) {
        return generateInputObjectSchema(inputType, ctx, baseType);
    }
    return undefined;
};
exports.generateJSONSchemaFromTypeNode = generateJSONSchemaFromTypeNode;
const generateFieldSchema = (field) => {
    const baseType = (0, graphql_transformer_common_1.getBaseType)(field.type);
    if (field.type.kind === 'ListType') {
        return {
            type: 'array',
            items: (0, graphql_transformer_common_1.isScalar)(field.type) ? generateScalarSchema(baseType) : { $ref: `#/$defs/${baseType}` },
        };
    }
    if ((0, graphql_transformer_common_1.isScalar)(field.type)) {
        return generateScalarSchema(baseType);
    }
    return { $ref: `#/$defs/${baseType}` };
};
const collectInputTypeDefinitions = (typeName, ctx, definitions, visited) => {
    var _a, _b;
    if (visited.has(typeName))
        return;
    visited.add(typeName);
    const type = ctx.output.getType(typeName);
    if (!type)
        return;
    if (type.kind === 'EnumTypeDefinition') {
        definitions[typeName] = {
            type: 'string',
            enum: ((_a = type.values) === null || _a === void 0 ? void 0 : _a.map((value) => value.name.value)) || [],
        };
        return;
    }
    if (type.kind === 'InputObjectTypeDefinition') {
        const properties = {};
        const required = [];
        (_b = type.fields) === null || _b === void 0 ? void 0 : _b.forEach((field) => {
            const fieldBaseType = (0, graphql_transformer_common_1.getBaseType)(field.type);
            const fieldType = ctx.output.getType(fieldBaseType);
            if (fieldType) {
                collectInputTypeDefinitions(fieldBaseType, ctx, definitions, visited);
            }
            const fieldSchema = generateFieldSchema(field);
            if (fieldSchema) {
                properties[field.name.value] = fieldSchema;
                if ((0, graphql_transformer_common_1.isNonNullType)(field.type)) {
                    required.push(field.name.value);
                }
            }
        });
        definitions[typeName] = {
            type: 'object',
            properties,
            ...(required.length > 0 && { required }),
        };
    }
};
const generateInputObjectSchema = (inputType, ctx, typeName) => {
    var _a;
    const properties = {};
    const required = [];
    const $defs = {};
    collectInputTypeDefinitions(typeName, ctx, $defs, new Set());
    (_a = inputType.fields) === null || _a === void 0 ? void 0 : _a.forEach((field) => {
        const fieldSchema = generateFieldSchema(field);
        if (fieldSchema) {
            properties[field.name.value] = fieldSchema;
            if ((0, graphql_transformer_common_1.isNonNullType)(field.type)) {
                required.push(field.name.value);
            }
        }
    });
    return {
        type: 'object',
        $defs,
        properties,
        ...(required.length > 0 && { required }),
    };
};
const generateScalarSchema = (scalarType) => {
    switch (scalarType) {
        case 'Int':
            return { type: 'integer' };
        case 'Float':
            return { type: 'number' };
        case 'Boolean':
            return { type: 'boolean' };
        case 'ID':
        case 'String':
        default:
            return { type: 'string' };
    }
};
//# sourceMappingURL=graphql-json-schema-type.js.map