@relq/orm 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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +236 -0
  3. package/dist/cjs/__test-types.cjs +17 -0
  4. package/dist/cjs/addon/cursor.cjs +1473 -0
  5. package/dist/cjs/addon/pg.cjs +4969 -0
  6. package/dist/cjs/cache/index.cjs +9 -0
  7. package/dist/cjs/cache/query-cache.cjs +311 -0
  8. package/dist/cjs/condition/array-condition-builder.cjs +527 -0
  9. package/dist/cjs/condition/array-numeric-condition-builder.cjs +186 -0
  10. package/dist/cjs/condition/array-specialized-condition-builder.cjs +206 -0
  11. package/dist/cjs/condition/array-string-condition-builder.cjs +146 -0
  12. package/dist/cjs/condition/base-condition-builder.cjs +2 -0
  13. package/dist/cjs/condition/condition-collector.cjs +461 -0
  14. package/dist/cjs/condition/fulltext-condition-builder.cjs +61 -0
  15. package/dist/cjs/condition/geometric-condition-builder.cjs +228 -0
  16. package/dist/cjs/condition/index.cjs +29 -0
  17. package/dist/cjs/condition/jsonb-condition-builder.cjs +448 -0
  18. package/dist/cjs/condition/network-condition-builder.cjs +237 -0
  19. package/dist/cjs/condition/postgis-condition-builder.cjs +188 -0
  20. package/dist/cjs/condition/range-condition-builder.cjs +98 -0
  21. package/dist/cjs/core/helpers/ConnectedAggregateBuilder.cjs +132 -0
  22. package/dist/cjs/core/helpers/ConnectedCTEBuilder.cjs +53 -0
  23. package/dist/cjs/core/helpers/ConnectedCountBuilder.cjs +73 -0
  24. package/dist/cjs/core/helpers/ConnectedDeleteBuilder.cjs +65 -0
  25. package/dist/cjs/core/helpers/ConnectedInsertBuilder.cjs +112 -0
  26. package/dist/cjs/core/helpers/ConnectedInsertFromSelectBuilder.cjs +66 -0
  27. package/dist/cjs/core/helpers/ConnectedQueryBuilder.cjs +146 -0
  28. package/dist/cjs/core/helpers/ConnectedRawQueryBuilder.cjs +46 -0
  29. package/dist/cjs/core/helpers/ConnectedSelectBuilder.cjs +331 -0
  30. package/dist/cjs/core/helpers/ConnectedTransactionBuilder.cjs +105 -0
  31. package/dist/cjs/core/helpers/ConnectedUpdateBuilder.cjs +79 -0
  32. package/dist/cjs/core/helpers/PaginateBuilder.cjs +178 -0
  33. package/dist/cjs/core/helpers/ReturningExecutor.cjs +70 -0
  34. package/dist/cjs/core/helpers/capability-guard.cjs +10 -0
  35. package/dist/cjs/core/helpers/index.cjs +31 -0
  36. package/dist/cjs/core/helpers/methods.cjs +10 -0
  37. package/dist/cjs/core/helpers/query-convenience.cjs +238 -0
  38. package/dist/cjs/core/helpers/select-joins.cjs +251 -0
  39. package/dist/cjs/core/helpers/select-pagination.cjs +233 -0
  40. package/dist/cjs/core/helpers/select-types.cjs +2 -0
  41. package/dist/cjs/core/pg-family/cockroachdb-client/capabilities.cjs +31 -0
  42. package/dist/cjs/core/pg-family/cockroachdb-client/index.cjs +7 -0
  43. package/dist/cjs/core/pg-family/cockroachdb-client/relq-cockroach.cjs +16 -0
  44. package/dist/cjs/core/pg-family/dsql-client/capabilities.cjs +31 -0
  45. package/dist/cjs/core/pg-family/dsql-client/index.cjs +7 -0
  46. package/dist/cjs/core/pg-family/dsql-client/relq-dsql.cjs +16 -0
  47. package/dist/cjs/core/pg-family/index.cjs +19 -0
  48. package/dist/cjs/core/pg-family/nile-client/capabilities.cjs +31 -0
  49. package/dist/cjs/core/pg-family/nile-client/index.cjs +7 -0
  50. package/dist/cjs/core/pg-family/nile-client/relq-nile.cjs +36 -0
  51. package/dist/cjs/core/pg-family/nile-client/tenant-context.cjs +44 -0
  52. package/dist/cjs/core/pg-family/pg-client/capabilities.cjs +31 -0
  53. package/dist/cjs/core/pg-family/pg-client/index.cjs +7 -0
  54. package/dist/cjs/core/pg-family/pg-client/relq-postgres.cjs +43 -0
  55. package/dist/cjs/core/pg-family/shared/pg-base.cjs +385 -0
  56. package/dist/cjs/core/pg-family/shared/pg-dialect.cjs +67 -0
  57. package/dist/cjs/core/pg-family/shared/pg-error-parser.cjs +34 -0
  58. package/dist/cjs/core/pg-family/shared/pg-type-coercion.cjs +14 -0
  59. package/dist/cjs/core/relq-base.cjs +307 -0
  60. package/dist/cjs/core/relq-client.cjs +56 -0
  61. package/dist/cjs/core/shared/cleanup.cjs +36 -0
  62. package/dist/cjs/core/shared/column-mapping.cjs +97 -0
  63. package/dist/cjs/core/shared/errors.cjs +17 -0
  64. package/dist/cjs/core/shared/index.cjs +24 -0
  65. package/dist/cjs/core/shared/table-accessor.cjs +22 -0
  66. package/dist/cjs/core/shared/transform.cjs +35 -0
  67. package/dist/cjs/core/shared/types.cjs +2 -0
  68. package/dist/cjs/core/shared/validation.cjs +140 -0
  69. package/dist/cjs/core/types/core.types.cjs +2 -0
  70. package/dist/cjs/count/count-builder.cjs +88 -0
  71. package/dist/cjs/count/index.cjs +5 -0
  72. package/dist/cjs/delete/delete-builder.cjs +176 -0
  73. package/dist/cjs/delete/index.cjs +5 -0
  74. package/dist/cjs/explain/explain-builder.cjs +99 -0
  75. package/dist/cjs/explain/index.cjs +5 -0
  76. package/dist/cjs/index.cjs +26 -0
  77. package/dist/cjs/insert/conflict-builder.cjs +213 -0
  78. package/dist/cjs/insert/index.cjs +5 -0
  79. package/dist/cjs/insert/insert-builder.cjs +320 -0
  80. package/dist/cjs/insert/insert-from-select-builder.cjs +86 -0
  81. package/dist/cjs/pubsub/index.cjs +7 -0
  82. package/dist/cjs/pubsub/listen-notify-builder.cjs +57 -0
  83. package/dist/cjs/pubsub/listener-connection.cjs +180 -0
  84. package/dist/cjs/raw/index.cjs +8 -0
  85. package/dist/cjs/raw/raw-query-builder.cjs +27 -0
  86. package/dist/cjs/raw/sql-template.cjs +73 -0
  87. package/dist/cjs/select/aggregate-builder.cjs +179 -0
  88. package/dist/cjs/select/index.cjs +16 -0
  89. package/dist/cjs/select/join-builder.cjs +192 -0
  90. package/dist/cjs/select/join-condition-builder.cjs +189 -0
  91. package/dist/cjs/select/join-internals.cjs +5 -0
  92. package/dist/cjs/select/join-many-condition-builder.cjs +159 -0
  93. package/dist/cjs/select/scalar-query-builder.cjs +134 -0
  94. package/dist/cjs/select/scalar-select-builder.cjs +78 -0
  95. package/dist/cjs/select/select-builder.cjs +426 -0
  96. package/dist/cjs/select/sql-expression.cjs +38 -0
  97. package/dist/cjs/select/table-proxy.cjs +99 -0
  98. package/dist/cjs/shared/aws-dsql.cjs +181 -0
  99. package/dist/cjs/shared/errors/relq-errors.cjs +361 -0
  100. package/dist/cjs/shared/pg-format.cjs +383 -0
  101. package/dist/cjs/shared/types/config-types.cjs +51 -0
  102. package/dist/cjs/transaction/index.cjs +6 -0
  103. package/dist/cjs/transaction/transaction-builder.cjs +78 -0
  104. package/dist/cjs/types/aggregate-types.cjs +2 -0
  105. package/dist/cjs/types/inference-types.cjs +18 -0
  106. package/dist/cjs/types/pagination-types.cjs +7 -0
  107. package/dist/cjs/types/result-types.cjs +2 -0
  108. package/dist/cjs/types/scalar-types.cjs +2 -0
  109. package/dist/cjs/types/schema-types.cjs +2 -0
  110. package/dist/cjs/types/subscription-types.cjs +2 -0
  111. package/dist/cjs/types.cjs +2 -0
  112. package/dist/cjs/update/array-update-builder.cjs +232 -0
  113. package/dist/cjs/update/index.cjs +16 -0
  114. package/dist/cjs/update/jsonb-update-builder.cjs +219 -0
  115. package/dist/cjs/update/update-builder.cjs +274 -0
  116. package/dist/cjs/utils/addon/pg/cursor.cjs +8 -0
  117. package/dist/cjs/utils/addon/pg/pg.cjs +23 -0
  118. package/dist/cjs/utils/case-converter.cjs +58 -0
  119. package/dist/cjs/utils/env-resolver.cjs +226 -0
  120. package/dist/cjs/utils/environment-detection.cjs +124 -0
  121. package/dist/cjs/utils/fk-resolver.cjs +186 -0
  122. package/dist/cjs/utils/index.cjs +25 -0
  123. package/dist/cjs/utils/pool-defaults.cjs +91 -0
  124. package/dist/cjs/utils/type-coercion.cjs +120 -0
  125. package/dist/cjs/window/index.cjs +5 -0
  126. package/dist/cjs/window/window-builder.cjs +80 -0
  127. package/dist/esm/__test-types.js +15 -0
  128. package/dist/esm/addon/cursor.js +1440 -0
  129. package/dist/esm/addon/pg.js +4931 -0
  130. package/dist/esm/cache/index.js +1 -0
  131. package/dist/esm/cache/query-cache.js +303 -0
  132. package/dist/esm/condition/array-condition-builder.js +519 -0
  133. package/dist/esm/condition/array-numeric-condition-builder.js +182 -0
  134. package/dist/esm/condition/array-specialized-condition-builder.js +200 -0
  135. package/dist/esm/condition/array-string-condition-builder.js +142 -0
  136. package/dist/esm/condition/base-condition-builder.js +1 -0
  137. package/dist/esm/condition/condition-collector.js +452 -0
  138. package/dist/esm/condition/fulltext-condition-builder.js +53 -0
  139. package/dist/esm/condition/geometric-condition-builder.js +220 -0
  140. package/dist/esm/condition/index.js +8 -0
  141. package/dist/esm/condition/jsonb-condition-builder.js +439 -0
  142. package/dist/esm/condition/network-condition-builder.js +229 -0
  143. package/dist/esm/condition/postgis-condition-builder.js +180 -0
  144. package/dist/esm/condition/range-condition-builder.js +90 -0
  145. package/dist/esm/core/helpers/ConnectedAggregateBuilder.js +128 -0
  146. package/dist/esm/core/helpers/ConnectedCTEBuilder.js +49 -0
  147. package/dist/esm/core/helpers/ConnectedCountBuilder.js +69 -0
  148. package/dist/esm/core/helpers/ConnectedDeleteBuilder.js +61 -0
  149. package/dist/esm/core/helpers/ConnectedInsertBuilder.js +108 -0
  150. package/dist/esm/core/helpers/ConnectedInsertFromSelectBuilder.js +62 -0
  151. package/dist/esm/core/helpers/ConnectedQueryBuilder.js +142 -0
  152. package/dist/esm/core/helpers/ConnectedRawQueryBuilder.js +42 -0
  153. package/dist/esm/core/helpers/ConnectedSelectBuilder.js +327 -0
  154. package/dist/esm/core/helpers/ConnectedTransactionBuilder.js +100 -0
  155. package/dist/esm/core/helpers/ConnectedUpdateBuilder.js +75 -0
  156. package/dist/esm/core/helpers/PaginateBuilder.js +174 -0
  157. package/dist/esm/core/helpers/ReturningExecutor.js +66 -0
  158. package/dist/esm/core/helpers/capability-guard.js +7 -0
  159. package/dist/esm/core/helpers/index.js +13 -0
  160. package/dist/esm/core/helpers/methods.js +6 -0
  161. package/dist/esm/core/helpers/query-convenience.js +194 -0
  162. package/dist/esm/core/helpers/select-joins.js +246 -0
  163. package/dist/esm/core/helpers/select-pagination.js +226 -0
  164. package/dist/esm/core/helpers/select-types.js +1 -0
  165. package/dist/esm/core/pg-family/cockroachdb-client/capabilities.js +28 -0
  166. package/dist/esm/core/pg-family/cockroachdb-client/index.js +2 -0
  167. package/dist/esm/core/pg-family/cockroachdb-client/relq-cockroach.js +12 -0
  168. package/dist/esm/core/pg-family/dsql-client/capabilities.js +28 -0
  169. package/dist/esm/core/pg-family/dsql-client/index.js +2 -0
  170. package/dist/esm/core/pg-family/dsql-client/relq-dsql.js +12 -0
  171. package/dist/esm/core/pg-family/index.js +6 -0
  172. package/dist/esm/core/pg-family/nile-client/capabilities.js +28 -0
  173. package/dist/esm/core/pg-family/nile-client/index.js +2 -0
  174. package/dist/esm/core/pg-family/nile-client/relq-nile.js +32 -0
  175. package/dist/esm/core/pg-family/nile-client/tenant-context.js +40 -0
  176. package/dist/esm/core/pg-family/pg-client/capabilities.js +28 -0
  177. package/dist/esm/core/pg-family/pg-client/index.js +2 -0
  178. package/dist/esm/core/pg-family/pg-client/relq-postgres.js +39 -0
  179. package/dist/esm/core/pg-family/shared/pg-base.js +347 -0
  180. package/dist/esm/core/pg-family/shared/pg-dialect.js +63 -0
  181. package/dist/esm/core/pg-family/shared/pg-error-parser.js +29 -0
  182. package/dist/esm/core/pg-family/shared/pg-type-coercion.js +6 -0
  183. package/dist/esm/core/relq-base.js +270 -0
  184. package/dist/esm/core/relq-client.js +48 -0
  185. package/dist/esm/core/shared/cleanup.js +27 -0
  186. package/dist/esm/core/shared/column-mapping.js +90 -0
  187. package/dist/esm/core/shared/errors.js +13 -0
  188. package/dist/esm/core/shared/index.js +6 -0
  189. package/dist/esm/core/shared/table-accessor.js +19 -0
  190. package/dist/esm/core/shared/transform.js +30 -0
  191. package/dist/esm/core/shared/types.js +1 -0
  192. package/dist/esm/core/shared/validation.js +136 -0
  193. package/dist/esm/core/types/core.types.js +1 -0
  194. package/dist/esm/count/count-builder.js +81 -0
  195. package/dist/esm/count/index.js +1 -0
  196. package/dist/esm/delete/delete-builder.js +169 -0
  197. package/dist/esm/delete/index.js +1 -0
  198. package/dist/esm/explain/explain-builder.js +95 -0
  199. package/dist/esm/explain/index.js +1 -0
  200. package/dist/esm/index.js +7 -0
  201. package/dist/esm/insert/conflict-builder.js +202 -0
  202. package/dist/esm/insert/index.js +1 -0
  203. package/dist/esm/insert/insert-builder.js +313 -0
  204. package/dist/esm/insert/insert-from-select-builder.js +79 -0
  205. package/dist/esm/pubsub/index.js +1 -0
  206. package/dist/esm/pubsub/listen-notify-builder.js +48 -0
  207. package/dist/esm/pubsub/listener-connection.js +173 -0
  208. package/dist/esm/raw/index.js +2 -0
  209. package/dist/esm/raw/raw-query-builder.js +20 -0
  210. package/dist/esm/raw/sql-template.js +66 -0
  211. package/dist/esm/select/aggregate-builder.js +172 -0
  212. package/dist/esm/select/index.js +4 -0
  213. package/dist/esm/select/join-builder.js +184 -0
  214. package/dist/esm/select/join-condition-builder.js +181 -0
  215. package/dist/esm/select/join-internals.js +2 -0
  216. package/dist/esm/select/join-many-condition-builder.js +151 -0
  217. package/dist/esm/select/scalar-query-builder.js +126 -0
  218. package/dist/esm/select/scalar-select-builder.js +70 -0
  219. package/dist/esm/select/select-builder.js +419 -0
  220. package/dist/esm/select/sql-expression.js +33 -0
  221. package/dist/esm/select/table-proxy.js +91 -0
  222. package/dist/esm/shared/aws-dsql.js +140 -0
  223. package/dist/esm/shared/errors/relq-errors.js +339 -0
  224. package/dist/esm/shared/pg-format.js +375 -0
  225. package/dist/esm/shared/types/config-types.js +46 -0
  226. package/dist/esm/transaction/index.js +1 -0
  227. package/dist/esm/transaction/transaction-builder.js +70 -0
  228. package/dist/esm/types/aggregate-types.js +1 -0
  229. package/dist/esm/types/inference-types.js +12 -0
  230. package/dist/esm/types/pagination-types.js +4 -0
  231. package/dist/esm/types/result-types.js +1 -0
  232. package/dist/esm/types/scalar-types.js +1 -0
  233. package/dist/esm/types/schema-types.js +1 -0
  234. package/dist/esm/types/subscription-types.js +1 -0
  235. package/dist/esm/types.js +1 -0
  236. package/dist/esm/update/array-update-builder.js +219 -0
  237. package/dist/esm/update/index.js +3 -0
  238. package/dist/esm/update/jsonb-update-builder.js +211 -0
  239. package/dist/esm/update/update-builder.js +267 -0
  240. package/dist/esm/utils/addon/pg/cursor.js +1 -0
  241. package/dist/esm/utils/addon/pg/pg.js +2 -0
  242. package/dist/esm/utils/case-converter.js +55 -0
  243. package/dist/esm/utils/env-resolver.js +213 -0
  244. package/dist/esm/utils/environment-detection.js +114 -0
  245. package/dist/esm/utils/fk-resolver.js +178 -0
  246. package/dist/esm/utils/index.js +4 -0
  247. package/dist/esm/utils/pool-defaults.js +85 -0
  248. package/dist/esm/utils/type-coercion.js +112 -0
  249. package/dist/esm/window/index.js +1 -0
  250. package/dist/esm/window/window-builder.js +73 -0
  251. package/dist/index.cjs +1 -0
  252. package/dist/index.d.ts +7281 -0
  253. package/dist/index.js +1 -0
  254. package/package.json +52 -0
