turbine-orm 0.81.0 → 0.90.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 (295) hide show
  1. package/README.md +26 -25
  2. package/dist/checkout.d.ts +27 -2
  3. package/dist/checkout.js +75 -4
  4. package/dist/cjs/checkout.d.ts +27 -2
  5. package/dist/cjs/checkout.js +76 -3
  6. package/dist/cjs/cli/code-first-tags.d.ts +62 -0
  7. package/dist/cjs/cli/code-first-tags.js +124 -0
  8. package/dist/cjs/cli/compile-query.js +9 -0
  9. package/dist/cjs/cli/config.d.ts +35 -6
  10. package/dist/cjs/cli/config.js +17 -1
  11. package/dist/cjs/cli/destructive.d.ts +7 -4
  12. package/dist/cjs/cli/destructive.js +224 -20
  13. package/dist/cjs/cli/error-catalog.js +36 -0
  14. package/dist/cjs/cli/error-text.d.ts +15 -0
  15. package/dist/cjs/cli/error-text.js +40 -0
  16. package/dist/cjs/cli/index.d.ts +62 -4
  17. package/dist/cjs/cli/index.js +568 -108
  18. package/dist/cjs/cli/local-server-guard.d.ts +53 -0
  19. package/dist/cjs/cli/local-server-guard.js +119 -0
  20. package/dist/cjs/cli/local-server-output.d.ts +41 -0
  21. package/dist/cjs/cli/local-server-output.js +103 -0
  22. package/dist/cjs/cli/mcp.d.ts +8 -0
  23. package/dist/cjs/cli/mcp.js +121 -32
  24. package/dist/cjs/cli/migrate.d.ts +113 -5
  25. package/dist/cjs/cli/migrate.js +270 -21
  26. package/dist/cjs/cli/observe.d.ts +6 -1
  27. package/dist/cjs/cli/observe.js +85 -55
  28. package/dist/cjs/cli/pii-predicate-guard.d.ts +43 -23
  29. package/dist/cjs/cli/pii-predicate-guard.js +98 -37
  30. package/dist/cjs/cli/prisma-resolve.js +17 -13
  31. package/dist/cjs/cli/prisma-schema.js +12 -4
  32. package/dist/cjs/cli/studio-ui.generated.js +1 -1
  33. package/dist/cjs/cli/studio.d.ts +14 -2
  34. package/dist/cjs/cli/studio.js +244 -69
  35. package/dist/cjs/cli/ui.d.ts +1 -1
  36. package/dist/cjs/client.d.ts +558 -85
  37. package/dist/cjs/client.js +1270 -395
  38. package/dist/cjs/connection-guard.d.ts +13 -0
  39. package/dist/cjs/connection-guard.js +28 -0
  40. package/dist/cjs/connection-url.d.ts +51 -16
  41. package/dist/cjs/connection-url.js +67 -34
  42. package/dist/cjs/diagnostics.d.ts +81 -0
  43. package/dist/cjs/diagnostics.js +147 -0
  44. package/dist/cjs/dialect.d.ts +449 -20
  45. package/dist/cjs/dialect.js +117 -76
  46. package/dist/cjs/engine-config.d.ts +7 -6
  47. package/dist/cjs/errors.d.ts +126 -6
  48. package/dist/cjs/errors.js +256 -13
  49. package/dist/cjs/generate.d.ts +57 -7
  50. package/dist/cjs/generate.js +635 -279
  51. package/dist/cjs/global-filters-config.d.ts +59 -0
  52. package/dist/cjs/global-filters-config.js +367 -0
  53. package/dist/cjs/index.d.ts +9 -4
  54. package/dist/cjs/index.js +10 -2
  55. package/dist/cjs/introspect.d.ts +31 -6
  56. package/dist/cjs/introspect.js +108 -50
  57. package/dist/cjs/log-codes.d.ts +12 -0
  58. package/dist/cjs/log-codes.js +77 -0
  59. package/dist/cjs/logger.d.ts +87 -0
  60. package/dist/cjs/logger.js +98 -0
  61. package/dist/cjs/mssql.d.ts +8 -5
  62. package/dist/cjs/mssql.js +352 -65
  63. package/dist/cjs/mysql.d.ts +3 -5
  64. package/dist/cjs/mysql.js +420 -70
  65. package/dist/cjs/nested-write.d.ts +3 -0
  66. package/dist/cjs/nested-write.js +179 -114
  67. package/dist/cjs/pipeline-submittable.d.ts +12 -0
  68. package/dist/cjs/pipeline-submittable.js +118 -44
  69. package/dist/cjs/pipeline.js +21 -26
  70. package/dist/cjs/powdb-introspect.d.ts +5 -2
  71. package/dist/cjs/powdb-introspect.js +20 -15
  72. package/dist/cjs/powdb-shared.d.ts +36 -5
  73. package/dist/cjs/powdb-shared.js +67 -8
  74. package/dist/cjs/powdb.d.ts +4 -0
  75. package/dist/cjs/powdb.js +183 -51
  76. package/dist/cjs/powql.d.ts +394 -51
  77. package/dist/cjs/powql.js +1829 -284
  78. package/dist/cjs/prisma-compat.d.ts +23 -15
  79. package/dist/cjs/prisma-compat.js +507 -372
  80. package/dist/cjs/query/aggregates.d.ts +17 -1
  81. package/dist/cjs/query/aggregates.js +261 -29
  82. package/dist/cjs/query/batched-loader.d.ts +25 -6
  83. package/dist/cjs/query/batched-loader.js +103 -20
  84. package/dist/cjs/query/builder.d.ts +325 -184
  85. package/dist/cjs/query/builder.js +1452 -490
  86. package/dist/cjs/query/column-ref.d.ts +61 -0
  87. package/dist/cjs/query/column-ref.js +73 -0
  88. package/dist/cjs/query/compound-unique.d.ts +21 -0
  89. package/dist/cjs/query/compound-unique.js +98 -18
  90. package/dist/cjs/query/deferred.d.ts +53 -16
  91. package/dist/cjs/query/expr.d.ts +217 -0
  92. package/dist/cjs/query/expr.js +859 -0
  93. package/dist/cjs/query/filters.d.ts +155 -53
  94. package/dist/cjs/query/filters.js +613 -76
  95. package/dist/cjs/query/index.d.ts +2 -0
  96. package/dist/cjs/query/index.js +7 -1
  97. package/dist/cjs/query/json-value.d.ts +43 -0
  98. package/dist/cjs/query/json-value.js +59 -0
  99. package/dist/cjs/query/normalize-args.d.ts +87 -0
  100. package/dist/cjs/query/normalize-args.js +527 -0
  101. package/dist/cjs/query/option-surface.d.ts +16 -4
  102. package/dist/cjs/query/option-surface.js +57 -14
  103. package/dist/cjs/query/relation-names.d.ts +14 -0
  104. package/dist/cjs/query/relation-names.js +77 -18
  105. package/dist/cjs/query/relations.d.ts +30 -3
  106. package/dist/cjs/query/relations.js +219 -63
  107. package/dist/cjs/query/row-lock.d.ts +49 -0
  108. package/dist/cjs/query/row-lock.js +138 -0
  109. package/dist/cjs/query/sql-comment.d.ts +161 -0
  110. package/dist/cjs/query/sql-comment.js +381 -0
  111. package/dist/cjs/query/stream-idle.d.ts +132 -0
  112. package/dist/cjs/query/stream-idle.js +212 -0
  113. package/dist/cjs/query/table-client.d.ts +101 -0
  114. package/dist/cjs/query/table-client.js +74 -0
  115. package/dist/cjs/query/types.d.ts +677 -298
  116. package/dist/cjs/query/utils.d.ts +105 -6
  117. package/dist/cjs/query/utils.js +426 -19
  118. package/dist/cjs/query/warn-registry.d.ts +18 -0
  119. package/dist/cjs/query/warn-registry.js +18 -0
  120. package/dist/cjs/query/where-compile.d.ts +138 -14
  121. package/dist/cjs/query/where-compile.js +513 -29
  122. package/dist/cjs/query/where.d.ts +159 -59
  123. package/dist/cjs/query/where.js +716 -246
  124. package/dist/cjs/query/writes.d.ts +112 -50
  125. package/dist/cjs/query/writes.js +1498 -200
  126. package/dist/cjs/query-events.d.ts +4 -2
  127. package/dist/cjs/query-events.js +3 -1
  128. package/dist/cjs/realtime.d.ts +7 -3
  129. package/dist/cjs/realtime.js +13 -2
  130. package/dist/cjs/schema-builder.d.ts +55 -4
  131. package/dist/cjs/schema-builder.js +382 -18
  132. package/dist/cjs/schema-metadata.d.ts +21 -1
  133. package/dist/cjs/schema-metadata.js +29 -7
  134. package/dist/cjs/schema-sql.d.ts +75 -5
  135. package/dist/cjs/schema-sql.js +497 -45
  136. package/dist/cjs/schema.d.ts +26 -5
  137. package/dist/cjs/schema.js +110 -13
  138. package/dist/cjs/sql-placeholders.d.ts +56 -0
  139. package/dist/cjs/sql-placeholders.js +204 -0
  140. package/dist/cjs/sqlite.d.ts +75 -20
  141. package/dist/cjs/sqlite.js +593 -95
  142. package/dist/cjs/supplied-pool-types.d.ts +48 -0
  143. package/dist/cjs/supplied-pool-types.js +256 -0
  144. package/dist/cjs/transaction-control.d.ts +51 -0
  145. package/dist/cjs/transaction-control.js +316 -0
  146. package/dist/cjs/transaction-state.d.ts +342 -0
  147. package/dist/cjs/transaction-state.js +707 -0
  148. package/dist/cjs/typed-sql.d.ts +37 -3
  149. package/dist/cjs/typed-sql.js +102 -8
  150. package/dist/cli/code-first-tags.d.ts +62 -0
  151. package/dist/cli/code-first-tags.js +120 -0
  152. package/dist/cli/compile-query.js +9 -0
  153. package/dist/cli/config.d.ts +35 -6
  154. package/dist/cli/config.js +16 -1
  155. package/dist/cli/destructive.d.ts +7 -4
  156. package/dist/cli/destructive.js +224 -20
  157. package/dist/cli/error-catalog.js +36 -0
  158. package/dist/cli/error-text.d.ts +15 -0
  159. package/dist/cli/error-text.js +37 -0
  160. package/dist/cli/index.d.ts +62 -4
  161. package/dist/cli/index.js +569 -112
  162. package/dist/cli/local-server-guard.d.ts +53 -0
  163. package/dist/cli/local-server-guard.js +113 -0
  164. package/dist/cli/local-server-output.d.ts +41 -0
  165. package/dist/cli/local-server-output.js +98 -0
  166. package/dist/cli/mcp.d.ts +8 -0
  167. package/dist/cli/mcp.js +121 -34
  168. package/dist/cli/migrate.d.ts +113 -5
  169. package/dist/cli/migrate.js +261 -21
  170. package/dist/cli/observe.d.ts +6 -1
  171. package/dist/cli/observe.js +84 -54
  172. package/dist/cli/pii-predicate-guard.d.ts +43 -23
  173. package/dist/cli/pii-predicate-guard.js +100 -35
  174. package/dist/cli/prisma-resolve.js +15 -11
  175. package/dist/cli/prisma-schema.js +12 -4
  176. package/dist/cli/studio-ui.generated.js +1 -1
  177. package/dist/cli/studio.d.ts +14 -2
  178. package/dist/cli/studio.js +246 -71
  179. package/dist/cli/ui.d.ts +1 -1
  180. package/dist/client.d.ts +558 -85
  181. package/dist/client.js +1275 -400
  182. package/dist/connection-guard.d.ts +13 -0
  183. package/dist/connection-guard.js +27 -0
  184. package/dist/connection-url.d.ts +51 -16
  185. package/dist/connection-url.js +63 -34
  186. package/dist/diagnostics.d.ts +81 -0
  187. package/dist/diagnostics.js +144 -0
  188. package/dist/dialect.d.ts +449 -20
  189. package/dist/dialect.js +115 -43
  190. package/dist/engine-config.d.ts +7 -6
  191. package/dist/errors.d.ts +126 -6
  192. package/dist/errors.js +252 -12
  193. package/dist/generate.d.ts +57 -7
  194. package/dist/generate.js +635 -281
  195. package/dist/global-filters-config.d.ts +59 -0
  196. package/dist/global-filters-config.js +361 -0
  197. package/dist/index.d.ts +9 -4
  198. package/dist/index.js +4 -2
  199. package/dist/introspect.d.ts +31 -6
  200. package/dist/introspect.js +106 -50
  201. package/dist/log-codes.d.ts +12 -0
  202. package/dist/log-codes.js +74 -0
  203. package/dist/logger.d.ts +87 -0
  204. package/dist/logger.js +93 -0
  205. package/dist/mssql.d.ts +8 -5
  206. package/dist/mssql.js +354 -67
  207. package/dist/mysql.d.ts +3 -5
  208. package/dist/mysql.js +423 -73
  209. package/dist/nested-write.d.ts +3 -0
  210. package/dist/nested-write.js +177 -112
  211. package/dist/pipeline-submittable.d.ts +12 -0
  212. package/dist/pipeline-submittable.js +117 -44
  213. package/dist/pipeline.js +21 -26
  214. package/dist/powdb-introspect.d.ts +5 -2
  215. package/dist/powdb-introspect.js +21 -16
  216. package/dist/powdb-shared.d.ts +36 -5
  217. package/dist/powdb-shared.js +65 -8
  218. package/dist/powdb.d.ts +4 -0
  219. package/dist/powdb.js +183 -51
  220. package/dist/powql.d.ts +394 -51
  221. package/dist/powql.js +1836 -291
  222. package/dist/prisma-compat.d.ts +23 -15
  223. package/dist/prisma-compat.js +508 -373
  224. package/dist/query/aggregates.d.ts +17 -1
  225. package/dist/query/aggregates.js +263 -32
  226. package/dist/query/batched-loader.d.ts +25 -6
  227. package/dist/query/batched-loader.js +101 -21
  228. package/dist/query/builder.d.ts +325 -184
  229. package/dist/query/builder.js +1458 -495
  230. package/dist/query/column-ref.d.ts +61 -0
  231. package/dist/query/column-ref.js +66 -0
  232. package/dist/query/compound-unique.d.ts +21 -0
  233. package/dist/query/compound-unique.js +97 -19
  234. package/dist/query/deferred.d.ts +53 -16
  235. package/dist/query/expr.d.ts +217 -0
  236. package/dist/query/expr.js +848 -0
  237. package/dist/query/filters.d.ts +155 -53
  238. package/dist/query/filters.js +597 -72
  239. package/dist/query/index.d.ts +2 -0
  240. package/dist/query/index.js +4 -0
  241. package/dist/query/json-value.d.ts +43 -0
  242. package/dist/query/json-value.js +54 -0
  243. package/dist/query/normalize-args.d.ts +87 -0
  244. package/dist/query/normalize-args.js +517 -0
  245. package/dist/query/option-surface.d.ts +16 -4
  246. package/dist/query/option-surface.js +56 -13
  247. package/dist/query/relation-names.d.ts +14 -0
  248. package/dist/query/relation-names.js +77 -19
  249. package/dist/query/relations.d.ts +30 -3
  250. package/dist/query/relations.js +220 -67
  251. package/dist/query/row-lock.d.ts +49 -0
  252. package/dist/query/row-lock.js +131 -0
  253. package/dist/query/sql-comment.d.ts +161 -0
  254. package/dist/query/sql-comment.js +374 -0
  255. package/dist/query/stream-idle.d.ts +132 -0
  256. package/dist/query/stream-idle.js +203 -0
  257. package/dist/query/table-client.d.ts +101 -0
  258. package/dist/query/table-client.js +70 -0
  259. package/dist/query/types.d.ts +677 -298
  260. package/dist/query/utils.d.ts +105 -6
  261. package/dist/query/utils.js +414 -18
  262. package/dist/query/warn-registry.d.ts +18 -0
  263. package/dist/query/warn-registry.js +18 -0
  264. package/dist/query/where-compile.d.ts +138 -14
  265. package/dist/query/where-compile.js +508 -31
  266. package/dist/query/where.d.ts +159 -59
  267. package/dist/query/where.js +711 -248
  268. package/dist/query/writes.d.ts +112 -50
  269. package/dist/query/writes.js +1496 -202
  270. package/dist/query-events.d.ts +4 -2
  271. package/dist/query-events.js +3 -1
  272. package/dist/realtime.d.ts +7 -3
  273. package/dist/realtime.js +13 -2
  274. package/dist/schema-builder.d.ts +55 -4
  275. package/dist/schema-builder.js +381 -18
  276. package/dist/schema-metadata.d.ts +21 -1
  277. package/dist/schema-metadata.js +28 -7
  278. package/dist/schema-sql.d.ts +75 -5
  279. package/dist/schema-sql.js +494 -44
  280. package/dist/schema.d.ts +26 -5
  281. package/dist/schema.js +109 -13
  282. package/dist/sql-placeholders.d.ts +56 -0
  283. package/dist/sql-placeholders.js +200 -0
  284. package/dist/sqlite.d.ts +75 -20
  285. package/dist/sqlite.js +597 -99
  286. package/dist/supplied-pool-types.d.ts +48 -0
  287. package/dist/supplied-pool-types.js +247 -0
  288. package/dist/transaction-control.d.ts +51 -0
  289. package/dist/transaction-control.js +311 -0
  290. package/dist/transaction-state.d.ts +342 -0
  291. package/dist/transaction-state.js +696 -0
  292. package/dist/typed-sql.d.ts +37 -3
  293. package/dist/typed-sql.js +100 -8
  294. package/package.json +7 -4
  295. package/skills/turbine-orm/SKILL.md +56 -6
