import { newQuery } from "./query-impl.js";
function normalizeParser(parser) {
    if (parser) {
        if ('parse' in parser) {
            return parser.parse.bind(parser);
        }
        return parser;
    }
    return undefined;
}
export function syncedQuery(name, parser, fn) {
    const impl = syncedQueryImpl(name, fn, false);
    const ret = (...args) => impl(undefined, args);
    ret.queryName = name;
    ret.parse = normalizeParser(parser);
    ret.takesContext = false;
    return ret;
}
export function syncedQueryWithContext(name, parser, fn) {
    const impl = syncedQueryImpl(name, fn, true);
    const ret = (context, ...args) => impl(context, args);
    ret.queryName = name;
    ret.parse = normalizeParser(parser);
    ret.takesContext = true;
    return ret;
}
function syncedQueryImpl(name, fn, takesContext) {
    return (context, args) => {
        const q = takesContext ? fn(context, ...args) : fn(...args);
        return q.nameAndArgs(name, args);
    };
}
export function withValidation(fn) {
    if (!fn.parse) {
        throw new Error('ret does not have a parse function defined');
    }
    const ret = (context, ...args) => {
        const f = fn;
        const parsed = f.parse(args);
        return f.takesContext ? f(context, ...parsed) : f(...parsed);
    };
    ret.queryName = fn.queryName;
    ret.parse = fn.parse;
    ret.takesContext = true;
    return ret;
}
/**
 * Returns a set of query builders for the given schema.
 */
export function createBuilder(s) {
    return makeQueryBuilders(s);
}
/**
 * This produces the query builders for a given schema.
 * For use in Zero on the server to process custom queries.
 */
function makeQueryBuilders(schema) {
    return new Proxy({}, {
        get: (target, prop) => {
            if (prop in target) {
                return target[prop];
            }
            if (!(prop in schema.tables)) {
                throw new Error(`Table ${prop} does not exist in schema`);
            }
            const q = newQuery(undefined, schema, prop);
            target[prop] = q;
            return q;
        },
    });
}
//# sourceMappingURL=named.js.map