@@ -0,0 +1,178 @@
1
+ export class ForeignKeyResolutionError extends Error {
2
+ fromTable;
3
+ toTable;
4
+ constructor(fromTable, toTable, message) {
5
+ super(message || `No foreign key relationship found between "${fromTable}" and "${toTable}"`);
6
+ this.fromTable = fromTable;
7
+ this.toTable = toTable;
8
+ this.name = 'ForeignKeyResolutionError';
9
+ }
10
+ }
11
+ function isArrayFormat(tableRelations) {
12
+ return Array.isArray(tableRelations);
13
+ }
14
+ function* iterateForeignKeys(tableRelations) {
15
+ if (!tableRelations)
16
+ return;
17
+ if (isArrayFormat(tableRelations)) {
18
+ for (const relationDef of tableRelations) {
19
+ if (relationDef.$type === 'foreignKey' && relationDef.$columns?.length > 0) {
20
+ const columnKey = relationDef.$columns[0].column;
21
+ yield [columnKey, relationDef];
22
+ }
23
+ }
24
+ }
25
+ else {
26
+ for (const [columnKey, relationDef] of Object.entries(tableRelations)) {
27
+ yield [columnKey, relationDef];
28
+ }
29
+ }
30
+ }
31
+ export function resolveForeignKey(relations, schema, fromTableKey, toTableKey) {
32
+ if (!relations) {
33
+ return null;
34
+ }
35
+ const fromTableDef = schema[fromTableKey];
36
+ const toTableDef = schema[toTableKey];
37
+ if (!fromTableDef || !toTableDef) {
38
+ return null;
39
+ }
40
+ const fromTableName = fromTableDef.$name || fromTableKey;
41
+ const toTableName = toTableDef.$name || toTableKey;
42
+ const fromTableRelations = relations[fromTableKey];
43
+ if (fromTableRelations) {
44
+ for (const [columnKey, relationDef] of Object.entries(fromTableRelations)) {
45
+ if (relationDef.$type === 'foreignKey' && relationDef.$targetTable === toTableName) {
46
+ const fromColumn = getSourceColumnName(fromTableDef, columnKey, relationDef);
47
+ const toColumn = getTargetColumnName(relationDef, toTableDef);
48
+ return {
49
+ fromTable: fromTableName,
50
+ fromColumn,
51
+ toTable: toTableName,
52
+ toColumn,
53
+ direction: 'forward'
54
+ };
55
+ }
56
+ }
57
+ }
58
+ const toTableRelations = relations[toTableKey];
59
+ if (toTableRelations) {
60
+ for (const [columnKey, relationDef] of Object.entries(toTableRelations)) {
61
+ if (relationDef.$type === 'foreignKey' && relationDef.$targetTable === fromTableName) {
62
+ const toColumn = getSourceColumnName(toTableDef, columnKey, relationDef);
63
+ const fromColumn = getTargetColumnName(relationDef, fromTableDef);
64
+ return {
65
+ fromTable: fromTableName,
66
+ fromColumn,
67
+ toTable: toTableName,
68
+ toColumn,
69
+ direction: 'reverse'
70
+ };
71
+ }
72
+ }
73
+ }
74
+ return null;
75
+ }
76
+ export function resolveForeignKeyOrThrow(relations, schema, fromTableKey, toTableKey) {
77
+ const result = resolveForeignKey(relations, schema, fromTableKey, toTableKey);
78
+ if (!result) {
79
+ const availableRelations = getAvailableRelations(relations, fromTableKey);
80
+ let message = `No foreign key relationship found between "${fromTableKey}" and "${toTableKey}".`;
81
+ if (availableRelations.length > 0) {
82
+ message += ` Available relations from "${fromTableKey}": ${availableRelations.join(', ')}.`;
83
+ }
84
+ else {
85
+ message += ` No relations defined for "${fromTableKey}".`;
86
+ }
87
+ message += ' Use an explicit join condition instead.';
88
+ throw new ForeignKeyResolutionError(fromTableKey, toTableKey, message);
89
+ }
90
+ return result;
91
+ }
92
+ export function getAvailableRelations(relations, tableKey) {
93
+ if (!relations) {
94
+ return [];
95
+ }
96
+ const tableRelations = relations[tableKey];
97
+ if (!tableRelations) {
98
+ return [];
99
+ }
100
+ return Object.entries(tableRelations)
101
+ .filter(([_, def]) => def.$type === 'foreignKey')
102
+ .map(([key, def]) => `${key} → ${def.$targetTable}`);
103
+ }
104
+ export function getAllForeignKeys(relations, schema, tableKey) {
105
+ if (!relations) {
106
+ return [];
107
+ }
108
+ const results = [];
109
+ const tableDef = schema[tableKey];
110
+ if (!tableDef) {
111
+ return [];
112
+ }
113
+ const tableName = tableDef.$name || tableKey;
114
+ const tableRelations = relations[tableKey];
115
+ if (tableRelations) {
116
+ for (const [columnKey, relationDef] of Object.entries(tableRelations)) {
117
+ if (relationDef.$type === 'foreignKey') {
118
+ const targetTableKey = findTableKeyByName(schema, relationDef.$targetTable);
119
+ const targetTableDef = targetTableKey ? schema[targetTableKey] : null;
120
+ results.push({
121
+ fromTable: tableName,
122
+ fromColumn: getSourceColumnName(tableDef, columnKey, relationDef),
123
+ toTable: relationDef.$targetTable,
124
+ toColumn: getTargetColumnName(relationDef, targetTableDef),
125
+ direction: 'forward'
126
+ });
127
+ }
128
+ }
129
+ }
130
+ for (const [otherTableKey, otherRelations] of Object.entries(relations)) {
131
+ if (otherTableKey === tableKey)
132
+ continue;
133
+ for (const [columnKey, relationDef] of Object.entries(otherRelations)) {
134
+ if (relationDef.$type === 'foreignKey' && relationDef.$targetTable === tableName) {
135
+ const otherTableDef = schema[otherTableKey];
136
+ results.push({
137
+ fromTable: tableName,
138
+ fromColumn: getTargetColumnName(relationDef, tableDef),
139
+ toTable: otherTableDef?.$name || otherTableKey,
140
+ toColumn: getSourceColumnName(otherTableDef, columnKey, relationDef),
141
+ direction: 'reverse'
142
+ });
143
+ }
144
+ }
145
+ }
146
+ return results;
147
+ }
148
+ function getSourceColumnName(tableDef, columnKey, relationDef) {
149
+ const colKey = (relationDef.$columns && relationDef.$columns.length > 0)
150
+ ? relationDef.$columns[0].column
151
+ : columnKey;
152
+ if (tableDef && tableDef.$columns && tableDef.$columns[colKey]) {
153
+ const colDef = tableDef.$columns[colKey];
154
+ return colDef.$columnName || colKey;
155
+ }
156
+ return camelToSnake(colKey);
157
+ }
158
+ function getTargetColumnName(relationDef, targetTableDef) {
159
+ const colKey = (relationDef.$references && relationDef.$references.length > 0)
160
+ ? relationDef.$references[0].column
161
+ : 'id';
162
+ if (targetTableDef && targetTableDef.$columns && targetTableDef.$columns[colKey]) {
163
+ const colDef = targetTableDef.$columns[colKey];
164
+ return colDef.$columnName || colKey;
165
+ }
166
+ return colKey;
167
+ }
168
+ function findTableKeyByName(schema, tableName) {
169
+ for (const [key, def] of Object.entries(schema)) {
170
+ if (def.$name === tableName || key === tableName) {
171
+ return key;
172
+ }
173
+ }
174
+ return null;
175
+ }
176
+ function camelToSnake(str) {
177
+ return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
178
+ }
@@ -0,0 +1,4 @@
1
+ export { convertCase } from "./case-converter.js";
2
+ export { default as format } from "../shared/pg-format.js";
3
+ export { resolveForeignKey, resolveForeignKeyOrThrow, getAvailableRelations, getAllForeignKeys, ForeignKeyResolutionError } from "./fk-resolver.js";
4
+ export { loadEnvFile, resolvePgEnv, resolveAwsEnv, hasPgEnvConfig, hasAwsEnvConfig, validateEnvConfig, mergeWithPgEnv, mergeWithAwsEnv } from "./env-resolver.js";
@@ -0,0 +1,85 @@
1
+ import { detectEnvironment } from "./environment-detection.js";
2
+ export function getSmartPoolDefaults() {
3
+ const env = detectEnvironment();
4
+ const baseConfig = {
5
+ min: 0,
6
+ idleTimeoutMillis: 10000,
7
+ connectionTimeoutMillis: 10000,
8
+ };
9
+ if (env.type === 'serverless' || env.type === 'edge') {
10
+ return {
11
+ ...baseConfig,
12
+ max: 1,
13
+ idleTimeoutMillis: 1000,
14
+ recommendation: `${env.type === 'serverless' ? 'Serverless' : 'Edge'} environment detected (${env.provider}).\n` +
15
+ ' Pool: min: 0, max: 1 (single lazy connection per invocation)'
16
+ };
17
+ }
18
+ return {
19
+ ...baseConfig,
20
+ max: 10,
21
+ idleTimeoutMillis: 30000,
22
+ recommendation: 'Traditional server environment.\n' +
23
+ ' Pool: min: 0, max: 10 (connections created on demand, scale under load)'
24
+ };
25
+ }
26
+ export function validatePoolConfig(config, env) {
27
+ const warnings = [];
28
+ const errors = [];
29
+ const min = config.min ?? 0;
30
+ const max = config.max ?? 10;
31
+ if (env.type === 'edge' && max > 1) {
32
+ warnings.push(`⚠️ Running in ${env.provider} (edge) with pool max: ${max}.\n` +
33
+ ' Edge runtimes have short-lived connections.\n' +
34
+ ' \n' +
35
+ ' Recommended: pool: { min: 0, max: 1 }');
36
+ }
37
+ if (min > max) {
38
+ warnings.push(`⚠️ Pool min (${min}) is greater than max (${max}).\n` +
39
+ ` This is invalid. Min will be clamped to max (${max}).`);
40
+ }
41
+ if (env.type === 'serverless' && max > 1) {
42
+ warnings.push(`⚠️ Running in ${env.provider} with pool max: ${max}.\n` +
43
+ ' Each serverless function will create up to ' + max + ' connections.\n' +
44
+ ' With many concurrent functions, this can exhaust PostgreSQL connections.\n' +
45
+ ' \n' +
46
+ ' Recommended: pool: { min: 0, max: 1 }\n' +
47
+ ' \n' +
48
+ ' If you need connection pooling in serverless:\n' +
49
+ ' - Use PgBouncer or connection pooler\n' +
50
+ ' - Use Supabase (built-in pooling)\n' +
51
+ ' - Use Neon serverless driver');
52
+ }
53
+ if (env.type === 'traditional' && min > 5) {
54
+ warnings.push(`⚠️ Pool min set to ${min}. This keeps ${min} connections always open.\n` +
55
+ ' High min values waste resources when traffic is low.\n' +
56
+ ' \n' +
57
+ ' Recommended: min: 0 (connections created on demand)\n' +
58
+ ' Pool will scale up to max: ' + max + ' under load automatically.');
59
+ }
60
+ if (max > 20) {
61
+ warnings.push(`⚠️ Pool max set to ${max}. This is very high.\n` +
62
+ ' PostgreSQL connection limit is typically 100-200.\n' +
63
+ ' Multiple app instances × max connections can exhaust the database.\n' +
64
+ ' \n' +
65
+ ' Recommended: max: 10-20 per app instance');
66
+ }
67
+ return {
68
+ valid: errors.length === 0,
69
+ warnings,
70
+ errors
71
+ };
72
+ }
73
+ export function mergeWithDefaults(userConfig) {
74
+ const defaults = getSmartPoolDefaults();
75
+ return {
76
+ min: userConfig?.min ?? defaults.min,
77
+ max: userConfig?.max ?? defaults.max,
78
+ idleTimeoutMillis: userConfig?.idleTimeoutMillis ?? defaults.idleTimeoutMillis,
79
+ connectionTimeoutMillis: userConfig?.connectionTimeoutMillis ?? defaults.connectionTimeoutMillis,
80
+ recommendation: defaults.recommendation
81
+ };
82
+ }
83
+ export function formatPoolConfig(config) {
84
+ return `{ min: ${config.min}, max: ${config.max}, idleTimeout: ${config.idleTimeoutMillis}ms }`;
85
+ }
@@ -0,0 +1,112 @@
1
+ const BIGINT_TYPES = new Set(['BIGINT', 'INT8', 'BIGSERIAL', 'SERIAL8']);
2
+ const DATE_TYPES = new Set(['TIMESTAMP', 'TIMESTAMPTZ', 'DATE', 'TIME', 'TIMETZ']);
3
+ const JSON_TYPES = new Set(['JSON', 'JSONB']);
4
+ export function deserializeValue(value, pgType) {
5
+ if (value === null || value === undefined) {
6
+ return value;
7
+ }
8
+ const upperType = pgType.toUpperCase();
9
+ if (BIGINT_TYPES.has(upperType)) {
10
+ if (typeof value === 'string') {
11
+ return BigInt(value);
12
+ }
13
+ if (typeof value === 'number') {
14
+ return BigInt(value);
15
+ }
16
+ return value;
17
+ }
18
+ if (DATE_TYPES.has(upperType) || upperType.startsWith('TIMESTAMP')) {
19
+ if (value instanceof Date) {
20
+ return value;
21
+ }
22
+ if (typeof value === 'string' || typeof value === 'number') {
23
+ return new Date(value);
24
+ }
25
+ return value;
26
+ }
27
+ if (JSON_TYPES.has(upperType)) {
28
+ if (typeof value === 'string') {
29
+ try {
30
+ return JSON.parse(value);
31
+ }
32
+ catch {
33
+ return value;
34
+ }
35
+ }
36
+ return value;
37
+ }
38
+ if (upperType === 'BOOLEAN' || upperType === 'BOOL') {
39
+ if (typeof value === 'string') {
40
+ return value.toLowerCase() === 'true' || value === 't' || value === '1';
41
+ }
42
+ return Boolean(value);
43
+ }
44
+ return value;
45
+ }
46
+ export function deserializeRow(row, schema) {
47
+ const result = {};
48
+ const columnMap = new Map();
49
+ for (const [key, config] of Object.entries(schema)) {
50
+ const dbColumnName = config.$columnName || key;
51
+ const sqlType = config.$sqlType || (typeof config.$type === 'string' ? config.$type : 'TEXT');
52
+ columnMap.set(dbColumnName, { key, type: sqlType });
53
+ }
54
+ for (const [dbColumn, value] of Object.entries(row)) {
55
+ const mapping = columnMap.get(dbColumn);
56
+ if (mapping) {
57
+ result[mapping.key] = deserializeValue(value, mapping.type);
58
+ }
59
+ else {
60
+ result[dbColumn] = value;
61
+ }
62
+ }
63
+ return result;
64
+ }
65
+ export function deserializeRows(rows, schema) {
66
+ return rows.map(row => deserializeRow(row, schema));
67
+ }
68
+ export function serializeValue(value, pgType) {
69
+ if (value === null || value === undefined) {
70
+ return value;
71
+ }
72
+ const upperType = pgType.toUpperCase();
73
+ if (BIGINT_TYPES.has(upperType)) {
74
+ if (typeof value === 'bigint') {
75
+ return value.toString();
76
+ }
77
+ return value;
78
+ }
79
+ if (DATE_TYPES.has(upperType) || upperType.startsWith('TIMESTAMP')) {
80
+ if (value instanceof Date) {
81
+ return value.toISOString();
82
+ }
83
+ return value;
84
+ }
85
+ if (JSON_TYPES.has(upperType)) {
86
+ if (typeof value === 'object' && value !== null) {
87
+ return JSON.stringify(value);
88
+ }
89
+ return value;
90
+ }
91
+ return value;
92
+ }
93
+ export function serializeRow(row, schema) {
94
+ const result = {};
95
+ for (const [key, value] of Object.entries(row)) {
96
+ const config = schema[key];
97
+ if (config) {
98
+ const sqlType = config.$sqlType || (typeof config.$type === 'string' ? config.$type : 'TEXT');
99
+ result[key] = serializeValue(value, sqlType);
100
+ }
101
+ else {
102
+ result[key] = value;
103
+ }
104
+ }
105
+ return result;
106
+ }
107
+ export function extractSchemaColumns(tableDefinition) {
108
+ if (tableDefinition && tableDefinition.$columns) {
109
+ return tableDefinition.$columns;
110
+ }
111
+ return null;
112
+ }
@@ -0,0 +1 @@
1
+ export { WindowBuilder } from "./window-builder.js";
@@ -0,0 +1,73 @@
1
+ import format from "../shared/pg-format.js";
2
+ export class WindowBuilder {
3
+ partitionColumns = [];
4
+ orderColumns = [];
5
+ frameStart;
6
+ frameEnd;
7
+ frameMode;
8
+ partitionBy(...columns) {
9
+ this.partitionColumns.push(...columns);
10
+ return this;
11
+ }
12
+ orderBy(column, direction = 'ASC') {
13
+ this.orderColumns.push({ column, direction });
14
+ return this;
15
+ }
16
+ rows(start, end) {
17
+ this.frameMode = 'ROWS';
18
+ this.frameStart = typeof start === 'number' ? `${start} PRECEDING` : start;
19
+ this.frameEnd = end ? (typeof end === 'number' ? `${end} FOLLOWING` : end) : 'CURRENT ROW';
20
+ return this;
21
+ }
22
+ range(start, end) {
23
+ this.frameMode = 'RANGE';
24
+ this.frameStart = typeof start === 'number' ? `${start} PRECEDING` : start;
25
+ this.frameEnd = end ? (typeof end === 'number' ? `${end} FOLLOWING` : end) : 'CURRENT ROW';
26
+ return this;
27
+ }
28
+ groups(start, end) {
29
+ this.frameMode = 'GROUPS';
30
+ this.frameStart = typeof start === 'number' ? `${start} PRECEDING` : start;
31
+ this.frameEnd = end ? (typeof end === 'number' ? `${end} FOLLOWING` : end) : 'CURRENT ROW';
32
+ return this;
33
+ }
34
+ toString() {
35
+ const parts = [];
36
+ if (this.partitionColumns.length > 0) {
37
+ parts.push(`PARTITION BY ${this.partitionColumns.map(c => format.ident(c)).join(', ')}`);
38
+ }
39
+ if (this.orderColumns.length > 0) {
40
+ parts.push(`ORDER BY ${this.orderColumns.map(o => `${format.ident(o.column)} ${o.direction}`).join(', ')}`);
41
+ }
42
+ if (this.frameMode && this.frameStart) {
43
+ parts.push(`${this.frameMode} BETWEEN ${this.frameStart} AND ${this.frameEnd}`);
44
+ }
45
+ return parts.join(' ');
46
+ }
47
+ rowNumber() {
48
+ return `ROW_NUMBER() OVER (${this.toString()})`;
49
+ }
50
+ rank() {
51
+ return `RANK() OVER (${this.toString()})`;
52
+ }
53
+ denseRank() {
54
+ return `DENSE_RANK() OVER (${this.toString()})`;
55
+ }
56
+ lag(column, offset = 1, defaultValue) {
57
+ const def = defaultValue !== undefined ? `, ${format('%L', defaultValue)}` : '';
58
+ return `LAG(${format.ident(column)}, ${offset}${def}) OVER (${this.toString()})`;
59
+ }
60
+ lead(column, offset = 1, defaultValue) {
61
+ const def = defaultValue !== undefined ? `, ${format('%L', defaultValue)}` : '';
62
+ return `LEAD(${format.ident(column)}, ${offset}${def}) OVER (${this.toString()})`;
63
+ }
64
+ firstValue(column) {
65
+ return `FIRST_VALUE(${format.ident(column)}) OVER (${this.toString()})`;
66
+ }
67
+ lastValue(column) {
68
+ return `LAST_VALUE(${format.ident(column)}) OVER (${this.toString()})`;
69
+ }
70
+ nthValue(column, n) {
71
+ return `NTH_VALUE(${format.ident(column)}, ${n}) OVER (${this.toString()})`;
72
+ }
73
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./cjs/index.cjs');