@@ -0,0 +1,59 @@
1
+ /**
2
+ * turbine-orm, `globalFilters` checked when the client is constructed
3
+ *
4
+ * A global filter is a tenancy or soft-delete boundary, so a filter that
5
+ * silently applies to nothing is the worst way for it to fail: a key naming no
6
+ * table (a typo, a renamed table), or a key the query builder does not look
7
+ * up. The builder looks filters up by TABLE name, while the config docs key
8
+ * them by client ACCESSOR (`blogPosts` for `blog_posts`).
9
+ *
10
+ * {@link normalizeGlobalFilters} maps each key to its table name, refuses a key
11
+ * that names no table and a static filter whose keys name no column or
12
+ * relation, and returns the map the query builder reads. Given the client's
13
+ * dialect it also compiles each static filter once, so a value the compiler
14
+ * refuses fails when the client is built rather than on the first query.
15
+ * Function filters are kept as they are: what they return is checked per query
16
+ * by the resolver, which also refuses a filter that resolves to `undefined`.
17
+ */
18
+ import type { Dialect } from './dialect.js';
19
+ import type { QueryInterface } from './query/builder.js';
20
+ import type { GlobalFilters } from './query/index.js';
21
+ import type { SchemaMetadata } from './schema.js';
22
+ /** The accessor a table gets on the client (`blog_posts` -> `blogPosts`). The one place it is derived. */
23
+ export declare function tableAccessorName(tableName: string): string;
24
+ /**
25
+ * Whether a `skipGlobalFilters: [UNSAFE, ...names]` list names `table`, by its
26
+ * table name or by its client accessor, the two spellings `globalFilters` keys
27
+ * accept. With `tables` (the schema's table map), an accessor spelling that is
28
+ * itself another table's name refers to that other table only.
29
+ */
30
+ export declare function skipListNamesTable(names: readonly string[], table: string, tables?: Readonly<Record<string, unknown>>): boolean;
31
+ /**
32
+ * Refuse a `skipGlobalFilters` list entry that names no table, by table name or
33
+ * accessor: a misspelled entry skips nothing, so the filter the caller meant to
34
+ * lift stays on and the query quietly returns fewer rows than intended.
35
+ */
36
+ export declare function assertSkipListNames(names: readonly string[], tables: Readonly<Record<string, unknown>>): void;
37
+ /**
38
+ * The client options a static filter is compiled with at construction: the
39
+ * ones that decide whether a where clause compiles, and to what.
40
+ */
41
+ export interface StaticFilterCompileOptions {
42
+ /**
43
+ * The SQL query builder. Passed in rather than imported: the query modules
44
+ * import this one, so a value import back would be an import cycle.
45
+ */
46
+ QueryInterface: typeof QueryInterface;
47
+ dialect?: Dialect | undefined;
48
+ utcTimestamps?: boolean | undefined;
49
+ }
50
+ /**
51
+ * Validate `globalFilters` against the schema and key it by table name.
52
+ * Throws `ValidationError` (E003) naming the bad key and the closest valid one.
53
+ *
54
+ * With `compile` (the client passes it for every SQL engine), each static
55
+ * filter is also compiled once with that dialect, so an operand the compiler
56
+ * refuses, a column misspelled inside a relation filter or a feature the
57
+ * engine lacks (E017) fails here and not on the first query.
58
+ */
59
+ export declare function normalizeGlobalFilters(filters: GlobalFilters | undefined | null, schema: SchemaMetadata, compile?: StaticFilterCompileOptions): GlobalFilters | undefined;
@@ -0,0 +1,367 @@
1
+ "use strict";
2
+ /**
3
+ * turbine-orm, `globalFilters` checked when the client is constructed
4
+ *
5
+ * A global filter is a tenancy or soft-delete boundary, so a filter that
6
+ * silently applies to nothing is the worst way for it to fail: a key naming no
7
+ * table (a typo, a renamed table), or a key the query builder does not look
8
+ * up. The builder looks filters up by TABLE name, while the config docs key
9
+ * them by client ACCESSOR (`blogPosts` for `blog_posts`).
10
+ *
11
+ * {@link normalizeGlobalFilters} maps each key to its table name, refuses a key
12
+ * that names no table and a static filter whose keys name no column or
13
+ * relation, and returns the map the query builder reads. Given the client's
14
+ * dialect it also compiles each static filter once, so a value the compiler
15
+ * refuses fails when the client is built rather than on the first query.
16
+ * Function filters are kept as they are: what they return is checked per query
17
+ * by the resolver, which also refuses a filter that resolves to `undefined`.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.tableAccessorName = tableAccessorName;
21
+ exports.skipListNamesTable = skipListNamesTable;
22
+ exports.assertSkipListNames = assertSkipListNames;
23
+ exports.normalizeGlobalFilters = normalizeGlobalFilters;
24
+ const errors_js_1 = require("./errors.js");
25
+ const filters_js_1 = require("./query/filters.js");
26
+ const utils_js_1 = require("./query/utils.js");
27
+ const where_compile_js_1 = require("./query/where-compile.js");
28
+ /** The accessor a table gets on the client (`blog_posts` -> `blogPosts`). The one place it is derived. */
29
+ function tableAccessorName(tableName) {
30
+ return tableName.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
31
+ }
32
+ /**
33
+ * Whether a `skipGlobalFilters: [UNSAFE, ...names]` list names `table`, by its
34
+ * table name or by its client accessor, the two spellings `globalFilters` keys
35
+ * accept. With `tables` (the schema's table map), an accessor spelling that is
36
+ * itself another table's name refers to that other table only.
37
+ */
38
+ function skipListNamesTable(names, table, tables) {
39
+ if (names.includes(table))
40
+ return true;
41
+ const accessor = tableAccessorName(table);
42
+ if (accessor === table || (tables !== undefined && Object.hasOwn(tables, accessor)))
43
+ return false;
44
+ return names.includes(accessor);
45
+ }
46
+ /**
47
+ * Refuse a `skipGlobalFilters` list entry that names no table, by table name or
48
+ * accessor: a misspelled entry skips nothing, so the filter the caller meant to
49
+ * lift stays on and the query quietly returns fewer rows than intended.
50
+ */
51
+ function assertSkipListNames(names, tables) {
52
+ for (const name of names) {
53
+ if (Object.hasOwn(tables, name))
54
+ continue;
55
+ if (Object.keys(tables).some((table) => skipListNamesTable([name], table, tables)))
56
+ continue;
57
+ const candidates = Object.keys(tables).flatMap((table) => [table, tableAccessorName(table)]);
58
+ const hint = nearestName(name, candidates);
59
+ throw new errors_js_1.ValidationError(`skipGlobalFilters names "${name}", which is not a table in the schema${hint ? `. Did you mean "${hint}"?` : '.'} ` +
60
+ 'An entry that names no table skips nothing. List tables by table name (`blog_posts`) or client accessor (`blogPosts`).');
61
+ }
62
+ }
63
+ const COMBINATORS = new Set(['AND', 'OR', 'NOT']);
64
+ /** How a non-plain-object config value reads in an error message. */
65
+ function describeShape(value) {
66
+ if (Array.isArray(value))
67
+ return 'an array';
68
+ if (value === null)
69
+ return 'null';
70
+ if (typeof value !== 'object')
71
+ return typeof value;
72
+ const name = Object.getPrototypeOf(value)?.constructor?.name;
73
+ return `an instance of ${name || 'a class'}, not a plain object`;
74
+ }
75
+ /**
76
+ * Validate `globalFilters` against the schema and key it by table name.
77
+ * Throws `ValidationError` (E003) naming the bad key and the closest valid one.
78
+ *
79
+ * With `compile` (the client passes it for every SQL engine), each static
80
+ * filter is also compiled once with that dialect, so an operand the compiler
81
+ * refuses, a column misspelled inside a relation filter or a feature the
82
+ * engine lacks (E017) fails here and not on the first query.
83
+ */
84
+ function normalizeGlobalFilters(filters, schema, compile) {
85
+ if (filters === undefined || filters === null)
86
+ return undefined;
87
+ if (!(0, filters_js_1.isPlainRecord)(filters)) {
88
+ throw new errors_js_1.ValidationError(`globalFilters must be an object keyed by table, for example \`{ posts: { deletedAt: null } }\`; received ${describeShape(filters)}.`);
89
+ }
90
+ const byAccessor = new Map();
91
+ for (const table of Object.keys(schema.tables)) {
92
+ const accessor = tableAccessorName(table);
93
+ if (accessor !== table && !Object.hasOwn(schema.tables, accessor))
94
+ byAccessor.set(accessor, table);
95
+ }
96
+ const normalized = {};
97
+ const keyFor = new Map();
98
+ for (const key of Object.keys(filters)) {
99
+ const table = Object.hasOwn(schema.tables, key) ? key : byAccessor.get(key);
100
+ if (table === undefined) {
101
+ const hint = nearestName(key, [...Object.keys(schema.tables), ...byAccessor.keys()]);
102
+ throw new errors_js_1.ValidationError(`globalFilters: "${key}" names no table in the schema${hint ? `. Did you mean "${hint}"?` : '.'} ` +
103
+ 'A filter under a name that matches no table is never applied, so the rows it was meant to hide ' +
104
+ 'would be returned. Key each filter by table name (`blog_posts`) or by its client accessor (`blogPosts`).');
105
+ }
106
+ const earlier = keyFor.get(table);
107
+ if (earlier !== undefined) {
108
+ throw new errors_js_1.ValidationError(`globalFilters: "${earlier}" and "${key}" both name table "${table}". Keep one filter per table, ` +
109
+ 'combining the conditions with `AND: [...]` if both are needed.');
110
+ }
111
+ keyFor.set(table, key);
112
+ const value = filters[key];
113
+ if (typeof value === 'function' || value === null) {
114
+ (0, filters_js_1.setOwn)(normalized, table, value);
115
+ continue;
116
+ }
117
+ if (!(0, filters_js_1.isPlainRecord)(value)) {
118
+ throw new errors_js_1.ValidationError(`globalFilters["${key}"] must be a where object or a function returning one; received ${describeShape(value)}. An undefined filter usually means the value it was built from was not available yet: pass a ` +
119
+ 'function, which is evaluated per query, for anything that depends on the current request.');
120
+ }
121
+ assertFilterNamesExist(value, schema.tables, schema.tables[table], key, '', 0);
122
+ // The query path refuses a filter holding `undefined` on every query (it
123
+ // may be a tenant id that was not set); a static filter is read once, so
124
+ // say so now, with the fix that applies to a static filter.
125
+ const hole = (0, filters_js_1.holdsUndefinedValue)(value, 0) ? (0, filters_js_1.findUndefinedPath)(value, '', 0) : null;
126
+ if (hole !== null) {
127
+ throw new errors_js_1.ValidationError(`globalFilters["${key}"] has an undefined value at "${hole}". A static filter is read once, when the ` +
128
+ 'client is constructed, so a value that was not available then stays undefined, and every query on ' +
129
+ 'the table would be refused. Pass a function, which is evaluated per query, for anything that depends ' +
130
+ 'on the current request.');
131
+ }
132
+ // The whole clause shape at every depth (relation quantifier values among
133
+ // it), checked here rather than at the first query that reads this table.
134
+ try {
135
+ (0, where_compile_js_1.foldWhereFor)(schema.tables, table, value);
136
+ }
137
+ catch (err) {
138
+ if (err instanceof errors_js_1.ValidationError)
139
+ throw new errors_js_1.ValidationError(`globalFilters["${key}"]: ${reasonOf(err)}`);
140
+ throw err;
141
+ }
142
+ (0, filters_js_1.setOwn)(normalized, table, value);
143
+ }
144
+ assertNoFilterCycle(normalized, schema, keyFor);
145
+ if (compile !== undefined)
146
+ assertStaticFiltersCompile(normalized, schema, keyFor, compile);
147
+ return normalized;
148
+ }
149
+ /** An error's own text, without the code tag and docs link a TurbineError message carries. */
150
+ function reasonOf(err) {
151
+ return err.message.replace(/^\[TURBINE_E\d+\] /, '').replace(/ \(https:\/\/\S+\)$/, '');
152
+ }
153
+ /** Swallows every line: a construction-time compile is a check, not a query. */
154
+ const SILENT_LOGGER = Object.freeze({});
155
+ /**
156
+ * Compile every static filter with the client's dialect, through the query
157
+ * builder the queries use, so each value is checked by the same code that
158
+ * will bind it. First each table with only its own filter (so an error names
159
+ * the filter that holds it), then each table with every static filter, which
160
+ * also compiles the filters a relation filter reaches. Function filters are
161
+ * never called here: they may read request state that does not exist yet.
162
+ */
163
+ function assertStaticFiltersCompile(filters, schema, keyFor, options) {
164
+ const staticFilters = {};
165
+ for (const table of Object.keys(filters)) {
166
+ const filter = filters[table];
167
+ if ((0, filters_js_1.isPlainRecord)(filter))
168
+ (0, filters_js_1.setOwn)(staticFilters, table, filter);
169
+ }
170
+ const compileOn = (table, applied) => {
171
+ try {
172
+ new options.QueryInterface(null, table, schema, [], {
173
+ dialect: options.dialect,
174
+ utcTimestamps: options.utcTimestamps,
175
+ globalFilters: applied,
176
+ sqlCache: false,
177
+ logger: SILENT_LOGGER,
178
+ diagnostics: { mode: 'production', advice: false },
179
+ }).buildFindMany({});
180
+ }
181
+ catch (err) {
182
+ throw labelledFilterError(err, keyFor.get(table) ?? table);
183
+ }
184
+ };
185
+ for (const table of Object.keys(staticFilters)) {
186
+ compileOn(table, { [table]: staticFilters[table] });
187
+ }
188
+ for (const table of Object.keys(staticFilters))
189
+ compileOn(table, staticFilters);
190
+ }
191
+ /** The compiler's refusal, named after the filter it came from, in its own class. */
192
+ function labelledFilterError(err, key) {
193
+ if (err instanceof errors_js_1.UnsupportedFeatureError) {
194
+ const head = `${err.feature} is unsupported on "${err.dialect}".`;
195
+ const reason = reasonOf(err);
196
+ const hint = reason.startsWith(head) ? reason.slice(head.length).trim() : '';
197
+ return new errors_js_1.UnsupportedFeatureError(`globalFilters["${key}"]: ${err.feature}`, err.dialect, hint || undefined);
198
+ }
199
+ if (err instanceof errors_js_1.ValidationError)
200
+ return new errors_js_1.ValidationError(`globalFilters["${key}"]: ${reasonOf(err)}`);
201
+ return err;
202
+ }
203
+ /**
204
+ * Refuse static filters that reach their own table through relations, directly
205
+ * (`comments: { parent: { is: {...} } }`) or through another table's filter
206
+ * (`posts: { user: {...} }` beside `users: { posts: {...} }`). A table's
207
+ * filter applies to every row a relation filter reaches, the rows reached from
208
+ * inside another table's filter included, so such filters would apply each
209
+ * other without end. Function filters are not inspected here; the query path
210
+ * applies each table's filter once per chain for them.
211
+ */
212
+ function assertNoFilterCycle(filters, schema, keyFor) {
213
+ const edges = new Map();
214
+ for (const table of Object.keys(filters)) {
215
+ const filter = filters[table];
216
+ if (!(0, filters_js_1.isPlainRecord)(filter))
217
+ continue;
218
+ const reached = [];
219
+ collectReachedTables(schema, table, table, filter, reached, 0);
220
+ edges.set(table, reached);
221
+ }
222
+ // Depth-first over tables with a static filter; `path[i]` is the table
223
+ // `chain[i]` leaves from, so a step back onto `path[k]` closes the cycle
224
+ // `chain[k..]`.
225
+ const done = new Set();
226
+ const visit = (table, chain, path) => {
227
+ if (done.has(table))
228
+ return;
229
+ for (const edge of edges.get(table) ?? []) {
230
+ const k = path.indexOf(edge.to);
231
+ if (k !== -1)
232
+ throw filterCycleError([...chain.slice(k), edge], keyFor);
233
+ if (edges.has(edge.to))
234
+ visit(edge.to, [...chain, edge], [...path, edge.to]);
235
+ }
236
+ done.add(table);
237
+ };
238
+ for (const table of edges.keys())
239
+ visit(table, [], [table]);
240
+ }
241
+ /** Every relation a where on `table` names, at any depth, as edges from `owner`'s filter. */
242
+ function collectReachedTables(schema, owner, table, where, out, depth) {
243
+ const meta = Object.hasOwn(schema.tables, table) ? schema.tables[table] : undefined;
244
+ if (!meta || depth > where_compile_js_1.MAX_WHERE_DEPTH)
245
+ return;
246
+ for (const event of (0, where_compile_js_1.walkWhere)((0, where_compile_js_1.metadataWhereHost)(meta), where)) {
247
+ if (event.kind === 'or' || event.kind === 'and') {
248
+ for (const branch of event.conditions)
249
+ collectReachedTables(schema, owner, table, branch, out, depth + 1);
250
+ }
251
+ else if (event.kind === 'not') {
252
+ collectReachedTables(schema, owner, table, event.condition, out, depth + 1);
253
+ }
254
+ else if (event.kind === 'relation') {
255
+ out.push({ from: owner, to: event.relDef.to, relation: `${table}.${event.key}` });
256
+ for (const wrapper of filters_js_1.RELATION_FILTER_WRAPPERS) {
257
+ const sub = event.filterObj[wrapper];
258
+ if ((0, filters_js_1.isPlainRecord)(sub))
259
+ collectReachedTables(schema, owner, event.relDef.to, sub, out, depth + 1);
260
+ }
261
+ }
262
+ }
263
+ }
264
+ function filterCycleError(cycle, keyFor) {
265
+ const steps = cycle.map((edge) => `the filter for "${keyFor.get(edge.from) ?? edge.from}" reaches "${edge.to}" through "${edge.relation}"`);
266
+ return new errors_js_1.ValidationError(`globalFilters: ${steps.join(', and ')}. A global filter applies to every row a relation filter reaches, ` +
267
+ "including the rows reached from inside another table's filter, so these filters would apply each other " +
268
+ 'without end. Remove the relation filter from one of them, or write that condition into the queries that ' +
269
+ 'need it.');
270
+ }
271
+ /**
272
+ * Every key of a static filter (of its AND/OR/NOT branches, and of the where
273
+ * objects its relation filters hold, against the related table) must be a
274
+ * column or relation, and every combinator must have a shape the query
275
+ * compiler reads: one it cannot read would apply no condition, so a tenant
276
+ * filter written as `OR: { ... }` would match every row.
277
+ */
278
+ function assertFilterNamesExist(filter, tables, meta, key, path, depth) {
279
+ if (depth > where_compile_js_1.MAX_WHERE_DEPTH)
280
+ return;
281
+ for (const field of Object.keys(filter)) {
282
+ const at = path ? `${path}.${field}` : field;
283
+ if (COMBINATORS.has(field)) {
284
+ const branch = filter[field];
285
+ try {
286
+ (0, where_compile_js_1.combinatorBranches)(field, branch, meta.name);
287
+ }
288
+ catch (err) {
289
+ if (!(err instanceof errors_js_1.ValidationError))
290
+ throw err;
291
+ throw new errors_js_1.ValidationError(`globalFilters["${key}"]: "${at}" is refused. ${reasonOf(err)}`);
292
+ }
293
+ if (Array.isArray(branch)) {
294
+ branch.forEach((b, i) => {
295
+ if (b !== undefined) {
296
+ assertFilterNamesExist(b, tables, meta, key, `${at}[${i}]`, depth + 1);
297
+ }
298
+ });
299
+ }
300
+ else if (branch !== undefined) {
301
+ assertFilterNamesExist(branch, tables, meta, key, at, depth + 1);
302
+ }
303
+ continue;
304
+ }
305
+ if ((0, utils_js_1.resolveColumnName)(meta, field) !== undefined)
306
+ continue;
307
+ const relation = (0, utils_js_1.resolveRelation)(meta.relations ?? {}, field);
308
+ if (relation !== undefined) {
309
+ const value = filter[field];
310
+ const target = Object.hasOwn(tables, relation.def.to) ? tables[relation.def.to] : undefined;
311
+ if (target === undefined || !(0, filters_js_1.isPlainRecord)(value))
312
+ continue;
313
+ const wrapped = filters_js_1.RELATION_FILTER_WRAPPERS.some((wrapper) => wrapper in value);
314
+ if (!wrapped) {
315
+ // A bare where object on a to-one relation (an implicit `is`).
316
+ assertFilterNamesExist(value, tables, target, key, at, depth + 1);
317
+ continue;
318
+ }
319
+ for (const wrapper of filters_js_1.RELATION_FILTER_WRAPPERS) {
320
+ const sub = value[wrapper];
321
+ if ((0, filters_js_1.isPlainRecord)(sub))
322
+ assertFilterNamesExist(sub, tables, target, key, `${at}.${wrapper}`, depth + 1);
323
+ }
324
+ continue;
325
+ }
326
+ const candidates = [...Object.keys(meta.columnMap), ...Object.keys(meta.relations ?? {})];
327
+ const hint = nearestName(field, candidates);
328
+ throw new errors_js_1.ValidationError(`globalFilters["${key}"]: "${at}" is not a column or relation of "${meta.name}"` +
329
+ `${hint ? `. Did you mean "${hint}"?` : '.'} The filter would fail on every query against this table.`);
330
+ }
331
+ }
332
+ /** Levenshtein distance between two strings. */
333
+ function editDistance(a, b) {
334
+ let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
335
+ for (let i = 1; i <= a.length; i++) {
336
+ const cur = [i];
337
+ for (let j = 1; j <= b.length; j++) {
338
+ cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
339
+ }
340
+ prev = cur;
341
+ }
342
+ return prev[b.length];
343
+ }
344
+ /**
345
+ * The candidate a mistyped name most likely meant, by edit distance with case
346
+ * and underscores ignored (so `tenent_id` and `tenentID` both reach
347
+ * `tenantId`), ties broken by the raw spelling. Not substring containment: a
348
+ * short name inside the typo (`id` in `tenentId`) is not what was meant.
349
+ */
350
+ function nearestName(input, candidates) {
351
+ const fold = (name) => name.toLowerCase().replace(/_/g, '');
352
+ const wanted = fold(input);
353
+ let best = null;
354
+ let bestScore = Number.POSITIVE_INFINITY;
355
+ for (const candidate of candidates) {
356
+ const folded = fold(candidate);
357
+ const distance = editDistance(wanted, folded);
358
+ if (distance > Math.max(2, Math.floor(Math.max(wanted.length, folded.length) / 3)))
359
+ continue;
360
+ const score = distance * 1000 + editDistance(input, candidate);
361
+ if (score < bestScore) {
362
+ bestScore = score;
363
+ best = candidate;
364
+ }
365
+ }
366
+ return best;
367
+ }
@@ -34,17 +34,22 @@
34
34
  */
