diff --git a/types/slonik/index.d.ts b/types/slonik/index.d.ts index 336386f9e1..35acc62d50 100644 --- a/types/slonik/index.d.ts +++ b/types/slonik/index.d.ts @@ -26,6 +26,17 @@ export type LogicalBooleanOperatorType = 'AND' | 'OR'; // EXPRESSIONS AND TOKENS // ---------------------------------------------------------------------- +export type TypeNameIdentifierType = + 'bool' | + 'bytea' | + 'float4' | + 'float8' | + 'int2' | + 'int4' | + 'json' | + 'text' | + 'timestamptz'; + export type SerializableValueType = | string | number @@ -42,23 +53,30 @@ export interface SerializableValueObject { export interface SerializableValueArray extends ReadonlyArray {} -export interface IdentifierTokenType { +export type PositionalParameterValuesType = ReadonlyArray; + +export type NamedParameterValuesType = Record; + +export interface ArraySqlTokenType { + memberType: TypeNameIdentifierType | SqlTokenType; + type: typeof SlonikSymbol.ArrayTokenSymbol; + values: PositionalParameterValuesType; +} + +export interface BinarySqlTokenType { + data: Buffer; + type: typeof SlonikSymbol.BinaryTokenSymbol; +} + +export interface IdentifierSqlTokenType { names: ReadonlyArray; type: typeof SlonikSymbol.IdentifierTokenSymbol; } -export type SqlSqlTokenType = TaggedTemplateLiteralInvocationType; - -export interface RawSqlTokenType { - sql: string; - type: typeof SlonikSymbol.RawSqlTokenSymbol; - values: PrimitiveValueExpressionType[]; -} - -export interface ArraySqlTokenType { - memberType: string; - type: typeof SlonikSymbol.ArrayTokenSymbol; - values: PrimitiveValueExpressionType[]; +export interface ListSqlTokenType { + glue: SqlTokenType; + members: ReadonlyArray; + type: typeof SlonikSymbol.ListTokenSymbol; } export interface JsonSqlTokenType { @@ -66,19 +84,24 @@ export interface JsonSqlTokenType { type: typeof SlonikSymbol.JsonTokenSymbol; } +export type SqlSqlTokenType = TaggedTemplateLiteralInvocationType; + export interface UnnestSqlTokenType { - columnTypes: string[]; - tuples: PrimitiveValueExpressionType[][]; + columnTypes: ReadonlyArray; + tuples: ReadonlyArray; type: typeof SlonikSymbol.UnnestTokenSymbol; } -export type PrimitiveValueExpressionType = string | number | boolean | null; +export type PrimitiveValueExpressionType = string | number | boolean | null | PrimitiveValueExpressionTypeArray; + +export interface PrimitiveValueExpressionTypeArray extends Array {} export type SqlTokenType = ArraySqlTokenType | - IdentifierTokenType | + BinarySqlTokenType | + IdentifierSqlTokenType | JsonSqlTokenType | - RawSqlTokenType | + ListSqlTokenType | SqlSqlTokenType | UnnestSqlTokenType; @@ -281,20 +304,24 @@ export interface SqlTaggedTemplateType { ) => ArraySqlTokenType; identifier: ( names: string[] - ) => IdentifierTokenType; + ) => IdentifierSqlTokenType; json: ( value: SerializableValueType ) => JsonSqlTokenType; + join: ( + members: ReadonlyArray, + glue: SqlTokenType, + ) => ListSqlTokenType; raw: ( rawSql: string, - values?: PrimitiveValueExpressionType[] - ) => RawSqlTokenType; + values?: ReadonlyArray + ) => SqlTokenType; unnest: ( - // Value might be PrimitiveValueExpressionType[], + // Value might be ReadonlyArray>, // or it can be infinitely nested array, e.g. // https://github.com/gajus/slonik/issues/44 - tuples: any[][], - columnTypes: string[] + tuples: ReadonlyArray>, + columnTypes: ReadonlyArray ) => UnnestSqlTokenType; } diff --git a/types/slonik/slonik-tests.ts b/types/slonik/slonik-tests.ts index f4d448b4df..fb22733e35 100644 --- a/types/slonik/slonik-tests.ts +++ b/types/slonik/slonik-tests.ts @@ -22,11 +22,11 @@ import { UniqueIntegrityConstraintViolationError, SqlTaggedTemplateType } from 'slonik'; -import { ArrayTokenSymbol, TupleListTokenSymbol } from 'slonik/symbols'; +import { ArrayTokenSymbol, BinaryTokenSymbol } from 'slonik/symbols'; // make sure symbols are unique // $ExpectError -const badSymbolAssignment: typeof ArrayTokenSymbol = TupleListTokenSymbol; +const badSymbolAssignment: typeof ArrayTokenSymbol = BinaryTokenSymbol; const VALUE = 'foo'; @@ -268,6 +268,23 @@ createTimestampWithTimeZoneTypeParser(); // ExpectType SqlSqlTokenType const query1 = sql`SELECT ${'baz'} FROM (${query0})`; + await connection.query(sql` + SELECT ${sql.identifier(['foo', 'a'])} + FROM ( + VALUES + ( + ${sql.join( + [ + sql.join(['a1', 'b1', 'c1'], sql`, `), + sql.join(['a2', 'b2', 'c2'], sql`, `) + ], + sql`), (` + )} + ) + ) foo(a, b, c) + WHERE foo.b IN (${sql.join(['c1', 'a2'], sql`, `)}) + `); + await connection.query(sql` SELECT (${sql.json([1, 2, { test: 12, other: 'test' }])}) `); diff --git a/types/slonik/symbols.d.ts b/types/slonik/symbols.d.ts index 44d7a3ec39..b0967e7d75 100644 --- a/types/slonik/symbols.d.ts +++ b/types/slonik/symbols.d.ts @@ -1,13 +1,7 @@ export const ArrayTokenSymbol: unique symbol; -export const AssignmentListTokenSymbol: unique symbol; -export const BooleanExpressionTokenSymbol: unique symbol; -export const ComparisonPredicateTokenSymbol: unique symbol; -export const IdentifierListTokenSymbol: unique symbol; +export const BinaryTokenSymbol: unique symbol; export const IdentifierTokenSymbol: unique symbol; export const JsonTokenSymbol: unique symbol; -export const RawSqlTokenSymbol: unique symbol; +export const ListTokenSymbol: unique symbol; export const SqlTokenSymbol: unique symbol; -export const ValueListTokenSymbol: unique symbol; -export const TupleTokenSymbol: unique symbol; -export const TupleListTokenSymbol: unique symbol; export const UnnestTokenSymbol: unique symbol;