@kuindji/typed-sql 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/dist/builder/assemble.d.ts +13 -0
  4. package/dist/builder/assemble.d.ts.map +1 -0
  5. package/dist/builder/assemble.js +86 -0
  6. package/dist/builder/assemble.js.map +1 -0
  7. package/dist/builder/condition-tree.d.ts +27 -0
  8. package/dist/builder/condition-tree.d.ts.map +1 -0
  9. package/dist/builder/condition-tree.js +91 -0
  10. package/dist/builder/condition-tree.js.map +1 -0
  11. package/dist/builder/conditional-sql.d.ts +80 -0
  12. package/dist/builder/conditional-sql.d.ts.map +1 -0
  13. package/dist/builder/conditional-sql.js +88 -0
  14. package/dist/builder/conditional-sql.js.map +1 -0
  15. package/dist/builder/db.d.ts +76 -0
  16. package/dist/builder/db.d.ts.map +1 -0
  17. package/dist/builder/db.js +12 -0
  18. package/dist/builder/db.js.map +1 -0
  19. package/dist/builder/delete.d.ts +39 -0
  20. package/dist/builder/delete.d.ts.map +1 -0
  21. package/dist/builder/delete.js +33 -0
  22. package/dist/builder/delete.js.map +1 -0
  23. package/dist/builder/extract-params.d.ts +97 -0
  24. package/dist/builder/extract-params.d.ts.map +1 -0
  25. package/dist/builder/extract-params.js +2 -0
  26. package/dist/builder/extract-params.js.map +1 -0
  27. package/dist/builder/index.d.ts +23 -0
  28. package/dist/builder/index.d.ts.map +1 -0
  29. package/dist/builder/index.js +14 -0
  30. package/dist/builder/index.js.map +1 -0
  31. package/dist/builder/insert.d.ts +51 -0
  32. package/dist/builder/insert.d.ts.map +1 -0
  33. package/dist/builder/insert.js +39 -0
  34. package/dist/builder/insert.js.map +1 -0
  35. package/dist/builder/mutate.d.ts +28 -0
  36. package/dist/builder/mutate.d.ts.map +1 -0
  37. package/dist/builder/mutate.js +17 -0
  38. package/dist/builder/mutate.js.map +1 -0
  39. package/dist/builder/params.d.ts +22 -0
  40. package/dist/builder/params.d.ts.map +1 -0
  41. package/dist/builder/params.js +65 -0
  42. package/dist/builder/params.js.map +1 -0
  43. package/dist/builder/return-type.d.ts +39 -0
  44. package/dist/builder/return-type.d.ts.map +1 -0
  45. package/dist/builder/return-type.js +2 -0
  46. package/dist/builder/return-type.js.map +1 -0
  47. package/dist/builder/scanner.d.ts +49 -0
  48. package/dist/builder/scanner.d.ts.map +1 -0
  49. package/dist/builder/scanner.js +240 -0
  50. package/dist/builder/scanner.js.map +1 -0
  51. package/dist/builder/select.d.ts +76 -0
  52. package/dist/builder/select.d.ts.map +1 -0
  53. package/dist/builder/select.js +240 -0
  54. package/dist/builder/select.js.map +1 -0
  55. package/dist/builder/sql-tag.d.ts +319 -0
  56. package/dist/builder/sql-tag.d.ts.map +1 -0
  57. package/dist/builder/sql-tag.js +3 -0
  58. package/dist/builder/sql-tag.js.map +1 -0
  59. package/dist/builder/sql.d.ts +17 -0
  60. package/dist/builder/sql.d.ts.map +1 -0
  61. package/dist/builder/sql.js +36 -0
  62. package/dist/builder/sql.js.map +1 -0
  63. package/dist/builder/state.d.ts +53 -0
  64. package/dist/builder/state.d.ts.map +1 -0
  65. package/dist/builder/state.js +18 -0
  66. package/dist/builder/state.js.map +1 -0
  67. package/dist/builder/update.d.ts +60 -0
  68. package/dist/builder/update.d.ts.map +1 -0
  69. package/dist/builder/update.js +40 -0
  70. package/dist/builder/update.js.map +1 -0
  71. package/dist/builder/write-assemble.d.ts +5 -0
  72. package/dist/builder/write-assemble.d.ts.map +1 -0
  73. package/dist/builder/write-assemble.js +57 -0
  74. package/dist/builder/write-assemble.js.map +1 -0
  75. package/dist/builder/write-state.d.ts +39 -0
  76. package/dist/builder/write-state.d.ts.map +1 -0
  77. package/dist/builder/write-state.js +6 -0
  78. package/dist/builder/write-state.js.map +1 -0
  79. package/dist/builder/write-tag.d.ts +91 -0
  80. package/dist/builder/write-tag.d.ts.map +1 -0
  81. package/dist/builder/write-tag.js +2 -0
  82. package/dist/builder/write-tag.js.map +1 -0
  83. package/dist/columns.d.ts +33 -0
  84. package/dist/columns.d.ts.map +1 -0
  85. package/dist/columns.js +2 -0
  86. package/dist/columns.js.map +1 -0
  87. package/dist/expressions.d.ts +71 -0
  88. package/dist/expressions.d.ts.map +1 -0
  89. package/dist/expressions.js +2 -0
  90. package/dist/expressions.js.map +1 -0
  91. package/dist/index.d.ts +22 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +5 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/parsing/extract.d.ts +47 -0
  96. package/dist/parsing/extract.d.ts.map +1 -0
  97. package/dist/parsing/extract.js +2 -0
  98. package/dist/parsing/extract.js.map +1 -0
  99. package/dist/parsing/normalize.d.ts +44 -0
  100. package/dist/parsing/normalize.d.ts.map +1 -0
  101. package/dist/parsing/normalize.js +2 -0
  102. package/dist/parsing/normalize.js.map +1 -0
  103. package/dist/parsing/pg-literals.d.ts +37 -0
  104. package/dist/parsing/pg-literals.d.ts.map +1 -0
  105. package/dist/parsing/pg-literals.js +2 -0
  106. package/dist/parsing/pg-literals.js.map +1 -0
  107. package/dist/parsing/split.d.ts +100 -0
  108. package/dist/parsing/split.d.ts.map +1 -0
  109. package/dist/parsing/split.js +2 -0
  110. package/dist/parsing/split.js.map +1 -0
  111. package/dist/parsing/string-utils.d.ts +29 -0
  112. package/dist/parsing/string-utils.d.ts.map +1 -0
  113. package/dist/parsing/string-utils.js +2 -0
  114. package/dist/parsing/string-utils.js.map +1 -0
  115. package/dist/parsing/tokenize.d.ts +27 -0
  116. package/dist/parsing/tokenize.d.ts.map +1 -0
  117. package/dist/parsing/tokenize.js +2 -0
  118. package/dist/parsing/tokenize.js.map +1 -0
  119. package/dist/parsing.d.ts +7 -0
  120. package/dist/parsing.d.ts.map +1 -0
  121. package/dist/parsing.js +9 -0
  122. package/dist/parsing.js.map +1 -0
  123. package/dist/partial.d.ts +30 -0
  124. package/dist/partial.d.ts.map +1 -0
  125. package/dist/partial.js +10 -0
  126. package/dist/partial.js.map +1 -0
  127. package/dist/schema.d.ts +28 -0
  128. package/dist/schema.d.ts.map +1 -0
  129. package/dist/schema.js +2 -0
  130. package/dist/schema.js.map +1 -0
  131. package/dist/tables.d.ts +34 -0
  132. package/dist/tables.d.ts.map +1 -0
  133. package/dist/tables.js +2 -0
  134. package/dist/tables.js.map +1 -0
  135. package/dist/utils.d.ts +13 -0
  136. package/dist/utils.d.ts.map +1 -0
  137. package/dist/utils.js +3 -0
  138. package/dist/utils.js.map +1 -0
  139. package/dist/validation/cte.d.ts +54 -0
  140. package/dist/validation/cte.d.ts.map +1 -0
  141. package/dist/validation/cte.js +2 -0
  142. package/dist/validation/cte.js.map +1 -0
  143. package/dist/validation/dispatch.d.ts +31 -0
  144. package/dist/validation/dispatch.d.ts.map +1 -0
  145. package/dist/validation/dispatch.js +2 -0
  146. package/dist/validation/dispatch.js.map +1 -0
  147. package/dist/validation/joins.d.ts +16 -0
  148. package/dist/validation/joins.d.ts.map +1 -0
  149. package/dist/validation/joins.js +2 -0
  150. package/dist/validation/joins.js.map +1 -0
  151. package/dist/validation/return-derived.d.ts +67 -0
  152. package/dist/validation/return-derived.d.ts.map +1 -0
  153. package/dist/validation/return-derived.js +5 -0
  154. package/dist/validation/return-derived.js.map +1 -0
  155. package/dist/validation/return-types.d.ts +41 -0
  156. package/dist/validation/return-types.d.ts.map +1 -0
  157. package/dist/validation/return-types.js +2 -0
  158. package/dist/validation/return-types.js.map +1 -0
  159. package/dist/validation/validate-columns.d.ts +63 -0
  160. package/dist/validation/validate-columns.d.ts.map +1 -0
  161. package/dist/validation/validate-columns.js +2 -0
  162. package/dist/validation/validate-columns.js.map +1 -0
  163. package/dist/validation.d.ts +7 -0
  164. package/dist/validation.d.ts.map +1 -0
  165. package/dist/validation.js +9 -0
  166. package/dist/validation.js.map +1 -0
  167. package/package.json +64 -0
  168. package/src/builder/assemble.ts +100 -0
  169. package/src/builder/condition-tree.ts +162 -0
  170. package/src/builder/conditional-sql.ts +325 -0
  171. package/src/builder/db.ts +281 -0
  172. package/src/builder/delete.ts +57 -0
  173. package/src/builder/extract-params.ts +507 -0
  174. package/src/builder/index.ts +58 -0
  175. package/src/builder/insert.ts +75 -0
  176. package/src/builder/mutate.ts +55 -0
  177. package/src/builder/params.ts +95 -0
  178. package/src/builder/return-type.ts +66 -0
  179. package/src/builder/scanner.ts +254 -0
  180. package/src/builder/select.ts +470 -0
  181. package/src/builder/sql-tag.ts +422 -0
  182. package/src/builder/sql.ts +51 -0
  183. package/src/builder/state.ts +55 -0
  184. package/src/builder/update.ts +77 -0
  185. package/src/builder/write-assemble.ts +52 -0
  186. package/src/builder/write-state.ts +43 -0
  187. package/src/builder/write-tag.ts +119 -0
  188. package/src/columns.ts +336 -0
  189. package/src/expressions.ts +745 -0
  190. package/src/index.ts +81 -0
  191. package/src/parsing/extract.ts +260 -0
  192. package/src/parsing/normalize.ts +243 -0
  193. package/src/parsing/pg-literals.ts +289 -0
  194. package/src/parsing/split.ts +288 -0
  195. package/src/parsing/string-utils.ts +172 -0
  196. package/src/parsing/tokenize.ts +321 -0
  197. package/src/parsing.ts +8 -0
  198. package/src/partial.ts +241 -0
  199. package/src/schema.ts +130 -0
  200. package/src/tables.ts +278 -0
  201. package/src/utils.ts +43 -0
  202. package/src/validation/cte.ts +198 -0
  203. package/src/validation/dispatch.ts +312 -0
  204. package/src/validation/joins.ts +198 -0
  205. package/src/validation/return-derived.ts +253 -0
  206. package/src/validation/return-types.ts +271 -0
  207. package/src/validation/validate-columns.ts +489 -0
  208. package/src/validation.ts +8 -0