35
35
  export type { DatabaseAdapter, IntrospectionOverrides } from './adapters/index.js';
36
36
  export { alloydb, cockroachdb, postgresql, timescale, yugabytedb } from './adapters/index.js';
37
- export { type Middleware, type MiddlewareNext, type MiddlewareParams, type PgCompatPool, type PgCompatPoolClient, type PgCompatQueryResult, type PlanCacheMode, type RetryOptions, TransactionClient, type TransactionOptions, TurbineClient, type TurbineConfig, type TurbineDriver, withRetry, } from './client.js';
38
- export type { BuiltStatement, BulkInsertStatementInput, ColumnDefinitionInput, ColumnTypeInput, CreateIndexStatementInput, CreateTableStatementInput, Dialect, DialectIntrospector, DialectMigrator, DialectName, InsertStatementInput, IntrospectOptions as DialectIntrospectOptions, ResultStrategy, StreamableConnection, UpsertStatementInput, } from './dialect.js';
37
+ export { type ConnectionLostEvent, type DisconnectOptions, type DisconnectResult, type Middleware, type MiddlewareNext, type MiddlewareParams, type PgCompatPool, type PgCompatPoolClient, type PgCompatQueryResult, type PlanCacheMode, type PoolErrorEvent, type PoolEvent, type PoolEventOrigin, type RetryOptions, TransactionClient, type TransactionOptions, TurbineClient, type TurbineConfig, type TurbineDriver, withRetry, } from './client.js';
38
+ export type { CacheCheckMode, DiagnosticsConfig, DiagnosticsMode, DiagnosticsOptions, ResolvedDiagnostics, } from './diagnostics.js';
39
+ export type { BuiltStatement, BulkInsertStatementInput, ColumnDefinitionInput, ColumnTypeInput, CreateIndexStatementInput, CreateTableStatementInput, Dialect, DialectIntrospector, DialectMigrator, DialectName, EngineCapabilities, InsertStatementInput, IntrospectOptions as DialectIntrospectOptions, ResultStrategy, StreamableConnection, UpsertStatementInput, } from './dialect.js';
39
40
  export { postgresDialect } from './dialect.js';
