const unsupported = new Set([
    'ZodEffects',
    'ZodPipeline',
    'ZodLazy',
    'ZodPromise',
    'ZodFunction',
    'ZodTransform',
    'pipe',
    'lazy',
    'promise',
    'function',
    'transform',
    'custom',
]);
export function validateZodSubset(schema) {
    const seen = new Set();
    visit(schema, '$', seen);
}
function visit(schema, path, seen) {
    if (seen.has(schema)) {
        return;
    }
    seen.add(schema);
    const typeName = schema?._def?.typeName ?? schema?._def?.type;
    if (unsupported.has(String(typeName))) {
        throw new Error(`${path}: unsupported Zod schema feature ${typeName}`);
    }
    const def = schema?._def;
    if (!def) {
        return;
    }
    rejectUnsupportedChecks(def, path);
    for (const child of childSchemas(def)) {
        visit(child.schema, `${path}${child.path}`, seen);
    }
}
function rejectUnsupportedChecks(def, path) {
    if (!Array.isArray(def.checks)) {
        return;
    }
    for (const [index, check] of def.checks.entries()) {
        const checkType = check?.def?.type ?? check?._def?.type ?? check?._zod?.def?.check;
        if (String(checkType) === 'custom') {
            throw new Error(`${path}.checks[${index}]: unsupported Zod schema feature custom`);
        }
    }
}
function childSchemas(def) {
    const children = [];
    if (def.innerType)
        children.push({ path: '.inner', schema: def.innerType });
    if (def.schema)
        children.push({ path: '.schema', schema: def.schema });
    if (def.valueType)
        children.push({ path: '.value', schema: def.valueType });
    if (def.keyType)
        children.push({ path: '.key', schema: def.keyType });
    if (def.element)
        children.push({ path: '.element', schema: def.element });
    if (Array.isArray(def.options)) {
        def.options.forEach((schema, index) => children.push({ path: `.options[${index}]`, schema }));
    }
    if (Array.isArray(def.items)) {
        def.items.forEach((schema, index) => children.push({ path: `.items[${index}]`, schema }));
    }
    const shape = typeof def.shape === 'function' ? def.shape() : def.shape;
    if (shape && typeof shape === 'object') {
        for (const [name, schema] of Object.entries(shape)) {
            children.push({ path: `.shape.${name}`, schema: schema });
        }
    }
    return children;
}
