import { Table } from "../table.cjs";
import { AnyColumn, Column } from "../column.cjs";
import { entityKind } from "../entity.cjs";
import { SelectResult } from "../query-builders/select.types.cjs";
import { Subquery } from "../subquery.cjs";
import { Assume, Equal } from "../utils.cjs";
import { CodecsCollection } from "../codecs.cjs";

//#region src/sql/sql.d.ts
/**
 * This class is used to indicate a primitive param value that is used in `sql` tag.
 * It is only used on type level and is never instantiated at runtime.
 * If you see a value of this type in the code, its runtime value is actually the primitive param value.
 */
declare class FakePrimitiveParam {
  static readonly [entityKind]: string;
}
type Chunk = string | Table | View | AnyColumn | Name | Param | Placeholder | SQL;
interface BuildQueryConfig {
  escapeName(name: string): string;
  escapeParam(num: number, value: unknown): string;
  escapeString(str: string): string;
  codecs?: CodecsCollection;
  paramStartIndex?: {
    value: number;
  };
  inlineParams?: boolean;
  invokeSource?: 'indexes' | 'mssql-check' | 'mssql-view-with-schemabinding' | undefined;
  tagged?: true;
}
interface Query {
  sql: string;
  params: unknown[];
  _sql?: TemplateStringsArray;
}
/**
 * Any value that implements the `getSQL` method. The implementations include:
 * - `Table`
 * - `Column`
 * - `View`
 * - `Subquery`
 * - `SQL`
 * - `SQL.Aliased`
 * - `Placeholder`
 * - `Param`
 */
interface SQLWrapper<T = unknown> {
  getSQL(): SQL<T>;
  shouldOmitSQLParens?(): boolean;
}
declare function isSQLWrapper(value: unknown): value is SQLWrapper;
declare class StringChunk implements SQLWrapper {
  readonly value: string;
  static readonly [entityKind]: string;
  constructor(value: string);
  getSQL(): SQL<unknown>;
}
declare class SQL<T = unknown> implements SQLWrapper<T> {
  readonly queryChunks: SQLChunk[];
  static readonly [entityKind]: string;
  _: {
    brand: 'SQL';
    type: T;
  };
  constructor(queryChunks: SQLChunk[]);
  append(query: SQL): this;
  toQuery(config: BuildQueryConfig): Query;
  buildQueryFromSourceParams(chunks: SQLChunk[], _config: BuildQueryConfig): Query;
  private collectSQL;
  private mapInlineParam;
  getSQL(): SQL<T>;
  as(alias: string): SQL.Aliased<T>;
  /**
   * @deprecated
   * Use ``sql<DataType>`query`.as(alias)`` instead.
   */
  as<TData>(): SQL<TData>;
  /**
   * @deprecated
   * Use ``sql<DataType>`query`.as(alias)`` instead.
   */
  as<TData>(alias: string): SQL.Aliased<TData>;
  mapWith<TDecoder extends DriverValueDecoder<any, Exclude<T, null>> | DriverValueDecoder<any, Exclude<T, null>>['mapFromDriverValue']>(decoder: TDecoder): Equal<T, unknown> extends true ? SQL<GetDecoderResult<TDecoder>> : Equal<T, any> extends true ? SQL<GetDecoderResult<TDecoder>> : SQL<GetDecoderResult<TDecoder> | (null extends T ? null : never)>;
  nullable(): SQL<T | null>;
  inlineParams(): this;
  /**
   * This method is used to conditionally include a part of the query.
   *
   * @param condition - Condition to check
   * @returns itself if the condition is `true`, otherwise `undefined`
   */
  if(condition: any | undefined): this | undefined;
}
type GetDecoderResult<T> = T extends Column ? T['_']['data'] : T extends DriverValueDecoder<infer TData, any> | DriverValueDecoder<infer TData, any>['mapFromDriverValue'] ? TData : never;
/**
 * Any DB name (table, column, index etc.)
 */