40
- export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockError, type ErrorMessageMode, ExclusionConstraintError, ForeignKeyError, getErrorMessageMode, MigrationError, NotFoundError, NotNullViolationError, OptimisticLockError, PipelineError, type PipelineResultSlot, REDACTED_DETAIL, ReadOnlyError, RelationError, SerializationFailureError, setErrorMessageMode, TimeoutError, TurbineError, TurbineErrorCode, UniqueConstraintError, UnsupportedFeatureError, ValidationError, wrapPgError, } from './errors.js';
41
+ export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockError, type ErrorMessageMode, ExclusionConstraintError, ForeignKeyError, getErrorMessageMode, InvariantError, LockNotAvailableError, MigrationError, NotFoundError, NotNullViolationError, OptimisticLockError, PipelineError, type PipelineResultSlot, REDACTED_DETAIL, ReadOnlyError, type ReadOnlyReason, RelationError, SerializationFailureError, setErrorMessageMode, TimeoutError, type TimeoutOutcome, TransactionRolledBackError, TurbineError, TurbineErrorCode, UniqueConstraintError, UnsupportedFeatureError, ValidationError, wrapPgError, } from './errors.js';
41
42
  export { type GenerateOptions, generate } from './generate.js';
42
43
  export { type IntrospectOptions, introspect } from './introspect.js';