@@ -0,0 +1,271 @@
1
+ // SELECT/RETURNING result inference + select-return assembly.
2
+ import type { AliasesInQuery, NullableRelations, TablesInQuery } from "../tables.js";
3
+ import type { AllTrue, Simplify } from "../utils.js";
4
+ import type { CleanIdent, ExtractAlias, ExtractReturningList, ExtractSelectList, SplitSelectList, StripSubqueries } from "../parsing.js";
5
+ import type { ColumnExists, DatabaseSchema } from "../schema.js";
6
+ import type { CteOuterQuery, CteReturn, MultiCteReturn, SingleCteMatch, WithDmlOuter } from "./cte.js";
7
+ import type { DerivedTableMatch, DerivedTableReturn, JoinedDerivedReturn } from "./return-derived.js";
8
+ import type { ExprToObject } from "../expressions.js";
9
+ import type { HasReturning, HasReturningQuoteAware, QueryKind } from "./dispatch.js";
10
+ export type GetReturnTypeNormalized<N extends string, S extends DatabaseSchema> =
11
+ TablesInQuery<N, S> extends infer Tables extends string
12
+ ? AliasesInQuery<N, S> extends infer Aliases extends string
13
+ ? [WithDmlOuter<N>] extends [never]
14
+ ? HasReturning<N> extends true
15
+ ? SelectReturnWith<ExtractReturningList<N>, Tables, Aliases, S>
16
+ : QueryKind<N> extends "select"
17
+ ? [SingleCteMatch<N>] extends [never]
18
+ ? [DerivedTableMatch<N>] extends [never]
19
+ ? OuterSelectReturn<N, Tables, Aliases, S>
20
+ : DerivedTableReturn<N, S>
21
+ : CteReturn<N, S>
22
+ : number
23
+ : WithDmlReturn<N, Tables, Aliases, S>
24
+ : number
25
+ : number;
26
+
27
+ // Outer-projection row for a plain (non-CTE, non-derived) SELECT. The outer
28
+ // SELECT list — `*` included — can only reference outer-scope relations, never a
29
+ // table that exists solely inside a `WHERE ... (NOT) EXISTS (SELECT ... FROM
30
+ // other)` / scalar subquery. So the relations the projection resolves against are
31
+ // collected from a subquery-stripped view: `select * from t where exists (select
32
+ // 1 from u)` expands `*` to `t`'s columns only, not `t`'s AND `u`'s.
33
+ //
34
+ // EXCEPTION: a `WITH ... SELECT` that reaches this branch is the multi-CTE
35
+ // fallback (a single CTE is handled by `CteReturn`); that path deliberately
36
+ // resolves the projected CTE columns against the relations *inside* the CTE
37
+ // bodies, so it must keep the unstripped table set.
38
+ export type OuterSelectReturn<
39
+ N extends string,
40
+ Tables extends string,
41
+ Aliases extends string,
42
+ S extends DatabaseSchema
43
+ > =
44
+ N extends `with ${string}`
45
+ ? CteOuterQuery<N> extends infer Outer extends string
46
+ ? Outer extends `${string} join ${string}`
47
+ // CTE outer that JOINs (CTE↔CTE or CTE↔base): outer cols are
48
+ // CTE-qualified (`a.id`) and the CTE rows aren't modeled, so the
49
+ // derived-table path can't resolve them. Keep the prior lenient
50
+ // behavior (resolve the first inner select list against the base
51
+ // table set) — unchanged, to avoid regressing those queries.
52
+ ? SelectReturnWith<ExtractSelectList<N>, Tables, Aliases, S, NullableRelations<N, S>>
53
+ // Outer reads from a single CTE (no join): resolve as a derived
54
+ // table so casts over CTE columns type precisely (via OuterCastTs)
55
+ // instead of poisoning to `never`.
56
+ : MultiCteReturn<Outer>
57
+ : SelectReturnWith<ExtractSelectList<N>, Tables, Aliases, S, NullableRelations<N, S>>
58
+ // A derived subquery JOINed under an alias (`... JOIN [LATERAL] (...) d`)
59
+ // is invisible to the plain table/alias resolution, so its projected
60
+ // `d.col` refs would be dropped. Merge their resolved (nullability-aware)
61
+ // contribution on top of the normal row; `JoinedDerivedReturn` is `{}`
62
+ // (a no-op merge) for any query without such a source.
63
+ : StripSubqueries<N> extends infer Outer extends string
64
+ ? TablesInQuery<Outer, S> extends infer OT extends string
65
+ ? AliasesInQuery<Outer, S> extends infer OA extends string
66
+ ? WithJoinedDerived<N, S, SelectReturnWith<ExtractSelectList<N>, OT, OA, S, NullableRelations<N, S>>>
67
+ : WithJoinedDerived<N, S, SelectReturnWith<ExtractSelectList<N>, Tables, Aliases, S, NullableRelations<N, S>>>
68
+ : WithJoinedDerived<N, S, SelectReturnWith<ExtractSelectList<N>, Tables, Aliases, S, NullableRelations<N, S>>>
69
+ : WithJoinedDerived<N, S, SelectReturnWith<ExtractSelectList<N>, Tables, Aliases, S, NullableRelations<N, S>>>;
70
+
71
+ export type WithJoinedDerived<N extends string, S extends DatabaseSchema, Row> =
72
+ Simplify<MergeRow<Row, JoinedDerivedReturn<N, S, NullableRelations<N, S>>>>;
73
+
74
+ // Result inference for a `WITH <cte> AS (...) <DML> ... RETURNING ...` statement:
75
+ // resolve the inner DML's RETURNING list against the query's tables. Only invoked
76
+ // when `WithDmlOuter<N>` is non-`never`, so the inner statement is a real DML.
77
+ export type WithDmlReturn<
78
+ N extends string,
79
+ Tables extends string,
80
+ Aliases extends string,
81
+ S extends DatabaseSchema
82
+ > =
83
+ WithDmlOuter<N> extends infer Outer extends string
84
+ ? HasReturningQuoteAware<Outer> extends true
85
+ ? SelectReturnWith<ExtractReturningList<Outer>, Tables, Aliases, S>
86
+ : number
87
+ : number;
88
+
89
+ // Derived table (subquery in FROM): `SELECT ... FROM (<subquery>) alias`.
90
+
91
+
92
+ // Select / returning return type
93
+
94
+ export type SelectReturn<SelectList extends string, N extends string, S extends DatabaseSchema> =
95
+ TablesInQuery<N, S> extends infer Tables extends string
96
+ ? AliasesInQuery<N, S> extends infer Aliases extends string
97
+ ? SelectReturnWith<SelectList, Tables, Aliases, S>
98
+ : unknown
99
+ : unknown;
100
+
101
+ export type SelectReturnWith<
102
+ SelectList extends string,
103
+ Tables extends string,
104
+ Aliases extends string,
105
+ S extends DatabaseSchema,
106
+ Nullable extends string = never
107
+ > = BuildSelectReturn<SplitSelectList<SelectList>, Tables, Aliases, S, Nullable>;
108
+
109
+ export type BuildSelectReturn<
110
+ Exprs extends string[],
111
+ Tables extends string,
112
+ Aliases extends string,
113
+ S extends DatabaseSchema,
114
+ Nullable extends string = never
115
+ > = MergeExprs<Exprs, Tables, Aliases, S, Nullable>;
116
+
117
+ // Project each expression to its column object INDEPENDENTLY into a tuple, then
118
+ // merge with a balanced pairwise reduction. A naive left fold nests one
119
+ // `Omit<Acc, …> &` per column, so resolving the final row needs a `keyof Acc`
120
+ // chain O(N) deep — on a wide (50+ column) SELECT that alone, plus the structural
121
+ // comparison a `RequireTrue<AssertExtends<…>>` test forces, crosses TS's depth-100
122
+ // guard (TS2589). The balanced merge keeps the merge tree O(log N) deep.
123
+ export type MergeExprs<
124
+ Exprs extends string[],
125
+ Tables extends string,
126
+ Aliases extends string,
127
+ S extends DatabaseSchema,
128
+ Nullable extends string = never
129
+ > = Simplify<MergeAll<ColObjects<Exprs, Tables, Aliases, S, Nullable>>>;
130
+
131
+ // Per-expression column objects, in source order (capped at 100 columns).
132
+ type ColObjects<
133
+ Exprs extends string[],
134
+ Tables extends string,
135
+ Aliases extends string,
136
+ S extends DatabaseSchema,
137
+ Nullable extends string,
138
+ Acc extends any[] = []
139
+ > = Acc["length"] extends 100
140
+ ? Acc
141
+ : Exprs extends [infer H extends string, ...infer Rest extends string[]]
142
+ ? ColObjects<Rest, Tables, Aliases, S, Nullable, [...Acc, ExprToObject<H, Tables, Aliases, S, Nullable>]>
143
+ : Acc;
144
+
145
+ // Merge adjacent pairs, halving the tuple each round, until a single object
146
+ // remains. Resolution depth is O(log N), not O(N). The projection path uses an
147
+ // INFORMATIVENESS-preferring merge (`MergeRowProj`) for duplicate output
148
+ // aliases: when the same alias is projected by more than one SELECT expression
149
+ // — e.g. two mutually-exclusive `selectIf` branches both rendered into the
150
+ // maximal query — the MORE INFORMATIVE of the two column types is kept (see
151
+ // `PreferInformative`) instead of blindly taking the last. PairMerge is
152
+ // left-associative, so the merge folds in source order.
153
+ type PairMerge<T extends any[]> =
154
+ T extends [infer A, infer B, ...infer Rest extends any[]]
155
+ ? [MergeRowProj<A, B>, ...PairMerge<Rest>]
156
+ : T;
157
+
158
+ type MergeAll<T extends any[]> =
159
+ T extends []
160
+ ? {}
161
+ : T extends [infer Only]
162
+ ? MergeRowProj<{}, Only>
163
+ : MergeAll<PairMerge<T>>;
164
+
165
+ // Merge a "later" column object into an "earlier" one, last write wins: a
166
+ // duplicate output alias keeps the later column's type instead of intersecting
167
+ // (which would collapse two differing same-named outputs to never). Either side
168
+ // may be `never` (an expression that projects nothing) — guard both.
169
+ //
170
+ // Used for JOIN/derived OVERLAYS, where a later contribution (e.g. an outer-join
171
+ // re-projection that adds `| null`) is meant to override an earlier same-named
172
+ // column — there, last-write-wins is correct.
173
+ export type MergeRow<Acc, Next> =
174
+ [Next] extends [never] ? Acc
175
+ : [Acc] extends [never] ? Next
176
+ : Omit<Acc, keyof Next> & Next;
177
+
178
+ // `true` for the `unknown` top type only (a column whose type we couldn't infer).
179
+ // `[unknown] extends [T]` holds only when T is `unknown` (or `any`, which never
180
+ // reaches here from inference). Guard `never` first so `[never]` doesn't qualify.
181
+ type IsUnknown<T> = [T] extends [never] ? false : [unknown] extends [T] ? true : false;
182
+
183
+ // Of two types for the SAME duplicate output alias, pick the more informative:
184
+ // - drop `unknown` in favour of any concrete type;
185
+ // - otherwise prefer the one whose non-null BASE is strictly narrower
186
+ // (e.g. a branded `User_id` over a plain `string`, ignoring `| null` on
187
+ // either side so a nullable branded column still beats a non-null `string`);
188
+ // - equal bases or incomparable types fall back to LAST-write-wins (`B`),
189
+ // preserving the historical behaviour for genuinely distinct same-named
190
+ // outputs (two different columns aliased identically).
191
+ type PreferInformative<A, B> =
192
+ IsUnknown<A> extends true ? B
193
+ : IsUnknown<B> extends true ? A
194
+ : [NonNullable<A>] extends [NonNullable<B>]
195
+ ? ([NonNullable<B>] extends [NonNullable<A>] ? B : A)
196
+ : B;
197
+
198
+ // Projection-path merge: like `MergeRow` for non-overlapping keys, but a key
199
+ // present on BOTH sides is resolved by `PreferInformative` rather than last-wins.
200
+ export type MergeRowProj<Acc, Next> =
201
+ [Next] extends [never] ? Acc
202
+ : [Acc] extends [never] ? Next
203
+ : {
204
+ [K in keyof Acc | keyof Next]:
205
+ K extends keyof Acc
206
+ ? K extends keyof Next ? PreferInformative<Acc[K], Next[K]> : Acc[K]
207
+ : K extends keyof Next ? Next[K] : never;
208
+ };
209
+
210
+ // Select aliases (for ORDER BY / HAVING alias references)
211
+
212
+ export type SelectAliasesInQuery<N extends string> =
213
+ QueryKind<N> extends "select"
214
+ ? HasReturning<N> extends true
215
+ ? SelectAliases<SplitSelectList<ExtractReturningList<N>>>
216
+ : SelectAliases<SplitSelectList<ExtractSelectList<N>>>
217
+ : never;
218
+
219
+ export type SelectAliasSet<N extends string> =
220
+ NeedsSelectAliasResolution<N> extends true ? SelectAliasesInQuery<N> : never;
221
+
222
+ export type NeedsSelectAliasResolution<N extends string> =
223
+ N extends `${string} order by ${infer OrderExpr}`
224
+ ? OrderExpr extends `${string}.${string}`
225
+ ? false
226
+ : true
227
+ : false;
228
+
229
+ export type RefScanSegment<N extends string> =
230
+ QueryKind<N> extends "select"
231
+ ? N extends `${string} from ${infer Rest}`
232
+ ? `from ${Rest}`
233
+ : N
234
+ : N;
235
+
236
+ // The ref-scan segment up to (but not including) the LAST top-level ` order by `.
237
+ // This is the part where SELECT-list aliases are NOT resolvable.
238
+ export type RefScanBeforeOrderBy<N extends string> =
239
+ RefScanSegment<N> extends infer Seg extends string
240
+ ? Seg extends `${infer Before} order by ${string}`
241
+ ? Before
242
+ : Seg
243
+ : N;
244
+
245
+ // The ` order by ...` slice of the ref-scan segment, where SELECT-list aliases
246
+ // ARE resolvable. Empty when there is no ORDER BY.
247
+ export type RefScanOrderBy<N extends string> =
248
+ RefScanSegment<N> extends infer Seg extends string
249
+ ? Seg extends `${string} order by ${infer After}`
250
+ ? `order by ${After}`
251
+ : ""
252
+ : "";
253
+
254
+ export type SelectAliases<
255
+ Exprs extends string[],
256
+ Acc extends string = never,
257
+ Steps extends any[] = []
258
+ > = Steps["length"] extends 140
259
+ ? Acc
260
+ : Exprs extends [infer H extends string, ...infer Rest extends string[]]
261
+ ? ExtractAlias<H> extends { alias: infer Alias }
262
+ ? Alias extends string
263
+ ? SelectAliases<Rest, Acc | Alias, [any, ...Steps]>
264
+ : SelectAliases<Rest, Acc, [any, ...Steps]>
265
+ : SelectAliases<Rest, Acc, [any, ...Steps]>
266
+ : Acc;
267
+
268
+ // Column lists
269
+
270
+ export type ColumnsExistInTable<Cols extends string[], TableKey extends string, S extends DatabaseSchema> =
271
+ AllTrue<Cols[number] extends infer C ? (C extends string ? ColumnExists<TableKey, CleanIdent<C>, S> : true) : true>;