declare class Name implements SQLWrapper {
  readonly value: string;
  static readonly [entityKind]: string;
  protected brand: 'Name';
  constructor(value: string);
  getSQL(): SQL<unknown>;
}
/**
 * Any DB name (table, column, index etc.)
 * @deprecated Use `sql.identifier` instead.
 */
declare function name(value: string): Name;
interface DriverValueDecoderFn<TData, TDriverParam> {
  (value: TDriverParam): TData;
}
interface DriverValueDecoder<TData, TDriverParam> {
  mapFromDriverValue: DriverValueDecoderFn<TData, TDriverParam>;
}
interface DriverValueEncoderFn<TData, TDriverParam> {
  (value: TData): TDriverParam;
}
interface DriverValueEncoder<TData, TDriverParam> {
  mapToDriverValue: DriverValueEncoderFn<TData, TDriverParam>;
}
declare function isDriverValueEncoder(value: unknown): value is DriverValueEncoder<any, any>;
declare const noopDecoder: DriverValueDecoder<any, any>;
declare const noopEncoder: DriverValueEncoder<any, any>;
interface DriverValueMapper<TData, TDriverParam> extends DriverValueDecoder<TData, TDriverParam>, DriverValueEncoder<TData, TDriverParam> {}
declare function isNoop(mapper: DriverValueEncoderFn<any, any> | DriverValueDecoderFn<any, any>): true | undefined;
declare const noopMapper: DriverValueMapper<any, any>;
/** Parameter value that is optionally bound to an encoder (for example, a column). */
declare class Param<TDataType = any, TDriverParamType = TDataType> implements SQLWrapper {
  readonly value: TDataType | Placeholder<string, TDataType>;
  readonly encoder: DriverValueEncoder<TDataType, TDriverParamType>;
  codec?: ((value: any) => any) | undefined;
  static readonly [entityKind]: string;
  protected brand: 'BoundParamValue';
  /**
   * @param value - Parameter value
   * @param encoder - Encoder to convert the value to a driver parameter
   */
  constructor(value: TDataType | Placeholder<string, TDataType>, encoder?: DriverValueEncoder<TDataType, TDriverParamType>, codec?: ((value: any) => any) | undefined);
  getSQL(): SQL<unknown>;
}
/** @deprecated Use `sql.param` instead. */
declare function param<TData, TDriver>(value: TData, encoder?: DriverValueEncoder<TData, TDriver>): Param<TData, TDriver>;
/**
 * Anything that can be passed to the `` sql`...` `` tagged function.
 */
