import { QueryParseError } from "./error.js";
import { asQueryInternals } from "./query-internals.js";
import "../../../zero-protocol/src/ast.js";
function normalizeParser(parser) {
  if (parser) {
    if ("parse" in parser) {
      return parser.parse.bind(parser);
    }
    return parser;
  }
  return void 0;
}
function syncedQuery(name, parser, fn) {
  const impl = syncedQueryImpl(name, fn, false);
  const ret = (...args) => impl(void 0, args);
  ret.queryName = name;
  ret.parse = normalizeParser(parser);
  ret.takesContext = false;
  return ret;
}
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 asQueryInternals(q).nameAndArgs(name, args);
  };
}
function withValidation(fn) {
  if ("parse" in fn) {
    const { parse } = fn;
    if (!parse) {
      throw new Error("ret does not have a parse function defined");
    }
    const ret = (context, ...args) => {
      let parsed;
      try {
        parsed = parse(args);
      } catch (error) {
        throw new QueryParseError({ cause: error });
      }
      return fn.takesContext ? fn(context, ...parsed) : fn(...parsed);
    };
    ret.queryName = fn.queryName;
    ret.parse = fn.parse;
    ret.takesContext = true;
    return ret;
  }
  return fn;
}
export {
  syncedQuery,
  syncedQueryWithContext,
  withValidation
};
//# sourceMappingURL=named.js.map
