import { faker } from '@faker-js/faker';
import { VineValidator } from '@vinejs/vine';
import _ from 'lodash';
export class VineParser {
    #node;
    get fieldName() {
        return this.#node.fieldName;
    }
    constructor(schema) {
        if (schema instanceof VineValidator) {
            this.#node = schema.toJSON().schema.schema;
        }
        else {
            this.#node = schema;
        }
    }
    parseAsParameter() {
        switch (this.#node.type) {
            case 'literal':
                const subtype = this.#node.subtype;
                return [
                    {
                        name: this.fieldName,
                        in: 'query',
                        required: !this.#node.isOptional,
                        schema: {
                            type: subtype === 'enum' ? 'string' : subtype,
                        },
                    },
                ];
            case 'object':
                return _(this.#node.properties)
                    .map((p) => new VineParser(p).parseAsParameter())
                    .flatten()
                    .value();
            case 'array':
                return new VineParser(this.#node.each).parseAsParameter();
            default:
                throw Error(`Can't parse vine type as parameters : ${this.#node.type}`);
        }
    }
    parseAsSchema() {
        if (_.has(this.#node, 'isOptional'))
            return {
                optional: this.#node.isOptional,
                schema: this.#parseAsSchemaNonOptional(),
            };
        throw Error(`Can't parse non field nodes`);
    }
    #parseAsSchemaNonOptional() {
        const parseVineObject = (schema) => {
            const parsedSchema = _.mapValues(schema, (v) => new VineParser(v).parseAsSchema());
            return {
                type: 'object',
                properties: _.mapValues(parsedSchema, (p) => p.schema),
                required: _(parsedSchema)
                    .omitBy((p) => p.optional)
                    .keys()
                    .value(),
            };
        };
        switch (this.#node.type) {
            case 'literal':
                const subtype = this.#node.subtype;
                const schema = this.#node.schema;
                if (subtype === 'instanceof' && schema) {
                    return new VineParser(schema).parseAsSchema().schema;
                }
                else
                    return {
                        type: subtype === 'enum' ? 'string' : subtype,
                        example: this.example(subtype),
                    };
            case 'object':
                const parsedProperties = _(this.#node.properties)
                    .map((p) => [p.fieldName, p])
                    .fromPairs()
                    .value();
                return parseVineObject(parsedProperties);
            case 'array':
                const subParser = new VineParser(this.#node.each);
                const subProperties = subParser.parseAsSchema();
                return {
                    type: 'array',
                    items: subProperties.schema,
                    example: subProperties.schema.type === 'enum'
                        ? subParser.example('enumValues')
                        : undefined,
                };
            default:
                throw Error(`Can't parse vine type as schema : ${this.#node.type}`);
        }
    }
    example(openApiType) {
        const subExample = (fieldName) => {
            const includes = {
                email: faker.internet.email,
                id: faker.string.uuid,
                url: faker.image.url,
                mimeType: faker.system.mimeType,
                path: faker.system.filePath,
                name: faker.internet.displayName,
                password: faker.internet.password,
                city: faker.location.city,
                postal: '69007',
                address: faker.location.streetAddress,
                siren: '320418301',
                siret: '32041830100023',
                latitude: faker.number.float,
                longitude: faker.number.float,
                token: faker.internet.jwt,
                phone: faker.phone.number,
                rate: faker.number.float,
            };
            for (const [key, fake] of Object.entries(includes)) {
                if (_.lowerCase(fieldName).includes(key)) {
                    return _.isFunction(fake) ? fake() : fake;
                }
            }
        };
        switch (openApiType) {
            case 'string':
                return subExample(this.fieldName) || 'example text';
            case 'date':
                return subExample(this.fieldName) || '2024-12-03T14:10:31Z';
            case 'enumValues':
                return this.#node.enumValues;
            case 'enum':
                return _.sample(this.#node.enumValues);
        }
    }
}
//# sourceMappingURL=vine_parser.js.map