type SQLChunk = StringChunk | SQLChunk[] | SQLWrapper | SQL | Table | View | Subquery | AnyColumn | Param | Name | undefined | FakePrimitiveParam | Placeholder;
type SQLGenerator<T = unknown> = typeof sql<T>;
declare function sql<T>(strings: TemplateStringsArray, ...params: any[]): SQL<T>;
declare namespace sql {
  function empty(): SQL;
  /** @deprecated - use `sql.join()` */
  function fromList(list: SQLChunk[]): SQL;
  /**
   * Convenience function to create an SQL query from a raw string.
   * @param str The raw SQL query string.
   */
  function raw(str: string): SQL;
  /**
   * Join a list of SQL chunks with a separator.
   * @example
   * ```ts
   * const query = sql.join([sql`a`, sql`b`, sql`c`]);
   * // sql`abc`
   * ```
   * @example
   * ```ts
   * const query = sql.join([sql`a`, sql`b`, sql`c`], sql`, `);
   * // sql`a, b, c`
   * ```
   */
  function join(chunks: SQLChunk[], separator?: SQLChunk): SQL;
  /**
   * Create a SQL chunk that represents a DB identifier (table, column, index etc.).
   * When used in a query, the identifier will be escaped based on the DB engine.
   * For example, in PostgreSQL, identifiers are escaped with double quotes.
   *
   * **WARNING: This function does not offer any protection against SQL injections, so you must validate any user input beforehand.**
   *
   * @example ```ts
   * const query = sql`SELECT * FROM ${sql.identifier('my-table')}`;
   * // 'SELECT * FROM "my-table"'
   * ```
   */
  function identifier(value: string): Name;
  function placeholder<TName extends string>(name: TName): Placeholder<TName>;
  function param<TData, TDriver>(value: TData | Placeholder<string, TData>, encoder?: DriverValueEncoder<TData, TDriver>): Param<TData, TDriver>;
  /**
   * Attach [sqlcommenter](https://google.github.io/sqlcommenter) comment to a query
   */
  function comment(input: CommentInput): SQL | undefined;
}
declare function sqlCommenter(input: CommentInput): string;
declare namespace sqlCommenter {
  function merge(input1: CommentInput | undefined, input2: CommentInput | undefined): string;
  function encodeInput(input: CommentInput): string;
  function sanitizeObjectElement(key: string): string;
  function sanitizeStringInput(input: string): string;
}
type CommentInput = string | SqlCommenterInput;
type SqlCommenterInput = Record<string, string | number | bigint | boolean | null | undefined>;
declare namespace SQL {
  class Aliased<T = unknown> implements SQLWrapper<T> {
    readonly sql: SQL<T>;
    readonly fieldAlias: string;
    static readonly [entityKind]: string;
    _: {
      brand: 'SQL.Aliased';
      type: T;
    };
    constructor(sql: SQL<T>, fieldAlias: string);
    getSQL(): SQL<T>;
  }
}
declare class Placeholder<TName extends string = string, TValue = any> implements SQLWrapper {
  readonly name: TName;
  static readonly [entityKind]: string;
  protected: TValue;
  constructor(name: TName);
  getSQL(): SQL;
}
/** @deprecated Use `sql.placeholder` instead. */
declare function placeholder<TName extends string>(name: TName): Placeholder<TName>;
declare function fillPlaceholders(params: unknown[], values: Record<string, unknown>): unknown[];
type ColumnsSelection = Record<string, unknown>;
declare abstract class View<TName extends string = string, TExisting extends boolean = boolean, TSelection extends ColumnsSelection = ColumnsSelection> {
  static readonly [entityKind]: string;
  _: {
    brand: 'View';
    viewBrand: string;
    name: TName;
    existing: TExisting;
    selectedFields: TSelection;
  };
  readonly $inferSelect: InferSelectViewModel<View<Assume<TName, string>, TExisting, TSelection>>;
  constructor({
    name,
    schema,
    selectedFields,
    query
  }: {
    name: TName;
    schema: string | undefined;
    selectedFields: ColumnsSelection;
    query: SQL | undefined;
  });
}
declare function isView(view: unknown): view is View;
declare function getViewName<T extends View>(view: T): T['_']['name'];
type InferSelectViewModel<TView extends View> = Equal<TView['_']['selectedFields'], {
  [x: string]: unknown;
}> extends true ? {
  [x: string]: unknown;
} : SelectResult<TView['_']['selectedFields'], 'single', Record<TView['_']['name'], 'not-null'>>;
type SQLEntity = SQL | SQLWrapper | SQL.Aliased | Table | View;
//#endregion
export { BuildQueryConfig, Chunk, ColumnsSelection, CommentInput, DriverValueDecoder, DriverValueDecoderFn, DriverValueEncoder, DriverValueEncoderFn, DriverValueMapper, FakePrimitiveParam, GetDecoderResult, InferSelectViewModel, Name, Param, Placeholder, Query, SQL, SQLChunk, SQLEntity, SQLGenerator, SQLWrapper, SqlCommenterInput, StringChunk, View, fillPlaceholders, getViewName, isDriverValueEncoder, isNoop, isSQLWrapper, isView, name, noopDecoder, noopEncoder, noopMapper, param, placeholder, sql, sqlCommenter };
//# sourceMappingURL=sql.d.cts.map