import { $$type } from "./thereCanBeOnlyOne.ts";
export { version } from "./version.ts";
/** Use this to enable coercing objects to SQL to make composing SQL fragments more ergonomic */
export declare const $$toSQL: unique symbol;
/** Experimental! */
export declare const $$symbolToIdentifier: unique symbol;
interface PgSQL2Proto {
}
/**
 * Represents raw SQL, the text will be output verbatim into the compiled query.
 */
export interface SQLRawNode {
    __proto__?: PgSQL2Proto;
    readonly [$$type]: "RAW";
}
/**
 * An SQL comment, ignored during comparisons
 */
export interface SQLCommentNode {
    __proto__?: PgSQL2Proto;
    readonly [$$type]: "COMMENT";
}
/**
 * Represents an SQL identifier such as table, column, function, etc name. These
 * identifiers will be automatically escaped when compiled, respecting any
 * reserved words.
 */
export interface SQLIdentifierNode {
    __proto__?: PgSQL2Proto;
    readonly [$$type]: "IDENTIFIER";
}
/**
 * A value that can be used in `sql.value(...)`; note that objects are **NOT**
 * valid values; you must `JSON.stringify(obj)` or similar.
 */
export type SQLRawValue = string | number | boolean | null | ReadonlyArray<SQLRawValue>;
/**
 * Represents an SQL value that will be replaced with a placeholder in the
 * compiled SQL statement.
 */
export interface SQLValueNode {
    __proto__?: PgSQL2Proto;
    readonly [$$type]: "VALUE";
}
/**
 * Represents that the SQL inside this should be indented when pretty printed.
 */
export interface SQLIndentNode {
    readonly [$$type]: "INDENT";
}
/**
 * Informs pg-sql2 to treat symbol2 as if it were the same as symbol1
 */
export interface SQLSymbolAliasNode {
    readonly [$$type]: "SYMBOL_ALIAS";
}
/**
 * A placeholder that should be replaced at compile time using one of the
 * replacements provided.
 */
export interface SQLPlaceholderNode {
    readonly [$$type]: "PLACEHOLDER";
}
export type SQLNode = SQLRawNode | SQLCommentNode | SQLValueNode | SQLIdentifierNode | SQLIndentNode | SQLSymbolAliasNode | SQLPlaceholderNode;
export interface SQLQuery {
    __proto__?: PgSQL2Proto;
    readonly [$$type]: "QUERY";
}
/**
 * Representation of SQL, identifiers, values, etc; to generate a query that
 * can be issued to the database it needs to be fed to `sql.compile`.
 */
export type SQL = SQLNode | SQLQuery;
export declare function escapeSqlIdentifier(str: string): string;
declare function isSQL(node: unknown): node is SQL;
export interface SQLable {
    [$$type]?: never;
    [$$toSQL](): SQL;
}
export interface PgSQLCompileOptions {
    placeholderValues?: ReadonlyMap<symbol, SQL>;
}
export interface PgSQLCompileResult {
    text: string;
    values: SQLRawValue[];
    [$$symbolToIdentifier]: Map<symbol, string>;
}
/**
 * Accepts an sql`...` expression and compiles it out to SQL text with
 * placeholders, and the values to substitute for these values.
 */
export declare function compile(sql: SQL, options?: PgSQLCompileOptions): PgSQLCompileResult;
/**
 * Creates a SQL item for some raw SQL text. Just plain ol‘ raw SQL. This
 * method is dangerous though because it involves no escaping, so proceed with
 * caution! It's very very rarely warranted - there is likely a safer way of
 * achieving your goal.
 */
export declare function raw(text: string): SQL;
/**
 * Creates a SQL item for a SQL identifier. A SQL identifier is anything like
 * a table, schema, or column name. An identifier may also have a namespace,
 * thus why many names are accepted.
 */
export declare function identifier(...names: Array<string | symbol>): SQL;
/**
 * Creates a SQL item for a value that will be included in our final query.
 * This value will be added in a way which avoids SQL injection.
 */
export declare function value(val: SQLRawValue): SQL;
/** Equivalent to
 *
 * ```
 * sql`${JSON.stringify(val)}::json`
 * ```
 */
export declare function json(val: any): SQL;
declare const trueNode: SQLRawNode;
declare const falseNode: SQLRawNode;
declare const nullNode: SQLRawNode;
export declare const blank: SQLRawNode;
export declare const dot: SQLRawNode;
/**
 * If the value is simple will inline it into the query, otherwise will defer
 * to `sql.value`.
 */
export declare function literal(val: string | number | boolean | null): SQL;
/**
 * Join some SQL items together, optionally separated by a string. Useful when
 * dealing with lists of SQL items, for example a dynamic list of columns or
 * variadic SQL function arguments.
 */