44
+ export type { TurbineLogCode, TurbineLogEntry, TurbineLogger, TurbineLogLevel } from './logger.js';
43
45
  export { executeNestedCreate, executeNestedUpdate, hasRelationFields, type NestedWriteContext, } from './nested-write.js';
44
46
  export { HttpJsonSink, type HttpJsonSinkOptions, type MetricsFlushBatch, type MetricsFlushRow, type ObserveConfig, type ObserveHandle, type ObserveSink, PgMetricsSink, type PgMetricsSinkOptions, } from './observe.js';
45
47
  export { executePipeline, type PipelineOptions, type PipelineResults, pipelineSupported } from './pipeline.js';
46
48
  export { fingerprintPrismaSchema } from './prisma-schema-fingerprint.js';
47
- export { type AggregateArgs, type AggregateResult, type ArrayFilter, AUTO_ASSUMED_ROUND_TRIP_MS, AUTO_COUNT_BATCH_MIN_PARENT_ROWS, AUTO_JOIN_PENALTY_MS_PER_ROW, AUTO_TO_ONE_JOIN_MAX_ROWS, AUTO_TO_ONE_JOIN_ROWS_MAX, AUTO_TO_ONE_JOIN_ROWS_MIN, type ColumnRef, type ConnectOrCreateOp, type CountArgs, type CreateArgs, type CreateDataInput, type CreateManyArgs, type DeferredQuery, type DeleteArgs, type DeleteManyArgs, type FieldResult, type FindManyArgs, type FindManyStreamArgs, type FindUniqueArgs, type GlobalFilters, type GroupByAggregateSpec, type GroupByArgs, type GroupByDistinctOn, type GroupByResult, type HavingClause, type JsonEncoding, type JsonFilter, type JsonPathAggregateTarget, type JsonPathGroupKey, type JsonPathOrderBy, type MiddlewareFn, type NestedCreateOp, type NestedUpdateOp, type NestedUpdateOpItem, type NestedUpsertOpItem, type OmitResult, type OrderByClause, type OrderByObject, type OrderBySpec, type OrderDirection, type PrivilegeOption, type QueryEvent, type QueryEventListener, QueryInterface, type QueryResult, type RelationDescriptor, type RelationFilter, type RelationLoadStrategy, type RelationOrderBy, type RelationOrderByChain, type RelationPickBy, type RelationPickOrderBy, type SelectResult, type SkipGlobalFilters, type TemporalInfinityReading, type TextSearchFilter, type TypedWithClause, UNSAFE, type Unsafe, type UpdateArgs, type UpdateDataInput, type UpdateInput, type UpdateManyArgs, type UpdateOperatorInput, type UpsertArgs, type VectorDistanceFilter, type VectorFilter, type VectorMetric, type VectorOrderBy, type VectorOrderByDistance, type WhereClause, type WhereOperator, type WhereValue, type WithClause, type WithOptions, type WithOrderByObject, type WithResult, } from './query/index.js';
49
+ export { type CaseArm, type ExprOperand, expr, type NumericOperand } from './query/expr.js';
50
+ export { type AggregateArgs, type AggregateResult, type ArrayFilter, AUTO_ASSUMED_ROUND_TRIP_MS, AUTO_COUNT_BATCH_MIN_PARENT_ROWS, AUTO_JOIN_PENALTY_MS_PER_ROW, AUTO_TO_ONE_JOIN_MAX_ROWS, AUTO_TO_ONE_JOIN_ROWS_MAX, AUTO_TO_ONE_JOIN_ROWS_MIN, type ColumnRef, type ConnectOrCreateOp, type CountArgs, type CreateArgs, type CreateDataInput, type CreateManyArgs, col, type DeferredQuery, type DeleteArgs, type DeleteManyArgs, type FieldResult, type FindManyArgs, type FindManyStreamArgs, type FindUniqueArgs, type GlobalFilters, type GroupByAggregateSpec, type GroupByArgs, type GroupByDistinctOn, type GroupByResult, type HavingClause, type JsonEncoding, type JsonFilter, type JsonPathAggregateTarget, type JsonPathGroupKey, type JsonPathOrderBy, type JsonValue, jsonValue, type MiddlewareFn, type NestedCreateOp, type NestedUpdateOp, type NestedUpdateOpItem, type NestedUpsertOpItem, type OmitResult, type OrderByClause, type OrderByObject, type OrderBySpec, type OrderDirection, type PrivilegeOption, type QueryEvent, type QueryEventListener, QueryInterface, type QueryResult, type RelationDescriptor, type RelationFilter, type RelationLoadStrategy, type RelationOrderBy, type RelationOrderByChain, type RelationPickBy, type RelationPickOrderBy, type SelectResult, type SkipGlobalFilters, type TemporalInfinityReading, type TextSearchFilter, type TypedWithClause, UNSAFE, type Unsafe, type UpdateArgs, type UpdateDataInput, type UpdateInput, type UpdateManyArgs, type UpdateOperatorInput, type UpsertArgs, type VectorDistanceFilter, type VectorFilter, type VectorMetric, type VectorOrderBy, type VectorOrderByDistance, type WhereClause, type WhereOperator, type WhereValue, type WithClause, type WithOptions, type WithOrderByObject, type WithResult, } from './query/index.js';
51
+ export type { SqlCommentOptions } from './query/sql-comment.js';
52
+ export type { AggregateResultOf, ConflictTarget, ConflictUpdateData, CreateManyOnConflict, DefaultInputTypes, ExcludedRef, GlobalFilter, NestedToOneCreateOp, NestedToOneUpdateOp, OptionalInput, PercentileMethod, PercentileSpec, RelationKind, RowLock, RowLockMode, SqlExpr, SqlExprKind, TableInputTypes, } from './query/types.js';
48
53
  export { MAX_QUERY_TAG_LENGTH, RAW_QUERY_MODEL } from './query-events.js';