export declare function join(items: ReadonlyArray<SQL>, separator?: string): SQL;
export declare function indent(fragment: SQL): SQL;
export declare function indent(strings: TemplateStringsArray, ...values: ReadonlyArray<SQL>): SQL;
export declare function indentIf(condition: boolean, fragment: SQL): SQL;
/**
 * Wraps the given fragment in parens if necessary (or if forced, e.g. for a
 * subquery or maybe stylistically a join condition).
 *
 * Returns the input SQL fragment if it does not need parenthesis to be
 * inserted into another expression, otherwise a parenthesised fragment if not
 * doing so could cause ambiguity. We're relying on the user to be sensible
 * here, this is not fool-proof.
 *
 * @remarks The following are all parens safe:
 *
 * - A placeholder `$1`
 * - A number `0.123456`
 * - A string `'Foo bar'` / `E'Foo bar'`
 * - An identifier `table.column` / `"MyTaBlE"."MyCoLuMn"`
 *
 * The following might seem but are not parens safe:
 *
 * - A function call `schema.func(param)` - reason: `schema.func(param).*`
 *   should be `(schema.func(param)).*`
 * - A simple expression `1 = 2` - reason: `1 = 2 = false` is invalid; whereas
 *   `(1 = 2) = false` is fine. Similarly `1 = 2::text` differs from `(1 = 2)::text`.
 * - An identifier `table.column.attribute` / `"MyTaBlE"."MyCoLuMn"."MyAtTrIbUtE"` (this needs to be `(table.column).attribute`)
 */
export declare function parens(frag: SQL, force?: boolean): SQL;
export declare function symbolAlias(symbol1: symbol, symbol2: symbol): SQL;
export declare function placeholder(symbol: symbol, fallback?: SQL): SQL;
export declare function comment(text: string, include?: boolean): SQLCommentNode | SQLRawNode;
export declare function arraysMatch<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, comparator?: (val1: T, val2: T) => boolean): boolean;
export interface PgSQLIsEquivalentOptions {
    symbolSubstitutes?: ReadonlyMap<symbol, symbol>;
}
export declare function isEquivalent(sql1: SQL, sql2: SQL, options?: PgSQLIsEquivalentOptions): boolean;
/**
 * @experimental
 */
export declare function replaceSymbol(frag: SQL, needle: symbol, replacement: symbol): SQL;
export type Transformer<TNewEmbed> = <TValue>(sql: PgSQL, value: TNewEmbed | TValue, where?: string) => SQL | TValue;
export declare function withTransformer<TNewEmbed, TResult = SQL>(transformer: Transformer<TNewEmbed>, callback: (sql: PgSQL<TNewEmbed>) => TResult): TResult;
/** If node is an identifier, return its symbol, otherwise return null */
declare function getIdentifierSymbol(potentialIdentifier: SQL): symbol | null;
export declare const sql: PgSQL;
export default sql;
export { falseNode as FALSE, falseNode as false, sql as fragment, isSQL, nullNode as NULL, nullNode as null, sql as query, trueNode as TRUE, trueNode as true, };
export interface PgSQL<TEmbed = never> {
    (strings: TemplateStringsArray, ...values: Array<SQL | SQLable | TEmbed>): SQL;
    escapeSqlIdentifier: typeof escapeSqlIdentifier;
    compile: typeof compile;
    isEquivalent: typeof isEquivalent;
    query: PgSQL<TEmbed>;
    raw: typeof raw;
    identifier: typeof identifier;
    value: typeof value;
    json: typeof json;
    literal: typeof literal;
    join: typeof join;
    indent(fragment: SQL): SQL;
    indent(strings: TemplateStringsArray, ...values: Array<SQL | SQLable | TEmbed>): SQL;
    indentIf: typeof indentIf;
    parens: typeof parens;
    comment: typeof comment;
    symbolAlias: typeof symbolAlias;
    placeholder: typeof placeholder;
    blank: typeof blank;
    fragment: PgSQL<TEmbed>;
    true: typeof trueNode;
    TRUE: typeof trueNode;
    false: typeof falseNode;
    FALSE: typeof falseNode;
    null: typeof nullNode;
    NULL: typeof nullNode;
    isSQL: typeof isSQL;
    replaceSymbol: typeof replaceSymbol;
    sql: PgSQL<TEmbed>;
    withTransformer<TNewEmbed, TResult = SQL>(transformer: Transformer<TNewEmbed>, callback: (sql: PgSQL<TEmbed | TNewEmbed>) => TResult): TResult;
    getIdentifierSymbol: typeof getIdentifierSymbol;
}
//# sourceMappingURL=index.d.ts.map