49
54
  export { type ActiveSubscription, type ListenOptions, type ListenReconnectOptions, type NotificationHandler, type Subscription, validateChannel, } from './realtime.js';
50
55
  export type { CheckMetadata, ColumnMetadata, IndexMetadata, PrismaCompatMap, PrismaModelMap, PrismaRelationMap, PrismaSchemaSource, ReferentialAction, RelationDef, SchemaMetadata, TableMetadata, } from './schema.js';
package/dist/cjs/index.js CHANGED
@@ -34,8 +34,8 @@
34
34
  * ```
35
35
  */
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.QueryInterface = exports.AUTO_TO_ONE_JOIN_ROWS_MIN = exports.AUTO_TO_ONE_JOIN_ROWS_MAX = exports.AUTO_TO_ONE_JOIN_MAX_ROWS = exports.AUTO_JOIN_PENALTY_MS_PER_ROW = exports.AUTO_COUNT_BATCH_MIN_PARENT_ROWS = exports.AUTO_ASSUMED_ROUND_TRIP_MS = exports.fingerprintPrismaSchema = exports.pipelineSupported = exports.executePipeline = exports.PgMetricsSink = exports.HttpJsonSink = exports.hasRelationFields = exports.executeNestedUpdate = exports.executeNestedCreate = exports.introspect = exports.generate = exports.wrapPgError = exports.ValidationError = exports.UnsupportedFeatureError = exports.UniqueConstraintError = exports.TurbineErrorCode = exports.TurbineError = exports.TimeoutError = exports.setErrorMessageMode = exports.SerializationFailureError = exports.RelationError = exports.ReadOnlyError = exports.REDACTED_DETAIL = exports.PipelineError = exports.OptimisticLockError = exports.NotNullViolationError = exports.NotFoundError = exports.MigrationError = exports.getErrorMessageMode = exports.ForeignKeyError = exports.ExclusionConstraintError = exports.DeadlockError = exports.ConnectionError = exports.CircularRelationError = exports.CheckConstraintError = exports.postgresDialect = exports.withRetry = exports.TurbineClient = exports.TransactionClient = exports.yugabytedb = exports.timescale = exports.postgresql = exports.cockroachdb = exports.alloydb = void 0;
38
- exports.TypedSqlQuery = exports.buildTypedSql = exports.turbineHttp = exports.defineSeed = exports.schemaToSQLString = exports.schemaToSQL = exports.schemaPush = exports.schemaDiff = exports.DestructivePushRefusal = exports.schemaDefToMetadata = exports.table = exports.isDocFieldIndexDef = exports.defineSchema = exports.column = exports.ColumnBuilder = exports.applyManyToManyRelations = exports.withDbFieldNames = exports.snakeToPascal = exports.snakeToCamel = exports.singularize = exports.pgTypeToTs = exports.pgArrayType = exports.normalizeKeyColumns = exports.isDateType = exports.camelToSnake = exports.validateChannel = exports.RAW_QUERY_MODEL = exports.MAX_QUERY_TAG_LENGTH = exports.UNSAFE = void 0;
37
+ exports.AUTO_JOIN_PENALTY_MS_PER_ROW = exports.AUTO_COUNT_BATCH_MIN_PARENT_ROWS = exports.AUTO_ASSUMED_ROUND_TRIP_MS = exports.expr = exports.fingerprintPrismaSchema = exports.pipelineSupported = exports.executePipeline = exports.PgMetricsSink = exports.HttpJsonSink = exports.hasRelationFields = exports.executeNestedUpdate = exports.executeNestedCreate = exports.introspect = exports.generate = exports.wrapPgError = exports.ValidationError = exports.UnsupportedFeatureError = exports.UniqueConstraintError = exports.TurbineErrorCode = exports.TurbineError = exports.TransactionRolledBackError = exports.TimeoutError = exports.setErrorMessageMode = exports.SerializationFailureError = exports.RelationError = exports.ReadOnlyError = exports.REDACTED_DETAIL = exports.PipelineError = exports.OptimisticLockError = exports.NotNullViolationError = exports.NotFoundError = exports.MigrationError = exports.LockNotAvailableError = exports.InvariantError = exports.getErrorMessageMode = exports.ForeignKeyError = exports.ExclusionConstraintError = exports.DeadlockError = exports.ConnectionError = exports.CircularRelationError = exports.CheckConstraintError = exports.postgresDialect = exports.withRetry = exports.TurbineClient = exports.TransactionClient = exports.yugabytedb = exports.timescale = exports.postgresql = exports.cockroachdb = exports.alloydb = void 0;
38
+ exports.TypedSqlQuery = exports.buildTypedSql = exports.turbineHttp = exports.defineSeed = exports.schemaToSQLString = exports.schemaToSQL = exports.schemaPush = exports.schemaDiff = exports.DestructivePushRefusal = exports.schemaDefToMetadata = exports.table = exports.isDocFieldIndexDef = exports.defineSchema = exports.column = exports.ColumnBuilder = exports.applyManyToManyRelations = exports.withDbFieldNames = exports.snakeToPascal = exports.snakeToCamel = exports.singularize = exports.pgTypeToTs = exports.pgArrayType = exports.normalizeKeyColumns = exports.isDateType = exports.camelToSnake = exports.validateChannel = exports.RAW_QUERY_MODEL = exports.MAX_QUERY_TAG_LENGTH = exports.UNSAFE = exports.QueryInterface = exports.jsonValue = exports.col = exports.AUTO_TO_ONE_JOIN_ROWS_MIN = exports.AUTO_TO_ONE_JOIN_ROWS_MAX = exports.AUTO_TO_ONE_JOIN_MAX_ROWS = void 0;
39
39
  var index_js_1 = require("./adapters/index.js");
40
40
  Object.defineProperty(exports, "alloydb", { enumerable: true, get: function () { return index_js_1.alloydb; } });
41
41
  Object.defineProperty(exports, "cockroachdb", { enumerable: true, get: function () { return index_js_1.cockroachdb; } });
@@ -58,6 +58,8 @@ Object.defineProperty(exports, "DeadlockError", { enumerable: true, get: functio
58
58
  Object.defineProperty(exports, "ExclusionConstraintError", { enumerable: true, get: function () { return errors_js_1.ExclusionConstraintError; } });
59
59
  Object.defineProperty(exports, "ForeignKeyError", { enumerable: true, get: function () { return errors_js_1.ForeignKeyError; } });
60
60
  Object.defineProperty(exports, "getErrorMessageMode", { enumerable: true, get: function () { return errors_js_1.getErrorMessageMode; } });
61
+ Object.defineProperty(exports, "InvariantError", { enumerable: true, get: function () { return errors_js_1.InvariantError; } });
62
+ Object.defineProperty(exports, "LockNotAvailableError", { enumerable: true, get: function () { return errors_js_1.LockNotAvailableError; } });
61
63
  Object.defineProperty(exports, "MigrationError", { enumerable: true, get: function () { return errors_js_1.MigrationError; } });
62
64
  Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_js_1.NotFoundError; } });
63
65
  Object.defineProperty(exports, "NotNullViolationError", { enumerable: true, get: function () { return errors_js_1.NotNullViolationError; } });
@@ -69,6 +71,7 @@ Object.defineProperty(exports, "RelationError", { enumerable: true, get: functio
69
71
  Object.defineProperty(exports, "SerializationFailureError", { enumerable: true, get: function () { return errors_js_1.SerializationFailureError; } });
70
72
  Object.defineProperty(exports, "setErrorMessageMode", { enumerable: true, get: function () { return errors_js_1.setErrorMessageMode; } });
71
73
  Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_js_1.TimeoutError; } });
74
+ Object.defineProperty(exports, "TransactionRolledBackError", { enumerable: true, get: function () { return errors_js_1.TransactionRolledBackError; } });
72
75
  Object.defineProperty(exports, "TurbineError", { enumerable: true, get: function () { return errors_js_1.TurbineError; } });
73
76
  Object.defineProperty(exports, "TurbineErrorCode", { enumerable: true, get: function () { return errors_js_1.TurbineErrorCode; } });
74
77
  Object.defineProperty(exports, "UniqueConstraintError", { enumerable: true, get: function () { return errors_js_1.UniqueConstraintError; } });
@@ -97,6 +100,9 @@ Object.defineProperty(exports, "pipelineSupported", { enumerable: true, get: fun
97
100
  // Prisma-schema fingerprint (provenance on a generated PRISMA_MAP)
98
101
  var prisma_schema_fingerprint_js_1 = require("./prisma-schema-fingerprint.js");
99
102
  Object.defineProperty(exports, "fingerprintPrismaSchema", { enumerable: true, get: function () { return prisma_schema_fingerprint_js_1.fingerprintPrismaSchema; } });
103
+ // Update expressions: `expr.add(col('n'), 1)`, `expr.excluded('name')`, ...
104
+ var expr_js_1 = require("./query/expr.js");
105
+ Object.defineProperty(exports, "expr", { enumerable: true, get: function () { return expr_js_1.expr; } });
100
106
  // Query builder
101
107
  // The privilege sentinel. `skipGlobalFilters` / `includePii` /
102
108
  // `allowFullTableScan` are unlocked by THIS VALUE and nothing else, so a
@@ -108,6 +114,8 @@ Object.defineProperty(exports, "AUTO_JOIN_PENALTY_MS_PER_ROW", { enumerable: tru
108
114
  Object.defineProperty(exports, "AUTO_TO_ONE_JOIN_MAX_ROWS", { enumerable: true, get: function () { return index_js_2.AUTO_TO_ONE_JOIN_MAX_ROWS; } });
109
115
  Object.defineProperty(exports, "AUTO_TO_ONE_JOIN_ROWS_MAX", { enumerable: true, get: function () { return index_js_2.AUTO_TO_ONE_JOIN_ROWS_MAX; } });
110
116
  Object.defineProperty(exports, "AUTO_TO_ONE_JOIN_ROWS_MIN", { enumerable: true, get: function () { return index_js_2.AUTO_TO_ONE_JOIN_ROWS_MIN; } });
117
+ Object.defineProperty(exports, "col", { enumerable: true, get: function () { return index_js_2.col; } });
118
+ Object.defineProperty(exports, "jsonValue", { enumerable: true, get: function () { return index_js_2.jsonValue; } });
111
119
  Object.defineProperty(exports, "QueryInterface", { enumerable: true, get: function () { return index_js_2.QueryInterface; } });
112
120
  Object.defineProperty(exports, "UNSAFE", { enumerable: true, get: function () { return index_js_2.UNSAFE; } });
113
121
  // $on('query') event metadata: raw-statement model name, $tag() label limit
@@ -8,6 +8,7 @@
8
8
  * This is the foundation of `npx turbine generate`.
9
9
  */
10
10
  import { type Dialect } from './dialect.js';
11
+ import { type TurbineLogger } from './logger.js';
11
12
  import { type ColumnMetadata, type IndexMetadata, type ReferentialAction, type RelationDef, type SchemaMetadata } from './schema.js';
12
13
  /**
13
14
  * Map a `pg_constraint.confdeltype` / `confupdtype` character to a
@@ -116,7 +117,28 @@ export interface IntrospectOptions {
116
117
  * here so `introspect()` works across databases.
117
118
  */
118
119
  dialect?: Dialect;
120
+ /**
121
+ * Where introspection notes go (a skipped cross-schema foreign key, a
122
+ * renamed or shadowing relation). Defaults to the console logger.
123
+ */
124
+ logger?: TurbineLogger;
119
125
  }
126
+ /**
127
+ * A catalog name made safe to PRINT. Every diagnostic that quotes a table,
128
+ * column, enum, relation or constraint name goes through this, because Postgres
129
+ * lets anyone with CREATE privilege pick any characters for those, and an
130
+ * unescaped name in an error message is a way to write escape sequences to the
131
+ * developer's terminal. Control and bidi characters become visible escapes
132
+ * (`\n`, `\u001b`); everything else, including non-ASCII letters, is untouched.
133
+ */
134
+ export declare function printableCatalogName(name: string): string;
135
+ /**
136
+ * An empty record for something keyed by catalog names. Prototype-less on
137
+ * purpose: a plain `{}` turns a table named `__proto__` into a prototype
138
+ * assignment (the table silently disappears), and makes `enums['constructor']`
139
+ * truthy before any enum was ever added.
140
+ */
141
+ export declare function nullRecord<T>(): Record<string, T>;
120
142
  /**
121
143
  * Refuse one catalog identifier carrying a character from
122
144
  * {@link UNSAFE_CATALOG_CHARS}. `subject` names the object in the error.
@@ -137,7 +159,8 @@ export declare function assertSafeCatalogSchema(schema: SchemaMetadata): void;
137
159
  /**
138
160
  * Introspect a database into {@link SchemaMetadata}, routing through the active
139
161
  * dialect's {@link Dialect.introspector} so each engine can override the catalog
140
- * SQL. PostgreSQL is driven by {@link introspectPostgresCatalog}.
162
+ * SQL. A dialect with none, PostgreSQL included, is read by
163
+ * {@link introspectPostgresCatalog}.
141
164
  */
142
165
  export declare function introspect(options: IntrospectOptions): Promise<SchemaMetadata>;
143
166
  /**
@@ -180,8 +203,8 @@ export declare function applyRelationRenames(schema: SchemaMetadata, renames: Re
180
203
  export declare function assertDistinctColumnFields(tableName: string, columns: readonly ColumnMetadata[]): void;
181
204
  /**
182
205
  * PostgreSQL catalog introspector: reads information_schema + pg_catalog and
183
- * produces {@link SchemaMetadata}. This is the implementation wrapped by
184
- * `postgresDialect.introspector`; call {@link introspect} for dialect routing.
206
+ * produces {@link SchemaMetadata}. {@link introspect} calls it for PostgreSQL;
207
+ * call {@link introspect} for dialect routing.
185
208
  */
186
209
  export declare function introspectPostgresCatalog(options: IntrospectOptions): Promise<SchemaMetadata>;
187
210
  /**
@@ -401,7 +424,7 @@ export declare function detectUniqueForeignKeySets(pkByTable: Map<string, string
401
424
  export declare function buildRelationsFromForeignKeys(foreignKeys: ForeignKeyEntry[], columnFieldsByTable: Map<string, Set<string>>, fkActions?: Map<string, {
402
425
  onDelete: ReferentialAction;
403
426
  onUpdate: ReferentialAction;
404
- }>, unknownTypedFieldsByTable?: Map<string, Set<string>>, uniqueSetsByTable?: Map<string, string[][]>): Map<string, Record<string, RelationDef>>;
427
+ }>, unknownTypedFieldsByTable?: Map<string, Set<string>>, uniqueSetsByTable?: Map<string, string[][]>, logger?: TurbineLogger): Map<string, Record<string, RelationDef>>;
405
428
  /**
406
429
  * Conservative auto-`manyToMany` detection over pure junction tables, shared
407
430
  * by the Postgres introspector, the engine introspectors (SQLite / MySQL /
@@ -428,7 +451,7 @@ export declare function buildRelationsFromForeignKeys(foreignKeys: ForeignKeyEnt
428
451
  * - a shadowed concrete-typed column → deterministic `Rel` suffix + warn
429
452
  * instead of silently dropping the relation.
430
453
  */
431
- export declare function addAutoManyToManyRelations(tableNames: Iterable<string>, foreignKeys: ForeignKeyEntry[], pkByTable: Map<string, string[]>, columnNamesByTable: Map<string, string[]>, relationsByTable: Map<string, Record<string, RelationDef>>, columnFieldsByTable?: Map<string, Set<string>>, unknownTypedFieldsByTable?: Map<string, Set<string>>, uniqueIndexColsByTable?: Map<string, string[][]>): void;
454
+ export declare function addAutoManyToManyRelations(tableNames: Iterable<string>, foreignKeys: ForeignKeyEntry[], pkByTable: Map<string, string[]>, columnNamesByTable: Map<string, string[]>, relationsByTable: Map<string, Record<string, RelationDef>>, columnFieldsByTable?: Map<string, Set<string>>, unknownTypedFieldsByTable?: Map<string, Set<string>>, uniqueIndexColsByTable?: Map<string, string[][]>, logger?: TurbineLogger): void;
432
455
  /** Everything the catalog relation derivation reads. See {@link deriveCatalogRelations}. */
433
456
  export interface CatalogRelationInputs {
434
457
  /** The introspected table set, post include/exclude filtering. */
@@ -452,6 +475,8 @@ export interface CatalogRelationInputs {
452
475
  }>;
453
476
  /** Opt out of the unique-FK → `hasOne` flip (F2), see {@link IntrospectOptions.legacyToManyUniques}. */
454
477
  legacyToManyUniques?: boolean;
478
+ /** Where relation-naming notes go. Defaults to the console logger. */
479
+ logger?: TurbineLogger;
455
480
  }
456
481
  /**
457
482
  * One-stop relation derivation for every surface that reads a live PostgreSQL
@@ -486,4 +511,4 @@ export declare function deriveCatalogRelations(inputs: CatalogRelationInputs): M
486
511
  * relation names for the same logical schema (the engines previously carried
487
512
  * stale copies of a retired naming scheme).
488
513
  */
489
- export declare function deriveEngineRelations(tableNames: string[], foreignKeys: ForeignKeyEntry[], pkByTable: Map<string, string[]>, columnsByTable: Map<string, Pick<ColumnMetadata, 'name' | 'field' | 'tsType'>[]>): Map<string, Record<string, RelationDef>>;
514
+ export declare function deriveEngineRelations(tableNames: string[], foreignKeys: ForeignKeyEntry[], pkByTable: Map<string, string[]>, columnsByTable: Map<string, Pick<ColumnMetadata, 'name' | 'field' | 'tsType'>[]>, logger?: TurbineLogger): Map<string, Record<string, RelationDef>>;